diff --git a/.ci/travis/after_script.sh b/.ci/travis/after_script.sh new file mode 100644 index 000000000..5b5a96448 --- /dev/null +++ b/.ci/travis/after_script.sh @@ -0,0 +1,9 @@ +#!/bin/bash +set -ev + +cd Resources +rm *.dll +cd ../doc +rm -r gh-pages +rm -r build +cd ../ \ No newline at end of file diff --git a/.ci/travis/before_script.sh b/.ci/travis/before_script.sh new file mode 100644 index 000000000..a0fc9529a --- /dev/null +++ b/.ci/travis/before_script.sh @@ -0,0 +1,20 @@ +#!/bin/bash +set -ev + +if [ "${TRAVIS_PULL_REQUEST}" = "false" ]; then + echo "Build from within the home repository, encryption enabled." + wget --quiet https://github.com/KSP-KOS/KSP_LIB/blob/master/kos-${KSP_VERSION}.tar.enc?raw=true -O kos-${KSP_VERSION}.tar.enc + openssl aes-256-cbc -K $encrypted_6287ee711a27_key -iv $encrypted_6287ee711a27_iv -in kos-${KSP_VERSION}.tar.enc -out kos-${KSP_VERSION}.tar -d +else + echo "Build from pull request outside of the home repository, encryption disabled." + wget --quiet https://github.com/KSP-KOS/KSP_LIB/blob/master/kos-${KSP_VERSION}.tar?raw=true -O kos-${KSP_VERSION}.tar +fi + +mkdir -p Resources +tar -xvf kos-${KSP_VERSION}.tar -C Resources/ + +python --version +pip --version +# workaround for not being able to use pip outside of a python project +export PATH=$HOME/.local/bin:$PATH +pip install --user $USER sphinx_rtd_theme \ No newline at end of file diff --git a/.ci/travis/script-sphinxdocs.sh b/.ci/travis/script-sphinxdocs.sh new file mode 100644 index 000000000..ebd714dab --- /dev/null +++ b/.ci/travis/script-sphinxdocs.sh @@ -0,0 +1,7 @@ +#!/bin/bash +set -ev + +cd doc +sphinx-build -b html -q -W -d build/doctrees source gh-pages +#make html +cd ../ \ No newline at end of file diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 000000000..771770f38 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,8 @@ +# Auto detect text files and perform LF normalization +# http://davidlaing.com/2012/09/19/customise-your-gitattributes-to-become-a-git-ninja/ +* text=auto + +*.cs diff=csharp + +*.csproj text=auto merge=union +*.sln text=auto eol=crlf merge=union \ No newline at end of file diff --git a/.gitignore b/.gitignore index 4f721b922..4bb455988 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,27 @@ -bin/ -obj/ +# VisualStudio +[Bb]in/ +[Oo]bj/ *.suo packages/ /src/kOS.sln.ide + +# Monodevelop +[Ee]xported[Oo]bj/ +*.userprefs + +# Unity +[Ll]ibrary/ +[Tt]emp/ +/*.pidb +/*.user + +# Build products and files generated during gameplay +Resources/GameData/kOS/Plugins/ +!Resources/GameData/kOS/ICSharpCode.SharpZipLib.dll + +# Symlink to KSP directory +KSPdirlink + +# OS Specific +.DS_STORE* +[Tt]humbs.db diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 000000000..906a8ea63 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,43 @@ +language: csharp +solution: src/kOS.sln +sudo: false + +addons: + apt: + packages: + - python-sphinx + - nunit-console + +env: + global: + - KSP_VERSION="1.0.5" + +# Pre-shared token for pushing notifications to slack chat +notifications: + slack: ksp-kos:51DTQ4ZBP9SlGNnLWJ5D84vp + +# Before the install the library dlls need to be downloaded +before_script: +- chmod +x .ci/travis/before_script.sh && ./.ci/travis/before_script.sh + +script: +- xbuild /p:Configuration=Release $TRAVIS_SOLUTION +# I know framework 4.0 is wrong, just trying it to see if it fixes the test +- nunit-console -framework=4.0 src/kOS.Safe.Test/bin/Release/kOS.Safe.Test.dll +# - chmod +x .ci/travis/script-sphinxdocs.sh && ./.ci/travis/script-sphinxdocs.sh + +# Cleanup the downloaded resources +after_script: +- chmod +x .ci/travis/after_script.sh && ./.ci/travis/after_script.sh + +before_deploy: +- mkdir src/kOS/bin/dist +- tar -zcvf src/kOS/bin/dist/build_$TRAVIS_BUILD_NUMBER.tgz src/kOS/bin/Release/kOS*.dll + +deploy: + provider: s3 + access_key_id: "AKIAINHSGTBU5O3DKV2Q" + secret_access_key: "$S3_DEPLOY_SECRET" + bucket: "kos-artifacts" + skip_cleanup: true + local_dir: "src/kOS/bin/dist/" diff --git a/CHANGELOG.md b/CHANGELOG.md index 53d83b5dc..8a8f19306 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,265 @@ kOS Mod Changelog ================= -# v0.17.1 +# v0.19.1 + +This release is a patch to v0.19.0, fixing some things +found by the user community in the two days shortly after +v0.19.0 released. + +It also happens to contain a few terminal window features +that were being worked on before v0.19.0 but were not deemed +ready yet when 0.19.0 was released. + +### NEW FEATURES +* PIDLoop tutorial section in the docs edited to mention new PIDLoop() + function that did not exist back when that page was first written. + (http://ksp-kos.github.io/KOS_DOC/tutorials/pidloops.html) +* New Terminal GUI doodads and widgets: A brightness slider, + and the ability to zoom the character width and height. Also + made the transparency and dimming of the 'non-active' terminals + a bit less severe so you can still read them when un-focused. + Also, these new features can be script controlled by new + suffixes, however it is unclear if that feature (doing it from + a script) will remain in the future so use it with care: + (http://ksp-kos.github.io/KOS_DOC/structures/misc/terminal.html) + +### BUG FIXES +* Fixed file rename bug on local hard disks: + (https://github.com/KSP-KOS/KOS/issues/1498) +* Fixed boot files can be larger than the local disk + (https://github.com/KSP-KOS/KOS/issues/1094) +* Fixed a bug where Infernal Robotics would break when switching vessels or + reverting. (https://github.com/KSP-KOS/KOS/issues/1501) +* Fixes problems with using PartModule's SetField(), and infernal Robotics which + had been failing for all cases where the field was a "float". + (https://github.com/KSP-KOS/KOS/issues/1503). + There may have been other places this bug affected, but this is + where it was noticed. Hypothetically, anywhere the stock game's + library insists on only accepting a single-precision float and + not a double would have had the problem. +* Improve steering when small control magnitudes are required. + (https://github.com/KSP-KOS/KOS/issues/1512) + +# v0.19.0 + +### BREAKING CHANGES +* As usual, you must recompile any KSM files when using the new version. +* Vecdraw :SCALE no longer applied to :START. Only applied to :VEC. +* Varying power consumption might make it so if you have high IPU settings some designs might run out of power when they didn't before. (in most cases it should draw less power for most people). +* !!!! Default extension of ".ks" is no longer applied to all new filenames created. But it still will be looked for when reading existing files if you leave the extension off !!!! +* FileInfo information now moved to Volume (http://ksp-kos.github.io/KOS_DOC/structures/volumes_and_files/volume.html). +* VOLUME:FILES was returning a LIST(), now it returns a LEXICON who's keys are the filename. +* String sort-order comparisons with "<" and ">" operators were implemented wrongly and just compared lengths. Now they do a character-by-character comparison (case-insensitively). On the off chance that anyone was actually trying to use the previous weird length-comparison behavior, that would break. + +### NEW FEATURES +* Art asset rework. The meshes and textures of the kOS CPU parts have recieved an update, and a new KAL9000 high-end computer part was included. +* Varying power consumption. Units of electric charge used now varies depending on CPU speed and how much the CPU is being actually used. If your IPU setting is low, or if your program isn't doing very much and is just stuck on a `wait` statement, it won't use as much power. (http://ksp-kos.github.io/KOS_DOC/general/cpu_hardware#electricdrain) +* Ability to read and write whole files at a time as one big string. (http://ksp-kos.github.io/KOS_DOC/structures/volumes_and_files/volumefile.html) +* User Functions can now be referred to with function pointers, or "delegates". (http://ksp-kos.github.io/KOS_DOC/language/delegates.html) +* Automatic serialization system to save/load some kinds of data values to JSON-format files (http://ksp-kos.github.io/KOS_DOC/commands/files.html#writejson-object-filename) +* User Programs and Functions now allow trailing optional parameters with defaulted values. (http://ksp-kos.github.io/KOS_DOC/language/user_functions.html#optional-parameters-parameter-defaults). +* There are now some suffixes that work on all value types, even primitive scalars. To accomplish this, a new "encapsulation" system has wrapped all kOS structures and primitive types inside a generic base type. (http://ksp-kos.github.io/KOS_DOC/structures/reflection.html) +* ENGINE type now supports multi-mode cases and has its gimbal accessible through :GIMBAL suffix (http://ksp-kos.github.io/KOS_DOC/structures/vessels/engine.html) +* Added GIMBAL:LIMIT suffix. (http://ksp-kos.github.io/KOS_DOC/structures/vessels/gimbal.html) +* Better support for DMagic's Orbital Science mod (http://ksp-kos.github.io/KOS_DOC/addons/OrbitalScience.html) +* Char() and Unchar() functions for translating unicode numbers to characters and visa versa (http://ksp-kos.github.io/KOS_DOC/math/basic.html#function:CHAR) +* New Range type for iterating over hardcoded lists (http://ksp-kos.github.io/KOS_DOC/structures/collections/range.html). +* Ability to iterate over the characters in a string using a FOR loop, as if the string was a LIST() of chars. +* New higher level cpu part. (https://github.com/KSP-KOS/KOS/pull/1380) +* HASTARGET and HASNODE functions (http://ksp-kos.github.io/KOS_DOC/bindings.html?highlight=hastarget) +* :JOIN suffix for LIST to make a string of the elements (http://ksp-kos.github.io/KOS_DOC/structures/collections/list.html#method:LIST:JOIN) +* KUNIVERSE now lets you read hours per day setting (http://ksp-kos.github.io/KOS_DOC/structures/misc/kuniverse.html#attribute:KUNIVERSE:HOURSPERDAY) +* The reserved word ARCHIVE is now a first-class citizen with proper binding, so you can do SET FOO TO ARCHIVE and it will work like you'd expect. +* New Lexicon creation syntax to make a Lexicon and populate it all in one statement. (http://ksp-kos.github.io/KOS_DOC/structures/collections/lexicon.html?highlight=lexicon#constructing-a-lexicon) + +### BUG FIXES +* Numerous additional checks to prevent control of other vessels the kOS CPU isn't attached to. +* The error beep and keyboard click sounds now obey game's UI volume settings. (https://github.com/KSP-KOS/KOS/pull/1287) +* Fixed two bugs with obtaining waypoints by name. (https://github.com/KSP-KOS/KOS/issues/1313) (https://github.com/KSP-KOS/KOS/pull/1319) +* Removed unnecessary rounding of THRUSTLIMIT to nearest 0.5%, now it can be more precise. (https://github.com/KSP-KOS/KOS/pull/1329) +* Removed the ability to activate both modes on multi-mode engine simultaneously. +* LIST ENGINES now lists all engines and displays part names instead of module names. (https://github.com/KSP-KOS/issues/1251) +* Fixed bug that caused hitting ESC to crash the telnet server. (https://github.com/KSP-KOS/KOS/issues/1328) +* Some exceptions didn't cause beep, now they all do. (https://github.com/KSP-KOS/KOS/issues/1317) +* Vecdraw :SCALE no longer applied to :START. Only applied to :VEC. (https://github.com/KSP-KOS/KOS/issues/1200) +* Fixed bug that made up-arrow work incorrectly when the cursor is at the bottom of the terminal window. (https://github.com/KSP-KOS/KOS/issues/1289) +* A multitude of small documentation fixes (https://github.com/KSP-KOS/KOS/pull/1341) +* Fixed a bug when performing an undock (https://github.com/KSP-KOS/KOS/issues/1321) +* IR:AVAILABLE was reporting incorrectly () +* Boot files now wait until the ship is fully unpacked and ready (https://github.com/KSP-KOS/KOS/issues/1280) +* The Vessel :HASBODY (aliases :HASOBT and :HASORBIT) suffix was in the documentation, but had been lost in a refactor last year. It is put back now. +* String sort-order comparisons with "<" and ">" operators were implemented wrongly and just compared lengths. Now they do a character-by-character comparison (case-insensitively) +* Small documentation edits and clarifications all over the place. + +### KNOWN issues +* Using `lock` variables in compiled scripts with a duplicate identifier (like "throttle") throws an error (https://github.com/KSP-KOS/KOS/issues/1347 and https://github.com/KSP-KOS/KOS/issues/1253). +* Occasionally staging with a probe core or root part in the ejected stage will break cooked steering (https://github.com/KSP-KOS/KOS/issues/1492). +* The limitations of RemoteTech integration can be bypassed by storing a volume in a variable before the ship looses a connection to the KSC (https://github.com/KSP-KOS/KOS/issues/1464). + +### CONTRIBUTORS THIS RELEASE + +(These are generated from records on Github of anyone who's Pull Requests are part of this release.) +(Names are simply listed here alphabetically, not by code contribution size. Anyone who even had so much as one line of change is mentioned.) + +Stephan Andreev (ZiwKerman) https://github.com/ZiwKerman +Bert Cotton (BertCotton) https://github.com/BertCotton +Kevin Gisi (gisikw) https://github.com/gisikw +Peter Goddard (pgodd) https://github.com/pgodd +Steven Mading (Dunbaratu) https://github.com/Dunbaratu +Eric A. Meyer (meyerweb) https://github.com/meyerweb +Tomek Piotrowski (tomekpiotrowski) https://github.com/tomekpiotrowski +Brad White (hvacengi) https://github.com/hvacengi +Chris Woerz (erendrake) https://github.com/erendrake (repository owner) +(name not public in github profile) (alchemist_ch) https://github.com/AlchemistCH +(name not public in github profile) (tdw89) https://github.com/TDW89 + +# v0.18.2 + +[Insert witty title here :-P] +------------------------------ + +### BREAKING CHANGES +* As usual, you MUST recompile all KSM files before running them on the new version. Some of the changes have altered how the VM works. +* Nothing else... we hope. + +### NEW FEATURES +* Compatibility with KSP version 1.0.5 +* `run once ...` syntax to run a script only once per session ( http://ksp-kos.github.io/KOS_DOC/commands/files.html#run-once-program ) +* Volumes and processors have better integration ( http://ksp-kos.github.io/structures/vessels/volume.html#structure:VOLUME ) +* Volume titles default to the name tag of the Processor part (only on launch) ( http://ksp-kos.github.io/KOS_DOC/general/volumes.html#naming-volumes ) +* New suffixes for interacting with kOS Processor modules (including `core`) ( http://ksp-kos.github.io/KOS_DOC/commands/processors.html ) +* `debuglog(...)` function to print directly to the KSP log file ( http://ksp-kos.github.io/KOS_DOC/structures/misc/kuniverse.html#method:KUNIVERSE:DEBUGLOG ) +* New `queue` and `stack` data structures ( http://ksp-kos.github.io/KOS_DOC/structures/misc/queue.html and http://ksp-kos.github.io/KOS_DOC/structures/misc/stack.html ) + +### BUG FIXES +* The processor's mode (on/off/starved) is now saved and restored ( https://github.com/KSP-KOS/KOS/issues/1172 ) +* Fixed stage resources again to address a change in KSP 1.0.5 ( https://github.com/KSP-KOS/KOS/issues/1242 ) +* Fix occasional instances of flight controls getting disabled during a docking/undocking/staging event ( https://github.com/KSP-KOS/KOS/issues/1205 ) +* kOS can now trigger module events with RemoteTech installed and no KSC connection ( https://github.com/RemoteTechnologiesGroup/RemoteTech/issues/437 ) +* Fixed handling of multiple thrust/gimbal transforms and corrected some of their directions ( https://github.com/KSP-KOS/KOS/issues/1259 ) + +# v0.18.1 + +Steering More Much Betterer +---------------------- + +### Changes +* Changed default MaxStoppingTime to 2 seconds ( was 1 ) + +### BUG FIXES +* Fixed a issue where the effect of the Kd parameter of PIDLoop was having a reversed effect #1229 +* Fixes an issue where NO_FLOW resources ( eg SolidFuel ) were not reporting correctly #1231 + +# v0.18 + +Steering Much Betterer +---------------------- + +### BREAKING CHANGES +* As usual, you MUST recompile all KSM files before running them on the new version. Some of the changes have altered how the VM works. +* New LOADDISTANCE obsoletes the previous way it worked ( http://ksp-kos.github.io/KOS_DOC/structures/misc/loaddistance.html ) +* Fixed broken spelling of "ACQUIRE" on docking ports. The old spelling of "AQUIRE" won't work anymore. +* Changed the bound variable "SURFACESPEED" to "GROUNDSPEED" instead, as the meaning of "SURFACESPEED" was confusingly ambiguous. +* New arg/param matching checks make some previously usable varying argument techniques not work. (We don't think anyone was using them anyway). +* Disabled the ability to control vessels the kOS computer part is not actually attached to. This always used to be possible, but it shouldn't have been as it breaks the theme of kOS. This affects all the following: vessel:control, part:controlfrom, part:tag (can still get, but not set), partmodule:doaction, partmodule:doevent, partmodule:setfield (can still getfield). These things become read-only when operating on any vessel other than the one the executing kOS module is actually part of. + +### NEW FEATURES +* THE BIG ONE: Fix to Cooked Steering! Should help people using torque-less craft like with Realism Overhaul. Removed the old steering logic and replaced it with a nice auto-tuning system. ( https://github.com/KSP-KOS/KOS/pull/1118 ) +* SteeringManager structure to let users tweak parts of the new steering system ( http://ksp-kos.github.io/KOS_DOC/structures/misc/steeringmanager.html ) +* PIDLoop structure to let users see parts of the new steering system, and to let them use the built-in PID system for their own needs ( http://ksp-kos.github.io/KOS_DOC/structures/misc/pidloop.html ) +* String manipulation methods. ( http://ksp-kos.github.io/KOS_DOC/structures/misc/string.html ) +* New Lexicon (Associateive Array) type. ( http://ksp-kos.github.io/KOS_DOC/structures/misc/lexicon.html ) +* New Science Experiment control interface allows scripts to directly execute science experiments, bypassing the on-screen prompts. ( http://ksp-kos.github.io/KOS_DOC/structures/vessels/scienceexperiment.html ) +* CrewMember API to let you query the registered crew - their class, gender, and skill ( http://ksp-kos.github.io/KOS_DOC/structures/vessels/crewmember.html ) +* Infernal Robotics API now lets you get Part containing a servo ( https://github.com/KSP-KOS/KOS/issues/1103 ) +* (user docs) Better tutorial for KSP 1.0 areo mode. ( https://github.com/KSP-KOS/KOS/pull/1081 ) +* A few more constants: C, ATMTOKPA, KPATOATM. ( http://ksp-kos.github.io/KOS_DOC/math/basic.html ) +* DYNAMICPRESSURE, or Q ( https://github.com/KSP-KOS/KOS/pull/1085 ) +* DEFINED keyword ( http://ksp-kos.github.io/KOS_DOC/language/variables.html#defined ) +* Load and Pack Distance manipulation ( http://ksp-kos.github.io/KOS_DOC/structures/misc/loaddistance.html ) +* KUniverse structure letting you break the 4th wall and revert from a script ( http://ksp-kos.github.io/KOS_DOC/structures/misc/kuniverse.html ) +* Added SolarPrimeVector to provide universal longitude direction ( http://ksp-kos.github.io/KOS_DOC/bindings.html#solarprimevector ) + +### BUG FIXES +* Made `stage:liquidfuel` more sane. ( https://github.com/KSP-KOS/KOS/issues/513 ) +* LIST BODIES returned unusuable structure type ( https://github.com/KSP-KOS/KOS/issues/1090 ) +* Made "ORBIT" and alias for "OBT" and visa versa ( https://github.com/KSP-KOS/KOS/issues/1089 ) +* Made vecdraws stop showing bogus atmospheric burning effects ( https://github.com/KSP-KOS/KOS/pull/1108 ) +* Removed non-functional broken attempts to save/restore variables ( https://github.com/KSP-KOS/KOS/issues/1098 ) +* KSM files didn't store relative jumps right, breaking short-circuit boolean logic ( https://github.com/KSP-KOS/KOS/issues/1137 ) +* (user docs) many minor docs fixes. +* Lock throttle inside a FROM loop was broken ( https://github.com/KSP-KOS/KOS/issues/1117 ) +* Unlock anything inside a Trigger body was broken ( https://github.com/KSP-KOS/KOS/issues/1151 ) +* Replaced KSP's incorrect ground speed with our own calculation ( https://github.com/KSP-KOS/KOS/issues/1097 ) +* SASMODE "radialin" and "raidialout" were swapped in the KSP API ( https://github.com/KSP-KOS/KOS/issues/1130 ) +* Bug with remote tech allowing access without antenna in one case ( https://github.com/KSP-KOS/KOS/pull/1171 ) +* Wheelsteering by integer compass heading was broken ( https://github.com/KSP-KOS/KOS/issues/1141 ) +* SHUTDOWN didn't shut down immediately ( https://github.com/KSP-KOS/KOS/issues/1120 ) +* Remote Tech delay, and the `wait` command, were ignoring the time warp multiplier ( https://github.com/KSP-KOS/KOS/issues/723 ) +* Better detection of arg/param matching. ( https://github.com/KSP-KOS/KOS/issues/1107 ) +* Doing PRINT AT that runs offscreen threw an error ( https://github.com/KSP-KOS/KOS/issues/813 ) + +# v0.17.3 + +1.0.4 Release +----------- + +### BREAKING CHANGES +* Removed all `ETA_` and `ALT_` bindings, please use `ETA:` and `ALT:` instead +* `TRUEANOMALY` and `MEANANOMALYATEPOCH` are now expressed in degrees to conform to our policy +* Deprecated INCOMMRANGE - now throws an exception with instructions to use the new addons:rt methods. +* Updated maxtthrust and availablethrust calculations for KSP v1.0.x. Due to the way KSP handles thrust, neither available thrust nor maxthrust values are constant at all altitudes around bodies with atmospheres. +* Boot files are now stored on local hard drives with their original names. You may get or set the boot file name using CORE:BOOTFILENAME suffix. +* Some undocumented and nonsensical bool math operations have been removed +* The Steering deadzone is much smaller now, this will allow for every precise RCS maneuvers. + +### New Hotness +* You can now point RemoteTech antenna directly from script +* You can now get RemoteTech's 'local control' status +* Infernal Robotics integration improvements +* New loop structure to allow for more flexible iteration +* New struct object `CORE:` to interact with the currently running processor. +* Added vessel:dockingports and vessel:elements suffixes. +* Added element:dockingports and element:vessel suffixes. +* Added availablethrust suffix to engines which mirrors the availablethrust suffix for vessels. +* Added maxthrustat, availablethrustat, and ispat suffixes to engines to read the values at specified atmoshperic pressures. See the documentation for details. +* Added maxthrustat and availablethrustat suffixes to vessels to read the values at a specified atmospheric pressures. See the documentation for details. +* You can now use bootfiles while "Start on Archive volume" is enabled +* Many new sound effects have been added (error, beep, and an option for key click) +* Boolean AND and OR operations can now short circuit +* Add new WARPTO command that uses the new KSP function +* Added new `BODY:SOIRADIUS` +* Added new suffixes to part that lets you get the bare names of events, actions, and modules +* Many new sound effects have been added (error, beep, and an option for key click) +* Added `CLEARVECDRAWS` that will remove all VECDRAWS +* Any floating point value that has no floating component will be converted to an integer + +### Old and busted +* Fixed empty return statements crashing with an argument count exception #934 +* Fix setting vector:mag to a new value actually setting the magnitude to 1 #952 +* Fix electricity being consumed while the game was paused #526 +* Fix Part Resource string representation #1062 +* Fix UNLOCK inside brace statements #1048 #1051 +* Fix setting PHYSICS warp mode #989 +* Fix printing engine list duplication #1026, #1057 +* Fix terminal lockout when RemoteTech has no connection to the KSC, but the ship has local control. +* Fixed a crappy parser error that was causing `,` to do bizarre things to some code #925 +* Fix running an empty program resetting the parent #858 +* Fix some error printing related to nodes #905 +* Fix kOS processor sinking into launch pad #980 +* Fix `rename file` command #971 +* Fix `return` statement breaking closure #923 +* Fix docking port query #937 +* better expression support inside square brackets #935 +* you can now `LOCK` in a loop #954 +* the kOS toolbar button should be better behaved now +* Volume indexes will truncate floating values rather than throwing an error +* `LIST FILES IN` syntax now works for archive +* electricity consumption is better behaved +* setting the target to an empty string will always unset target + +# v0.17.2 1.0 Release ----------- @@ -14,29 +272,29 @@ kOS Mod Changelog ### Old and busted -* fixes keyword lexxing +* fixes keyword lexxing # v0.17.1 -Corrections and omissions +Corrections and omissions ------------------------- ### "New" features * Due to erendrake's inability to correctly use git. The new list constructor was omitted from the 0.17.0 release binaries. - + ### Bug Fixes: * Many Doc fixes * Fixed bug with setting KAC Alarm action to correct value -* Fixed some unneeded log spamming +* Fixed some unneeded log spamming # v0.17.0 FUNCTIONS! FUNCTIONS! FUNCTIONS! -------------------------------- -Big feature: You can make your own user-defined functions, that +Big feature: You can make your own user-defined functions, that can handle recursion, and can use local variable scoping. You can build a library of your own function calls and load them into your script. @@ -169,7 +427,7 @@ this fixes #603 the mess that I made of the Node structure, thanks Tabris from t caution to the wind, you can tell it to stop using loopback and use your real IP address. Be aware of the security risk if you choose this. * Added HUDTEXT that lets you add text to the screen. Thanks @pgodd ! - * more information here: http://ksp-kos.github.io/KOS_DOC/commands/terminal.html#HUDTEXT + * more information here: http://ksp-kos.github.io/KOS_DOC/commands/terminal.html#HUDTEXT * #72 - Added STAGE:NUMBER and STAGE:READY to allow for staging very close together * #522 - Added BODY:GEOPOSITIONOF and BODY:ALTITUDEOF for getting body-relative info about a 3D point in space. * #524 and #523 - mission waypoints now have 3d positions @@ -200,14 +458,14 @@ this fixes #603 the mess that I made of the Node structure, thanks Tabris from t ### New Features * (AGX) Action Groups Extended Support! Thanks @SirDiazo * Getting or setting groups 11-250 should behave the same as the stock groups if you have AGX installed. - * Groundwork is laid for getting parts and modules by the new action groups. + * Groundwork is laid for getting parts and modules by the new action groups. * Gimbals are now a well known module. providing read access to its state * Added PART:GETMODULEBYINDEX(int). This is most useful when you have a part with the same module twice. Thanks @jwvanderbeck * More documentation work. http://ksp-kos.github.io/KOS_DOC/ ### Bug Fixes * Fixes RemoteTech Integration -* Structures can now be correctly ==, <> and concatenated with + +* Structures can now be correctly ==, <> and concatenated with + * STAGE:RESOURCE[?]:CAPACITY is now spell correctly :P # v0.15.5 @@ -299,7 +557,7 @@ Please follow the links to see the full information on the new features. * Added suffixes to OBT for [walking orbit conic patches](http://ksp-kos.github.io/KOS_DOC/structure/orbit/index.html) * ORB:HASNEXTPATCH - A boolean that shows the presence of a future patch - * ORB:NEXTPATCH - The next OBT patch + * ORB:NEXTPATCH - The next OBT patch * Added better techniques for selecting the Part you want from a Vessel: * Ability to give any part any name you like with the [new nametag feature](http://ksp-kos.github.io/KOS_DOC/summary_topics/nametag/index.html). @@ -412,7 +670,7 @@ Please follow the links to see the full information on the new features. ~~~ * (WHEN and ON) Triggers that are taking longer than an Update is meant to take, and thus can freeze KSP are caught and reported (Github issue #104). Gives the user an explanatory message about the problem. * WARNING: Because of a change that had to be done for this, it is **_Highly_ recommended that you increase your *InstructionsPerUpdate* setting in config.xml to 150% as much** as it was before (i.e. from 100 to 150, or if it was 200, make it 300.). -* Multiple Terminal Windows - possible to have one open per CPU part. (Github issue #158) +* Multiple Terminal Windows - possible to have one open per CPU part. (Github issue #158) ![Multiple Windows!](https://github.com/KSP-KOS/KOS/blob/master/Docs/Images/MultiEdit.png) @@ -420,7 +678,7 @@ Please follow the links to see the full information on the new features. * "rename" was deleting files instead of moving them. (Github issue #220). * Was parsing array index brakets "[..]" incorrectly when they were on the lefthand side of an assignment. (Github issue #219) * SHIP:SENSORS were reading the wrong ship's sensors sometimes in multi-ship scenarios. (GIthub issue #218 ) -* Integer and Floating point numbers were not quite properly interchangable like they were meant to be. (Github issue #209) +* Integer and Floating point numbers were not quite properly interchangable like they were meant to be. (Github issue #209) # v0.13.1 @@ -429,7 +687,7 @@ Please follow the links to see the full information on the new features. # v0.13 ## MAJOR -* BREAKING: Commrange has more or less been removed from stock kOS, we realized that most of the behavior of it was copied by other mods and was invisible to users +* BREAKING: Commrange has more or less been removed from stock kOS, we realized that most of the behavior of it was copied by other mods and was invisible to users * BREAKING: All direction references are now relative to the controlling part, not the vessel, this will only break on vessels there these two directions are not the same. * BREAKING: Direction:Vector will always return a unit vector. * BREAKING: Body:Velocity now returns a pair of orbit/surface velocities just like Vessel:Velocity does. (previously it returned just the orbit velocity as a single vector.) @@ -441,7 +699,7 @@ Please follow the links to see the full information on the new features. ## New Features * Added the ability to get and set the current timewarp "Mode" either RAILS or PHYSICS -* Added Boot files that will run when you get to the pad automatically, you select which one will run in the VAB thanks @WazWaz +* Added Boot files that will run when you get to the pad automatically, you select which one will run in the VAB thanks @WazWaz * Vessels and Bodies now can be used interchangeably as much as possible. * Three new prediction routines for finding state of an object at a future time: * POSITIONAT( Object, Time ). @@ -449,14 +707,14 @@ Please follow the links to see the full information on the new features. * ORBITATAT( Object, Time ). * you can now get the FACING of all parts. * ITERATOR:END is now split into :NEXT and :ATEND -* Direction can now always return a proper vector. +* Direction can now always return a proper vector. * IE SHIP:FACING returned V(0,0,0) before -* Added a 3d Drawing tool for letting you draw lines and labels. +* Added a 3d Drawing tool for letting you draw lines and labels. * Tour: https://www.youtube.com/watch?v=Vn6lUozVUHA * Added a new and improved file editor so the edit command actually works again in game! * Added the ability to switch to MapView and back in code * ACTIVESHIP alias links to the ship that is currently under user direct control -* added GEOPOSITION suffixes BODY and TERRAINHEIGHT +* added GEOPOSITION suffixes BODY and TERRAINHEIGHT ## Known Issues @@ -467,7 +725,7 @@ Please follow the links to see the full information on the new features. * increased power requirement of the kOS Module * Bodies are now targetable * MAXTHRUST no longer includes flamed out engines -* resource floating values are now truncated to 2 significant digits to match the game UI and behavior +* resource floating values are now truncated to 2 significant digits to match the game UI and behavior * files saved to the local volume maintain their linebreaks * radar altimiter now returns a double * fixed an issues where setting some controls blocked the rest. @@ -489,7 +747,7 @@ BREAKING: DOCKINGPORT:ORIENTATION is now DOCKINGPORT:FACING * Fixed LOCK s in subprograms * Fixed RemoteTech integration blowing up everything * Fixed flight controls not releasing when they should -* Disabled RemoteTech Integration while RT development is stalled +* Disabled RemoteTech Integration while RT development is stalled * Fix exception when trying to type a multiline instruction in the interpreter * srfprograde is available as a new shortcut * BODY now has an OBT suffix @@ -510,7 +768,7 @@ BREAKING: DOCKINGPORT:ORIENTATION is now DOCKINGPORT:FACING * Added List square brackets [] as list subelement accessor * you can use variables as arguments for PRINT AT statements -This version adds a new 0.625m part. Thanks to SMA on this neat new addition. +This version adds a new 0.625m part. Thanks to SMA on this neat new addition. * it works as a kOS computer core * has 5000 units of code space * as a smaller part it is unlocked with "precision engineering" in career mode. @@ -518,13 +776,13 @@ This version adds a new 0.625m part. Thanks to SMA on this neat new addition. Bug fixes -* Cannot "set" a variable that later will become a "lock" #13 -* Sanitize values sent to KSP #14 -* Strange order of operations: "and" seems to evaluate before ">" #20 +* Cannot "set" a variable that later will become a "lock" #13 +* Sanitize values sent to KSP #14 +* Strange order of operations: "and" seems to evaluate before ">" #20 * moved some names back to "kOS" * Work on some structure's ToString return. * Parameters now get passed in the correct order -* Ship resources no longer generate an error if they arent present +* Ship resources no longer generate an error if they arent present * Ctrl+C now interrupts correctly once again. * ETA:TRANSITION returns the correct time. * Better handling of types. @@ -567,7 +825,7 @@ Bug fixes * TOP - Translation (1 to -1) * ROTATION - Vector * TRANSLATION - Vector - * NEUTRAL - bool, + * NEUTRAL - bool, * MAINTHROTTLE (1 to -1) * WHEELTHROTTLE (1 to -1) * WHEELSTEER (1 to -1) @@ -580,26 +838,26 @@ Bug fixes * TOP - Translation (1 to -1) * ROTATION - Vector * TRANSLATION - Vector - * NEUTRALIZE - bool, releases vessel control, + * NEUTRALIZE - bool, releases vessel control, * MAINTHROTTLE (1 to -1) * WHEELTHROTTLE (1 to -1) * WHEELSTEER (1 to -1) -* changing systems vessel load distance +* changing systems vessel load distance * LOADDISTANCE get/set for adjusting load distance for every vessel * VESSELTARGET:LOAD bool - is the vessel loaded * VESSELTARGET:PACKDISTANCE - Setter for pack distance for every vessel. * Added RANDOM() generator (0 - 1) -* Power requirements are now directly tied to the active volume's size, the ARCHIVE's size is unlimited so it is capped at the equivalent of 50KB. +* Power requirements are now directly tied to the active volume's size, the ARCHIVE's size is unlimited so it is capped at the equivalent of 50KB. ### 0.11.0 -- Thanks to enkido and jwvanderbeck for your help. +- Thanks to enkido and jwvanderbeck for your help. - BREAKING: BODY, SHIP:BODY, TARGET:BODY now all return a Body structure rather than the name of the body - BREAKING: Removed NODE:APOAPSIS and NODE:PERIAPSIS. They are now available in NODE:ORBIT:APOAPSIS -- Basic RemoveTech Intergration +- Basic RemoveTech Intergration - Added VOLUME:NAME to getting the current volume - Lists can now be populated with basic data that you can loop over or index [Full Info](/wiki/List/) - Bodies (eg Kerbin, Mun, Duna) @@ -617,7 +875,7 @@ Bug fixes ### 0.10.0 - Compatible with KSP 0.23 Thanks to Logris and MaHuJa for Commits -- Added List() which creates a collection and the following commands +- Added List() which creates a collection and the following commands - ADD - Adds the value of any variable - CONTAINS - Tests and returns if the value exists in the list - REMOVE - removes the item from the list if the list contains the item @@ -640,19 +898,19 @@ Bug fixes - Adding a few BODY members - RADIUS - MU - G * Body Mass - - G - Gravitational Constant + - G - Gravitational Constant - ATM atmosphere info with sub elements - EXISTS - HASOXYGEN - SCALE - HEIGHT - + - Added ORBIT to NODE - Added the following commands - UNSET #VARIABLE - remove the variable, ALL removes all variables Thanks a1070 - FOR #USERVARIABLE IN #LIST takes a list and loops over it, exposing each item in the collection as a user defined variable - New close window action binding -- Performance fixes +- Performance fixes ### 0.9.2 @@ -791,11 +1049,11 @@ Bug fixes ### 0.3 -- Support for loops +- Support for loops - Support for the IF statement - Support for the BREAK statement -### 0.2 +### 0.2 - Initial public release! - Execution system redesigned to be more heirarchical diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5a5fe2360..41ea0c071 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,2 +1,32 @@ +Pull Requests +============= + * All PRs must be related to an open issue * If a PR changes the scripting API, it must include all related changes to the documentation. + +Setting Up Your Environment +=========================== + +1. Copy `Resources/GameData/kOS` to `$KSP/GameData/`, `where $KSP` is your + Kerbal Space Program installation directory. + +2. Download the latest KSPAPIExtensions.dll from + https://github.com/Swamp-Ig/KSPAPIExtensions/releases, and copy + it to `$KSP/GameData/kOS/Plugins`. + +3. Create a file at src/kOS/kOS.csproj.user conaining the following XML, + replacing /path/to/KSP with your own KSP install directory. + + + + + + /path/to/KSP/KSP_Data/Managed; + /path/to/KSP/GameData/kOS/Plugins + + + + +4. If you want building the solution to update the dlls in your KSP + directory, create a symbolic link called `KSPdirlink` from the root + of this repository to your KSP installation directory. diff --git a/README.md b/README.md index 3d70c3b11..1fe61a6fc 100644 --- a/README.md +++ b/README.md @@ -9,3 +9,4 @@ Addon release thread: http://forum.kerbalspaceprogram.com/threads/68089-0-23-kOS Addon development thread: http://forum.kerbalspaceprogram.com/threads/68096-kOS-Autopilot +Contribution : If you have contributed to the development of the mod, and wish to be named a certain way in the next release notes, then add your edit to the ``### Contributors`` section of the CHANGELOG.md file in your pull request. diff --git a/RELEASECHECKLIST.md b/RELEASECHECKLIST.md index f11c1b600..fadd5379a 100644 --- a/RELEASECHECKLIST.md +++ b/RELEASECHECKLIST.md @@ -1,7 +1,6 @@ # This is a precursor to an automated build system ### Pre-Build -* Update the kOS.Core.cs VersionInfo * Update AssemblyInfo for kOS project * Update AssemblyInfo for kOS.Safe project * Update Resources\GameData\kOS\kOS.version @@ -10,7 +9,7 @@ ### Build * Build kOS solution in release mode -* Copy kOS.dll and kOS.Safe.dll to \Resources\GameData\kOS\Plugins\ +* Ensure that all required resources are in place (ie KSP API Extensions DLL, ModuleManager DLL) * Create zip file with a root starting in the \Resources\ directory * Name the zip file with the following pattern kOS.v...zip (eg kOS.v0.14.2.zip ) * Build the documentation in \docs\ diff --git a/Resources/GameData/kOS/GFX/brightness-button.png b/Resources/GameData/kOS/GFX/brightness-button.png new file mode 100644 index 000000000..10ef08fb6 Binary files /dev/null and b/Resources/GameData/kOS/GFX/brightness-button.png differ diff --git a/Resources/GameData/kOS/GFX/error.wav b/Resources/GameData/kOS/GFX/error.wav new file mode 100644 index 000000000..7dc81bdd0 Binary files /dev/null and b/Resources/GameData/kOS/GFX/error.wav differ diff --git a/Resources/GameData/kOS/GFX/font-height-button.png b/Resources/GameData/kOS/GFX/font-height-button.png new file mode 100644 index 000000000..b17ad735f Binary files /dev/null and b/Resources/GameData/kOS/GFX/font-height-button.png differ diff --git a/Resources/GameData/kOS/GFX/font-width-button.png b/Resources/GameData/kOS/GFX/font-width-button.png new file mode 100644 index 000000000..f72acdb14 Binary files /dev/null and b/Resources/GameData/kOS/GFX/font-width-button.png differ diff --git a/Resources/GameData/kOS/GFX/monitor_minimal_frame.png b/Resources/GameData/kOS/GFX/monitor_minimal_frame.png new file mode 100644 index 000000000..7ac64931f Binary files /dev/null and b/Resources/GameData/kOS/GFX/monitor_minimal_frame.png differ diff --git a/Resources/GameData/kOS/GFX/monitor_minimal_frame_active.png b/Resources/GameData/kOS/GFX/monitor_minimal_frame_active.png new file mode 100644 index 000000000..3496bf89a Binary files /dev/null and b/Resources/GameData/kOS/GFX/monitor_minimal_frame_active.png differ diff --git a/Resources/GameData/kOS/GFX/terminal-beep.wav b/Resources/GameData/kOS/GFX/terminal-beep.wav new file mode 100644 index 000000000..11e0901bf Binary files /dev/null and b/Resources/GameData/kOS/GFX/terminal-beep.wav differ diff --git a/Resources/GameData/kOS/GFX/terminal-click.wav b/Resources/GameData/kOS/GFX/terminal-click.wav new file mode 100644 index 000000000..5112203cd Binary files /dev/null and b/Resources/GameData/kOS/GFX/terminal-click.wav differ diff --git a/Resources/GameData/kOS/Parts/KOSCherryLight/Cherrylight.mu b/Resources/GameData/kOS/Parts/KOSCherryLight/Cherrylight.mu new file mode 100644 index 000000000..736519a93 Binary files /dev/null and b/Resources/GameData/kOS/Parts/KOSCherryLight/Cherrylight.mu differ diff --git a/Resources/GameData/kOS/Parts/KOSCherryLight/Metal_Silver.mbm b/Resources/GameData/kOS/Parts/KOSCherryLight/Metal_Silver.mbm new file mode 100644 index 000000000..288a01e01 Binary files /dev/null and b/Resources/GameData/kOS/Parts/KOSCherryLight/Metal_Silver.mbm differ diff --git a/Resources/GameData/kOS/Parts/KOSCherryLight/dirty aluminum.mbm b/Resources/GameData/kOS/Parts/KOSCherryLight/dirty aluminum.mbm new file mode 100644 index 000000000..e155873ea Binary files /dev/null and b/Resources/GameData/kOS/Parts/KOSCherryLight/dirty aluminum.mbm differ diff --git a/Resources/GameData/kOS/Parts/KOSCherryLight/part.cfg b/Resources/GameData/kOS/Parts/KOSCherryLight/part.cfg new file mode 100644 index 000000000..9c4a1db3e --- /dev/null +++ b/Resources/GameData/kOS/Parts/KOSCherryLight/part.cfg @@ -0,0 +1,44 @@ +PART +{ + + name = Cherry Light + module = Part + author = Peter Goddard (pgodd) and Brad White (hvacengi) + mesh = model/cherrylight.mu + scale = 1 + rescaleFactor = 1 + node_stack_bottom = 0, -0.01, 0, 0, -90, 0, 0 + node_attach = 0.0, -0.01, 0.0, 0, -90, 0, 0 + TechRequired = advElectrics + cost = 500 + entryCost = 1200 + category = Utility + subcategory = 0 + title = Cherry Light + manufacturer = kOS Peripherals + description = Watch out! It's the coppers! Fool your friends, be the life of the party with our simulated police style light. Not for use by real police. + attachRules = 1,1,0,0,0 + mass = 0.001 + dragModelType = default + maximum_drag = .002 + minimum_drag = .002 + angularDrag = 2 + crashTolerance = 9 + maxTemp = 2400 + MODULE + { + name = ModuleLight + lightName = PowerLight + isOn = true + lightR = 0.5 + lightG = 0 + lightB = 0 + } + MODULE + { + name = kOSLightModule + resourceAmount = 0.02 + animationName = Rotation + } + +} diff --git a/Resources/GameData/kOS/Parts/kOSMachine0m/KR-2042_uv_layout_1_EMIS.mbm b/Resources/GameData/kOS/Parts/kOSMachine0m/KR-2042_uv_layout_1_EMIS.mbm index 294e13f18..c858c1db7 100644 Binary files a/Resources/GameData/kOS/Parts/kOSMachine0m/KR-2042_uv_layout_1_EMIS.mbm and b/Resources/GameData/kOS/Parts/kOSMachine0m/KR-2042_uv_layout_1_EMIS.mbm differ diff --git a/Resources/GameData/kOS/Parts/kOSMachine0m/KR-2042_uv_layout_1_d_NRM.mbm b/Resources/GameData/kOS/Parts/kOSMachine0m/KR-2042_uv_layout_1_d_NRM.mbm old mode 100644 new mode 100755 index 680de75b1..0511d03d8 Binary files a/Resources/GameData/kOS/Parts/kOSMachine0m/KR-2042_uv_layout_1_d_NRM.mbm and b/Resources/GameData/kOS/Parts/kOSMachine0m/KR-2042_uv_layout_1_d_NRM.mbm differ diff --git a/Resources/GameData/kOS/Parts/kOSMachine0m/KR-2042_uv_layout_d.mbm b/Resources/GameData/kOS/Parts/kOSMachine0m/KR-2042_uv_layout_d.mbm old mode 100644 new mode 100755 index 57a12f292..e496380dc Binary files a/Resources/GameData/kOS/Parts/kOSMachine0m/KR-2042_uv_layout_d.mbm and b/Resources/GameData/kOS/Parts/kOSMachine0m/KR-2042_uv_layout_d.mbm differ diff --git a/Resources/GameData/kOS/Parts/kOSMachine0m/model.mu b/Resources/GameData/kOS/Parts/kOSMachine0m/model.mu index b0cbcac24..b7fd6a978 100644 Binary files a/Resources/GameData/kOS/Parts/kOSMachine0m/model.mu and b/Resources/GameData/kOS/Parts/kOSMachine0m/model.mu differ diff --git a/Resources/GameData/kOS/Parts/kOSMachine0m/part.cfg b/Resources/GameData/kOS/Parts/kOSMachine0m/part.cfg old mode 100644 new mode 100755 index 4b29b640b..08ca110c9 --- a/Resources/GameData/kOS/Parts/kOSMachine0m/part.cfg +++ b/Resources/GameData/kOS/Parts/kOSMachine0m/part.cfg @@ -1,9 +1,9 @@ PART { // --- general parameters --- -name = kOSMachine0m +name = KR-2042 module = Part -author = SMA +author = SMA and Peter Goddard // --- asset parameters --- mesh = model/model.mu @@ -12,8 +12,8 @@ rescaleFactor = 1 // --- node definitions --- // definition format is Position X, Position Y, Position Z, Up X, Up Y, Up Z, connector node size -node_stack_bottom = 0.0, -0.0566, 0.0, 0.0, 1.0, 0.0, 0 -node_stack_top = 0.0, 0.0466, 0.0, 0.0, 1.0, 0.0, 0 +node_stack_bottom = 0.0, -0.081, 0.0, 0.0, -1.0, 0.0, 0 +node_stack_top = 0.0, -0.003, 0.0, 0.0, 1.0, 0.0, 0 // --- Tech tree --- @@ -29,7 +29,7 @@ manufacturer = Compotronix description = Would you trust life and limb to a mindless autopilot, powered by untested software you hastily wrote yourself? Spacefaring kerbals would! // attachment rules: stack, srfAttach, allowStack, allowSrfAttach, allowCollision -attachRules = 1,0,1,1,1 +attachRules = 1,0,1,0,0 // --- standard part parameters --- mass = 0.08 @@ -44,6 +44,8 @@ MODULE { name = kOSProcessor diskSpace = 5000 + ECPerBytePerSecond = 0 + ECPerInstruction = 0.000004 } RESOURCE @@ -57,15 +59,17 @@ MODULE { name = ModuleLight lightName = PowerLight - useAnimationDim = true - lightBrightenSpeed = 4 - lightDimSpeed = 4 - resourceAmount = 0.01 - animationName = PowerLight - useResources = true - startEventGUIName = "Power Off" - endEventGUIName = "Power On" + lightR = 0 + lightG = 0.1 + lightB = 0 } +MODULE +{ + name = kOSLightModule + resourceAmount = 0.02 + animationName = flickerStart +} -} \ No newline at end of file + +} diff --git a/Resources/GameData/kOS/Parts/kOSMachine0mLegacy/KR-2042_uv_layout_1_EMIS.mbm b/Resources/GameData/kOS/Parts/kOSMachine0mLegacy/KR-2042_uv_layout_1_EMIS.mbm new file mode 100644 index 000000000..02250eb61 Binary files /dev/null and b/Resources/GameData/kOS/Parts/kOSMachine0mLegacy/KR-2042_uv_layout_1_EMIS.mbm differ diff --git a/Resources/GameData/kOS/Parts/kOSMachine0mLegacy/KR-2042_uv_layout_1_d_NRM.mbm b/Resources/GameData/kOS/Parts/kOSMachine0mLegacy/KR-2042_uv_layout_1_d_NRM.mbm new file mode 100644 index 000000000..0511d03d8 Binary files /dev/null and b/Resources/GameData/kOS/Parts/kOSMachine0mLegacy/KR-2042_uv_layout_1_d_NRM.mbm differ diff --git a/Resources/GameData/kOS/Parts/kOSMachine0mLegacy/KR-2042_uv_layout_d.mbm b/Resources/GameData/kOS/Parts/kOSMachine0mLegacy/KR-2042_uv_layout_d.mbm new file mode 100644 index 000000000..a4b5a062f Binary files /dev/null and b/Resources/GameData/kOS/Parts/kOSMachine0mLegacy/KR-2042_uv_layout_d.mbm differ diff --git a/Resources/GameData/kOS/Parts/kOSMachine0mLegacy/model.mu b/Resources/GameData/kOS/Parts/kOSMachine0mLegacy/model.mu new file mode 100644 index 000000000..b6e63e26d Binary files /dev/null and b/Resources/GameData/kOS/Parts/kOSMachine0mLegacy/model.mu differ diff --git a/Resources/GameData/kOS/Parts/kOSMachine0mLegacy/part.cfg b/Resources/GameData/kOS/Parts/kOSMachine0mLegacy/part.cfg new file mode 100644 index 000000000..7d1fd2924 --- /dev/null +++ b/Resources/GameData/kOS/Parts/kOSMachine0mLegacy/part.cfg @@ -0,0 +1,71 @@ +PART +{ +// --- general parameters --- +name = kOSMachine0m +module = Part +author = SMA and Peter Goddard + +// --- asset parameters --- +mesh = model/model.mu +scale = 1 +rescaleFactor = 1 + +// --- node definitions --- +// definition format is Position X, Position Y, Position Z, Up X, Up Y, Up Z, connector node size +node_stack_bottom = 0.0, -0.04, 0.0, 0.0, -1.0, 0.0, 0 +node_stack_top = 0.0, 0.03, 0.0, 0.0, 1.0, 0.0, 0 + + +// --- Tech tree --- +TechRequired = precisionEngineering + +// --- editor parameters --- +cost = 1200 +entryCost = 6800 +category = -1 +subcategory = 0 +title = KR-2042 b Scriptable Control System +manufacturer = Compotronix +description = Would you trust life and limb to a mindless autopilot, powered by untested software you hastily wrote yourself? Spacefaring kerbals would! + +// attachment rules: stack, srfAttach, allowStack, allowSrfAttach, allowCollision +attachRules = 1,0,1,1,0 + +// --- standard part parameters --- +mass = 0.08 +dragModelType = default +maximum_drag = 0.2 +minimum_drag = 0.2 +angularDrag = 2 +crashTolerance = 9 +maxTemp = 3400 + +MODULE +{ + name = kOSProcessor + diskSpace = 5000 +} + +RESOURCE +{ + name = ElectricCharge + amount = 5 + maxAmount = 5 +} + +MODULE +{ + name = ModuleLight + lightName = PowerLight + useAnimationDim = true + lightBrightenSpeed = 8 + lightDimSpeed = 4 + resourceAmount = 0.01 + animationName = PowerLight + useResources = true + startEventGUIName = "Power Off" + endEventGUIName = "Power On" +} + + +} diff --git a/Resources/GameData/kOS/Parts/kOSMachine1m/model.mu b/Resources/GameData/kOS/Parts/kOSMachine1m/model.mu old mode 100644 new mode 100755 index 54bb0f434..111c8ae8f Binary files a/Resources/GameData/kOS/Parts/kOSMachine1m/model.mu and b/Resources/GameData/kOS/Parts/kOSMachine1m/model.mu differ diff --git a/Resources/GameData/kOS/Parts/kOSMachine1m/model001.mbm b/Resources/GameData/kOS/Parts/kOSMachine1m/model001.mbm deleted file mode 100644 index 337f39893..000000000 Binary files a/Resources/GameData/kOS/Parts/kOSMachine1m/model001.mbm and /dev/null differ diff --git a/Resources/GameData/kOS/Parts/kOSMachine1m/model000.mbm b/Resources/GameData/kOS/Parts/kOSMachine1m/model002.mbm old mode 100644 new mode 100755 similarity index 86% rename from Resources/GameData/kOS/Parts/kOSMachine1m/model000.mbm rename to Resources/GameData/kOS/Parts/kOSMachine1m/model002.mbm index a2196892f..9f79a976a Binary files a/Resources/GameData/kOS/Parts/kOSMachine1m/model000.mbm and b/Resources/GameData/kOS/Parts/kOSMachine1m/model002.mbm differ diff --git a/Resources/GameData/kOS/Parts/kOSMachine1m/part.cfg b/Resources/GameData/kOS/Parts/kOSMachine1m/part.cfg old mode 100644 new mode 100755 index fa8a0c5bd..078ea9b44 --- a/Resources/GameData/kOS/Parts/kOSMachine1m/part.cfg +++ b/Resources/GameData/kOS/Parts/kOSMachine1m/part.cfg @@ -1,9 +1,9 @@ PART { -// --- general parameters --- +// --- general parameters --- V2~ fixed collision mesh name = kOSMachine1m module = Part -author = KevinLaity +author = KevinLaity / Peter Goddard // --- asset parameters --- mesh = model/model.mu @@ -44,6 +44,8 @@ MODULE { name = kOSProcessor diskSpace = 10000 + ECPerBytePerSecond = 0 + ECPerInstruction = 0.000004 } RESOURCE diff --git a/Resources/GameData/kOS/Parts/kOSMachineRad/Model.mu b/Resources/GameData/kOS/Parts/kOSMachineRad/Model.mu old mode 100644 new mode 100755 index 4c23dbd54..9a65fa250 Binary files a/Resources/GameData/kOS/Parts/kOSMachineRad/Model.mu and b/Resources/GameData/kOS/Parts/kOSMachineRad/Model.mu differ diff --git a/Resources/GameData/kOS/Parts/kOSMachineRad/colorTexture.mbm b/Resources/GameData/kOS/Parts/kOSMachineRad/colorTexture.mbm old mode 100644 new mode 100755 diff --git a/Resources/GameData/kOS/Parts/kOSMachineRad/part.cfg b/Resources/GameData/kOS/Parts/kOSMachineRad/part.cfg index c4f313189..149e764f5 100755 --- a/Resources/GameData/kOS/Parts/kOSMachineRad/part.cfg +++ b/Resources/GameData/kOS/Parts/kOSMachineRad/part.cfg @@ -1,71 +1,73 @@ -PART -{ -// --- general parameters --- -name = kOSMachineRad -module = Part -author = Peter Goddard - -// --- asset parameters --- -mesh = model/model.mu -scale = 1 -rescaleFactor = 0.99999999999 -iconCenter = 0, 0, 0 - -// --- node definitions --- -node_attach = 0.0, 0.0, 0.0, 1, 0, 0 - -// --- Tech tree --- -TechRequired = unmannedTech - -// --- editor parameters --- -cost = 2200 -entryCost = 4200 -category = Control -subcategory = 0 -title = CompoMax Radial Tubeless -manufacturer = Squalid-State Devices Inc. -description = Would you trust life and limb to a mindless autopilot, powered by untested software you hastily wrote yourself? Spacefaring kerbals would! - -// attachment rules: stack, srfAttach, allowStack, allowSrfAttach, allowCollision -attachRules = 0,1,0,0,1 - -// --- standard part parameters --- -mass = 0.03 -dragModelType = default -maximum_drag = 0.0 -minimum_drag = 0.0 -angularDrag = 0 -crashTolerance = 6 -maxTemp = 3400 - - -MODULE -{ - name = kOSProcessor - diskSpace = 60000 -} -MODULE -{ - name = ModuleDeployableSolarPanel - sunTracking = false - raycastTransformName = suncatcher - pivotName = suncatcher - isBreakable = false - resourceName = ElectricCharge - chargeRate = 0.5 - powerCurve - { - key = 206000000000 0 0 0 - key = 13599840256 1 0 0 - key = 68773560320 0.5 0 0 - key = 0 10 0 0 - } -} -} -RESOURCE -{ - name = ElectricCharge - amount = 10 - maxAmount = 10 -} -} +PART +{ +// --- general parameters --- +name = kOSMachineRad +module = Part +author = Peter Goddard + +// --- asset parameters --- +mesh = model/model.mu +scale = 1 +rescaleFactor = 1 +iconCenter = 0, 0, 0 + +// --- node definitions --- +node_attach = 0.0, 0.0, 0.0, 1, 0, 0 + +// --- Tech tree --- +TechRequired = unmannedTech + +// --- editor parameters --- +cost = 2200 +entryCost = 4200 +category = Control +subcategory = 0 +title = CompoMax Radial Tubeless +manufacturer = Squalid-State Devices Inc. +description = Would you trust life and limb to a mindless autopilot, powered by untested software you hastily wrote yourself? Spacefaring kerbals would! + +// attachment rules: stack, srfAttach, allowStack, allowSrfAttach, allowCollision +attachRules = 0,1,0,0,1 + +// --- standard part parameters --- +mass = 0.03 +dragModelType = default +maximum_drag = 0.0 +minimum_drag = 0.0 +angularDrag = 0 +crashTolerance = 6 +maxTemp = 3400 + + +MODULE +{ + name = kOSProcessor + diskSpace = 60000 + ECPerBytePerSecond = 0 + ECPerInstruction = 0.000004 +} +MODULE +{ + name = ModuleDeployableSolarPanel + sunTracking = false + raycastTransformName = suncatcher + pivotName = suncatcher + isBreakable = false + resourceName = ElectricCharge + chargeRate = 0.5 + powerCurve + { + key = 206000000000 0 0 0 + key = 13599840256 1 0 0 + key = 68773560320 0.5 0 0 + key = 0 10 0 0 + } +} +} +RESOURCE +{ + name = ElectricCharge + amount = 10 + maxAmount = 10 +} +} diff --git a/Resources/GameData/kOS/Parts/kOSkal9000/kal9000.mbm b/Resources/GameData/kOS/Parts/kOSkal9000/kal9000.mbm new file mode 100644 index 000000000..8da51e9ac Binary files /dev/null and b/Resources/GameData/kOS/Parts/kOSkal9000/kal9000.mbm differ diff --git a/Resources/GameData/kOS/Parts/kOSkal9000/kal9000back.mbm b/Resources/GameData/kOS/Parts/kOSkal9000/kal9000back.mbm new file mode 100644 index 000000000..021066a02 Binary files /dev/null and b/Resources/GameData/kOS/Parts/kOSkal9000/kal9000back.mbm differ diff --git a/Resources/GameData/kOS/Parts/kOSkal9000/kal9000eye.mbm b/Resources/GameData/kOS/Parts/kOSkal9000/kal9000eye.mbm new file mode 100644 index 000000000..9ca359503 Binary files /dev/null and b/Resources/GameData/kOS/Parts/kOSkal9000/kal9000eye.mbm differ diff --git a/Resources/GameData/kOS/Parts/kOSkal9000/model.mu b/Resources/GameData/kOS/Parts/kOSkal9000/model.mu new file mode 100644 index 000000000..d47a6b3f0 Binary files /dev/null and b/Resources/GameData/kOS/Parts/kOSkal9000/model.mu differ diff --git a/Resources/GameData/kOS/Parts/kOSkal9000/part.cfg b/Resources/GameData/kOS/Parts/kOSkal9000/part.cfg new file mode 100644 index 000000000..e8000c891 --- /dev/null +++ b/Resources/GameData/kOS/Parts/kOSkal9000/part.cfg @@ -0,0 +1,60 @@ +PART +{ +// --- general parameters --- +name = KAL9000 +module = Part +author = Peter Goddard and kOS Crew + +// --- asset parameters --- +mesh = model/model.mu +scale = 1 +rescaleFactor = 1 + +// --- node definitions --- +node_attach = 0.01, 0.0, 0.0, 1, 0, 0, 0 + +// --- Tech tree --- +TechRequired = automation + +// --- editor parameters --- +cost = 1200 +entryCost = 6800 +category = Control +subcategory = 0 +title = KAL9000 Scriptable Control System +manufacturer = Squalid State Devices +description = Mildly Malevolent artificial entity, use caution on EVA's + +// attachment rules: stack, srfAttach, allowStack, allowSrfAttach, allowCollision +attachRules = 0,1,0,0,0 + +// --- standard part parameters --- +mass = 0.0005 +dragModelType = default +maximum_drag = 0 +minimum_drag = 0 +angularDrag = 0 +crashTolerance = 9 +maxTemp = 3400 + +MODULE +{ + name = kOSProcessor + diskSpace = 255000 +} +MODULE +{ + name = ModuleLight + lightName = PowerLight + lightR = 0.5 + lightG = 0 + lightB = 0 +} + +MODULE +{ + name = kOSLightModule + resourceAmount = 0.02 + animationName = KAL9000Lives +} +} diff --git a/Resources/GameData/kOS/kOS.ckan b/Resources/GameData/kOS/kOS.ckan deleted file mode 100644 index 5803fa6bf..000000000 --- a/Resources/GameData/kOS/kOS.ckan +++ /dev/null @@ -1,34 +0,0 @@ -{ - "spec_version" : 1, - "identifier" : "kOS", - "$kref" : "#/ckan/kerbalstuff", - "license" : "GPL-3.0", - "release_status" : "stable", - "resources" : { - "manual" : "http://ksp-kos.github.io/KOS_DOC/", - "github" : { - "url" : "https://github.com/KSP-KOS/KOS", - "releases" : true - } - }, - "install" : [ - { - "file" : "GameData/kOS", - "install_to" : "GameData" - } - ], - "recommends": [ - { - "name": "ModuleManager", - "min_version": "2.5.6", - "comment": "Earlier versions of MM have forward compatibility problems, according to the MM release notes." - } - ], - "suggests": [ - { - "name": "RemoteTech", - "min_version": "1.5.1", - "comment": "RT gives incentive to having local control of craft, even unmanned ones" - } - ], -} diff --git a/Resources/GameData/kOS/kOS.version b/Resources/GameData/kOS/kOS.version index ead55c775..2cbbf45ae 100644 --- a/Resources/GameData/kOS/kOS.version +++ b/Resources/GameData/kOS/kOS.version @@ -1,8 +1,8 @@ { "NAME": "kOS", "URL": "https://raw.githubusercontent.com/KSP-KOS/KOS/master/Resources/GameData/kOS/kOS.version", - "DOWNLOAD":"TODO - when release..." - "CHANGE_LOG_URL":"https://raw.githubusercontent.com/KSP-KOS/KOS/master/CHANGELOG.md", + "DOWNLOAD": "TODO - when release...", + "CHANGE_LOG_URL": "https://raw.githubusercontent.com/KSP-KOS/KOS/master/CHANGELOG.md", "GITHUB": { "USERNAME":"KSP-KOS", "REPOSITORY":"KOS", @@ -10,22 +10,22 @@ }, "VERSION": { "MAJOR": 0, - "MINOR": 17, - "PATCH": 2 + "MINOR": 19, + "PATCH": 1 }, "KSP_VERSION": { - "MAJOR": 0, - "MINOR": 90, - "PATCH": 0 - } + "MAJOR": 1, + "MINOR": 0, + "PATCH": 5 + }, "KSP_VERSION_MIN": { - "MAJOR": 0, - "MINOR": 90, - "PATCH": 0 + "MAJOR": 1, + "MINOR": 0, + "PATCH": 4 }, "KSP_VERSION_MAX": { - "MAJOR": 0, - "MINOR": 90, + "MAJOR": 1, + "MINOR": 0, "PATCH": 99 } } diff --git a/doc/KerboscriptLexer.py b/doc/KerboscriptLexer.py new file mode 100644 index 000000000..09db02720 --- /dev/null +++ b/doc/KerboscriptLexer.py @@ -0,0 +1,69 @@ +# +# File used for syntax-highlighting code sections in the documentation. +# + +import re + +from pygments.lexer import RegexLexer, include, bygroups, using, \ + this, inherit, default, words +from pygments.util import get_bool_opt +from pygments.token import Text, Comment, Operator, Keyword, Name, String, \ + Number, Punctuation, Error + +class KerboscriptLexer(RegexLexer): + + name = 'Kerboscript' + aliases = ['kerboscript'] + filenames = ['*.ks'] + # mimetypes = ['text/somethinghere'] # We don't have a kerboscript mime type (yet?) + + flags = re.MULTILINE | re.DOTALL | re.IGNORECASE + + __all__ = ['KerboscriptLexer'] + + tokens = { + # + # See http://pygments.org/docs/tokens/ for a list of parts of speech + # to assign things to in this list + # + 'root': [ + # + # Note: Precedence in a tie is to pick the one that + # came earlier in this list. + # + # Warning: In my experimentation I found that if a rule is + # present in the list below where a string of zero length + # matches the regex, this causes Pygment to just get stuck + # in an infinite loop. + # For example, if the whitespace regex was: + # [\t\s\r\n]* + # Instead of : + # [\t\s\r\n]+ + # Then zero chars would be a valid match. So + # Pygment matches the rule without advancing + # any further into the input, and just gets + # stuck doing that forever. + # + (r'//[^\r\n]*[\r\n]', Comment.Single), + (r'"[^"]*"', String), + (r'[\t\s\r\n]+', Text), #whitespace + (r'[*/+|?<>=#^\-]', Operator), + (r'\b(to|is|not|and|or|all)\b', Operator.Word), + (r'[()\[\]\.,:\{\}@]', Punctuation), + (words(( 'set', 'if', 'else', 'until', 'step', 'do', + 'lock', 'unlock', 'print', 'at', 'toggle', 'wait', + 'when', 'then', 'stage', 'clearscreen', 'add', 'remove', + 'log', 'break', 'preserve', 'declare', 'defined', 'local', + 'global', 'return', 'switch', 'copy', 'from', 'rename', + 'volume', 'file', 'delete', 'edit', 'run', 'once', 'compile', + 'list', 'reboot', 'shutdown', 'for', 'unset'), suffix=r'\b'), Keyword), + (r'\b(declare|local|global|parameter|function)\b', Keyword.Declaration), + (r'\b(true|false|on|off)\b', Name.Builtin), + (r'\b[a-z_][a-z_\d]*\b', Name.Variable), # TODO - we could differentiate type of name: i.e. built-in vs user. + (r'\b(\d+\.\d*|\.\d+|\d+)[eE][+-]?\d+\b', Number.Float), + (r'\b(\d+)+\b', Number.Float), # markup ints just like floats + ] + } + +def setup(app): + app.add_lexer("kerboscript", KerboscriptLexer()) diff --git a/doc/source/_images/general/disk_space_slider.png b/doc/source/_images/general/disk_space_slider.png new file mode 100644 index 000000000..c9beaade2 Binary files /dev/null and b/doc/source/_images/general/disk_space_slider.png differ diff --git a/doc/source/_images/kos_logo.png b/doc/source/_images/kos_logo.png new file mode 100644 index 000000000..35b9db752 Binary files /dev/null and b/doc/source/_images/kos_logo.png differ diff --git a/doc/source/_images/kos_logo_small.png b/doc/source/_images/kos_logo_small.png new file mode 100644 index 000000000..8eed4bfe6 Binary files /dev/null and b/doc/source/_images/kos_logo_small.png differ diff --git a/doc/source/_images/tutorials/quickstart/MyFirstRocket.craft b/doc/source/_images/tutorials/quickstart/MyFirstRocket.craft new file mode 100644 index 000000000..fc446acad --- /dev/null +++ b/doc/source/_images/tutorials/quickstart/MyFirstRocket.craft @@ -0,0 +1,2200 @@ +ship = My First Rocket +version = 1.0.4 +description = +type = VAB +size = 3.127958,17.63077,4.510109 +PART +{ + part = probeStackSmall_4287645852 + partName = Part + pos = 0,15,0 + attPos = 0,0,0 + attPos0 = 0,15,0 + rot = 0,0,0,1 + attRot = 0,0,0,1 + attRot0 = 0,0,0,1 + mir = 1,1,1 + symMethod = Radial + istg = 0 + dstg = 0 + sidx = -1 + sqor = -1 + sepI = 0 + attm = 0 + modCost = 0 + modMass = 0 + modSize = (0.0, 0.0, 0.0) + link = noseCone_4287640986 + link = kOSMachine1m_4294064856 + attN = bottom,kOSMachine1m_4294064856 + attN = top,noseCone_4287640986 + EVENTS + { + } + ACTIONS + { + } + PARTDATA + { + } + MODULE + { + name = ModuleCommand + isEnabled = True + controlSrcStatusText = + EVENTS + { + MakeReference + { + active = True + guiActive = True + guiIcon = Control From Here + guiName = Control From Here + category = Control From Here + guiActiveUnfocused = False + unfocusedRange = 2 + externalToEVAOnly = True + } + RenameVessel + { + active = True + guiActive = True + guiIcon = Rename Vessel + guiName = Rename Vessel + category = Rename Vessel + guiActiveUnfocused = False + unfocusedRange = 2 + externalToEVAOnly = True + } + } + ACTIONS + { + } + } + MODULE + { + name = ModuleReactionWheel + isEnabled = True + stateString = Active + WheelState = Active + EVENTS + { + OnToggle + { + active = True + guiActive = True + guiActiveEditor = True + guiIcon = Toggle Torque + guiName = Toggle Torque + category = Toggle Torque + guiActiveUnfocused = False + unfocusedRange = 2 + externalToEVAOnly = True + } + } + ACTIONS + { + Activate + { + actionGroup = None + } + Deactivate + { + actionGroup = None + } + Toggle + { + actionGroup = None + } + } + } + MODULE + { + name = ModuleSAS + isEnabled = True + standaloneToggle = True + standaloneToggle_UIFlight + { + controlEnabled = True + } + EVENTS + { + } + ACTIONS + { + } + } + MODULE + { + name = KOSNameTag + isEnabled = True + nameTag = + EVENTS + { + PopupNameTagChanger + { + active = True + guiActive = True + guiActiveEditor = True + guiIcon = Change Name Tag + guiName = Change Name Tag + category = Change Name Tag + guiActiveUnfocused = False + unfocusedRange = 2 + externalToEVAOnly = True + } + } + ACTIONS + { + } + } + MODULE + { + name = ModuleTripLogger + isEnabled = True + EVENTS + { + } + ACTIONS + { + } + Log + { + flight = 0 + } + } + RESOURCE + { + name = ElectricCharge + amount = 15 + maxAmount = 15 + flowState = True + isTweakable = True + hideFlow = False + flowMode = Both + } +} +PART +{ + part = noseCone_4287640986 + partName = Part + pos = 0,15.1,0 + attPos = 0,0,0 + attPos0 = 0,0.1000004,0 + rot = 0,0,0,1 + attRot = 0,0,0,1 + attRot0 = 0,0,0,1 + mir = 1,1,1 + symMethod = Radial + istg = 0 + dstg = 0 + sidx = -1 + sqor = -1 + sepI = 0 + attm = 0 + modCost = 0 + modMass = 0 + modSize = (0.0, 0.0, 0.0) + attN = bottom01,probeStackSmall_4287645852 + EVENTS + { + } + ACTIONS + { + } + PARTDATA + { + } + MODULE + { + name = KOSNameTag + isEnabled = True + nameTag = + EVENTS + { + PopupNameTagChanger + { + active = True + guiActive = True + guiActiveEditor = True + guiIcon = Change Name Tag + guiName = Change Name Tag + category = Change Name Tag + guiActiveUnfocused = False + unfocusedRange = 2 + externalToEVAOnly = True + } + } + ACTIONS + { + } + } +} +PART +{ + part = kOSMachine1m_4294064856 + partName = Part + pos = 0,14.727,0 + attPos = 0,0,0 + attPos0 = 0,-0.2730007,0 + rot = 0,0,0,1 + attRot = 0,0,0,1 + attRot0 = 0,0,0,1 + mir = 1,1,1 + symMethod = Radial + istg = 0 + dstg = 0 + sidx = -1 + sqor = -1 + sepI = 0 + attm = 0 + modCost = 0 + modMass = 0 + modSize = (0.0, 0.0, 0.0) + link = fuelTank_4294699826 + link = solarPanels5_4290881882 + link = solarPanels5_4290881686 + link = solarPanels5_4290881652 + link = solarPanels5_4290881618 + attN = bottom,fuelTank_4294699826 + attN = top,probeStackSmall_4287645852 + EVENTS + { + } + ACTIONS + { + } + PARTDATA + { + } + MODULE + { + name = kOSProcessor + isEnabled = True + bootFile = boot.ks + diskSpace = 10000 + baseDiskSpace = 10000 + baseModuleCost = 0 + basePartMass = 0.12 + additionalCost = 0 + MaxPartId = 100 + RequiredPower = 0 + bootFile_UIEditor + { + controlEnabled = False + } + EVENTS + { + Activate + { + active = True + guiActive = True + guiIcon = Open Terminal + guiName = Open Terminal + category = Open Terminal + guiActiveUnfocused = False + unfocusedRange = 2 + externalToEVAOnly = True + } + TogglePower + { + active = True + guiActive = True + guiIcon = Toggle Power + guiName = Toggle Power + category = Toggle Power + guiActiveUnfocused = False + unfocusedRange = 2 + externalToEVAOnly = True + } + } + ACTIONS + { + Activate + { + actionGroup = None + } + Deactivate + { + actionGroup = None + } + Toggle + { + actionGroup = Custom01 + } + TogglePower + { + actionGroup = None + } + } + } + MODULE + { + name = KOSNameTag + isEnabled = True + nameTag = + EVENTS + { + PopupNameTagChanger + { + active = True + guiActive = True + guiActiveEditor = True + guiIcon = Change Name Tag + guiName = Change Name Tag + category = Change Name Tag + guiActiveUnfocused = False + unfocusedRange = 2 + externalToEVAOnly = True + } + } + ACTIONS + { + } + } + RESOURCE + { + name = ElectricCharge + amount = 5 + maxAmount = 5 + flowState = True + isTweakable = True + hideFlow = False + flowMode = Both + } +} +PART +{ + part = fuelTank_4294699826 + partName = Part + pos = 0,13.58831,0 + attPos = 0,0,0 + attPos0 = 0,-1.138691,0 + rot = 0,0,0,1 + attRot = 0,0,0,1 + attRot0 = 0,0,0,1 + mir = 1,1,1 + symMethod = Radial + istg = 0 + dstg = 0 + sidx = -1 + sqor = -1 + sepI = 0 + attm = 0 + modCost = 0 + modMass = 0 + modSize = (0.0, 0.0, 0.0) + link = liquidEngine3_4294696668 + attN = top,kOSMachine1m_4294064856 + attN = bottom,liquidEngine3_4294696668 + EVENTS + { + } + ACTIONS + { + } + PARTDATA + { + } + MODULE + { + name = KOSNameTag + isEnabled = True + nameTag = + EVENTS + { + PopupNameTagChanger + { + active = True + guiActive = True + guiActiveEditor = True + guiIcon = Change Name Tag + guiName = Change Name Tag + category = Change Name Tag + guiActiveUnfocused = False + unfocusedRange = 2 + externalToEVAOnly = True + } + } + ACTIONS + { + } + } + RESOURCE + { + name = LiquidFuel + amount = 180 + maxAmount = 180 + flowState = True + isTweakable = True + hideFlow = False + flowMode = Both + } + RESOURCE + { + name = Oxidizer + amount = 220 + maxAmount = 220 + flowState = True + isTweakable = True + hideFlow = False + flowMode = Both + } +} +PART +{ + part = liquidEngine3_4294696668 + partName = Part + pos = 0,12.40519,0 + attPos = 0,0,0 + attPos0 = 0,-1.183123,0 + rot = 0,0,0,1 + attRot = 0,0,0,1 + attRot0 = 0,0,0,1 + mir = 1,1,1 + symMethod = Radial + istg = 0 + dstg = 0 + sidx = 0 + sqor = 0 + sepI = 0 + attm = 0 + modCost = 0 + modMass = 0 + modSize = (0.0, 0.0, 0.0) + link = stackDecoupler_4294691790 + attN = top,fuelTank_4294699826 + attN = bottom,stackDecoupler_4294691790 + EVENTS + { + } + ACTIONS + { + } + PARTDATA + { + } + MODULE + { + name = ModuleEngines + isEnabled = True + staged = False + flameout = False + EngineIgnited = False + engineShutdown = False + currentThrottle = 0 + thrustPercentage = 100 + manuallyOverridden = False + thrustPercentage_UIFlight + { + controlEnabled = True + minValue = 0 + maxValue = 100 + stepIncrement = 0.5 + } + EVENTS + { + Activate + { + active = True + guiActive = True + guiIcon = Activate Engine + guiName = Activate Engine + category = Activate Engine + guiActiveUnfocused = False + unfocusedRange = 2 + externalToEVAOnly = True + } + Shutdown + { + active = False + guiActive = True + guiIcon = Shutdown Engine + guiName = Shutdown Engine + category = Shutdown Engine + guiActiveUnfocused = False + unfocusedRange = 2 + externalToEVAOnly = True + } + } + ACTIONS + { + OnAction + { + actionGroup = None + } + ShutdownAction + { + actionGroup = None + } + ActivateAction + { + actionGroup = None + } + } + } + MODULE + { + name = ModuleGimbal + isEnabled = True + gimbalLock = False + gimbalLimiter = 100 + gimbalLock_UIFlight + { + controlEnabled = True + } + gimbalLimiter_UIFlight + { + controlEnabled = True + minValue = 0 + maxValue = 100 + stepIncrement = 1 + } + EVENTS + { + } + ACTIONS + { + ToggleAction + { + actionGroup = None + } + LockAction + { + actionGroup = None + } + FreeAction + { + actionGroup = None + } + } + } + MODULE + { + name = ModuleAnimateHeat + isEnabled = True + EVENTS + { + } + ACTIONS + { + } + } + MODULE + { + name = ModuleJettison + isEnabled = True + isJettisoned = False + EVENTS + { + Jettison + { + active = False + guiActive = True + guiIcon = Jettison + guiName = Jettison + category = Jettison + guiActiveUnfocused = False + unfocusedRange = 2 + externalToEVAOnly = True + } + } + ACTIONS + { + JettisonAction + { + actionGroup = None + } + } + } + MODULE + { + name = ModuleTestSubject + isEnabled = True + EVENTS + { + RunTestEvent + { + active = False + guiActive = True + guiIcon = Run Test + guiName = Run Test + category = Run Test + guiActiveUnfocused = False + unfocusedRange = 2 + externalToEVAOnly = True + } + } + ACTIONS + { + } + } + MODULE + { + name = ModuleSurfaceFX + isEnabled = True + EVENTS + { + } + ACTIONS + { + } + } + MODULE + { + name = KOSNameTag + isEnabled = True + nameTag = + EVENTS + { + PopupNameTagChanger + { + active = True + guiActive = True + guiActiveEditor = True + guiIcon = Change Name Tag + guiName = Change Name Tag + category = Change Name Tag + guiActiveUnfocused = False + unfocusedRange = 2 + externalToEVAOnly = True + } + } + ACTIONS + { + } + } +} +PART +{ + part = stackDecoupler_4294691790 + partName = Part + pos = 0,11.86732,0 + attPos = 0,0,0 + attPos0 = 0,-0.5378656,0 + rot = 0,0,0,1 + attRot = 0,0,0,1 + attRot0 = 0,0,0,1 + mir = 1,1,1 + symMethod = Radial + istg = 0 + dstg = 1 + sidx = 1 + sqor = 0 + sepI = 1 + attm = 0 + modCost = 0 + modMass = 0 + modSize = (0.0, 0.0, 0.0) + link = fuelTank.long_4294687468 + attN = bottom,fuelTank.long_4294687468 + attN = top,liquidEngine3_4294696668 + EVENTS + { + } + ACTIONS + { + } + PARTDATA + { + } + MODULE + { + name = ModuleDecouple + isEnabled = True + ejectionForcePercent = 100 + isDecoupled = False + ejectionForcePercent_UIFlight + { + controlEnabled = True + minValue = 0 + maxValue = 100 + stepIncrement = 1 + } + EVENTS + { + Decouple + { + active = True + guiActive = True + guiIcon = Decouple + guiName = Decouple + category = Decouple + guiActiveUnfocused = False + unfocusedRange = 2 + externalToEVAOnly = True + } + } + ACTIONS + { + DecoupleAction + { + actionGroup = None + } + } + } + MODULE + { + name = ModuleTestSubject + isEnabled = True + EVENTS + { + RunTestEvent + { + active = False + guiActive = True + guiIcon = Run Test + guiName = Run Test + category = Run Test + guiActiveUnfocused = False + unfocusedRange = 2 + externalToEVAOnly = True + } + } + ACTIONS + { + } + } + MODULE + { + name = KOSNameTag + isEnabled = True + nameTag = + EVENTS + { + PopupNameTagChanger + { + active = True + guiActive = True + guiActiveEditor = True + guiIcon = Change Name Tag + guiName = Change Name Tag + category = Change Name Tag + guiActiveUnfocused = False + unfocusedRange = 2 + externalToEVAOnly = True + } + } + ACTIONS + { + } + } +} +PART +{ + part = fuelTank.long_4294687468 + partName = Part + pos = 0,9.85933,0 + attPos = 0,0,0 + attPos0 = 0,-2.007995,0 + rot = 0,0,0,1 + attRot = 0,0,0,1 + attRot0 = 0,0,0,1 + mir = 1,1,1 + symMethod = Radial + istg = 2 + dstg = 2 + sidx = -1 + sqor = -1 + sepI = 1 + attm = 0 + modCost = 0 + modMass = 0 + modSize = (0.0, 0.0, 0.0) + link = fuelTank.long_4294687162 + attN = top,stackDecoupler_4294691790 + attN = bottom,fuelTank.long_4294687162 + EVENTS + { + } + ACTIONS + { + } + PARTDATA + { + } + MODULE + { + name = KOSNameTag + isEnabled = True + nameTag = + EVENTS + { + PopupNameTagChanger + { + active = True + guiActive = True + guiActiveEditor = True + guiIcon = Change Name Tag + guiName = Change Name Tag + category = Change Name Tag + guiActiveUnfocused = False + unfocusedRange = 2 + externalToEVAOnly = True + } + } + ACTIONS + { + } + } + RESOURCE + { + name = LiquidFuel + amount = 360 + maxAmount = 360 + flowState = True + isTweakable = True + hideFlow = False + flowMode = Both + } + RESOURCE + { + name = Oxidizer + amount = 440 + maxAmount = 440 + flowState = True + isTweakable = True + hideFlow = False + flowMode = Both + } +} +PART +{ + part = fuelTank.long_4294687162 + partName = Part + pos = 0,6.096828,0 + attPos = 0,0,0 + attPos0 = 0,-3.7625,0 + rot = 0,0,0,1 + attRot = 0,0,0,1 + attRot0 = 0,0,0,1 + mir = 1,1,1 + symMethod = Radial + istg = 2 + dstg = 2 + sidx = -1 + sqor = -1 + sepI = 1 + attm = 0 + modCost = 0 + modMass = 0 + modSize = (0.0, 0.0, 0.0) + link = liquidEngine2_4294683890 + link = winglet3_4294678112 + link = winglet3_4294677872 + link = winglet3_4294677826 + link = winglet3_4294677780 + link = launchClamp1_4294673818 + attN = top,fuelTank.long_4294687468 + attN = bottom,liquidEngine2_4294683890 + EVENTS + { + } + ACTIONS + { + } + PARTDATA + { + } + MODULE + { + name = KOSNameTag + isEnabled = True + nameTag = + EVENTS + { + PopupNameTagChanger + { + active = True + guiActive = True + guiActiveEditor = True + guiIcon = Change Name Tag + guiName = Change Name Tag + category = Change Name Tag + guiActiveUnfocused = False + unfocusedRange = 2 + externalToEVAOnly = True + } + } + ACTIONS + { + } + } + RESOURCE + { + name = LiquidFuel + amount = 360 + maxAmount = 360 + flowState = True + isTweakable = True + hideFlow = False + flowMode = Both + } + RESOURCE + { + name = Oxidizer + amount = 440 + maxAmount = 440 + flowState = True + isTweakable = True + hideFlow = False + flowMode = Both + } +} +PART +{ + part = liquidEngine2_4294683890 + partName = Part + pos = 0,3.307501,0 + attPos = 0,0,0 + attPos0 = 0,-2.789327,0 + rot = 0,0,0,1 + attRot = 0,0,0,1 + attRot0 = 0,0,0,1 + mir = 1,1,1 + symMethod = Radial + istg = 1 + dstg = 2 + sidx = 0 + sqor = 1 + sepI = 1 + attm = 0 + modCost = 0 + modMass = 0 + modSize = (0.0, 0.0, 0.0) + attN = top,fuelTank.long_4294687162 + EVENTS + { + } + ACTIONS + { + } + PARTDATA + { + } + MODULE + { + name = ModuleEngines + isEnabled = True + staged = False + flameout = False + EngineIgnited = False + engineShutdown = False + currentThrottle = 0 + thrustPercentage = 100 + manuallyOverridden = False + thrustPercentage_UIFlight + { + controlEnabled = True + minValue = 0 + maxValue = 100 + stepIncrement = 0.5 + } + EVENTS + { + Activate + { + active = True + guiActive = True + guiIcon = Activate Engine + guiName = Activate Engine + category = Activate Engine + guiActiveUnfocused = False + unfocusedRange = 2 + externalToEVAOnly = True + } + Shutdown + { + active = False + guiActive = True + guiIcon = Shutdown Engine + guiName = Shutdown Engine + category = Shutdown Engine + guiActiveUnfocused = False + unfocusedRange = 2 + externalToEVAOnly = True + } + } + ACTIONS + { + OnAction + { + actionGroup = None + } + ShutdownAction + { + actionGroup = None + } + ActivateAction + { + actionGroup = None + } + } + } + MODULE + { + name = ModuleJettison + isEnabled = True + isJettisoned = True + EVENTS + { + Jettison + { + active = False + guiActive = True + guiIcon = Jettison + guiName = Jettison + category = Jettison + guiActiveUnfocused = False + unfocusedRange = 2 + externalToEVAOnly = True + } + } + ACTIONS + { + JettisonAction + { + actionGroup = None + } + } + } + MODULE + { + name = ModuleGimbal + isEnabled = True + gimbalLock = False + gimbalLimiter = 100 + gimbalLock_UIFlight + { + controlEnabled = True + } + gimbalLimiter_UIFlight + { + controlEnabled = True + minValue = 0 + maxValue = 100 + stepIncrement = 1 + } + EVENTS + { + } + ACTIONS + { + ToggleAction + { + actionGroup = None + } + LockAction + { + actionGroup = None + } + FreeAction + { + actionGroup = None + } + } + } + MODULE + { + name = ModuleAnimateHeat + isEnabled = True + EVENTS + { + } + ACTIONS + { + } + } + MODULE + { + name = ModuleAlternator + isEnabled = True + EVENTS + { + } + ACTIONS + { + } + } + MODULE + { + name = ModuleSurfaceFX + isEnabled = True + EVENTS + { + } + ACTIONS + { + } + } + MODULE + { + name = ModuleTestSubject + isEnabled = True + EVENTS + { + RunTestEvent + { + active = False + guiActive = True + guiIcon = Run Test + guiName = Run Test + category = Run Test + guiActiveUnfocused = False + unfocusedRange = 2 + externalToEVAOnly = True + } + } + ACTIONS + { + } + } + MODULE + { + name = KOSNameTag + isEnabled = True + nameTag = + EVENTS + { + PopupNameTagChanger + { + active = True + guiActive = True + guiActiveEditor = True + guiIcon = Change Name Tag + guiName = Change Name Tag + category = Change Name Tag + guiActiveUnfocused = False + unfocusedRange = 2 + externalToEVAOnly = True + } + } + ACTIONS + { + } + } + RESOURCE + { + name = ElectricCharge + amount = 0 + maxAmount = 0 + flowState = True + isTweakable = False + hideFlow = True + flowMode = Both + } +} +PART +{ + part = winglet3_4294678112 + partName = Part + pos = -0.7810385,5.095463,-0.7810386 + attPos = 0,0,0 + attPos0 = -0.7810386,-1.001366,-0.7810386 + rot = 5.671899E-09,0.3826834,-1.369318E-08,-0.9238796 + attRot = 0,0,0,1 + attRot0 = 5.671899E-09,0.3826834,-1.369318E-08,-0.9238796 + mir = 1,1,1 + symMethod = Radial + istg = 2 + dstg = 2 + sidx = -1 + sqor = -1 + sepI = 1 + attm = 1 + modCost = 0 + modMass = 0 + modSize = (0.0, 0.0, 0.0) + sym = winglet3_4294677872 + sym = winglet3_4294677826 + sym = winglet3_4294677780 + srfN = srfAttach,fuelTank.long_4294687162 + EVENTS + { + } + ACTIONS + { + } + PARTDATA + { + } + MODULE + { + name = ModuleControlSurface + isEnabled = True + ignorePitch = False + ignoreYaw = False + ignoreRoll = False + deploy = False + deployInvert = False + ignorePitch_UIFlight + { + controlEnabled = True + } + ignoreYaw_UIFlight + { + controlEnabled = True + } + ignoreRoll_UIFlight + { + controlEnabled = True + } + deploy_UIFlight + { + controlEnabled = True + } + deployInvert_UIFlight + { + controlEnabled = True + } + EVENTS + { + } + ACTIONS + { + ActionToggle + { + actionGroup = None + } + ActionExtend + { + actionGroup = None + } + ActionRetract + { + actionGroup = None + } + } + } + MODULE + { + name = KOSNameTag + isEnabled = True + nameTag = + EVENTS + { + PopupNameTagChanger + { + active = True + guiActive = True + guiActiveEditor = True + guiIcon = Change Name Tag + guiName = Change Name Tag + category = Change Name Tag + guiActiveUnfocused = False + unfocusedRange = 2 + externalToEVAOnly = True + } + } + ACTIONS + { + } + } +} +PART +{ + part = winglet3_4294677872 + partName = Part + pos = -0.7810385,5.095463,0.7810385 + attPos = 0,0,0 + attPos0 = -0.7810386,-1.001366,0.7810385 + rot = -5.671899E-09,-0.3826835,-1.369318E-08,-0.9238796 + attRot = 0,0,0,1 + attRot0 = -5.6719E-09,-0.3826835,-1.369318E-08,-0.9238796 + mir = 1,1,1 + symMethod = Radial + istg = 2 + dstg = 2 + sidx = -1 + sqor = -1 + sepI = 1 + attm = 1 + modCost = 0 + modMass = 0 + modSize = (0.0, 0.0, 0.0) + sym = winglet3_4294678112 + sym = winglet3_4294677826 + sym = winglet3_4294677780 + srfN = srfAttach,fuelTank.long_4294687162 + EVENTS + { + } + ACTIONS + { + } + PARTDATA + { + } + MODULE + { + name = ModuleControlSurface + isEnabled = True + ignorePitch = False + ignoreYaw = False + ignoreRoll = False + deploy = False + deployInvert = False + ignorePitch_UIFlight + { + controlEnabled = True + } + ignoreYaw_UIFlight + { + controlEnabled = True + } + ignoreRoll_UIFlight + { + controlEnabled = True + } + deploy_UIFlight + { + controlEnabled = True + } + deployInvert_UIFlight + { + controlEnabled = True + } + EVENTS + { + } + ACTIONS + { + ActionToggle + { + actionGroup = None + } + ActionExtend + { + actionGroup = None + } + ActionRetract + { + actionGroup = None + } + } + } + MODULE + { + name = KOSNameTag + isEnabled = True + nameTag = + EVENTS + { + PopupNameTagChanger + { + active = True + guiActive = True + guiActiveEditor = True + guiIcon = Change Name Tag + guiName = Change Name Tag + category = Change Name Tag + guiActiveUnfocused = False + unfocusedRange = 2 + externalToEVAOnly = True + } + } + ACTIONS + { + } + } +} +PART +{ + part = winglet3_4294677826 + partName = Part + pos = 0.7810385,5.095463,0.7810386 + attPos = 0,0,0 + attPos0 = 0.7810386,-1.001366,0.7810386 + rot = -1.369318E-08,-0.9238796,-5.671899E-09,-0.3826834 + attRot = 0,0,0,1 + attRot0 = -1.369318E-08,-0.9238796,-5.671899E-09,-0.3826834 + mir = 1,1,1 + symMethod = Radial + istg = 2 + dstg = 2 + sidx = -1 + sqor = -1 + sepI = 1 + attm = 1 + modCost = 0 + modMass = 0 + modSize = (0.0, 0.0, 0.0) + sym = winglet3_4294678112 + sym = winglet3_4294677872 + sym = winglet3_4294677780 + srfN = srfAttach,fuelTank.long_4294687162 + EVENTS + { + } + ACTIONS + { + } + PARTDATA + { + } + MODULE + { + name = ModuleControlSurface + isEnabled = True + ignorePitch = False + ignoreYaw = False + ignoreRoll = False + deploy = False + deployInvert = False + ignorePitch_UIFlight + { + controlEnabled = True + } + ignoreYaw_UIFlight + { + controlEnabled = True + } + ignoreRoll_UIFlight + { + controlEnabled = True + } + deploy_UIFlight + { + controlEnabled = True + } + deployInvert_UIFlight + { + controlEnabled = True + } + EVENTS + { + } + ACTIONS + { + ActionToggle + { + actionGroup = None + } + ActionExtend + { + actionGroup = None + } + ActionRetract + { + actionGroup = None + } + } + } + MODULE + { + name = KOSNameTag + isEnabled = True + nameTag = + EVENTS + { + PopupNameTagChanger + { + active = True + guiActive = True + guiActiveEditor = True + guiIcon = Change Name Tag + guiName = Change Name Tag + category = Change Name Tag + guiActiveUnfocused = False + unfocusedRange = 2 + externalToEVAOnly = True + } + } + ACTIONS + { + } + } +} +PART +{ + part = winglet3_4294677780 + partName = Part + pos = 0.7810385,5.095463,-0.7810385 + attPos = 0,0,0 + attPos0 = 0.7810385,-1.001366,-0.7810386 + rot = -1.369318E-08,-0.9238796,5.671899E-09,0.3826835 + attRot = 0,0,0,1 + attRot0 = -1.369318E-08,-0.9238796,5.6719E-09,0.3826835 + mir = 1,1,1 + symMethod = Radial + istg = 2 + dstg = 2 + sidx = -1 + sqor = -1 + sepI = 1 + attm = 1 + modCost = 0 + modMass = 0 + modSize = (0.0, 0.0, 0.0) + sym = winglet3_4294678112 + sym = winglet3_4294677872 + sym = winglet3_4294677826 + srfN = srfAttach,fuelTank.long_4294687162 + EVENTS + { + } + ACTIONS + { + } + PARTDATA + { + } + MODULE + { + name = ModuleControlSurface + isEnabled = True + ignorePitch = False + ignoreYaw = False + ignoreRoll = False + deploy = False + deployInvert = False + ignorePitch_UIFlight + { + controlEnabled = True + } + ignoreYaw_UIFlight + { + controlEnabled = True + } + ignoreRoll_UIFlight + { + controlEnabled = True + } + deploy_UIFlight + { + controlEnabled = True + } + deployInvert_UIFlight + { + controlEnabled = True + } + EVENTS + { + } + ACTIONS + { + ActionToggle + { + actionGroup = None + } + ActionExtend + { + actionGroup = None + } + ActionRetract + { + actionGroup = None + } + } + } + MODULE + { + name = KOSNameTag + isEnabled = True + nameTag = + EVENTS + { + PopupNameTagChanger + { + active = True + guiActive = True + guiActiveEditor = True + guiIcon = Change Name Tag + guiName = Change Name Tag + category = Change Name Tag + guiActiveUnfocused = False + unfocusedRange = 2 + externalToEVAOnly = True + } + } + ACTIONS + { + } + } +} +PART +{ + part = launchClamp1_4294673818 + partName = Part + pos = -4.488975E-07,3.385004,-1.426199 + attPos = 0,0,0 + attPos0 = -4.513211E-07,-2.711823,-1.426199 + rot = 1.711427E-08,-3.132037E-07,-5.360253E-15,-1 + attRot = 0,0,0,1 + attRot0 = 1.711427E-08,-3.132037E-07,-5.360253E-15,-1 + mir = 1,1,1 + symMethod = Radial + istg = 1 + dstg = 2 + sidx = 1 + sqor = 1 + sepI = 2 + attm = 1 + modCost = 0 + modMass = 0 + modSize = (0.0, 0.0, 0.0) + srfN = srfAttach,fuelTank.long_4294687162 + EVENTS + { + } + ACTIONS + { + } + PARTDATA + { + } + MODULE + { + name = LaunchClamp + isEnabled = True + scaleFactor = 1.603186 + height = 4.045155 + towerRot = -1.711427E-08,3.132037E-07,5.360253E-15,-1 + EVENTS + { + Release + { + active = False + guiActive = True + guiIcon = Release Clamp + guiName = Release Clamp + category = Release Clamp + guiActiveUnfocused = False + unfocusedRange = 2 + externalToEVAOnly = True + } + } + ACTIONS + { + ReleaseClamp + { + actionGroup = None + } + } + } + MODULE + { + name = ModuleGenerator + isEnabled = True + generatorIsActive = False + throttle = 0 + EVENTS + { + Activate + { + active = True + guiActive = True + guiIcon = Activate Generator + guiName = Activate Generator + category = Activate Generator + guiActiveUnfocused = False + unfocusedRange = 2 + externalToEVAOnly = True + } + Shutdown + { + active = True + guiActive = True + guiIcon = Shutdown Generator + guiName = Shutdown Generator + category = Shutdown Generator + guiActiveUnfocused = False + unfocusedRange = 2 + externalToEVAOnly = True + } + } + ACTIONS + { + ToggleAction + { + actionGroup = None + } + ActivateAction + { + actionGroup = None + } + ShutdownAction + { + actionGroup = None + } + } + } + MODULE + { + name = ModuleTestSubject + isEnabled = True + EVENTS + { + RunTestEvent + { + active = False + guiActive = True + guiIcon = Run Test + guiName = Run Test + category = Run Test + guiActiveUnfocused = False + unfocusedRange = 2 + externalToEVAOnly = True + } + } + ACTIONS + { + } + } + MODULE + { + name = KOSNameTag + isEnabled = True + nameTag = + EVENTS + { + PopupNameTagChanger + { + active = True + guiActive = True + guiActiveEditor = True + guiIcon = Change Name Tag + guiName = Change Name Tag + category = Change Name Tag + guiActiveUnfocused = False + unfocusedRange = 2 + externalToEVAOnly = True + } + } + ACTIONS + { + } + } +} +PART +{ + part = solarPanels5_4290881882 + partName = Part + pos = -4.842877E-08,14.65845,-0.597011 + attPos = 0,0,0 + attPos0 = -5.215406E-08,-0.06854534,-0.597011 + rot = 0,1,0,-5.464577E-08 + attRot = 0,0,0,1 + attRot0 = 0,1,0,-5.464577E-08 + mir = 1,1,1 + symMethod = Radial + istg = 0 + dstg = 0 + sidx = -1 + sqor = -1 + sepI = 0 + attm = 1 + modCost = 0 + modMass = 0 + modSize = (0.0, 0.0, 0.0) + sym = solarPanels5_4290881686 + sym = solarPanels5_4290881652 + sym = solarPanels5_4290881618 + srfN = srfAttach,kOSMachine1m_4294064856 + EVENTS + { + } + ACTIONS + { + } + PARTDATA + { + } + MODULE + { + name = ModuleDeployableSolarPanel + isEnabled = True + currentRotation = (0, 0, 0, 0) + stateString = RETRACTED + storedAnimationTime = 0 + storedAnimationSpeed = 0 + EVENTS + { + Extend + { + active = True + guiActive = True + guiIcon = Extend Panels + guiName = Extend Panels + category = Extend Panels + guiActiveUnfocused = True + unfocusedRange = 4 + externalToEVAOnly = True + } + Retract + { + active = True + guiActive = True + guiIcon = Retract Panels + guiName = Retract Panels + category = Retract Panels + guiActiveUnfocused = True + unfocusedRange = 4 + externalToEVAOnly = True + } + } + ACTIONS + { + ExtendPanelsAction + { + actionGroup = None + } + ExtendAction + { + actionGroup = None + } + RetractAction + { + actionGroup = None + } + } + } + MODULE + { + name = KOSNameTag + isEnabled = True + nameTag = + EVENTS + { + PopupNameTagChanger + { + active = True + guiActive = True + guiActiveEditor = True + guiIcon = Change Name Tag + guiName = Change Name Tag + category = Change Name Tag + guiActiveUnfocused = False + unfocusedRange = 2 + externalToEVAOnly = True + } + } + ACTIONS + { + } + } +} +PART +{ + part = solarPanels5_4290881686 + partName = Part + pos = -0.597011,14.65845,1.722947E-08 + attPos = 0,0,0 + attPos0 = -0.5970109,-0.06854534,1.676381E-08 + rot = 0,0.7071068,0,-0.7071068 + attRot = 0,0,0,1 + attRot0 = 0,0.7071068,0,-0.7071069 + mir = 1,1,1 + symMethod = Radial + istg = 0 + dstg = 0 + sidx = -1 + sqor = -1 + sepI = 0 + attm = 1 + modCost = 0 + modMass = 0 + modSize = (0.0, 0.0, 0.0) + sym = solarPanels5_4290881882 + sym = solarPanels5_4290881652 + sym = solarPanels5_4290881618 + srfN = srfAttach,kOSMachine1m_4294064856 + EVENTS + { + } + ACTIONS + { + } + PARTDATA + { + } + MODULE + { + name = ModuleDeployableSolarPanel + isEnabled = True + currentRotation = (0, 0, 0, 0) + stateString = RETRACTED + storedAnimationTime = 0 + storedAnimationSpeed = 0 + EVENTS + { + Extend + { + active = True + guiActive = True + guiIcon = Extend Panels + guiName = Extend Panels + category = Extend Panels + guiActiveUnfocused = True + unfocusedRange = 4 + externalToEVAOnly = True + } + Retract + { + active = True + guiActive = True + guiIcon = Retract Panels + guiName = Retract Panels + category = Retract Panels + guiActiveUnfocused = True + unfocusedRange = 4 + externalToEVAOnly = True + } + } + ACTIONS + { + ExtendPanelsAction + { + actionGroup = None + } + ExtendAction + { + actionGroup = None + } + RetractAction + { + actionGroup = None + } + } + } + MODULE + { + name = KOSNameTag + isEnabled = True + nameTag = + EVENTS + { + PopupNameTagChanger + { + active = True + guiActive = True + guiActiveEditor = True + guiIcon = Change Name Tag + guiName = Change Name Tag + category = Change Name Tag + guiActiveUnfocused = False + unfocusedRange = 2 + externalToEVAOnly = True + } + } + ACTIONS + { + } + } +} +PART +{ + part = solarPanels5_4290881652 + partName = Part + pos = 1.005828E-07,14.65845,0.597011 + attPos = 0,0,0 + attPos0 = 1.043081E-07,-0.06854534,0.597011 + rot = 0,-9.835716E-08,0,-1 + attRot = 0,0,0,1 + attRot0 = 0,-9.835716E-08,0,-1 + mir = 1,1,1 + symMethod = Radial + istg = 0 + dstg = 0 + sidx = -1 + sqor = -1 + sepI = 0 + attm = 1 + modCost = 0 + modMass = 0 + modSize = (0.0, 0.0, 0.0) + sym = solarPanels5_4290881882 + sym = solarPanels5_4290881686 + sym = solarPanels5_4290881618 + srfN = srfAttach,kOSMachine1m_4294064856 + EVENTS + { + } + ACTIONS + { + } + PARTDATA + { + } + MODULE + { + name = ModuleDeployableSolarPanel + isEnabled = True + currentRotation = (0, 0, 0, 0) + stateString = RETRACTED + storedAnimationTime = 0 + storedAnimationSpeed = 0 + EVENTS + { + Extend + { + active = True + guiActive = True + guiIcon = Extend Panels + guiName = Extend Panels + category = Extend Panels + guiActiveUnfocused = True + unfocusedRange = 4 + externalToEVAOnly = True + } + Retract + { + active = True + guiActive = True + guiIcon = Retract Panels + guiName = Retract Panels + category = Retract Panels + guiActiveUnfocused = True + unfocusedRange = 4 + externalToEVAOnly = True + } + } + ACTIONS + { + ExtendPanelsAction + { + actionGroup = None + } + ExtendAction + { + actionGroup = None + } + RetractAction + { + actionGroup = None + } + } + } + MODULE + { + name = KOSNameTag + isEnabled = True + nameTag = + EVENTS + { + PopupNameTagChanger + { + active = True + guiActive = True + guiActiveEditor = True + guiIcon = Change Name Tag + guiName = Change Name Tag + category = Change Name Tag + guiActiveUnfocused = False + unfocusedRange = 2 + externalToEVAOnly = True + } + } + ACTIONS + { + } + } +} +PART +{ + part = solarPanels5_4290881618 + partName = Part + pos = 0.597011,14.65845,-8.800998E-08 + attPos = 0,0,0 + attPos0 = 0.5970109,-0.06854534,-8.754432E-08 + rot = 0,-0.7071068,0,-0.7071068 + attRot = 0,0,0,1 + attRot0 = 0,-0.7071069,0,-0.7071068 + mir = 1,1,1 + symMethod = Radial + istg = 0 + dstg = 0 + sidx = -1 + sqor = -1 + sepI = 0 + attm = 1 + modCost = 0 + modMass = 0 + modSize = (0.0, 0.0, 0.0) + sym = solarPanels5_4290881882 + sym = solarPanels5_4290881686 + sym = solarPanels5_4290881652 + srfN = srfAttach,kOSMachine1m_4294064856 + EVENTS + { + } + ACTIONS + { + } + PARTDATA + { + } + MODULE + { + name = ModuleDeployableSolarPanel + isEnabled = True + currentRotation = (0, 0, 0, 0) + stateString = RETRACTED + storedAnimationTime = 0 + storedAnimationSpeed = 0 + EVENTS + { + Extend + { + active = True + guiActive = True + guiIcon = Extend Panels + guiName = Extend Panels + category = Extend Panels + guiActiveUnfocused = True + unfocusedRange = 4 + externalToEVAOnly = True + } + Retract + { + active = True + guiActive = True + guiIcon = Retract Panels + guiName = Retract Panels + category = Retract Panels + guiActiveUnfocused = True + unfocusedRange = 4 + externalToEVAOnly = True + } + } + ACTIONS + { + ExtendPanelsAction + { + actionGroup = None + } + ExtendAction + { + actionGroup = None + } + RetractAction + { + actionGroup = None + } + } + } + MODULE + { + name = KOSNameTag + isEnabled = True + nameTag = + EVENTS + { + PopupNameTagChanger + { + active = True + guiActive = True + guiActiveEditor = True + guiIcon = Change Name Tag + guiName = Change Name Tag + category = Change Name Tag + guiActiveUnfocused = False + unfocusedRange = 2 + externalToEVAOnly = True + } + } + ACTIONS + { + } + } +} diff --git a/doc/source/_images/tutorials/quickstart/example_2_0.png b/doc/source/_images/tutorials/quickstart/example_2_0.png new file mode 100644 index 000000000..4af649893 Binary files /dev/null and b/doc/source/_images/tutorials/quickstart/example_2_0.png differ diff --git a/doc/source/_images/tutorials/quickstart/example_2_1.png b/doc/source/_images/tutorials/quickstart/example_2_1.png index 469e5b5cb..f33cfe0bc 100644 Binary files a/doc/source/_images/tutorials/quickstart/example_2_1.png and b/doc/source/_images/tutorials/quickstart/example_2_1.png differ diff --git a/doc/source/_images/tutorials/quickstart/example_2_2.png b/doc/source/_images/tutorials/quickstart/example_2_2.png index 747bb0a59..18688e7eb 100644 Binary files a/doc/source/_images/tutorials/quickstart/example_2_2.png and b/doc/source/_images/tutorials/quickstart/example_2_2.png differ diff --git a/doc/source/_images/tutorials/quickstart/example_2_3.png b/doc/source/_images/tutorials/quickstart/example_2_3.png index 6833d466d..9aeb740c5 100644 Binary files a/doc/source/_images/tutorials/quickstart/example_2_3.png and b/doc/source/_images/tutorials/quickstart/example_2_3.png differ diff --git a/doc/source/_images/tutorials/quickstart/example_2_4.png b/doc/source/_images/tutorials/quickstart/example_2_4.png index 3898ec833..6d6ef0be9 100644 Binary files a/doc/source/_images/tutorials/quickstart/example_2_4.png and b/doc/source/_images/tutorials/quickstart/example_2_4.png differ diff --git a/doc/source/_images/tutorials/quickstart/example_2_5.png b/doc/source/_images/tutorials/quickstart/example_2_5.png index c51a301e5..93c259f14 100644 Binary files a/doc/source/_images/tutorials/quickstart/example_2_5.png and b/doc/source/_images/tutorials/quickstart/example_2_5.png differ diff --git a/doc/source/_images/tutorials/quickstart/example_2_6.png b/doc/source/_images/tutorials/quickstart/example_2_6.png index 3fab8a28e..34702abaf 100644 Binary files a/doc/source/_images/tutorials/quickstart/example_2_6.png and b/doc/source/_images/tutorials/quickstart/example_2_6.png differ diff --git a/doc/source/_images/tutorials/quickstart/example_2_7.png b/doc/source/_images/tutorials/quickstart/example_2_7.png new file mode 100644 index 000000000..3a04d23f2 Binary files /dev/null and b/doc/source/_images/tutorials/quickstart/example_2_7.png differ diff --git a/doc/source/_static/css/kos_theme.css b/doc/source/_static/css/kos_theme.css new file mode 100644 index 000000000..756c06d8d --- /dev/null +++ b/doc/source/_static/css/kos_theme.css @@ -0,0 +1,20 @@ +/* start from read-the-docs' standard theme: */ +@import url("theme.css"); + +/* Some of the syntax highlighing done by + * read-the-docs is barely visible unless the + * font is zoomed large. At 10 point or 12 point, + * boldface doesn't stand out on the font they use, + * and many of the keywords are only highlighted + * by being bold. So doing a slight tint from + * the default black just to make it stand out a + * little bit more: + */ +.k { color:#042; } /*keywords*/ +.o { color:#024; } /*operators*/ + +a.reference span.pre { color: #2980B9; } + +/* It is possible to do a lot more here, but let's + * leave it at that for now. + */ diff --git a/doc/source/about.rst b/doc/source/about.rst index 7b0d1e362..f7bf0d948 100644 --- a/doc/source/about.rst +++ b/doc/source/about.rst @@ -4,6 +4,6 @@ About **kOS** and **KerboScript** ================================= kOS was originally created by Nivekk. -It is under `active development`_ by the +It is under active development by the `kOS Team `_ and is licensed under terms of GNU General Public License Version 3, 29 June 2007, Copyright © 2007 `Free Software Foundation, Inc. `_ diff --git a/doc/source/addons.rst b/doc/source/addons.rst index ab715c98c..71723ac94 100644 --- a/doc/source/addons.rst +++ b/doc/source/addons.rst @@ -12,6 +12,7 @@ Addon Reference RemoteTech Kerbal Alarm Clock Infernal Robotics + DMagic Orbital Science To help KOS scripts identify whether or not certain mod is installed and available following suffixed functions were introduced in version 0.17 diff --git a/doc/source/addons/IR.rst b/doc/source/addons/IR.rst index 5cf064e1e..6dee5caed 100644 --- a/doc/source/addons/IR.rst +++ b/doc/source/addons/IR.rst @@ -16,19 +16,19 @@ Access structure IRAddon via `ADDONS:IR`. .. structure:: IRAddon - ===================================== ========================= ============= - Suffix Type Description - ===================================== ========================= ============= - :attr:`AVAILABLE` bool(readonly) Returns True if mod Infernal Robotics is installed, available to KOS and applicable to current craft. - :attr:`GROUPS` List (readonly) Lists all Servo Groups for current focused vessel - :attr:`ALLSERVOS` List (readonly) Lists all Servos for current focused vessel - ===================================== ========================= ============= + ===================================== ==================================== ============= + Suffix Type Description + ===================================== ==================================== ============= + :attr:`AVAILABLE` :ref:`boolean ` (readonly) Returns True if mod Infernal Robotics is installed, available to KOS and applicable to current craft. + :attr:`GROUPS` List (readonly) Lists all Servo Groups for the Vessel on which CPU runs this command (see details below). + :attr:`ALLSERVOS` List (readonly) Lists all Servos for the Vessel on which CPU runs this command (see details below). + ===================================== ==================================== ============= .. attribute:: IRAddon:AVAILABLE - :type: bool + :type: :ref:`boolean ` :access: Get only Returns True if mod Infernal Robotics is installed, available to KOS and applicable to current craft. @@ -44,7 +44,8 @@ Access structure IRAddon via `ADDONS:IR`. :type: List of :struct:`IRControlGroup` objects :access: Get only - Lists all Servo Groups for current focused vessel. Example of use:: + Lists all Servo Groups for the Vessel on which the script is being executed. On IR versions prior to 0.21.5 will always return servo groups for current focused vessel. + Example of use:: for g in ADDONS:IR:GROUPS { @@ -57,7 +58,8 @@ Access structure IRAddon via `ADDONS:IR`. :type: List of :struct:`IRServo` objects :access: Get only - Lists all Servos for current focused vessel. Example of use:: + Lists all Servos for the Vessel on which the script is being executed. On IR versions prior to 0.21.5 will always return servos for current focused vessel. + Example of use:: for s in ADDONS:IR:ALLSERVOS { @@ -70,12 +72,13 @@ Access structure IRAddon via `ADDONS:IR`. ===================================== ========================= ============= Suffix Type Description ===================================== ========================= ============= - :attr:`NAME` string Name of the Control Group - :attr:`SPEED` float Speed multiplier set in the IR UI - :attr:`EXPANDED` bool True if Group is expanded in IR UI - :attr:`FORWARDKEY` string Key assigned to forward movement - :attr:`REVERSEKEY` string Key assigned to reverse movement + :attr:`NAME` :ref:`string ` Name of the Control Group + :attr:`SPEED` :ref:`scalar ` Speed multiplier set in the IR UI + :attr:`EXPANDED` :ref:`Boolean ` True if Group is expanded in IR UI + :attr:`FORWARDKEY` :ref:`string ` Key assigned to forward movement + :attr:`REVERSEKEY` :ref:`string ` Key assigned to reverse movement :attr:`SERVOS` List (readonly) List of servos in the group + :attr:`VESSEL` :struct:`Vessel` Vessel object, owning this servo group. Readonly, requires IR version 0.21.5 or later. :meth:`MOVERIGHT()` void Commands servos in the group to move in positive direction :meth:`MOVELEFT()` void Commands servos in the group to move in negative direction @@ -87,35 +90,35 @@ Access structure IRAddon via `ADDONS:IR`. .. attribute:: IRControlGroup:NAME - :type: string + :type: :ref:`string ` :access: Get/Set Name of the Control Group (cannot be empty). .. attribute:: IRControlGroup:SPEED - :type: float + :type: :ref:`scalar ` :access: Get/Set Speed multiplier as set in the IR user interface. Avoid setting it to 0. .. attribute:: IRControlGroup:EXPANDED - :type: bool + :type: :ref:`Boolean ` :access: Get/Set True if Group is expanded in IR UI .. attribute:: IRControlGroup:FORWARDKEY - :type: string + :type: :ref:`string ` :access: Get/Set Key assigned to forward movement. Can be empty. .. attribute:: IRControlGroup:REVERSEKEY - :type: string + :type: :ref:`string ` :access: Get/Set Key assigned to reverse movement. Can be empty. @@ -136,6 +139,13 @@ Access structure IRAddon via `ADDONS:IR`. } } +.. attribute:: IRControlGroup:VESSEL + + :type: :struct:`Vessel` + :access: Get only + + If IR 0.21.5 or later is installed will return a Vessel that owns this ServoGroup, otherwise will return current focused Vessel + .. method:: IRControlGroup:MOVERIGHT() :return: void @@ -175,115 +185,155 @@ Access structure IRAddon via `ADDONS:IR`. .. structure:: IRServo - ===================================== ========================= ============= - Suffix Type Description - ===================================== ========================= ============= - :attr:`NAME` string Name of the Servo - :attr:`UID` int Unique ID of the servo part (part.flightID). - :attr:`HIGHLIGHT` bool (set-only) Set Hightlight status of the part. - :attr:`POSITION` float (readonly) Current position of the servo. - :attr:`MINCFGPOSITION` float (readonly) Minimum position for servo as defined by part creator in part.cfg - :attr:`MAXCFGPOSITION` float (readonly) Maximum position for servo as defined by part creator in part.cfg - :attr:`MINPOSITION` float Minimum position for servo, from tweakable. - :attr:`MAXPOSITION` float Maximum position for servo, from tweakable. - :attr:`CONFIGSPEED` float (readonly) Servo movement speed as defined by part creator in part.cfg - :attr:`SPEED` float Servo speed multiplier, from tweakable. - :attr:`CURRENTSPEED` float (readonly) Current Servo speed. - :attr:`ACCELERATION` float Servo acceleration multiplier, from tweakable. - - :meth:`MOVERIGHT()` void Commands servo to move in positive direction - :meth:`MOVELEFT()` void Commands servo to move in negative direction - :meth:`MOVECENTER()` void Commands servo to move to default position - :meth:`MOVENEXTPRESET()` void Commands servo to move to next preset - :meth:`MOVEPREVPRESET()` void Commands servo to move to previous preset - :meth:`STOP()` void Commands servo to stop - :meth:`MOVETO(position, speedMult)` void Commands servo to move to `position` with `speedMult` multiplier - ===================================== ========================= ============= + ===================================== ==================================== ============= + Suffix Type Description + ===================================== ==================================== ============= + :attr:`NAME` :ref:`string ` Name of the Servo + :attr:`UID` :ref:`scalar ` (int) Unique ID of the servo part (part.flightID). + :attr:`HIGHLIGHT` :ref:`Boolean ` (set-only) Set Hightlight status of the part. + :attr:`POSITION` :ref:`scalar ` (readonly) Current position of the servo. + :attr:`MINCFGPOSITION` :ref:`scalar ` (readonly) Minimum position for servo as defined by part creator in part.cfg + :attr:`MAXCFGPOSITION` :ref:`scalar ` (readonly) Maximum position for servo as defined by part creator in part.cfg + :attr:`MINPOSITION` :ref:`scalar ` Minimum position for servo, from tweakable. + :attr:`MAXPOSITION` :ref:`scalar ` Maximum position for servo, from tweakable. + :attr:`CONFIGSPEED` :ref:`scalar ` (readonly) Servo movement speed as defined by part creator in part.cfg + :attr:`SPEED` :ref:`scalar ` Servo speed multiplier, from tweakable. + :attr:`CURRENTSPEED` :ref:`scalar ` (readonly) Current Servo speed. + :attr:`ACCELERATION` :ref:`scalar ` Servo acceleration multiplier, from tweakable. + :attr:`ISMOVING` :ref:`Boolean ` (readonly) True if Servo is moving + :attr:`ISFREEMOVING` :ref:`Boolean ` (readonly) True if Servo is uncontrollable (ex. docking washer) + :attr:`LOCKED` :ref:`Boolean ` Servo's locked status, set true to lock servo. + :attr:`INVERTED` :ref:`Boolean ` Servo's inverted status, set true to invert servo's axis. + :attr:`PART` :struct:`Part` A reference to a Part containing servo module. + + :meth:`MOVERIGHT()` void Commands servo to move in positive direction + :meth:`MOVELEFT()` void Commands servo to move in negative direction + :meth:`MOVECENTER()` void Commands servo to move to default position + :meth:`MOVENEXTPRESET()` void Commands servo to move to next preset + :meth:`MOVEPREVPRESET()` void Commands servo to move to previous preset + :meth:`STOP()` void Commands servo to stop + :meth:`MOVETO(position, speedMult)` void Commands servo to move to `position` with `speedMult` multiplier + ===================================== ==================================== ============= .. attribute:: IRServo:NAME - :type: string + :type: :ref:`string ` :access: Get/Set Name of the Control Group (cannot be empty). .. attribute:: IRServo:UID - :type: int + :type: :ref:`scalar ` :access: Get Unique ID of the servo part (part.flightID). .. attribute:: IRServo:HIGHLIGHT - :type: bool + :type: :ref:`Boolean ` :access: Set Set Hightlight status of the part. .. attribute:: IRServo:POSITION - :type: float + :type: :ref:`scalar ` :access: Get Current position of the servo. .. attribute:: IRServo:MINCFGPOSITION - :type: float + :type: :ref:`scalar ` :access: Get Minimum position for servo as defined by part creator in part.cfg .. attribute:: IRServo:MAXCFGPOSITION - :type: float + :type: :ref:`scalar ` :access: Get Maximum position for servo as defined by part creator in part.cfg .. attribute:: IRServo:MINPOSITION - :type: float + :type: :ref:`scalar ` :access: Get/Set Minimum position for servo, from tweakable. .. attribute:: IRServo:MAXPOSITION - :type: float + :type: :ref:`scalar ` :access: Get/Set Maximum position for servo, from tweakable. .. attribute:: IRServo:CONFIGSPEED - :type: float + :type: :ref:`scalar ` :access: Get Servo movement speed as defined by part creator in part.cfg .. attribute:: IRServo:SPEED - :type: float + :type: :ref:`scalar ` :access: Get/Set Servo speed multiplier, from tweakable. .. attribute:: IRServo:CURRENTSPEED - :type: float + :type: :ref:`scalar ` :access: Get Current Servo speed. .. attribute:: IRServo:ACCELERATION - :type: float + :type: :ref:`scalar ` :access: Get/Set Servo acceleration multiplier, from tweakable. +.. attribute:: IRServo:ISMOVING + + :type: :ref:`Boolean ` + :access: Get + + True if Servo is moving + +.. attribute:: IRServo:ISFREEMOVING + + :type: :ref:`Boolean ` + :access: Get + + True if Servo is uncontrollable (ex. docking washer) + +.. attribute:: IRServo:LOCKED + + :type: :ref:`Boolean ` + :access: Get/Set + + Servo's locked status, set true to lock servo. + +.. attribute:: IRServo:INVERTED + + :type: :ref:`Boolean ` + :access: Get/Set + + Servo's inverted status, set true to invert servo's axis. + +.. attribute:: IRServo:PART + + :type: :struct:`Part` + :access: Get + + Returns reference to the :struct:`Part` containing servo module. Please note that Part:UID does not equal IRServo:UID. + .. method:: IRServo:MOVERIGHT() diff --git a/doc/source/addons/KAC.rst b/doc/source/addons/KAC.rst index 3052be904..4ec13d60f 100644 --- a/doc/source/addons/KAC.rst +++ b/doc/source/addons/KAC.rst @@ -54,38 +54,38 @@ Access structure KACAddon via `ADDONS:KAC`. .. structure:: KACAlarm - ===================================== ========================= ============= - Suffix Type Description - ===================================== ========================= ============= - :attr:`ID` string (readonly) Unique identifier - :attr:`NAME` string Name of the alarm - :attr:`ACTION` string What should the Alarm Clock do when the alarm fires - :attr:`TYPE` string (readonly) What type of Alarm is this - affects icon displayed and some calc options - :attr:`NOTES` string Long description of the alarm (optional) - :attr:`REMAINING` scalar (s) Time remaining until alarm is triggered - :attr:`REPEAT` bool Should the alarm be repeated once it fires - :attr:`REPEATPERIOD` scalar (s) How long after the alarm fires should the next alarm be set up - :attr:`ORIGINBODY` string Name of the body the vessel is departing from - :attr:`TARGETBODY` string Name of the body the vessel is arriving at - ===================================== ========================= ============= + ===================================== ============================ ============= + Suffix Type Description + ===================================== ============================ ============= + :attr:`ID` :struct:`string` (readonly) Unique identifier + :attr:`NAME` :struct:`string` Name of the alarm + :attr:`ACTION` :struct:`string` What should the Alarm Clock do when the alarm fires + :attr:`TYPE` :struct:`string` (readonly) What type of Alarm is this - affects icon displayed and some calc options + :attr:`NOTES` :struct:`string` Long description of the alarm (optional) + :attr:`REMAINING` :struct:`scalar` (s) Time remaining until alarm is triggered + :attr:`REPEAT` :struct:`boolean` Should the alarm be repeated once it fires + :attr:`REPEATPERIOD` :struct:`scalar` (s) How long after the alarm fires should the next alarm be set up + :attr:`ORIGINBODY` :struct:`string` Name of the body the vessel is departing from + :attr:`TARGETBODY` :struct:`string` Name of the body the vessel is arriving at + ===================================== ============================ ============= .. attribute:: KACAlarm:ID - :type: string + :type: :ref:`string ` :access: Get only Unique identifier of the alarm. .. attribute:: KACAlarm:NAME - :type: string + :type: :ref:`string ` :access: Get/Set Name of the alarm. Displayed in main KAC window. .. attribute:: KACAlarm:ACTION - :type: string + :type: :ref:`string ` :access: Get/Set Should be one of the following @@ -99,7 +99,7 @@ Access structure KACAddon via `ADDONS:KAC`. .. attribute:: KACAlarm:TYPE - :type: string + :type: :ref:`string ` :access: Get only Can only be set at Alarm creation. @@ -126,7 +126,7 @@ Access structure KACAddon via `ADDONS:KAC`. .. attribute:: KACAlarm:NOTES - :type: string + :type: :ref:`string ` :access: Get/Set Long description of the alarm. Can be seen when alarm pops or by double-clicking alarm in UI. @@ -135,35 +135,35 @@ Access structure KACAddon via `ADDONS:KAC`. .. attribute:: KACAlarm:REMAINING - :type: double + :type: :ref:`scalar ` :access: Get only Time remaining until alarm is triggered. .. attribute:: KACAlarm:REPEAT - :type: bool - :access: Get/Set + :type: :ref:`boolean ` + :access: Get/Set - Should the alarm be repeated once it fires. + Should the alarm be repeated once it fires. .. attribute:: KACAlarm:REPEATPERIOD - :type: double - :access: Get/Set + :type: :ref:`scalar ` + :access: Get/Set - How long after the alarm fires should the next alarm be set up. + How long after the alarm fires should the next alarm be set up. .. attribute:: KACAlarm:ORIGINBODY - :type: string + :type: :ref:`string ` :access: Get/Set Name of the body the vessel is departing from. .. attribute:: KACAlarm:TARGETBODY - :type: string + :type: :ref:`string ` :access: Get/Set Name of the body the vessel is arriving to. @@ -193,7 +193,7 @@ Available Functions .. function:: LISTALARMS(alarmType) If `alarmType` equals "All", returns :struct:`List` of *all* :struct:`KACAlarm` objects attached to current vessel or have no vessel attached. - Otherwise returns :struct:`List` of all :struct:`KACAlarm` objects with `KACAlarm:TYPE` equeal to `alarmType' and attached to current vessel or have no vessel attached.:: + Otherwise returns :struct:`List` of all :struct:`KACAlarm` objects with `KACAlarm:TYPE` equeal to `alarmType` and attached to current vessel or have no vessel attached.:: set al to listAlarms("All"). for i in al diff --git a/doc/source/addons/OrbitalScience.rst b/doc/source/addons/OrbitalScience.rst new file mode 100644 index 000000000..965f4648d --- /dev/null +++ b/doc/source/addons/OrbitalScience.rst @@ -0,0 +1,41 @@ +.. _orbitalscience: + +DMagic Orbital Science +====================== + +DMagic Orbital Science is a modification for Squad’s "Kerbal Space Program" (KSP) which adds extra science experiments to the game. Those experiments under the hood work differently +than stock ones and require dedicated support (see :ref:`ScienceExperimentModule `). + +- Download: http://spacedock.info/mod/128/DMagic%20Orbital%20Science or https://github.com/DMagic1/Orbital-Science/releases +- Sources: https://github.com/DMagic1/Orbital-Science + +Most of the time Orbital Science experiments should work exactly like stock ones, +they inherit all suffixes from :ref:`ScienceExperimentModule `:: + + SET P TO SHIP:PARTSTAGGED("")[0]. + SET M TO P:GETMODULE("dmmodulescienceanimate"). + + PRINT M:ISRERUNNABLE. + PRINT M:INOPERABLE. + M:DEPLOY. + WAIT UNTIL M:HASDATA. + M:TRANSMIT. + +All Orbital Science experiments do get an extra :code:`TOGGLE` suffix that activates and +deactivates them:: + + + SET P TO SHIP:PARTSTAGGED("collector")[0]. + SET M TO P:GETMODULE("dmsolarcollector"). + + M:TOGGLE. + +`Submersible Oceanography and Bathymetry` has two extra suffixes that turn the experiment's +lights on and off:: + + SET P TO SHIP:PARTSTAGGED("bathymetry")[0]. + SET M TO P:GETMODULE("dmbathymetry"). + + M:LIGHTSON. + WAIT 3. + M:LIGHTSOFF. diff --git a/doc/source/addons/RemoteTech.rst b/doc/source/addons/RemoteTech.rst index 1ad08f764..6cc594f4c 100644 --- a/doc/source/addons/RemoteTech.rst +++ b/doc/source/addons/RemoteTech.rst @@ -15,25 +15,40 @@ Interaction with kOS When you have RemoteTech installed you can only interact with the core's terminal when you have a connection to KSC on any unmanned craft. Scripts launched when you still had a connection will continue to execute even if your unmanned craft loses connection to KSC. But you should note, that when there is no connection to KSC the archive volume is inaccessible. This will require you to plan ahead and copy necessary scripts for your mission to probe hard disk, if your kerbals and/or other scripts need to use them while not connected. +If you launch a manned craft while using RemoteTech, you are still able to input commands from the terminal even if you do not have a connection to the KSC. The archive will still be inaccessible without a connection to the KSC. Under the current implementation, there is no delay when accessing the archive with a local terminal. This implementation may change in the future to account for delays in reading and writing data over the connection. + +It is possible to activate/deactivate RT antennas, as well as set their targets using kOS:: + + SET p TO SHIP:PARTSNAMED("mediumDishAntenna")[0]. + SET m to p:GETMODULE("ModuleRTAntenna"). + m:DOEVENT("activate"). + m:SETFIELD("target", "mission-control"). + // or + m:SETFIELD("target", mun). + m:SETFIELD("target", "minmus"). + +Acceptable values for `"target"` are: `"no-target"`, `"active-vessel"`, `"mission-control"`, a :struct:`Body`, a :struct:`Vessel`, or a string containing the name of a body or vessel. + Starting version 0.17 of kOS you can access structure RTAddon via `ADDONS:RT`. .. structure:: RTAddon - ===================================== ========================= ============= - Suffix Type Description - ===================================== ========================= ============= - :attr:`AVAILABLE` bool(readonly) True if RT is installed and RT integration enabled. - :meth:`DELAY(vessel)` double Get shortest possible delay to given :struct:`Vessel` - :meth:`KSCDELAY(vessel)` double Get delay from KSC to given :struct:`Vessel` - :meth:`HASCONNECTION(vessel)` bool True if given :struct:`Vessel` has any connection - :meth:`HASKSCCONNECTION(vessel)` bool True if given :struct:`Vessel` has connection to KSC - ===================================== ========================= ============= + ===================================== ===================================== ============= + Suffix Type Description + ===================================== ===================================== ============= + :attr:`AVAILABLE` :ref:`Boolean ` (readonly) True if RT is installed and RT integration enabled. + :meth:`DELAY(vessel)` :ref:`scalar ` Get shortest possible delay to given :struct:`Vessel` + :meth:`KSCDELAY(vessel)` :ref:`scalar ` Get delay from KSC to given :struct:`Vessel` + :meth:`HASCONNECTION(vessel)` :ref:`Boolean ` True if given :struct:`Vessel` has any connection + :meth:`HASKSCCONNECTION(vessel)` :ref:`Boolean ` True if given :struct:`Vessel` has connection to KSC + :meth:`HASLOCALCONTROL(vessel)` :ref:`Boolean ` True if given :struct:`Vessel` has local control + ===================================== ===================================== ============= .. attribute:: RTADDON:AVAILABLE - :type: bool + :type: :ref:`Boolean ` :access: Get only True if RT is installed and RT integration enabled. @@ -41,27 +56,34 @@ Starting version 0.17 of kOS you can access structure RTAddon via `ADDONS:RT`. .. method:: RTAddon:DELAY(vessel) :parameter vessel: :struct:`Vessel` - :return: (double) seconds + :return: (:ref:`scalar `) seconds Returns shortest possible delay for `vessel` (Will be less than KSC delay if you have a local command post). .. method:: RTAddon:KSCDELAY(vessel) :parameter vessel: :struct:`Vessel` - :return: (double) seconds + :return: (:ref:`scalar `) seconds Returns delay in seconds from KSC to `vessel`. .. method:: RTAddon:HASCONNECTION(vessel) :parameter vessel: :struct:`Vessel` - :return: bool + :return: :ref:`Boolean ` Returns True if `vessel` has any connection (including to local command posts). .. method:: RTAddon:HASKSCCONNECTION(vessel) :parameter vessel: :struct:`Vessel` - :return: bool + :return: :ref:`Boolean ` Returns True if `vessel` has connection to KSC. + +.. method:: RTAddon:HASLOCALCONTROL(vessel) + + :parameter vessel: :struct:`Vessel` + :return: :ref:`Boolean ` + + Returns True if `vessel` has local control (and thus not requiring a RemoteTech connection). diff --git a/doc/source/bindings.rst b/doc/source/bindings.rst index 451203c0b..455a5dc0b 100644 --- a/doc/source/bindings.rst +++ b/doc/source/bindings.rst @@ -16,19 +16,41 @@ NAMED VESSELS AND BODIES SHIP: -| **Variable name**: SHIP -| **Gettable**: yes -| **Settable**: no -| **Type**: `Vessel `__ -| **Description**: Whichever vessel happens to be the one containing the CPU part that is running this Kerboscript code at the moment. This is the `CPU Vessel `__. +- **Variable name**: SHIP +- **Gettable**: yes +- **Settable**: no +- **Type**: `Vessel `__ +- **Description**: Whichever vessel happens to be the one containing the + CPU part that is running this Kerboscript code at the moment. This is + the `CPU Vessel `__. TARGET: -| **Variable Name**: TARGET -| **Gettable**: yes -| **Settable**: yes -| **Type**: `Vessel `__ or `Body `__ -| **Description**: Whichever `Orbitable `__ object happens to be the one selected as the current KSP target. If set to a string, it will assume the string is the name of a vessel being targetted and set it to a vessel by that name. For best results set it to Body("some name") or Vessel("some name") explicitly. +- **Variable Name**: TARGET +- **Gettable**: yes +- **Settable**: yes +- **Type**: `Vessel `__ or + `Body `__ +- **Description**: Whichever `Orbitable `__ + object happens to be the one selected as the current KSP target. If set + to a string, it will assume the string is the name of a vessel being + targeted and set it to a vessel by that name. For best results set it + to Body("some name") or Vessel("some name") explicitly. This will + throw an exception if called from a vessel other than the active vessel, + as limitations in how KSP sets the target vessel limit the + implementation to working with only the active vessel. + +.. _hastarget: + +HASTARGET: + +- **Variable Name**: TARGET +- **Gettable**: yes +- **Settable**: no +- **Type**: boolean +- **Description**: Will return true if the ship has a target selected. + This will always return false when not on the active vessel, due to + limitations in how KSP sets the target vessel. Alias shortcuts for SHIP fields ------------------------------- @@ -57,12 +79,11 @@ BODY Same as SHIP:BODY ANGULARMOMENTUM Same as SHIP:ANGULARMOMENTUM ANGULARVEL Same as SHIP:ANGULARVEL ANGULARVELOCITY Same as SHIP:ANGULARVEL -COMMRANGE Same as SHIP:COMMRANGE MASS Same as SHIP:MASS VERTICALSPEED Same as SHIP:VERTICALSPEED -SURFACESPEED Same as SHIP:SURFACESPEED +GROUNDSPEED Same as SHIP:GROUNDSPEED +SURFACESPEED This has been obsoleted as of kOS 0.18.0. Replace it with GROUNDSPEED. AIRSPEED Same as SHIP:AIRSPEED -VESSELNAME Same as SHIP:VESSELNAME ALTITUDE Same as SHIP:ALTITUDE APOAPSIS Same as SHIP:APOAPSIS PERIAPSIS Same as SHIP:PERIAPSIS @@ -71,9 +92,64 @@ SRFPROGRADE Same as SHIP:SRFPROGRADE SRFREROGRADE Same as SHIP:SRFREROGRADE OBT Same as SHIP:OBT STATUS Same as SHIP:STATUS -VESSELNAME Same as SHIP:NAME +SHIPNAME Same as SHIP:NAME ================ ============================================================================== +Constants (pi, e, etc) +---------------------- + +Get-only. + +The variable ``constant`` provides a way to access a few +:ref:`basic math and physics constants `, such as Pi, Euler's +number, and so on. + +Example:: + + print "Kerbin's circumference: " + (2*constant:pi*Kerbin:radius) + "meters.". + +The full list is here: :ref:`constants page `. + +Terminal +-------- + +Get-only. ``terminal`` returns a :struct:`terminal` structure describing +the attributes of the current terminal screen associated with the +CPU this script is running on. + +Core +---- + +Get-only. ``core`` returns a :struct:`core` structure referring to the CPU you +are running on. + +Archive +------- + +Get-only. ``archive`` returns a :struct:`Volume` structure referring to the archive. +You can read more about what archive is on the :ref:`File & volumes ` page. + +Stage +----- + +Get-only. ``stage`` returns a :struct:`stage` structure used to count resources +in the current stage. Not to be confused with the COMMAND stage +which triggers the next stage. + +NextNode +-------- + +Get-only. ``nextnode`` returns the next planned maneuver :struct:`node` in the SHIP's flight plan. Will throw an exception if +no node exists, or if called on a ship that is not the active vessel. + +.. _hasnode: + +HasNode +-------- + +Get-only. ``hasnode`` returns true if there is a planned maneuver :struct:`node` in the SHIP's flight plan. This will always return +false for the non-active vessel, as access to maneuver nodes is limited to the active vessel. + Resource Types -------------- @@ -92,7 +168,7 @@ corner of the screen in the KSP window. |Resources| All of the above resources can be queried using either the prefix SHIP or STAGE, depending on whether you are trying to query how much is left -in the curent stage or the entire ship: +in the current stage or the entire ship: How much liquid fuel is left in the entire ship: @@ -118,45 +194,46 @@ the term exactly as it appears in the resources window. You can also get a list of all resources, either in SHIP: or STAGE: with the :RESOURCES suffix. +.. |Resources| image:: /_images/reference/bindings/resources.png + ALT ALIAS --------- -The special variable ALT is a unique exception. It behaves like a -structure with suffixes but it's actually a bit "fake" in that it's not -really a structure. The following terms are just exceptions that don't -fit anywhere else: +The special variable `ALT `__ gives you +access to a few altitude predictions: + +ALT:APOAPSIS + +ALT:PERIAPSIS + +ALT:RADAR + +Further details are found on the `ALT page `__ . -============== ======== ========== -Variable Type Meaning -============== ======== ========== -ALT:APOAPSIS number The altitude of the apoapsis of the current ship. Identical to SHIP:APOAPSIS. -ALT:PERIAPSIS number The altitude of the periapsis of the current ship. Identical to SHIP:PERIAPSIS. -ALT:RADAR number The altitude of the current ship above the terrain. Does not have an alias anywhere. -============== ======== ========== ETA ALIAS --------- -The special variable ETA is a unique exception. It behaves like a -structure with suffixes but it's actually a bit "fake" in that it's not -really a structure. The following terms are just exceptions that don't -fit anywhere else: +The special variable `ETA `__ gives you +access to a few time predictions: + +ETA:APOAPSIS -============== ======== ========== -Variable Type Meaning -============== ======== ========== -ETA:APOAPSIS number seconds until SHIP will reach its apoapsis. -ETA:PERIAPSIS number seconds until SHIP will reach its periapsis. -ETA:TRANSITION number seconds until SHIP will leave its SOI to enter the SOI of another body. -============== ======== ========== +ETA:PERIAPSIS + +ETA:TRANSITION + +Further details are found on the `ETA page `__ . ENCOUNTER --------- -The body being encountered next by the current vessel. Returns the -special string "None" if there is no expected encounter, or an object of -type `Body `__ if an encounter is -expected. +The orbit patch describing the next encounter with a body the current +vessel will enter. If there is no such encounter coming, it will return +the special string "None". If there is an encounter coming, it will +return an object :ref:`of type Orbit `. (i.e. to obtain the name +of the planet the encounter is with, you can do: +``print ENCOUNTER:BODY:NAME.``, for example.). BOOLEAN TOGGLE FIELDS: ---------------------- @@ -229,16 +306,65 @@ Controls that must be used with LOCK WHEELTHROTTLE // Separate throttle for wheels WHEELSTEERING // Separate steering system for wheels +Time +---- + +MISSIONTIME +~~~~~~~~~~~~~~~~~~~ + +You can obtain the number of seconds it has been since the current +CPU vessel has been launched with the bound global variable +``MISSIONTIME``. In real space programs this is referred to usually +as "MET" - Mission Elapsed Time, and it's what's being measured when +you hear that familiar voice saying "T minus 10 seconds..." Point "T" +is the zero point of the mission elapsed time, and everything before that +is a negative number and everything after it is a positive number. +kOS is only capable of returning the "T+" times, not the "T-" times, +because it doesn't read your mind to know ahead of time when you plan +to launch. + +Time Structure +~~~~~~~~~~~~~~ + +`Time `__ is the simulated amount of time that passed since the beginning of the game's universe epoch. (A brand new campaign that just started begins at TIME zero.) + +TIME is a useful system variable for calculating the passage of time +between taking +physical measurements (i.e. to calculate how fast a phenomenon is +changing in a loop). +It returns the KSP *simulated* time, rather than the actual realtime +sitting in the +chair playing the game. If everything is running smoothly on a fast +computer, one +second of simulated time will match one second of real time, but if +anything is +causing the game to stutter or lag a bit, then the simulated time will +be a bit +slower than the real time. For any script program trying to calculate +physical +properties of the KSP universe, the time that matters is the simulated +time, which +is what TIME returns. + +It's important to be aware of the `frozen update +nature `__ of the kOS +computer when reading TIME. + System Variables ---------------- -Returns values about kOS and hardware +This section is about variables that describe the things that are slightly +outside the simulated universe of the game and are more about +the game's user interface or the kOS mod itself. They represent things +that slightly "break the fourth wall" and let your script access +something entirely outside the in-character experience. :: - PRINT VERSION. // Returns operating system version number. i.e. 0.8.6 + PRINT VERSION. // Returns operating system version number. e.g. 0.8.6 PRINT VERSION:MAJOR. // Returns major version number. e.g. 0 PRINT VERSION:MINOR. // Returns minor version number. e.g. 8 + PRINT VERSION:BUILD. // Returns build version number. e.g. 6 PRINT SESSIONTIME. // Returns amount of time, in seconds, from vessel load. NOTE the following important difference: @@ -250,54 +376,87 @@ TIME is the time since the entire saved game campaign started, in the kerbal universe's time. i.e. TIME = 0 means a brand new campaign was just started. -WARPING -~~~~~~~ +KUNIVERSE +~~~~~~~~~ -Time warp can be controlled with WARP, and WARPMODE. See -:ref:`WARP ` +:ref:`Kuniverse ` is a structure that contains many settings that +break the fourth wall a little bit and control the game simulation directly. +The eventual goal is probably to move many of the variables you see listed +below into ``kuniverse``. Config ------- +~~~~~~ CONFIG is a special variable name that refers to the configuration -settings for -the kOS mod, and can be used to set or get various options. +settings for the kOS mod, and can be used to set or get various +options. `CONFIG has its own page `__ for further details. -Game State ----------- +WARP and WARPMODE +~~~~~~~~~~~~~~~~~ -Variables that have something to do with the state of the universe. +Time warp can be controlled with the variables +WARP and WARPMODE. See :ref:`WARP ` -========= ====================================== ============== -Variable Type Meaning -========= ====================================== ============== -TIME `Time `__ Simulated amount of time that passed since the beginning of the game's universe epoch. (A brand new campaign that just started begins at TIME zero.) -MAPVIEW boolean Both settable and gettable. If you query MAPVIEW, it's true if on the map screen, and false if on the flight view screen. If you SET MAPVIEW, you can cause the game to switch between mapview and flight view or visa versa. -========= ====================================== ============== +MAPVIEW +~~~~~~~ -TIME is a useful system variable for calculating the passage of time -between taking -physical measurements (i.e. to calculate how fast a phenomenon is -changing in a loop). -It returns the KSP *simulated* time, rather than the actual realtime -sitting in the -chair playing the game. If everything is running smoothly on a fast -computer, one -second of simulated time will match one second of real time, but if -anything is -causing the game to stutter or lag a bit, then the simulated time will -be a bit -slower than the real time. For any script program trying to calculate -physical -properties of the KSP universe, the time that matters is the simulated -time, which -is what TIME returns. +A boolean that is both gettable and settable. -It's important to be aware of the `frozen update -nature `__ of the kOS -computer when reading TIME. +If you query MAPVIEW, it's true if on the map screen, and false if on the flight view screen. If you SET MAPVIEW, you can cause the game to switch between mapview and flight view or visa versa. -.. |Resources| image:: /_images/reference/bindings/resources.png +LOADDISTANCE +~~~~~~~~~~~~ + +LOADDISTANCE sets the distance from the active vessel at +which vessels get removed from the full physics engine and put +on-rails, or visa versa. Note that as of KSP 1.0 the stock game +supports multiple different load distance settings for different +situations such that the value changes depending on where you are. +But kOS does not support this at the moment so in kOS if you set +the LOADDISTANCE, you are setting it to the same value +universally for all situations. + +.. _solarprimevector: + +SOLARPRIMEVECTOR +---------------- + +Gives the Prime Meridian :struct:`Vector` for the Solar System itself, in +current Ship-Raw XYZ coordinates. + +Both the :attr:`Orbit:LONGITUDEOFASCENDINGNODE` orbit suffix and the +:attr:`Body:ROTATIONANGLE` body suffix are expressed in terms of +degree offsets from this *Prime Meridian Reference Vector*. + +What is the Solar Prime Reference Vector? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The solar prime vector is an arbitrary vector in space used to measure +some orbital parameters that are supposed to remain fixed to space +regardless of how the planets underneath the orbit rotate, or where the +Sun is. In a sense it can be thought of as the celestial "prime +meridian" of the entire solar system, rather than the "prime meridian" of +any one particular rotating planet or moon. + +In a hypothetical Earthling's solar system our Kerbal scientists have +hypothesized may exist in a galaxy far away, Earthbound astronomers use +a reference they called the +`First Point of Aries `__, +for this purpose. + +For Kerbals, it refers to a more arbitrary line in space, pointing at a fixed +point in the firmament, also known as the "skybox". + +Addons +------ + +Get-only. ``addons`` is a special variable used to access various extensions +to kOS that are designed to support the features introduced by some other mods. More info can be found on the :ref:`addons ` page. + +Colors +------ + +There are several bound variables associated with :ref:`hardcoded colors ` such as WHITE, BLACK, RED, etc. See the linked page for the full list. diff --git a/doc/source/changes.rst b/doc/source/changes.rst index 59ab95495..de72b5df0 100644 --- a/doc/source/changes.rst +++ b/doc/source/changes.rst @@ -9,10 +9,383 @@ users familiar with older versions of the documentation who want only a quick update to the docs without reading the entire set of documentation again from scratch. +This list is NOT a comprehensive list of everything. Specifically, +minor one-line changes, or bug fixes, are not mentioned here. + +Most importantly, changes that might have broken previously working +scripts are not always signposted here. To be sure, you should read +the change log in the main github repository, which is repeated in the +release announcements that are made in various places with each +release. + .. contents:: :local: :depth: 3 +**** + +Changes in 0.19.1 +----------------- + +This change was mostly for small bug fixes and didn't affect the +documentation much. + +Mentioned PIDLoop() function in tutorial +:::::::::::::::::::::::::::::::::::::::: + +:ref:`Added section to PID loop tutorial ` +that explains better that there's a new function for doing PID loops. +The tutorial had been originally written before that function existed. + + +New Terminal brightness and char size features +:::::::::::::::::::::::::::::::::::::::::::::: + +:struct:`Terminal` structure now has suffixes, :attr:`TERMINAL:BRIGHTNESS`, +:attr:`TERMINAL:CHARWIDTH`, and :attr:`TERMINAL:CHARHEIGHT` to go with +the new widgets on the terminal GUI. + +Changes in 0.19.0 +----------------- + +Art asset changes +::::::::::::::::: + +Though not represented in these documents, numerous changes to the +part models and artwork are included as part of this update, including +the new KAL9000 high-end computer part. + +Varying Power Consumption +::::::::::::::::::::::::: + +:ref:`Electrical drain ` is now handled in a dynamically +changing way that actually notices how much you are using the CPU and +uses less power if the CPU is mostly idling (if it spends most of its +time on WAIT statements). + +For mods that want to re-balance the meaning of electric charge units, +the drain factor is also editable in +:ref:`module config fields ` in the various ``part.cfg`` +files the mod ships with. This opens them up to being changed by +ModuleManager rules. + +Delegates (function pointers) +::::::::::::::::::::::::::::: + +User functions and built-in functions (but not suffixes yet) can +now be referred to with function pointers called :ref:`delegates ` +along with "currying" of pre-loaded arguments. + +Optional Defaulted Parameters +::::::::::::::::::::::::::::: + +User functions and user programs can now be configured to have +:ref:`optional trailing parameters ` that receive +unmentioned when calling them. + +File I/O +:::::::: + +:ref:`VolumeFile ` now lets you read and write arbitrary +strings in files in a more natural way than using the LOG command, +and allows you to read the whole file into one big string in one go. + +Serialization in JSON +::::::::::::::::::::: + +Automatic serialization system added to the :ref:`file operations ` +to save/load some kinds of data values to +`JSON-format files. `__ + +Universal Object Suffixes +::::::::::::::::::::::::: + +All user values now are a kind of :ref:`structure ` and thus +there are a few universal suffixes that can be used to query what +type of data a thing is (``:ISTYPE`` and ``:TYPENAME``). + +Multimode Engine and Gimbal Support +::::::::::::::::::::::::::::::::::: + +:ref:`Engines ` can now support multiple-mode information, and can +acces thei gimbal information in the ``:GIMBAL`` suffix. + +DMagic Orbital Science +:::::::::::::::::::::: + +Better support for :ref:`DMagic's Orbital Science mod ` + +Range +::::: + +New :ref:`Range ` type for getting arbitrary iterable collections +of ranges of integers. + +Char and Unchar +::::::::::::::: + +:func:`CHAR(a)` and :func:`UNCHAR(a)` functions for getting the Unicode +value of a character or making a character from its Unicode value. + +For loop on string chars +:::::::::::::::::::::::: + +The for loop can now iterate over the characters of a :ref:`string `. + +HASTARGET, HASNODE +:::::::::::::::::: + +:ref:`HASTARGET `. +:ref:`HASNODE `. + +JOIN +:::: + +Join suffix on :ref:`lists ` now lets you make a string with a +delimeter of the list's elements. + +Hours per day +::::::::::::: + +:ref:`KUniverse ` now has a suffix to let you read the +user setting for whether the clock is using a 24 hour day or a +Kerbin 6 hour day. + +Archive +::::::: + +The reserved word ``Archive`` is now a first class citizen so that +``SET FOO TO ARCHIVE.`` works like you'd expect it to. + +Changes in 0.18.2 +----------------- + +Queue and Stack +::::::::::::::: + +:ref:`Queues ` and :ref:`Stacks ` are now a feature +you can use along with lists. + +Run Once +:::::::: + +:ref:`New ONCE argment to the run command ` + +Volumes and Processors integration +:::::::::::::::::::::::::::::::::: + +:ref:`Volumes ` now get a default name equal to the core +processor's nametag, and have several suffixes that can be queried. + +Get the volume that goes with a :ref:`core ` + +Debuglog +:::::::: + +:ref:`Debuglog ` suffix of KUNIVERSE for writing messages to the +Unity log file. + + +Changes in 0.18.1 +----------------- + +(This update had only bug fixes and nothing that affected these +user documentation pages.) + +Changes in 0.18 - Steering Much Betterer +---------------------------------------- + +Steering Overhaul +::::::::::::::::: + +A major change to Cooked Steering! + +Should help people using torque-less craft like with Realism Overhaul. +Removed the old steering logic and replaced it with a nice auto-tuning system. + +:ref:`SteeringManager ` structure now lests you acccess and alter parts of the cooked steering system. + +:ref:`PIDLoop ` structure now lets you borrow the PID mechanism used by the new cooked steering, for your own purposes. + +Lexicon +::::::: + +New :ref:`Lexicon ` structure now allows associative arrays. + +String methods +:::::::::::::: + +New :ref:`String ` structure now allows string manipulations. + +Science Experiment Control +:::::::::::::::::::::::::: + +New :ref:`ScienceExperimentModule ` allows you to fire off science experiments bypassing the user +interface dialog. + +Crew Member API +::::::::::::::: + +New :ref:`CrewMember ` structure allows you to query the registered crew - their class, gender, and skill. + +LOADISTANCE +::::::::::: + +New :struct:`LOADDISTANCE` obsoletes the previous way it worked. + +Infernal Robotics Part suffix +::::::::::::::::::::::::::::: + +Renamed built-ins +::::::::::::::::: + +"AQUIRE" on docking ports is now "ACQUIRE". +"SURFACESPEED" is now "GROUNDSPEED" instead. + +Enforces control of own-vessel only +::::::::::::::::::::::::::::::::::: + +It was previously possible to control vessels that weren't attached to the kOS computer +running the script. This has been corrected. + +New quickstart tutorial +::::::::::::::::::::::: + +`http://ksp-kos.github.io/KOS_DOC/tutorials/quickstart.html `_ + +A few more constants +:::::::::::::::::::: + +:ref:`constants ` + +Dynamic pressure +:::::::::::::::: + +DYNAMICPRESSURE, or Q, a new suffix of :struct:`Vessel`. + +DEFINED keyword +::::::::::::::: + +:ref:`DEFINED keyword ` that can be used to check if a variable has been declared. + +KUNIVERSE +::::::::: + +:struct:`KUniverse` structure letting you break the 4th wall and revert from a script + +SolarPrimeVector +:::::::::::::::: + +:ref:`SolarPrimeVector `, a bound variable to provide universal longitude direction. + + +**** + +Changes in 0.17.3 +----------------- + +New Looping control flow, the FROM loop +::::::::::::::::::::::::::::::::::::::: + +There is now a new kind of loop, :ref:`the FROM loop `, +which is a bit like the typical 3-part for-loop seen in a +lot of other languages with a separate init, check, and increment +section. + +Short-Circuit Booleans +:::::::::::::::::::::: + +Previously, kerboscript's AND and OR operators were not +short-circuiting. :ref:`Now they are `. + +New Infernal Robotics interface +::::::::::::::::::::::::::::::: + +There are a few new helper addon utilities for the Infernal +Robotics mod, on the :ref:`IR addon page `. + +New RemoteTech interface +:::::::::::::::::::::::: + +There are a few new helper addon utilities for the RemoteTech +mod, on the :ref:`RemoteTech addon page `. + +Deprecated INCOMMRANGE +:::::::::::::::::::::::::: + +Reading from the INCOMMRANGE bound variable will now throw a +deprecation exception with instructions to use the new +:struct:`RTAddon` structure for the RT mod. + +Updated thrust calculations for 1.0.x +::::::::::::::::::::::::::::::::::::: + +KSP 1.0 caused the thrust calculations to become a LOT more +complex than they used to be and kOS hadn't caught up yet. +For a lot of scripts, trying to figure out a good throttle +setting is no longer a matter of just taking a fraction of the +engine's MAXTHRUST. + +We fixed the existing suffixes of MAXTHRUST and AVAILABLETHRUST for +:struct:`engine` and :struct:`vessel` to account for the new changes +in thrust based on +ISP at different altitudes. MAXTHRUST is now the max the engine can +put out at the CURRENT atmospheric pressure and current velocity. +It might not be the maximum it could put out under other conditions. +The AVAILABLETHRUST suffix is now implemented for engines (it was +previously only available on vessels). There are also new +suffixes MAXTHRUSTAT (engines and vessels), AVAILABLETHRUSTAT +(engines and vessels), and ISPAT (engines only) to +read the applicable value at a given atmospheric pressure. + +New CORE struct +::::::::::::::: + +The :ref:`core ` bound variable gives you a structure you can use +to access properties of the current in-game CPU the script is running on, +including the vessel part it's inside of, and the vessel it's inside +of, as well as the currently selected volume. Moving forward this +will be the struct where we enable features that interact with +the processor itself, like local configuration or current +operational status. + +Updated boot file name handling +::::::::::::::::::::::::::::::: + +Boot files are now copied to the local hard disk using their original +file name. This allows for uniform file name access either on the +archive or local drive and fixes boot files not working when kOS is +configured to start on the Archive. You can also get or set the boot +file using the BOOTFILENAME suffix of the :struct:`CORE` bound variable. + +Docking port, element, and vessel references +:::::::::::::::::::::::::::::::::::::::::::: + +You can now get a list of docking ports on any element or vessel using +the DOCKINGPORTS suffix. Vessels also expose a list of their elements +(the ELEMENTS suffix) and an element will refernce it's parent vessel +(the VESSEL suffix). + +New sounds and terminal features +:::::::::::::::::::::::::::::::: + +For purely cosmetic purpopses, there are new sound features and + a few terminal tweaks. + +- A terminal keyclick option for the in-game GUI terminal. +- The ability to BEEP when printing ascii code 7 (BEL), although + the only way currently to achieve this is with the KSlib's spec_char.ksm + file, as kOS has no BEL char, but this will be addressed later. +- A sound effect on exceptions, which can be turned off on the CONFIG panel. + +Clear vecdraws all at once +:::::::::::::::::::::::::: + +For convenience, you can clear all vecdraws off the screen at once +now with the :ref:`clearvecdraws() ` function. + +**** + Changes in 0.17.0 ----------------- diff --git a/doc/source/commands.rst b/doc/source/commands.rst index 89adff2e7..100639551 100644 --- a/doc/source/commands.rst +++ b/doc/source/commands.rst @@ -12,4 +12,5 @@ Command Reference Parts Information File I/O Terminal and GUI - Resource Transfer \ No newline at end of file + Resource Transfer + Processors diff --git a/doc/source/commands/files.rst b/doc/source/commands/files.rst index d1eb46687..a50862f65 100644 --- a/doc/source/commands/files.rst +++ b/doc/source/commands/files.rst @@ -5,9 +5,25 @@ File I/O For information about where files are kept and how to deal with volumes see the :ref:`Volumes ` page in the general topics section of this documentation. +.. contents:: + :local: + :depth: 2 + .. note:: - All file names (program names) must be valid Identifiers. They can not contain spaces or special characters. For example, you can't have a file name called "this is my-file". + *Limitations on file names used for programs* + + All file names used as program names with the ``run`` command must be + valid identifiers. They can not contain spaces or special characters. For + example, you can't have a program named ``this is my-file.ks``. This rule + does not necessarily apply to other filenames such as log files. However + to use a filename that contains spaces, you will have to put quotes around + it. + + On case-sensitive filesystems typically found on Linux and Mac, you should + name program files used with the ``run`` command entirely with + lowercase-only filenames or the system may fail to find them when you + use the ``run`` command. .. warning:: @@ -34,8 +50,10 @@ of the RUN command\*\*, follow these rules: filename. - A bareword filename may contain file extensions with dots, provided it does not end in a dot. -- If the filename does not contain a file extension, kOS will pad it - with a ".ks" extension and use that. +- Commands that try to read files will add '.ks' to filenames if + the original filename was not found, for example ``RUN abc.`` + will first look for a file named ``abc``. If such a file is not found + it will look for ``abc.ks``. Putting the above rules together, you can refer to filenames in any of the following ways: @@ -77,8 +95,8 @@ example: - set volNum to 1. copy "myfile" to volNum. -``COMPILE program (TO compiledProgram).`` ------------------------------------------ +COMPILE program (TO compiledProgram). +------------------------------------- **(experimental)** @@ -102,8 +120,8 @@ placed on a separate page. Please see :ref:`the details of the Kerboscript ML Executable `. -``COPY programFile FROM/TO voumeNumber.`` ------------------------------------------ +COPY programFile FROM/TO Volume|volumeId|volumeName. +---------------------------------------------------- Arguments ^^^^^^^^^ @@ -112,7 +130,7 @@ Arguments - argument 2: Target volume. Copies a file to or from another volume. Volumes can be referenced by -their ID numbers or their names if they’ve been given one. See LIST, +instances of :struct:`Volume`, their ID numbers or their names if they’ve been given one. See LIST, SWITCH and RENAME. Understanding how :ref:`volumes @@ -121,19 +139,22 @@ understanding this command. Example:: - SWITCH TO 1. // Makes volume 1 the active volume - COPY file1 FROM 0. // Copies a file called file1.ks from volume 0 to volume 1 - COPY file2 TO 0. // Copies a file called file1.ks from volume 1 to volume 0 - COPY file1.ks FROM 0. // Copies a file called file1.ks from volume 0 to volume 1 - COPY file2.ksm TO 0. // Copies a file called file1.ksm from volume 1 to volume 0 - COPY "file1.ksm" FROM 0. // Copies a file called file1.ksm from volume 0 to volume 1 + SWITCH TO 1. // Makes volume 1 the active volume + COPY file1 FROM 0. // Copies a file called file1.ks from volume 0 to volume 1 + COPY file2 TO 0. // Copies a file called file2.ks from volume 1 to volume 0 + COPY file1.ks FROM 0. // Copies a file called file1.ks from volume 0 to volume 1 + COPY file2.ksm TO 0. // Copies a file called file2.ksm from volume 1 to volume 0 + COPY "file1.ksm" FROM 0. // Copies a file called file1.ksm from volume 0 to volume 1 COPY "file1" + "." + "ks" FROM 0. // Copies a file called file1.ks from volume 0 to volume 1 + COPY file2.ksm TO CORE:VOLUME. // Copies a file called file2.ksm to active processor's volume + COPY file2.ksm TO "other". // Copies a file called file2.ksm to volume named 'other' -``DELETE filename FROM volumeNumber.`` --------------------------------------- +DELETE filename FROM Volume|volumeId|volumeName. +------------------------------------------------ -Deletes a file. You can delete a file from the current volume, or from a named volume. +Deletes a file. Volumes can be referenced by instances of :struct:`Volume`, their ID numbers or their names +if they’ve been given one. Arguments ^^^^^^^^^ @@ -143,15 +164,17 @@ Arguments Example:: - DELETE file1. // Deletes file1.ks from the active volume. - DELETE "file1". // Deletes file1.ks from the active volume. - DELETE file1.txt. // Deletes file1.txt from the active volume. - DELETE "file1.txt". // Deletes file1.txt from the active volume. - DELETE file1 FROM 1. // Deletes file1.ks from volume 1 + DELETE file1. // Deletes file1.ks from the active volume. + DELETE "file1". // Deletes file1.ks from the active volume. + DELETE file1.txt. // Deletes file1.txt from the active volume. + DELETE "file1.txt". // Deletes file1.txt from the active volume. + DELETE file1 FROM 1. // Deletes file1.ks from volume 1 + DELETE file1 FROM CORE:VOLUME. // Deletes file1.ks from active processor's volume + DELETE file1 FROM "other". // Deletes file1.ks from volume name 'other' -``EDIT program.`` ------------------ +EDIT program. +------------- Edits a program on the currently selected volume. @@ -173,8 +196,8 @@ Example:: EDIT "filename.txt". // edits filename.txt -``LOG text TO filename.`` -------------------------- +LOG text TO filename. +--------------------- Logs the selected text to a file on the local volume. Can print strings, or the result of an expression. @@ -186,15 +209,19 @@ Arguments Example:: - LOG “Hello†to mylog.txt. // logs to "mylog.txt". + LOG "Hello" to mylog.txt. // logs to "mylog.txt". LOG 4+1 to "mylog" . // logs to "mylog.ks" because .ks is the default extension. - LOG “4 times 8 is: “ + (4*8) to mylog. // logs to mylog.ks because .ks is the default extension. + LOG "4 times 8 is: " + (4*8) to mylog. // logs to mylog.ks because .ks is the default extension. + +RENAME VOLUME Volume|volumeId|oldVolumeName TO name. +---------------------------------------------------- -``RENAME name1 TO name2.`` --------------------------- +RENAME FILE oldName TO newName. +------------------------------- -Renames a file or volume. +Renames a file or volume. Volumes can be referenced by +instances of :struct:`Volume`, their ID numbers or their names if they've been given one. Arguments ^^^^^^^^^ @@ -207,11 +234,22 @@ Example:: RENAME VOLUME 1 TO AwesomeDisk RENAME FILE MyFile TO AutoLaunch. -``RUN .`` ------------------- +.. _run_once: + +RUN [ONCE] . +--------------------- Runs the specified file as a program, optionally passing information to the program in the form of a comma-separated list of arguments in parentheses. +If the optional ``ONCE`` keyword is used after the word ``RUN``, it means +the run will not actually occur if the program has already been run once +during the current program context. This is intended mostly for loading library +program files that may have mainline code in them for initialization purposes +that you don't want to get run a second time just because you use the library +in two different subprograms. + +``RUN ONCE`` means "Run unless it's already been run, in which case skip it." + Arguments ^^^^^^^^^ @@ -227,6 +265,8 @@ Example:: RUN AutoLaunch.ks( 75000, true, "hello" ). RUN AutoLaunch.ksm( 75000, true, "hello" ). + RUN ONCE myLibrary. // run myLibrary unless it's been run already. + The program that is reading the arguments sees them in the variables it mentions in :ref:`DECLARE PARAMETER`. @@ -245,25 +285,21 @@ RUN only works when the filename is a bareword filename. It cannot use expressio // called "ProgName.ksm" or "ProgName.ks", when it sees this, // rather than "MyProgram". - The reasons for the exception to how filenames work for the RUN - command are too complex to go into in large detail here. Here's the - short version: While the kOS system does defer the majority of the - work - of actually compiling subprogram scripts until run-time, it still - has to - generate some header info about them at compile time, and the - filename - has to be set in stone at that time. Changing this would require a - large re-write of some of the architecture of the virtual machine. +The reasons for the exception to how filenames work for the RUN command are +too complex to go into in large detail here. Here's the short version: While +the kOS system does defer the majority of the work of actually compiling +subprogram scripts until run-time, it still has to generate some header info +about them at compile time, and the filename has to be set in stone at that +time. Changing this would require a large re-write of some of the architecture +of the virtual machine. -``SWITCH TO .`` ------------------------------ +SWITCH TO Volume|volumeId|volumeName. +------------------------------------- -Switches to the specified volume. Volumes can be specified by number, or -it’s name (if it has one). See LIST and RENAME. Understanding how -:ref:`volumes work ` is important -to understanding this command. +Switches to the specified volume. Volumes can be referenced by +instances of :struct:`Volume`, their ID numbers or their names if they've been given one. See LIST and RENAME. Understanding how +:ref:`volumes work ` is important to understanding this command. Example:: @@ -272,25 +308,79 @@ Example:: SWITCH TO AwesomeDisk. // Switch to volume 1. PRINT VOLUME:NAME. // Prints "AwesomeDisk". +EXISTS(FILENAME). +----------------- + +A shortcut for ``CORE:CURRENTVOLUME:EXISTS(FILENAME)``. See :meth:`Volume:EXISTS`. + +CREATE(FILENAME). +----------------- + +A shortcut for ``CORE:CURRENTVOLUME:CREATE(FILENAME)``. See :meth:`Volume:CREATE`. + +OPEN(FILENAME). +--------------- + +A shortcut for ``CORE:CURRENTVOLUME:OPEN(FILENAME)``. See :meth:`Volume:OPEN`. + +.. _writejson: + +WRITEJSON(OBJECT, FILENAME). +---------------------------- + +Serializes the given object to JSON format and saves it under the given filename on the current volume. + +**Important:** only certain types of objects can be serialized. If a type is serializable then that fact +is explicitly mentioned in the type's documentation like so: + +.. note:: + + This type is serializable. + + +Usage example:: + + SET L TO LEXICON(). + SET NESTED TO QUEUE(). + + L:ADD("key1", "value1"). + L:ADD("key2", NESTED). + + NESTED:ADD("nestedvalue"). + + WRITEJSON(l, "output.json"). + +READJSON(FILENAME). +------------------- + +Reads the contents of a file previously created using ``WRITEJSON`` and deserializes them. Example:: + + SET L TO READJSON("output.json"). + PRINT L["key1"]. + + .. _boot: Special handling of files starting with "boot" (example ``boot.ks``) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +-------------------------------------------------------------------- **(experimental)** For users requiring even more automation, the feature of custom boot scripts was introduced. If you have at least 1 file in your Archive volume starting with "boot" (for example "boot.ks", "boot2.ks" or even "boot_custom_script.ks"), you will be presented with the option to choose one of those files as a boot script for your kOS CPU. .. image:: http://i.imgur.com/05kp7Sy.jpg -As soon as you vessel leaves VAB/SPH and is being initialised on the launchpad (e.g. its status is PRELAUNCH) the assigned script will be copied to CPU's local hard disk and named "boot.ks". This script will be run as soon as CPU boots, e.g. as soon as you bring your CPU in physics range or power on your CPU if it was turned off. +As soon as you vessel leaves VAB/SPH and is being initialised on the launchpad (e.g. its status is PRELAUNCH) the assigned script will be copied to CPU's local hard disk with the same name. If kOS is configured to start on the archive, the file will not be copied locally automatically. This script will be run as soon as CPU boots, e.g. as soon as you bring your CPU in physics range or power on your CPU if it was turned off. You may get or set the name of the boot file using the :ref:`core:bootfilename` suffix. + +.. warning:: + + .. versionchanged:: 0.18 + + **boot file name changed** + + Previously boot files were copied to the local hard disk as "boot.ks". This behaviour was changed so that boot files could be handled consistently if kOS is configured to start on the Archive. Some scripts may have terminated with a generic "delete boot." line to clear the boot script. Going forward you should use the new core:bootfilename suffix when dealing the boot file. Important things to consider: * kOS CPU hard disk space is limited, avoid using complex boot scripts or increase disk space using MM config. - * If your kOS set to start from Archive, this feature may not work as intended. Possible workaround: disable starting from Archive and create simple default "boot.ks" file like this:: - - //default boot script, just switches to Archive - switch to 0. - * Boot script runs immediately on initialisation, it should avoid interaction with parts/modules until physics fully load. It is best to wait for couple seconds or until certain trigger. diff --git a/doc/source/commands/flight/cooked.rst b/doc/source/commands/flight/cooked.rst index af6e107b6..dbc505210 100644 --- a/doc/source/commands/flight/cooked.rst +++ b/doc/source/commands/flight/cooked.rst @@ -3,17 +3,36 @@ Cooked Control ============== +.. contents:: Contents + :local: + :depth: 1 + +For more information, check out the documentation for the :struct:`SteeringManager` structure. + In this style of controlling the craft, you do not steer the craft directly, but instead select a goal direction and let kOS pick the way to steer toward that goal. This method of controlling the craft consists primarily of the following two commands: +The special LOCK variables for cooked steering +---------------------------------------------- + .. _LOCK THROTTLE: -.. object:: LOCK THROTTLE TO value. +.. object:: LOCK THROTTLE TO expression. // value range [0.0 .. 1.0] + + This sets the main throttle of the ship to *expression*. Where *expression* is a floating point number between 0.0 and 1.0. A value of 0.0 means the throttle is idle, and a value of 1.0 means the throttle is at maximum. A value of 0.5 means the throttle is at the halfway point, and so on. + + + The expression used in this statement can be any formula and can + call your own user functions. Just make sure it returns a value + in the range [0..1]. - This sets the main throttle of the ship to *value*. Where *value* is a floating point number between 0.0 and 1.0. A value of 0.0 means the throttle is idle, and a value of 1.0 means the throttle is at maximum. A value of 0.5 means the throttle is at the halfway point, and so on. +.. warning:: + + You cannot ``WAIT`` during the execution of the expression in a + LOCK THROTTLE. See the note in the next section below. .. _LOCK STEERING: -.. object:: LOCK STEERING TO value. +.. object:: LOCK STEERING TO expression. - This sets the direction **kOS** should point the ship where *value* is a :struct:`Vector` or a :ref:`Direction ` created from a :ref:`Rotation ` or :ref:`Heading `: + This sets the direction **kOS** should point the ship where *expression* is a :struct:`Vector` or a :ref:`Direction ` created from a :ref:`Rotation ` or :ref:`Heading `: :ref:`Rotation ` @@ -51,6 +70,132 @@ In this style of controlling the craft, you do not steer the craft directly, but Like all ``LOCK`` expressions, the steering and throttle continually update on their own when using this style of control. If you lock your steering to velocity, then as your velocity changes, your steering will change to match it. Unlike with other ``LOCK`` expressions, the steering and throttle are special in that the lock expression gets executed automatically all the time in the background, while other ``LOCK`` expressions only get executed when you try to read the value of the variable. The reason is that the **kOS** computer is constantly querying the lock expression multiple times per second as it adjusts the steering and throttle in the background. +.. warning:: + + You cannot ``WAIT`` during the execution of the expression in a + LOCK STEERING. See the note in the next section below. + + +.. _LOCK WHEELTHROTTLE: +.. object:: LOCK WHEELTHROTTLE TO expression. // value range [-1.0 .. 1.0] + + **(For Rovers)** This is used to control the throttle that is used when + driving a wheeled vehicle on the ground. It is an entirely independent + control from the flight throttle used with ``LOCK THROTTLE`` above. + It is analogous to holding the 'W' (value of +1) or 'S' (value of -1) + key when driving a rover manually under default keybindings. + + ``WHEELTHROTTLE`` allows you to set + a negative value, up to -1.0, while ``THROTTLE`` can't go below zero. + A negative value means you are trying to accelerate in reverse. + + Unlike trying to drive manually, using ``WHEELTHROTTLE`` in kOS does + not cause the torque wheels to engage as well. In stock KSP using + the 'W' or 'S' keys on a rover engages both the wheel driving AND the + torque wheel rotational power. In kOS those two features are + done independently. + + The expression used in this statement can be any formula and can + call your own user functions. Just make sure it returns a value + in the range [0..1]. + +.. warning:: + + You cannot ``WAIT`` during the execution of the expression in a + LOCK WHEELTHROTTLE. See the note in the next section below. + +.. _LOCK WHEELSTEERING: +.. object:: LOCK WHEELSTEERING TO expression. + + **(For Rovers)** This is used to tell the rover's cooked steering + where to go. The rover's cooked steering doesn't use nearly as + sophisticated a PID control system as the flight cooked steering + does, but it does usually get the job done, as driving has more + physical effects that help dampen the steering down automatically. + + There are 3 kinds of value understood by WHEELSTEERING: + + - :struct:`GeoCoordinates` - If you lock wheelsteering to a + :struct:`GetCoordinates`, that will mean the rover will try to steer in + whichever compass direction will aim at that location. + + - :struct:`Vessel` - If you try to lock wheelsteering to a vessel, + that will mean the rover will try to steer in whichever compass + direction will aim at that vessel. The vessel being aimed at + does not need to be landed. If it is in the sky, the rover will + attempt to aim at a location directly underneath it on the ground. + + - *Scalar Number* - If you try to lock wheelsteering to just a plain + scalar number, that will mean the rover will try to aim at that + compass heading. For example ``lock wheelsteering to 45.`` will + try to drive the rover northeast. + + For more precise control over steering, you can use raw steering to + just directly tell the rover to yaw left and right as it drives and + that will translate into wheel steering provided the vessel is landed + and you have a probe core aiming the right way. + + **A warning about WHEELSTEERING and vertically mounted probe cores**: + + If you built your rover in such a way that the probe core controlling it + is stack-mounted facing up at the sky when the rover is driving, that + will confuse the ``lock WHEELSTEERING`` cooked control mechanism. This + is a common building pattern for KSP players and it seems to work okay + when driving manually, but when driving by a kOS script, the fact that + the vessel's facing is officially pointing up at the sky causes it to + get confused. If you notice that your rover tends to drive in the + correct direction only when on a flat or slight downslope, but then + turns around and around in circles when driving toward the target + requires going up a slope, then this may be exactly what's happening. + When it tilted back, the 'forward' vector aiming up at the sky started + pointing behind it, and the cooked steering thought the rover was + aimed in the opposite direction to the way it was really going. + To fix this problem, either mount your rover probe core facing the + front of the rover, or perform a "control from here" on some forward + facing docking port or something like that to get it to stop thinking + of the sky as "forward". + +.. warning:: + + You cannot ``WAIT`` during the execution of the expression in a + LOCK WHEELSTEERING. See the note in the next section below. + + +Cannot 'WAIT' during cooked control calculation +----------------------------------------------- + +Be aware that because LOCK THROTTLE, LOCK STEERING, LOCK +WHEELTHROTTLE, and LOCK WHEELSTEERING cause your expression +to be calculated every single physics update tick behind +the scenes, you cannot execute a ``WAIT`` command during +the evaluation of the value used in them. + +For example, if you attempt this:: + + function get_throttle { + wait 1. // this line won't work. + return 0.5. + } + lock throttle to get_throttle(). + +Then the ``WAIT`` command won't work. You can't make the +system pause execution while it's trying to run the +expression that tells it what to do 25 times a second. + +The entire expression that you LOCK any of the four cooked +controls to must execute and finish quickly enough that it can +be called 25 times a second (on typical default game settings +that's how often the steering manager will run your expression). + +Normally when you use a LOCK command, the expression is only evaluated +when it needs to be by some other part of the script that is trying +to read the value. But with these special cooked control locks, +remember that the kOS system *itself* will query the value repeatedly +in the background so it knows how to adjust the piloting. Unlike +normal LOCKs, these LOCKs will be executed again and again even when +you're not explicitly trying to get their values. + + Unlocking controls ------------------ @@ -61,7 +206,312 @@ If you ``LOCK`` the ``THROTTLE`` or ``STEERING``, be aware that this prevents th When the program ends, these automatically unlock as well, which means that to control a craft you must make sure the program doesn't end. The moment it ends it lets go of the controls. +.. _cooked_tuning: + +Tuning cooked steering +---------------------- + +.. versionadded:: 0.18.0 + + Version 0.18 of kOS completely gutted the internals of the old steering + system and replaced them with the system described below. Anything + said below this point is pertinent to version 0.18 and higher only. + +While cooked steering tries to come balanced to perform decently without user +interaction, there are some instances where you may need to help tune the +behavior. There are a number of settings you can adjust to tweak the +behavior of the cooked steering if it's not performing exactly as you'd +like. It may be the case that making your own control mechanism from +scratch, while entirely possible with kOS, might be unnecessary if all +you really want to do is just make the cooked steering behave slightly +differently. + +The adjustments described below all come from the +:ref:`SteeringManager ` structure, which +has its own detailed documentation page. + +Some simple suggestions to try fixing common problems +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If you don't want to understand the intricate details of the cooked +steering system, here's some quick suggestions for changes to the +settings that might help solve some problems, in the list below: + +- **problem**: A large vessel with low torque doesn't seem to be even trying to + rotate very quickly. The controls may be fluctuating around the zero point, + but it doesn't seem to want to even try to turn faster. + + - **solution**: Increase `STEERINGMANAGER:MAXSTOPPINGTIME` to about 5 or + 10 seconds or so. Also, slightly increase `STEERINGMANAGER:PITCHPID:KD` + and `STEERINGMANAGER:YAWPID:KD` to about 1 or 2 as well to go with it. + + - **explanation**: Once the steering manager gets such a ship rotating at + a tiny rate, it stops trying to make it rotate any faster than that + because it's "afraid" of allowing it to obtain a larger momentum than it + thinks it could quickly stop. It needs to be told that in this case + it's okay to build up more "seconds worth" of rotational velocity. The + reason for increasing the Kd term as well is to tell it to anticipate + the need to starting slowing down rotation sooner than it normally + would. + +- **problem**: A vessel seems to reasonably come to the desired direction + sensibly, but once it's there the ship vibrates back and forth by about 1 + degree or less excessively around the setpoint. + + - **solution**: Increase `STEERINGMANAGER:PITCHTS` and + `STEERINGMANAGER:YAWTS` to several seconds. + + - **explanation**: Once it's + at the desired orientation and it has mostly zeroed the rotational + velocity, it's trying to hold it there with microadjustments to the + controls, and those microadjustments are "too tight". + +- **problem**: The vessel's nose seems to be waving slowly back and forth + across the set direction, taking too long to center on it, and you notice + the control indicators are pushing all the way to the extremes as it does + so. + + - **solution**: Increase `STEERINGMANAGER:PITCHPID:KD` and + `STEERINGMANGER:YAWPID:KD`. + + - **explanation**: The ship is *trying* to + push its rotation rate too high when almost at the setpoint. It needs + to anticipate the fact that it is going to reach the desired direction + and start slowing down BEFORE it gets there. + +- **problem**: The vessel's nose seems to be waving slowly back and forth across + the set direction, taking too long to center on it, but you notice that the + control indicators are NOT pushing all the way to the extremes as it does + so. Instead they seem to be staying low in magnitude, wavering around zero + and may be getting smaller over time. + + - **solution**: Decrease `STEERINGMANAGER:PITCHTS` and/or + `STEERINGMANAGER:YAWTS` + + - **explanation**: While larger values for the + settling time on the Torque PID controller will help to smooth out + spikes in the controls, it also results in a longer time period before + the steering comes to a rest at the setpoint (also knows as settling). + If you had previously increased the settling time to reduce + oscillations, try picking a value half way between the default and the + new value you previously selected. + + +But to understand how to tune the cooked steering in a more complex way than +just with that simple list, you first have to understand what a PID controller +is, at least a little bit, so you know what the settings you can tweak +actually do. + +If you don't know what a PID controller is and want to learn more, you can +read numerous descriptions of the concept on the internet that can be found +in moments by a web search. If you just want to know a two minute explanation +for the sake of tuning the cooked steering a bit, read on. + +Quick and Dirty description of a PID controller +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +You can think of a PID controller as a magic mathematical black box that can +learn where to set a control lever in order to achieve a given goal. A good +example of this is cruise control on a car. You tell the cruise control +what speed you'd like it to maintain, and it attempts to move the accelerator +pedal to the necessary position that will maintain that constant speed. + +That, in a nutshell is the goal of a PID controller - to perform tasks +like that. You have control over a lever or dial of some sort, and it +indirectly affects a phenomenon you can measure, and you feed the +mathematical black box of the PID controller the measurement of the +phenomenon, and obey its instructions of where to set the control lever. +Over time, the PID controller, under the assumption that you are obeying +its instructions of where to set the control lever, learns how to fine +tune its commands about how to set the lever to get the measurement to +settle on the value you asked for. + +A more complex discussion of PID controllers than that is outside the +scope of this document, but you can check out :ref:`the PID Loop tutorial. ` + +Cooked Steering's use of PID controllers +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. highlight:: none + +kOS's cooked steering uses two nested PID controllers per axis of rotation:: + + Seek direction Current Direction Measurement + | | + | | + \|/ \|/ + +-seek me---------cur val---+ + | | + | Rotational Velocity PID | + | | + +-output--------------------+ + desired + rotational + velocity + (i.e. "I'd like to be rotating at 3 degrees per second downward") + | + | + | Current Rotational Velocity measurement + | | + | | + \|/ \|/ + +-seek me---------cur val---+ + | | + | Torque PID | + | | + +-output--------------------+ + desired + control + setting + (i.e. "ship:control:pitch should be -0.2") + | + | + | + | + \|/ + Feed this control value to KSP. (This is the value you can see + on the control indicator meters in the lower-left of the screen). + +.. highlight:: kerboscript + +.. _cooked_omega_pid: + +The Rotational Velocity PID +::::::::::::::::::::::::::: + +The first PID controller looks at the current direction the ship is pointed, +versus the direction the ship is meant to be pointed, and uses the offset +between the two to decide how to set the desired rotational velocity (rate +at which the angle is changing). + +The suffixes to :ref:`SteeringManager ` allow direct +manipulation of the rotational velocity's PID tuning parameters. + +.. _cooked_torque_pid: + +The Torque PID +:::::::::::::: + +But there is no such thing as a lever that directly controls the rotational +velocity. What there is, is a lever that directly controls the rotational +*acceleration*. When you pull on the yoke (i.e. hold down the "S" key), +you are telling the ship to either rotate *faster* or *slower* than it +already is. + +So given a result from the Rotational Velocity PID, with a desired +rotational velocity to seek, the second PID controller takes over, +the Torque PID, which uses that information to choose how to set +the actual controls themselves (i.e. the WASDQE controls) to accelerate +toward that goal rotational velocity. + +The suffixes to :ref:`SteeringManager ` don't quite +allow direct manipulation of the torque PID tuning parameters Kp, Ki, +and Kd, because they are calculated indirectly from the ship's own +attributes. However, there are several suffixes to +:ref:`SteeringManager ` that allow you to make +indirect adjustments to them that are used in calculating the values +it uses for Kp, Ki, and Kd. + +**** + +This technique of using two different PID controllers, the first one +telling the second one which seek value to use, and the second one +actually being connected to the control "lever", is one of many ways of dealing +with a phenomenon with two levels of indirection from the control. + +Keeping the above two things separate, the rotational velocity PID +versus the Torque PID, is important in knowing which setting +you need to tweak in order to achieve the desired effect. + +One pair of PID's per axis of rotation +:::::::::::::::::::::::::::::::::::::: + +The above pair of controllers is replicated per each of the 3 axes of +rotation, for a total of 6 altogether. Some of the settings you can +adjust affect all 3 axes together, while others are specific to just +one. See the descriptions of each setting carefully to know which is +which. + +Corrects 2 axes first, then the 3rd +::::::::::::::::::::::::::::::::::: + +The cooked steering tries to correct first the pitch and yaw, to aim +the rocket at the desired pointing vector, then only after it's very +close to finishing that task does it allow the 3rd axis, the roll axis, +to correct itself. This is because if you try correcting all three at +the same time, it causes the cooked steering to describe a curved arc +toward its destination orientation, rather than rotating straight +towards it. + +This behavior is correct for rockets with radial symmetry, but is +probably a bit wrong for trying to steer an airplane to a new heading +while in atmosphere. For flying an airplane to a new heading, it's +still best to make your own control scheme from scratch with raw steering. + + +The settings to change +:::::::::::::::::::::: + +First, you can modify how kOS decides how fast the ship should turn:: + + // MAXSTOPPINGTIME tells kOS how to calculate the maximum allowable + // angular velocity the Rotational Velocity PID is allowed to output. + // Increasing the value will result in the ship turning + // faster, but it may introduce more overshoot. + // Adjust this setting if you have a small amount of torque on a large mass, + // or if your ship appears to oscillate back and forth rapidly without + // moving towards the target direction. + SET STEERINGMANAGER:MAXSTOPPINGTIME TO 10. + + // You can also modify the PID constants that calculate desired angular + // velocity based on angular error, in the angular velocity PID controller. + // Note that changes made directly to the PIDLoop's MINIMUM and MAXIMUM + // suffixes will be overwritten based on the value MAXSTOPPINGTIME, the + // ship's torque and moment of inertia. + // These values will require precision and testing to ensure consistent + // performance. + // Beware of large KD values: Due to the way angular velocity and part + // facing directions are calculated in KSP, it is normal to have small rapid + // fluctuations which may introduce instability in the derivative component. + SET STEERINGMANAGER:PITCHPID:KP TO 0.85. + SET STEERINGMANAGER:PITCHPID:KI TO 0.5. + SET STEERINGMANAGER:PITCHPID:KD TO 0.1. + +Second, you can change how the controls are manipulated to achieve the desired +angular velocity. This is for the Torque PID mentioned above. Internally, +kOS uses the ship's available torque and moment of inertial to dynamically +calculate the PID constants. Then the desired torque is calculated based on +the desired angular velocity. The steering controls are then set based on +the the percentage the desired torque is of the available torque. You can +change the settling time for the torque calculation along each axis:: + + // Increase the settling time to slow down control reaction time and + // reduce control spikes. This is helpful in vessels that wobble enough to + // cause fluctuations in the measured angular velocity. + // This is recommended if your ship turns towards the target direction well + // but then oscillates when close to the target direction. + SET STEERINGMANAGER:PITCHTS TO 10. + SET STEERINGMANAGER:ROLLTS TO 5. + +If you find that kOS is regularly miscalculating the available torque, you can +also define an adjust bias, or factor. Check out these :struct:`SteeringManager` +suffixes for more details: PITCHTORQUEADJUST, YAWTORQUEADJUST, ROLLTORQUEADJUST, +PITCHTORQUEFACTOR, YAWTORQUEFACTOR, ROLLTORQUEFACTOR + Advantages/Disadvantages ------------------------ -The advantge of "Cooked" control is that it is simpler to write scripts for, but the disadvantage is that you have no control over the details of the motion. You can't dictate how fast or slow the craft rotates, or which axis it tries to rotate around first, and if your craft is wobbly, you can't dampen the wobbliness. +The advantage of "Cooked" control is that it is simpler to write scripts +for, but the disadvantage is that you have only partial control over +the details of the motion. + +Cooked controls perform best on ships that do not rely heavily on control +surfaces, have medium levels of torque, and are structurally stable. You can +improve the control by placing the ship's root part or control part close to the +center of mass (preferably both). Adding struts to critical joints (like +decouplers) or installing a mod like Kerbal Joint Reinforcement will also help. + +But because of the impossibility of finding one setting that is universally +correct for all possible vessels, sometimes the only way to make cooked +steering work well for you is to adjust the parameters as described above, +or to make your own steering control from scratch using raw steering. diff --git a/doc/source/commands/flight/pilot.rst b/doc/source/commands/flight/pilot.rst index 9a4383be9..67b79f386 100644 --- a/doc/source/commands/flight/pilot.rst +++ b/doc/source/commands/flight/pilot.rst @@ -20,66 +20,66 @@ Will ensure that the throttle will be 0 when execution stops. These suffixes all - Equivalent Key * - :ref:`PILOTMAINTHROTTLE ` - - scalar [0,1] + - :ref:`scalar ` [0,1] - ``LEFT-CTRL``, ``LEFT-SHIFT`` * - :ref:`PILOTYAW ` - - scalar [-1,1] + - :ref:`scalar ` [-1,1] - ``D``, ``A`` * - :ref:`PILOTPITCH ` - - scalar [-1,1] + - :ref:`scalar ` [-1,1] - ``W``, ``S`` * - :ref:`PILOTROLL ` - - scalar [-1,1] + - :ref:`scalar ` [-1,1] - ``Q``, ``E`` * - :ref:`PILOTROTATION ` - :struct:`Vector` - ``(YAW,PITCH,ROLL)`` * - :ref:`PILOTYAWTRIM ` - - scalar [-1,1] + - :ref:`scalar ` [-1,1] - ``ALT+D``, ``ALT+A`` * - :ref:`PILOTPITCHTRIM ` - - scalar [-1,1] + - :ref:`scalar ` [-1,1] - ``ALT+W``, ``ALT+S`` * - :ref:`PILOTROLLTRIM ` - - scalar [-1,1] + - :ref:`scalar ` [-1,1] - ``ALT+Q``, ``ALT+E`` * - :ref:`PILOTFORE ` - - scalar [-1,1] + - :ref:`scalar ` [-1,1] - ``N``, ``H`` * - :ref:`PILOTSTARBOARD ` - - scalar [-1,1] + - :ref:`scalar ` [-1,1] - ``L``, ``J`` * - :ref:`PILOTTOP ` - - scalar [-1,1] + - :ref:`scalar ` [-1,1] - ``I``, ``K`` * - :ref:`PILOTTRANSLATION ` - :struct:`Vector` - ``(STARBOARD,TOP,FORE)`` * - :ref:`PILOTWHEELSTEER ` - - scalar [-1,1] + - :ref:`scalar ` [-1,1] - ``A``, ``D`` * - :ref:`PILOTWHEELTHROTTLE ` - - scalar [-1,1] + - :ref:`scalar ` [-1,1] - ``W``, ``S`` * - :ref:`PILOTWHEELSTEERTRIM ` - - scalar [-1,1] + - :ref:`scalar ` [-1,1] - ``ALT+A``, ``ALT+D`` * - :ref:`PILOTWHEELTHROTTLETRIM ` - - scalar [-1,1] + - :ref:`scalar ` [-1,1] - ``ALT+W``, ``ALT+S`` * - :ref:`PILOTNEUTRAL ` - - boolean + - :ref:`Boolean ` - Is **kOS** Controlling? .. _SHIP CONTROL PILOTMAINTHROTTLE: -.. object:: SHIP:CONTROL:MAINTHROTTLE +.. object:: SHIP:CONTROL:PILOTMAINTHROTTLE Returns the pilot's input for the throttle. This is the only ``PILOT`` variable that is settable and is used to set the throttle upon termination of the current **kOS** program. diff --git a/doc/source/commands/flight/raw.rst b/doc/source/commands/flight/raw.rst index 12532f5b0..6cd0aea6a 100644 --- a/doc/source/commands/flight/raw.rst +++ b/doc/source/commands/flight/raw.rst @@ -43,7 +43,14 @@ Raw Flight Controls Reference These "Raw" controls allow you the direct control of flight parameters while the current program is running. .. note:: - The ``MAINTHROTTLE`` requires active engines and, of course, sufficient and appropriate fuel. The rotational controls ``YAW``, ``PITCH`` and ``ROW`` require active reaction wheels with sufficient energy or *RCS* to be ON with properly placed thrusters and appropriate fuel. The translational controls ``FORE``, ``STARBOARD`` and ``TOP`` require *RCS* to be ON with properly placed thrusters and appropriate fuel. + The ``MAINTHROTTLE`` requires active engines and, of course, + sufficient and appropriate fuel. The rotational controls ``YAW``, + ``PITCH`` and ``ROW`` require one of the following: active reaction + wheels with sufficient energy, *RCS* to be ON with properly placed + thrusters and appropriate fuel, or control surfaces with an atmosphere + in which to operate. The translational controls ``FORE``, ``STARBOARD`` + and ``TOP`` only work with *RCS*, and require RCS to be ON with + properly placed thrusters and appropriate fuel. .. list-table:: @@ -55,64 +62,64 @@ These "Raw" controls allow you the direct control of flight parameters while the - Equivalent Key * - :ref:`MAINTHROTTLE ` - - scalar [0,1] + - :ref:`scalar ` [0,1] - ``LEFT-CTRL``, ``LEFT-SHIFT`` * - :ref:`YAW ` - - scalar [-1,1] + - :ref:`scalar ` [-1,1] - ``D``, ``A`` * - :ref:`PITCH ` - - scalar [-1,1] + - :ref:`scalar ` [-1,1] - ``W``, ``S`` * - :ref:`ROLL ` - - scalar [-1,1] + - :ref:`scalar ` [-1,1] - ``Q``, ``E`` * - :ref:`ROTATION ` - :struct:`Vector` - ``(YAW,PITCH,ROLL)`` * - :ref:`YAWTRIM ` - - scalar [-1,1] + - :ref:`scalar ` [-1,1] - ``ALT+D``, ``ALT+A`` * - :ref:`PITCHTRIM ` - - scalar [-1,1] + - :ref:`scalar ` [-1,1] - ``ALT+W``, ``ALT+S`` * - :ref:`ROLLTRIM ` - - scalar [-1,1] + - :ref:`scalar ` [-1,1] - ``ALT+Q``, ``ALT+E`` * - :ref:`FORE ` - - scalar [-1,1] + - :ref:`scalar ` [-1,1] - ``N``, ``H`` * - :ref:`STARBOARD ` - - scalar [-1,1] + - :ref:`scalar ` [-1,1] - ``L``, ``J`` * - :ref:`TOP ` - - scalar [-1,1] + - :ref:`scalar ` [-1,1] - ``I``, ``K`` * - :ref:`TRANSLATION ` - :struct:`Vector` - ``(STARBOARD,TOP,FORE)`` * - :ref:`WHEELSTEER ` - - scalar [-1,1] + - :ref:`scalar ` [-1,1] - ``A``, ``D`` * - :ref:`WHEELTHROTTLE ` - - scalar [-1,1] + - :ref:`scalar ` [-1,1] - ``W``, ``S`` * - :ref:`WHEELSTEERTRIM ` - - scalar [-1,1] + - :ref:`scalar ` [-1,1] - ``ALT+A``, ``ALT+D`` * - :ref:`WHEELTHROTTLETRIM ` - - scalar [-1,1] + - :ref:`scalar ` [-1,1] - ``ALT+W``, ``ALT+S`` * - :ref:`NEUTRAL ` - - boolean + - :ref:`Boolean ` - Is **kOS** Controlling? * - :ref:`NEUTRALIZE ` - - boolean + - :ref:`Boolean ` - Releases Control @@ -136,7 +143,7 @@ These "Raw" controls allow you the direct control of flight parameters while the .. _SHIP CONTROL ROLL: .. object:: SHIP:CONTROL:ROLL - Rotation about the logintudinal axis of the ship left-wing-down :math:`(-1)` or left-wing-up :math:`(+1)`. + Rotation about the longitudinal axis of the ship left-wing-down :math:`(-1)` or left-wing-up :math:`(+1)`. .. _SHIP CONTROL ROTATION: .. object:: SHIP:CONTROL:ROTATION @@ -217,7 +224,8 @@ These "Raw" controls allow you the direct control of flight parameters while the Unlocking controls ------------------ -Once any of the ``SET SHIP:CONTROL`` commands have been used to control the ship, then the manual control by the player is locked out. To give control back to the player you must execute:: +Setting any one of ``SHIP:CONTROL`` values will prevent player from manipulating that specific control manually. Other controls will not be locked. +To free any single control, set it back to zero. To give all controls back to the player you must execute:: SET SHIP:CONTROL:NEUTRALIZE to TRUE. diff --git a/doc/source/commands/flight/systems.rst b/doc/source/commands/flight/systems.rst index 204e8960c..48962c7ff 100644 --- a/doc/source/commands/flight/systems.rst +++ b/doc/source/commands/flight/systems.rst @@ -4,9 +4,17 @@ Ship Systems ============ .. _CONTROLFROM: -.. object:: SET somepart:CONTROLFROM TO (true|false). - If you have a handle on a part, from ``LIST PARTS``, you can select that part to set the orientation of the craft, just like using the "control from here" in the right-click menu in the game. For more information see :attr:`Part:CONTROLFROM`. + e.g.:: + + set somepart to ship:partstagged("my favorite docking port")[0]. + somepart:CONTROLFROM(). + + If you have a handle on a part, from ``LIST PARTS``, you can select that part to set the orientation of the craft, just like using the "control from here" in the right-click menu in the game. For more information see :attr:`Part:CONTROLFROM`. + All vessels must have at least one "control from" + part on them somewhere, which is why there's no mechanism for un-setting + the "control from" setting other than to pick another part and set it + to that part instead. .. global:: RCS @@ -31,15 +39,15 @@ Ship Systems :access: Get/Set :type: string - Getting this variable will return the currently selected mode. Where ``value`` is one of the valid strings listed below, this will set the stock SAS mode for the cpu vessel:: + Getting this variable will return the currently selected mode. Where ``value`` is one of the valid strings listed below, this will set the stock SAS mode for the cpu vessel:: SET SASMODE TO value. - It is the equivalent to clicking on the buttons next to the nav ball while manually piloting the craft, and will respect the current mode of the nav ball (orbital, surface, or target velocity). Valid strings for ``value`` are ``"PROGRADE"``, ``"RETROGRADE"``, ``"NORMAL"``, ``"ANTINORMAL"``, ``"RADIALOUT"``, ``"RADIALIN"``, ``"TARGET"``, ``"ANTITARGET"``, ``MANEUVER``, ``"STABILITYASSIST"``, and ``"STABILITY"``. A null or empty string will default to stability assist mode, however any other invalid string will throw an exception. This feature will respect career mode limitations, and will throw an exception if the current vessel is not able to use the mode passed to the command. An exception is also thrown if ``"TARGET"`` or ``"ANTITARGET"`` are used, but no target is selected. + It is the equivalent to clicking on the buttons next to the nav ball while manually piloting the craft, and will respect the current mode of the nav ball (orbital, surface, or target velocity). Valid strings for ``value`` are ``"PROGRADE"``, ``"RETROGRADE"``, ``"NORMAL"``, ``"ANTINORMAL"``, ``"RADIALOUT"``, ``"RADIALIN"``, ``"TARGET"``, ``"ANTITARGET"``, ``"MANEUVER"``, ``"STABILITYASSIST"``, and ``"STABILITY"``. A null or empty string will default to stability assist mode, however any other invalid string will throw an exception. This feature will respect career mode limitations, and will throw an exception if the current vessel is not able to use the mode passed to the command. An exception is also thrown if ``"TARGET"`` or ``"ANTITARGET"`` are used, but no target is selected. .. warning:: SASMODE does not work with RemoteTech - Due to the way that RemoteTech disables flight control input, the built in SAS modes do not function properly when there is no connection to the KSC or a Command Center. If you are writing scripts for use with RemoteTech, make sure to take this into account. + Due to the way that RemoteTech disables flight control input, the built in SAS modes do not function properly when there is no connection to the KSC or a Command Center. If you are writing scripts for use with RemoteTech, make sure to take this into account. .. global:: LIGHTS diff --git a/doc/source/commands/flight/warp.rst b/doc/source/commands/flight/warp.rst index d8a4348bb..b152afe96 100644 --- a/doc/source/commands/flight/warp.rst +++ b/doc/source/commands/flight/warp.rst @@ -6,6 +6,10 @@ Time Warping .. global:: WARP + You may use the WARPTO(time) function to automatically warp to the specified time (given in seconds game universal time). If you need more precise control, you can use the other options below.:: + + WARPTO(TIME:SECONDS + 60 * 10). // warp to a time 10 minutes in the future + The :global:`WARP` global variable can be set to change the game warp to a value between 0 and 7 (for rails warp) or 0 to 3 (for physics warp):: SET WARP TO 5. // Sets warp to 1000x diff --git a/doc/source/commands/list.rst b/doc/source/commands/list.rst index b6be33b35..0f5b9e612 100644 --- a/doc/source/commands/list.rst +++ b/doc/source/commands/list.rst @@ -48,6 +48,8 @@ Vessel Lists These generate :struct:`lists ` of items on the :struct:`Vessel`: +``Processors`` + :struct:`List` of :struct:`Processors ` ``Resources`` :struct:`List` of :struct:`AggregateResources ` ``Parts`` @@ -67,9 +69,9 @@ File System Lists These generate :struct:`lists ` about the files in the system: ``Files`` - :struct:`List` the :struct:`files ` on the current Volume. (note below) + :struct:`List` the :struct:`files ` on the current Volume. (note below) ``Volumes`` - :struct:`List` all the :ref:`volumes` that exist. + :struct:`List` all the :struct:`volumes ` that exist. .. note:: @@ -82,7 +84,7 @@ Examples:: LIST VOLUMES. // which volumes can be seen by this CPU? LIST FILES IN fileList. // fileList is now a LIST() containing file structures. -The file structures returned by ``LIST FILES IN fileList.`` are documented :ref:`on a separate page `. +The file structures returned by ``LIST FILES IN fileList.`` are documented :ref:`on a separate page `. Here are some more examples:: diff --git a/doc/source/commands/prediction.rst b/doc/source/commands/prediction.rst index 4939ebb5a..217adf60a 100644 --- a/doc/source/commands/prediction.rst +++ b/doc/source/commands/prediction.rst @@ -13,6 +13,23 @@ Predictions of Flight Path Using the Add and Remove commands as described on that page, you may alter the flight plan of the CPU\_vessel, however kOS does not automatically execute the nodes. You still have to write the code to decide how to successfully execute a planned maneuver node. +.. warning:: + + Be aware that a limitation of KSP makes it so that some vessels' + maneuver node systems cannot be accessed. KSP appears to limit the + maneuver node system to only functioning on the current PLAYER + vessel, under the presumption that its the only vessel that needs + them, as ever other vessel cannot be maneuvered. kOS can maneuver a + vessel that is not the player vessel, but it cannot overcome this + limitation of the base game that unloads the maneuver node system + for other vessels. + + Be aware that the effect this has is that when you try to predict + another vessel's position, it will sometimes give you answers that + presume that other vessel will be purely drifting, and not following + its maneuver nodes. + + The following prediction functions do take into account the future maneuver nodes planned, and operate under the assumption that they will be executed as planned. These return predicted information about the future position and velocity of an object. @@ -27,6 +44,11 @@ These return predicted information about the future position and velocity of an Returns a prediction of where the :struct:`Orbitable` will be at some :ref:`universal Timestamp `. If the :struct:`Orbitable` is a :struct:`Vessel`, and the :struct:`Vessel` has planned :ref:`maneuver nodes `, the prediction assumes they will be executed exactly as planned. + *Prerequisite:* If you are in a career mode game rather than a + sandbox mode game, This function requires that you have your space + center's buildings advanced to the point where you can make maneuver + nodes on the map view, as described in :struct:`Career:CANMAKENODES`. + .. function:: VELOCITYAT(orbitable,time) :param orbitable: A :struct:`Vessel`, :struct:`Body` or other :struct:`Orbitable` object @@ -37,6 +59,11 @@ These return predicted information about the future position and velocity of an Returns a prediction of what the :ref:`Orbitable's ` velocity will be at some :ref:`universal Timestamp `. If the :struct:`Orbitable` is a :struct:`Vessel`, and the :struct:`Vessel` has planned :struct:`maneuver nodes `, the prediction assumes they will be executed exactly as planned. + *Prerequisite:* If you are in a career mode game rather than a + sandbox mode game, This function requires that you have your space + center's buildings advanced to the point where you can make manuever + nodes on the map view, as described in :struct:`Career:CANMAKENODES`. + .. function:: ORBITAT(orbitable,time) :param orbitable: A :Ref:`Vessel `, :struct:`Body` or other :struct:`Orbitable` object @@ -47,6 +74,11 @@ These return predicted information about the future position and velocity of an Returns the :ref:`Orbit patch ` where the :struct:`Orbitable` object is predicted to be at some :ref:`universal Timestamp `. If the :struct:`Orbitable` is a :struct:`Vessel`, and the :struct:`Vessel` has planned :ref:`maneuver nodes `, the prediction assumes they will be executed exactly as planned. + *Prerequisite:* If you are in a career mode game rather than a + sandbox mode game, This function requires that you have your space + center's buildings advanced to the point where you can make maneuver + nodes on the map view, as described in :struct:`Career:CANMAKENODES`. + Examples:: //kOS diff --git a/doc/source/commands/processors.rst b/doc/source/commands/processors.rst new file mode 100644 index 000000000..940a0992c --- /dev/null +++ b/doc/source/commands/processors.rst @@ -0,0 +1,26 @@ +.. _processors: + +Processors +============================= + +A vessel can potentially have more than one :struct:`processor ` on board. It is possible for them to query information about each other and interact. + +Accessing processors +-------------------- + +The easiest way of accessing the vessel's :struct:`processors ` is to use the following function: + +.. function:: PROCESSOR(volumeOrNameTag) + + :parameter volumeOrNameTag: (:struct:`Volume` | `String`) can be either an instance of :struct:`Volume` or a string + + Depending on the type of the parameter value will either return the processor associated with the given :struct:`Volume` or the processor with the given name tag. + +A list of all processors can be obtained using the :ref:`List ` command:: + + LIST PROCESSORS IN ALL_PROCESSORS. + PRINT ALL_PROCESSORS[0]:NAME. + +Finally, processors can be accessed directly, like other :ref:`parts and modules `:: + + PRINT SHIP:MODULESNAMED("kOSProcessor")[0]:VOLUME:NAME. diff --git a/doc/source/commands/terminalgui.rst b/doc/source/commands/terminalgui.rst index 3d6d14725..68f4c72ed 100644 --- a/doc/source/commands/terminalgui.rst +++ b/doc/source/commands/terminalgui.rst @@ -1,4 +1,4 @@ -.. _terminal: +.. _terminalgui: Terminal and game environment ============================= @@ -14,17 +14,19 @@ Terminal and game environment Prints the selected text to the screen. Can print strings, or the result of an expression:: - PRINT “Helloâ€. + PRINT "Hello". PRINT 4+1. - PRINT “4 times 8 is: “ + (4*8). + PRINT "4 times 8 is: " + (4*8). .. global:: SET TERMINAL:WIDTH. GET TERMINAL:WIDTH Gets or sets the terminal's width in characters. + For more information see :ref:`terminal struct `. .. global:: SET TERMINAL:HEIGHT. GET TERMINAL:HEIGHT Gets or sets the terminal's height in characters. + For more information see :ref:`terminal struct `. .. function:: AT(col,line) @@ -33,9 +35,9 @@ Terminal and game environment Used in combination with :global:`PRINT`. Prints the selected text to the screen at specified location. Can print strings, or the result of an expression:: - PRINT “Hello†AT(0,10). + PRINT "Hello" AT(0,10). PRINT 4+1 AT(0,10). - PRINT “4 times 8 is: “ + (4*8) AT(0,10). + PRINT "4 times 8 is: " + (4*8) AT(0,10). .. global:: MAPVIEW diff --git a/doc/source/conf.py b/doc/source/conf.py index 2f199b621..e9f8463eb 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -32,8 +32,10 @@ extensions = [ 'sphinx.ext.mathjax', 'ksdomain', + 'KerboscriptLexer', ] + primary_domain = 'ks' # Add any paths that contain templates here, relative to this directory. @@ -46,20 +48,20 @@ #source_encoding = 'utf-8-sig' # The master toctree document. -master_doc = 'index' +master_doc = 'contents' # General information about the project. project = u'kOS' -copyright = u'2013-2015, Developed and maintained by kOS Team, Originally By Nivekk' +copyright = u'2013-2016, Developed and maintained by kOS Team, Originally By Nivekk' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # # The short X.Y version. -version = '0.17.2 ' +version = '0.19.1' # The full version, including alpha/beta/rc tags. -release = '0.17.2' +release = '0.19.1' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. @@ -92,7 +94,7 @@ # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'sphinx' -highlight_language = 'c' +highlight_language = 'kerboscript' # A list of ignored prefixes for module index sorting. #modindex_common_prefix = [] @@ -142,6 +144,7 @@ if html_theme == 'sphinx_rtd_theme': import sphinx_rtd_theme html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] + html_style = 'css/kos_theme.css' # adjusts the read_the_docs CSS theme a tad. # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the @@ -160,7 +163,7 @@ # The name of an image file (relative to this directory) to place at the top # of the sidebar. -#html_logo = None +html_logo = '_images/kos_logo_small.png' # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 @@ -170,7 +173,7 @@ # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_images'] +html_static_path = ['_images','_static'] # Add any extra paths that contain custom files (such as robots.txt or # .htaccess) here, relative to this directory. These files are copied diff --git a/doc/source/contents.rst b/doc/source/contents.rst new file mode 100644 index 000000000..dd4be5d04 --- /dev/null +++ b/doc/source/contents.rst @@ -0,0 +1,30 @@ +.. _contents: + +Documentation Table of Contents +=============================== + +.. toctree:: + :includehidden: + :titlesonly: + :maxdepth: 5 + + Home + Table of Contents + Downloads and Links + Tutorials + Community Example Library + General + Language + Mathematics + Commands + Structures + Addons + Contribute + Changes + About + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`search` diff --git a/doc/source/contribute.rst b/doc/source/contribute.rst index bc9ee809d..bf5bf78b4 100644 --- a/doc/source/contribute.rst +++ b/doc/source/contribute.rst @@ -6,18 +6,59 @@ Contribute How to Contribute to this Project --------------------------------- -Do you know or are willing to learn C# and the **KSP** public API? Great, we could use your help! The source code for **kOS** is kept on `github`_ and is currently maintained by `Chris Woerz`_ and `Steven Mading`_. The first steps you will want to take is to clone the latest version of **kOS** from github and try to build it using your favorite C# compiler suite. +Do you know or are willing to learn C# and the **KSP** public API? Great, we could use your help! The source code for **kOS** is kept on `github`_ under http://github.io/KSP-KOS/KOS. + +If you are already quite familiar with git and Github, the usual Github project development path is used: + + - Tell github to fork the main repository to your own github clone of it. + - Clone your fork to your local computer. + - On your local computer, make a branch from ``develop`` (don't edit ``develop`` directly) and make your changes in your branch. + - Commit your changes and push them up to the same branch name on your github fork. + - Make a Pull Request on Github to merge the branch from your fork to the ``develop`` branch of the main repository. + - Wait for a developer to notice the Pull Request and start examining it. There should be at the very least a comment letting you know it's being looked at, within a short time. KSP-KOS is quite actively developed and someone should notice it soon. + + - Your request is more likely to get merged quickly if you make sure the ``develop`` branch you start from is always up to date with the latest upstream develop when you first split your branch from it. If it takes a long time to finish, it may be a good idea to check again before making the Pull Request to see if there's been any new upstream ``develop`` changes, and merge them into your branch yourself so the rest of the team has an easier time deciphering the git diff output. + +If you do know how to program on large projects and would like to contribute, but just aren't familiar with how git and Github do repository management, contact one of the developers and ask for help on how to get started, or ask to be added to the Slack channel first. .. _github: https://github.com/KSP-KOS -.. _Chris Woerz: https://github.com/erendrake -.. _Steven Mading: https://github.com/Dunbaratu + +Slack Chat +---------- + +There is an active Slack chat channel where the developers often discuss complex ideas before even mentioning them in a github issue or pull request. If you wish to be added to this channel, please contact one of the main developers to ask to be invited to the channel. + +How to get credited in the next Release +--------------------------------------- + +After version 0.19.0, Only people who opt-in to being credited will be mentioned in the release notes. + +When you contribute to the development of the mod, if you wish to be named a certain way in the next release notes, then add your edit to the ``### Contributors`` section of the CHANGELOG.md file in your pull request. +In past releases we have tried to scour the github history to find all authors and it's a bit of a pain to pull the data together. In future releases we will simply rely on this opt-in technique. If you don't edit the file, you won't be opted-in to the contributors section. This also avoids the hassle of having to ask everyone's permission in the last days of putting a release out, and then waiting for people's responses. How to Edit this Documentation ------------------------------ -This documentation was written using `reStructuredText`_ and compiled into HTML using `Sphinx`_ and the `Read The Docs Theme`_. It is maintained by `Steven Mading`_, `Chris Woerz`_ and `Johann Goetz`_ +This documentation was written using `reStructuredText`_ and compiled into HTML using `Sphinx`_ and the `Read The Docs Theme`_. .. _reStructuredText: http://docutils.sourceforge.net/rst.html .. _Sphinx: http://sphinx-doc.org/ .. _Read The Docs Theme: https://github.com/snide/sphinx_rtd_theme + +To re-build the documentation tree locally, get a local clone of the project, `cd` into the `doc/` directory, and do these two commands: + +.. highlight:: none + +:: + + make clean + make html + +.. highlight:: kerboscript + +Note, this requires you set up Sphinx and Read-the-Docs first, as described in the links above. + +This documentation system was first set up for us by Johann Goetz, to whom we are grateful: + .. _Johann Goetz: http://github.com/theodoregoetz + diff --git a/doc/source/downloads_links.rst b/doc/source/downloads_links.rst index c75f7fddf..1c5cfdf47 100644 --- a/doc/source/downloads_links.rst +++ b/doc/source/downloads_links.rst @@ -18,9 +18,10 @@ Obtaining kOS itself Github is where development of the mod occurs, and new releases will apear there first, without delays, and its where old obsolete releases can be found, if you need one for use with an older version of KSP. - - `Use KerbalStuff `__ - Kerbalstuff is a community supported Kerbal Space Program mod hosting site that behaves - much like Curse, but without Curse's embedded advertisements all over the webpage. + - `Use SpaceDock `__ + SpaceDock is a community supported Kerbal Space Program mod hosting site that behaves + much like Curse, but without Curse's embedded advertisements all over the webpage. It + was designed as the successor to KerbalStuff. - `Download from Curse `__ Love it or Loathe it, Curse is the official place SQUAD points people to for KSP addons, so we make it available there too. @@ -32,6 +33,22 @@ Change Log - `Change Log `__ on Github. +.. _koscommunity: + +Online Community +---------------- + +There are two good places to go for help and sharing of ideas with other +users of kOS, and the developers of the mod frequent those locations too: + +- `/r/kos on reddit `__ +- `On Kerbal Space Program's forum `__ + +Of these two locations, the Reddit one tends to be more active because it +allows multiple sub-threads about kOS. On the Kerbal Space Program +forum, all kOS talk occurs in one uniform thread, which is a little less +useful for discussing different ideas and different scripts. + .. _showandtell: Show and Tell, and Tutorials @@ -47,18 +64,20 @@ Show and Tell, and Tutorials **Tutorials** - `Seth Persigehl's Tutorial playlist `__ + - `CheersKevinGames `__ + A channel devoted to a career mode game played with kOS from day 1, in which no + Kerbals themselves are allowed to touch the controls. All piloting is performed + by kOS programs. Also works as a good deep explanation of many topics to new + users of the mod, and people new to programming in general. **Show and Tell** - - `Steven Mading's user scripts playlist `__ + - `Ozin's amazing drone video `__ + - `Dunbaratu's user scripts playlist `__ + - `Seth Persihel's SpaceX-style first stage return in FAR `__ + - `NearlyEnoughDice demonstrating a leg leveller `__ + - `Allmhuran's Mechs with scripted AI `__ + - `Scripted airplane takeoff, waypoint seek, and landing `__ Some of these are very old and out of date, going back as far as kOS version 0.65. The actual code used may have to be tweaked a bit to work with recent kOS releases. - `Parasite's first docking script, reddit post `__ - -**Past Teasers** - - - `Steven Mading's Developer teasers playlist `__ - (Note these are teasers that were created just before new features were first released, to - show off what was (at the time) new content that hadn't been public yet. They also can - constitute a tutorial of sorts to show how some of the features work.) - diff --git a/doc/source/general.rst b/doc/source/general.rst index 344c1c92d..427c09949 100644 --- a/doc/source/general.rst +++ b/doc/source/general.rst @@ -13,6 +13,8 @@ These topics discuss the interfacing between **kOS** and **Kerbal Space Program* CPU Vessel (SHIP) CPU Hardware + Game Part + Launcher Panel Telnet Server diff --git a/doc/source/general/career_limits.rst b/doc/source/general/career_limits.rst index 3f9274d42..78af8e238 100644 --- a/doc/source/general/career_limits.rst +++ b/doc/source/general/career_limits.rst @@ -61,32 +61,32 @@ Structure - Set * - :attr:`CANTRACKOBJECTS` - - boolean + - :ref:`Boolean ` - yes - no * - :attr:`PATCHLIMIT` - - number + - :ref:`scalar ` - yes - no * - :attr:`CANMAKENODES` - - boolean + - :ref:`Boolean ` - yes - no * - :attr:`CANDOACTIONS` - - boolean + - :ref:`Boolean ` - yes - no .. attribute:: Career:CANTRACKOBJECTS - :type: boolean + :type: :ref:`Boolean ` :access: Get If your tracking center allows the tracking of unnamed objects (asteroids, mainly) then this will return true. .. attribute:: Career:PATCHLIMIT - :type: number + :type: :ref:`scalar ` :access: Get If your tracking center allows some patched conics predictions, then this number will be greater than zero. @@ -95,7 +95,7 @@ Structure .. attribute:: Career:CANMAKENODES - :type: boolean + :type: :ref:`Boolean ` :access: Get If your tracking center and mission control buildings are both upgraded enough, then the game allows @@ -104,7 +104,7 @@ Structure .. attribute:: Career:CANDOACTIONS - :type: boolean + :type: :ref:`Boolean ` :access: Get If your VAB or SPH are upgraded enough to allow custom action groups, then you will also be allowed diff --git a/doc/source/general/cpu_hardware.rst b/doc/source/general/cpu_hardware.rst index a226d55ce..b3da2bbab 100644 --- a/doc/source/general/cpu_hardware.rst +++ b/doc/source/general/cpu_hardware.rst @@ -86,6 +86,50 @@ On each physics tick, each kOS CPU that's within physics range (i.e. 2.5 km), wa Note that the number of instructions being executed (CONFIG:IPU) are NOT lines of code or kerboscript statements, but rather the smaller instruction opcodes that they are compiled into behind the scenes. A single kerboscript statement might become anywhere from one to ten or so instructions when compiled. + +.. _electricdrain: + +Electric Drain +-------------- + +.. versionadded:: 0.19.0 + + As of version 0.19.0, the electric charge drain varies depending + on CPU % usage. Prior to version 0.19.0, the CPU load made no + difference and the electric drain was constant regardless of + utilization. + +Real world CPUs often have low power modes, and sleep modes, and these are +vital to long distance probes. In these modes the computer deliberately +runs slowly in order to use less power, and then the program can tell it to +speed up to normal speed again when it needs to wake up and do something. + +In kOS, this concept is simplified by just draining electric charge by +"micropayments" of charge per instruction executed. + +To change this setting if you want to re-balance the system, see the +page about :ref:`kOSProcessor part config values `. + +The shorthand version is this: The more instructions per update +actually get executed, the more power is drained. This can be reduced +by either lowering ``CONFIG:IPU`` or by making sure your main loop +has a ``WAIT`` statement in it. (When encountering a ``WAIT`` statement, +the remainder of the instructions for that update are not used and end +up not counting against electric charge). + +The system always costs at least 1 instruction of electric charge per +update no matter what the CPU is doing, unless it's powered down entirely, +because there's always at least 1 instruction just to check if it's time +to resume yet in a ``WAIT``. The electric cost is never entirely zero +as long as it's turned on, but it can be very close to zero while it is +stuck on a wait. + +If your program spins in a busy loop, never waiting, it can consume +quite a bit more power than it would if you explicitly throw in a +``WAIT 0.001.`` in the loop. Even if the wait is very small, the +mere fact that it yields the remaining instructions still allowed +that update can make a big difference. + Triggers -------- diff --git a/doc/source/general/kospartmodule.rst b/doc/source/general/kospartmodule.rst new file mode 100644 index 000000000..489097709 --- /dev/null +++ b/doc/source/general/kospartmodule.rst @@ -0,0 +1,108 @@ +.. _kospartmodule: + +KOS Processor PartModule Configuration Fields +============================================= + +.. note:: + (The most important part of this page is probably the + section below on the EcPerInstruction setting.) + +When using `ModuleManager `_ +or directly editing the part.cfg files a mod ships with, it is useful to +know what those settings mean. This page documents what some of the +settings in the kOS part config files mean. + +These are the settings typically found in the files named: + +``GameData/kOS/Parts/`` name_of_part_here ``/part.cfg`` + +You can add kOS to any other part in the game by adding the kOS module +to the part (although this may cause strange interactions that are not +officially supported). + +Here is an example of the kOS processor module : the one that is +attached to the small disk shaped CPU part (KR-2402 b):: + + MODULE + { + name = kOSProcessor + diskSpace = 5000 + ECPerBytePerSecond = 0 + ECPerInstruction = 0.000004 + } + +If you add a section like that to the part.cfg, via directly editing it, +or via a ModuleManager configuration, then you cause that part to contain +a kOS computer. + +When editing these values, the case is important. You must capitalize +them and lowercase them exactly as shown here. + +Here is a list of all the potential fields you could set in that section: + +.. _diskSpace: + +diskSpace +--------- + + - **Type:** integer + - **Default if omitted:** 1024 + - **Effect:** The disk space the part has by default if the + adjustment slider in the VAB isn't changed by the user. + +.. _baseDiskSpace: + +baseDiskSpace +------------- + + - **Type:** integer + - **Default if omitted:** copied from initial :ref:`diskSpace ` setting + - **Effect:** The lowest disk space the part can have at the lowest + end of the slider in the VAB. + +The possible choices for disk space the user can select on the +slider is always one of 1x, 2x, and 4x this amount. + +.. _ECPerInstruction: + +ECPerInstruction: +----------------- + + - **Type:** float + - **Default if omitted:** 0.000004 + - **Effect:** How much ElectricCharge resource is consumed per + instruction the program executes. + +This is a very small number so the electric charge can be payed +in micro-amounts as the CPU executes. Remember that with default +Unity settings (which can be changed on the KSP game's main settings +screen at the launch of the program), the game runs 25 physical +updates per second. So if the setting is 0.000004, and program is +executing 200 instructions per update, at 25 updates per second, +then it's consuming 0.02 Ec per second, or 1 Ec every 50 seconds. + +This is the setting from which the value in the VAB/SPH info panel, +1 Electric Charge per N instructions, is derived (it's the reciprocal +of that display value). + +More information about programs reducing power consumption can be +found in the section of the CPU hardware description that +:ref:`talks about electric drain`. + +.. _ECPerBytePerSecond: + +ECPerBytePerSecond: +------------------- + + - **Type:** float + - **Default if omitted:** 0.0 + - **Effect:** How much ElectricCharge resource is consumed per + byte of disk space avaialable (not just used). + +It is possible to make the disk cost more electricity to run the +bigger it is. By default this ships as zero, but it can be changed +by a re-balancing mod by changing this value. This value is +multiplied by how much available space there is total (used + free), +not just how much is currently in use. + +.. _electriccharge: diff --git a/doc/source/general/telnet.rst b/doc/source/general/telnet.rst index bdc437e18..eb127a361 100644 --- a/doc/source/general/telnet.rst +++ b/doc/source/general/telnet.rst @@ -82,6 +82,8 @@ Using it 3. Launch your telnet client (there is a list of telnet clients that are known to work listed below. +.. highlight:: none + 4. When you first log in to the server you should see the "Welcome menu", which is a screen looking like this:: @@ -126,6 +128,8 @@ Using it The welcome menu, shown here in a Mac OSX terminal. +.. highlight:: kerboscript + 5. **Pick a CPU.** Pick one of the CPU's listed by typing its number and hitting enter. 6. Your telnet is now connected to the server and should behave as the terminal for @@ -270,6 +274,8 @@ HOWTO: Command-line client the loopback address 127.0.0.1, and port number 5410. If you've changed those settings then alter the numbers you see here accordingly.) +.. highlight:: none + 1. Run KSP, and get it into a scene where there exists a vessel with at least one kOS CPU loaded into it. @@ -280,6 +286,8 @@ settings then alter the numbers you see here accordingly.) telnet 127.0.0.1 5410 +.. highlight:: kerboscript + HOWTO: Other client ------------------- diff --git a/doc/source/general/volumes.rst b/doc/source/general/volumes.rst index e7b3ed7c7..e55c7ab9e 100644 --- a/doc/source/general/volumes.rst +++ b/doc/source/general/volumes.rst @@ -51,20 +51,50 @@ A Volume is a small unit of disk storage that contains a single hard drive with very limited storage capacity. It can store more than one program on it. To simulate the sense that this game takes place at the dawn of the space race with 1960's and 1970's technology, the storage -capacity of a volume is very limited. It can only store 10,000 bytes of -program text - less than 10 Kb The byte count of a program is just the +capacity of a volume is very limited. + +For example, the CX-4181 Scriptable Control System part defaults to only +allowing 1000 bytes of storage. + +The byte count of a program is just the count of the characters in the source code text. Writing programs with short cryptic variable names instead of long descriptive ones does save -space. This is old school programming, where squeezing every byte out -matters. +space, although you can also save space by compiling your programs to +KSM files where the variable names are only stored once in the file, but +that's another topic for another page. + +Each of the computer parts that kOS supports have their own different default +storage capacity limits for their local volume. As you get better parts +higher up the tech tree, they come with bigger default size limits. + +You can get more space by paying extra cost in money and mass +------------------------------------------------------------- + +.. figure:: /_images/general/disk_space_slider.png + +If you wish to have more disk space on your local volume, and are willing to +pay a little extra cost in money and in mass, you can use the disk space +slider in the vehicle assembly building to increase the limit. + +Every part comes with 3 different multiplier options: + + * 1x default size, + * 2x default size, + * 4x default size + +The higher the multiplier the more mass it will +cost you, to represent that you're using old storage technology, +so it costs a lot of mass to have more storage. + +The disk size is only settable like this in the assembly building. Once +you launch a vessel, its volume size is stuck the way it was when you +launched it. Multiple Volumes on One Vessel ------------------------------ Each kOS CX-4181 Scriptable Control System part contains '''one''' such -volume inside it. Therefore to send a craft into space with more storage -capacity than 10,000 bytes requires putting multiple CX-4181 Scriptable -Control System parts on the craft. +volume inside it. If you have multiple CX-4181 parts on the same craft, they are assumed to be networked together on the same system, and capable of reading each @@ -90,6 +120,9 @@ Therefore using the RENAME command on the volumes is useful when dealing with multiple CX-4181's on the same vessel, so they all will refer to the volumes using the same names. +If a kOS processor has a name tag set, then that processor's volume +will have its name initially set to the value of the name tag. + Archive ------- @@ -100,12 +133,12 @@ volume but with the following exceptions: - The archive represents the large bank of disk storage back at mission control's mainframe, rather than the storage on an indivdual craft. While "Volume 1" on one vessel might be a different disk than "Volume - 1" on another vessel, there is only volume called "archive" in the + 1" on another vessel, there is only one volume called "archive" in the entire solar system. Also, there's only one "archive" across all saved universes. If you play a new campaign from scratch, your archive in that new game will still have all the files in it from your previous saved game. This is because behid the scenes it's - stored in the plugin's directory, not the save game directory. + stored in the ``Ships/Script`` directory, not the save game directory. - It is infinitely large. - Unlike the other volumes, the archive volume does not have a byte limit. This is because the mainframe back at home base can store a @@ -117,16 +150,6 @@ volume but with the following exceptions: themselves also reverts to what it was at the time of the saved game. Because the archive is saved outside the normal game save, changes made there are retained even when reverting a flight. -- It's not always reachable if you are out in space, unless you have - antennae. -- Once a vessel is more than 100,000 meters away from mission control, - by default it cannot access the files on the archive. Commands such - as SWITCH TO , and COPY FROM will fail to work when trying to access - the archive volume while out of range. This can be changed by putting - antennae on the vessel. With enough - `antennae `__ it becomes possible - to reach the archive drive from farther away. Using this method it is - possible to alter the software stored on a vessel after launch. - Files in Archive are editable with a text editor directly and they will have the ``.ks`` extension. - Files in the Archive are stored on your computer in the subdirectory: diff --git a/doc/source/index.rst b/doc/source/index.rst index 976834d3d..7262f141f 100644 --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -1,60 +1,86 @@ .. _index: -Welcome to the **kOS** Documentation Website! -============================================= +kOS: Kerbal Operating System +============================ -**kOS** is a scriptable autopilot modification for **Kerbal Space Program**. It allows you write small programs that automate specific tasks. +==================================== ======================== =================================== +:ref:`Full Documentation ` :ref:`Download ` :ref:`Getting started ` +==================================== ======================== =================================== -.. toctree:: - :includehidden: - :titlesonly: - :maxdepth: 5 +:: - Home - Downloads and Links - Tutorials - Community Example Library - General - Language - Mathematics - Commands - Structures - Addons - Contribute - Changes - About + PRINT "Hello World.". + PRINT "These are the documents for Kerbal Operating System.". -Introduction to **kOS** and **KerboScript** -=========================================== -**KerboScript** is the language used to program the CPU device attached to your vessel and **kOS** is the operating system that interprets the code you write. The program can be as simple as printing the current altitude of the vessel and as complicated as a six-axis autopilot controller taking your vessel from the launchpad to Duna and back! With **kOS**, the sky is *not* the limit. +The do-it-yourself autopilot +---------------------------- -This mod *is* compatible with `RemoteTech`_, you just have to make sure you copy the program onto the local CPU before it goes out of range of KSC. +**kOS**, or Kerbal Operating System, is a community-supported +mod for the popular game +`Kerbal Space Program `__ -Installation +**kOS** is an autopilot you script yourself. **kOS** is to +programming, what Kerbal Space Program itself is to rocket science. +You don't have to know what you're doing to get started, but +you may find yourself learning a lot by accident as you play +with it. And if you already know a lot about the topic, it will +still be able to hold your interest. **kOS** is meant to scale +with the skill level of the user. You can start off doing very +small simple things with it, and get more and more into using its +features as you go. + +What it does ------------ -Like other mods, simply merge the contents of the zip file into your -Kerbal Space Program folder. +**kOS** introduces a few new parts that each contain a simulated +computer capable of running programs written in its own scripting +langauge called **kerboscript**. The computer has powerful +smarts built in to the hardware that allow it to do complex +spacecraft operations in one command, thus making it possible to +make complex programs with only a few lines of script text. -KerboScript ------------ +The intent of **kOS** is to be a fully in-game item that lives +inside the Kerbal's universe. The program isn't running on +your own gaming computer, but rather it's being run in a +virtual machine that is simulated in the underlying Unity engine. -**KerboScript** is a programming language that is derived from the language of planet Kerbin, which *sounds* like gibberish to non-native speakers but for some reason is *written* exactly like English. As a result, **KerboScript** is very English-like in its syntax. For example, it uses periods as statement terminators. +Get me Started! +--------------- -The language is designed to be easily accessible to novice programmers, therefore it is case-insensitive, and types are cast automatically whenever possible. +There is a quickstart tutorial for people new to **kOS** that +gets you off the ground with a very simple launching script, +sufficient to be an introduction for people new to the mod. +:ref:`Go ahead and give it a try `. -A typical command in **KerboScript** might look like this: -:: +Installation +------------ + +Like other Kerbal Space Program mods, simply copy the contents +of the zip file into your Kerbal Space Program folder, where it +will install into your ``GameData`` folder. + +:ref:`The mod is downloadable from a number of locations `. + +Documentation +------------- + +The page you are looking at right now is the entry point +into the full documentation of kOS. See the full table of +contents here: :ref:`Full Documentation `. - PRINT "Hello World". +Online Community +---------------- -Indices and tables -================== +:ref:`kOS has an active community ` of users willing +to help each other with ideas and algorithms. -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` +History +------- -.. _RemoteTech: https://kerbalstuff.com/mod/134/RemoteTech +kOS was originally begun as a mod by a single author, Kevin Laity aka Nivekk. +Although the project has undergone massive changes since then and now has +a very different underlying archetecture and is under active development +by a `different set of people `_, none +of that would have been possible without his original vision and work. diff --git a/doc/source/language.rst b/doc/source/language.rst index d1dca13e1..1f5b3ee21 100644 --- a/doc/source/language.rst +++ b/doc/source/language.rst @@ -6,8 +6,9 @@ The **KerboScript** Language .. toctree:: :maxdepth: 2 - General Features - Language Syntax - Flow Control - Variables - User Functions + General Features + Language Syntax + Flow Control + Variables + User Functions + Delegates (function references) diff --git a/doc/source/language/delegates.rst b/doc/source/language/delegates.rst new file mode 100644 index 000000000..96e093caa --- /dev/null +++ b/doc/source/language/delegates.rst @@ -0,0 +1,401 @@ +.. _delegates: + +Delegates (function references) +=============================== + +.. versionadded:: 0.19.0 + The delegate feature described on this page did not exist + prior to kOS 0.19.0. + +.. contents:: Contents + :local: + :depth: 2 + +Overview +-------- + +There are times it would be useful to be able to store, not the +result of calling a function, but rather a reference to the function +itself without calling it yet. Then you can use this value to call +the function later on. Or it would be useful to choose one of several +functions you might want to call, store that choice in a variable, so +that you can call it multiple times later. + +(If you are an experienced programmer, you have probably heard of this +feature or a similar feature under one of a number of names, depending +on which language you learned it in: "Function pointers", +"Function references", "Callbacks", "Delegates", "Deferred execution", +etc.) + +Kerboscript provides this feature with a built-in type called a +:struct:`KOSDelegate`, which remembers the details needed +to be able to call a function later on. + +The topic can be a bit confusing to people new to it, but this video, +produced shortly before the release of kOS 0.19.0 by one of the +(then new) collaborators of the team may help: + +`CheersKevin's explanation of delegates `__ + +.. note:: + It's important to know before going into this explanation, that the + feature described here does not work on structure suffixes as of + this release of kOS. See the bottom of this page for more details. + +.. _kosdelegate_atsign: + +Syntax: @ symbol +~~~~~~~~~~~~~~~~ + +To obtain a *delegate* of a function in kOS, you place a single +at-sign (``@``) to the right of the function name, where the +parentheses and arguments would normally have gone, as shown +below:: + + // example function: + function myfunc { parameter a,b. return a+b. } + + // example delegate of that function. + // Note the at-sign ('@'): + set aaa to myfunc@. + +When you do this, you are creating a variable of type +:struct:`KOSDelegate`, which can be passed around and +copied to other variables, sent as an argument to other +functions, and so on. + +.. _kosdelegate_call: + +Then you may call the function later on by using the ``:call`` +suffix, and giving it the parameters that ``myfunc`` would normally +have expected, which might look something like this:: + + print aaa:call(1, 2). + +Here's the full example:: + + function myfunc { + parameter a,b. + + return a + b. + } + + print myfunc(1, 2). // Prints the number 3, by calling myfunc now. + set aaa to myfunc@. // You don't see any effect just yet from this. + print aaa:call(1, 2). // Now you see the number 3 printed, + // just like calling myfunc directly. + +Omitting :CALL +~~~~~~~~~~~~~~ + +You can call a KOSDelegate without the use of the ``:call`` suffix, +instead just using parentheses directly abutted against the variable +name like a normal function call:: + + function testfunc {print "test".} + set del to testfunc@. + + // The following two are equivalent: + + del:call(). + del(). + +Why the '@' sign? +~~~~~~~~~~~~~~~~~ + +In Kerboscript, often when you mention a function's name and don't provide +any empty parentheses, if it's a function that takes zero arguments, it +ends up being called anyway. Thus ``set x to myfunc.`` ends up doing +the same thing as ``set x to myfunc().``. It ends up calling the +function right now. This is why you must append the ``@`` (at-sign) +symbol to the end of the function name to obtain a delegate of it. +It tells the compiler to suppress the normal automatic calling of the +function that would have occurred if you had left it bare. + +Why? +---- + +There are several reasons this feature can be useful. Some experienced +programmers will already know them, but here is an example of a useful +case as an illustration for people new to programming. Let's say you +wanted to start from a list of numbers, and you wanted to create a +subset list of just those numbers which are negative. You might write +code to do so like this:: + + // Just a hodgepodge list of numbers to use as an example: + local numlist is LIST(5, 6, 1, 49.1, 10, -2, 0, -12, 50, 0.3, 1.2, -1, 0). + + local result is list(). + for num in numlist { + if num < 0 { + result:add(num). + } + } + // Now result is the subset list. + +Okay, but then later let's say you want to do the same thing, but now you +want to get the subset which are integers (no fractional component after +the decimal point). Then you might do this:: + + local result is list(). + for num in numlist { + if num = round(num,0) { + result:add(num). + } + } + // Now result is the subset list. + +Okay, but then later let's say you want to do the same thing, but now you +want to get the subset which are even numbers:: + + local result is list(). + for num in numlist { + if mod(num,2) = 0 { + result:add(num). + } + } + // Now result is the subset list. + +So you look at these three cases and think "well, gee, they're all pretty much +the same thing except for what I put in the 'if' check. I should probably +combine them into one function." You want to make one function that does +essentially this:: + + function make_sublist { + parameter + input_list, // Full list to take a subset of. + check. // Condition to look for. + + local result is list(). + for num in input_list { + if check...TO-DO, how do I do this?? { + result:add(num). + } + } + return result. + } + +But how do you call it telling it what condition to look for? You're +essentially not trying to pass it a value, but you're trying to pass it +some code for it to run. + +And that's what you would use a delegate for. Here's the full example +that passes in a delegate where you tell it what kind of check you want +it to do by giving it a function you want it to call for the boolean check:: + + function make_sublist { + parameter + input_list, // Full list to take a subset of. + check_func. // pass in a delegate that expects 1 number parameter and returns 1 number. + + local result is list(). + for num in input_list { + if check_func:call(num) { + result:add(num). + } + } + return result. + } + + // Just a hodgepodge list of numbers to use as an example: + local numlist is LIST(5, 6, 1, 49.1, 10, -2, 0, -12, 50, 0.3, 1.2, -1, 0). + + function is_neg { parameter n. return (n < 0). } + function is_round { parameter n. return (n = round(n,0)). } + function is_even { parameter n. return (mod(n,2) = 0). } + + print "A list of all the negatives:". + print make_sublist(numlist, is_neg@). // note the '@' for a delegate of the function. + + print "A list of all the round numbers:". + print make_sublist(numlist, is_round@). // note the '@' for a delegate of the function. + + print "A list of all the even numbers:". + print make_sublist(numlist, is_even@). // note the '@' for a delegate of the function. + +This technique can be chained together to form very powerful operations on +collections and enumerations of data. You can start nesting several of +these types of function calls inside each other to perform a result, such +as "get the average mass of the subset of the subset of the parts on my +vessel that are fuel tanks that have oxidizer in them". There is a style +of programming called +`Functional programming `__ +in which you are meant to try to think this way about all possible problems +you are trying to solve. While Kerboscript is mostly an +`imperative programming language `__, +some limited concepts of functional programming style are possible through the use +of these delegates. + +lib_enum in KSLib +----------------- + +There is a library in the kslib that can be used to perform many data +set enumeration operations like the one described in the above section. +It was written to be released coinciding with the addition of this feature +to Kerboscript. In addition to being useful as a library, it also can +serve as a good list of example cases for how you can use this +"delegate" feature in your own code. Please have a look at +`the lib_enum library in KSLib `__ +to see what it has to offer. It allows you to do things such as sorting +a LIST() based on whatever comparison criteria you like, finding the +minimum or maximum from a list, transforming all items in the list according +to a mapping rule, finding the index of the first hit in a list that +matches given criteria, and so on. + +Advanced topics +=============== + +.. _kosdelegate_bind: + +Pre-binding arguments with :bind +-------------------------------- + +A :struct:`KOSDelegate` allows you to create another KOSDelegate that +has some of its parameters bound to some pre-set values, so you then +only need to supply the remaining, unbound values when you call it. +This allows you to implement certain types of functional programming +styles. This is done using the ``:bind`` suffix of KOSDelegate. + +Let's say you have a function you made that draws a vector arrow +from one ship to another, in a color of your choice, that looks like so:: + + function draw_ship_to_ship { + parameter + ship1, + ship2, + drawColor. + + local vdraw is vecdraw(). + set vdraw:start to ship1:position. + set vdraw:vec to ship2:position - ship1:position. + set vdraw:color to drawColor. + set vdraw:show to true. + return vdraw. + } + +You realize that you'll be using this a lot with the same two ships +over and over. You decide to create a variation of this function +that already has the two ships hardcoded to begin with, only +asking you for the final color parameter. + +You can do that with KOSDelegates, using the ``:bind`` suffix of +KOSDelegate, as follows:: + + local draw_delegate is draw_ship_to_ship@. + local draw_a_to_b is draw_delegate:bind(shipA, shipB). + + // Then later on you can call it with the first two arguments omitted + // because you pre-loaded them with BIND: + + set greenvec to draw_a_to_b(green). // note, only passing 1 arg, the color. + set tanvec to draw_a_to_b( rgb(0.7,0.6,0) ). // note, only passing 1 arg, the color. + set whitevec to draw_a_to_b(white). // note, only passing 1 arg, the color. + +Note that you can combine the two lines above that looked like this:: + + local draw_delegate is draw_ship_to_ship@. + local draw_a_to_b is draw_delegate:bind(shipA, shipB). + +into just this:: + + local draw_a_to_b is draw_a_to_b@:bind(shipA, shipB). + +When you use the at-sign(``@``), you are returning an object of type +:struct:`KOSDelegate` that can be used in-line right in the expression, +as demonstrated above. + +Currying +~~~~~~~~ + +It is possible to shave off exactly one parameter at a time in a chain +of these ``:bind`` calls. You could do this, for example:: + + // V() is the built-in function that makes a vector of x, y, and z + // components. You could bind the values one at a time as follows: + local vecx is V@:bind(10). // vecx is now a KOSDelegate hardcoding x to 10 and taking just y and z args + local vecxy is vecx:bind(5). // vecxy is a KOSDelegate hardcoding x to 10 and y to 5, taking just the z arg + local vecxyz is vecxy:bind(1). // vecxyz is a KOSDelegate hardcoding x to 10, y to 5, and z to 1, taking no args. + local vec is vecxyz:call(). // makes a V(10, 5, 1). + + // The above chain of bindings could have been chained together on one line like so: + local vec is V@:bind(10):bind(5):bind(1):call(). + +The technique of transforming a function that takes many arguments into +a nested succession of functions that each only take one argument has a +name. It's called `Currying `__. +(It's named after mathematician +`Haskell Curry `__ +and has nothing to do with delicious spicy food). + +(If anyone reading this is an experienced functional programmer and is thinking, +"But ``:bind`` as described here isn't currying", yes, we are aware that this is +correct. The KOSDelegate suffix ``:bind`` is technically not a proper "curry" because +it is actually a +`partial function application `__. +and thus doesn't *require* that you limit it to only one parameter at a time.) + +Anonymous functions +------------------- + +(If you are a beginner programmer, you can skip this paragraph.) + +If you are an experienced programmer who knows of a concept +called "anonymous functions" in which you can create instant +delegates as just in-line expressions, you should know that this +feature is not supported in Kerboscript. All KOSDelegates must +start as named functions you declare in the usual way. The +anonymous function feature may be added in a future release, +or it might not, depending on how complex it becomes to add it +to the language syntax. + +Closures +-------- + +Kerboscript :struct:`KOSDelegates` of user functions do hold their +"closure" information inside themselves. What on earth does that +mean? If you haven't heard this term before, it essentially means +that the KOSDelegate "remembers" what the local variables were +at the location where it was created. It is possible for the +KOSDelegate you make of a function to access the local variables +that only that function is allowed to see, even if you call that +delegate from a "foreign" location where those variables wouldn't +normally be in :ref:`scope `. + +Kinds of Delegate (no suffixes) +=============================== + +Under the hood, kOS handles several different kinds of 'functions' and +methods that aren't actually implemented the same way. A ``KOSDelegate`` +attempts to hide the details of these differences from the user, but +one difference in particular still stands out. In kOS version 0.19.0, +you cannot reliably make a delegate of a suffix just yet. (*This is +intended as a future feature though. It's been put off because it +involves decisions that impact the future of the language and once made, +can't be changed easily.*) + +- You **can** make a delegate of a :ref:`user function ` + implemented in Kerboscript code.:: + + function mysquarefunc { parameter a. return a*a. } + set x to mysquarefunc@. + set y to x:call(5). // y is now 25. + +- You **can** make a delegate of a built-in function provided by kOS + itself, provided it isn't a structure suffix.:: + + set r to round@. + set s to sqrt@. + print "square root of 7, to the nearest 2 places is: " + r:call(s:call(7), 2). + +- You **cannot** make a delegate of a suffix of a structure (*yet?*) + in Kerboscript.:: + + // + // WON'T WORK, WILL GIVE ERROR: + // + set altpos to latlng(10,20):altitudeposition@. // altitudeposition is a suffix of geoposition. + print "altpos at altitude 1000 is " + altpos:call(1000). + + However, if you like you can make your own user function that is a + wrapper around a structure suffix call, and make a delegate of THAT. + diff --git a/doc/source/language/features.rst b/doc/source/language/features.rst index fa9b9dc9e..40e1bdd59 100644 --- a/doc/source/language/features.rst +++ b/doc/source/language/features.rst @@ -10,29 +10,34 @@ General Features of the **KerboScript** Language Case Insensitivity ------------------ -Everything in **KerboScript** is case-insensitive, including your own variable names and filenames. The only exception is when you perform a string comparison, (``"Hello"="HELLO"`` will return false.) - -Most of the examples here will show the syntax in all-uppercase to help make it stand out from the explanatory text. +Everything in **KerboScript** is case-insensitive, including your own variable names and filenames. +This extends to string comparison as well. (``"Hello"="HELLO"`` will return true.) Expressions ----------- KerboScript uses an expression evaluation system that allows you to perform math operations on variables. Some variables are defined by you. Others are defined by the system. There are four basic types: -1. Numbers -~~~~~~~~~~ +Numbers (Scalars) +~~~~~~~~~~~~~~~~~ You can use mathematical operations on numbers, like this:: SET X TO 4 + 2.5. PRINT X. // Outputs 6.5 -The system follows the order of operations, but currently the implementation is imperfect. For example, multiplication will always be performed before division, regardless of the order they come in. This will be fixed in a future release. +The system follows the usual mathematical order of operations. -2. Strings -~~~~~~~~~~ +Throughout the documentation, numbers like this are referred to +as :struct:`Scalars ` to distinguish them from the many +places where the mod works with :struct:`Vector ` values +instead. -Strings are pieces of text that are generally meant to be printed to the screen. For example:: +Strings +~~~~~~~ + +:struct:`Strings ` are pieces of text that are generally +meant to be printed to the screen. For example:: PRINT "Hello World!". @@ -40,16 +45,34 @@ To concatenate strings, you can use the + operator. This works with mixtures of PRINT "4 plus 3 is: " + (4+3). +Booleans +~~~~~~~~ + +:struct:`Booleans ` are values that can either be ``True`` +or ``False`` and can be used to store the result of conditional checks:: + + set myValue to (x >= 10 and x <= 99). + if myValue { + print "x is a two digit number.". + } + .. _features structures: -3. Structures -~~~~~~~~~~~~~ +Structures +~~~~~~~~~~ Structures are variables that contain more than one piece of information. For example, a Vector has an X, a Y, and a Z component. Structures can be used with SET.. TO just like any other variable. To access the sub-elements of a structure, you use the colon operator (":"). Here are some examples:: PRINT "The Mun's periapsis altitude is: " + MUN:PERIAPSIS. PRINT "The ship's surface velocity is: " + SHIP:VELOCITY:SURFACE. +.. versionadded:: 0.19.0 + + As of kOS version 0.19.0, in fact ALL values a script can see are + now a kind of :struct:`Structure `, even basic primitive + types such as Boolean and Scalar. + + Many structures also let you set a specific component of them, for example:: SET VEC TO V(10,10,10). // A vector with x,y,z components @@ -59,8 +82,8 @@ Many structures also let you set a specific component of them, for example:: .. _features methods: -4. Structure Methods -~~~~~~~~~~~~~~~~~~~~ +Structure Methods +~~~~~~~~~~~~~~~~~ Structures also often contain methods. A method is a suffix of a structure that actually performs an activity when you mention it, and can sometimes take parameters. The following are examples of calling methods of a structure:: @@ -79,6 +102,44 @@ Structures also often contain methods. A method is a suffix of a structure that For more information, see the :ref:`Structures Section `. A full list of structure types can be found on the :ref:`Structures ` page. For a more detailed breakdown of the language, see the :ref:`Language Syntax Constructs ` page. + +.. _short_circuit: + +Short-circuiting booleans +------------------------- + +Further reading: https://en.wikipedia.org/wiki/Short-circuit_evaluation + +When performing any boolean operation involving the use of the AND or the OR +operator, kerboscript will short-circuit the boolean check. What this means +is that if it gets to a point in the expression where it already knows the +result is a forgone conclusion, it doesn't bother calculating the rest of +the expression and just quits there. + +Example:: + + set x to true. + if x or y+2 > 10 { + print "yes". + } else { + print "no". + }. + +In this case, the fact that x is true means that when evaluating +the boolean expression ``x or y+2 > 10`` it never even bothers trying +to add y and 2 to find out if it's greater than 10. It already knew +as soon as it got to the ``x or whatever`` that given that x is true, +the *whatever* doesn't matter one bit. Once one side of an OR is true, +the other side can either be true or false and it won't change the fact +that the whole expression will be true anyway. + +A similar short circuiting happens with AND. Once the left side of the +AND operator is false, then the entire AND expression is guaranteed +to be false regardless of what's on the right side, so kerboscript +doesn't bother calculating the righthand side once the lefthand side is false. + +Read the link above for implications of why this matters in programming. + Late Typing ----------- @@ -119,7 +180,7 @@ User Functions Kerboscript supports user functions which you can write yourself and call from your own scripts. *These are not* :ref:`structure -methods ` *(which as of this writing are a feature which +methods ` *(which as of this writing are a feature which only works for the built-in kOS types, and are not yet supported by the kerboscript language for user functions you write yourself).* diff --git a/doc/source/language/flow.rst b/doc/source/language/flow.rst index 97869b049..620ee8b1d 100644 --- a/doc/source/language/flow.rst +++ b/doc/source/language/flow.rst @@ -103,8 +103,8 @@ Releases a lock on a variable. See ``LOCK``:: .. index:: UNTIL .. _until: -``UNTIL`` ---------- +``UNTIL`` loop +-------------- Performs a loop until a certain condition is met:: @@ -114,6 +114,11 @@ Performs a loop until a certain condition is met:: SET X to X + 1. } +.. note:: + If you are writing an ``UNTIL`` loop that looks much like the + example above, consider the possibility of writing it as a + :ref:`FROM ` loop instead. + Note that if you are creating a loop in which you are watching a physical value that you expect to change each iteration, it's vital that you insert a small WAIT at the bottom of the loop like so:: SET PREV_TIME to TIME:SECONDS. @@ -134,8 +139,8 @@ page `. .. index:: FOR .. _for: -``FOR`` -------- +``FOR`` loop +------------ Loops over a list collection, letting you access one element at a time. Syntax:: @@ -144,7 +149,7 @@ Loops over a list collection, letting you access one element at a time. Syntax:: Where: - `variable1` is a variable to hold each element one at a time. -- `varaible2` is a LIST variable to iterate over. +- `variable2` is a LIST variable to iterate over. Example:: @@ -158,9 +163,218 @@ Example:: } PRINT "There are " + numOut + "Flamed out engines.". +.. note:: + If you are an experienced programmer looking for something more + like the for-loop from C, with its 3-part clauses of init, + check, and increment in the header, see the :ref:`FROM ` loop + description. The kerboscript 'for' loop is more like a + 'foreach' loop from other modern languages like C#. + +.. index:: FROM +.. _from: + +``FROM`` loop +------------- + +Identical to the :ref:`UNTIL ` loop, except that it also contains +an explicit initializer and incrementer section in the header. + +Syntax: +~~~~~~~ + + ``FROM`` { one or more statements } ``UNTIL`` Boolean_expression + ``STEP`` { one or more statements } ``DO`` one statement or a block of statements inside braces '{}' + +Quick Example:: + + print "Countdown initiated:". + FROM {local x is 10.} UNTIL x = 0 STEP {set x to x-1.} DO { + print "T -" + x. + } + +.. note:: + If you are an experienced programmer, you can think of the ``FROM`` + loop as just being Kerboscript's version of the generic 3-part + for-loop ``for( int x=10; x > 0; --x ) {...}`` that first appeared + in C and is now so common to many programming languages, except + that its Boolean check uses the reverse of that logic because it's + based on UNTIL loops instead of WHILE loops. + +What the parts mean +~~~~~~~~~~~~~~~~~~~ + +- ``FROM`` { one or more statements } + + - Perform these statements at the beginning before starting the first + pass through the loop. They may contain local declarations of new + variables. If they do, then the variables will be local to the body + of the loop and won't be visible outside the loop. In this case the + braces ``{`` and ``}`` are mandatory even when there is only one + statement present. To create a a null FROM clause, give it an empty + set of braces. + +- ``UNTIL`` expression + + - Exactly like the :ref:`UNTIL ` loop. The loop will run this + expression at the start of each pass through the loop body, and if + it's true, it will abort and stop running the loop. It checks before + the initial first pass of the loop as well, so it's possible for the + check to prevent the loop body from even executing once. Braces + ``{``..``}`` are not used here because this is not technically a + complete statement. It is just an expression that evaluates to a + value. + +- ``STEP`` { one or more statements } + + - Perform these statements at the bottom of each loop pass. The purpose + is typically to increment or decrement the variable you declared in + your ``FROM`` clause to get it ready for the next loop pass. In this + case the braces ``{`` and ``}`` are mandatory even when there is + only one statement present. To create a null FROM clause, give + it an empty set of braces. + +- ``DO`` one statement or a block of statements inside braxes ``{``..``}``: + + - This is where the loop body gets put. Much like with the UNTIL and FOR + loops, these braces are not mandatory when there is only exactly one + statement in the body, but are a very good idea to have anyway. + +Why some braces are mandatory +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Some braces are mandatory (for the ``FROM`` and ``STEP`` clauses) even +when there is only one statement inside them, because the period that +ends a single statement would look like it's terminating the entire +FROM loop if it was open and bare. Wrapping it inside braces makes it +more visually obvious that it's not the end of the FROM loop. + +Why ``DO`` is mandatory +~~~~~~~~~~~~~~~~~~~~~~~ + +Other loop types don't require a keyword to begin the loop body. You +can just start in with the opening left-brace ``{``. The reason the +additional ``DO`` keyword exists in the FROM loop is because otherwise +you'd have two back-to-back brace sections (The end of the ``STEP`` +clause would abut against the start of the loop body) without any +punctuation between them, and that would look too much like it was +starting a brand new thing from scratch. + +Other formatting examples +~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + // prints a count from 1 to 10: + FROM {local x is 1.} UNTIL x > 10 STEP {set x to x+1.} DO { print x.} + + // Entire header in one line, body indented: + // -------------------------------------------- + FROM {local x is 1.} UNTIL x > 10 STEP {set x to x+1.} DO { + print x. + } + + // Each header part on its own line, body indented: + // -------------------------------------------- + FROM {local x is 1.} + UNTIL x > 10 + STEP {set x to x+1.} + DO { + print x. + } + + // Fully exploded out: Each header part on its own line, + // each clause indented separately: + // -------------------------------------------- + FROM + { + local x is 1. // x will count upward from 1. + local y is 10. // while y is counting downward from 10. + } + UNTIL + x > 10 or y = 0 + STEP + { + set x to x+1. + set y to y-1. + } + DO + { + print "x is " + x + ", y is " + y. + } + + // ETC. + +Any such combination of indenting styles, or mix and match of them, is +understood by the compiler. The compiler ignores the spacing and +indenting. It is recommended that you pick just two of them and stick +with them - one compact one to use for short headers, and one longer exploded +one to use for more wordy headers when you have to split it up across lines. + +The literal meaning of ``FROM`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If you have a ``FROM`` loop, it ends up being exactly identical to an +:ref:`UNTIL ` loop written as follows: + +If we assume that AAAA, BBBB, CCCC, and DDDD are placeholders referring +to the actual script syntax, then in the generic case, the following +is how all FROM loops work: + +FROM LOOP:: + + FROM { AAAA } UNTIL BBBB STEP { CCCC } DO { DDDD } + +Is exactly the same as doing this:: + + { // start a brace to keep the scope of AAAA local to the loop. + AAAA + UNTIL BBBB { + DDDD + + CCCC + } + } // end a brace to throw away the local scope of AAAA + + +An example of why the FROM loop is useful +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Given that the ``FROM`` loop is really just an alternate way to write a +certain format of UNTIL loop, you might ask why bother having it. +The reason is that in the long run it makes your script easier to +edit and maintain. It makes things more self-contained and cut-and-pasteable: + +Above, in the documentation for :ref:`UNTIL ` loops, this example was +given:: + + SET X to 1. + UNTIL X > 10 { // Prints the numbers 1-10 + PRINT X. + SET X to X + 1. + } + +The same example, expressed as a ``FROM`` loop is this:: + + FROM {SET X to 1.} UNTIL X > 10 {SET X to X + 1.} DO { + PRINT X. + } + +Kerboscript ``FROM`` loop provides a way to place those sections in the +loop header so they are declared up front and let people see the layout +of how the loop iterates, leaving the body to just contain the statements +to be done for that iteration. + +If you are editing your script and need to cut a loop section and move it +elsewhere, the FROM loop makes it more visually obvious how to cut +that loop and move it. It makes the important parts of the loop be self +contained in the header, so you don't leave the initializer behind when +moving the loop. + + .. index:: WAIT .. _wait: + ``WAIT`` -------- @@ -177,7 +391,10 @@ Note that any ``WAIT`` statement, no matter what the actual expression is, will The :ref:`WAIT ` command only causes mainline code to be suspended. Trigger code such as WHEN, ON, LOCK STEERING, and LOCK THROTTLE, will continue executing while your program - is sitting still on the WAIT command. + is sitting still on the WAIT command. Furthermore, you cannot + cause a WAIT to happen when executing a trigger's body like + WHEN or ON, or in the formula for a LOCK STEERING or LOCK + THROTTLE or LOCK WHEELSTEERING or LOCK WHEELTHROTTLE statement. .. index:: WHEN @@ -202,6 +419,11 @@ The body of a ``THEN`` or an ``ON`` statement interrupts the normal flow of a ** .. warning:: Do not make the body of a ``WHEN``/``THEN`` take a long time to execute. If you attempt to run code that lasts too long in the body of your ``WHEN``/``THEN`` statement, :ref:`it will cause an error `. Avoid looping during ``WHEN``/``THEN`` if you can. For details on how to deal with this, see the :ref:`tutorial on design patterns `. +For the reason mentioned in the warning above, you also cannot +make the system execute a ``WAIT`` command when inside the +body of a WHEN/THEN statement. Attempting to do so will have +no effect. + .. note:: .. versionchanged:: 0.12 **IMPORTANT BREAKING CHANGE:** In previous versions of **kOS**, the body of a ``WHEN``/``THEN`` would execute simultaneously in the background with the rest of the main program. This behavior has changed as of version *0.12* of **kOS**, as described above, and scripts that used to rely on this behavior will not work with version *0.12* of **kOS** @@ -254,6 +476,12 @@ The body of an ``ON`` statement can be a list of commands inside curly braces, j .. warning:: DO NOT make the body of an ``ON`` statement take a long time to execute. If you attempt to run code that lasts too long in the body of your ``ON`` statement, :ref:`it will cause an error `. For general help on how to deal with this, see the :ref:`tutorial on design patterns `. +For the reason mentioned in the warning above, you also cannot +make the system execute a ``WAIT`` command when inside the +body of a WHEN/THEN statement. Attempting to do so will have +no effect. + + Avoid looping during ``ON`` code blocks if you can. If you are going to make extensive use of ``ON`` triggers, it's important to understand more details of how they :ref:`work in the kOS CPU `. .. index:: PRESERVE diff --git a/doc/source/language/syntax.rst b/doc/source/language/syntax.rst index 8821d0f32..58413be60 100644 --- a/doc/source/language/syntax.rst +++ b/doc/source/language/syntax.rst @@ -21,6 +21,8 @@ General Rules The following are **reserved command keywords** and special operator symbols: +.. highlight:: none + **Arithmetic Operators**:: + - * / ^ e ( ) @@ -31,27 +33,33 @@ operator symbols: **Instructions and keywords**:: - set to if else until lock unlock print at on toggle - wait when then off stage clearscreen add remove log - break preserve declare parameter switch copy from rename - volume file delete edit run compile list reboot shutdown - for unset batch deploy in all + add all at batch break clearscreen compile copy declare delete + deploy do do edit else file for from from function global if + in list local lock log off on once parameter preserve print reboot + remove rename run set shutdown stage step switch then to toggle + unlock unset until volume wait when **Other symbols**:: { } [ ] , : // +.. highlight:: kerboscript + *Comments* consist of everything from a "//" symbol to the end of the line:: set x to 1. // this is a comment. +.. highlight:: none + **Identifiers**: Identifiers consist of: a string of (letter, digit, or underscore). The first character must be a letter. The rest may be letters, digits or underscores. **Identifiers are case-insensitive**. The following are identical identifiers:: My_Variable my_varible MY_VARAIBLE +.. highlight:: kerboscript + **case-insensitivity** - The same case-insensitivity applies throughout the entire language, with all keywords except when comparing literal strings. The values inside the strings are still case-sensitive, for example, the following will print "unequal":: + The same case-insensitivity applies throughout the entire language, with all keywords and when comparing literal strings. The values inside the strings are also case-insensitive, for example, the following will print "equal":: if "hello" = "HELLO" { print "equal". diff --git a/doc/source/language/user_functions.rst b/doc/source/language/user_functions.rst index 9a400afb7..70dc6cbe1 100644 --- a/doc/source/language/user_functions.rst +++ b/doc/source/language/user_functions.rst @@ -44,8 +44,8 @@ Help for the new user - What is a Function? .. _declare function: -``DECLARE FUNCTION`` --------------------- +DECLARE FUNCTION +---------------- In kerboscript, you can make your own user functions using the DECLARE FUNCTION command, which has syntax as follows: @@ -104,16 +104,102 @@ and once its been "parsed" by the compiler, the function can be called from anywhere in the program. The best design pattern is probably to create your library of function -calls as one or more separate .ks files that contain ONLY function -definitions and nothing else in them. Then when you "run" the file +calls as one or more separate .ks files that contain just function +definitions and not much else in them. Then when you "run" the file containing the functions, what you're really doing is just loading the function definitions into memory so they can be called by other programs. At the top of your main script you can then "run" the other scripts containing the library of functions to get them compiled into memory. -``DECLARE PARAMETER`` ---------------------- +Using RUN ONCE +-------------- + +If you want to load a library of functions that ALSO perform some +initialization mainline code, but you only want the mainline code +to execute once when the library is first loaded, rather than +every time a subprogram runs your library, then use the 'once' +keyword with the run command as follows:: + + // This will run mylib1 3 times, re-running the mainline code in it:` + run mylib1. + run mylib1. + run mylib1. + + // This will run mylib2 only one time, ignoring the additional + // instances: + run once mylib2. + run once mylib2. // mylib2 was already run, will not be run again. + run once mylib2. // mylib2 was already run, will not be run again. + +Example: Let's say you want to have a library that keeps a counter +and always returns the next number up every time it's called. You +want it initialized to start with, but not get re-initialized every time +another sub-program includes the library in its code. So you have this: + +**prog1, which calls counterlib:** :: + + // prog1 + run once counterlib. + + // Get some unique IDs: + print "prog1: next counter ID = " + counter_next(). + print "prog1: next counter ID = " + counter_next(). + print "prog1: next counter ID = " + counter_next(). + + run subprogram. + +**subprogram, which ALSO calls counterlib:** :: + + // subprogram + run once counterlib. + + print "subprogram: next counter ID = " + counter_next(). + print "subprogram: next counter ID = " + counter_next(). + print "subprogram: next counter ID = " + counter_next(). + + +**counterlib** :: + + // init code: + global current_num is 0. + + // counter_next() + function counter_next { + set current_num to current_num + 1. + return current_num. + } + +.. highlight:: none + +The above example prints this:: + + prog1: next counter ID = 1 + prog1: next counter ID = 2 + prog1: next counter ID = 3 + subprogram: next counter ID = 4 + subprogram: next counter ID = 5 + subprogram: next counter ID = 6 + +whereas, had you used just ``run counterlib.`` instead of +``run once counterlib.``, then it would have printed this:: + + prog1: next counter ID = 1 + prog1: next counter ID = 2 + prog1: next counter ID = 3 + subprogram: next counter ID = 1 + subprogram: next counter ID = 2 + subprogram: next counter ID = 3 + +.. highlight:: kerboscript + +because ``subprogram`` would have run the mainline code +``global current_num is 0`` again when it was run inside +``subprogram``. + + +DECLARE PARAMETER +----------------- If your function expects to have parameters passed into it, you can use the :ref:`DECLARE PARAMETER ` command to do @@ -147,10 +233,82 @@ in the previous example where it said:: print_corner(4,"That's me in the corner"). +.. _default_parameters: + +Optional Parameters (parameter defaults) +---------------------------------------- + +If you wish, you may make some of the parameters of a user function optional +by defaulting them to a starting value with the ``IS`` keyword, as follows: + +example 1:: + + FUNCTION MYFUNC { + DECLARE PARAMETER P1, P2, P3 is 0, P4 is "cheese". + print P1 + ", " + P2 + ", " + P3 + ", " + P4. + } + +example 2:: + + FUNCTION MYFUNC { + PARAMETER P1, P2, P3 is 0, P4 is "cheese". + + print P1 + ", " + P2 + ", " + P3 + ", " + P4. + } + +example 3:: + + FUNCTION MYFUNC { + PARAMETER P1. + PARAMETER P2. + PARAMETER P3 is 0. + PARAMETER P4 is "cheese". + + print P1 + ", " + P2 + ", " + P3 + ", " + P4. + } + +In the above examples, all of which are the same, if you call the function +with parameter 3 or 4 missing, kOS will assign it the default value mentioned +in the ``PARAMETER`` statement, like in the examples below:: + + MYFUNC(1,2). // prints "1, 2, 0, cheese". + MYFUNC(1,2,3). // prints "1, 2, 3, cheese". + MYFUNC(1,2,3,"hi"). // prints "1, 2, 3, hi". + +Whenever arguments are missing, the system always makes up the difference by +using defaults for the lastmost parameters until the correct number have been +padded. (So for example, if you call MYFUNC() above with 3 arguments, it's +the last argument, P4, that gets defaulted, but P3 does not. But if you call +it with 2 arguments, both P4 and P3 get defaulted.) + +It is illegal to put mandatory (not defaulted) parameters after defaulted ones. + +This will not work:: + + DECLARE PARAMETER thisIsOptional is 0, + thisIsOptionalToo is 0. + thisIsMandatory. + +Because the optional parameters didn't come at the end. + + +Default parameters follow short-circuit logic +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Remember that if you have an optional parameter with an initializer +expression, the expression will not get executed if the calling +function had an argument present in that position. The expression +only gets executed if the system needed to pad a missing argument. + +.. versionadded:: 0.18.3 + Optional Parameters were added as a new feature in kOS 0.18.3 + + + .. _interpreter functions: Functions and the terminal interpreter -:::::::::::::::::::::::::::::::::::::: +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ You **cannot** call functions from the interpreter interactive command line if they were declared inside of script programs. @@ -175,7 +333,7 @@ In the future we may find a way to fix this problem, but for right now, just don't do it. Calling a function without parentheses (please don't) -::::::::::::::::::::::::::::::::::::::::::::::::::::: +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In some cases it is possible to call a function with the parentheses off, as shown below, but this is not recommended:: @@ -201,8 +359,8 @@ function (a function you made for yourself in another file) then it does not work, for complex reason involving the compiler and late-time binding. -``LOCAL .. TO`` ------------------ +LOCAL .. TO +----------- (aka: **local variables**) @@ -236,7 +394,7 @@ A more in-depth explanation of kerboscript's scoping rules and how they work is found :ref:`on another page ` Initializers are now mandatory for the DECLARE statement -:::::::::::::::::::::::::::::::::::::::::::::::::::::::: +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This is now **illegal** syntax:: @@ -262,7 +420,7 @@ initializer clause. use - a string, an integer, a floating point number, etc.* Difference between declare and set -:::::::::::::::::::::::::::::::::: +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ You may think that:: @@ -280,8 +438,8 @@ be made (and that new ``x`` will be global, not local). .. _return: -``RETURN`` ----------- +RETURN +------ ``return`` *expression(optional)* *dot(mandatory)* @@ -336,17 +494,22 @@ value of the parameter, as in this example:: embiggen(global_val). print global_val. + +.. highlight:: none + The above example will print:: 30 x has been embiggened to 40 30 +.. highlight:: kerboscript + Although the function added 10 to its OWN copy of the parameter, the caller's copy of the parameter remained unchanged. Important exception to passing by value - structures -:::::::::::::::::::::::::::::::::::::::::::::::::::: +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ If the value being sent to the function as its parameter is a complex structure consisting of sub-parts (i.e. if it has @@ -371,12 +534,16 @@ in the object really WILL change it, as shown here:: half_vector(global_vec). print "afterward, global_vec is now " + global_vec. +.. highlight:: none + This will give the following result:: full vector is v(10,20,30) half vector is v(5,10,15) afterward, global_vec is now v(5,10,15) +.. highlight:: kerboscript + Because a vector is a suffixed structure, it effectively acts as if it was passed in by reference instead of by value, and so when it was changed in the function, the caller's original copy is what was @@ -418,7 +585,7 @@ Example:: return getSum(aList) / aList:LENGTH. }. - set L to LIST(); + set L to LIST(). L:ADD(10). L:ADD(9). print "mean average is " + getMean(L). @@ -443,7 +610,7 @@ User Function Gotchas --------------------- Calling program's functions from the interpreter -:::::::::::::::::::::::::::::::::::::::::::::::: +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ As :ref:`explained above `, kOS 0.17.0 does not support the calling of a function from the interpreter console @@ -451,7 +618,7 @@ and if you attempt it you will get very strange and random errors that you might waste a lot of time trying to track down. Inconsistent returns -:::::::::::::::::::: +~~~~~~~~~~~~~~~~~~~~ Note that if you sometimes do and sometimes don't return a value, from the same function, as in the example here:: @@ -483,7 +650,7 @@ a user function, that you *always* do so in every path through your function. Accidentally using globals -:::::::::::::::::::::::::: +~~~~~~~~~~~~~~~~~~~~~~~~~~ It is possible to accidentally create global variables when you didn't meant to, just because you made a typo. diff --git a/doc/source/language/variables.rst b/doc/source/language/variables.rst index dcd823f14..be92b0dcf 100644 --- a/doc/source/language/variables.rst +++ b/doc/source/language/variables.rst @@ -63,7 +63,7 @@ Detailed Description of the syntax: * After that it must contain some expression for the initial starting value of the variable. * After that it must contain a dot ("period"), like all commands in - kerboscript. + Kerboscript. :: @@ -157,10 +157,14 @@ Program 2:: SET A TO 7. RUN PROGRAM1( A, A+1 ). +.. highlight:: none + The above example would give the output:: X times Y is 56. +.. highlight:: kerboscript + It is also possible to put more than one parameter into a single ``DECLARE PARAMETER`` statement, separated by commas, as shown below:: DECLARE PARAMETER X, Y, CheckFlag. @@ -186,6 +190,53 @@ are always local to the location they were declared at, the keyword The ``DECLARE PARAMETER`` statements can appear anywhere in a program as long as they are in the file at a point earlier than the point at which the parameter is being used. The order the arguments need to be passed in by the caller is the order the ``DECLARE PARAMETER`` statements appear in the program being called. +Optional Parameters (defaulted parameters) +:::::::::::::::::::::::::::::::::::::::::: + +If you wish, you may make some of the parameters of a program or a user +function optional by defaulting them to a starting value with the ``IS`` keyword, as follows: + + // Imagine this is a file called MYPROG + + DECLARE PARAMETER P1, P2, P3 is 0, P4 is "cheese". + print P1 + ", " + P2 + ", " + P3 + ", " + P4. + + + // Imagine this is a different file that runs it: + + run MYPROG(1,2). // prints "1, 2, 0, cheese". + run MYPROG(1,2,3). // prints "1, 2, 3, cheese". + run MYPROG(1,2,3,"hi"). // prints "1, 2, 3, hi". + +Whenever arguments are missing, the system always makes up the difference by +using defaults for the lastmost parameters until the correct number have been +padded. (So for example, if you call MYFUNC() above with 3 arguments, it's +the last argument, P4, that gets defaulted, but P3 does not. But if you call +it with 2 arguments, both P4 and P3 get defaulted.) + +It is illegal to put mandatory (not defaulted) parameters after defaulted ones. + +This will not work:: + + DECLARE PARAMETER thisIsOptional is 0, + thisIsOptionalToo is 0. + thisIsMandatory. + +Because the optional parameters didn't come at the end. + +Default parameters follow short-circuit logic +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Remember that if you have an optional parameter with an initializer +expression, the expression will not get executed if the calling +function had an argument present in that position. The expression +only gets executed if the system needed to pad a missing argument. + +.. versionadded:: 0.18.3 + Optional Parameters were added as a new feature in kOS 0.18.3 + + + .. note:: **Pass By Value** @@ -208,6 +259,49 @@ This follows the :ref:`scoping rules explained below `. If the variable can be found in the current local scope, or any scope higher up, then it won't be created and instead the existing one will be used. +.. _defined: + +``DEFINED`` +----------- + +:: + + DEFINED identifier + +Returns a boolean true or false according to whether or not an +identifier is defined in such a way that you can use it from +this part of the program. (i.e. is it declared and is it in scope +and visible right now):: + + // This part prints 'doesn't exist": + if defined var1 { + print "var1 exists". + } else { + print "var1 doesn't exist." + } + + local var1 is 0. + + // But now it prints that it does exist: + if defined var1 { + print "var1 exists". + } else { + print "var1 doesn't exist." + } + +The DEFINED operator pays attention to all the normal scoping rules +described in the :ref:`scoping section below `. If an identifier +does exist but is not usable from the current scope, it will return false. + +Note that DEFINED does not work well on things that are not pure identifiers. +for example:: + + print defined var1:suffix1. + +is going to end up printing "False" because it's looking for pure identifiers, +not complex suffix chains, and there's no identifier called "var1:suffix1". + + Difference between SET and DECLARE LOCAL and DECLARE GLOBAL ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: @@ -284,7 +378,7 @@ File2.ks:: lock x to "this is x". -But now with the kerboscript of kOS 0.17.0, you can make it work +But now with the Kerboscript of kOS 0.17.0, you can make it work by inserting empty parentheses after the lock name to help give the compiler the hint that you expected x to be a function call (which is what a lock really is): @@ -387,7 +481,7 @@ Scoping terms .. note:: .. versionadded:: 0.17 - In prior versions of kerboscript, all identifiers other than + In prior versions of Kerboscript, all identifiers other than DECLARE PARAMETER identifiers were always global variables no matter what, even if you used the DECLARE statement to make them. @@ -402,7 +496,7 @@ What is Scope? Global scope The simplest scope is called "global". Global scope simply means "this variable can be used from anywhere in the program". If you - never use the DECLARE statement, then your variables in kerboscript + never use the DECLARE statement, then your variables in Kerboscript will all be in *global scope*. For simple easy scripts used by beginners, this is often enough and you don't have to read the rest of this topic until you start advancing to more intermediate scripts. @@ -532,12 +626,17 @@ Examples:: print "average is " + calcAverage(testList). print "but out here where it's global, sum is still " + sum. +.. highlight:: none + This example will print:: + Inside calcAverage, sum is 30 average is 10 but out here where it's global, sum is still -1 +.. highlight:: kerboscript + Thus proving that the variable called SUM inside the function is NOT the same variable as the one called SUM out in the global main code. @@ -581,7 +680,7 @@ down the road. If you make a typo in a variable name, you end up creating a new variable instead of generating an error. Or you may just forget to mark the variable as local when you intended to. -If you wish to instruct kerboscript to alter its behavior and +If you wish to instruct Kerboscript to alter its behavior and disable its normal implicit globals, and instead demand that all variables MUST be explicitly declared and may not use implied lazy scoping, the ``@LAZYGLOBAL`` compiler directive allows you to @@ -597,6 +696,14 @@ all variables you use in a declaration somewhere (with the exception of the built-in variables such as THROTTLE, STEERING, SHIP, and so on.) +.. note:: + The @LAZYGLOBAL directive does not affect LOCK statements. + LOCKS are a special case that define new pseudo-functions + when encountered and don't quite work the same way as + SET statements do. Thus even with @LAZYGLOBAL OFF, it's still + possible to make a LOCK statement with a typo in the identifier + name and it will still create the new typo'ed lock that way. + @LAZYGLOBAL Can only exist at the top of your code. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -677,13 +784,13 @@ History: variable implicitly by just using it in a SET statement. There are a variety of programming languages that work like this, - such as Perl, Javascript, and Lua. However, they all share one + such as Perl, JavaScript, and Lua. However, they all share one thing in common - once you want to allow the possibility of having local variables, you have to figure out how this should work with the implicit variable declaration feature. And all those languages went with the same solution, which - kerboscript now follows as well. Because implicit undeclared + Kerboscript now follows as well. Because implicit undeclared variables are intended to be a nice easy way for new users to ease into programming, they should always default to being global so that people who wish to keep programming that way diff --git a/doc/source/library.rst b/doc/source/library.rst index 76602859e..acb11de08 100644 --- a/doc/source/library.rst +++ b/doc/source/library.rst @@ -5,10 +5,10 @@ Community Examples Library Starting with version 0.17.0 of kOS, we have decided to support a separate repository of examples and libraries that "live" entirely -in kerboscript code only. This is a useful place to find helpful -code written by other users of kOS, some of whom may be members of -the main kOS development team, and some of whom might ber users in the -community. +in Kerboscript code only. This is a useful place to find helpful +code written mostly by other users of kOS, some of whom may be members +of the main kOS development team, but most of whom are not and are +just ordinary users of kOS like you. The separate repository is found here: @@ -16,15 +16,10 @@ https://github.com/KSP-KOS/KSLib Some examples of useful things you can find there are: -* A generic all-purpose **PID controller** function: - `library script `_, - `documentation `_, and - `example `_ - * A library for getting **navball orientation** information: - `library script `_, - `documentation `_, and - `example `_ - * An example of how to use the :ref:`sasmode ` feature: - `example `_ +* A helpful set of routines letting you enumerate over lists, queues, and stacks, using callback delegates. +* An example of a seven-segment display controller. +* A keypad emulator that lets you move a 'finger' cursor around a visual keyboard and type letters. +* A library for drawing chunky lines out of the character cells of the terminal. +* A library routine to help calculate when to launch from the launchpad to match a given target inclination orbit. diff --git a/doc/source/math.rst b/doc/source/math.rst index cba3e7c89..815977812 100644 --- a/doc/source/math.rst +++ b/doc/source/math.rst @@ -7,6 +7,7 @@ Mathematics and Basic Geometry :maxdepth: 2 math/basic + math/scalar math/vector math/direction math/geocoordinates diff --git a/doc/source/math/basic.rst b/doc/source/math/basic.rst index 73c079ca0..23d7c897b 100644 --- a/doc/source/math/basic.rst +++ b/doc/source/math/basic.rst @@ -1,12 +1,27 @@ .. _basic math: +Basic Math Functions +==================== + +These functions are built-in for performing basic math operations in kOS. + .. _constants: .. index:: Fundamental Constants Fundamental Constants -===================== +--------------------- + +There is a bound variable called CONSTANT which contains some basic fundamental +constants about the universe that you may find handy in your math operations. + +.. versionadded:: 0.18 -A few fundamental constants can be obtained by using the expression ``CONSTANT()`` followed by a colon (``:``) followed by one of the following: + Prior to kOS version 0.18, ``constant`` was a function call, and + therefore to say ``constant:pi``, you had to say ``constant():pi``. + The function call ``constant()`` still exists and still works, but + the new way without the parentheses is preferred going forward, + and the way with the parentheses may become deprecated later. + For the moment, both ways of doing it work. .. list-table:: :header-rows: 1 @@ -18,34 +33,96 @@ A few fundamental constants can be obtained by using the expression ``CONSTANT() * - :global:`G` - Newton's Gravitational Constant * - :global:`E` - - Natural Log + - Base of the natural log (Euler's number) * - :global:`PI` - - :math:`Ï€` + - :math:`\pi` + * - :global:`c` + - Speed of light in a vacuum, in m/s. + * - :global:`AtmToKPa` + - Conversion constant: Atmospheres to kiloPascals. + * - :global:`KPaToAtm` + - Conversion constant: kiloPascals to Atmospheres. + * - :global:`DegToRad` + - Conversion constant: Degrees to Radians. + * - :global:`RadToDeg` + - Conversion constant: Radians to Degrees. -.. global:: Constant():G +.. global:: Constant:G Newton's Gravitational Constant, 6.67384E-11:: PRINT "Gravitational parameter of Kerbin is:". - PRINT constant():G * Kerbin:Mass. + PRINT constant:G * Kerbin:Mass. -.. global:: Constant():E +.. global:: Constant:E Natural Log base "e":: PRINT "e^2 is:". - PRINT constant():e ^ 2. + PRINT constant:e ^ 2. -.. global:: Constant():PI +.. global:: Constant:PI Ratio of circumference of a circle to its diameter +.. global:: Constant:C + + Speed of light in a vacuum, in meters per second. + + .. note:: + In Kerbal Space Program, all physics motion is purely Newtonian. + You can go faster than the speed of light provided you have enough + delta-V, and no time dilation effects will occur. The universe + will behave entirely linearly even at speeds near *c*. + + This constant is provided mainly for the benefit of people who are + playing with the mod "RemoteTech" installed, who may want to perform + calculations about signal delays to hypothetical probes. (Note that + if the probe already has a connection, you can + :ref:`ask Remotetech directly ` what the signal delay is. + +.. global:: Constant:AtmToKPa + + A conversion constant. + + If you have a pressure measurement expressed in atmospheres of pressure, + you can multiply it by this to get the equivalent in kiloPascals + (kiloNewtons per square meter). + +.. global:: Constant:KPaToATM + + A conversion constant. + + If you have a pressure measurement expressed in kiloPascals (kiloNewtons + per square meter), you can multiply it by this to get the equivalent + in atmospheres. + +.. global:: Constant:DegToRad + + A conversion constant. + + If you have an angle measured in degrees, you can multiply it by + this to get the equivalent measure in radians. It is exactly + the same thing as saying ``constant:pi / 180``, except the result is + pre-recorded as a constant number and thus no division is performed + at runtime. + +.. global:: Constant:RadToDeg + + A conversion constant. + + If you have an angle measured in radians, you can multiply it by + this to get the equivalent measure in degrees. It is exactly + the same thing as saying ``180 / constant:pi``, except the result is + pre-recorded as a constant number and thus no division is performed + at runtime. + .. _math functions: .. index:: Mathematical Functions Mathematical Functions -====================== +---------------------- ==================== =================================================== Function Description @@ -62,6 +139,8 @@ Mathematical Functions :func:`ROUND(a)` round to whole number :func:`ROUND(a,b)` round to nearest place :func:`SQRT(a)` square root + :func:`CHAR(a)` character from unicode + :func:`UNCHAR(a)` unicode from character ==================== =================================================== .. function:: ABS(a) @@ -138,11 +217,29 @@ Mathematical Functions PRINT SQRT(7.89). // prints 2.80891438103763 +.. function:: CHAR(a) + + :parameter a: (number) + :return: (string) single-character string containing the unicode character specified + + :: + + PRINT CHAR(34) + "Apples" + CHAR(34). // prints "Apples" + +.. function:: UNCHAR(a) + + :parameter a: (string) + :return: (number) unicode number representing the character specified + + :: + + PRINT UNCHAR("A"). // prints 65 + .. _trig: .. index:: Trigonometric Functions Trigonometric Functions ------------------------ +~~~~~~~~~~~~~~~~~~~~~~~ .. list-table:: :header-rows: 1 @@ -155,7 +252,7 @@ Trigonometric Functions * - :func:`ARCSIN(x)` * - :func:`ARCCOS(x)` * - :func:`ARCTAN(x)` - * - :func:`ARCTAN2(x,y)` + * - :func:`ARCTAN2(y,x)` .. function:: SIN(a) @@ -186,7 +283,7 @@ Trigonometric Functions .. function:: ARCSIN(x) - :parameter x: (scalar) + :parameter x: (:ref:`scalar `) :return: (deg) angle whose sine is x :: @@ -195,7 +292,7 @@ Trigonometric Functions .. function:: ARCCOS(x) - :parameter x: (scalar) + :parameter x: (:ref:`scalar `) :return: (deg) angle whose cosine is x :: @@ -204,7 +301,7 @@ Trigonometric Functions .. function:: ARCTAN(x) - :parameter x: (scalar) + :parameter x: (:ref:`scalar `) :return: (deg) angle whose tangent is x :: @@ -213,8 +310,8 @@ Trigonometric Functions .. function:: ARCTAN2(y,x) - :parameter y: (scalar) - :parameter x: (scalar) + :parameter y: (:ref:`scalar `) + :parameter x: (:ref:`scalar `) :return: (deg) angle whose tangent is :math:`\frac{y}{x}` :: diff --git a/doc/source/math/direction.rst b/doc/source/math/direction.rst index 6681b847e..b22cb5845 100644 --- a/doc/source/math/direction.rst +++ b/doc/source/math/direction.rst @@ -43,9 +43,16 @@ Creation .. function:: Q(x,y,z,rot) - A :struct:`Direction` can also be created out of a *Quaternion* tuple, indicated with the :func:`Q()` function, as shown below where ``x``, ``y``, and ``z`` are a :struct:`Vector` to rotate around, and ``rot`` is how many degrees to rotate:: + A :struct:`Direction` can also be created out of a *Quaternion* tuple, + indicated with the :func:`Q()` function, passing it the x, y, z, w + values of the Quaternion. + `The concept of a Quaternion `__ + uses complex numbers and is beyond the scope of the kOS + documentation, which is meant to be simple to understand. It is + best to not use the Q() function unless Quaternions are something + you already understand. - SET myDir TO Q( x, y, z, rot ). + SET myDir TO Q( x, y, z, w ). .. _heading: .. function:: HEADING(dir,pitch) @@ -125,21 +132,21 @@ Structure The suffixes of a :struct:`Direction` cannot be altered, so to get a new :struct:`Direction` you must construct a new one. - ========================= =================== ================================ - Suffix Type Description - ========================= =================== ================================ - :attr:`PITCH` scalar (deg) Rotation around :math:`x` axis - :attr:`YAW` scalar (deg) Rotation around :math:`y` axis - :attr:`ROLL` scalar (deg) Rotation around :math:`z` axis - :attr:`FOREVECTOR` :struct:`Vector` This Direction's forward vector (z axis after rotation). - VECTOR :struct:`Vector` Alias synonym for :attr:`FOREVECTOR` - :attr:`TOPVECTOR` :struct:`Vector` This Direction's top vector (y axis after rotation). - UPVECTOR :struct:`Vector` Alias synonym for :attr:`TOPVECTOR` - :attr:`STARVECTOR` :struct:`Vector` This Direction's starboard vector (z axis after rotation). - RIGHTVECTOR :struct:`Vector` Alias synonym for :attr:`STARVECTOR` - :attr:`INVERSE` :struct:`Direction` The inverse of this direction. - :attr:`unary minus` :struct:`Direction` Using the negation operator "-" on a Direction does the same thing as using the :INVERSE suffix on it. - ========================= =================== ================================ + ========================= ======================= ================================ + Suffix Type Description + ========================= ======================= ================================ + :attr:`PITCH` :struct:`scalar` (deg) Rotation around :math:`x` axis + :attr:`YAW` :struct:`scalar` (deg) Rotation around :math:`y` axis + :attr:`ROLL` :struct:`scalar` (deg) Rotation around :math:`z` axis + :attr:`FOREVECTOR` :struct:`Vector` This Direction's forward vector (z axis after rotation). + VECTOR :struct:`Vector` Alias synonym for :attr:`FOREVECTOR` + :attr:`TOPVECTOR` :struct:`Vector` This Direction's top vector (y axis after rotation). + UPVECTOR :struct:`Vector` Alias synonym for :attr:`TOPVECTOR` + :attr:`STARVECTOR` :struct:`Vector` This Direction's starboard vector (z axis after rotation). + RIGHTVECTOR :struct:`Vector` Alias synonym for :attr:`STARVECTOR` + :attr:`INVERSE` :struct:`Direction` The inverse of this direction. + :attr:`unary minus` :struct:`Direction` Using the negation operator "-" on a Direction does the same thing as using the :INVERSE suffix on it. + ========================= ======================= ================================ The :struct:`Direction` object exists primarily to enable automated steering. You can initialize a :struct:`Direction` using a :struct:`Vector` or a ``Rotation``. :struct:`Direction` objects represent a rotation starting from an initial point in **KSP**'s coordinate system where the initial state was looking down the :math:`+z` axis, with the camera "up" being the :math:`+y` axis. So for example, a :struct:`Direction` pointing along the :math:`x` axis might be represented as ``R(0,90,0)``, meaning the initial :math:`z`-axis direction was rotated *90 degrees* around the :math:`y` axis. @@ -155,7 +162,7 @@ Structure .. attribute:: Direction:PITCH - :type: scalar (deg) + :type: :ref:`scalar ` (deg) :access: Get only @@ -163,14 +170,14 @@ Structure .. attribute:: Direction:YAW - :type: scalar (deg) + :type: :ref:`scalar ` (deg) :access: Get only Rotation around the :math:`y` axis. .. attribute:: Direction:ROLL - :type: scalar (deg) + :type: :ref:`scalar ` (deg) :access: Get only diff --git a/doc/source/math/geocoordinates.rst b/doc/source/math/geocoordinates.rst index d3286aa06..0651ab0f5 100644 --- a/doc/source/math/geocoordinates.rst +++ b/doc/source/math/geocoordinates.rst @@ -39,27 +39,27 @@ Structure - Description * - :attr:`LAT` - - scalar (deg) + - :ref:`scalar ` (deg) - none - Latitude * - :attr:`LNG` - - scalar (deg) + - :ref:`scalar ` (deg) - none - Longitude * - :attr:`DISTANCE` - - scalar (m) + - :ref:`scalar ` (m) - none - distance from :ref:`CPU Vessel ` * - :attr:`TERRAINHEIGHT` - - scalar (m) + - :ref:`scalar ` (m) - none - above or below sea level * - :attr:`HEADING` - - scalar (deg) + - :ref:`scalar ` (deg) - none - *absolute* heading from :ref:`CPU Vessel ` * - :attr:`BEARING` - - scalar (deg) + - :ref:`scalar ` (deg) - none - *relative* direction from :ref:`CPU Vessel ` * - :attr:`POSITION` @@ -68,9 +68,13 @@ Structure - Position of the surface point. * - :attr:`ALTITUDEPOSITION` - `Vector` (3D Ship-Raw coords) - - scalar (altitude above sea level) + - :ref:`scalar ` (altitude above sea level) - Position of a point above (or below) the surface point, by giving the altitude number. +.. note:: + + This type is serializable. + .. attribute:: GeoCoordinates:LAT The latitude of this position on the surface. diff --git a/doc/source/math/scalar.rst b/doc/source/math/scalar.rst new file mode 100644 index 000000000..c04f531eb --- /dev/null +++ b/doc/source/math/scalar.rst @@ -0,0 +1,99 @@ +.. _scalar: + +Scalar +====== + +.. structure:: Scalar + + .. list-table:: **Members** + :widths: 1 + :header-rows: 1 + + * - (Scalar values have no suffixes other than the ones inherited from :struct:`Structure `.) + + * - + +A Scalar value is the kind the system gives you whenever you are working +with a number of some sort which, unlike with a :struct:`Vector `, +does not have a pointing orientation in 3D space. + +In other words, it's just a number. A plain no-frills ordinary number. + +Experienced programmers will be aware of the concept of there being +different kinds of number depending on what you want to do with it. +There's "integer" versus "floating point" versus "fixed point", +and theres single-precision, double-precision and so on. + +kOS tries to be friendly to the new person just playing around with +simple programming without a lot of expertise, and to that end, the +difference between these types is abstracted away as much as possible. + +Operators +--------- + +The following basic arithmetic operators are defined when both `a` and `b` +are scalars: + +- `a ^ b` exponent: `a` to the power `b` +- `-a` negative of `a` +- `a * b` `a / b` muiltiply or divide two numbers. +- `a + b` `a - b` add or subtract two numbers + +The order of operations is in the order of the table listing above. +(for example multiplication and division happen before subtraction +and addition). + +Scientific Notation +------------------- + +You can specify a number using scientific notation using the letter 'e', +as shown:: + + set x to 1.23e5. + print x. // prints 123000 + set x to 1.23e-5. + print x. // prints 0.0000123 + +Limitations of Scalars +---------------------- + +The implementation of Scalars can currently only store values that fit +the following criteria: + +The value is a *real number* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Or "What the heck does 'attempted to push NaN onto the stack' mean?". + +kOS does not have a numeric type designed to deal with +*imaginary numbers* or *complex numbers*. Therefore, for +example, if you attempted to perform ``sqrt(-4)``, you would get +a "NaN error", rather than the irrational number ``2i``. NaN means +"Not a Number" and it means the system is incapable of storing the +correct answer. Another example of where you will get a "NaN error" +would be if you attempted to perform ``arcsin(1.01)``, since there is +no such thing as the angle that gives a sine of 1.01. + +The value must be a *rational number* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +When you ask kOS to tell you `constant:pi`, you are technically not +getting the *actual* correct value. Instead you are getting a rational +number approximation that is accurate to about 15 decimal places. In +kOS, Scalar values cannot store irrational numbers. + +The larger the magnitude, the less the precision +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +For example, while it *is* possible to store exactly the number ``99.001``, +it is not possible to store exactly the number ``999999999999999.001``, even +though both numbers are only precise up to the thousandths place. + +If you attempt to ``set x to 999999999999999.001.`` and then ``print x.``, +you'll find that the value you get back has been rounded off a bit. + +In a nutshell, what really matters is how many significant digits there are, +not how many places after the decimal point. You can't have more than +roughly 15 significant decimal digits (it's not exactly 15 because of +differences between binary and decimal counting, but that gives you +a rough estimate). + diff --git a/doc/source/math/vector.rst b/doc/source/math/vector.rst index 0e636566d..98435493b 100644 --- a/doc/source/math/vector.rst +++ b/doc/source/math/vector.rst @@ -40,19 +40,19 @@ Structure - Set * - :attr:`X` - - scalar + - :ref:`scalar ` - yes - yes * - :attr:`Y` - - scalar + - :ref:`scalar ` - yes - yes - * - :attr:`Y` - - scalar + * - :attr:`Z` + - :ref:`scalar ` - yes - yes * - :attr:`MAG` - - scalar + - :ref:`scalar ` - yes - yes * - :attr:`NORMALIZED` @@ -60,7 +60,7 @@ Structure - yes - no * - :attr:`SQRMAGNITUDE` - - scalar + - :ref:`scalar ` - yes - no * - :attr:`DIRECTION` @@ -72,30 +72,34 @@ Structure - yes - no +.. note:: + + This type is serializable. + .. attribute:: Vector:X - :type: scalar + :type: :ref:`scalar ` :access: Get/Set The :math:`x` component of the vector. .. attribute:: Vector:Y - :type: scalar + :type: :ref:`scalar ` :access: Get/Set The :math:`y` component of the vector. .. attribute:: Vector:Z - :type: scalar + :type: :ref:`scalar ` :access: Get/Set The :math:`z` component of the vector. .. attribute:: Vector:MAG - :type: scalar + :type: :ref:`scalar ` :access: Get/Set The magnitude of the vector, as a scalar number, by the Pythagorean Theorem. @@ -109,7 +113,7 @@ Structure .. attribute:: Vector:SQRMAGNITUDE - :type: scalar + :type: :ref:`scalar ` :access: Get only The magnitude of the vector, squared. Use instead of ``vec:MAG^2`` if you need to square of the magnitude as this skips the step in the Pythagorean formula where you take the square root in the first place. Taking the square root and then squaring that would introduce floating point error needlessly. @@ -139,13 +143,13 @@ Operations and Methods ============================================================= ============= Method / Operator Return Type ============================================================= ============= - :ref:`* (asterisk) ` scalar or :struct:`Vector` + :ref:`* (asterisk) ` :struct:`scalar` or :struct:`Vector` :ref:`+ (plus) ` :struct:`Vector` :ref:`- (minus) ` :struct:`Vector` :ref:`- (unary) ` :struct:`Vector` - :func:`VDOT`, :func:`VECTORDOTPRODUCT`, :ref:`* ` scalar + :func:`VDOT`, :func:`VECTORDOTPRODUCT`, :ref:`* ` :struct:`scalar` :func:`VCRS`, :func:`VECTORCROSSPRODUCT` :struct:`Vector` - :func:`VANG`, :func:`VECTORANGLE` scalar (deg) + :func:`VANG`, :func:`VECTORANGLE` :struct:`scalar` (deg) :func:`VXCL`, :func:`VECTOREXCLUDE` :struct:`Vector` ============================================================= ============= @@ -243,7 +247,7 @@ Method / Operator Return Type :parameter v1: (:struct:`Vector`) :parameter v2: (:struct:`Vector`) :return: Angle between two vectors - :rtype: scalar + :rtype: :ref:`scalar ` This returns the angle between v1 and v2. It is the same result as: diff --git a/doc/source/structures.rst b/doc/source/structures.rst index df9e79fe3..f1d9d3955 100644 --- a/doc/source/structures.rst +++ b/doc/source/structures.rst @@ -5,50 +5,15 @@ Structure Reference A general discussion of structures :ref:`can be found here `. -* :ref:`Mathematics ` - * :ref:`Fundamental Constants ` - * :ref:`Mathematical Functions ` - * :ref:`Trigonometric Functions ` - * :struct:`Vector` - * :struct:`Direction` - * :struct:`GeoCoordinates` -* :struct:`Waypoint` -* :ref:`Orbits ` - * :struct:`Orbit` - * :struct:`Orbitable` - * :struct:`OrbitableVelocity` -* :ref:`Celestial Bodies ` - * :struct:`Body` - * :struct:`Atmosphere` -* :ref:`Vessels ` - * :struct:`Vessel` - * :struct:`Control` - * :struct:`ManeuverNode` - * :struct:`Engine` - * :struct:`AggregateResource` - * :struct:`DockingPort` - * :struct:`Gimbal` - * :struct:`Stage` - * :struct:`Part` - * :struct:`PartModule` - * :struct:`Sensor` - * :struct:`VesselSensors` -* :ref:`Configuration and Misc ` - * :struct:`Config` - * :struct:`FileInfo` - * :struct:`List` - * :struct:`Highlight` - * :struct:`Iterator` - * :struct:`Terminal` - * :ref:`Colors ` - * :ref:`Time `, + then this example:: + + print thingy:hassuffix("maxthrust"). + + would print ``True`` if ``thingy`` was a vessel of some sort, but + ``False`` if ``thingy`` was a body, because there exists a maxthrust + suffix for vessels but not for bodies. + + When searching for suffix names, the search is performed in a + case-insensitive way. Kerboscript cannot distinguish ":AAA" + and ":aaa" as being two different suffixes. In kerboscript, + they'd be the same suffix. + +.. attribute:: Structure:SUFFIXNAMES + + :type: :struct:`List ` of :struct:`strings ` + :access: Get only + + Returns a list of all the string names of the suffixes that can + be used by the thing you call it on. As of this release, no + information is shown about the parameters the suffix expects, or + about the return value it gives. All you see is the suffix names. + + If this object's type is inherited from other types (for example, a + :struct:`Body ` is also a kind of :struct:`Orbitable `.) + then what you see here contains the list of all the suffixes from the base + type as well. (Therefore the suffixes described here on this very page + always appear in the list for any type.) + + Note, for some objects, like Vessels, this can be a rather long list. + + The list is returned sorted in alphabetical order. + + Example:: + + set v1 to V(12,41,0.1). // v1 is a vector + print v1:suffixnames. + List of 14 items: + [0] = DIRECTION + [1] = HASSUFFIX + [2] = ISSERIALIZABLE + [3] = ISTYPE + [4] = MAG + [5] = NORMALIZED + [6] = SQRMAGNITUDE + [7] = SUFFIXNAMES + [8] = TOSTRING + [9] = TYPENAME + [10] = VEC + [11] = X + [12] = Y + [13] = Z + +.. attribute:: Structure:TYPENAME + + :type: :struct:`String` + :access: Get only + + Gives the name of the type of the object, in kOS terminology. + + Type names correspond to the types mentioned throughout these + documentation pages, at the tops of the tables that list + suffixes. + + Examples:: + + set x to 1. + print x:typename + Scalar + + set x to 1.1. + print x:typename + Scalar + + set x to ship:parts[2]. + print x:typename + Part + + set x to Mun. + print x:typename + Body + + The kOS types described in these documentaion pages correspond + one-to-one with underlying types in the C# code the implements + them. However they don't have the same name as the underlying + C# names. This returns an abstraction of the C# name. There + are a few places in the C# code where an error message will + mention the C# type name instead of the kOS type name. This is + an issue that might be resolved in a later release. + +.. attribute:: Structure:ISTYPE(name) + + :Parameter name: string name of the type being checked for + :type: :struct:`Boolean` + :access: Get only + + This is ``True`` if the value is of the type mentioned in the name, or + if it is a type that is derived from the type mentioned in the name. + Otherwise it is ``False``. + + Example:: + + set x to SHIP. + print x:istype("Vessel"). + True + print x:istype("Orbitable"). + True + print x:istype("Structure"). + True. + print x:istype("Body"). + False + print x:istype("Vector"). + False + print x:istype("Some bogus type name that doesn't exist"). + False + + The type name is searched in a case-insensitive way. + +.. attribute:: Structure:INHERITANCE + + :type: :struct:`String` + :access: Get only + + Gives a string describing the typename of this value, and the + typename of the type this value is inherited from, and the typename + of the type that type is inherited from, etc all the way to + this root type of ``Structure`` that all values share. + + Example:: + + set x to SHIP. + print x:inheritance. + Vessel derived from Orbitable derived from Structure + + (The kOS types described in that string are an abstraction of the + underlying C# names in the mod's implementation, and a few of the + C# types the mod uses to abstract a few things are skipped along + the way, as they are types the script code can't see directly.) + +.. attribute:: Structure:ISSERIALIZABLE + + :type: :struct:`Boolean` + :access: Get only + + Not all types can be saved using the built-in serialization function + :ref:`WRITEJSON `. For those that can, values of that + type will return ``True`` for this suffix, otherwise it returns ``False``. + diff --git a/doc/source/structures/vessels/aggregateresource.rst b/doc/source/structures/vessels/aggregateresource.rst index 33b5adae5..02c11254e 100644 --- a/doc/source/structures/vessels/aggregateresource.rst +++ b/doc/source/structures/vessels/aggregateresource.rst @@ -13,7 +13,7 @@ IN MyList :: LIST RESOURCES IN RESLIST. FOR RES IN RESLIST { PRINT "Resource " + RES:NAME. - PRINT " value = " + AMOUNT. + PRINT " value = " + RES:AMOUNT. PRINT " which is " + ROUND(100*RES:AMOUNT/RES:CAPACITY) + "% full.". @@ -25,7 +25,7 @@ This is also the type returned by STAGE:RESOURCES :: SET RESLIST TO STAGE:RESOURCES. FOR RES IN RESLIST { PRINT "Resource " + RES:NAME. - PRINT " value = " + AMOUNT. + PRINT " value = " + RES:AMOUNT. PRINT " which is " + ROUND(100*RES:AMOUNT/RES:CAPACITY) + "% full.". @@ -42,13 +42,13 @@ This is also the type returned by STAGE:RESOURCES :: - Description * - :attr:`NAME` - - string + - :ref:`string ` - Resource name * - :attr:`AMOUNT` - - scalar + - :ref:`scalar ` - Total amount remaining * - :attr:`CAPACITY` - - scalar + - :ref:`scalar ` - Total amount when full * - :attr:`PARTS` - List @@ -58,21 +58,21 @@ This is also the type returned by STAGE:RESOURCES :: .. attribute:: AggregateResource:NAME :access: Get only - :type: string + :type: :ref:`string ` The name of the resource, i.e. "LIQUIDFUEL", "ELECTRICCHARGE", "MONOPROP". .. attribute:: AggregateResource:AMOUNT :access: Get only - :type: scalar + :type: :ref:`scalar ` The value of how much resource is left. .. attribute:: AggregateResource:CAPACITY :access: Get only - :type: scalar + :type: :ref:`scalar ` What AMOUNT would be if the resource was filled to the top. diff --git a/doc/source/structures/vessels/alt.rst b/doc/source/structures/vessels/alt.rst new file mode 100644 index 000000000..7126a3d66 --- /dev/null +++ b/doc/source/structures/vessels/alt.rst @@ -0,0 +1,34 @@ +.. _alt: + +ALT +=== + +ALT is a special object that exists just to help you get the +altitudes of interest for a vessel future. It is grandfathered +in for the sake of backward compatibility, but this information +is also available on the Vessel structure as well, which is +the better new way to do it: + + +.. structure:: ALT + + .. list-table:: + :header-rows: 1 + :widths: 2 1 4 + + * - Suffix + - Type + - Description + + * - :attr:`APOAPSIS` + - :ref:`scalar `, meters + - altitude in meters of SHIP's apoapsis. Same as SHIP:APOAPSIS. + + * - :attr:`PERIAPSIS` + - :ref:`scalar `, meters + - altitude in meters of SHIP's periapsis. Same as SHIP:PERIAPSIS. + + * - :attr:`RADAR` + - :ref:`scalar `, meters + - Altitude of SHIP above the ground terrain, rather than above sea level. + diff --git a/doc/source/structures/vessels/crewmember.rst b/doc/source/structures/vessels/crewmember.rst new file mode 100644 index 000000000..d654870a6 --- /dev/null +++ b/doc/source/structures/vessels/crewmember.rst @@ -0,0 +1,78 @@ +.. _crewmember: + +CrewMember +=========== + +Represents a single crew member of a vessel. + +.. structure:: CrewMember + + .. list-table:: + :header-rows: 1 + :widths: 2 1 4 + + * - Suffix + - Type + - Description + + * - :attr:`NAME` + - :ref:`string ` + - crew member's name + * - :attr:`GENDER` + - :ref:`string ` + - "Male" or "Female" + * - :attr:`EXPERIENCE` + - :ref:`scalar ` + - experience level (number of stars) + * - :attr:`TRAIT` + - :ref:`string ` + - "Pilot", "Engineer" or "Scientist" + * - :attr:`TOURIST` + - :ref:`Boolean ` + - true if this crew member is a tourist + * - :attr:`PART` + - :struct:`Part` + - part in which the crew member is located + + +.. attribute:: CrewMember:NAME + + :type: :ref:`string ` + :access: Get only + + crew member's name + +.. attribute:: CrewMember:GENDER + + :type: :ref:`string ` + :access: Get only + + "Male" or "Female" + +.. attribute:: CrewMember:EXPERIENCE + + :type: :ref:`scalar ` + :access: Get only + + experience level (number of stars) + +.. attribute:: CrewMember:TRAIT + + :type: :ref:`string ` + :access: Get only + + crew member's trait (specialization), for example "Pilot" + +.. attribute:: CrewMember:TOURIST + + :type: :ref:`Boolean ` + :access: Get only + + true if this crew member is a tourist + +.. attribute:: CrewMember:PART + + :type: :struct:`Part` + :access: Get only + + :struct:`Part` this crew member is located in diff --git a/doc/source/structures/vessels/dockingport.rst b/doc/source/structures/vessels/dockingport.rst index 7115f07e1..476cf047b 100644 --- a/doc/source/structures/vessels/dockingport.rst +++ b/doc/source/structures/vessels/dockingport.rst @@ -5,6 +5,12 @@ DockingPort Some of the Parts returned by :ref:`LIST PARTS ` will be of type :struct:`DockingPort`. +.. note:: + + .. versionadded:: 0.18 + + The spelling of suffixes `AQUIRERANGE`, `AQUIREFORCE`, and `AQUIRETORQURE` on the :struct:`DockingPort` structure has been corrected. Please use `ACQUIRERANGE`, `ACQUIREFORCE`, and `ACQUIRETORQURE` instead. Using the old incorrect spelling, a deprecation exception will be thrown, with instruction to use the new spelling. + .. structure:: DockingPort @@ -20,29 +26,35 @@ Some of the Parts returned by :ref:`LIST PARTS ` will be of type : - - A :struct:`DockingPort` is a kind of :struct:`Part` - * - :attr:`AQUIRERANGE` + * - :attr:`ACQUIRERANGE` - scalar - active range of the port - * - :attr:`AQUIREFORCE` + * - :attr:`ACQUIREFORCE` - scalar - force experienced when docking - * - :attr:`AQUIRETORQUE` + * - :attr:`ACQUIRETORQUE` - scalar - torque experienced when docking * - :attr:`REENGAGEDDISTANCE` - scalar - distance at which the port is reset * - :attr:`DOCKEDSHIPNAME` - - string + - :ref:`string ` - name of vessel the port is docked to + * - :attr:`NODEPOSITION` + - vector + - coords of where the docking node attachment point is in SHIP-RAW xyz + * - :attr:`NODETYPE` + - :ref:`string ` + - two nodes are only dockable together if their NODETYPE strings match * - :attr:`PORTFACING` - :struct:`Direction` - facing of the port * - :attr:`STATE` - - string + - :ref:`string ` - current state of the port * - :meth:`UNDOCK` - - + - - callable to release the dock * - :attr:`TARGETABLE` - boolean @@ -53,21 +65,21 @@ Some of the Parts returned by :ref:`LIST PARTS ` will be of type : :struct:`DockingPort` is a type of :struct:`Part`, and therefore can use all the suffixes of :struct:`Part`. Shown below are only the suffixes that are unique to :struct:`DockingPort`. -.. attribute:: DockingPort:AQUIRERANGE +.. attribute:: DockingPort:ACQUIRERANGE :type: scalar :access: Get only gets the range at which the port will "notice" another port and pull on it. -.. attribute:: DockingPort:AQUIREFORCE +.. attribute:: DockingPort:ACQUIREFORCE :type: scalar :access: Get only gets the force with which the port pulls on another port. -.. attribute:: DockingPort:AQUIRETORQUE +.. attribute:: DockingPort:ACQUIRETORQUE :type: scalar :access: Get only @@ -83,11 +95,45 @@ Some of the Parts returned by :ref:`LIST PARTS ` will be of type : .. attribute:: DockingPort:DOCKEDSHIPNAME - :type: string + :type: :ref:`string ` :access: Get only name of vessel on the other side of the docking port. +.. attribute:: DockingPort:NODEPOSITION + + :type: vector + :access: Get only + + The coordinates of the point on the docking port part where the + port attachment spot is located. This is different from the + part's position itself because that's the position of the center + of the whole part. This is the position of the face of the + docking port. Coordinates are in SHIP-RAW xyz coords. + +.. attribute:: DockingPort:NODETYPE + + :type: :ref:`string ` + :access: Get only + + Each docking port has a node type string that specifies its + compatibility with other docking ports. In order for two docking + ports to be able to attach to each other, the values for their + NODETYPEs must be the same. + + The base KSP stock docking port parts all use one of the following + three values: + + - "size0" for all Junior-sized docking ports. + - "size1" for all Normal-sized docking ports. + - "size2" for all Senior-sized docking ports. + + Mods that provide their own new kinds of docking port might use + any other value they feel like here, but only if they are trying + to declare that the new part isn't supposed to be able to connect + to stock docking ports. Any docking port that is meant to connect + to stock ports will have to adhere to the above scheme. + .. attribute:: DockingPort:PORTFACING :type: :struct:`Direction` @@ -97,7 +143,7 @@ Some of the Parts returned by :ref:`LIST PARTS ` will be of type : .. attribute:: DockingPort:STATE - :type: string + :type: :ref:`string ` :access: Get only One of the following string values: @@ -122,10 +168,7 @@ Some of the Parts returned by :ref:`LIST PARTS ` will be of type : .. attribute:: DockingPort:TARGETABLE - :type: boolean + :type: :ref:`Boolean ` :access: Get only True if this part can be picked with ``SET TARGET TO``. - - - diff --git a/doc/source/structures/vessels/element.rst b/doc/source/structures/vessels/element.rst index f9b76530d..11b677e83 100644 --- a/doc/source/structures/vessels/element.rst +++ b/doc/source/structures/vessels/element.rst @@ -1,7 +1,7 @@ .. _element: Element -====== +======= An element is a *docked component* of a :struct:`Vessel`. When you dock several vessels together to create one larger vessel, you can obtain the "chunks" of the @@ -22,27 +22,29 @@ elements and what they do. .. structure:: Element ===================================== ========================= ============= - Suffix Type Description + Suffix Type Description ===================================== ========================= ============= - :attr:`NAME` string The name of the docked craft - :attr:`UID` string Unique Identifier - :attr:`PARTS` :struct:`List` all :struct:`Parts ` - :attr:`RESOURCES` :struct:`List` all :struct:`AggrgateResources ` + :attr:`NAME` :struct:string The name of the docked craft + :attr:`UID` :struct:string Unique Identifier + :attr:`PARTS` :struct:`List` all :struct:`Parts ` + :attr:`DOCKINGPORTS` :struct:`List` all :struct:`DockingPorts ` + :attr:`VESSEL` :struct:`Vessel` the parent :struct:`Vessel` + :attr:`RESOURCES` :struct:`List` all :struct:`AggrgateResources ` ===================================== ========================= ============= .. attribute:: Element:UID - :type: string + :type: :ref:`string ` :access: Get only A unique id .. attribute:: Element:NAME - :type: string + :type: :ref:`string ` :access: Get/Set - The name of the Element element, is an artifact from the vessel the element belonged to before docking. Cannot be set to an empty string. + The name of the Element element, is an artifact from the vessel the element belonged to before docking. Cannot be set to an empty :ref:`string `. .. attribute:: Element:PARTS @@ -51,6 +53,20 @@ elements and what they do. A List of all the :ref:`parts ` on the Element. ``SET FOO TO SHIP:PARTS.`` has exactly the same effect as ``LIST PARTS IN FOO.``. For more information, see :ref:`ship parts and modules `. +.. attribute:: Element:DOCKINGPORTS + + :type: :struct:`List` of :struct:`DockingPort` objects + :access: Get only + + A List of all the :ref:`docking ports ` on the Element. + +.. attribute:: Element:VESSEL + + :type: :struct:`Vessel` + :access: Get only + + The parent vessel containing the element. + .. attribute:: Element:RESOURCES :type: :struct:`List` of :struct:`AggregateResource` objects diff --git a/doc/source/structures/vessels/engine.rst b/doc/source/structures/vessels/engine.rst index 97d10135f..309a31e60 100644 --- a/doc/source/structures/vessels/engine.rst +++ b/doc/source/structures/vessels/engine.rst @@ -30,47 +30,83 @@ Some of the Parts returned by :ref:`LIST PARTS ` will be of type E - - Turn engine off * - :attr:`THRUSTLIMIT` - - scalar (%) + - :ref:`scalar ` (%) - Tweaked thrust limit * - :attr:`MAXTHRUST` - - scalar (kN) + - :ref:`scalar ` (kN) - Untweaked thrust limit + * - :meth:`MAXTHRUSTAT(pressure)` + - :ref:`scalar ` (kN) + - Max thrust at the specified pressure (in standard Kerbin atmospheres). * - :attr:`THRUST` - - scalar (kN) + - :ref:`scalar ` (kN) - Current thrust + * - :attr:`AVAILABLETHRUST` + - :ref:`scalar ` (kN) + - Available thrust at full throttle accounting for thrust limiter + * - :meth:`AVAILABLETHRUSTAT(pressure)` + - :ref:`scalar ` (kN) + - Available thrust at the specified pressure (in standard Kerbin atmospheres). * - :attr:`FUELFLOW` - - scalar (l/s maybe) + - :ref:`scalar ` (l/s maybe) - Rate of fuel burn * - :attr:`ISP` - - scalar - - `Specific impulse `_ + - :ref:`scalar ` + - `Specific impulse `_ + * - :meth:`ISPAT(pressure)` + - :ref:`scalar ` + - `Specific impulse `_ at the given pressure (in standard Kerbin atmospheres). * - :attr:`VACUUMISP` - - scalar - - `Vacuum Specific impulse `_ + - :ref:`scalar ` + - Vacuum `specific impulse `_ * - :attr:`VISP` - - scalar - - `Synonym for VACUUMISP`_ + - :ref:`scalar ` + - Synonym for VACUUMISP * - :attr:`SEALEVELISP` - - scalar - - `Specific impulse at Kerbin sealevel `_ + - :ref:`scalar ` + - `Specific impulse `_ at Kerbin sealevel * - :attr:`SLISP` - - scalar - - `Synonym for SEALEVELISP`_ + - :ref:`scalar ` + - Synonym for SEALEVELISP * - :attr:`FLAMEOUT` - - boolean + - :ref:`Boolean ` - Check if no more fuel * - :attr:`IGNITION` - - boolean + - :ref:`Boolean ` - Check if engine is active * - :attr:`ALLOWRESTART` - - boolean + - :ref:`Boolean ` - Check if engine can be reactivated * - :attr:`ALLOWSHUTDOWN` - - boolean + - :ref:`Boolean ` - Check if engine can be shutdown * - :attr:`THROTTLELOCK` - - boolean + - :ref:`Boolean ` - Check if throttle can not be changed + * - :attr:`MULTIMODE` + - :ref:`Boolean ` + - Check if engine has multiple modes + * - :attr:`MODES` + - :struct:`List` + - List (string) of the engine modes + * - :attr:`MODE` + - :ref:`string ` + - Name of the current mode (only if multiple) + * - :attr:`TOGGLEMODE` + - + - Switch to another mode (only if multiple) + * - :attr:`PRIMARYMODE` + - :ref:`Boolean ` + - Is the engine in primary mode? (only if multiple) + * - :attr:`AUTOSWITCH` + - :ref:`Boolean ` + - Can the engine switch modes automatically? (only if multiple) + * - :attr:`HASGIMBAL` + - :ref:`Boolean ` + - Check if engine has gimbal + * - :attr:`GIMBAL` + - :struct:`Gimbal` + - Gimbal of this engine (only if available) .. note:: @@ -90,99 +126,204 @@ Some of the Parts returned by :ref:`LIST PARTS ` will be of type E .. attribute:: Engine:THRUSTLIMIT :access: Get/Set - :type: scalar (%) + :type: :ref:`scalar ` (%) - If this an engine with a thrust limiter (tweakable) enabled, what percentage is it limited to? + If this an engine with a thrust limiter (tweakable) enabled, what + percentage is it limited to? Note that this is expressed as a + percentage, not a simple 0..1 coefficient. e.g. To set thrustlimit + to half, you use a value of 50.0, not 0.5. + + This value is not allowed to go outside the range [0..100]. If you + attempt to do so, it will be clamped down into the allowed range. + + Note that although a kerboscript is allowed to set the value to a + very precise number (for example 10.5123), the stock in-game display + widget that pops up when you right-click the engine will automatically + round it to the nearest 0.5 whenever you open the panel. So if you + do something like ``set ship:part[20]:thrustlimit to 10.5123.`` in + your script, then look at the rightclick menu for the engine, the very + act of just looking at the menu will cause it to become 10.5 instead + of 10.5123. There isn't much that kOS can to to change this. It's a + user interface decision baked into the stock game. + +.. _engine_MAXTHRUST: .. attribute:: Engine:MAXTHRUST :access: Get only - :type: scalar (kN) + :type: :ref:`scalar ` (kN) + + How much thrust would this engine give at its current atmospheric pressure and velocity if the throttle was max at 1.0, and the thrust limiter was max at 100%. Note this might not be the engine's actual max thrust it could have under other air pressure conditions. Some engines have a very different value for MAXTHRUST in vacuum as opposed to at sea level pressure. Also, some jet engines have a very different value for MAXTHRUST depending on how fast they are currently being rammed through the air. + +.. _engine_MAXTHRUSTAT: + +.. method:: Engine:MAXTHRUSTAT(pressure) - How much thrust would this engine give if the throttle was max and conditions were ideal. + :parameter pressure: atmospheric pressure (in standard Kerbin atmospheres) + :type: :ref:`scalar ` (kN) + + How much thrust would this engine give if both the throttle and thrust limtier was max at the current velocity, and at the given atmospheric pressure. Use a pressure of 0.0 for vacuum, and 1.0 for sea level (on Kerbin) (or more than 1 for thicker atmospheres like on Eve). .. attribute:: Engine:THRUST :access: Get only - :type: scalar (kN) + :type: :ref:`scalar ` (kN) How much thrust is this engine giving at this very moment. +.. _engine_AVAILABLETHRUST: + +.. attribute:: Engine:AVAILABLETHRUST + + :access: Get only + :type: :ref:`scalar ` (kN) + + Taking into account the thrust limiter tweakable setting, how much thrust would this engine give if the throttle was max at its current thrust limit setting and atmospheric pressure and velocity conditions. + +.. _engine_AVAILABLETHRUSTAT: + +.. method:: Engine:AVAILABLETHRUSTAT(pressure) + + :parameter pressure: atmospheric pressure (in standard Kerbin atmospheres) + :type: :ref:`scalar ` (kN) + + Taking into account the thrust limiter tweakable setting, how much thrust would this engine give if the throttle was max at its current thrust limit setting and velocity, but at a different atmospheric pressure you pass into it. The pressure is measured in ATM's, meaning 0.0 is a vacuum, 1.0 is seal level at Kerbin. + .. attribute:: Engine:FUELFLOW :access: Get only - :type: scalar (Liters/s? maybe) + :type: :ref:`scalar ` (Liters/s? maybe) Rate at which fuel is being burned. Not sure what the units are. .. attribute:: Engine:ISP :access: Get only - :type: scalar + :type: :ref:`scalar ` + + `Specific impulse `_ + +.. method:: Engine:ISPAT(pressure) - `Specific impulse `_ + :parameter pressure: atmospheric pressure (in standard Kerbin atmospheres) + :type: :ref:`scalar ` + + `Specific impulse `_ at the given atmospheric pressure. Use a pressure of 0 for vacuum, and 1 for sea level (on Kerbin). .. attribute:: Engine:VACUUMISP :access: Get only - :type: scalar + :type: :ref:`scalar ` - `Vacuum Specific impulse `_ + Vacuum `specific impulse `_ .. attribute:: Engine:VISP :access: Get only - :type: scalar + :type: :ref:`scalar ` - `Synonym for :VACUUMISP`_ + Synonym for :VACUUMISP .. attribute:: Engine:SEALEVELISP :access: Get only - :type: scalar + :type: :ref:`scalar ` - `Specific impulse at Kerbin sealevel `_ + `Specific impulse `_ at Kerbin sealevel. .. attribute:: Engine:SLISP :access: Get only - :type: scalar + :type: :ref:`scalar ` - `Synonym for :SEALEVELISP`_ + Synonym for :SEALEVELISP .. attribute:: Engine:FLAMEOUT :access: Get only - :type: boolean + :type: :ref:`Boolean ` Is this engine failed because it is starved of a resource (liquidfuel, oxidizer, oxygen)? .. attribute:: Engine:IGNITION :access: Get only - :type: boolean + :type: :ref:`Boolean ` Has this engine been ignited? If both :attr:`Engine:IGNITION` and :attr:`Engine:FLAMEOUT` are true, that means the engine could start up again immediately if more resources were made available to it. .. attribute:: Engine:ALLOWRESTART :access: Get only - :type: boolean + :type: :ref:`Boolean ` Is this an engine that can be started again? Usually True, but false for solid boosters. .. attribute:: Engine:ALLOWSHUTDOWN :access: Get only - :type: boolean + :type: :ref:`Boolean ` Is this an engine that can be shut off once started? Usually True, but false for solid boosters. .. attribute:: Engine:THROTTLELOCK :access: Get only - :type: boolean + :type: :ref:`Boolean ` Is this an engine that is stuck at a fixed throttle? (i.e. solid boosters) +.. attribute:: Engine:MULTIMODE + + :access: Get only + :type: :ref:`Boolean ` + + Does this engine have multiple modes (i.e. RAPIER)? Check this before calling multi-mode specific suffixes. + +.. attribute:: Engine:MODES + + :access: Get only + :type: :struct:`List` of strings + + Lists names of modes of this engine if multimode, returns a list of 1 string "Single mode" otherwise. + +.. attribute:: Engine:MODE + + :access: Get only + :type: :ref:`string ` + + Name of the current mode. Only assessible for multi-mode engines. + +.. method:: Engine:TOGGLEMODE + + Call to switch to another mode. Only assessible for multi-mode engines. + +.. attribute:: Engine:PRIMARYMODE + + :access: Get/Set + :type: :ref:`Boolean ` + + True for primary mode, false for secondary. Setting to other value equals toggling the mode. Only assessible for multi-mode engines. + +.. attribute:: Engine:AUTOSWITCH + + :access: Get/Set + :type: :ref:`Boolean ` + + Is automatic switching enabled? Can set to switch between manual and automatic switching. Only assessible for multi-mode engines. + +.. attribute:: Engine:HASGIMBAL + + :access: Get only + :type: :ref:`Boolean ` + + Does this engine have a gimbal enabled? + +.. attribute:: Engine:GIMBAL + + :access: Get only + :type: :struct:`Gimbal` + + Returns the :struct:`Gimbal` attached to this engine. Only accessible if the gimbal is present (Use :attr:`Engine:HASGIMBAL` to check if available). + .. _isp: http://en.wikipedia.org/wiki/Specific_impulse diff --git a/doc/source/structures/vessels/eta.rst b/doc/source/structures/vessels/eta.rst new file mode 100644 index 000000000..a9ff2285b --- /dev/null +++ b/doc/source/structures/vessels/eta.rst @@ -0,0 +1,61 @@ +.. _eta: + +ETA +=== + +ETA is a special object that exists just to help you get the +times from now to certain events in a vessel's future. It +always presumes you're operating on the current SHIP vessel: + + +.. structure:: ETA + + .. list-table:: + :header-rows: 1 + :widths: 2 1 4 + + * - Suffix + - Type + - Description + + * - :attr:`APOAPSIS` + - :ref:`scalar `, seconds + - Seconds until SHIP hits its apoapsis. + + * - :attr:`PERIAPSIS` + - :ref:`scalar `, seconds + - Seconds until SHIP hits its periapsis. + + * - :attr:`TRANSITION` + - :ref:`scalar `, seconds + - Seconds until SHIP hits the next orbit patch. + +.. attribute:: ETA:APOAPSIS + + :type: :ref:`scalar `, seconds + :access: Get only + + Seconds until SHIP hits its apoapsis. If the ship is on an escape + trajectory (hyperbolic orbit) such that you will never reach apoapsis, + it will return zero. + +.. attribute:: ETA:PERIAPSIS + + :type: :ref:`scalar `, seconds + :access: Get only + + Seconds until SHIP hits its periapsis. If the ship is on an intersect + with the ground, such that you'll hit the ground first before you'd + get to periapsis, it will still return the hypothetical number of + seconds it would have taken to get to periapsis if you had the magical + ability to pass through the ground as if it wasn't there. + +.. attribute:: ETA:TRANSITION + + :type: :ref:`scalar `, seconds + :access: Get only + + Seconds until SHIP hits its the end of its current orbit patch and + transitions into another one, ignoring the effect of any intervening + manuever nodes it might hit before it gets there. + diff --git a/doc/source/structures/vessels/gimbal.rst b/doc/source/structures/vessels/gimbal.rst index b83a83718..517b6b2bd 100644 --- a/doc/source/structures/vessels/gimbal.rst +++ b/doc/source/structures/vessels/gimbal.rst @@ -3,7 +3,7 @@ Gimbal ====== -Many engines in KSP have thrust vectoring gimbals and in ksp they are their own module +Many engines in KSP have thrust vectoring gimbals which are handled by their own module .. structure:: Gimbal @@ -13,72 +13,93 @@ Many engines in KSP have thrust vectoring gimbals and in ksp they are their own :widths: 2 1 4 * - Suffix - - Type + - Type (units) - Description + * - All suffixes of :struct:`PartModule` + - + - + + * - :attr:`LOCK` + - :ref:`Boolean ` + - Is the Gimbal locked in neutral position? + + * - :attr:`LIMIT` + - :ref:`scalar ` (%) + - Percentage of the maximum range the Gimbal is allowed to travel + * - :attr:`RANGE` - - scalar + - :ref:`scalar ` (deg) - The Gimbal's Possible Range of movement * - :attr:`RESPONSESPEED` - - scalar + - :ref:`scalar ` - The Gimbal's Possible Rate of travel * - :attr:`PITCHANGLE` - - scalar + - :ref:`scalar ` - Current Gimbal Pitch * - :attr:`YAWANGLE` - - scalar + - :ref:`scalar ` - Current Gimbal Yaw * - :attr:`ROLLANGLE` - - scalar + - :ref:`scalar ` - Current Gimbal Roll - - * - :attr:`LOCK` - - boolean - - Is the gimbal free to travel? - + + +.. note:: + + :struct:`Gimbal` is a type of :struct:`PartModule`, and therefore can use all the suffixes of :struct:`PartModule`. Shown below are only the suffixes that are unique to :struct:`Gimbal`. + :struct:`Gimbal` can be accessed as :attr:`Engine:GIMBAL` atribute of :struct:`Engine`. + +.. attribute:: Gimbal:LOCK + + :type: :ref:`Boolean ` + :access: Get/Set + + Is this gimbal locked to neutral position and not responding to steering controls right now? When you set it to true it will snap the engine back to 0s for pitch, yaw and roll + +.. attribute:: Gimbal:LIMIT + + :type: :ref:`scalar ` (%) + :access: Get/Set + + Percentage of maximum range this gimbal is allowed to travel + .. attribute:: Gimbal:RANGE - :type: scalar + :type: :ref:`scalar ` (deg) :access: Get only The maximum extent of travel possible for the gimbal along all 3 axis (Pitch, Yaw, Roll) .. attribute:: Gimbal:RESPONSESPEED - :type: scalar + :type: :ref:`scalar ` :access: Get only A Measure of the rate of travel for the gimbal .. attribute:: Gimbal:PITCHANGLE - :type: scalar + :type: :ref:`scalar ` :access: Get only The gimbals current pitch, has a range of -1 to 1. Will always be 0 when LOCK is true .. attribute:: Gimbal:YAWANGLE - :type: scalar + :type: :ref:`scalar ` :access: Get only The gimbals current yaw, has a range of -1 to 1. Will always be 0 when LOCK is true .. attribute:: Gimbal:ROLLANGLE - :type: scalar + :type: :ref:`scalar ` :access: Get only The gimbals current roll, has a range of -1 to 1. Will always be 0 when LOCK is true -.. attribute:: Gimbal:LOCK - - :type: string - :access: Get/Set - - Can this Gimbal produce torque right now, when you set it to false it will snap the engine back to 0s for pitch,yaw and roll - diff --git a/doc/source/structures/vessels/kosprocessor.rst b/doc/source/structures/vessels/kosprocessor.rst new file mode 100644 index 000000000..7d57fff1d --- /dev/null +++ b/doc/source/structures/vessels/kosprocessor.rst @@ -0,0 +1,84 @@ +.. _kosprocessor: + +kOSProcessor +================== + +The type of structures returned by kOS when querying a module that contains a kOS processor. + + +.. structure:: kOSProcessor + + .. list-table:: + :header-rows: 1 + :widths: 2 1 4 + + * - Suffix + - Type + - Description + + * - All suffixes of :struct:`PartModule` + - + - :struct:`kOSProcessor` objects are a type of :struct:`PartModule` + * - :attr:`MODE` + - `:ref:`string `` + - `OFF`, `READY` or `STARVED` + * - :meth:`ACTIVATE` + - None + - Activates this processor + * - :meth:`DEACTIVATE` + - None + - Deactivates this processor + * - :attr:`TAG` + - `:ref:`string `` + - This processor's name tag + * - :attr:`VOLUME` + - :struct:`Volume` + - This processor's hard disk + * - :attr:`BOOTFILENAME` + - `:ref:`string `` + - The filename for the boot file on this processor + +.. note:: + + A :struct:`kOSProcessor` is a type of :struct:`PartModule`, and therefore can use all the suffixes of :struct:`PartModule`. + +.. attribute:: kOSProcessor:MODE + + :access: Get only + :type: `:ref:`string `` + + Indicates the current state of this processor. `OFF` - deactivated, `READY` - active, or `STARVED` - no power. + +.. method:: kOSProcessor:ACTIVATE + + :returns: None + + Activate this processor + +.. method:: kOSProcessor:DEACTIVATE + + :returns: None + + Deactivate this processor + +.. attribute:: kOSProcessor:TAG + + :access: Get only + :type: `:ref:`string `` + + This processor's name tag + +.. attribute:: kOSProcessor:VOLUME + + :access: Get only + :type: :struct:`Volume` + + This processor's hard disk. + +.. attribute:: kOSProcessor:BOOTFILENAME + + :access: Get or Set + :type: `:ref:`string `` + + The filename for the boot file on this processor. This may be set to an empty :ref:`string ` Ҡor to “None†to disable the use of a boot file. + diff --git a/doc/source/structures/vessels/node.rst b/doc/source/structures/vessels/node.rst index 22c88aeea..b765fdc6f 100644 --- a/doc/source/structures/vessels/node.rst +++ b/doc/source/structures/vessels/node.rst @@ -13,6 +13,24 @@ Maneuver Node A planned velocity change along an orbit. These are the nodes that you can set in the KSP user interface. Setting one through kOS will make it appear on the in-game map view, and creating one manually on the in-game map view will cause it to be visible to kOS. +.. warning:: + + Be aware that a limitation of KSP makes it so that some vessels' + manuever node systems cannot be accessed. KSP appears to limit the + maneuver node system to only functioning on the current PLAYER + vessel, under the presumption that its the only vessel that needs + them, as ever other vessel cannot be manuevered. kOS can manuever a + vessel that is not the player vessel, but it cannot overcome this + limitation of the base game that unloads the maneuver node system + for other vessels. + + Be aware that the effect this has is that when you try to use some of + these commands on some vessels, they won't work because those vessels + do not have their manuever node system in play. This is mostly only + going to happen when you try to run a script on a vessel that is not + the current player active vessel. + + Creation -------- @@ -46,12 +64,20 @@ Creation You should immediately see it appear on the map view when you do this. The :global:`ADD` command can add nodes anywhere within the flight plan. To insert a node earlier in the flight than an existing node, simply give it a smaller :attr:`ETA ` time and then :global:`ADD` it. +.. warning:: + + As per the warning above at the top of the section, ADD won't work on vessels that are not the active vessel. + .. global:: REMOVE To remove a maneuver node from the flight path of the cur:rent :ref:`CPU vessel ` (i.e. ``SHIP``), just :global:`REMOVE` it like so:: REMOVE myNode. +.. warning:: + + As per the warning above at the top of the section, REMOVE won't work on vessels that are not the active vessel. + .. global:: NEXTNODE :global:`NEXTNODE` is a built-in variable that always refers to the next upcoming node that has been added to your flight plan:: @@ -62,6 +88,10 @@ Creation Currently, if you attempt to query :global:`NEXTNODE` and there is no node on your flight plan, it produces a run-time error. (This needs to be fixed in a future release so it is possible to query whether or not you have a next node). +.. warning:: + + As per the warning above at the top of the section, NEXTNODE won't work on vessels that are not the active vessel. + If you need to query whether or not you have a :global:`NEXTNODE`, the following has been suggested as a workaround in the meantime: Set a node really far into the future, beyond any reasonable amount of time. Add it to your flight plan. Then check :global:`NEXTNODE` to see if it returns THAT node, or an earlier one. If it returns an earlier one, then that earlier one was there all along and is the real :global:`NEXTNODE`. If it returns the fake far-future node you made instead, then there were no nodes before that point. In either case, remove the far-future node after you perform the test. The special identifier :global:`NEXTNODE` is a euphemism for "whichever node is coming up soonest on my flight path". Therefore you can remove a node even if you no longer have the maneuver node variable around, by doing this:: @@ -117,19 +147,19 @@ Structure - Get only - Alias for :attr:`DELTAV` * - :attr:`ETA` - - scalar (s) + - :ref:`scalar ` (s) - Get/Set - Time until this maneuver * - :attr:`PROGRADE` - - scalar (m/s) + - :ref:`scalar ` (m/s) - Get/Set - Delta-V along prograde * - :attr:`RADIALOUT` - - scalar (m/s) + - :ref:`scalar ` (m/s) - Get/Set - Delta-V along radial to orbited :struct:`Body` * - :attr:`NORMAL` - - scalar (m/s) + - :ref:`scalar ` (m/s) - Get/Set - Delta-V along normal to the :struct:`Vessel`'s :struct:`Orbit` * - :attr:`ORBIT` @@ -152,28 +182,28 @@ Structure .. attribute:: ManeuverNode:ETA :access: Get/Set - :type: scalar + :type: :ref:`scalar ` The number of seconds until the expected burn time. If you SET this, it will actually move the maneuver node along the path in the map view, identically to grabbing the maneuver node and dragging it. .. attribute:: ManeuverNode:PROGRADE :access: Get/Set - :type: scalar + :type: :ref:`scalar ` The delta V in (meters/s) along just the prograde direction (the yellow and green 'knobs' of the maneuver node). A positive value is a prograde burn and a negative value is a retrograde burn. .. attribute:: ManeuverNode:RADIALOUT :access: Get/Set - :type: scalar + :type: :ref:`scalar ` The delta V in (meters/s) along just the radial direction (the cyan knobs' of the maneuver node). A positive value is a radial out burn and a negative value is a radial in burn. .. attribute:: ManeuverNode:NORMAL :access: Get/Set - :type: scalar + :type: :ref:`scalar ` The delta V in (meters/s) along just the normal direction (the purple knobs' of the maneuver node). A positive value is a normal burn and a negative value is an anti-normal burn. diff --git a/doc/source/structures/vessels/part.rst b/doc/source/structures/vessels/part.rst index a48e0c2d8..c67cb369e 100644 --- a/doc/source/structures/vessels/part.rst +++ b/doc/source/structures/vessels/part.rst @@ -16,31 +16,31 @@ These are the generic properties every PART has. You can obtain a list of values - Description * - :attr:`NAME` - - string + - :ref:`string ` - Name of this part * - :attr:`TITLE` - - string + - :ref:`string ` - Title as it appears in KSP * - :attr:`MASS` - - scalar + - :ref:`scalar ` - Current mass of part and its resources * - :attr:`DRYMASS` - - scalar + - :ref:`scalar ` - Mass of part if all resources were empty * - :attr:`WETMASS` - - scalar + - :ref:`scalar ` - Mass of part if all resources were full * - :attr:`TAG` - - string + - :ref:`string ` - Name-tag if assigned by the player * - :attr:`CONTROLFROM` - - boolean - - Set control-from to this part + - Void + - Call to control-from to this part * - :attr:`STAGE` - - scalar + - :ref:`scalar ` - The stage this is associated with * - :attr:`UID` - - string + - :ref:`string ` - Unique identifying number of this part * - :attr:`ROTATION` - :struct:`Direction` @@ -55,7 +55,7 @@ These are the generic properties every PART has. You can obtain a list of values - :struct:`List` - list of the :struct:`Resource` in this part * - :attr:`TARGETABLE` - - boolean + - :ref:`Boolean ` - true if this part can be selected as a target * - :attr:`SHIP` - :struct:`Vessel` @@ -65,7 +65,7 @@ These are the generic properties every PART has. You can obtain a list of values - Get one of the :struct:`PartModules ` by name * - :attr:`MODULES` - :struct:`List` - - Names (string) of all :struct:`PartModules ` + - Names (:ref:`string `) of all :struct:`PartModules ` * - :attr:`ALLMODULES` - :struct:`List` - Same as :attr:`MODULES` @@ -73,10 +73,10 @@ These are the generic properties every PART has. You can obtain a list of values - :struct:`Part` - Adjacent :struct:`Part` on this :struct:`Vessel`. * - :attr:`HASPARENT` - - boolean + - :ref:`Boolean ` - Check if this part has a parent :struct:`Part` * - :attr:`HASPHYSICS` - - boolean + - :ref:`Boolean ` - Does this part have mass or drag * - :attr:`CHILDREN` - :struct:`List` @@ -88,7 +88,7 @@ These are the generic properties every PART has. You can obtain a list of values .. attribute:: Part:NAME :access: Get only - :type: string + :type: :ref:`string ` Name of part as it is used behind the scenes in the game's API code. @@ -97,7 +97,7 @@ These are the generic properties every PART has. You can obtain a list of values .. attribute:: Part:TITLE :access: Get only - :type: string + :type: :ref:`string ` The title of the part as it appears on-screen in the gui. @@ -106,12 +106,14 @@ These are the generic properties every PART has. You can obtain a list of values .. attribute:: Part:TAG :access: Get / Set - :type: string + :type: :ref:`string ` The name tag value that may exist on this part if you have given the part a name via the :ref:`name-tag system `. A part's *tag* is whatever custom name you have given it using the :ref:`name-tag system described here `. This is probably the best naming convention to use because it lets you make up whatever name you like for the part and use it to pick the parts you want to deal with in your script. + WARNING: This suffix is only settable for parts attached to the :ref:`CPU Vessel ` + This example assumes you have a target vessel picked, and that the target vessel is loaded into full-physics range and not "on rails". vessels that are "on rails" do not have their full list of parts entirely populated at the moment:: LIST PARTS FROM TARGET IN tParts. @@ -131,22 +133,28 @@ These are the generic properties every PART has. You can obtain a list of values .. attribute:: Part:CONTROLFROM - :access: Get only - :type: boolean + :access: Callable function only + :type: void + + Call this function to cause the game to do the same thing as when you right-click a part on a vessel and select "control from here" on the menu. It rotates the control orientation so that fore/aft/left/right/up/down now match the orientation of this part. NOTE that this will not work for every type of part. It only works for those parts that KSP itself allows this for (control cores and docking ports). It accepts no arguments, and returns no value. + All vessels must have at least one "control from" + part on them somewhere, which is why there's no mechanism for un-setting + the "control from" setting other than to pick another part and set it + to that part instead. - Set to TRUE to cause the game to do the same thing as when you right-click a part on a vessel and select "control from here" on the menu. It rotates the control orientation so that fore/aft/left/right/up/down now match the orientation of this part. NOTE that this will not work for every type of part. It only works for those parts that KSP itself allows this for (control cores and docking ports). + WARNING: This suffix is only callable for parts attached to the :ref:`CPU Vessel ` .. attribute:: Part:STAGE :access: Get only - :type: scalar + :type: :ref:`scalar ` the stage this part is part of. .. attribute:: Part:UID :access: Get only - :type: string + :type: :ref:`string ` All parts have a unique ID number. Part's uid never changes because it is the same value as stored in persistent.sfs. Although you can compare parts by comparing their uid it is recommended to compare parts directly if possible. @@ -174,21 +182,21 @@ These are the generic properties every PART has. You can obtain a list of values .. attribute:: Part:MASS :access: Get only - :type: scalar + :type: :ref:`scalar ` The current mass or the part and its resources. If the part has no physics this will always be 0. .. attribute:: Part:WETMASS :access: Get only - :type: scalar + :type: :ref:`scalar ` The mass of the part if all of its resources were full. If the part has no physics this will always be 0. .. attribute:: Part:DRYMASS :access: Get only - :type: scalar + :type: :ref:`scalar ` The mass of the part if all of its resources were empty. If the part has no physics this will always be 0. @@ -202,7 +210,7 @@ These are the generic properties every PART has. You can obtain a list of values .. attribute:: Part:TARGETABLE :access: Get only - :type: boolean + :type: :ref:`Boolean ` true if this part can be selected by KSP as a target. @@ -215,7 +223,7 @@ These are the generic properties every PART has. You can obtain a list of values .. method:: Part:GETMODULE(name) - :parameter name: (string) Name of the part module + :parameter name: (:ref:`string `) Name of the part module :returns: :struct:`PartModule` Get one of the :struct:`PartModules ` attached to this part, given the name of the module. (See :attr:`Part:MODULES` for a list of all the names available). @@ -250,7 +258,7 @@ These are the generic properties every PART has. You can obtain a list of values .. attribute:: Part:HASPARENT :access: Get only - :type: boolean + :type: :ref:`Boolean ` When walking the :ref:`tree of parts `, this is true as long as there is a parent part to this part, and is false if this part has no parent (which can only happen on the root part). diff --git a/doc/source/structures/vessels/partmodule.rst b/doc/source/structures/vessels/partmodule.rst index d1010394d..a71e3c900 100644 --- a/doc/source/structures/vessels/partmodule.rst +++ b/doc/source/structures/vessels/partmodule.rst @@ -29,12 +29,21 @@ Once you have a :struct:`PartModule`, you can use it to invoke the behaviors tha * - :attr:`ALLFIELDS` - :struct:`List` of strings - Accessible fields + * - :attr:`ALLFIELDNAMES` + - :struct:`List` of strings + - Accessible fields (name only) * - :attr:`ALLEVENTS` - :struct:`List` of strings - Triggerable events + * - :attr:`ALLEVENTNAMES` + - :struct:`List` of strings + - Triggerable event names * - :attr:`ALLACTIONS` - :struct:`List` of strings - Triggerable actions + * - :attr:`ALLACTIONNAMES` + - :struct:`List` of strings + - Triggerable event names * - :meth:`GETFIELD(name)` - - Get value of a field by name @@ -48,13 +57,13 @@ Once you have a :struct:`PartModule`, you can use it to invoke the behaviors tha - - Activate action by name with True or False * - :meth:`HASFIELD(name)` - - boolean + - :ref:`Boolean ` - Check if field exists * - :meth:`HASEVENT(name)` - - boolean + - :ref:`Boolean ` - Check if event exists * - :meth:`HASACTION(name)` - - boolean + - :ref:`Boolean ` - Check if action exists @@ -81,6 +90,13 @@ Once you have a :struct:`PartModule`, you can use it to invoke the behaviors tha Get a list of all the names of KSPFields on this PartModule that the kos script is CURRENTLY allowed to get or set with :GETFIELD or :SETFIELD. Note the Security access comments below. This list can become obsolete as the game continues running depending on what the PartModule chooses to do. +.. attribute:: PartModule:ALLFIELDNAMES + + :access: Get only + :test: :struct:`List` of strings + + Similar to :ALLFIELDS except that it returns the string without the formatting to make it easier to use in a script. This list can become obsolete as the game continues running depending on what the PartModule chooses to do. + .. attribute:: PartModule:ALLEVENTS :access: Get only @@ -88,6 +104,13 @@ Once you have a :struct:`PartModule`, you can use it to invoke the behaviors tha Get a list of all the names of KSPEvents on this PartModule that the kos script is CURRENTLY allowed to trigger with :DOEVENT. Note the Security access comments below. This list can become obsolete as the game continues running depending on what the PartModule chooses to do. +.. attribute:: PartModule:ALLEVENTNAMES + + :access: Get only + :test: :struct:`List` of strings + + Similar to :ALLEVENTS except that it returns the string without the formatting to make it easier to use in a script. This list can become obsolete as the game continues running depending on what the PartModule chooses to do. + .. attribute:: PartModule:ALLACTIONS :access: Get only @@ -95,6 +118,13 @@ Once you have a :struct:`PartModule`, you can use it to invoke the behaviors tha Get a list of all the names of KSPActions on this PartModule that the kos script is CURRENTLY allowed to trigger with :DOACTION. Note the Security access comments below. +.. attribute:: PartModule:ALLACTIONNAMES + + :access: Get only + :test: :struct:`List` of strings + + Similar to :ALLACTIONS except that it returns the string without the formatting to make it easier to use in a script. This list can become obsolete as the game continues running depending on what the PartModule chooses to do. + .. method:: PartModule:GETFIELD(name) :parameter name: (string) Name of the field @@ -108,37 +138,43 @@ Once you have a :struct:`PartModule`, you can use it to invoke the behaviors tha Set the value of one of the fields that this PartModule has placed onto the rightclick menu for the part. Note the Security comments below. + WARNING: This suffix is only settable for parts attached to the :ref:`CPU Vessel ` + .. method:: PartModule:DOEVENT(name) :parameter name: (string) Name of the event Trigger an "event button" that is on the rightclick part menu at the moment. Note the Security comments below. + WARNING: This suffix is only callable for parts attached to the :ref:`CPU Vessel ` + .. method:: PartModule:DOACTION(name,bool) :parameter name: (string) Name of the action - :parameter bool: (boolean) Value to set: True or False + :parameter bool: (:ref:`Boolean `) Value to set: True or False + + Activate one of this PartModule's action-group-able actions, bypassing the action group system entirely by just activating it for this one part directly. The :ref:`Boolean ` value decides whether you are toggling the action ON or toggling it OFF. Note the Security comments below. - Activate one of this PartModule's action-group-able actions, bypassing the action group system entirely by just activating it for this one part directly. The boolean value decides whether you are toggling the action ON or toggling it OFF. Note the Security comments below. + WARNING: This suffix is only callable for parts attached to the :ref:`CPU Vessel ` .. method:: PartModule:HASFIELD(name) :parameter name: (string) Name of the field - :return: boolean + :return: :ref:`Boolean ` Return true if the given field name is currently available for use with :GETFIELD or :SETFIELD on this PartModule, false otherwise. .. method:: PartModule:HASEVENT(name) :parameter name: (string) Name of the event - :return: boolean + :return: :ref:`Boolean ` Return true if the given event name is currently available for use with :DOEVENT on this PartModule, false otherwise. .. method:: PartModule:HASACTION(name) :parameter name: (string) Name of the action - :return: boolean + :return: :ref:`Boolean ` Return true if the given action name is currently available for use with :DOACTION on this PartModule, false otherwise. diff --git a/doc/source/structures/vessels/resource.rst b/doc/source/structures/vessels/resource.rst index f05f1fe78..d07bd2a51 100644 --- a/doc/source/structures/vessels/resource.rst +++ b/doc/source/structures/vessels/resource.rst @@ -16,40 +16,53 @@ A single resource value a thing holds (i.e. fuel, electric charge, etc). This is - Description * - :attr:`NAME` - - string + - :ref:`string ` - Resource name * - :attr:`AMOUNT` - - scalar + - :ref:`scalar ` - Amount of this resource left + * - :attr:`DENSITY` + - :ref:`scalar ` + - Density of this resource * - :attr:`CAPACITY` - - scalar + - :ref:`scalar ` - Maximum amount of this resource * - :attr:`TOGGLEABLE` - - boolean + - :ref:`Boolean ` - Can this tank be removed from the fuel flow * - :attr:`ENABLED` - - boolean + - :ref:`Boolean ` - Is this tank currently in the fuel flow .. attribute:: Resource:NAME :access: Get only - :type: string + :type: :ref:`string ` The name of the resource, i.e. "LIQUIDFUEL", "ELECTRICCHARGE", "MONOPROP". .. attribute:: Resource:AMOUNT :access: Get only - :type: scalar + :type: :ref:`scalar ` The value of how much resource is left. +.. attribute:: Resource:DENSITY + + :access: Get only + :type: :ref:`scalar ` + + The density value of this resource, expressed in Megagrams f mass + per Unit of resource. (i.e. a value of 0.005 would mean that each + unit of this resource is 5 kilograms. Megagrams [metric tonnes] is + the usual unit that most mass in the game is represented in.) + .. attribute:: Resource:CAPACITY :access: Get only - :type: scalar + :type: :ref:`scalar ` What AMOUNT would be if the resource was filled to the top. @@ -57,13 +70,13 @@ A single resource value a thing holds (i.e. fuel, electric charge, etc). This is .. attribute:: Resource:TOGGLEABLE :access: Get only - :type: boolean + :type: :ref:`Boolean ` Many, but not all, resources can be turned on and off, this removes them from the fuel flow. .. attribute:: Resource:ENABLED :access: Get/Set - :type: boolean + :type: :ref:`Boolean ` If the resource is TOGGLEABLE, setting this to false will prevent the resource from being taken out normally. diff --git a/doc/source/structures/vessels/sciencedatavalue.rst b/doc/source/structures/vessels/sciencedatavalue.rst new file mode 100644 index 000000000..7c1bd588e --- /dev/null +++ b/doc/source/structures/vessels/sciencedatavalue.rst @@ -0,0 +1,57 @@ +.. _sciencedata: + +ScienceData +=========== + +Represents results of a :struct:`science experiment `. + +.. structure:: ScienceData + + .. list-table:: + :header-rows: 1 + :widths: 2 1 4 + + * - Suffix + - Type + - Description + + * - :attr:`TITLE` + - string + - Experiment title + * - :attr:`SCIENCEVALUE` + - scalar + - Amount of science that would be gained by returning this data to KSC + * - :attr:`TRANSMITVALUE` + - scalar + - Amount of science that would be gained by transmitting this data to KSC + * - :attr:`DATAAMOUNT` + - scalar + - Amount of data + +.. attribute:: ScienceData:TITLE + + :access: Get only + :type: string + + Experiment title + +.. attribute:: ScienceData:SCIENCEVALUE + + :access: Get only + :type: scalar + + Amount of science that would be gained by returning this data to KSC + +.. attribute:: ScienceData:TRANSMITVALUE + + :access: Get only + :type: scalar + + Amount of science that would be gained by transmitting this data to KSC + +.. attribute:: ScienceData:DATAAMOUNT + + :access: Get only + :type: scalar + + Amount of data diff --git a/doc/source/structures/vessels/scienceexperiment.rst b/doc/source/structures/vessels/scienceexperiment.rst new file mode 100644 index 000000000..7325e530b --- /dev/null +++ b/doc/source/structures/vessels/scienceexperiment.rst @@ -0,0 +1,132 @@ +.. _scienceexperimentmodule: + +ScienceExperimentModule +======================= + +The type of structures returned by kOS when querying a module that contains a science experiment. + +Some of the science-related tasks are normally not available to kOS scripts. It is for +example possible to deploy a science experiment:: + + SET P TO SHIP:PARTSNAMED("GooExperiment")[1]. + SET M TO P:GETMODULE("ModuleScienceExperiment"). + M:DOEVENT("observe mystery goo"). + +Hovewer, this results in a dialog being shown to the user. Only from that dialog it is possible +to reset the experiment or transmit the experiment results back to Kerbin. +:struct:`ScienceExperimentModule` structure introduces a few suffixes that allow the player +to perform all science-related tasks without any manual intervention:: + + SET P TO SHIP:PARTSNAMED("GooExperiment")[0]. + SET M TO P:GETMODULE("ModuleScienceExperiment"). + M:DEPLOY. + WAIT UNTIL M:HASDATA. + M:TRANSMIT. + +Please note the use of :code:`WAIT UNTIL M:HASDATA`. + +This structure should work well with stock science experiments. Mods that introduce their own +science parts might not be compatible with it. One notable example is SCANsat. Even though +SCANsat parts look and behave very similarly to stock science experiments under the hood +they work very differently. Other mods can cause problems as well, please test them before use. + +:ref:`DMagic Orbital Science ` has dedicated support in kOS and should work +properly. + +.. structure:: ScienceExperimentModule + + .. list-table:: + :header-rows: 1 + :widths: 2 1 4 + + * - Suffix + - Type + - Description + + * - All suffixes of :struct:`PartModule` + - + - :struct:`ScienceExperimentModule` objects are a type of :struct:`PartModule` + * - :meth:`DEPLOY()` + - + - Deploy and run the science experiment + * - :meth:`RESET()` + - + - Reset this experiment if possible + * - :meth:`TRANSMIT()` + - + - Transmit the scientific data back to Kerbin + * - :meth:`DUMP()` + - + - Discard the data + * - :attr:`INOPERABLE` + - :ref:`Boolean ` + - Is this experiment inoperable + * - :attr:`RERUNNABLE` + - :ref:`Boolean ` + - Can this experiment be run multiple times + * - :attr:`DEPLOYED` + - :ref:`Boolean ` + - Is this experiment deployed + * - :attr:`HASDATA` + - :ref:`Boolean ` + - Does the experiment have scientific data + * - :attr:`DATA` + - :struct:`List` of :struct:`ScienceData` + - List of scientific data obtained by this experiment + +.. note:: + + A :struct:`ScienceExperimentModule` is a type of :struct:`PartModule`, and therefore can use all the suffixes of :struct:`PartModule`. + +.. method:: ScienceExperimentModule:DEPLOY() + + Call this method to deploy and run this science experiment. This method will fail if the experiment already contains scientific + data or is inoperable. + +.. method:: ScienceExperimentModule:RESET() + + Call this method to reset this experiment. This method will fail if the experiment is inoperable. + +.. method:: ScienceExperimentModule:TRANSMIT() + + Call this method to transmit the results of the experiment back to Kerbin. This will render the experiment + inoperable if it is not rerunnable. This method will fail if there is no data to send. + +.. method:: ScienceExperimentModule:DUMP() + + Call this method to discard the data obtained as a result of running this experiment. + +.. attribute:: ScienceExperimentModule:INOPERABLE + + :access: Get only + :type: :ref:`Boolean ` + + True if this experiment is no longer operable. + +.. attribute:: ScienceExperimentModule:RERUNNABLE + + :access: Get only + :type: :ref:`Boolean ` + + True if this experiment can be run multiple times. + +.. attribute:: ScienceExperimentModule:DEPLOYED + + :access: Get only + :type: :ref:`Boolean ` + + True if this experiment is deployed. + +.. attribute:: ScienceExperimentModule:HASDATA + + :access: Get only + :type: :ref:`Boolean ` + + True if this experiment has scientific data stored. + +.. attribute:: ScienceExperimentModule:DATA + + :access: Get only + :type: :struct:`List` of :struct:`ScienceData` + + List of scientific data obtained by this experiment diff --git a/doc/source/structures/vessels/sensor.rst b/doc/source/structures/vessels/sensor.rst index 4a96b45e0..e57e59fe6 100644 --- a/doc/source/structures/vessels/sensor.rst +++ b/doc/source/structures/vessels/sensor.rst @@ -34,7 +34,7 @@ The type of structures returned by :ref:`LIST SENSORS IN SOMEVARIABLE ` - Check if this sensor is active * - :attr:`TYPE` - @@ -43,7 +43,7 @@ The type of structures returned by :ref:`LIST SENSORS IN SOMEVARIABLE ` - Rate of required electric charge * - :meth:`TOGGLE()` - @@ -56,7 +56,7 @@ The type of structures returned by :ref:`LIST SENSORS IN SOMEVARIABLE ` True of the sensor is enabled. Can SET to cause the sensor to activate or de-activate. @@ -74,7 +74,7 @@ The type of structures returned by :ref:`LIST SENSORS IN SOMEVARIABLE ` The rate at which this sensor drains ElectricCharge. diff --git a/doc/source/structures/vessels/stage.rst b/doc/source/structures/vessels/stage.rst index 6e080b31c..946c89765 100644 --- a/doc/source/structures/vessels/stage.rst +++ b/doc/source/structures/vessels/stage.rst @@ -56,29 +56,33 @@ Structure - Description * - :attr:`READY` - - bool + - :ref:`Boolean ` - Get only - Is the craft ready to activate the next stage. * - :attr:`NUMBER` - - scalar + - :ref:`scalar ` - Get only - The current stage number for the craft * - :attr:`RESOURCES` - :struct:`List` - Get only - the :struct:`List` of :struct:`Resource` in the current stage + * - :attr:`RESOURCESLEX` + - :struct:`Lexicon` + - Get only + - the :struct:`Lexicon` of name :struct:`String` keyed :struct:`Resource` values in the current stage .. attribute:: Stage:READY :access: Get only - :type: bool + :type: :ref:`Boolean ` Kerbal Space Program enforces a small delay between staging commands, this is to allow the last staging command to complete. This bool value will let you know if kOS can activate the next stage. .. attribute:: Stage:NUMBER :access: Get only - :type: scalar + :type: :ref:`scalar ` Every craft has a current stage, and that stage is represented by a number, this is it! @@ -88,4 +92,14 @@ Structure :type: :struct:`List` This is a collection of the available :struct:`Resource` for the current stage. - \ No newline at end of file + +.. attribute:: Stage:Resourceslex + + :access: Get + :type: :struct:`Lexicon` + + This is a dictionary style collection of the available :struct:`Resource` + for the current stage. The :struct:`String` key in the lexicon will match + the name suffix on the :struct:`Resource`. This suffix walks the parts + list entirely on every call, so it is recommended that you cache the value + if it will be reference repeatedly. diff --git a/doc/source/structures/vessels/vessel.rst b/doc/source/structures/vessels/vessel.rst index 49b1243ee..39ac6af54 100644 --- a/doc/source/structures/vessels/vessel.rst +++ b/doc/source/structures/vessels/vessel.rst @@ -26,46 +26,60 @@ All vessels share a structure. To get a variable referring to any vessel you can .. structure:: Vessel - ===================================== ========================= ============= - Suffix Type Description - ===================================== ========================= ============= - Every suffix of :struct:`Orbitable` - ----------------------------------------------------------------------------- - :attr:`CONTROL` :struct:`Control` Raw flight controls - :attr:`BEARING` scalar (deg) relative heading to this vessel - :attr:`HEADING` scalar (deg) Absolute heading to this vessel - :attr:`MAXTHRUST` scalar Sum of active maximum thrusts - :attr:`AVAILABLETHRUST` scalar Sum of active limited maximum thrusts - :attr:`FACING` :struct:`Direction` The way the vessel is pointed - :attr:`MASS` scalar (metric tons) Mass of the ship - :attr:`WETMASS` scalar (metric tons) Mass of the ship fully fuelled - :attr:`DRYMASS` scalar (metric tons) Mass of the ship with no resources - :attr:`VERTICALSPEED` scalar (m/s) How fast the ship is moving "up" - :attr:`SURFACESPEED` scalar (m/s) How fast the ship is moving "horizontally" - :attr:`AIRSPEED` scalar (m/s) How fast the ship is moving relative to the air - :attr:`TERMVELOCITY` scalar (m/s) terminal velocity of the vessel - :attr:`SHIPNAME` string The name of the vessel - :attr:`NAME` string Synomym for SHIPNAME - :attr:`STATUS` string Current ship status - :attr:`TYPE` string Ship type - :attr:`ANGULARMOMENTUM` :struct:`Vector` In :ref:`SHIP_RAW ` - :attr:`ANGULARVEL` :struct:`Vector` In :ref:`SHIP_RAW ` - :attr:`SENSORS` :struct:`VesselSensors` Sensor data - :attr:`LOADED` Boolean loaded into KSP physics engine or "on rails" - :attr:`ISDEAD` Boolean True if the vessel refers to a ship that has gone away. - :attr:`PATCHES` :struct:`List` :struct:`Orbit` patches - :attr:`ROOTPART` :struct:`Part` Root :struct:`Part` of this vessel - :attr:`PARTS` :struct:`List` all :struct:`Parts ` - :attr:`RESOURCES` :struct:`List` all :struct:`AggrgateResources ` - :meth:`PARTSNAMED(name)` :struct:`List` :struct:`Parts ` by :attr:`NAME ` - :meth:`PARTSTITLED(title)` :struct:`List` :struct:`Parts ` by :attr:`TITLE ` - :meth:`PARTSTAGGED(tag)` :struct:`List` :struct:`Parts ` by :attr:`TAG ` - :meth:`PARTSDUBBED(name)` :struct:`List` :struct:`Parts ` by :attr:`NAME `, :attr:`TITLE ` or :attr:`TAG ` - :meth:`MODULESNAMED(name)` :struct:`List` :struct:`PartModules ` by :attr:`NAME ` - :meth:`PARTSINGROUP(group)` :struct:`List` :struct:`Parts ` by action group - :meth:`MODULESINGROUP(group)` :struct:`List` :struct:`PartModules ` by action group - :meth:`ALLPARTSTAGGED()` :struct:`List` :struct:`Parts ` that have non-blank nametags - ===================================== ========================= ============= + ===================================== =============================== ============= + Suffix Type Description + ===================================== =============================== ============= + Every suffix of :struct:`Orbitable` + ----------------------------------------------------------------------------------- + :attr:`CONTROL` :struct:`Control` Raw flight controls + :attr:`BEARING` :struct:`scalar` (deg) relative heading to this vessel + :attr:`HEADING` :struct:`scalar` (deg) Absolute heading to this vessel + :attr:`MAXTHRUST` :struct:`scalar` Sum of active maximum thrusts + :meth:`MAXTHRUSTAT(pressure)` :struct:`scalar` Sum of active maximum thrusts at the given atmospheric pressure + :attr:`AVAILABLETHRUST` :struct:`scalar` Sum of active limited maximum thrusts + :meth:`AVAILABLETHRUSTAT(pressure)` :struct:`scalar` Sum of active limited maximum thrusts at the given atmospheric pressure + :attr:`FACING` :struct:`Direction` The way the vessel is pointed + :attr:`MASS` :struct:`scalar` (metric tons) Mass of the ship + :attr:`WETMASS` :struct:`scalar` (metric tons) Mass of the ship fully fuelled + :attr:`DRYMASS` :struct:`scalar` (metric tons) Mass of the ship with no resources + :attr:`DYNAMICPRESSURE` :struct:`scalar` (ATM's) Air Pressure surrounding the vessel + :attr:`Q` :struct:`scalar` (ATM's) Alias name for DYNAMICPRESSURE + :attr:`VERTICALSPEED` :struct:`scalar` (m/s) How fast the ship is moving "up" + :attr:`GROUNDSPEED` :struct:`scalar` (m/s) How fast the ship is moving "horizontally" + :attr:`AIRSPEED` :struct:`scalar` (m/s) How fast the ship is moving relative to the air + :attr:`TERMVELOCITY` :struct:`scalar` (m/s) terminal velocity of the vessel + :attr:`SHIPNAME` :struct:`string` The name of the vessel + :attr:`NAME` :struct:`string` Synonym for SHIPNAME + :attr:`STATUS` :struct:`string` Current ship status + :attr:`TYPE` :struct:`string` Ship type + :attr:`ANGULARMOMENTUM` :struct:`Vector` In :ref:`SHIP_RAW ` + :attr:`ANGULARVEL` :struct:`Vector` In :ref:`SHIP_RAW ` + :attr:`SENSORS` :struct:`VesselSensors` Sensor data + :attr:`LOADED` :struct:`Boolean` loaded into KSP physics engine or "on rails" + :attr:`UNPACKED` :struct:`Boolean` The ship has individual parts unpacked + :attr:`LOADDISTANCE` :struct:`LoadDistance` the :struct:`LoadDistance` object for this vessel + :attr:`ISDEAD` :struct:`Boolean` True if the vessel refers to a ship that has gone away. + :attr:`PATCHES` :struct:`List` :struct:`Orbit` patches + :attr:`ROOTPART` :struct:`Part` Root :struct:`Part` of this vessel + :attr:`PARTS` :struct:`List` all :struct:`Parts ` + :attr:`DOCKINGPORTS` :struct:`List` all :struct:`DockingPorts ` + :attr:`ELEMENTS` :struct:`List` all :struct:`Elements ` + :attr:`RESOURCES` :struct:`List` all :struct:`AggrgateResources ` + :meth:`PARTSNAMED(name)` :struct:`List` :struct:`Parts ` by :attr:`NAME ` + :meth:`PARTSTITLED(title)` :struct:`List` :struct:`Parts ` by :attr:`TITLE ` + :meth:`PARTSTAGGED(tag)` :struct:`List` :struct:`Parts ` by :attr:`TAG ` + :meth:`PARTSDUBBED(name)` :struct:`List` :struct:`Parts ` by :attr:`NAME `, :attr:`TITLE ` or :attr:`TAG ` + :meth:`MODULESNAMED(name)` :struct:`List` :struct:`PartModules ` by :attr:`NAME ` + :meth:`PARTSINGROUP(group)` :struct:`List` :struct:`Parts ` by action group + :meth:`MODULESINGROUP(group)` :struct:`List` :struct:`PartModules ` by action group + :meth:`ALLPARTSTAGGED()` :struct:`List` :struct:`Parts ` that have non-blank nametags + :attr:`CREWCAPACITY` :struct:`scalar` Crew capacity of this vessel + :meth:`CREW()` :struct:`List` all :struct:`CrewMembers ` + ===================================== =============================== ============= + +.. note:: + + This type is serializable. .. attribute:: Vessel:CONTROL @@ -74,33 +88,49 @@ All vessels share a structure. To get a variable referring to any vessel you can The structure representing the raw flight controls for the vessel. + WARNING: This suffix is only gettable for :ref:`CPU Vessel ` + .. attribute:: Vessel:BEARING - :type: scalar + :type: :ref:`scalar ` :access: Get only *relative* compass heading (degrees) to this vessel from the :ref:`CPU Vessel `, taking into account the CPU Vessel's own heading. .. attribute:: Vessel:HEADING - :type: scalar + :type: :ref:`scalar ` :access: Get only *absolute* compass heading (degrees) to this vessel from the :ref:`CPU Vessel ` .. attribute:: Vessel:MAXTHRUST - :type: scalar + :type: :ref:`scalar ` :access: Get only - Sum of all the Max thrust of all the currently active engines In Kilonewtons. - -.. attribute:: vessel:AVAILABLETHRUST + Sum of all the :ref:`engines' MAXTHRUSTs ` of all the currently active engines In Kilonewtons. + +.. method:: Vessel:MAXTHRUSTAT(pressure) + + :parameter pressure: atmospheric pressure (in standard Kerbin atmospheres) + :type: :ref:`scalar ` (kN) + + Sum of all the :ref:`engines' MAXTHRUSTATs ` of all the currently active engines In Kilonewtons at the given atmospheric pressure. Use a pressure of 0 for vacuum, and 1 for sea level (on Kerbin). - :type: scalar +.. attribute:: Vessel:AVAILABLETHRUST + + :type: :ref:`scalar ` :access: Get only - - Sum of all the Max thrust of all the currently active engines taking into acount their throttlelimits. Result is in Kilonewtons. + + Sum of all the :ref:`engines' AVAILABLETHRUSTs ` of all the currently active engines taking into account their throttlelimits. Result is in Kilonewtons. + +.. method:: Vessel:AVAILABLETHRUSTAT(pressure) + + :parameter pressure: atmospheric pressure (in standard Kerbin atmospheres) + :type: :ref:`scalar ` (kN) + + Sum of all the :ref:`engines' AVAILABLETHRUSTATs ` of all the currently active engines taking into account their throttlelimits at the given atmospheric pressure. Result is in Kilonewtons. Use a pressure of 0 for vacuum, and 1 for sea level (on Kerbin). .. attribute:: Vessel:FACING @@ -111,56 +141,86 @@ All vessels share a structure. To get a variable referring to any vessel you can .. attribute:: Vessel:MASS - :type: scalar (metric tons) + :type: :ref:`scalar ` (metric tons) :access: Get only The mass of the ship .. attribute:: Vessel:WETMASS - :type: scalar (metric tons) + :type: :ref:`scalar ` (metric tons) :access: Get only The mass of the ship if all resources were full .. attribute:: Vessel:DRYMASS - :type: scalar (metric tons) + :type: :ref:`scalar ` (metric tons) :access: Get only The mass of the ship if all resources were empty +.. attribute:: Vessel:DYNAMICPRESSURE + + :type: :ref:`scalar ` (ATM's) + :access: Get only + + Returns what the air pressure is in the atmosphere surrounding the vessel. + The value is returned in units of sea-level Kerbin atmospheres. Many + formulae expect you to plug in a value expressed in kiloPascals, or + kPA. You can convert this value into kPa by multiplying it by + `constant:ATMtokPa`. + +.. attribute:: Vessel:Q + + :type: :ref:`scalar ` (ATM's) + :access: Get only + + Alias for DYNAMICPRESSURE + .. attribute:: Vessel:VERTICALSPEED - :type: scalar (m/s) + :type: :ref:`scalar ` (m/s) :access: Get only How fast the ship is moving. in the "up" direction relative to the SOI Body's sea level surface. -.. attribute:: Vessel:SURFACESPEED +.. attribute:: Vessel:GROUNDSPEED - :type: scalar (m/s) + :type: :ref:`scalar ` (m/s) :access: Get only - How fast the ship is moving in the plane horizontal to the SOI body's sea level surface. + How fast the ship is moving in the two dimensional plane horizontal + to the SOI body's sea level surface. The vertical component of the + ship's velocity is ignored when calculating this. + + .. note:: + + .. versionadded:: 0.18 + + The old name for this value was SURFACESPEED. The name was changed + because it was confusing before. "surface speed" implied it's the + :ref:`scalar ` magnitude of "surface velocity", but it wasn't, because of how + it ignores the vertical component. + .. attribute:: Vessel:AIRSPEED - :type: scalar (m/s) + :type: :ref:`scalar ` (m/s) :access: Get only How fast the ship is moving relative to the air. KSP models atmosphere as simply a solid block of air "glued" to the planet surface (the weather on Kerbin is boring and there's no wind). Therefore airspeed is generally the same thing as as the magnitude of the surface velocity. .. attribute:: Vessel:TERMVELOCITY - :type: scalar (m/s) + :type: :ref:`scalar ` (m/s) :access: Get only terminal velocity of the vessel in freefall through atmosphere, based on the vessel's current altitude above sea level, and its drag properties. Warning, can cause values of Infinity if used in a vacuum, and kOS sometimes does not let you store Infinity in a variable. .. attribute:: Vessel:SHIPNAME - :type: string + :type: :ref:`string ` :access: Get/Set The name of the vessel as it appears in the tracking station. When you set this, it cannot be empty. @@ -171,14 +231,14 @@ All vessels share a structure. To get a variable referring to any vessel you can .. attribute:: Vessel:STATUS - :type: string + :type: :ref:`string ` :access: get only - + The current status of the vessel possible results are: `LANDED`, `SPLASHED`, `PRELAUNCH`, `FLYING`, `SUB_ORBITAL`, `ORBITING`, `ESCAPING` and `DOCKED`. - + .. attribute:: Vessel:TYPE - :type: string + :type: :ref:`string ` :access: Get/Set The ship's type as described `on the KSP wiki `_. @@ -188,8 +248,29 @@ All vessels share a structure. To get a variable referring to any vessel you can :type: :struct:`Direction` :access: Get only - Given in :ref:`SHIP_RAW ` reference frame. The vector represents the axis of the rotation, and its magnitude is the angular momentum of the rotation, which varies not only with the speed of the rotation, but also with the angular inertia of the vessel. - + Given in :ref:`SHIP_RAW ` reference frame. The vector + represents the axis of the rotation (in left-handed convention, + not right handed as most physics textbooks show it), and its + magnitude is the angular momentum of the rotation, which varies + not only with the speed of the rotation, but also with the angular + inertia of the vessel. + + Units are expressed in: (Megagrams * meters^2) / (seconds * radians) + + (Normal SI units would use kilograms, but in KSP all masses use a + 1000x scaling factor.) + + **Justification for radians here:** + Unlike the trigonometry functions in kOS, this value uses radians + rather than degrees. The convention of always expressing angular + momentum using a formula that assumes you're using radians is a very + strongly adhered to universal convention, for... reasons. + It's so common that it's often not even explicitly + mentioned in information you may find when doing a web search on + helpful formulae about angular momentum. This is why kOS doesn't + use degrees here. (That an backward compatibility for old scripts. + It's been like this for quite a while.). + .. note:: .. versionchanged:: 0.15.4 @@ -198,16 +279,23 @@ All vessels share a structure. To get a variable referring to any vessel you can .. attribute:: Vessel:ANGULARVEL - :type: :struct:`Direction` - :access: Get only - - Given in :ref:`SHIP_RAW ` reference frame. The vector represents the axis of the rotation, and its magnitude is the speed of that rotation (Presumably in degrees per second? This is not documented in the KSP API and may take some experimentation to discover if it's radians or degrees). + Angular velocity of the body's rotation about its axis (its + day) expressed as a vector. - .. note:: + The direction the angular velocity points is in Ship-Raw orientation, + and represents the axis of rotation. Remember that everything in + Kerbal Space Program uses a *left-handed coordinate system*, which + affects which way the angular velocity vector will point. If you + curl the fingers of your **left** hand in the direction of the rotation, + and stick out your thumb, the thumb's direction is the way the + angular velocity vector will point. - .. versionchanged:: 0.15.4 + The magnitude of the vector is the speed of the rotation. - This has been changed to a vector, as it should have been all along. + Note, unlike many of the other parts of kOS, the rotation speed is + expressed in radians rather than degrees. This is to make it + congruent with how VESSEL:ANGULARMOMENTUM is expressed, and for + backward compatibility with older kOS scripts. .. attribute:: Vessel:SENSORS @@ -218,14 +306,32 @@ All vessels share a structure. To get a variable referring to any vessel you can .. attribute:: Vessel:LOADED - :type: Boolean + :type: :ref:`Boolean ` + :access: Get only + + True if the vessel is fully loaded into the complete KSP physics engine (false if it's "on rails"). + See :struct:`LoadDistance` for details. + +.. attribute:: Vessel:UNPACKED + + :type: :ref:`Boolean ` + :access: Get only + + True if the vessel is fully unpacked. That is to say that all of the individual parts are loaded + and can be interacted with. This allows docking ports to be targeted, and controls if some + actions/events on parts will actually trigger. See :struct:`LoadDistance` for details. + + +.. attribute:: Vessel:LOADDISTANCE + + :type: :struct:`LoadDistance` :access: Get only - true if the vessel is fully loaded into the complete KSP physics engine (false if it's "on rails"). + Returns the load distance object for this vessel. The suffixes of this object may be adjusted to change the loading behavior of this vessel. Note: these settings are not persistent across flight instances, and will reset the next time you launch a craft from an editor or the tracking station. .. attribute:: Vessel:ISDEAD - :type: Boolean + :type: :ref:`Boolean ` :access: Get only It is possible to have a variable that refers to a vessel that @@ -257,6 +363,20 @@ All vessels share a structure. To get a variable referring to any vessel you can A List of all the :ref:`parts ` on the vessel. ``SET FOO TO SHIP:PARTS.`` has exactly the same effect as ``LIST PARTS IN FOO.``. For more information, see :ref:`ship parts and modules `. +.. attribute:: Vessel:DOCKINGPORTS + + :type: :struct:`List` of :struct:`DockingPort` objects + :access: Get only + + A List of all the :ref:`docking ports ` on the Vessel. + +.. attribute:: Vessel:ELEMENTS + + :type: :struct:`List` of :struct:`Element` objects + :access: Get only + + A List of all the :ref:`elements ` on the Vessel. + .. attribute:: Vessel:RESOURCES :type: :struct:`List` of :struct:`AggregateResource` objects @@ -267,35 +387,35 @@ All vessels share a structure. To get a variable referring to any vessel you can .. method:: Vessel:PARTSNAMED(name) - :parameter name: (string) Name of the parts + :parameter name: (:ref:`string `) Name of the parts :return: :struct:`List` of :struct:`Part` objects Part:NAME. The matching is done case-insensitively. For more information, see :ref:`ship parts and modules `. .. method:: Vessel:PARTSTITLED(title) - :parameter title: (string) Title of the parts + :parameter title: (:ref:`string `) Title of the parts :return: :struct:`List` of :struct:`Part` objects Part:TITLE. The matching is done case-insensitively. For more information, see :ref:`ship parts and modules `. .. method:: Vessel:PARTSTAGGED(tag) - :parameter tag: (string) Tag of the parts + :parameter tag: (:ref:`string `) Tag of the parts :return: :struct:`List` of :struct:`Part` objects Part:TAG value. The matching is done case-insensitively. For more information, see :ref:`ship parts and modules `. .. method:: Vessel:PARTSDUBBED(name) - :parameter name: (string) name, title or tag of the parts + :parameter name: (:ref:`string `) name, title or tag of the parts :return: :struct:`List` of :struct:`Part` objects name regardless of whether that name is the Part:Name, the Part:Tag, or the Part:Title. It is effectively the distinct union of :PARTSNAMED(val), :PARTSTITLED(val), :PARTSTAGGED(val). The matching is done case-insensitively. For more information, see :ref:`ship parts and modules `. .. method:: Vessel:MODULESNAMED(name) - :parameter name: (string) Name of the part modules + :parameter name: (:ref:`string `) Name of the part modules :return: :struct:`List` of :struct:`PartModule` objects match the given name. The matching is done case-insensitively. For more information, see :ref:`ship parts and modules `. @@ -319,3 +439,16 @@ All vessels share a structure. To get a variable referring to any vessel you can :return: :struct:`List` of :struct:`Part` objects nametag on them of any sort that is nonblank. For more information, see :ref:`ship parts and modules `. + +.. attribute:: Vessel:CREWCAPACITY + + :type: :ref:`scalar ` + :access: Get only + + crew capacity of this vessel + +.. method:: Vessel:CREW() + + :return: :struct:`List` of :struct:`CrewMember` objects + + list of all :struct:`kerbonauts ` aboard this vessel diff --git a/doc/source/structures/vessels/vesselsensors.rst b/doc/source/structures/vessels/vesselsensors.rst index 2218d3253..721cb449e 100644 --- a/doc/source/structures/vessels/vesselsensors.rst +++ b/doc/source/structures/vessels/vesselsensors.rst @@ -11,12 +11,6 @@ If you store this in a variable and wait, the numbers are frozen in time and won .. structure:: VesselSensors - .. warning:: - - **BUG** - - This information is currenlty being read from the Active Vessel even when the Active Vessel is not the :ref:`CPU Vessel `. This comment will be removed when that bug is fixed. - .. list-table:: Members :header-rows: 1 :widths: 1 1 3 @@ -28,16 +22,16 @@ If you store this in a variable and wait, the numbers are frozen in time and won - :struct:`Vector` - Acceleration experienced by the :struct:`Vessel` * - :attr:`PRES` - - scalar + - :ref:`scalar ` - Atmospheric Pressure outside this :struct:`Vessel` * - :attr:`TEMP` - - scalar + - :ref:`scalar ` - Temperature outside this :struct:`Vessel` * - :attr:`GRAV` - :struct:`Vector` (g's) - Gravitational acceleration * - :attr:`LIGHT` - - scalar + - :ref:`scalar ` - Sun exposure on the solar panels of this :struct:`Vessel` @@ -51,14 +45,14 @@ If you store this in a variable and wait, the numbers are frozen in time and won .. attribute:: VesselSensors:PRES :access: Get only - :type: scalar + :type: :ref:`scalar ` The current pressure of this ship. .. attribute:: VesselSensors:TEMP :access: Get only - :type: scalar + :type: :ref:`scalar ` The current temperature. @@ -72,7 +66,7 @@ If you store this in a variable and wait, the numbers are frozen in time and won .. attribute:: VesselSensors:LIGHT :access: Get only - :type: scalar + :type: :ref:`scalar ` The total amount of sun exposure that exists here - only readable if there are solar panels on the vessel. diff --git a/doc/source/structures/volumes_and_files.rst b/doc/source/structures/volumes_and_files.rst new file mode 100644 index 000000000..5c33f320f --- /dev/null +++ b/doc/source/structures/volumes_and_files.rst @@ -0,0 +1,10 @@ +.. _volumes_and_files: + +Volumes and files +================= + +.. toctree:: + :glob: + :maxdepth: 1 + + volumes_and_files/* diff --git a/doc/source/structures/volumes_and_files/filecontent.rst b/doc/source/structures/volumes_and_files/filecontent.rst new file mode 100644 index 000000000..6a6835417 --- /dev/null +++ b/doc/source/structures/volumes_and_files/filecontent.rst @@ -0,0 +1,98 @@ +.. _filecontent: + +FileContent +================ + +Represents the contents of a file. You can obtain an instance of this class using :meth:`VolumeFile:READALL`. + +Internally this class stores raw data (a byte array). It can be passed around as is, for example this will copy a file:: + + SET CONTENTS TO OPEN("filename"):READALL. + SET NEWFILE TO CREATE("newfile"). + NEWFILE:WRITE(CONTENTS). + +You can parse the contents to read them as a string:: + + SET CONTENTS_AS_STRING TO OPEN("filename"):READALL:STRING. + // do something with a string: + PRINT CONTENTS_AS_STRING:CONTAINS("test"). + +Instances of this class can be iterated over. In each iteration step a single line of the file will be read. + +.. structure:: FileContent + + .. list-table:: Members + :header-rows: 1 + :widths: 1 1 4 + + * - Suffix + - Type + - Description + + + * - :attr:`LENGTH` + - :ref:`scalar ` + - File length (in bytes) + * - :attr:`EMPTY` + - :ref:`boolean ` + - True if the file is empty + * - :attr:`TYPE` + - :struct:`String` + - Type of the content + * - :attr:`STRING` + - :struct:`String` + - Contents of the file decoded using UTF-8 encoding + * - :attr:`ITERATOR` + - :struct:`Iterator` + - Iterates over the lines of a file +.. note:: + + This type is serializable. + + +.. attribute:: FileContent:LENGTH + + :type: :ref:`scalar ` + :access: Get only + + Length of the file. + +.. attribute:: FileContent:EMPTY + + :type: :ref:`boolean ` + :access: Get only + + True if the file is empty + +.. attribute:: FileContent:TYPE + + :access: Get only + :type: :struct:`String` + + Type of the content as a string. Can be one of the following:\ + + TOOSHORT + Content too short to establish a type + + ASCII + A file containing ASCII text, like the result of a LOG command. + + KSM + A type of file containing KerboMachineLanguage compiled code, that was created from the :ref:`COMPILE command `. + + BINARY + Any other type of file. + +.. attribute:: FileContent:STRING + + :access: Get only + :type: :struct:`String` + + Contents of the file decoded using UTF-8 encoding + +.. attribute:: FileContent:ITERATOR + + :access: Get only + :type: :struct:`Iterator` + + Iterates over the lines of a file diff --git a/doc/source/structures/volumes_and_files/volume.rst b/doc/source/structures/volumes_and_files/volume.rst new file mode 100644 index 000000000..4e58f4c90 --- /dev/null +++ b/doc/source/structures/volumes_and_files/volume.rst @@ -0,0 +1,128 @@ +.. _volume: + +Volume +====== + +Represents a :struct:`kOSProcessor` hard disk or the archive. + + +.. structure:: Volume + + .. list-table:: + :header-rows: 1 + :widths: 2 1 4 + + * - Suffix + - Type + - Description + + * - :attr:`FREESPACE` + - :ref:`scalar ` + - Free space left on the volume + + * - :attr:`CAPACITY` + - :ref:`scalar ` + - Total space on the volume + + * - :attr:`NAME` + - :ref:`String` + - Volume name + + * - :attr:`RENAMEABLE` + - :ref:`scalar ` + - True if the name can be changed + + * - :attr:`FILES` + - :struct:`Lexicon` + - Lexicon of all files on the volume + + * - :attr:`POWERREQUIREMENT` + - :ref:`scalar ` + - Amount of power consumed when this volume is set as the current volume + + * - :meth:`EXISTS(filename)` + - :ref:`boolean ` + - Returns true if the given file exists + + * - :meth:`CREATE(filename)` + - :struct:`VolumeFile` + - Creates a file + + * - :meth:`OPEN(filename)` + - :struct:`VolumeFile` + - Opens a file + + * - :meth:`DELETE(filename)` + - :ref:`boolean ` + - Deletes a file + +.. attribute:: Volume:FREESPACE + + :type: :ref:`scalar ` + :access: Get only + + Free space left on the volume + +.. attribute:: Volume:CAPACITY + + :type: :ref:`scalar ` + :access: Get only + + Total space on the volume + +.. attribute:: Volume:NAME + + :type: :ref:`String` + :access: Get only + + Volume name. This name can be used instead of the volumeId with some :ref:`file and volume-related commands` + +.. attribute:: Volume:RENAMEABLE + + :type: :ref:`boolean ` + :access: Get only + + True if the name of this volume can be changed. Currently only the name of the archive can't be changed. + + +.. attribute:: Volume:FILES + + :type: :struct:`Lexicon` of :struct:`VolumeFile` + :access: Get only + + List of files on this volume. Keys are the names of all files on this volume and values are the associated :struct:`VolumeFile` structures. + + +.. attribute:: Volume:POWERREQUIREMENT + + :type: :ref:`scalar ` + :access: Get only + + Amount of power consumed when this volume is set as the current volume + + +.. method:: Volume:EXISTS(filename) + + :return: :ref:`boolean ` + + Returns true if the given file exists. This will also return true when the given file does not exist, but there is a file with the same name and `.ks` or `.ksm` extension added. + Use ``Volume:FILES:HASKEY(filename)`` to perform a strict check. + +.. method:: Volume:OPEN(filename) + + :return: :struct:`VolumeFile` + + Opens the file with the given name and returns :struct:`VolumeFile`. It will fail if the file doesn't exist. + +.. method:: Volume:CREATE(filename) + + :return: :struct:`VolumeFile` + + Creates a file with the given name and returns :struct:`VolumeFile`. It will fail if the file already exists. + +.. method:: Volume:DELETE(filename) + + :return: boolean + + Deletes the given file. It will return true if file was successfully deleted and false otherwise. + diff --git a/doc/source/structures/volumes_and_files/volumefile.rst b/doc/source/structures/volumes_and_files/volumefile.rst new file mode 100644 index 000000000..afc6d4986 --- /dev/null +++ b/doc/source/structures/volumes_and_files/volumefile.rst @@ -0,0 +1,86 @@ +.. _volumefile: + +VolumeFile +================ + +File name and size information. You can obtain a list of values of type VolumeFile using the :ref:`LIST FILES ` command. + +.. structure:: VolumeFile + + .. list-table:: Members + :header-rows: 1 + :widths: 1 1 4 + + * - Suffix + - Type + - Description + + + * - :attr:`NAME` + - :struct:`String` + - Name of the file including extension + * - :attr:`EXTENSION` + - :struct:`String` + - File extension + * - :attr:`SIZE` + - :ref:`scalar ` (bytes) + - Size of the file + * - :meth:`READALL` + - :struct:`FileContent` + - Reads file contents + * - :meth:`WRITE(String|FileContent)` + - :ref:`boolean ` + - Writes the given string to the file + * - :meth:`WRITELN(string)` + - :struct:`FileContent` + - Writes the given string and a newline to the file + * - :meth:`CLEAR` + - None + - Clears this file + + +.. attribute:: VolumeFile:NAME + + :access: Get only + :type: :struct:`String` + + name of the file, including its file extension. + +.. attribute:: VolumeFile:EXTENSION + + :access: Get only + :type: :struct:`String` + + File extension (part of the filename after the last dot). + +.. attribute:: VolumeFile:SIZE + + :access: Get only + :type: :ref:`scalar ` + + size of the file, in bytes. + + +.. method:: VolumeFile:READALL + + :return: :struct:`FileContent` + + Reads the content of the file. + +.. method:: VolumeFile:WRITE(String|FileContent) + + :return: :ref:`boolean ` + + Writes the given string or a :struct:`FileContent` to the file. Returns true if successful (lack of space on the :struct:`Volume` can cause a failure). + +.. method:: VolumeFile:WRITELN(string) + + :return: :ref:`boolean ` + + Writes the given string followed by a newline to the file. Returns true if successful. + +.. method:: VolumeFile:CLEAR + + :return: None + + Clears this file diff --git a/doc/source/structures/waypoint.rst b/doc/source/structures/waypoint.rst index 12bc0e81a..5b36885e2 100644 --- a/doc/source/structures/waypoint.rst +++ b/doc/source/structures/waypoint.rst @@ -11,7 +11,7 @@ Waypoints are the location markers you can see on the map view showing you where .. function:: WAYPOINT(name) - :parameter name: (string) Name of the waypoint as it appears on the map or in the contract description + :parameter name: (:ref:`string `) Name of the waypoint as it appears on the map or in the contract description :return: :struct:`Waypoint` This creates a new Waypoint from a name of a waypoint you read from the contract paramters. Note that this only works on contracts you've accpted. Waypoints for proposed contracts haven't accepted yet do not actually work in kOS. @@ -36,7 +36,7 @@ Waypoints are the location markers you can see on the map view showing you where - Type * - :attr:`NAME` - - string + - :ref:`string ` * - :attr:`BODY` - `BodyTarget` * - :attr:`GEOPOSITION` @@ -44,22 +44,22 @@ Waypoints are the location markers you can see on the map view showing you where * - :attr:`POSITION` - `Vector` * - :attr:`ALTITUDE` - - scalar + - :ref:`scalar ` * - :attr:`AGL` - - scalar + - :ref:`scalar ` * - :attr:`NEARSURFACE` - - boolean + - :ref:`boolean ` * - :attr:`GROUNDED` - - boolean + - :ref:`boolean ` * - :attr:`INDEX` - - scalar + - :ref:`scalar ` * - :attr:`CLUSTERED` - - boolean + - :ref:`boolean ` .. attribute:: Waypoint:NAME - :type: string + :type: :ref:`string ` :access: Get only Name of waypoint as it appears on the map and contract @@ -88,7 +88,7 @@ Waypoints are the location markers you can see on the map view showing you where .. attribute:: Waypoint:ALTITUDE - :type: scalar + :type: :ref:`scalar ` :access: Get only Altitude of waypoint **above "sea" level**. Warning, this a point somewhere in the midst of the contract altitude range, not the edge of the altitude range. It corresponds towhere the marker tip hovers on the map, which is not actually at the very edge of the contract condition's range. It represents a typical midling location inside the contract's altitude range. @@ -96,7 +96,7 @@ Waypoints are the location markers you can see on the map view showing you where .. attribute:: Waypoint:AGL - :type: scalar + :type: :ref:`scalar ` :access: Get only Altitude of waypoint **above ground**. Warning, this a point somewhere in the midst of the contract altitude range, not the edge of the altitude range. It corresponds to where the marker tip hovers on the map, which is not actually at the very edge of the contract condition's range. It represents a typical midling location inside the contract's altitude range. @@ -104,7 +104,7 @@ Waypoints are the location markers you can see on the map view showing you where .. attribute:: Waypoint:NEARSURFACE - :type: boolean + :type: :ref:`boolean ` :access: Get only True if waypoint is a point near or on the body rather than high in orbit. @@ -112,21 +112,21 @@ Waypoints are the location markers you can see on the map view showing you where .. attribute:: Waypoint:GROUNDED - :type: boolean + :type: :ref:`boolean ` :access: Get only True if waypoint is actually glued to the ground. .. attribute:: Waypoint:INDEX - :type: scalar + :type: :ref:`scalar ` :access: Get only The integer index of this waypoint amongst its cluster of sibling waypoints. In other words, when you have a cluster of waypoints called "Somewhere Alpha", "Somewhere Beta", and "Somewhere Gamma", then the alpha site has index 0, the beta site has index 1 and the gamma site has index 2. When Waypoint:CLUSTERED is false, this value is zero but meaningless. .. attribute:: Waypoint:CLUSTERED - :type: boolean + :type: :ref:`boolean ` :access: Get only True if this waypoint is part of a set of clustered waypoints with greek letter names appended (Alpha, Beta, Gamma, etc). If true, there should be a one-to-one correspondence with the greek letter name and the :INDEX suffix. (0 = Alpha, 1 = Beta, 2 = Gamma, etc). diff --git a/doc/source/tutorials/designpatterns.rst b/doc/source/tutorials/designpatterns.rst index a9a4a5de6..e5cd0b853 100644 --- a/doc/source/tutorials/designpatterns.rst +++ b/doc/source/tutorials/designpatterns.rst @@ -216,7 +216,7 @@ With this in mind, consider an extension of the example script in the previous s WAIT 0.1. } -This example does what is expected of it without problems. But the ship's altitude is being checked at least five times for every update, including the UNTIL loop check. Certaintly, the kOS CPU can keep up with this, however, one can imagine a whole series of WHEN/THEN statements which make use of complicated calculations based on atmospheric data or orbital mechanics. One way to minimize the trigger condition checking is to take strictly-sequential triggers and nest them: +This example does what is expected of it without problems. But the ship's altitude is being checked at least five times for every update, including the UNTIL loop check. Certainly, the kOS CPU can keep up with this, however, one can imagine a whole series of WHEN/THEN statements which make use of complicated calculations based on atmospheric data or orbital mechanics. One way to minimize the trigger condition checking is to take strictly-sequential triggers and nest them: :: diff --git a/doc/source/tutorials/exenode.rst b/doc/source/tutorials/exenode.rst index 3b93e427b..3bc309f4b 100644 --- a/doc/source/tutorials/exenode.rst +++ b/doc/source/tutorials/exenode.rst @@ -1,11 +1,11 @@ .. _exenode: -Advanced Tutorial -================= +Execute Node Script +=================== -Let's try to automate one of the most common tasks in orbital maneuvering - execution of the maneuver node. In this tutorial I'll try to show you how to write a script for precise maneuver node execution. +Let's try to automate one of the most common tasks in orbital maneuvering - execution of the maneuver node. In this tutorial I'll try to show you how to write a script for somewhat precise maneuver node execution. -So to start our script we need to get the next available :ref:`maneuver node <_maneuver node>`:: +So to start our script we need to get the next available :ref:`maneuver node `:: set nd to nextnode(). @@ -17,9 +17,23 @@ Our next step is to calculate how much time our vessel needs to burn at full thr //calculate ship's max acceleration set max_acc to ship:maxthrust/ship:mass. - //now we just need to divide deltav:mag by our ship's max acceleration + // Now we just need to divide deltav:mag by our ship's max acceleration + // to get the estimated time of the burn. + // + // Please note, this is not exactly correct. The real calculation + // needs to take into account the fact that the mass will decrease + // as you lose fuel during the burn. In fact throwing the fuel out + // the back of the engine very fast is the entire reason you're able + // to thrust at all in space. The proper calculation for this + // can be found easily enough online by searching for the phrase + // "Tsiolkovsky rocket equation". + // This example here will keep it simple for demonstration purposes, + // but if you're going to build a serious node execution script, you + // need to look into the Tsiolkovsky rocket equation to account for + // the change in mass over time as you burn. + // set burn_duration to nd:deltav:mag/max_acc. - print "Estimated burn duration: " + round(burn_duration) + "s". + print "Crude Estimated burn duration: " + round(burn_duration) + "s". So now we have our node's deltav vector, ETA to the node and we calculated our burn duration. All that is left for us to do is wait until we are close to node's ETA less half of our burn duration. But we want to write a universal script, and some of our current and/or future ships can be quite slow to turn, so let's give us some time, 60 seconds, to prepare for the maneuver burn:: @@ -29,7 +43,7 @@ This wait can be tedious and you'll most likely end up warping some time, but we The wait has finished, and now we need to start turning our ship in the direction of the burn:: - set np to lookdirup(nd:deltav, ship:facing:topvector). //points to node, keeping roll the same. + set np to nd:deltav. //points to node, don't care about the roll direction. lock steering to np. //now we need to wait until the burn vector and ship's facing are aligned @@ -54,7 +68,7 @@ Now we are ready to burn. It is usually done in the `until` loop, checking main //throttle is 100% until there is less than 1 second of time left to burn //when there is less than 1 second - decrease the throttle linearly - set tset to min(nd:deltav:mag/maxa_acc, 1). + set tset to min(nd:deltav:mag/max_acc, 1). //here's the tricky part, we need to cut the throttle as soon as our nd:deltav and initial deltav start facing opposite directions //this check is done via checking the dot product of those 2 vectors diff --git a/doc/source/tutorials/pidloops.rst b/doc/source/tutorials/pidloops.rst index 39d9f5cd4..25a864d07 100644 --- a/doc/source/tutorials/pidloops.rst +++ b/doc/source/tutorials/pidloops.rst @@ -3,6 +3,22 @@ PID Loops in kOS ================ +.. versionadded:: 0.18.1 + + Note, this is an older tutorial. As of + kOS version 0.18.1 and up, a new :struct:`pidloop` + feature was added to kOS to allow you to use a built-in PID + controller that executes very quickly in the kOS "hardware" + rather than in your script code. You can use it to perform + the work described in detail on this page. However, this + tutorial is still quite important because it walks you through + how a PID controller works and what it's really doing under the + hood. It's probably a good idea to use the built-in + :struct:`pidloop` instead of the program shown here, once you + understand the topic this page describes. However, it's also + a good idea to have a read through this page to get an + understanding of what that built-in feature is really doing. + This tutorial covers how one can implement a `PID loop`_ using kOS. A P-loop, or "proportional feedback loop" was already introduced in the second section of the :ref:`Design Patterns Tutorial `, and that will serve as our starting point. After some code rearrangement, the integral and derivative terms will be added and discussed in turn. Next, a couple extra features will be added to the full PID-loop. Lastly, we'll show a case-study in tuning a full PID loop using the Ziegler-Nichols method. We'll use the LOG method to dump telemetry from KSP into a file and our favorite graphing software to visualize the data. .. _PID loop: http://en.wikipedia.org/wiki/PID_controller @@ -158,6 +174,40 @@ Incorporating the derivative term (D) and derivative gain (Kd) requires an addit When tuned properly, the derivative term will cause the PID-loop to act quickly without causing problematic oscillations. Later in this tutorial, we will cover a way to tune a PID-loop using only the proportional term called the Zieger-Nichols method. +.. _struct_pidloop_in_tutorial: + +Using :struct:`pidloop` +----------------------- + +As mentioned earlier, kOS 0.18.1 introduced a new structure called :struct:`pidloop` that can take the place of much of the previous code. Here is the previous script, converted to use :struct:`pidloop`. + +:: + + // pidloop + SET g TO KERBIN:MU / KERBIN:RADIUS^2. + LOCK accvec TO SHIP:SENSORS:ACC - SHIP:SENSORS:GRAV. + LOCK gforce TO accvec:MAG / g. + + SET Kp TO 0.01. + SET Ki TO 0.006. + SET Kd TO 0.006. + SET PID TO PIDLOOP(Kp, Kp, Kd). + SET PID:SETPOINT TO 1.2. + + SET thrott TO 1. + LOCK THROTTLE TO thrott. + + UNTIL SHIP:ALTITUDE > 40000 { + SET thrott TO thrott + PID:UPDATE(TIME:SECONDS, gforce). + // pid:update() is given the input time and input and returns the output. gforce is the input. + WAIT 0.001. + } + +The primary advantage to using :struct:`pidloop` is the reduction in the number of instructions per update (see :attr:`Config:IPU`). For example, this :struct:`pidloop` script requires approximately one-third the number of instructions needed by the script shown in the previous section. Since the number of instructions executed has a direct bearing on :ref:`electrical drain ` as of 0.19.0, this can be a great help with power conservation. + +Note that :struct:`pidloop` offers a great deal more options than were presented here, but nevertheless, this should provide a decent introduction to using :struct:`pidloop`. + + Final Touches ------------- @@ -225,7 +275,7 @@ Tuning a PID-loop We are going to start with the same rocket design we have been using so far and actually tune the PID-loop using the Ziegler-Nichols method. This is where we turn off the integral and derivative terms in the loop and bring the proportional gain (Kp) up from zero to the point where the loop causes a steady oscillation with a measured period (Tu). At this point, the proportional gain is called the "ultimate gain" (Ku) and the actual gains (Kp, Ki and Kd) are set according to this table `taken from wikipedia`_: -.. _taken from wikipedia: http://en.wikipedia.org/wiki/Ziegler%E2%80%93Nichols_method +.. _taken from Wikipedia: http://en.wikipedia.org/wiki/Ziegler%E2%80%93Nichols_method +------------------------+-----------+---------------+--------------+ | Control Type | Kp | Ki | Kd | diff --git a/doc/source/tutorials/quickstart.rst b/doc/source/tutorials/quickstart.rst index ad4fbd0f3..c5d8263b0 100644 --- a/doc/source/tutorials/quickstart.rst +++ b/doc/source/tutorials/quickstart.rst @@ -34,7 +34,7 @@ Put the vessel on the launchpad. For this first example it doesn't matter if the Step 4: Invoke the terminal ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Rightclick for the SCS part on the vessel and then click the button that says "Open Terminal". +Right click for the SCS part on the vessel and then click the button that says "Open Terminal". Note that if the terminal is semi-transparent, this means it's not currently selected. If you click on the terminal, then your keyboard input is directed to the terminal INSTEAD of to piloting. In other words if you type ``W`` ``A`` ``S`` ``D``, you'll actually get the word "wasd" to appear on the terminal, rather than the ``W`` ``A`` ``S`` ``D`` keys steering the ship. To switch back to manual control of the game instead of typing into the terminal, click outside the terminal window anywhere on the background of the screen. @@ -74,7 +74,7 @@ Type this text into the window:: PRINT "THIS IS THE FIRST SCRIPT I WROTE IN kOS.". PRINT "=========================================". -Click "Save" then "Exit" in the editor popup window. +Click "Save" then "Exit" in the editor pop-up window. - *Side Note: The editor font* - Experienced programmers may have noticed that the editor's font is proportional width rather than monospaced and that this is not ideal for programming work. You are right, but there is little that can be done about it for a variety of technical reasons that are too complex to go into right now. @@ -132,7 +132,7 @@ Further reading about files and volumes: - :ref:`Volumes ` - :ref:`File Control ` -- :ref:`File Information ` +- :ref:`VolumeFile structure ` Second Example: Doing something real ------------------------------------ @@ -146,32 +146,33 @@ But in order to give you an example that you can start with from scratch, that's Step 1: Make a vessel ^^^^^^^^^^^^^^^^^^^^^ -Make any sort of rocket that can lift you to orbit that fills the following pattern: +This tutorial is designed to work with a very specific rocket design. +You need to make the vessel you see here: -- It uses ONLY liquid fuel rockets. The example code here will assume this is the case. **kOS** can deal with solid fuel boosters as well, but to keep the example simple we'll use liquid fuel only here. -- Make the vessel's staging list set up in the right order for a launch. (Make sure it has no need to manually rightclick parts to stage things weirdly, and no need to use action groups to activate stages weirdly). -- Make sure the vessel has plenty of torque power to stay steady without a lot of wobble. -- Make the vessel have at least these parts on it: -- battery power of at least 400 charge -- ability to recharge equal to at least 6 solar panel sections or 1 RTG unit -- the **kOS** SCS part somewhere in the stack, near the top bit where it won't fall off due to staging. +.. figure:: /_images/tutorials/quickstart/example_2_0.png + :width: 80 % + +If you prefer, you can instead download the +`.craft file here <../_static/tutorials/quickstart/MyFirstRocket.craft>`_ Step 2: Make the start of the script ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Okay, so type the lines below in an external *text editor of your choice* (i.e. Notepad on Windows, or TextEdit on Mac, or whatever you fancy):: - // My First Launcher. + //hellolaunch + + //First, we'll clear the terminal screen to make it look nice + CLEARSCREEN. - SET countdown TO 10. + //This is our countdown loop, which cycles from 10 to 0 PRINT "Counting down:". - UNTIL countdown = 0 { + FROM {local countdown is 10.} UNTIL countdown = 0 STEP {SET countdown to countdown - 1.} DO { PRINT "..." + countdown. - SET countdown TO countdown - 1. WAIT 1. // pauses the script here for 1 second. } -See those things with the two slashes ("//")? Those are comments in the kerboscript language and they're just ways to write things in the program that don't do anything - they're there for humans like you to read so you understand what's going on. In these examples you never actually have to type in the things you see after the slashes. They're there for your benefit when reading this document but you can leave them out if you wish. +See those things with the two slashes ("//")? Those are comments in the Kerboscript language and they're just ways to write things in the program that don't do anything - they're there for humans like you to read so you understand what's going on. In these examples you never actually have to type in the things you see after the slashes. They're there for your benefit when reading this document but you can leave them out if you wish. Save the file in your ``Ships/Script`` folder of your **KSP** installation under the filename "hellolaunch.ks". DO NOT save it anywhere under ``GameData/kOS/``. Do NOT. According to the **KSP** standard, normally **KSP** mods should put their files in ``GameData/[mod name]``, but **kOS** puts the archive outside the ``GameData`` folder because it represents content owned by you, the player, not content owned by the **kOS** mod. @@ -189,7 +190,7 @@ after saving the file from your external text editor program, you will see a lis .. figure:: /_images/tutorials/quickstart/example_2_1.png :width: 80 % -Okay so the program doesn't actaully DO anything yet other than just countdown from 10 to 0. A bit of a dissapointment, but we haven't written the rest of the program yet. +Okay so the program doesn't actually DO anything yet other than just countdown from 10 to 0. A bit of a disappointment, but we haven't written the rest of the program yet. You'll note that what you've done is switch to the local volume (1) and then copy the program from the archive (0) to the local volume (1) and then run it from the local volume. Technically you didn't need to do this. You could have just run it directly from the archive. For those looking at the **KSP** game as a bit of a role-play experience, it makes sense to never run programs directly from the archive, and instead live with the limitation that software should be copied to the craft for it to be able to run it. @@ -198,30 +199,33 @@ Step 3: Make the script actually do something Okay now go back into your *text editor of choice* and append a few more lines to the hellolaunch.ks file so it now looks like this:: - // My First Launcher. + //hellolaunch - SET countdown TO 10. + //First, we'll clear the terminal screen to make it look nice + CLEARSCREEN. + + //Next, we'll lock our throttle to 100%. + LOCK THROTTLE TO 1.0. // 1.0 is the max, 0.0 is idle. + + //This is our countdown loop, which cycles from 10 to 0 PRINT "Counting down:". - UNTIL countdown = 0 { + FROM {local countdown is 10.} UNTIL countdown = 0 STEP {SET countdown to countdown - 1.} DO { PRINT "..." + countdown. - SET countdown TO countdown - 1. WAIT 1. // pauses the script here for 1 second. } - PRINT "Main throttle up. 2 seconds to stabalize it.". - LOCK THROTTLE TO 1.0. // 1.0 is the max, 0.0 is idle. - WAIT 2. // give throttle time to adjust. UNTIL SHIP:MAXTHRUST > 0 { WAIT 0.5. // pause half a second between stage attempts. PRINT "Stage activated.". STAGE. // same as hitting the spacebar. } - WAIT UNTIL SHIP:ALTITUDE > 70000. // pause here until ship is high up. + + WAIT UNTIL SHIP:ALTITUDE > 70000. // NOTE that it is vital to not just let the script end right away // here. Once a kOS script just ends, it releases all the controls // back to manual piloting so that you can fly the ship by hand again. - // If the pogram just ended here, then that would cause the throttle + // If the program just ended here, then that would cause the throttle // to turn back off again right away and nothing would happen. Save this file to hellolaunch.ks again, and re-copy it to your vessel that should still be sitting on the launchpad, then run it, like so:: @@ -255,37 +259,39 @@ So to steer always UP, just do this:: So if you just add this one line to your script, you'll get something that should keep the craft aimed straight up and not let it tip over. Add the line just after the line that sets the THROTTLE, like so:: - // My First Launcher. + //hellolaunch - SET countdown TO 10. + //First, we'll clear the terminal screen to make it look nice + CLEARSCREEN. + + //Next, we'll lock our throttle to 100%. + LOCK THROTTLE TO 1.0. // 1.0 is the max, 0.0 is idle. + + //This is our countdown loop, which cycles from 10 to 0 PRINT "Counting down:". - UNTIL countdown = 0 { + FROM {local countdown is 10.} UNTIL countdown = 0 STEP {SET countdown to countdown - 1.} DO { PRINT "..." + countdown. - SET countdown TO countdown - 1. WAIT 1. // pauses the script here for 1 second. } - PRINT "Main throttle up. 2 seconds to stabalize it.". - LOCK THROTTLE TO 1.0. // 1.0 is the max, 0.0 is idle. - - - LOCK STEERING TO UP. // This is the new line to add - + + //This is the line we added + LOCK STEERING TO UP. - WAIT 2. // give throttle time to adjust. UNTIL SHIP:MAXTHRUST > 0 { WAIT 0.5. // pause half a second between stage attempts. PRINT "Stage activated.". STAGE. // same as hitting the spacebar. } - WAIT UNTIL SHIP:ALTITUDE > 70000. // pause here until ship is high up. + + WAIT UNTIL SHIP:ALTITUDE > 70000. // NOTE that it is vital to not just let the script end right away // here. Once a kOS script just ends, it releases all the controls // back to manual piloting so that you can fly the ship by hand again. - // If the pogram just ended here, then that would cause the throttle + // If the program just ended here, then that would cause the throttle // to turn back off again right away and nothing would happen. -Again, copy this and run it, like before. If your craft crashed in the previous step, which it probably did, then revert to the VAB and re-launch it. *NOTE: Due to a bug sometimes reverting just to the launchpad does not work well and you need to revert all the way back to the VAB.*:: +Again, copy this and run it, like before. If your craft crashed in the previous step, which it probably did, then revert to the VAB and re-launch it.:: SWITCH TO 1. // should be the default already, but just in case. COPY HELLOLAUNCH FROM 0. @@ -312,49 +318,54 @@ There are some complex dangers with writing WHEN triggers that can cause **KSP** The WHEN trigger we are going to add to the launch script looks like this:: - WHEN STAGE:LIQUIDFUEL < 0.001 THEN { - PRINT "No liquidfuel. Attempting to stage.". + WHEN MAXTHRUST = 0 THEN { + PRINT "Staging". STAGE. PRESERVE. - } + }. -It says, "Whenever the amount of liquid fuel in the current stage is so small it may as well be zero (< 0.001), then activate the next stage." The PRESERVE keyword says, "don't stop checking this condition just because it's been triggered once. It should still keep checking for it again in the future." -The check for < 0.001 is because sometimes **KSP** won't quite burn the last drop of fuel in a stage. -If this block of code is inserted into the script, then it will set up a constant background check that will always hit the next stage as soon as the current stage has no liquidfuel in it. +It says, "Whenever the maximum thrust of our vehicle is zero, then activate the next stage." The PRESERVE keyword says, "don't stop checking this condition just because it's been triggered once. It should still keep checking for it again in the future." +If this block of code is inserted into the script, then it will set up a constant background check that will always hit the next stage as soon as the current stage has no thrust. UNLIKE with all the previous edits this tutorial has asked you to make to the script, this time you're going to be asked to delete something and replace it. The new WHEN section above should actually **REPLACE** the existing "UNTIL SHIP:MAXTHRUST > 0" loop that you had before. Now your script should look like this:: - // My First Launcher. + //hellolaunch + + //First, we'll clear the terminal screen to make it look nice + CLEARSCREEN. - SET countdown TO 10. + //Next, we'll lock our throttle to 100%. + LOCK THROTTLE TO 1.0. // 1.0 is the max, 0.0 is idle. + + //This is our countdown loop, which cycles from 10 to 0 PRINT "Counting down:". - UNTIL countdown = 0 { + FROM {local countdown is 10.} UNTIL countdown = 0 STEP {SET countdown to countdown - 1.} DO { PRINT "..." + countdown. - SET countdown TO countdown - 1. WAIT 1. // pauses the script here for 1 second. } - PRINT "Main throttle up. 2 seconds to stabalize it.". - LOCK THROTTLE TO 1.0. // 1.0 is the max, 0.0 is idle. - LOCK STEERING TO UP. - WAIT 2. // give throttle time to adjust. - - // The section below replaces previous UNTIL loop: - WHEN STAGE:LIQUIDFUEL < 0.001 THEN { - PRINT "No liquidfuel. Attempting to stage.". + //This is a trigger that constantly checks to see if our thrust is zero. + //If it is, it will attempt to stage and then return to where the script + //left off. The PRESERVE keyword keeps the trigger active even after it + //has been triggered. + WHEN MAXTHRUST = 0 THEN { + PRINT "Staging". STAGE. PRESERVE. - } - WAIT UNTIL SHIP:ALTITUDE > 70000. // pause here until ship is high up. + }. + + LOCK STEERING TO UP. + + WAIT UNTIL ALTITUDE > 70000. // NOTE that it is vital to not just let the script end right away // here. Once a kOS script just ends, it releases all the controls // back to manual piloting so that you can fly the ship by hand again. - // If the pogram just ended here, then that would cause the throttle + // If the program just ended here, then that would cause the throttle // to turn back off again right away and nothing would happen. -Again, relaunch the ship, copy the script as before, and run it again. This time you should see it activate your later upper stages correctly. (again, assuming you made the entire vessel with only liquidfuel engines.) +Again, relaunch the ship, copy the script as before, and run it again. This time you should see it activate your later upper stages correctly. .. figure:: /_images/tutorials/quickstart/example_2_4.png :width: 80 % @@ -365,86 +376,248 @@ Step 6: Now to make it turn *Okay that's fine but it still just goes straight up! What about a gravity turn?* -Well, a true and proper gravity turn is a very complex bit of math that is best left as an excercise for the reader, given that the goal of **kOS** is to let you write your OWN autopilot, not to write it for you. But to give some basic examples of commands, lets just make a crude gravity turn approximation that simply flies the ship like a lot of new **KSP** pilots learn to do it for the first time: +Well, a true and proper gravity turn is a very complex bit of math that is best left as an exercise for the reader, given that the goal of **kOS** is to let you write your OWN autopilot, not to write it for you. But to give some basic examples of commands, lets just make a crude gravity turn approximation that simply flies the ship like a lot of new **KSP** pilots learn to do it for the first time: -- Fly straight up to 10000m. -- Aim at 45 degrees down toward the east until 40000m. -- Thrust horizontally east after that. +- Fly straight up until your velocity is 100m/s. +- Pitch ten degrees towards the East. +- Continue to pitch 10 degrees down for each 100m/s of velocity. To make this work, we introduce a new way to make a Direction, called the HEADING function. Whenever you call the function HEADING(a,b), it makes a Direction oriented as follows on the navball: - Point at the compass heading A. - Pitch up a number of degrees from the horizon = to B. -So for example, HEADING(45,10) would aim northeast, 10 degrees above the horizon. Combining this with the WHEN command from before, we get this section:: +So for example, HEADING(45,10) would aim northeast, 10 degrees above the horizon. We can use this to easily set our orientation. For example:: + + //This locks our steering to due east, pitched 45 degrees above the horizon. + LOCK STEERING TO HEADING(90,45). + +Instead of using WAIT UNTIL to pause the script and keep it from exiting, we can use an UNTIL loop to constantly perform actions until a certain condition is met. For example:: + + SET MYSTEER TO HEADING(90,90). //90 degrees east and pitched up 90 degrees (straight up) + LOCK STEERING TO MYSTEER. // from now on we'll be able to change steering by just assigning a new value to MYSTEER + UNTIL APOAPSIS > 100000 { + SET MYSTEER TO HEADING(90,90). //90 degrees east and pitched up 90 degrees (straight up) + PRINT ROUND(SHIP:APOAPSIS,0) AT (0,16). // prints new number, rounded to the nearest integer. + //We use the PRINT AT() command here to keep from printing the same thing over and + //over on a new line every time the loop iterates. Instead, this will always print + //the apoapsis at the same point on the screen. + }. + +This loop will continue to execute all of its instructions until the apoapsis reaches 100km. Once the apoapsis is past 100km, the loop exits and the rest of the code continues. + +We can combine this with IF statements in order to have one main loop that only executes certain chunks of its code under certain conditions. For example:: + + SET MYSTEER TO HEADING(90,90). + LOCK STEERING TO MYSTEER. + UNTIL SHIP:APOAPSIS > 100000 { //Remember, all altitudes will be in meters, not kilometers + + //For the initial ascent, we want our steering to be straight + //up and rolled due east + IF SHIP:VELOCITY:SURFACE:MAG < 100 { + //This sets our steering 90 degrees up and yawed to the compass + //heading of 90 degrees (east) + SET MYSTEER TO HEADING(90,90). + + //Once we pass 100m/s, we want to pitch down ten degrees + } ELSE IF SHIP:VELOCITY:SURFACE:MAG >= 100 AND SHIP:VELOCITY:SURFACE:MAG < 200 { + SET MYSTEER TO HEADING(90,80). + PRINT "Pitching to 80 degrees" AT(0,15). + PRINT ROUND(SHIP:APOAPSIS,0) AT (0,16). + }. + }. + +Each time this loop iterates, it will check the surface velocity. If the velocity is below 100m/s, it will continuously execute the first block of instructions. +Once the velocity reaches 100m/s, it will stop executing the first block and start executing the second block, which will pitch the nose down to 80 degrees above the horizon. + +Putting this into your script, it should look like this:: + + //hellolaunch + + //First, we'll clear the terminal screen to make it look nice + CLEARSCREEN. + + //Next, we'll lock our throttle to 100%. + LOCK THROTTLE TO 1.0. // 1.0 is the max, 0.0 is idle. - WHEN SHIP:ALTITUDE > 10000 THEN { - PRINT "Starting turn. Aiming to 45 degree pitch.". - LOCK STEERING TO HEADING(90,45). // east, 45 degrees pitch. - } - WHEN SHIP:ALTITUDE > 40000 THEN { - PRINT "Starting flat part. Aiming to horizon.". - LOCK STEERING TO HEADING(90,0). // east, horizontal. + //This is our countdown loop, which cycles from 10 to 0 + PRINT "Counting down:". + FROM {local countdown is 10.} UNTIL countdown = 0 STEP {SET countdown to countdown - 1.} DO { + PRINT "..." + countdown. + WAIT 1. // pauses the script here for 1 second. } -Note that these lack the command PRESERVE like the previous WHEN example had. This is because we want these to trigger just once and then never again. There's no point in constantly telling **kOS** to reset the steering to the same thing over and over as the script runs. + //This is a trigger that constantly checks to see if our thrust is zero. + //If it is, it will attempt to stage and then return to where the script + //left off. The PRESERVE keyword keeps the trigger active even after it + //has been triggered. + WHEN MAXTHRUST = 0 THEN { + PRINT "Staging". + STAGE. + PRESERVE. + }. + + //This will be our main control loop for the ascent. It will + //cycle through continuously until our apoapsis is greater + //than 100km. Each cycle, it will check each of the IF + //statements inside and perform them if their conditions + //are met + SET MYSTEER TO HEADING(90,90). + LOCK STEERING TO MYSTEER. // from now on we'll be able to change steering by just assigning a new value to MYSTEER + UNTIL SHIP:APOAPSIS > 100000 { //Remember, all altitudes will be in meters, not kilometers + + //For the initial ascent, we want our steering to be straight + //up and rolled due east + IF SHIP:VELOCITY:SURFACE:MAG < 100 { + //This sets our steering 90 degrees up and yawed to the compass + //heading of 90 degrees (east) + SET MYSTEER TO HEADING(90,90). + + //Once we pass 100m/s, we want to pitch down ten degrees + } ELSE IF SHIP:VELOCITY:SURFACE:MAG >= 100 { + SET MYSTEER TO HEADING(90,80). + PRINT "Pitching to 80 degrees" AT(0,15). + PRINT ROUND(SHIP:APOAPSIS,0) AT (0,16). + }. + }. + +Again, copy this into your script and run it. You should see your countdown occur, then it will launch. Once the ship passes 100m/s surface velocity, it will +pitch down to 80 degrees and continuously print the apoapsis until the apoapsis reaches 100km, staging if necessary. The script will then end. + +.. figure:: /_images/tutorials/quickstart/example_2_5.png + :width: 80 % + +Step 7: Putting it all together +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Now, if you insert this new section to the script, we have a nice nifty example of a start of a launching script. Note that it works even if you insert it at the top of the script, because it sets up the triggers to occur LATER when the condition becomes true. They don't execute right away:: +We now have every element of the script necessary to do a proper (albeit simple) gravity turn. We just need to extend it all the way through the ascent. - // My First Launcher. +Adding additional IF statements inside our main loop will allow us to perform further actions based on our velocity. Each IF statement you see in the script below +covers a 100m/s block of velocity, and will adjust the pitch 10 degrees farther down than the previous block. - WHEN SHIP:ALTITUDE > 10000 THEN { - PRINT "Starting turn. Aiming to 45 degree pitch.". - LOCK STEERING TO HEADING(90,45). // east, 45 degrees pitch. - } - WHEN SHIP:ALTITUDE > 40000 THEN { - PRINT "Starting flat part. Aiming to horizon.". - LOCK STEERING TO HEADING(90,0). // east, horizontal. - } - SET countdown TO 10. +You can see that with the AND statement, we can check multiple conditions and only execute that block when all of those conditions are true. We can carefully set up +the conditions for each IF statement to allow a block of code to be executed no matter what our surface velocity is. + +Copy this into your script and run it. It should take you nearly to orbit:: + + //hellolaunch + + //First, we'll clear the terminal screen to make it look nice + CLEARSCREEN. + + //Next, we'll lock our throttle to 100%. + LOCK THROTTLE TO 1.0. // 1.0 is the max, 0.0 is idle. + + //This is our countdown loop, which cycles from 10 to 0 PRINT "Counting down:". - UNTIL countdown = 0 { + FROM {local countdown is 10.} UNTIL countdown = 0 STEP {SET countdown to countdown - 1.} DO { PRINT "..." + countdown. - SET countdown TO countdown - 1. WAIT 1. // pauses the script here for 1 second. } - PRINT "Main throttle up. 2 seconds to stabalize it.". - LOCK THROTTLE TO 1.0. // 1.0 is the max, 0.0 is idle. - LOCK STEERING TO UP. - WAIT 2. // give throttle time to adjust. - // The section below replaces previous UNTIL loop: - - WHEN STAGE:LIQUIDFUEL < 0.001 THEN { - PRINT "No liquidfuel. Attempting to stage.". + //This is a trigger that constantly checks to see if our thrust is zero. + //If it is, it will attempt to stage and then return to where the script + //left off. The PRESERVE keyword keeps the trigger active even after it + //has been triggered. + WHEN MAXTHRUST = 0 THEN { + PRINT "Staging". STAGE. PRESERVE. - } - WAIT UNTIL SHIP:ALTITUDE > 70000. // pause here until ship is high up. + }. + + //This will be our main control loop for the ascent. It will + //cycle through continuously until our apoapsis is greater + //than 100km. Each cycle, it will check each of the IF + //statements inside and perform them if their conditions + //are met + SET MYSTEER TO HEADING(90,90). + LOCK STEERING TO MYSTEER. // from now on we'll be able to change steering by just assigning a new value to MYSTEER + UNTIL SHIP:APOAPSIS > 100000 { //Remember, all altitudes will be in meters, not kilometers + + //For the initial ascent, we want our steering to be straight + //up and rolled due east + IF SHIP:VELOCITY:SURFACE:MAG < 100 { + //This sets our steering 90 degrees up and yawed to the compass + //heading of 90 degrees (east) + SET MYSTEER TO HEADING(90,90). + + //Once we pass 100m/s, we want to pitch down ten degrees + } ELSE IF SHIP:VELOCITY:SURFACE:MAG >= 100 AND SHIP:VELOCITY:SURFACE:MAG < 200 { + SET MYSTEER TO HEADING(90,80). + PRINT "Pitching to 80 degrees" AT(0,15). + PRINT ROUND(SHIP:APOAPSIS,0) AT (0,16). + + //Each successive IF statement checks to see if our velocity + //is within a 100m/s block and adjusts our heading down another + //ten degrees if so + } ELSE IF SHIP:VELOCITY:SURFACE:MAG >= 200 AND SHIP:VELOCITY:SURFACE:MAG < 300 { + SET MYSTEER TO HEADING(90,70). + PRINT "Pitching to 70 degrees" AT(0,15). + PRINT ROUND(SHIP:APOAPSIS,0) AT (0,16). + + } ELSE IF SHIP:VELOCITY:SURFACE:MAG >= 300 AND SHIP:VELOCITY:SURFACE:MAG < 400 { + SET MYSTEER TO HEADING(90,60). + PRINT "Pitching to 60 degrees" AT(0,15). + PRINT ROUND(SHIP:APOAPSIS,0) AT (0,16). + + } ELSE IF SHIP:VELOCITY:SURFACE:MAG >= 400 AND SHIP:VELOCITY:SURFACE:MAG < 500 { + SET MYSTEER TO HEADING(90,50). + PRINT "Pitching to 50 degrees" AT(0,15). + PRINT ROUND(SHIP:APOAPSIS,0) AT (0,16). + + } ELSE IF SHIP:VELOCITY:SURFACE:MAG >= 500 AND SHIP:VELOCITY:SURFACE:MAG < 600 { + SET MYSTEER TO HEADING(90,40). + PRINT "Pitching to 40 degrees" AT(0,15). + PRINT ROUND(SHIP:APOAPSIS,0) AT (0,16). + + } ELSE IF SHIP:VELOCITY:SURFACE:MAG >= 600 AND SHIP:VELOCITY:SURFACE:MAG < 700 { + SET MYSTEER TO HEADING(90,30). + PRINT "Pitching to 30 degrees" AT(0,15). + PRINT ROUND(SHIP:APOAPSIS,0) AT (0,16). + + } ELSE IF SHIP:VELOCITY:SURFACE:MAG >= 700 AND SHIP:VELOCITY:SURFACE:MAG < 800 { + SET MYSTEER TO HEADING(90,11). + PRINT "Pitching to 20 degrees" AT(0,15). + PRINT ROUND(SHIP:APOAPSIS,0) AT (0,16). + + //Beyond 800m/s, we can keep facing towards 10 degrees above the horizon and wait + //for the main loop to recognize that our apoapsis is above 100km + } ELSE IF SHIP:VELOCITY:SURFACE:MAG >= 800 { + SET MYSTEER TO HEADING(90,10). + PRINT "Pitching to 10 degrees" AT(0,15). + PRINT ROUND(SHIP:APOAPSIS,0) AT (0,16). + + }. + + }. + + PRINT "100km apoapsis reached, cutting throttle". + + //At this point, our apoapsis is above 100km and our main loop has ended. Next + //we'll make sure our throttle is zero and that we're pointed prograde + LOCK THROTTLE TO 0. + + //This sets the user's throttle setting to zero to prevent the throttle + //from returning to the position it was at before the script was run. + SET SHIP:CONTROL:PILOTMAINTHROTTLE TO 0. - // NOTE that it is vital to not just let the script end right away - // here. Once a kOS script just ends, it releases all the controls - // back to manual piloting so that you can fly the ship by hand again. - // If the program just ended here, then that would cause the throttle - // to turn back off again right away and nothing would happen. And here is it in action: -.. figure:: /_images/tutorials/quickstart/example_2_5.png +.. figure:: /_images/tutorials/quickstart/example_2_6.png :width: 80 % And toward the end: -.. figure:: /_images/tutorials/quickstart/example_2_6.png +.. figure:: /_images/tutorials/quickstart/example_2_7.png :width: 80 % -If we assume you made a vessel that has enough fuel and power to get up to orbit, this script should in principle work to get you to the point of leaving the atmosphere. It will probably still fall back down, because this script makes no attempt to ensure that the craft is going fast enough to maintain the orbit. +This script should, in principle, work to get you to the point of leaving the atmosphere. It will probably still fall back down, because this script makes no attempt to ensure that the craft is going fast enough to maintain the orbit. As you can probably see, it would still have a long way to go before it would become a really GOOD launching autopilot. Think about the following features you could add yourself as you become more familiar with **kOS**: -- You could change the steering logic to make a more smooth gravity turn by constantly adjusting the pitch in the HEADING according to some math formula. The example shown here tends to create a "too high" launch that's a bit inefficient. -- You could complete the launching script by making sure once the vessel breaks the atmosphere it actually makes a circular orbit rather than just stopping after 70000m and coasting. -- This script just stupidly leaves the throttle at max the whole way. You could make it more sophisticated by adjusting the throttle as necessary to avoid too much wasted energy fighting air friction. (The way **KSP**'s stock areodynamic model works, the optimal speed is terminal velocity, by the way). This is partly addressed in the :ref:`PID Loop Tutorial `. -- With more sophisticated staging checks, the script could be made to work with solid fuel engines as well. -- With even more sophisticated checks, the script could be made to work with fancy staging methods like asaparagus. -- Using the PRINT AT command, you can make fancier status readouts in the termainl window as the script runs. +- You could change the steering logic to make a more smooth gravity turn by constantly adjusting the pitch in the HEADING according to some math formula. The example shown here tends to create a "too high" launch that's a bit inefficient. In addition, this method relies on velocity to determine pitch angle, which could result in some very firey launches for other ships with a higher TWR profile. +- This script just stupidly leaves the throttle at max the whole way. You could make it more sophisticated by adjusting the throttle as necessary to avoid velocities that result in high atmospheric heating. +- This script does not attempt to circularize. With some simple checks of the time to apoapsis and the orbital velocity, you can execute a burn that circularizes your orbit. +- With even more sophisticated checks, the script could be made to work with fancy staging methods like asparagus. +- Using the PRINT AT command, you can make fancier status readouts in the terminal window as the script runs. diff --git a/kOS.netkan b/kOS.netkan new file mode 100644 index 000000000..319a96502 --- /dev/null +++ b/kOS.netkan @@ -0,0 +1,38 @@ +{ + "spec_version" : 1, + "identifier" : "kOS", + "$kref" : "#/ckan/github/KSP-KOS/KOS", + "$vref" : "#/ckan/ksp-avc", + "name" : "kOS: Scriptable Autopilot System", + "abstract" : "kOS is a scriptable autopilot Mod for Kerbal Space Program. It allows you write small programs that automate specific tasks.", + "author" : "erendrake", + "license" : "GPL-3.0", + "release_status" : "stable", + "x_netkan_version_edit": "^[vV]?(?.+)$", + "resources" : { + "homepage" : "http://ksp-kos.github.io/KOS_DOC/", + "manual" : "http://ksp-kos.github.io/KOS_DOC/", + "repository" : "https://github.com/KSP-KOS/KOS" + }, + "conflicts" : [ { "name" : "kOS-Classic" } ], + "recommends" : [ + { + "name": "ModuleManager", + "min_version": "2.5.6", + "comment": "Earlier versions of MM have forward compatibility problems, according to the MM release notes." + } + ], + "suggests": [ + { + "name": "RemoteTech", + "min_version": "1.5.1", + "comment": "RT gives incentive to having local control of craft, even unmanned ones" + } + ], + "install" : [ + { + "file" : "GameData/kOS", + "install_to" : "GameData" + } + ] +} diff --git a/kerboscript_tests/compile/compiletest1.ks b/kerboscript_tests/compile/compiletest1.ks new file mode 100644 index 000000000..34de6ef63 --- /dev/null +++ b/kerboscript_tests/compile/compiletest1.ks @@ -0,0 +1,14 @@ +// compiletest1 +print "Tests the case where an empty script file is run". +print "from another script. It should do nothing, rather". +print "than get stuck forever or error out.". +print " ". +print "You must 'set count to 0' before you run the test". +set count to count + 1. +if count > 1 { print 1/0. }. // force dump after a few runs +print "program started". +log "" to empty_file. +delete empty_file. +log "" to empty_file. +run empty_file. +print "If it got this far without complaint, then it passed the test.". diff --git a/kerboscript_tests/compile/compiletest2.ks b/kerboscript_tests/compile/compiletest2.ks new file mode 100644 index 000000000..24740d39e --- /dev/null +++ b/kerboscript_tests/compile/compiletest2.ks @@ -0,0 +1,5 @@ +print "this will test whether or not you can ". +print "use lock inside for loop.". +FOR p IN SHIP:PARTS { + LOCK THROTTLE TO 0. +} diff --git a/kerboscript_tests/compile/testrunonce/testrunonce_lib1.ks b/kerboscript_tests/compile/testrunonce/testrunonce_lib1.ks new file mode 100644 index 000000000..a3c40ecfe --- /dev/null +++ b/kerboscript_tests/compile/testrunonce/testrunonce_lib1.ks @@ -0,0 +1,10 @@ +// Library to be called by testrunonce: + +// Lib1 runs Lib2 even though lib2 is also called by the main prog too: +run once testrunonce_lib2("dummy"). + +function lib1 { + return "lib1 value". +} + +print "MAINLINE CODE of lib1 is running.". diff --git a/kerboscript_tests/compile/testrunonce/testrunonce_lib2.ks b/kerboscript_tests/compile/testrunonce/testrunonce_lib2.ks new file mode 100644 index 000000000..590e296d9 --- /dev/null +++ b/kerboscript_tests/compile/testrunonce/testrunonce_lib2.ks @@ -0,0 +1,12 @@ +// Library to be called by testrunonce: + +parameter dummy. // just to test passing args not getting stack misaligned. + +// Lib2 runs Lib1 even though lib1 is also called by the main prog too: +run once testrunonce_lib1. + +function lib2 { + return "lib2 value". +} + +print "MAINLINE CODE of lib2 is running.". diff --git a/kerboscript_tests/compile/testrunonce/testrunonce_p1.ks b/kerboscript_tests/compile/testrunonce/testrunonce_p1.ks new file mode 100644 index 000000000..0d8976d5d --- /dev/null +++ b/kerboscript_tests/compile/testrunonce/testrunonce_p1.ks @@ -0,0 +1,20 @@ +// Outermost level of testing the run-once system: + +print "Testing run without 'once' to ensure backward compatibility.". + +print "running lib1 and lib2 first time.". +run testrunonce_lib1. +run testrunonce_lib2("dummy arg"). + +print "Testing that the funcs exist:". +print "lib1 function returns: " + lib1(). +print "lib2 function returns: " + lib2(). + +print "running lib1 and lib2 second time.". +print "Next lines SHOULD print 'MAINLINE CODE' as it runs the libs.". +run testrunonce_lib1. +run testrunonce_lib2("dummy arg"). + +print "Testing that the funcs still exist:". +print "lib1 function returns: " + lib1(). +print "lib2 function returns: " + lib2(). diff --git a/kerboscript_tests/compile/testrunonce/testrunonce_p2.ks b/kerboscript_tests/compile/testrunonce/testrunonce_p2.ks new file mode 100644 index 000000000..d216223c1 --- /dev/null +++ b/kerboscript_tests/compile/testrunonce/testrunonce_p2.ks @@ -0,0 +1,23 @@ +// Outermost level of testing the run-once system: + +print "Testing run with 'once' to test new functionality.". + +print "running lib1 and lib2 first time.". +run once testrunonce_lib1. +run once testrunonce_lib2("dummy"). + +print "Testing that the funcs exist:". +print "lib1 function returns: " + lib1(). +print "lib2 function returns: " + lib2(). + +print "running lib1 and lib2 second time.". +print "Next line should NOT print 'MAINLINE CODE IS RUNNING.". +run once testrunonce_lib1. +run once testrunonce_lib2("dummy"). + +print "Testing that the funcs still exist:". +print "lib1 function returns: " + lib1(). +print "lib2 function returns: " + lib2(). + + + diff --git a/kerboscript_tests/compile/testrunonce/testrunonce_p3.ks b/kerboscript_tests/compile/testrunonce/testrunonce_p3.ks new file mode 100644 index 000000000..a6a87dbca --- /dev/null +++ b/kerboscript_tests/compile/testrunonce/testrunonce_p3.ks @@ -0,0 +1,38 @@ +// Outermost level of testing the run-once system: + +print "Testing run with a mix of 'once' and not 'once':". + +print "running lib1 and lib2 first time.". +run once testrunonce_lib1. // should have no effect since its the first time. +run testrunonce_lib2("dummy"). + +print "Testing that the funcs exist:". +print "lib1 function returns: " + lib1(). +print "lib2 function returns: " + lib2(). + +print "running lib1 and lib2 second time with 'once'". +print "Next lines should NOT print 'MAINLINE CODE' as it runs the libs.". +run once testrunonce_lib1. +run once testrunonce_lib2("dummy"). + +print "Testing that the funcs still exist:". +print "lib1 function returns: " + lib1(). +print "lib2 function returns: " + lib2(). + +print "running lib1 and lib2 second time without 'once'.". +print "Next lines SHOULD print 'MAINLINE CODE' as it runs the libs.". +run testrunonce_lib1. +run testrunonce_lib2("dummy"). + +print "Testing that the funcs still exist:". +print "lib1 function returns: " + lib1(). +print "lib2 function returns: " + lib2(). + +print "running lib1 and lib2 third time with 'once'.". +print "Next lines should NOT print 'MAINLINE CODE' as it runs the libs.". +run once testrunonce_lib1. +run once testrunonce_lib2("dummy"). + +print "Testing that the funcs still exist:". +print "lib1 function returns: " + lib1(). +print "lib2 function returns: " + lib2(). diff --git a/kerboscript_tests/cooked_steering/testwheelsteertypes1.ks b/kerboscript_tests/cooked_steering/testwheelsteertypes1.ks new file mode 100644 index 000000000..534cf14b1 --- /dev/null +++ b/kerboscript_tests/cooked_steering/testwheelsteertypes1.ks @@ -0,0 +1,79 @@ +print "This needs to be run on a rover, on ground at KSC". +print " ". +print "-------------------------------------------------". + +brakes off. +print "going north by integer compass heading 0". +lock wheelsteering to 0. +lock wheelthrottle to 1.0. +wait 3. +lock wheelthrottle to 0.5. +wait 7. +brakes on. +print "stopping". +wait 5. + +print "going westish by float compass heading 270.5". +brakes off. +lock wheelsteering to 270.5. +lock wheelthrottle to 1.0. +wait 3. +lock wheelthrottle to 0.5. +wait 7. +lock wheelthrottle to 0. +brakes on. +print "stopping". +wait 5. + +print "going south by integer compass heading 180". +brakes off. +lock wheelsteering to 180. +lock wheelthrottle to 1.0. +wait 3. +lock wheelthrottle to 0.5. +wait 7. +lock wheelthrottle to 0. +brakes on. +print "stopping". +wait 5. + +print "going east by integer compass heading 90". +brakes off. +lock wheelsteering to 90. +lock wheelthrottle to 1.0. +wait 3. +lock wheelthrottle to 0.5. +wait 7. +lock wheelthrottle to 0. +brakes on. +print "stopping". +wait 5. + +print "going south again, now by float compass heading 180.1". +brakes off. +lock wheelsteering to 180.1. +lock wheelthrottle to 1.0. +wait 3. +lock wheelthrottle to 0.5. +wait 7. +lock wheelthrottle to 0. +brakes on. +print "stopping". +wait 5. + +print "Going toward a LATLNG position that is southeast of here". +set newlat to latitude + 1. +set newlng to longitude + 1. +brakes off. +lock wheelsteering to LATLNG(newlat,newlng). +lock wheelthrottle to 1.0. +wait 3. +lock wheelthrottle to 0.5. +wait 7. +lock wheelthrottle to 0. +brakes on. +print "stopping". +wait 5. + + +print "okay that's enough. done testing". diff --git a/kerboscript_tests/declaration/definedtest.ks b/kerboscript_tests/declaration/definedtest.ks new file mode 100644 index 000000000..310157c87 --- /dev/null +++ b/kerboscript_tests/declaration/definedtest.ks @@ -0,0 +1,55 @@ +// Tests the defined operator. +print "Because this test uses globals, it is vital that it only be run". +print "after a TOGGLE POWER has guaranteed the globals are cleared". + +print "Testing the defined operator.". +print " 1: Should say False: " + (defined var1). +set var1 to 0. +print " 2: Should say True: " + (defined var1). +print " 3: Should say False: " + (defined var2). +local var2 is 0. +print " 4: Should say True: " + (defined var2). + +// test with nest: +function nesttest { + local nesttest_1 is 0. + + function nesttest_inner { + local nesttest_inner_1 is 0. + + print " 9: Should say True: " + defined nesttest_1. + print "10: Should say True: " + defined nesttest_inner_1. + } + + print " 7: Should say True: " + defined nesttest_1. + print " 8: Should say False: " + defined nesttest_inner_1. + + nesttest_inner(). +} + +// Can't see these from outside the function: +print " 5: Should say False: " + defined nesttest_1. +print " 6: Should say False: " + defined nesttest_inner_1. + +nesttest(). + +// Test other kinds of braces besides functions: +if true { + local truebrace_1 is 0. + + print "11: Should say True: " + defined truebrace_1. + + until truebrace_1 > 0 { + local loopbrace_1 is 0. + + print "12: Should say True: " + defined loopbrace_1. + + set truebrace_1 to 1. // make it get out of the until loop. + } + + print "13: Should say False: " + defined loopbrace_1. +} + +// Can't see from outside the if braces: +print "14: Should say False: " + defined truebrace_1. +print "15: Should say False: " + defined loopbrace_1. diff --git a/kerboscript_tests/delegates/delegatetest1.ks b/kerboscript_tests/delegates/delegatetest1.ks new file mode 100644 index 000000000..49ee95621 --- /dev/null +++ b/kerboscript_tests/delegates/delegatetest1.ks @@ -0,0 +1,32 @@ +print "ship vel = " + ship:velocity:orbit:mag(). + +function foo { + print " -- proof I am in foo.". +} + +function bar { + parameter a, b, c. + + print " -- proof I am in bar("+a+", "+b+", "+c+")". + return a+b+c. +} + +print "== calling foo normally ==". +foo(). +print "== getting a delegate of foo ==". +set foo_ref to foo@. +print "== calling the delegate of foo ==". +foo_ref:call(). + +print "== calling bar normally ==". +set sum to bar(1,2,3). +print "bar returned " + sum. +print "== calling bar through a delegate ==". +set bar_ref to bar@. +set refsum to bar_ref:call(1,2,3). +print "bar via a ref returned " + refsum + " which should be 6". +print "== getting a bound curry of bar delegate ==". +set bar_bound to bar_ref:bind(1,2). +print "== calling bar through bound curry ==". +set refsum to bar_bound:call(3). +print "bar via a bound curry returned " + refsum + " which should be 6". diff --git a/kerboscript_tests/delegates/delegatetest2.ks b/kerboscript_tests/delegates/delegatetest2.ks new file mode 100644 index 000000000..affa9e3eb --- /dev/null +++ b/kerboscript_tests/delegates/delegatetest2.ks @@ -0,0 +1,32 @@ +function map { + parameter operation, itemlist. + local results is list(). + for item in itemlist { + results:add(operation:call(item)). + } + return results. +} + +function square { + parameter x. return x * x. +} + +print "== ensuring delegates as arguments ==". +set map_delegate to map@. +set square_list to map_delegate:bind(square@). +print " — squares of list(1,2,3) are " + square_list:call(list(1,2,3)). + +function make_greeter { + parameter name. + function greet { + parameter name_to_greet. + print " — proof Hello, " + name_to_greet + ". I'm " + name. + } + return greet@. +} + +print "== ensuring delegates as return values ==". +set my_greeter to make_greeter("Jebediah Kerman"). +my_greeter:call("Brave kOS Dev"). +print "== ensuring returned-delegates with immediate execution ==". +make_greeter("Bill Kerman"):call("Brave kOS Dev"). diff --git a/kerboscript_tests/delegates/delegatetest3.ks b/kerboscript_tests/delegates/delegatetest3.ks new file mode 100644 index 000000000..75d9c0aac --- /dev/null +++ b/kerboscript_tests/delegates/delegatetest3.ks @@ -0,0 +1,16 @@ +print "Testing a parent program that runs a child program". +print "making delegates that the parent tries calling.". + +{ + // Hide the parent delegate + function triple { parameter i. return i * 3. } + function announce { parameter i. print " -- Announcing " + i. } + + print "== Pass delegate to child, receieve delegate back ==". + run delegatetest3_lib.ks(triple@, true). + print " -- Ensure list(6,9,12) " + mapper_result:call(list(2,3,4)). + + print "== Allow delegate to run in child context". + print " -- Ensure announced: 2, 3, 4 on next line:". + run delegatetest3_lib.ks(announce@, false). +} diff --git a/kerboscript_tests/delegates/delegatetest3_lib.ks b/kerboscript_tests/delegates/delegatetest3_lib.ks new file mode 100644 index 000000000..01cab1816 --- /dev/null +++ b/kerboscript_tests/delegates/delegatetest3_lib.ks @@ -0,0 +1,31 @@ + +parameter op, yield_results. + +function make_mapper { + function map { + parameter operation, collection. + local result is list(). + for item in collection result:add(operation:call(item)). + return result. + } + return map@. +} + +function make_eacher { + function for_each { + parameter operation, collection. + for item in collection { + operation:call(item). + } + } + return for_each@. +} + +if yield_results { + global mapper_result is make_mapper():bind(op). +} else { + global mapper_result is make_eacher():bind(op). + mapper_result:call(list(2,3,4)). +} + + diff --git a/kerboscript_tests/delegates/delegatetest4.ks b/kerboscript_tests/delegates/delegatetest4.ks new file mode 100644 index 000000000..1e3db5a10 --- /dev/null +++ b/kerboscript_tests/delegates/delegatetest4.ks @@ -0,0 +1,48 @@ +print "This is a test that delegates can be". +print "called from steeringmanager context.". +print " ". +print "This must be run from a new vessel on launchpad". +print " ". +print "Creating deeply nested delegate function...". +function outer { + parameter outerParam. + + function middle { + local twenty is 20. + + function inner { + parameter addMore. + local fifteen is 15. + + // Proof that it is seeing all the nested local vars + // when calculating the angle: + return addMore + twenty + fifteen. + } + return inner@. + } + return middle:bind(outerParam). +} + +print "launch in 3...". +wait 1. +print "launch in 2...". +wait 1. +print "launch in 1...". +wait 1. +print "If it succeeds, you should see the craft taking off". +print "with its steering locked to heading(90,45).". +print "if it's going some other direction, it didn't work.". + +print "steering by delegate: ". +print " " + outer(10). +print "which evals to " + outer(10):call(). + +lock steering to heading(90,outer(10):call() ). +lock throttle to 1. +until maxthrust > 0 { stage. wait 0.2. } + + +print "Press control-C to abort, then you'll need to revert flight". + +wait until false. + diff --git a/kerboscript_tests/delegates/delegatetest5.ks b/kerboscript_tests/delegates/delegatetest5.ks new file mode 100644 index 000000000..97f337f90 --- /dev/null +++ b/kerboscript_tests/delegates/delegatetest5.ks @@ -0,0 +1,26 @@ +print "Testing an array of delegates.". + +function f1 { parameter a,b. return a+b. } + +local f1_curry1 is f1@:bind(1). +local f1_curry2 is f1_curry1:bind(2). +local mod_del is mod@:bind(8,5). // testing a delegate of a built-in too. + +local func_arr is LIST(f1@, f1_curry1, f1_curry2, mod_del). + +print "Array of functions is:". + +print "--- func_arr[0] -----". +print func_arr[0]. +print "--- func_arr[1] -----". +print func_arr[1]. +print "--- func_arr[2] -----". +print func_arr[2]. +print "--- func_arr[3] -----". +print func_arr[3]. + +print "Calling them. These should all print 3:". +print "calling func_arr[0](1,2) returns " + func_arr[0](1,2). +print "calling func_arr[1](2) returns " + func_arr[1](2). +print "calling func_arr[2]() returns " + func_arr[2](). +print "calling func_arr[3]() returns " + func_arr[3](). diff --git a/kerboscript_tests/demo/testrefvec.ks b/kerboscript_tests/demo/testrefvec.ks new file mode 100644 index 000000000..8cfe6cce9 --- /dev/null +++ b/kerboscript_tests/demo/testrefvec.ks @@ -0,0 +1,31 @@ +// A small sample script to demonstrate the reference vector +// idea. + +clearscreen. +print "Solar Prime Vector demo.". +print " ". +print "Use time-warp to watch things change.". +print "press action group 1 to quit.". + +set refdraw to vecdraw(). +set refdraw:color to white. +set refdraw:label to "SolarPrimeVector". +set refdraw:show to true. +set zerodraw to vecdraw(). +set zerodraw:color to yellow. +set zerodraw:label to ship:body:name + "'s zero meridian". +set zerodraw:show to true. + +until ag1 { + set refdraw:start to ship:body:position. + set zerodraw:start to ship:body:position. + set refdraw:vec to 2500000*SOLARPRIMEVECTOR. + set zerodraw:vec to 4*(latlng(0,0):position - ship:body:position). + print ship:body:name + + ":ROTATIONANGLE = " + + round(ship:body:rotationangle,2) + " deg " + at (0,1). +}. + +set refdraw to 0. +set zerodraw to 0. diff --git a/kerboscript_tests/functest28.ks b/kerboscript_tests/functest28.ks new file mode 100644 index 000000000..86bb6a845 --- /dev/null +++ b/kerboscript_tests/functest28.ks @@ -0,0 +1,11 @@ +function wants_three_args { + parameter p1, p2, p3. + + print "args were: " + p1 + ", " + p2 + ", " + p3. +}. + +print "Testing function call with too few args.". +print "You should expect an error when this runs.". +print " ". + +wants_three_args("arg1", "arg2" ). // missing arg3. diff --git a/kerboscript_tests/functest29.ks b/kerboscript_tests/functest29.ks new file mode 100644 index 000000000..fb34abe0a --- /dev/null +++ b/kerboscript_tests/functest29.ks @@ -0,0 +1,11 @@ +function wants_three_args { + parameter p1, p2, p3. + + print "args were: " + p1 + ", " + p2 + ", " + p3. +}. + +print "Testing function call with too many args.". +print "You should expect an error when this runs.". +print " ". + +wants_three_args("arg1", "arg2", "arg3", "arg4" ). // arg4 uncalled for. diff --git a/kerboscript_tests/functest30.ks b/kerboscript_tests/functest30.ks new file mode 100644 index 000000000..a1d15ebe7 --- /dev/null +++ b/kerboscript_tests/functest30.ks @@ -0,0 +1,8 @@ +print "Testing the case of a RUN in a loop.". + +set i to 1. +until i > 4 { + print "Iteration " + i. + run functest30_inner(i). + set i to i + 1. +} diff --git a/kerboscript_tests/functest30_inner.ks b/kerboscript_tests/functest30_inner.ks new file mode 100644 index 000000000..c7c145281 --- /dev/null +++ b/kerboscript_tests/functest30_inner.ks @@ -0,0 +1,3 @@ +declare parameter p1. + +print "functest31_inner here: I was called with arg: " + p1. diff --git a/kerboscript_tests/functest31.ks b/kerboscript_tests/functest31.ks new file mode 100644 index 000000000..076b7d22f --- /dev/null +++ b/kerboscript_tests/functest31.ks @@ -0,0 +1,38 @@ +// +// I am not too sure if this is a feature we want to advertise yet, +// but it does seem to be doable: +// +print "Testing varying args logic". + +// A function that accepts varying args. +// the first arg is a number: how many more args to expect. +// the rest of the args are just printed for testing. +function print_var_args { + parameter how_many. + + // read parameters, filling a local string. + local my_string is "". + local i is 1. + until i > how_many { + parameter next_arg. + set my_string to my_string + " " + next_arg. + set i to i + 1. + } + + print my_string. +} + + +print "This test should work and print: A B C". +print_var_args(3, "A", "B", "C"). + +print "This test should work and print: 10 20 30 40 50 60". +print_var_args(6, 10, 20, 30, 40, 50, 60). + +print "This test should work and print: ". +print_var_args(0). + +print "This test should fail and complain about not enough args:". +print_var_args(5, "A", "B", "C"). // it will try to read more than I sent. + + diff --git a/kerboscript_tests/lib/testlibpid.ks b/kerboscript_tests/lib/testlibpid.ks index be9262771..1c4dcefac 100644 --- a/kerboscript_tests/lib/testlibpid.ks +++ b/kerboscript_tests/lib/testlibpid.ks @@ -39,7 +39,7 @@ declare function display_block { startCol, startRow. // define where the block of text should be positioned print round(seekAlt,2) + "m " at (startCol,startRow). - print round(alt_radar,2) + "m " at (startCol,startRow+1). + print round(alt:radar,2) + "m " at (startCol,startRow+1). print round(myth,3) + " " at (startCol,startRow+3). }. @@ -55,7 +55,7 @@ set hoverPID to pid_init( 0.05, 0.01, 0.1 ). // Kp, Ki, Kd vals. gear on. gear off. // on then off because of the weird KSP 'have to hit g twice' bug. until gear { - set myTh to pid_seek( hoverPID, seekAlt, alt_radar ). + set myTh to pid_seek( hoverPID, seekAlt, alt:radar ). display_block(18,11). wait 0.001. }. @@ -64,4 +64,3 @@ set ship:control:pilotmainthrottle to throttle. print "------------------------------". print "Releasing control back to you.". print "------------------------------". - diff --git a/kerboscript_tests/loop/fromthrottletest.ks b/kerboscript_tests/loop/fromthrottletest.ks new file mode 100644 index 000000000..651057c03 --- /dev/null +++ b/kerboscript_tests/loop/fromthrottletest.ks @@ -0,0 +1,14 @@ +print "This test from issue #1117 excercises the". +print "bug with trying to LOCK THROTTLE inside". +print "a FROM loop". +print "It should move the throttle at T -3 seconds.". +print "--------------------------------------------". +print " ". +FROM { LOCAL countdown IS 10. } UNTIL countdown = 0 STEP { SET countdown TO countdown - 1. } DO { + PRINT "T -" + countdown. + IF countdown = 3 { + print "Throttle should now become 1.". + LOCK THROTTLE TO 1.0. + } + WAIT 1. +} diff --git a/kerboscript_tests/loop/looptest1.ks b/kerboscript_tests/loop/looptest1.ks new file mode 100644 index 000000000..094d431b9 --- /dev/null +++ b/kerboscript_tests/loop/looptest1.ks @@ -0,0 +1,8 @@ +// Test of from loop syntax: + +print "Simple from loop to print from 1 to 10.". + +from {local i is 1.} until i > 10 step {set i to i+1.} do { + print i. +} +print "done". diff --git a/kerboscript_tests/loop/looptest2.ks b/kerboscript_tests/loop/looptest2.ks new file mode 100644 index 000000000..5aa441853 --- /dev/null +++ b/kerboscript_tests/loop/looptest2.ks @@ -0,0 +1,35 @@ +// Test of from loop syntax: + +doTest(). // body of test wrapped in function to prove it's local vars. + +function doTest +{ + print "Nested from loop test.". + print "Fills a 2-D array from 0,0, to 3,3, and then prints the array.". + + local arr is List(). + local count is 0. + + print "filling array:". + from {local i is 0.} until i > 3 step {set i to i+1.} do { + arr:add( list() ). + from {local j is 0.} until j > 3 step {set j to j+1.} do { + arr[i]:add( count ). + set count to count + 1. + } + } + + print "printing array:". + from {local i is 0.} until i > 3 step {set i to i+1.} do { + from {local j is 0.} until j > 3 step {set j to j+1.} do { + print "arr["+i+"]["+j+"] = " + arr[i][j]. + } + } + + print "Done, now trying something that should bomb out on purpose.". + print "proving local scope by trying to access i,j outside the loop:". + print "If the next line errors out with unknown identifier, that's CORRECT.". + print "i is " + i + ", and j is " + j. + print "SHOULD NOT GET THIS FAR.". +} + diff --git a/kerboscript_tests/loop/looptest3.ks b/kerboscript_tests/loop/looptest3.ks new file mode 100644 index 000000000..f0b5efd88 --- /dev/null +++ b/kerboscript_tests/loop/looptest3.ks @@ -0,0 +1,26 @@ +// Additional test to make sure that a from loop can access a nested and an outer function in a loop +set testValue to 0. +doTest(). + +function doTest +{ + from {local i is 0.} until i > 3 step {set i to i+1.} do { + addOnce(i). + addDouble(i). + } + + function addOnce{ + parameter addMe. + set testValue to testValue + addMe. + } +} + +function addDouble{ + parameter addMe. + set testValue to testValue + addMe * 2. +} + +if testValue <> 18 { + print "failed: testValue should be 18 and is " + testValue. +} +print "success". diff --git a/kerboscript_tests/parameters/paramtest1.ks b/kerboscript_tests/parameters/paramtest1.ks new file mode 100644 index 000000000..3c6dd9160 --- /dev/null +++ b/kerboscript_tests/parameters/paramtest1.ks @@ -0,0 +1,9 @@ +print " ". +print "Defaultable prog params.". +print "Try calling with 2, 3, and 4 args.". + +declare parameter p1, p2, p3 is sqrt(4) - 3. // an expression that evals to -1. +declare parameter p4 is -2. // a hardcoded -1, also test case where they aren't all on the same parameter statement. + +print "Parameters as seen inside program are:". +print " " + p1 + ", " + p2 + ", " + p3 + ", " + p4. diff --git a/kerboscript_tests/parameters/paramtest2.ks b/kerboscript_tests/parameters/paramtest2.ks new file mode 100644 index 000000000..d820549cd --- /dev/null +++ b/kerboscript_tests/parameters/paramtest2.ks @@ -0,0 +1,9 @@ +print " ". +print "Default params, one prog calling another.". +print " ". +print "executing RUN paramtest1(100,200).". +RUN paramtest1(100,200). +print "executing RUN paramtest1(100,200,300).". +RUN paramtest1(100,200,300). +print "executing RUN paramtest1(100,200,300,400).". +RUN paramtest1(100,200,300,400). diff --git a/kerboscript_tests/parameters/paramtest3.ks b/kerboscript_tests/parameters/paramtest3.ks new file mode 100644 index 000000000..31ac002be --- /dev/null +++ b/kerboscript_tests/parameters/paramtest3.ks @@ -0,0 +1,31 @@ +print " ". +print "Defaultable params calling functions". +print "from same program they're declared in.". +print " ". + +function needsZeroOfOne { + parameter funcParam1 is "def1". + + print "inside function, the function is seeing param:". + print " " + funcParam1. +} + +function needsTwoOfFour { + parameter funcParam1, funcParam2, funcParam3 is "def3", funcParam4 is "def4". + + print "inside function, the function is seeing params:". + print " " + funcParam1 + ", " + funcParam2 + ", " + funcParam3 + ", " + funcParam4. +} + +print "Calling needsZeroOfOne('a')". // can't embed quotes yet. +needsZeroOfOne("a"). +print "Calling needsZeroOfOne()". +needsZeroOfOne(). + +print "Calling needsTwoOfFour('a','b','c','d')". +needsTwoOfFour("a","b","c","d"). +print "Calling needsTwoOfFour('a','b','c')". +needsTwoOfFour("a","b","c"). +print "Calling needsTwoOfFour('a','b')". +needsTwoOfFour("a","b"). + diff --git a/kerboscript_tests/parameters/paramtest4.ks b/kerboscript_tests/parameters/paramtest4.ks new file mode 100644 index 000000000..442cceb0b --- /dev/null +++ b/kerboscript_tests/parameters/paramtest4.ks @@ -0,0 +1,19 @@ +print " ". +print "Defaultable params calling functions". +print "from library program.". +print " ". + +run paramtest4_lib. + +print "Calling needsZeroOfOne('a')". // can't embed quotes yet. +needsZeroOfOne("a"). +print "Calling needsZeroOfOne()". +needsZeroOfOne(). + +print "Calling needsTwoOfFour('a','b','c','d')". +needsTwoOfFour("a","b","c","d"). +print "Calling needsTwoOfFour('a','b','c')". +needsTwoOfFour("a","b","c"). +print "Calling needsTwoOfFour('a','b')". +needsTwoOfFour("a","b"). + diff --git a/kerboscript_tests/parameters/paramtest4_lib.ks b/kerboscript_tests/parameters/paramtest4_lib.ks new file mode 100644 index 000000000..bfd9769df --- /dev/null +++ b/kerboscript_tests/parameters/paramtest4_lib.ks @@ -0,0 +1,18 @@ +print " ". +print "Running Library paramtest4_lib". +print " ". + +function needsZeroOfOne { + parameter funcParam1 is "def1". + + print "inside function, the function is seeing param:". + print " " + funcParam1. +} + +function needsTwoOfFour { + parameter funcParam1, funcParam2, funcParam3 is "def3", funcParam4 is "def4". + + print "inside function, the function is seeing params:". + print " " + funcParam1 + ", " + funcParam2 + ", " + funcParam3 + ", " + funcParam4. +} + diff --git a/kerboscript_tests/parameters/paramtest5.ks b/kerboscript_tests/parameters/paramtest5.ks new file mode 100644 index 000000000..7966853a6 --- /dev/null +++ b/kerboscript_tests/parameters/paramtest5.ks @@ -0,0 +1,35 @@ +print " ". +print "Defaultable params calling nested functions". +print " ". + +function needsTwoOfFour { + parameter funcParam1, funcParam2, funcParam3 is "def3". + + // Tricky and ugly example - inner function is nested BEFORE the end of + // the parameters - to test the nested tracking of params: + + function needsZeroOfOne { + parameter funcParam1 is "inner def1". + + print " inside needsZeroOfOne". + print " the function is seeing param:". + print " " + funcParam1. + } + + parameter funcParam4 is "def4". + + print " inside needsTwoOfFour.". + print " the function is seeing these params:". + print " " + funcParam1 + ", " + funcParam2 + ", " + funcParam3 + ", " + funcParam4. + needsZeroOfOne("a"). + needsZeroOfOne(). + +} + +print "Calling needsTwoOfFour('a','b','c','d')". +needsTwoOfFour("a","b","c","d"). +print "Calling needsTwoOfFour('a','b','c')". +needsTwoOfFour("a","b","c"). +print "Calling needsTwoOfFour('a','b')". +needsTwoOfFour("a","b"). + diff --git a/kerboscript_tests/parameters/paramtest6.ks b/kerboscript_tests/parameters/paramtest6.ks new file mode 100644 index 000000000..6e080cd7e --- /dev/null +++ b/kerboscript_tests/parameters/paramtest6.ks @@ -0,0 +1,8 @@ +print " ". +print "Default params - deliberate syntax error.". +print " ". +print "You should see an error as we try to". +print "compile a program that has default". +print "parameters that aren't at the end". + +run paramtest6_error.ks. diff --git a/kerboscript_tests/parameters/paramtest6_error.ks b/kerboscript_tests/parameters/paramtest6_error.ks new file mode 100644 index 000000000..d5d81bd61 --- /dev/null +++ b/kerboscript_tests/parameters/paramtest6_error.ks @@ -0,0 +1,4 @@ + +parameter mandatory1, default1 is 0, mandatory2. + +print "will never get this far - will break on compile". diff --git a/kerboscript_tests/parameters/paramtest7.ks b/kerboscript_tests/parameters/paramtest7.ks new file mode 100644 index 000000000..06ca7c7ae --- /dev/null +++ b/kerboscript_tests/parameters/paramtest7.ks @@ -0,0 +1,8 @@ +print " ". +print "Default params - deliberate syntax error.". +print " ". +print "You should see an error as we try to". +print "compile a program that has default". +print "parameters that aren't at the end". + +run paramtest7_error.ks. diff --git a/kerboscript_tests/parameters/paramtest7_error.ks b/kerboscript_tests/parameters/paramtest7_error.ks new file mode 100644 index 000000000..a7d6668b0 --- /dev/null +++ b/kerboscript_tests/parameters/paramtest7_error.ks @@ -0,0 +1,4 @@ +function will_fail_compile { + parameter p1 is 0. + parameter p2. // not defaulted - is an error. +} diff --git a/kerboscript_tests/serialization/lexicon.ks b/kerboscript_tests/serialization/lexicon.ks new file mode 100644 index 000000000..0b511cda1 --- /dev/null +++ b/kerboscript_tests/serialization/lexicon.ks @@ -0,0 +1,65 @@ +// Serializes a lexicon with nested structures in it + +set l to lexicon(). + +l:add("key1", "stringvalue"). +l:add("0", 1). +l:add(0, 1.5). // test a key that when stringified is the same as one of the previous keys +l:add("key5", body:atm). // put in a non-serializable type, this should use object's ToString() method +l:add(kerbin, true). // serializable type as key + +set nested to lexicon(). +nested:add("nestedkey1", "value"). +l:add("nestedlexicon", nested). + +set nested_list to list(). +nested_list:add("element1"). +nested_list:add(1.2). +l:add("nestedlist", nested_list). + +set nested_stack to stack(). +nested_stack:push("test_stack"). +nested_stack:push(2). +l:add("nestedstack", nested_stack). + +set nested_queue to queue(). +nested_queue:push(1). +nested_queue:push("test_queue"). +l:add("nestedqueue", nested_queue). + +writejson(l, "lexicon.json"). + +print "--------". +print "This printout should look reasonable:". +print l:dump. + +// Reading & verification + +set read to readjson("lexicon.json"). + +print "--------". +print "These should all be 'True':". + +print read:length = 9. + +print read["key1"] = "stringvalue". +print read["0"] = 1. +print read["0"] + 1 = 2. +print read[0] = 1.5. +print read[kerbin]. +print read["key5"]:contains("BODYATMOSPHERE"). + +set l to read["nestedlexicon"]. +print l["nestedkey1"] = "value". + +set l to read["nestedlist"]. +print l[0] = "element1". +print l[1] = 1.2. + +set s to read["nestedstack"]. +print s:pop = 2. +print s:pop = "test_stack". + +set q to read["nestedqueue"]. +print q:pop = 1. +print q:pop = "test_queue". diff --git a/kerboscript_tests/serialization/list.ks b/kerboscript_tests/serialization/list.ks new file mode 100644 index 000000000..c08482863 --- /dev/null +++ b/kerboscript_tests/serialization/list.ks @@ -0,0 +1,61 @@ +// Serializes a list with nested structures in it + +set l to list(). + +l:add("stringvalue"). +l:add(1). +l:add(true). +l:add(1.5). +l:add(body:atm). // put in a non-serializable type, this should use object's ToString() method + +set nested to lexicon(). +nested:add("nestedkey1", "value"). +l:add(nested). + +set nested_list to list(). +nested_list:add("element1"). +nested_list:add(1.2). +l:add(nested_list). + +set nested_stack to stack(). +nested_stack:push("test_stack"). +nested_stack:push(2). +l:add(nested_stack). + +set nested_queue to queue(). +nested_queue:push(1). +nested_queue:push("test_queue"). +l:add(nested_queue). + +writejson(l, "list.json"). + +// Reading & verification + +set read to readjson("list.json"). + +print "These should all be 'True':". + +print read:length = 9. + +print read[0] = "stringvalue". +print read[1] = 1. +print read[1] + 1 = 2. +print read[2]. +print read[3] = 1.5. +print read[4]:contains("BODYATMOSPHERE"). + +set l to read[5]. +print l["nestedkey1"] = "value". + +set l to read[6]. +print l[0] = "element1". +print l[1] = 1.2. + +set s to read[7]. +print s:pop = 2. +print s:pop = "test_stack". + +set q to read[8]. +print q:pop = 1. +print q:pop = "test_queue". + diff --git a/kerboscript_tests/serialization/misc.ks b/kerboscript_tests/serialization/misc.ks new file mode 100644 index 000000000..7ae856683 --- /dev/null +++ b/kerboscript_tests/serialization/misc.ks @@ -0,0 +1,33 @@ +// Tests miscellaneous structures + +print "These should all be 'True':". + +// Body +writejson(kerbin, "misc.json"). +set read to readjson("misc.json"). +print read:name = "Kerbin". + +// GeoCoordinates +writejson(latlng(10,20), "misc.json"). +set read to readjson("misc.json"). +print read:lat = 10. +print read:lng = 20. + +// Timespan +set t to time. +writejson(t, "misc.json"). +set read to readjson("misc.json"). +print read:seconds = t:seconds. + +// Vector +set vec to v(1,2,3). +writejson(vec, "vector.json"). +set read to readjson("vector.json"). +print read:x = 1. +print read:y = 2. +print read:z = 3. + +// Vessel +writejson(ship, "vessel.json"). +set read to readjson("vessel.json"). +print read:name = ship:name. diff --git a/kerboscript_tests/serialization/queue.ks b/kerboscript_tests/serialization/queue.ks new file mode 100644 index 000000000..02e092d9c --- /dev/null +++ b/kerboscript_tests/serialization/queue.ks @@ -0,0 +1,60 @@ +// Serializes a queue with nested structures in it + +set q to queue(). + +q:push("stringvalue"). +q:push(1). +q:push(true). +q:push(1.5). +q:push(body:atm). // put in a non-serializable type, this should use object's ToString() method + +set nested to lexicon(). +nested:add("nestedkey1", "value"). +q:push(nested). + +set nested_list to list(). +nested_list:add("element1"). +nested_list:add(1.2). +q:push(nested_list). + +set nested_stack to stack(). +nested_stack:push("test_stack"). +nested_stack:push(2). +q:push(nested_stack). + +set nested_queue to queue(). +nested_queue:push(1). +nested_queue:push("test_queue"). +q:push(nested_queue). + +writejson(q, "queue.json"). + +// Reading & verification + +set read to readjson("queue.json"). + +print "These should all be 'True':". + +print read:length = 9. + +print read:pop = "stringvalue". +print read:pop = 1. +print read:pop. +print read:pop = 1.5. +print read:pop:contains("BODYATMOSPHERE"). + +set l to read:pop. +print l["nestedkey1"] = "value". + +set l to read:pop. +print l[0] = "element1". +print l[1] = 1.2. + +set s to read:pop. +print s:pop = 2. +print s:pop = "test_stack". + +set q to read:pop. +print q:pop = 1. +print q:pop = "test_queue". + diff --git a/kerboscript_tests/serialization/range.ks b/kerboscript_tests/serialization/range.ks new file mode 100644 index 000000000..e101b0e18 --- /dev/null +++ b/kerboscript_tests/serialization/range.ks @@ -0,0 +1,11 @@ +set r to range(1, 13, 2). + +writejson(r, "range.json"). +set read to readjson("range.json"). + +print "These should all be 'True':". + +print read:length = r:length. +print read:from = 1. +print read:to = 13. +print read:step = 2. diff --git a/kerboscript_tests/serialization/stack.ks b/kerboscript_tests/serialization/stack.ks new file mode 100644 index 000000000..4b459f53f --- /dev/null +++ b/kerboscript_tests/serialization/stack.ks @@ -0,0 +1,60 @@ +// Serializes a stack with nested structures in it + +set s to stack(). + +s:push("stringvalue"). +s:push(1). +s:push(true). +s:push(1.5). +s:push(body:atm). // put in a non-serializable type, this should use object's ToString() method + +set nested to lexicon(). +nested:add("nestedkey1", "value"). +s:push(nested). + +set nested_list to list(). +nested_list:add("element1"). +nested_list:add(1.2). +s:push(nested_list). + +set nested_stack to stack(). +nested_stack:push("test_stack"). +nested_stack:push(2). +s:push(nested_stack). + +set nested_queue to queue(). +nested_queue:push(1). +nested_queue:push("test_queue"). +s:push(nested_queue). + +writejson(s, "stack.json"). + +// Reading & verification + +set read to readjson("stack.json"). + +print "These should all be 'True':". + +print read:length = 9. + +set q to read:pop. +print q:pop = 1. +print q:pop = "test_queue". + +set s to read:pop. +print s:pop = 2. +print s:pop = "test_stack". + +set l to read:pop. +print l[0] = "element1". +print l[1] = 1.2. + +set l to read:pop. +print l["nestedkey1"] = "value". + + +print read:pop:contains("BODYATMOSPHERE"). +print read:pop = 1.5. +print read:pop. +print read:pop = 1. +print read:pop = "stringvalue". diff --git a/kerboscript_tests/string/stringtester.ks b/kerboscript_tests/string/stringtester.ks new file mode 100644 index 000000000..c327fe613 --- /dev/null +++ b/kerboscript_tests/string/stringtester.ks @@ -0,0 +1,78 @@ +CLEARSCREEN. // CORRECT OUTPUTS +SET s TO "Hello, Strings!". // --------------- +PRINT "Original String: " + s. // Hello, Strings! +PRINT "string[7]: " + s[7]. // S +PRINT "LENGTH: " + s:LENGTH. // 15 +PRINT "SUBSTRING(7, 6): " + s:SUBSTRING(7, 6). // String +PRINT "CONTAINS(''ring''): " + s:CONTAINS("ring"). // True +PRINT "CONTAINS(''bling''): " + s:CONTAINS("bling"). // False +PRINT "ENDSWITH(''ings!''): " + s:ENDSWITH("ings!"). // True +PRINT "ENDSWITH(''outs!''): " + s:ENDSWITH("outs"). // False +PRINT "FIND(''l''): " + s:FIND("l"). // 2 +PRINT "FINDLAST(''l''): " + s:FINDLAST("l"). // 3 +PRINT "FINDAT(''l'', 0): " + s:FINDAT("l", 0). // 2 +PRINT "FINDAT(''l'', 3): " + s:FINDAT("l", 3). // 3 +PRINT "FINDLASTAT(''l'', 9): " + s:FINDLASTAT("l", 9). // 3 +PRINT "FINDLASTAT(''l'', 2): " + s:FINDLASTAT("l", 2). // 2 +PRINT "INSERT(7, ''Big ''): " + s:INSERT(7, "Big "). // Hello, Big Strings! + +PRINT " ". +PRINT " |------ 18 ------|". +PRINT "PADLEFT(18): " + s:PADLEFT(18). // Hello, Strings! +PRINT "PADRIGHT(18): " + s:PADRIGHT(18). // Hello, Strings! +PRINT " ". + +PRINT "REMOVE(1, 3): " + s:REMOVE(1, 3). // Ho, Strings! +PRINT "REPLACE(''Hell'', ''Heaven''): " + s:REPLACE("Hell", "Heaven"). // Heaveno, Strings! +PRINT "STARTSWITH(''Hell''): " + s:STARTSWITH("Hell"). // True +PRINT "STARTSWITH(''Heaven''): " + s:STARTSWITH("Heaven"). // False +PRINT "TOUPPER: " + s:TOUPPER(). // HELLO, STRINGS! +PRINT "TOLOWER: " + s:TOLOWER(). // hello, strings! +PRINT " ". +PRINT "'' Hello! '':TRIM(): " + " Hello! ":TRIM(). // Hello! +PRINT "'' Hello! '':TRIMSTART(): " + " Hello! ":TRIMSTART(). // Hello! +PRINT "'' Hello! '':TRIMEND(): " + " Hello! ":TRIMEND(). // Hello! +PRINT " ". +PRINT "Chained: " + "Hello!":SUBSTRING(0, 4):TOUPPER():REPLACE("ELL", "ELEPHANT"). // HELEPHANT +function comparetest { + parameter a, b. + + // This is the correct way, but it can't be run until PR #1412 is merged: + // local qt_a is "". + // if a:istype("string") { set qt_a to CHAR(34). } + // local qt_b is "". + // if b:istype("string") { set qt_b to CHAR(34). } + // This is the less good way for now: quote everything, like it or not: + local qt_a is CHAR(34). + local qt_b is CHAR(34). + + PRINT "string compare: " + qt_a + a + qt_a + " < " + qt_b + b + qt_b + " is " + (a < b). + PRINT "string compare: " + qt_a + a + qt_a + " <= " + qt_b + b + qt_b + " is " + (a <= b). + PRINT "string compare: " + qt_a + a + qt_a + " > " + qt_b + b + qt_b + " is " + (a > b). + PRINT "string compare: " + qt_a + a + qt_a + " >= " + qt_b + b + qt_b + " is " + (a >= b). + PRINT "string compare: " + qt_a + a + qt_a + " = " + qt_b + b + qt_b + " is " + (a = b). + PRINT "string compare: " + qt_a + a + qt_a + " <> " + qt_b + b + qt_b + " is " + (a <> b). +} +SET s1_lower to "abc def". +SET s1_upper to "ABC DEF". +SET s2_lower to "abc dfe". +SET s2_upper to "ABC DFE". +PRINT "Test: differ in case only:". +comparetest(s1_lower,s1_upper). +PRINT "Test: differ in case only:". +comparetest(s2_lower,s2_upper). +PRINT "Test: left < right, same case:". +comparetest(s1_lower,s2_lower). +PRINT "Test: left < right, different case:". +comparetest(s1_lower,s2_upper). +PRINT ":::". +PRINT "Mixing types with string to make ToString compares:". +PRINT ":::". +PRINT "Test: same value, int:". +comparetest("123", 123). +PRINT "Test: same value, double:". +comparetest("123.456", 123.456). +PRINT "Test: different value, int, note string, not number compare:". +comparetest("123", 1000). +PRINT "Test: different value, double, note string, not number compare:". +comparetest("123.456", 1000.456). diff --git a/kerboscript_tests/user_functions/functest21_inner.ks b/kerboscript_tests/user_functions/functest21_inner.ks index aa11edba3..b28896b56 100644 --- a/kerboscript_tests/user_functions/functest21_inner.ks +++ b/kerboscript_tests/user_functions/functest21_inner.ks @@ -5,6 +5,6 @@ // an update tick must occur while it is running because // it executes a lot of instructions: set counter to 0. -until counter >= 5000 { +until counter >= 1000 { set counter to counter + 1. }. diff --git a/kerboscript_tests/user_functions/functest25.ks b/kerboscript_tests/user_functions/functest25.ks new file mode 100644 index 000000000..d9650f671 --- /dev/null +++ b/kerboscript_tests/user_functions/functest25.ks @@ -0,0 +1,30 @@ +// Test weird case with index nested inside suffix and visa versa. +// within SET statements. + +set a to list(1,2,3). +set endIndex to a:length()-1. + +print "This test case should NOT error out.". +print "------------------------------------". +print " ". +print "Testing nesting suffixes inside set list element:". +print "Of the list " + a + " ...". +print "the last element is currently " + a[endIndex]. +print "or also gotten another way, " + a[a:length()-1]. + +print "And now we change to 5 it one way:". +set a[endIndex] to 5. +print "And the list is now: " + a. + +print "And now we change to 10 a different way:". +set a[a:length()-1] to 10. +print "And the list is now: " + a. + +print " ". +print "Testing list element lookups inside setting suffixes:". + +set b to ship. +print "Setting ship's rootpart tagname to a new name: 'aaaa' ". +set b:parts[0]:tag to "aaaa". +print "New name is '" + b:parts[0]:tag + "'". + diff --git a/kerboscript_tests/user_functions/functest26.ks b/kerboscript_tests/user_functions/functest26.ks new file mode 100644 index 000000000..f0758262b --- /dev/null +++ b/kerboscript_tests/user_functions/functest26.ks @@ -0,0 +1,10 @@ +// Test for empty return statement: + +@lazyglobal off. +function reproduce_bug{ + return. +} +print "Testing whether or not naked return works.". +print "The next line should print zero.". +print reproduce_bug(). +print "If it got this far, it worked.". diff --git a/kerboscript_tests/user_functions/functest27.ks b/kerboscript_tests/user_functions/functest27.ks new file mode 100644 index 000000000..85da06d6d --- /dev/null +++ b/kerboscript_tests/user_functions/functest27.ks @@ -0,0 +1,14 @@ +print "running a test to see if you can call". +print "a function from inside a KSM file.". + +print "Ensuring functest27_b.ksm is deleted:". +log "" to "functest27_b.ksm". delete "functest27_b.ksm". + +print "Trying to compile functest27_b.ks to KSM file:". +compile functest27_b. +print "Now running the compiled KSM file:". +run functest27_b.ksm. +print "Now trying to call the function that was in KSM:". +print_check(). +print "If you got here without error, test passed.". + diff --git a/kerboscript_tests/user_functions/functest27_b.ks b/kerboscript_tests/user_functions/functest27_b.ks new file mode 100644 index 000000000..f7c94f8f2 --- /dev/null +++ b/kerboscript_tests/user_functions/functest27_b.ks @@ -0,0 +1,3 @@ +function print_check { + print "++ I am the function inside functest27_b.". +}. diff --git a/kerboscript_tests/user_functions/functest32.ks b/kerboscript_tests/user_functions/functest32.ks new file mode 100644 index 000000000..6b1bf7e82 --- /dev/null +++ b/kerboscript_tests/user_functions/functest32.ks @@ -0,0 +1,30 @@ +print "testing how arg count works with premature return.". + +function foo { + parameter a. + if a < 1 { + print "abort function foo, invalid arg count given". + return. + } + print "reading " + a + " args.". + from {local i is 1.} until i > a step {set i to i + 1.} do { + parameter temp. + print "arg " + i + " is " + temp. + } + + return. +} + + +foo(1,"a"). +foo(3,"a","b","c"). +print "Premature return test, with no extra args passed. Should be okay.". +foo(0). +print "Premature return test, with some extra args passed. Should be okay.". +foo(0,1,1,1). // check that premature return stmt consumes args properly. +print "Trying again after the premature return cases.". +foo(3,"aaa","bbb","ccc"). // what happens after the premature abort case? +print " ". +print "BUT, THE FOLLOWING SHOULD STILL FAIL.". +print "BECAUSE IT HAS WRONG ARGS BUT NOT A PREMATURE RETURN.". +foo(1,"a","b","c"). // will only read it up to the "a". diff --git a/src/gimp/kOS Art/kOSLogo2016.jpg b/src/gimp/kOS Art/kOSLogo2016.jpg new file mode 100644 index 000000000..6942256eb Binary files /dev/null and b/src/gimp/kOS Art/kOSLogo2016.jpg differ diff --git a/src/gimp/kOS Art/kOSLogo2016.psd b/src/gimp/kOS Art/kOSLogo2016.psd new file mode 100644 index 000000000..e807ae266 Binary files /dev/null and b/src/gimp/kOS Art/kOSLogo2016.psd differ diff --git a/src/gimp/kOS Art/kOSLogoNew_blueWoutline.jpg b/src/gimp/kOS Art/kOSLogoNew_blueWoutline.jpg new file mode 100644 index 000000000..87007a949 Binary files /dev/null and b/src/gimp/kOS Art/kOSLogoNew_blueWoutline.jpg differ diff --git a/src/gimp/kOS Art/kos logo work.psd b/src/gimp/kOS Art/kos logo work.psd new file mode 100644 index 000000000..fd9cbac2d Binary files /dev/null and b/src/gimp/kOS Art/kos logo work.psd differ diff --git a/src/gimp/kOS Art/kos logo work2.psd b/src/gimp/kOS Art/kos logo work2.psd new file mode 100644 index 000000000..11e7b0649 Binary files /dev/null and b/src/gimp/kOS Art/kos logo work2.psd differ diff --git a/src/gimp/kOS Art/kos_logo260x104.png b/src/gimp/kOS Art/kos_logo260x104.png new file mode 100644 index 000000000..fdc458c6d Binary files /dev/null and b/src/gimp/kOS Art/kos_logo260x104.png differ diff --git a/src/kOS.Safe.Test/Collections/CollectionValueTest.cs b/src/kOS.Safe.Test/Collections/CollectionValueTest.cs new file mode 100644 index 000000000..b2dd4c421 --- /dev/null +++ b/src/kOS.Safe.Test/Collections/CollectionValueTest.cs @@ -0,0 +1,21 @@ +using System; +using kOS.Safe.Encapsulation; +using NUnit.Framework; +using kOS.Safe.Encapsulation.Suffixes; +using kOS.Safe.Serialization; + +namespace kOS.Safe.Test +{ + public abstract class CollectionValueTest + { + + protected object InvokeDelegate(SerializableStructure stack, string suffixName, params object[] parameters) + { + var lengthObj = stack.GetSuffix(suffixName) as DelegateSuffixResult; + Assert.IsNotNull(lengthObj); + Assert.IsNotNull(lengthObj.Del); + return lengthObj.Del.DynamicInvoke(parameters); + } + } +} + diff --git a/src/kOS.Safe.Test/Collections/LexiconTest.cs b/src/kOS.Safe.Test/Collections/LexiconTest.cs new file mode 100644 index 000000000..6f6f9c968 --- /dev/null +++ b/src/kOS.Safe.Test/Collections/LexiconTest.cs @@ -0,0 +1,323 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using kOS.Safe.Encapsulation; +using kOS.Safe.Encapsulation.Suffixes; +using kOS.Safe.Exceptions; +using kOS.Safe.Test.Opcode; +using NUnit.Framework; +using kOS.Safe.Serialization; + +namespace kOS.Safe.Test.Collections +{ + [TestFixture] + public class LexiconTest + { + [SetUp] + public void Setup() + { + + } + + [Test] + public void CanAddAndGetKey() + { + var lex = new Lexicon {{new StringValue("foo"), new StringValue("bar")}}; + + var testValue = lex[new StringValue("foo")]; + + Assert.AreEqual(new StringValue("bar"), testValue); + } + + [Test] + public void HasCaseInsensitiveKeys() + { + var lex = new Lexicon {{new StringValue("foo"), new StringValue("bar")}}; + + Assert.AreEqual(new StringValue("bar"), lex[new StringValue("FOO")]); + } + + [Test] + public void HashHitOnEqualValues() + { + var lex = new Lexicon {{ScalarDoubleValue.MaxValue(), new StringValue("bar")}}; + + Assert.AreEqual(new StringValue("bar"), lex[ScalarDoubleValue.MaxValue()]); + } + + [Test] + [ExpectedException(typeof(KOSKeyNotFoundException))] + public void HashMissOnDifferentValues() + { + var lex = new Lexicon {{ScalarDoubleValue.MinValue(), new StringValue("bar")}}; + + Assert.AreNotEqual("bar", lex[ScalarDoubleValue.MaxValue()]); + } + + [Test] + public void ContainsReturnsTrueIfTheKeyIsPresent() + { + var lex = new Lexicon {{ScalarDoubleValue.MinValue(), new StringValue("bar")}}; + + Assert.IsTrue(lex.ContainsKey(ScalarDoubleValue.MinValue())); + } + + [Test] + public void ContainsReturnsFalseIfTheKeyIsMissing() + { + var lex = new Lexicon {{ScalarDoubleValue.MinValue(), new StringValue("bar")}}; + + Assert.IsFalse(lex.ContainsKey(ScalarDoubleValue.MaxValue())); + } + + [Test] + public void CanRemoveKeyOfDifferentCase() + { + var lex = new Lexicon {{new StringValue("foo"), new StringValue("bar")}}; + + Assert.AreEqual(1, lex.Count); + + lex.Remove(new StringValue("foo")); + Assert.AreEqual(0, lex.Count); + + lex.Add(new StringValue("foo"), new StringValue("bar")); + Assert.AreEqual(1, lex.Count); + + lex.Remove(new StringValue("FOO")); + Assert.AreEqual(0, lex.Count); + + lex.Add(new StringValue("foo"), new StringValue("bar")); + Assert.AreEqual(1, lex.Count); + + lex.Remove(new StringValue("Foo")); + Assert.AreEqual(0, lex.Count); + } + + [Test] + public void DoesNotErrorOnRemoveNullKey() + { + var lex = new Lexicon(); + lex.Remove(new StringValue("foo")); + } + + [Test] + public void CanSetNewIndex() + { + var lex = new Lexicon(); + lex[new StringValue("foo")] = new StringValue("bang"); + + Assert.AreEqual(1, lex.Count); + } + + [Test] + public void CanSetAndGetIndex() + { + var lex = new Lexicon(); + lex.SetIndex(new StringValue("fizz"), new StringValue("bang")); + var value = lex.GetIndex(new StringValue("fizz")); + + Assert.AreEqual(new StringValue("bang"), value); + } + + [Test] + [ExpectedException(typeof(KOSKeyNotFoundException))] + public void ErrorsOnGetEmptyKey() + { + var lex = new Lexicon(); + var val = lex[new StringValue("fizz")]; + } + + [Test] + public void CanDumpLexicon() + { + var map = MakeNestedExample(); + + var result = (StringValue)InvokeDelegate(map, "DUMP"); + + //TODO: build Asserts + } + + [Test] + public void CanPrintLexicon() + { + var map = MakeNestedExample(); + + string result = map.ToString(); + + //TODO: build Asserts + } + + [Test] + public void CanFindExistingKey() + { + var map = MakeNestedExample(); + + var hasKeyFirst = (BooleanValue)InvokeDelegate(map, "HASKEY" , new StringValue("first")); + Assert.IsTrue(hasKeyFirst); + var hasKeySecond = (BooleanValue)InvokeDelegate(map, "HASKEY" , new StringValue("second")); + Assert.IsTrue(hasKeySecond); + var hasKeyLast = (BooleanValue)InvokeDelegate(map, "HASKEY" , new StringValue("second")); + Assert.IsTrue(hasKeyLast); + } + + [Test] + public void CantFindMissingKey() + { + var map = MakeNestedExample(); + + var hasKeyFirst = (BooleanValue)InvokeDelegate(map, "HASKEY" , new StringValue("2")); + Assert.IsFalse(hasKeyFirst); + var hasKeySecond = (BooleanValue)InvokeDelegate(map, "HASKEY" , new StringValue("3")); + Assert.IsFalse(hasKeySecond); + var hasKeyLast = (BooleanValue)InvokeDelegate(map, "HASKEY" , new StringValue("testing")); + Assert.IsFalse(hasKeyLast); + } + + [Test] + public void CanFindExistingValue() + { + var map = MakeNestedExample(); + + var hasKeyFirst = (BooleanValue)InvokeDelegate(map, "HASVALUE" , new ScalarIntValue(100)); + Assert.IsTrue(hasKeyFirst); + var hasKeySecond = (BooleanValue)InvokeDelegate(map, "HASVALUE" , new ScalarIntValue(200)); + Assert.IsTrue(hasKeySecond); + var hasKeyLast = (BooleanValue)InvokeDelegate(map, "HASVALUE" , new StringValue("String, outer value")); + Assert.IsTrue(hasKeyLast); + } + + [Test] + public void CantFindMissingValue() + { + var map = MakeNestedExample(); + + var hasKeyFirst = (BooleanValue)InvokeDelegate(map, "HASVALUE" , new StringValue("2")); + Assert.IsFalse(hasKeyFirst); + var hasKeySecond = (BooleanValue)InvokeDelegate(map, "HASVALUE" , new StringValue("3")); + Assert.IsFalse(hasKeySecond); + var hasKeyLast = (BooleanValue)InvokeDelegate(map, "HASVALUE" , new StringValue("testing")); + Assert.IsFalse(hasKeyLast); + } + + [Test] + public void CopyGetsCollectionOfSameType() + { + var map = MakeNestedExample(); + + var mapCopy = InvokeDelegate(map, "COPY"); + + Assert.AreEqual(map.GetType(), mapCopy.GetType()); + } + + [Test] + public void CopyIsDifferentObject() + { + var map = MakeNestedExample(); + var mapCopy = (SerializableStructure)InvokeDelegate(map, "COPY"); + + + var hasKeyFirst = (BooleanValue)InvokeDelegate(map, "HASKEY" , new StringValue("first")); + Assert.IsTrue(hasKeyFirst); + InvokeDelegate(map, "REMOVE" , new StringValue("first")); + var hasKeyFirstAfterRemove = (BooleanValue)InvokeDelegate(map, "HASKEY" , new StringValue("first")); + Assert.IsFalse(hasKeyFirstAfterRemove); + + var copyHasKeyFirstAfterRemove = (BooleanValue)InvokeDelegate(mapCopy, "HASKEY" , new StringValue("first")); + Assert.IsTrue(copyHasKeyFirstAfterRemove); + + } + + [Test] + public void CanFormatNumericKeys() + { + var map = MakeNestedExample(); + + var hasKeyInner = (BooleanValue)InvokeDelegate(map, "HASKEY" , new StringValue("inner")); + Assert.IsTrue(hasKeyInner); + + var inner = (Lexicon) ((Lexicon)map)[new StringValue("inner")]; + Assert.IsNotNull(inner); + + var hasNumericKey = (BooleanValue)InvokeDelegate(inner, "HASKEY" , new ScalarIntValue(3)); + Assert.IsTrue(hasNumericKey); + + var innerString = inner.ToString(); + + Assert.IsTrue(innerString.Contains("[\"2\"]")); + Assert.IsTrue(innerString.Contains("[3]")); + } + + [Test] + public void CanClearOnCaseChange() + { + var map = MakeNestedExample(); + + var length = (ScalarIntValue)InvokeDelegate(map, "LENGTH"); + + Assert.IsTrue(length > 0); + + map.SetSuffix("CASESENSITIVE", BooleanValue.True); + + length = (ScalarIntValue)InvokeDelegate(map, "LENGTH"); + Assert.IsTrue(length == 0); + + InvokeDelegate(map,"ADD", new StringValue("first"), new ScalarIntValue(100)); + + length = (ScalarIntValue)InvokeDelegate(map, "LENGTH"); + Assert.IsTrue(length > 0); + + map.SetSuffix("CASESENSITIVE", BooleanValue.False); + + length = (ScalarIntValue)InvokeDelegate(map, "LENGTH"); + Assert.IsTrue(length == 0); + } + + private SerializableStructure MakeNestedExample() + { + const string OUTER_STRING = "String, outer value"; + + var map = new Lexicon(); + var innerMap1 = new Lexicon(); + var innerMap2 = new Lexicon(); + var innerInnerMap = new Lexicon + { + {new StringValue("inner"), new StringValue("inner string 1")}, + {new ScalarIntValue(2), new ScalarIntValue(2)} + }; + + innerMap1.Add(new StringValue("map"), innerInnerMap); + innerMap1.Add(new StringValue("2"), new StringValue("string,one.two")); + innerMap1.Add(new ScalarIntValue(3), new StringValue("string,one.three")); + + innerMap2.Add(new StringValue("testing"), new StringValue("string,two.one") ); + innerMap2.Add(new StringValue("2"), new StringValue("string,two.two") ); + + InvokeDelegate(map,"ADD", new StringValue("first"), new ScalarIntValue(100)); + InvokeDelegate(map,"ADD", new StringValue("second"), new ScalarIntValue(200)); + InvokeDelegate(map,"ADD", new StringValue("inner"), innerMap1); + InvokeDelegate(map,"ADD", new StringValue("inner2"), innerMap2); + InvokeDelegate(map,"ADD", new StringValue("last"), new StringValue(OUTER_STRING)); + + return map; + } + + private Encapsulation.Structure InvokeDelegate(ISuffixed map, string suffixName, params Encapsulation.Structure[] parameters) + { + ISuffixResult lengthResult = map.GetSuffix(suffixName); + Assert.IsNotNull(lengthResult); + + if (!lengthResult.HasValue) + { + var delegateResult = lengthResult as DelegateSuffixResult; + if (delegateResult != null) + { + var temp = delegateResult.Del.DynamicInvoke(parameters); + + return temp as Encapsulation.Structure; + } + } + + return lengthResult.Value; + } + } +} diff --git a/src/kOS.Safe.Test/Collections/ListValueTest.cs b/src/kOS.Safe.Test/Collections/ListValueTest.cs new file mode 100644 index 000000000..10f88cb7a --- /dev/null +++ b/src/kOS.Safe.Test/Collections/ListValueTest.cs @@ -0,0 +1,225 @@ +using System; +using System.Collections.Generic; +using kOS.Safe.Encapsulation; +using kOS.Safe.Encapsulation.Suffixes; +using kOS.Safe.Execution; +using kOS.Safe.Test.Opcode; +using NUnit.Framework; +using kOS.Safe.Serialization; + +namespace kOS.Safe.Test.Collections +{ + [TestFixture] + public class ListValueTest : CollectionValueTest + { + [Test] + public void CanCreate() + { + var list = new ListValue(); + Assert.IsNotNull(list); + } + + [Test] + public void CanAddItem() + { + var list = new ListValue(); + Assert.IsNotNull(list); + var length = InvokeDelegate(list, "LENGTH"); + Assert.AreEqual(ScalarIntValue.Zero, length); + + InvokeDelegate(list, "ADD", ScalarIntValue.Zero); + + length = InvokeDelegate(list, "LENGTH"); + Assert.AreEqual(ScalarIntValue.One, length); + } + + [Test] + public void CanClear() + { + var list = new ListValue(); + + InvokeDelegate(list, "ADD", ScalarIntValue.Zero); + InvokeDelegate(list, "ADD", ScalarIntValue.Zero); + + var length = InvokeDelegate(list, "LENGTH"); + Assert.AreEqual(ScalarIntValue.Two,length); + InvokeDelegate(list, "CLEAR"); + length = InvokeDelegate(list, "LENGTH"); + Assert.AreEqual(ScalarIntValue.Zero,length); + } + + [Test] + public void CanGetIndex() + { + var list = new ListValue(); + + var zedObject = ScalarIntValue.Zero; + InvokeDelegate(list, "ADD", zedObject); + var firstObject = ScalarIntValue.One; + InvokeDelegate(list, "ADD", firstObject); + var secondObject = ScalarIntValue.Two; + InvokeDelegate(list, "ADD", secondObject); + var thirdObject = new ScalarIntValue(4); + InvokeDelegate(list, "ADD", thirdObject); + + var length = InvokeDelegate(list, "LENGTH"); + Assert.AreEqual(new ScalarIntValue(4),length); + + Assert.AreSame(zedObject, list[0]); + Assert.AreSame(firstObject, list[1]); + Assert.AreSame(secondObject, list[2]); + Assert.AreSame(thirdObject, list[3]); + Assert.AreNotSame(list[0], list[1]); + Assert.AreNotSame(list[0], list[2]); + Assert.AreNotSame(list[0], list[3]); + Assert.AreNotSame(list[1], list[2]); + Assert.AreNotSame(list[1], list[3]); + Assert.AreNotSame(list[2], list[3]); + } + + [Test] + public void CopyIsACopy() + { + var list = new ListValue(); + + var zedObject = ScalarIntValue.Zero; + InvokeDelegate(list, "ADD", zedObject); + var firstObject = ScalarIntValue.One; + InvokeDelegate(list, "ADD", firstObject); + var secondObject = ScalarIntValue.Two; + InvokeDelegate(list, "ADD", secondObject); + var thirdObject = new ScalarIntValue(4); + InvokeDelegate(list, "ADD", thirdObject); + + var length = InvokeDelegate(list, "LENGTH"); + Assert.AreEqual(new ScalarIntValue(4), length); + + var copy = InvokeDelegate(list, "COPY") as ListValue; + Assert.AreNotSame(list, copy); + + var copyLength = InvokeDelegate(copy, "LENGTH"); + Assert.AreEqual(new ScalarIntValue(4), copyLength); + + InvokeDelegate(copy, "CLEAR"); + + copyLength = InvokeDelegate(copy, "LENGTH"); + Assert.AreEqual(ScalarIntValue.Zero, copyLength); + + length = InvokeDelegate(list, "LENGTH"); + Assert.AreEqual(new ScalarIntValue(4), length); + } + + [Test] + public void CanTestContains() + { + var list = new ListValue(); + + var zedObject = ScalarIntValue.Zero; + InvokeDelegate(list, "ADD", zedObject); + var firstObject = ScalarIntValue.One; + InvokeDelegate(list, "ADD", firstObject); + var secondObject = ScalarIntValue.Two; + var thirdObject = new ScalarIntValue(4); + + var length = InvokeDelegate(list, "LENGTH"); + Assert.AreEqual(ScalarIntValue.Two, length); + + + Assert.IsTrue((BooleanValue)InvokeDelegate(list, "CONTAINS", zedObject)); + Assert.IsTrue((BooleanValue)InvokeDelegate(list, "CONTAINS", firstObject)); + Assert.IsFalse((BooleanValue)InvokeDelegate(list, "CONTAINS", secondObject)); + Assert.IsFalse((BooleanValue)InvokeDelegate(list, "CONTAINS", thirdObject)); + } + + /// + /// Creates a complex example of a nested list of lists and other + /// things, to use in some of the tests to prove complex example cases. + /// Returns a list that looks like so: + ///
+        /// list {
+        ///     100,
+        ///     200,
+        ///     list {
+        ///         list {
+        ///             "inner string 1",
+        ///             2
+        ///         },
+        ///         "string,one.two",
+        ///         "string,one.three"
+        ///     },
+        ///     list {
+        ///         "string,two.one",
+        ///         "string,two.two"
+        ///     },
+        ///     "String, outer value"
+        /// }
+        /// 
+ /// This should be sufficiently complex to work with for testing a variety of cases. + /// + ///
+ /// A list containing the description above + private ListValue MakeNestedExample() + { + const string OUTER_STRING = "String, outer value"; + + ListValue list = new ListValue(); + ListValue innerList1 = new ListValue(); + ListValue innerList2 = new ListValue(); + ListValue innerInnerList = new ListValue + { + new StringValue("inner string 1"), + new ScalarIntValue(2) + }; + + + innerList1.Add( innerInnerList ); + innerList1.Add( new StringValue("string,one.two") ); + innerList1.Add( new StringValue("string,one.three") ); + + innerList2.Add( new StringValue("string,two.one") ); + innerList2.Add( new StringValue("string,two.two") ); + + InvokeDelegate(list,"ADD", new ScalarIntValue(100)); + InvokeDelegate(list,"ADD", new ScalarIntValue(200)); + InvokeDelegate(list,"ADD", innerList1); + InvokeDelegate(list,"ADD", innerList2); + InvokeDelegate(list,"ADD", OUTER_STRING); + + return list; + } + + [Test] + public void EachListConstructor() + { + var cpu = new FakeCpu(); + cpu.PushStack(new KOSArgMarkerType()); + + var baseList = new ListValue(); + var baseDelegate = baseList.GetSuffix("LENGTH"); + cpu.PushStack(null); // dummy push to be popped by ReverseStackArgs + cpu.PushStack(new KOSArgMarkerType()); + baseDelegate.Invoke(cpu); + Assert.AreEqual(ScalarIntValue.Zero, baseDelegate.Value); + + var castList = ListValue.CreateList(new List()); + var castDelegate = castList.GetSuffix("LENGTH"); + cpu.PushStack(null); // dummy push to be popped by ReverseStackArgs + cpu.PushStack(new KOSArgMarkerType()); + castDelegate.Invoke(cpu); + Assert.AreEqual(ScalarIntValue.Zero, castDelegate.Value); + + var copyDelegate = baseList.GetSuffix("COPY"); + cpu.PushStack(null); // dummy push to be popped by ReverseStackArgs + cpu.PushStack(new KOSArgMarkerType()); + copyDelegate.Invoke(cpu); + var copyList = copyDelegate.Value; + Assert.AreEqual(baseList, copyList); + + var lengthDelegate = copyList.GetSuffix("LENGTH"); + cpu.PushStack(null); // dummy push to be popped by ReverseStackArgs + cpu.PushStack(new KOSArgMarkerType()); + lengthDelegate.Invoke(cpu); + Assert.AreEqual(ScalarIntValue.Zero, lengthDelegate.Value); + } + } +} diff --git a/src/kOS.Safe.Test/Collections/MixedCollectionPrintingTest.cs b/src/kOS.Safe.Test/Collections/MixedCollectionPrintingTest.cs new file mode 100644 index 000000000..e090418fc --- /dev/null +++ b/src/kOS.Safe.Test/Collections/MixedCollectionPrintingTest.cs @@ -0,0 +1,57 @@ +using System; +using kOS.Safe.Encapsulation; +using kOS.Safe.Serialization; +using NUnit.Framework; + +namespace kOS.Safe.Test.Collections +{ + [TestFixture] + public class MixedCollectionPrintingTest : CollectionValueTest + { + + [Test] + public void CanPrintListInLexicon() + { + var list = new ListValue + { + new StringValue("First In List"), + new StringValue("Second In List"), + new StringValue("Last In List") + }; + + var lexicon = new Lexicon + { + {new StringValue("list"), list}, + {new StringValue("not list"), new ScalarIntValue(2)} + }; + + var result = (StringValue)InvokeDelegate(lexicon, "DUMP"); + + Assert.IsTrue(result.Contains("LEXICON of 2 items")); + Assert.IsTrue(result.Contains("[\"list\"] = LIST of 3 items")); + Assert.IsTrue(result.Contains("Last In List")); + } + + [Test] + public void DoesNotContainInvalidToString() + { + var list = new ListValue + { + new StringValue("First In List"), + new StringValue("Second In List"), + new StringValue("Last In List") + }; + + var lexicon = new Lexicon + { + {new StringValue("list"), list}, + {new StringValue("not list"), new ScalarIntValue(2)} + }; + + var result = (StringValue)InvokeDelegate(lexicon, "DUMP"); + + Assert.IsFalse(result.Contains("System")); + Assert.IsFalse(result.Contains("string[]")); + } + } +} diff --git a/src/kOS.Safe.Test/Collections/QueueValueTest.cs b/src/kOS.Safe.Test/Collections/QueueValueTest.cs new file mode 100644 index 000000000..3b26a0ddd --- /dev/null +++ b/src/kOS.Safe.Test/Collections/QueueValueTest.cs @@ -0,0 +1,113 @@ +using System; +using System.Collections.Generic; +using kOS.Safe.Encapsulation; +using kOS.Safe.Encapsulation.Suffixes; +using NUnit.Framework; +using kOS.Safe.Serialization; + +namespace kOS.Safe.Test.Collections +{ + [TestFixture] + public class QueueValueTest : CollectionValueTest + { + [Test] + public void CanCreate() + { + var queue = new QueueValue(); + Assert.IsNotNull(queue); + } + + [Test] + public void CanPushPopItem() + { + var queue = new QueueValue(); + Assert.IsNotNull(queue); + var length = InvokeDelegate(queue, "LENGTH"); + Assert.AreEqual(ScalarIntValue.Zero, length); + + InvokeDelegate(queue, "PUSH", new StringValue("value1")); + InvokeDelegate(queue, "PUSH", new StringValue("value2")); + + length = InvokeDelegate(queue, "LENGTH"); + Assert.AreEqual(ScalarIntValue.Two, length); + + object popped = InvokeDelegate(queue, "POP"); + Assert.AreEqual(new StringValue("value1"), popped); + + popped = InvokeDelegate(queue, "POP"); + Assert.AreEqual(new StringValue("value2"), popped); + + length = InvokeDelegate(queue, "LENGTH"); + Assert.AreEqual(ScalarIntValue.Zero, length); + } + + [Test] + public void CanClear() + { + var queue = new QueueValue(); + + InvokeDelegate(queue, "PUSH", ScalarIntValue.One); + InvokeDelegate(queue, "PUSH", ScalarIntValue.Two); + + var length = InvokeDelegate(queue, "LENGTH"); + Assert.AreEqual(ScalarIntValue.Two, length); + InvokeDelegate(queue, "CLEAR"); + length = InvokeDelegate(queue, "LENGTH"); + Assert.AreEqual(ScalarIntValue.Zero, length); + } + + [Test] + public void CopyIsACopy() + { + var queue = new QueueValue(); + + var zedObject = ScalarIntValue.Zero; + InvokeDelegate(queue, "PUSH", zedObject); + var firstObject = ScalarIntValue.One; + InvokeDelegate(queue, "PUSH", firstObject); + var secondObject = ScalarIntValue.Two; + InvokeDelegate(queue, "PUSH", secondObject); + var thirdObject = new ScalarIntValue(4); + InvokeDelegate(queue, "PUSH", thirdObject); + + var length = InvokeDelegate(queue, "LENGTH"); + Assert.AreEqual(new ScalarIntValue(4), length); + + var copy = InvokeDelegate(queue, "COPY") as QueueValue; + Assert.AreNotSame(queue, copy); + + var copyLength = InvokeDelegate(copy, "LENGTH"); + Assert.AreEqual(new ScalarIntValue(4), copyLength); + + InvokeDelegate(copy, "CLEAR"); + + copyLength = InvokeDelegate(copy, "LENGTH"); + Assert.AreEqual(ScalarIntValue.Zero, copyLength); + + length = InvokeDelegate(queue, "LENGTH"); + Assert.AreEqual(new ScalarIntValue(4), length); + } + + [Test] + public void CanTestContains() + { + var queue = new QueueValue(); + + var zedObject = new StringValue("abc"); + InvokeDelegate(queue, "PUSH", zedObject); + var firstObject = new StringValue("def"); + InvokeDelegate(queue, "PUSH", firstObject); + var secondObject = new StringValue("xyz"); + var thirdObject = ScalarIntValue.Zero; + + var length = InvokeDelegate(queue, "LENGTH"); + Assert.AreEqual(ScalarIntValue.Two, length); + + + Assert.IsTrue((BooleanValue)InvokeDelegate(queue, "CONTAINS", zedObject)); + Assert.IsTrue((BooleanValue)InvokeDelegate(queue, "CONTAINS", firstObject)); + Assert.IsFalse((BooleanValue)InvokeDelegate(queue, "CONTAINS", secondObject)); + Assert.IsFalse((BooleanValue)InvokeDelegate(queue, "CONTAINS", thirdObject)); + } + } +} diff --git a/src/kOS.Safe.Test/Collections/RangeValueTest.cs b/src/kOS.Safe.Test/Collections/RangeValueTest.cs new file mode 100644 index 000000000..cc3deb920 --- /dev/null +++ b/src/kOS.Safe.Test/Collections/RangeValueTest.cs @@ -0,0 +1,78 @@ +using System; +using System.Collections.Generic; +using kOS.Safe.Encapsulation; +using kOS.Safe.Encapsulation.Suffixes; +using NUnit.Framework; +using System.Linq; + +namespace kOS.Safe.Test.Collections +{ + [TestFixture] + public class RangeValueTest : CollectionValueTest + { + [Test] + public void CanCreate() + { + var range = new RangeValue(); + Assert.IsNotNull(range); + } + + [Test] + public void CanCreateEmptyRange() + { + var range = new RangeValue(0); + Assert.AreEqual(ScalarIntValue.Zero, range.Count()); + Assert.IsTrue((BooleanValue)InvokeDelegate(range, "EMPTY")); + } + + [Test] + public void CanCreateSimpleRange() + { + var range = new RangeValue(5); + Assert.AreEqual(new ScalarIntValue(5), InvokeDelegate(range, "LENGTH")); + Assert.AreEqual(new ScalarIntValue(0), InvokeDelegate(range, "START")); + Assert.AreEqual(new ScalarIntValue(5), InvokeDelegate(range, "STOP")); + Assert.AreEqual(new ScalarIntValue(1), InvokeDelegate(range, "STEP")); + Assert.IsFalse((BooleanValue)InvokeDelegate(range, "EMPTY")); + Assert.IsTrue((BooleanValue)InvokeDelegate(range, "CONTAINS", new ScalarIntValue(1))); + Assert.IsFalse((BooleanValue)InvokeDelegate(range, "CONTAINS", new ScalarIntValue(5))); + } + + [Test] + public void CanCreateRangeWithFrom() + { + var range = new RangeValue(6, -3); + Assert.AreEqual(new ScalarIntValue(9), InvokeDelegate(range, "LENGTH")); + Assert.AreEqual(new ScalarIntValue(6), InvokeDelegate(range, "START")); + Assert.AreEqual(new ScalarIntValue(-3), InvokeDelegate(range, "STOP")); + Assert.AreEqual(new ScalarIntValue(1), InvokeDelegate(range, "STEP")); + Assert.IsFalse((BooleanValue)InvokeDelegate(range, "EMPTY")); + Assert.IsTrue((BooleanValue)InvokeDelegate(range, "CONTAINS", new ScalarIntValue(-2))); + Assert.IsFalse((BooleanValue)InvokeDelegate(range, "CONTAINS", new ScalarIntValue(-3))); + Assert.IsTrue((BooleanValue)InvokeDelegate(range, "CONTAINS", new ScalarIntValue(6))); + + List l = range.ToList(); + Assert.AreEqual(new ScalarIntValue(6), l[0]); + Assert.AreEqual(new ScalarIntValue(5), l[1]); + Assert.AreEqual(new ScalarIntValue(-2), l[8]); + } + + [Test] + public void CanCreateRangeWithFromAndStep() + { + var range = new RangeValue(2, 12, 3); + Assert.AreEqual(new ScalarIntValue(4), InvokeDelegate(range, "LENGTH")); + Assert.AreEqual(new ScalarIntValue(2), InvokeDelegate(range, "START")); + Assert.AreEqual(new ScalarIntValue(12), InvokeDelegate(range, "STOP")); + Assert.AreEqual(new ScalarIntValue(3), InvokeDelegate(range, "STEP")); + Assert.IsFalse((BooleanValue)InvokeDelegate(range, "EMPTY")); + Assert.IsTrue((BooleanValue)InvokeDelegate(range, "CONTAINS", new ScalarIntValue(5))); + Assert.IsFalse((BooleanValue)InvokeDelegate(range, "CONTAINS", new ScalarIntValue(4))); + + List l = range.ToList(); + Assert.AreEqual(new ScalarIntValue(2), l[0]); + Assert.AreEqual(new ScalarIntValue(5), l[1]); + Assert.AreEqual(new ScalarIntValue(11), l[3]); + } + } +} diff --git a/src/kOS.Safe.Test/Collections/StackValueTest.cs b/src/kOS.Safe.Test/Collections/StackValueTest.cs new file mode 100644 index 000000000..a3bc36beb --- /dev/null +++ b/src/kOS.Safe.Test/Collections/StackValueTest.cs @@ -0,0 +1,115 @@ +using System; +using System.Collections.Generic; +using kOS.Safe.Encapsulation; +using kOS.Safe.Encapsulation.Suffixes; +using NUnit.Framework; +using kOS.Safe.Serialization; + +namespace kOS.Safe.Test.Collections +{ + [TestFixture] + public class StackValueTest : CollectionValueTest + { + [Test] + public void CanCreate() + { + var stack = new StackValue(); + Assert.IsNotNull(stack); + } + + [Test] + public void CanPushPopItem() + { + var stack = new StackValue(); + Assert.IsNotNull(stack); + var length = InvokeDelegate(stack, "LENGTH"); + Assert.AreEqual(new ScalarIntValue(0), length); + + InvokeDelegate(stack, "PUSH", new StringValue("value1")); + InvokeDelegate(stack, "PUSH", new StringValue("value2")); + + length = InvokeDelegate(stack, "LENGTH"); + Assert.AreEqual(ScalarIntValue.Two, length); + + object popped = InvokeDelegate(stack, "POP"); + Assert.AreEqual(new StringValue("value2"), popped); + + popped = InvokeDelegate(stack, "POP"); + Assert.AreEqual(new StringValue("value1"), popped); + + length = InvokeDelegate(stack, "LENGTH"); + Assert.AreEqual(ScalarIntValue.Zero, length); + } + + [Test] + public void CanClear() + { + var stack = new StackValue(); + + InvokeDelegate(stack, "PUSH", new ScalarIntValue(1)); + InvokeDelegate(stack, "PUSH", new ScalarIntValue(2)); + + var length = InvokeDelegate(stack, "LENGTH"); + Assert.AreEqual(new ScalarIntValue(2),length); + InvokeDelegate(stack, "CLEAR"); + length = InvokeDelegate(stack, "LENGTH"); + Assert.AreEqual(new ScalarIntValue(0),length); + } + + [Test] + public void CopyIsACopy() + { + var stack = new StackValue(); + + var zedObject = ScalarIntValue.Zero; + InvokeDelegate(stack, "PUSH", zedObject); + var firstObject = ScalarIntValue.One; + InvokeDelegate(stack, "PUSH", firstObject); + var secondObject = ScalarIntValue.Two; + InvokeDelegate(stack, "PUSH", secondObject); + var thirdObject = new StringValue("third"); + InvokeDelegate(stack, "PUSH", thirdObject); + + var length = InvokeDelegate(stack, "LENGTH"); + Assert.AreEqual(new ScalarIntValue(4), length); + + var copy = InvokeDelegate(stack, "COPY") as StackValue; + Assert.AreNotSame(stack, copy); + + var copyLength = InvokeDelegate(copy, "LENGTH"); + Assert.AreEqual(new ScalarIntValue(4),copyLength); + + object popped = InvokeDelegate(copy, "POP"); + Assert.AreEqual(thirdObject, popped); + + InvokeDelegate(copy, "CLEAR"); + + copyLength = InvokeDelegate(copy, "LENGTH"); + Assert.AreEqual(ScalarIntValue.Zero, copyLength); + + length = InvokeDelegate(stack, "LENGTH"); + Assert.AreEqual(new ScalarIntValue(4), length); + } + + [Test] + public void CanTestContains() + { + var stack = new StackValue(); + + var zedObject = new StringValue("abc"); + InvokeDelegate(stack, "PUSH", zedObject); + var firstObject = ScalarIntValue.One; + InvokeDelegate(stack, "PUSH", firstObject); + var secondObject = ScalarIntValue.Two; + var thirdObject = new ScalarIntValue(4); + + var length = InvokeDelegate(stack, "LENGTH"); + Assert.AreEqual(ScalarIntValue.Two, length); + + Assert.IsTrue((BooleanValue)InvokeDelegate(stack, "CONTAINS", zedObject)); + Assert.IsTrue((BooleanValue)InvokeDelegate(stack, "CONTAINS", firstObject)); + Assert.IsFalse((BooleanValue)InvokeDelegate(stack, "CONTAINS", secondObject)); + Assert.IsFalse((BooleanValue)InvokeDelegate(stack, "CONTAINS", thirdObject)); + } + } +} diff --git a/src/kOS.Safe.Test/ListValueTest.cs b/src/kOS.Safe.Test/ListValueTest.cs deleted file mode 100644 index 48b382de8..000000000 --- a/src/kOS.Safe.Test/ListValueTest.cs +++ /dev/null @@ -1,240 +0,0 @@ -using System; -using System.Collections.Generic; -using kOS.Safe.Encapsulation.Suffixes; -using NUnit.Framework; -using kOS.Safe.Encapsulation; - -namespace kOS.Safe.Test -{ - [TestFixture] - public class ListValueTest - { - [Test] - public void CanCreate() - { - var list = new ListValue(); - Assert.IsNotNull(list); - } - - [Test] - public void CanAddItem() - { - var list = new ListValue(); - Assert.IsNotNull(list); - var length = InvokeDelegate(list, "LENGTH"); - Assert.AreEqual(0,length); - - InvokeDelegate(list, "ADD", new object()); - - length = InvokeDelegate(list, "LENGTH"); - Assert.AreEqual(1,length); - } - - [Test] - public void CanClear() - { - var list = new ListValue(); - - InvokeDelegate(list, "ADD", new object()); - InvokeDelegate(list, "ADD", new object()); - - var length = InvokeDelegate(list, "LENGTH"); - Assert.AreEqual(2,length); - InvokeDelegate(list, "CLEAR"); - length = InvokeDelegate(list, "LENGTH"); - Assert.AreEqual(0,length); - } - - [Test] - public void CanGetIndex() - { - var list = new ListValue(); - - var zedObject = new object(); - InvokeDelegate(list, "ADD", zedObject); - var firstObject = new object(); - InvokeDelegate(list, "ADD", firstObject); - var secondObject = new object(); - InvokeDelegate(list, "ADD", secondObject); - var thirdObject = new object(); - InvokeDelegate(list, "ADD", thirdObject); - - var length = InvokeDelegate(list, "LENGTH"); - Assert.AreEqual(4,length); - - Assert.AreSame(zedObject, list[0]); - Assert.AreSame(firstObject, list[1]); - Assert.AreSame(secondObject, list[2]); - Assert.AreSame(thirdObject, list[3]); - Assert.AreNotSame(list[0],list[1]); - Assert.AreNotSame(list[0],list[2]); - Assert.AreNotSame(list[0],list[3]); - Assert.AreNotSame(list[1],list[2]); - Assert.AreNotSame(list[1],list[3]); - Assert.AreNotSame(list[2],list[3]); - } - - [Test] - public void CopyIsACopy() - { - var list = new ListValue(); - - var zedObject = new object(); - InvokeDelegate(list, "ADD", zedObject); - var firstObject = new object(); - InvokeDelegate(list, "ADD", firstObject); - var secondObject = new object(); - InvokeDelegate(list, "ADD", secondObject); - var thirdObject = new object(); - InvokeDelegate(list, "ADD", thirdObject); - - var length = InvokeDelegate(list, "LENGTH"); - Assert.AreEqual(4,length); - - var copy = InvokeDelegate(list, "COPY") as ListValue; - Assert.AreNotSame(list, copy); - - var copyLength = InvokeDelegate(copy, "LENGTH"); - Assert.AreEqual(4,copyLength); - - InvokeDelegate(copy, "CLEAR"); - - copyLength = InvokeDelegate(copy, "LENGTH"); - Assert.AreEqual(0,copyLength); - - length = InvokeDelegate(list, "LENGTH"); - Assert.AreEqual(4,length); - } - - [Test] - public void CanTestContains() - { - var list = new ListValue(); - - var zedObject = new object(); - InvokeDelegate(list, "ADD", zedObject); - var firstObject = new object(); - InvokeDelegate(list, "ADD", firstObject); - var secondObject = new object(); - var thirdObject = new object(); - - var length = InvokeDelegate(list, "LENGTH"); - Assert.AreEqual(2,length); - - - Assert.IsTrue((bool)InvokeDelegate(list, "CONTAINS", zedObject)); - Assert.IsTrue((bool)InvokeDelegate(list, "CONTAINS", firstObject)); - Assert.IsFalse((bool)InvokeDelegate(list, "CONTAINS", secondObject)); - Assert.IsFalse((bool)InvokeDelegate(list, "CONTAINS", thirdObject)); - } - - /// - /// Creates a complex example of a nested list of lists and other - /// things, to use in some of the tests to prove complex example cases. - /// Returns a list that looks like so: - ///
-        /// list {
-        ///     100,
-        ///     200,
-        ///     list {
-        ///         list {
-        ///             "inner string 1",
-        ///             2
-        ///         },
-        ///         "string,one.two",
-        ///         "string,one.three"
-        ///     },
-        ///     list {
-        ///         "string,two.one",
-        ///         "string,two.two"
-        ///     },
-        ///     "String, outer value"
-        /// }
-        /// 
- /// This should be sufficiently complex to work with for testing a variety of cases. - /// - ///
- /// A list containing the description above - private ListValue MakeNestedExample() - { - const string OUTER_STRING = "String, outer value"; - - ListValue list = new ListValue(); - ListValue innerList1 = new ListValue(); - ListValue innerList2 = new ListValue(); - ListValue innerInnerList = new ListValue(); - - innerInnerList.Add( "inner string 1"); - innerInnerList.Add( 2 ); - - innerList1.Add( innerInnerList ); - innerList1.Add( "string,one.two" ); - innerList1.Add( "string,one.three" ); - - innerList2.Add( "string,two.one" ); - innerList2.Add( "string,two.two" ); - - InvokeDelegate(list,"ADD", 100); - InvokeDelegate(list,"ADD", 200); - InvokeDelegate(list,"ADD", innerList1); - InvokeDelegate(list,"ADD", innerList2); - InvokeDelegate(list,"ADD", OUTER_STRING); - - return list; - } - - [Test] - public void EachListConstructor() - { - var baseList = new ListValue(); - var baseDelegate = ((NoArgsSuffix.Del)baseList.GetSuffix("LENGTH")); - Assert.AreEqual(0, baseDelegate.Invoke()); - - var castList = ListValue.CreateList(new List()); - var castDelegate = ((NoArgsSuffix.Del)castList.GetSuffix("LENGTH")); - Assert.AreEqual(0, castDelegate.Invoke()); - - var copyDelegate = (NoArgsSuffix.Del)baseList.GetSuffix("COPY"); - var copyList = copyDelegate.Invoke(); - - Assert.AreEqual(0, ((NoArgsSuffix.Del)copyList.GetSuffix("LENGTH")).Invoke()); - } - - [Test] - public void CanShallowToString() - { - ListValue list = MakeNestedExample(); - - string result = list.ToString(); - - Assert.IsTrue(result.Contains("100"),"CanShallowToString(): ToString from list isn't shallow enough and is finding number 100\n"+result); - Assert.IsTrue(result.Contains("String, outer value"),"CanShallowToString(): ToString from list isn't shallow enough and is finding \"string,outer value\"\n"+result); - Assert.IsTrue(result.Contains("LIST of 5 items"),"CanShallowToString(): failed to find expected inner list object terse dump\n"+result); - Assert.IsFalse(result.Contains("string,one.two"),"CanShallowToString(): ToString from list isn't shallow enough and is finding inner component 'string,one.two'\n"+result); - } - - [Test] - public void CanDeepToString() - { - ListValue list = MakeNestedExample(); - - string result = (string)InvokeDelegate(list, "DUMP"); - - Assert.IsTrue(result.Contains("100"),"CanDeepToString(): failed to find expected integer 100 in string output\n"+result); - Assert.IsTrue(result.Contains("String, outer value"),"CanDeepToString(): failed to find expected string value in string output\n"+result); - Assert.IsTrue(result.Contains("string,one.two"),"CanDeepToString(): Listvalue:DUMP isn't going deep enough to print inner member 'string,one.two'\n"+result); - Assert.IsTrue(result.Contains("inner string 1"),"CanDeepToString(): Listvalue:DUMP isn't going deep enough to print inner member 'inner string 1'\n"+result); - } - - - private object InvokeDelegate(ListValue list, string suffixName, params object[] parameters) - { - var lengthObj = list.GetSuffix(suffixName); - Assert.IsNotNull(lengthObj); - var lengthDelegate = lengthObj as Delegate; - Assert.IsNotNull(lengthDelegate); - var length = lengthDelegate.DynamicInvoke(parameters); - return length; - } - } -} diff --git a/src/kOS.Safe.Test/NoArgsSuffixTest.cs b/src/kOS.Safe.Test/NoArgsSuffixTest.cs deleted file mode 100644 index c7f1083bb..000000000 --- a/src/kOS.Safe.Test/NoArgsSuffixTest.cs +++ /dev/null @@ -1,58 +0,0 @@ -using System; -using NUnit.Framework; -using kOS.Safe.Encapsulation.Suffixes; - -namespace kOS.Safe.Test -{ - [TestFixture] - public class NoArgsSuffixTest - { - [Test] - public void CanCreate() - { - var suffix = new NoArgsSuffix(() => new object() ); - Assert.IsNotNull(suffix.Get()); - } - - [Test] - public void CanGetDelegate() - { - var obj = new object(); - var suffix = new NoArgsSuffix(() => obj ); - var del = suffix.Get(); - Assert.IsNotNull(del); - var delegateAsDelegate = del as Delegate; - Assert.IsNotNull(delegateAsDelegate); - } - - [Test] - public void CanGetDelegateValue() - { - var obj = new object(); - var suffix = new NoArgsSuffix(() => obj ); - var del = suffix.Get(); - Assert.IsNotNull(del); - var delegateAsDelegate = del as Delegate; - Assert.IsNotNull(delegateAsDelegate); - var value = delegateAsDelegate.DynamicInvoke(); - Assert.IsNotNull(value); - Assert.AreSame(obj,value); - } - - [Test] - public void CanGetDelegateValueType() - { - const int VALUE = 12345; - var suffix = new NoArgsSuffix(() => VALUE ); - var del = suffix.Get(); - Assert.IsNotNull(del); - var delegateAsDelegate = del as Delegate; - Assert.IsNotNull(delegateAsDelegate); - var value = delegateAsDelegate.DynamicInvoke(); - Assert.IsNotNull(value); - Assert.IsInstanceOf(value); - Assert.AreEqual(VALUE,value); - } - - } -} diff --git a/src/kOS.Safe.Test/Opcode/FakeCpu.cs b/src/kOS.Safe.Test/Opcode/FakeCpu.cs new file mode 100644 index 000000000..06116c5d5 --- /dev/null +++ b/src/kOS.Safe.Test/Opcode/FakeCpu.cs @@ -0,0 +1,238 @@ +using System; +using System.Collections.Generic; +using kOS.Safe.Execution; + +namespace kOS.Safe.Test.Opcode +{ + public class FakeCpu : ICpu + { + private readonly Stack fakeStack; + + public FakeCpu() + { + fakeStack = new Stack(); + } + + public void Dispose() + { + throw new NotImplementedException(); + } + + public void KOSFixedUpdate(double deltaTime) + { + throw new NotImplementedException(); + } + + public void PushStack(object item) + { + fakeStack.Push(item); + } + + public object PopStack() + { + return fakeStack.Pop(); + } + + public void MoveStackPointer(int delta) + { + throw new NotImplementedException(); + } + + public void PushAboveStack(object thing) + { + throw new NotImplementedException(); + } + + public object PopAboveStack(int howMany) + { + throw new NotImplementedException(); + } + + public List GetCurrentClosure() + { + throw new NotImplementedException(); + } + + public IUserDelegate MakeUserDelegate(int entryPoint, bool withClosure) + { + throw new NotImplementedException(); + } + + public void AssertValidDelegateCall(IUserDelegate userDelegate) + { + throw new NotImplementedException(); + } + + public object GetValue(object testValue, bool barewordOkay = false) + { + throw new NotImplementedException(); + } + + public object PopValue(bool barewordOkay = false) + { + return PopStack(); + } + + public object PeekValue(int digDepth, bool barewordOkay = false) + { + throw new NotImplementedException(); + } + + public object PeekRaw(int digDepth, out bool checkOkay) + { + throw new NotImplementedException(); + } + + public Encapsulation.Structure GetStructureEncapsulated(Encapsulation.Structure testValue, bool barewordOkay = false) + { + throw new NotImplementedException(); + } + + public Encapsulation.Structure PopStructureEncapsulated(bool barewordOkay = false) + { + return kOS.Safe.Encapsulation.Structure.FromPrimitiveWithAssert(PopValue(barewordOkay)); + } + + public Encapsulation.Structure PeekStructureEncapsulated(int digDepth, bool barewordOkay = false) + { + return kOS.Safe.Encapsulation.Structure.FromPrimitiveWithAssert(PeekValue(digDepth, barewordOkay)); + } + + public object PopValueEncapsulated(bool barewordOkay = false) + { + return kOS.Safe.Encapsulation.Structure.FromPrimitive(PopValue(barewordOkay)); + } + + public object PeekValueEncapsulated(int digDepth, bool barewordOkay = false) + { + return kOS.Safe.Encapsulation.Structure.FromPrimitive(PeekValue(digDepth, barewordOkay)); + } + + public int GetStackSize() + { + return fakeStack.Count; + } + + public void SetValue(string identifier, object value) + { + throw new NotImplementedException(); + } + + public void SetValueExists(string identifier, object value) + { + throw new NotImplementedException(); + } + + public void SetNewLocal(string identifier, object value) + { + throw new NotImplementedException(); + } + + public void SetGlobal(string identifier, object value) + { + throw new NotImplementedException(); + } + + public bool IdentifierExistsInScope(string identifier) + { + throw new NotImplementedException(); + } + + public string DumpVariables() + { + throw new NotImplementedException(); + } + + public string DumpStack() + { + throw new NotImplementedException(); + } + + public void RemoveVariable(string identifier) + { + throw new NotImplementedException(); + } + + public int InstructionPointer + { + get { throw new NotImplementedException(); } + set { throw new NotImplementedException(); } + } + + public double SessionTime + { + get { throw new NotImplementedException(); } + } + + public void AddTrigger(int triggerFunctionPointer) + { + throw new NotImplementedException(); + } + + public void RemoveTrigger(int triggerFunctionPointer) + { + throw new NotImplementedException(); + } + + public void StartWait(double waitTime) + { + throw new NotImplementedException(); + } + + public void EndWait() + { + throw new NotImplementedException(); + } + + public void CallBuiltinFunction(string functionName) + { + throw new NotImplementedException(); + } + + public bool BuiltInExists(string functionName) + { + throw new NotImplementedException(); + } + + public void BreakExecution(bool manual) + { + throw new NotImplementedException(); + } + + public void AddVariable(Variable variable, string identifier, bool local, bool overwrite = false) + { + throw new NotImplementedException(); + } + + public Compilation.Opcode GetOpcodeAt(int instructionPtr) + { + throw new NotImplementedException(); + } + + public void Boot() + { + throw new NotImplementedException(); + } + + public List GetCallTrace() + { + throw new NotImplementedException(); + } + + public List GetCodeFragment(int contextLines) + { + throw new NotImplementedException(); + } + + public void RunProgram(List program) + { + throw new NotImplementedException(); + } + + + public int InstructionsThisUpdate + { + get { throw new NotImplementedException(); } + } + } +} diff --git a/src/kOS.Safe.Test/Opcode/OpcodeGetIndexText.cs b/src/kOS.Safe.Test/Opcode/OpcodeGetIndexText.cs new file mode 100644 index 000000000..bd84030b3 --- /dev/null +++ b/src/kOS.Safe.Test/Opcode/OpcodeGetIndexText.cs @@ -0,0 +1,114 @@ +using kOS.Safe.Compilation; +using kOS.Safe.Encapsulation; +using kOS.Safe.Execution; +using NUnit.Framework; + +namespace kOS.Safe.Test.Opcode +{ + [TestFixture] + public class OpcodeGetIndexText + { + private ICpu cpu; + + [SetUp] + public void Setup() + { + cpu = new FakeCpu(); + } + + [Test] + public void CanGetListIndex() + { + var list = new ListValue(); + list.Add(new StringValue("bar")); + cpu.PushStack(list); + + const int INDEX = 0; + cpu.PushStack(INDEX); + + var opcode = new OpcodeGetIndex(); + + opcode.Execute(cpu); + + Assert.AreEqual(1, list.Count()); + Assert.AreEqual(new StringValue("bar"), cpu.PopStack()); + } + + [Test] + public void CanGetCorrectListIndex() + { + var list = new ListValue(); + list.Add(new StringValue("bar")); + list.Add(new StringValue("foo")); + list.Add(new StringValue("fizz")); + cpu.PushStack(list); + + const int INDEX = 1; + cpu.PushStack(INDEX); + + var opcode = new OpcodeGetIndex(); + + opcode.Execute(cpu); + + Assert.AreEqual(3, list.Count()); + Assert.AreEqual(new StringValue("foo"), cpu.PopStack()); + } + + [Test] + public void CanGetDoubleIndex() + { + var list = new ListValue(); + list.Add(new StringValue("bar")); + list.Add(new StringValue("foo")); + list.Add(new StringValue("fizz")); + cpu.PushStack(list); + + const double INDEX = 2.5; + cpu.PushStack(INDEX); + + var opcode = new OpcodeGetIndex(); + + opcode.Execute(cpu); + + Assert.AreEqual(3, list.Count()); + Assert.AreEqual(new StringValue("fizz"), cpu.PopStack()); + } + + [Test] + public void CanGetLexiconIndex() + { + var list = new Lexicon(); + list.Add(new StringValue("foo"), new StringValue("bar")); + cpu.PushStack(list); + + const string INDEX = "foo"; + cpu.PushStack(INDEX); + + var opcode = new OpcodeGetIndex(); + + opcode.Execute(cpu); + + Assert.AreEqual(1, list.Count); + Assert.AreEqual(new StringValue("bar"), cpu.PopStack()); + } + + [Test] + public void CanGetCorrectLexiconIndex() + { + var list = new Lexicon(); + list.Add(new StringValue("foo"), new StringValue("bar")); + list.Add(new StringValue("fizz"), new StringValue("bang")); + cpu.PushStack(list); + + const string INDEX = "fizz"; + cpu.PushStack(INDEX); + + var opcode = new OpcodeGetIndex(); + + opcode.Execute(cpu); + + Assert.AreEqual(2, list.Count); + Assert.AreEqual(new StringValue("bang"), cpu.PopStack()); + } + } +} diff --git a/src/kOS.Safe.Test/Opcode/OpcodeSetIndexTest.cs b/src/kOS.Safe.Test/Opcode/OpcodeSetIndexTest.cs new file mode 100644 index 000000000..d29458a12 --- /dev/null +++ b/src/kOS.Safe.Test/Opcode/OpcodeSetIndexTest.cs @@ -0,0 +1,146 @@ +using kOS.Safe.Compilation; +using kOS.Safe.Encapsulation; +using kOS.Safe.Exceptions; +using kOS.Safe.Execution; +using NUnit.Framework; + +namespace kOS.Safe.Test.Opcode +{ + [TestFixture] + public class OpcodeSetIndexTest + { + private ICpu cpu; + + [SetUp] + public void Setup() + { + cpu = new FakeCpu(); + } + + [Test] + public void CanSetListIndex() + { + var list = new ListValue(); + list.Add(new StringValue("bar")); + cpu.PushStack(list); + + const int INDEX = 0; + cpu.PushStack(INDEX); + + const string VALUE = "foo"; + cpu.PushStack(VALUE); + + var opcode = new OpcodeSetIndex(); + + opcode.Execute(cpu); + + Assert.AreEqual(1, list.Count()); + Assert.AreNotEqual(new StringValue("bar"), list[0]); + Assert.AreEqual(new StringValue("foo"), list[0]); + } + + [Test] + public void CanSetListIndexWithFloat() + { + var list = new ListValue(); + list.Add(new StringValue("bar")); + cpu.PushStack(list); + + const float INDEX = 0.0f; + cpu.PushStack(INDEX); + + const string VALUE = "foo"; + cpu.PushStack(VALUE); + + var opcode = new OpcodeSetIndex(); + + opcode.Execute(cpu); + + Assert.AreEqual(1, list.Count()); + Assert.AreNotEqual(new StringValue("bar"), list[0]); + Assert.AreEqual(new StringValue("foo"), list[0]); + } + + [Test] + public void CanSetListIndexWithDouble() + { + var list = new ListValue(); + list.Add(new StringValue("bar")); + cpu.PushStack(list); + + const double INDEX = 0.0d; + cpu.PushStack(INDEX); + + const string VALUE = "foo"; + cpu.PushStack(VALUE); + + var opcode = new OpcodeSetIndex(); + + opcode.Execute(cpu); + + Assert.AreEqual(1, list.Count()); + Assert.AreNotEqual(new StringValue("bar"), list[0]); + Assert.AreEqual(new StringValue("foo"), list[0]); + } + + [Test] + [ExpectedException(typeof(KOSException))] + public void WillThrowOnNonIntListIndex() + { + var list = new ListValue(); + list.Add(new StringValue("bar")); + cpu.PushStack(list); + + const string INDEX = "fizz"; + cpu.PushStack(INDEX); + + const string VALUE = "foo"; + cpu.PushStack(VALUE); + + var opcode = new OpcodeSetIndex(); + + opcode.Execute(cpu); + } + + [Test] + public void CanSetLexiconIndex() + { + Encapsulation.Structure index = new StringValue("foo"); + + var lex = new Lexicon(); + lex.Add(index, new StringValue("bar")); + cpu.PushStack(lex); + + cpu.PushStack(index); + + const string VALUE = "fizz"; + cpu.PushStack(VALUE); + + var opcode = new OpcodeSetIndex(); + + opcode.Execute(cpu); + + Assert.AreEqual(1, lex.Count); + Assert.AreNotEqual("bar", lex[new StringValue("foo")]); + } + + [Test] + [ExpectedException(typeof(KOSException))] + public void WillThrowOnNonListType() + { + const string INDEX = "foo"; + + var lex = new object(); + cpu.PushStack(lex); + + cpu.PushStack(INDEX); + + const string VALUE = "fizz"; + cpu.PushStack(VALUE); + + var opcode = new OpcodeSetIndex(); + + opcode.Execute(cpu); + } + } +} diff --git a/src/kOS.Safe.Test/Properties/AssemblyInfo.cs b/src/kOS.Safe.Test/Properties/AssemblyInfo.cs index 277383e33..6150b846d 100644 --- a/src/kOS.Safe.Test/Properties/AssemblyInfo.cs +++ b/src/kOS.Safe.Test/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] +[assembly: AssemblyVersion("1.19.1.0")] +[assembly: AssemblyFileVersion("1.19.1.0")] diff --git a/src/kOS.Safe.Test/Serialization/JSONFormatterTest.cs b/src/kOS.Safe.Test/Serialization/JSONFormatterTest.cs new file mode 100644 index 000000000..5f1d2ec4e --- /dev/null +++ b/src/kOS.Safe.Test/Serialization/JSONFormatterTest.cs @@ -0,0 +1,105 @@ +using kOS.Safe.Encapsulation; +using kOS.Safe.Serialization; +using NUnit.Framework; + +namespace kOS.Safe.Test.Serialization +{ + [TestFixture] + public class JSONFormatterTest + { + [SetUp] + public void Setup() + { + + } + + [Test] + public void CanSerializeLexicons() + { + var lex = new Lexicon(); + var nested = new Lexicon(); + + lex[new StringValue("key1")] = new StringValue("value1"); + lex[new StringValue("key2")] = new ScalarIntValue(1); + lex[new StringValue("key3")] = nested; + + nested[new StringValue("nested1")] = new StringValue("nested1value"); + nested[new StringValue("nested2")] = new StringValue("nested2value"); + + Lexicon deserialized = Deserialize(Serialize(lex)) as Lexicon; + + Assert.AreEqual(new StringValue("value1"), deserialized[new StringValue("key1")]); + Assert.AreEqual(new ScalarIntValue(1), deserialized[new StringValue("key2")]); + Assert.IsTrue(deserialized[new StringValue("key3")] is Lexicon); + Assert.AreEqual(new StringValue("nested1value"), (deserialized[new StringValue("key3")] as Lexicon)[new StringValue("nested1")]); + } + + [Test] + public void CanSerializeLists() + { + var list = new ListValue(); + var nested = new ListValue(); + + list.Add(new StringValue("item1")); + list.Add(new ScalarIntValue(2)); + list.Add(nested); + + nested.Add(new StringValue("nested1")); + + ListValue deserialized = Deserialize(Serialize(list)) as ListValue; + + Assert.AreEqual(new StringValue("item1"), deserialized[0]); + Assert.AreEqual(new ScalarIntValue(2), deserialized[1]); + Assert.IsTrue(deserialized[2] is ListValue); + } + + [Test] + public void CanSerializeStacks() + { + var stack = new StackValue(); + var nested = new StackValue(); + + stack.Push(new StringValue("item1")); + stack.Push(new ScalarIntValue(2)); + stack.Push(nested); + + nested.Push(new StringValue("nested1")); + + StackValue deserialized = Deserialize(Serialize(stack)) as StackValue; + + Assert.AreEqual(new StringValue("nested1"), (deserialized.Pop() as StackValue).Pop()); + Assert.AreEqual(new ScalarIntValue(2), deserialized.Pop()); + Assert.AreEqual(new StringValue("item1"), deserialized.Pop()); + + } + + [Test] + public void CanSerializeQueues() + { + var queue = new QueueValue(); + var nested = new QueueValue(); + + queue.Push(new StringValue("item1")); + queue.Push(new ScalarIntValue(2)); + queue.Push(nested); + + nested.Push(new StringValue("nested1")); + + QueueValue deserialized = Deserialize(Serialize(queue)) as QueueValue; + + Assert.AreEqual(new StringValue("item1"), deserialized.Pop()); + Assert.AreEqual(new ScalarIntValue(2), deserialized.Pop()); + Assert.IsTrue(deserialized.Pop() is QueueValue); + } + + private string Serialize(SerializableStructure o) + { + return new SafeSerializationMgr().Serialize(o, JsonFormatter.WriterInstance); + } + + private SerializableStructure Deserialize(string s) + { + return new SafeSerializationMgr().Deserialize(s, JsonFormatter.ReaderInstance); + } + } +} diff --git a/src/kOS.Safe.Test/Serialization/TerminalFormatterTest.cs b/src/kOS.Safe.Test/Serialization/TerminalFormatterTest.cs new file mode 100644 index 000000000..1d141aa02 --- /dev/null +++ b/src/kOS.Safe.Test/Serialization/TerminalFormatterTest.cs @@ -0,0 +1,42 @@ +using System; +using kOS.Safe.Encapsulation; +using NUnit.Framework; +using kOS.Safe.Serialization; + +namespace kOS.Safe.Test.Serialization +{ + [TestFixture] + public class TerminalFormatterTest + { + [SetUp] + public void Setup() + { + + } + + [Test] + public void CanSerializeLexicons() + { + var lex = new Lexicon(); + var nested = new Lexicon(); + + lex[new StringValue("key1")] = new StringValue("value1"); + lex[new StringValue("2")] = new ScalarIntValue(10); + lex[new ScalarIntValue(2)] = new ScalarIntValue(11); // make sure int 2 is different than string "2" + lex[new StringValue("key3")] = nested; + + nested[new StringValue("nested1")] = new StringValue("nested1value"); + nested[new StringValue("nested2")] = new StringValue("nested2value"); + + var lines = new string[] { "LEXICON of 4 items:", "[\"key1\"] = \"value1\"", "[\"2\"] = 10", "[2] = 11", "[\"key3\"] = LEXICON of 2 items:", + " [\"nested1\"] = \"nested1value\"", " [\"nested2\"] = \"nested2value\""}; + + Assert.AreEqual(string.Join(Environment.NewLine, lines), Serialize(lex)); + } + + private string Serialize(SerializableStructure o) + { + return new SafeSerializationMgr().Serialize(o, TerminalFormatter.Instance, false); + } + } +} diff --git a/src/kOS.Safe.Test/ClampSetSuffixTest.cs b/src/kOS.Safe.Test/Structure/ClampSetSuffixTest.cs similarity index 60% rename from src/kOS.Safe.Test/ClampSetSuffixTest.cs rename to src/kOS.Safe.Test/Structure/ClampSetSuffixTest.cs index fd5988f8a..16faaa1f7 100644 --- a/src/kOS.Safe.Test/ClampSetSuffixTest.cs +++ b/src/kOS.Safe.Test/Structure/ClampSetSuffixTest.cs @@ -1,7 +1,8 @@ -using kOS.Safe.Encapsulation.Suffixes; +using kOS.Safe.Encapsulation; +using kOS.Safe.Encapsulation.Suffixes; using NUnit.Framework; -namespace kOS.Safe.Test +namespace kOS.Safe.Test.Structure { [TestFixture] public class ClampSetSuffixTest @@ -13,9 +14,9 @@ public void CanGet() const int MAX_VALUE = 1; float value = 0.5f; - var suffix = new ClampSetSuffix(() => value, i => value = i, MIN_VALUE, MAX_VALUE); + var suffix = new ClampSetSuffix(() => value, i => value = i, MIN_VALUE, MAX_VALUE); - Assert.AreEqual(value, suffix.Get()); + Assert.AreEqual(new ScalarDoubleValue(value), suffix.Get().Value); } @@ -24,14 +25,14 @@ public void CanSet() { const int MIN_VALUE = 0; const int MAX_VALUE = 1; - const float SET_VALUE = 0.5f; + ScalarValue SET_VALUE = 0.5f; - float value = 0; - var suffix = new ClampSetSuffix(() => value, i => value = i, MIN_VALUE, MAX_VALUE); + ScalarValue value = 0; + var suffix = new ClampSetSuffix(() => value, i => value = i, MIN_VALUE, MAX_VALUE); suffix.Set(SET_VALUE); - Assert.AreEqual(value, suffix.Get()); + Assert.AreEqual(value, suffix.Get().Value); Assert.AreEqual(value, SET_VALUE); } @@ -44,11 +45,11 @@ public void CanSimpleClamp() const float SET_VALUE = 1.5f; float value = 0; - var suffix = new ClampSetSuffix(() => value, i => value = i, MIN_VALUE, MAX_VALUE); + var suffix = new ClampSetSuffix(() => value, i => value = i, MIN_VALUE, MAX_VALUE); suffix.Set(SET_VALUE); - Assert.AreEqual(value, suffix.Get()); + Assert.AreEqual(ScalarValue.Create(value), suffix.Get().Value); Assert.AreNotEqual(SET_VALUE, value); Assert.AreEqual(MAX_VALUE, value); @@ -64,11 +65,11 @@ public void CanStepClamp() const float STEP_VALUE = 0.5f; float value = 0; - var suffix = new ClampSetSuffix(() => value, i => value = i, MIN_VALUE, MAX_VALUE, STEP_VALUE); + var suffix = new ClampSetSuffix(() => value, i => value = i, MIN_VALUE, MAX_VALUE, STEP_VALUE); suffix.Set(SET_VALUE); - Assert.AreEqual(value, suffix.Get()); + Assert.AreEqual(ScalarValue.Create(value), suffix.Get().Value); Assert.AreNotEqual(SET_VALUE, value); Assert.AreEqual(EXPECTED_VALUE, value); } @@ -83,11 +84,11 @@ public void CanComplexStepClamp() const float STEP_VALUE = 0.5f; float value = 0; - var suffix = new ClampSetSuffix(() => value, i => value = i, MIN_VALUE, MAX_VALUE, STEP_VALUE); + var suffix = new ClampSetSuffix(() => value, i => value = i, MIN_VALUE, MAX_VALUE, STEP_VALUE); suffix.Set(SET_VALUE); - Assert.AreEqual(value, suffix.Get()); + Assert.AreEqual(ScalarValue.Create(value), suffix.Get().Value); Assert.AreNotEqual(SET_VALUE, value); Assert.AreEqual(EXPECTED_VALUE, value); } diff --git a/src/kOS.Safe.Test/Structure/NoArgsSuffixTest.cs b/src/kOS.Safe.Test/Structure/NoArgsSuffixTest.cs new file mode 100644 index 000000000..b2a6b7748 --- /dev/null +++ b/src/kOS.Safe.Test/Structure/NoArgsSuffixTest.cs @@ -0,0 +1,77 @@ +using System; +using kOS.Safe.Encapsulation; +using kOS.Safe.Encapsulation.Suffixes; +using NUnit.Framework; +using kOS.Safe.Test.Opcode; +using kOS.Safe.Execution; + +namespace kOS.Safe.Test.Structure +{ + public class MockStructure : Encapsulation.Structure + { + + } + + [TestFixture] + public class NoArgsSuffixTest + { + private ICpu cpu; + + [SetUp] + public void Setup() + { + cpu = new FakeCpu(); + } + [Test] + public void CanCreate() + { + var suffix = new NoArgsSuffix(() => new MockStructure() ); + Assert.IsNotNull(suffix.Get()); + } + + [Test] + public void CanGetDelegate() + { + var obj = new MockStructure(); + var suffix = new NoArgsSuffix(() => obj ); + var del = suffix.Get(); + Assert.IsNotNull(del); + } + + [Test] + public void CanGetDelegateValue() + { + var obj = new MockStructure(); + var suffix = new NoArgsSuffix(() => obj ); + var del = suffix.Get(); + Assert.IsNotNull(del); + + cpu.PushStack(null); // dummy variable for ReverseStackArgs to pop + cpu.PushStack(new KOSArgMarkerType()); + del.Invoke(cpu); + + var value = del.Value; + Assert.IsNotNull(value); + Assert.AreSame(obj,value); + } + + [Test] + public void CanGetDelegateValueType() + { + const int VALUE = 12345; + var suffix = new NoArgsSuffix(() => ScalarValue.Create(VALUE)); + var del = suffix.Get(); + Assert.IsNotNull(del); + + cpu.PushStack(null); // dummy variable for ReverseStackArgs to pop + cpu.PushStack(new KOSArgMarkerType()); + del.Invoke(cpu); + + var value = del.Value; + Assert.IsNotNull(value); + Assert.IsInstanceOf(value); + Assert.AreEqual(ScalarValue.Create(VALUE), value); + } + + } +} diff --git a/src/kOS.Safe.Test/SetSuffixTest.cs b/src/kOS.Safe.Test/Structure/SetSuffixTest.cs similarity index 60% rename from src/kOS.Safe.Test/SetSuffixTest.cs rename to src/kOS.Safe.Test/Structure/SetSuffixTest.cs index 443c98bd4..458f0def8 100644 --- a/src/kOS.Safe.Test/SetSuffixTest.cs +++ b/src/kOS.Safe.Test/Structure/SetSuffixTest.cs @@ -1,9 +1,10 @@ using System.Runtime.CompilerServices; -using NUnit.Framework; +using kOS.Safe.Encapsulation; using kOS.Safe.Encapsulation.Suffixes; using kOS.Safe.Utilities; +using NUnit.Framework; -namespace kOS.Safe.Test +namespace kOS.Safe.Test.Structure { [TestFixture] public class SetSuffixTest @@ -14,26 +15,20 @@ public void Setup() SafeHouse.Logger = new TestLogger(); } - [Test] - public void CanGetDefaultValue() - { - var suffix = BuildBasicSetSuffix(); - - Assert.IsNotNull(suffix); - Assert.AreEqual(default(int), suffix.Get()); - } + // Deleted the CanGetDefaultValue test because all structures + // are now reference types with a default value of null. [Test] public void CanSetAndGet() { - var suffix = BuildBasicSetSuffix(); + var suffix = BuildBasicSetSuffix(); Assert.IsNotNull(suffix); suffix.Set(15); - Assert.AreEqual(15,suffix.Get()); + Assert.AreEqual(ScalarValue.Create(15),suffix.Get().Value); } - private static SetSuffix BuildBasicSetSuffix() + private static SetSuffix BuildBasicSetSuffix() where TParam : Encapsulation.Structure { var basicInstance = new StrongBox(default(TParam)); @@ -46,38 +41,38 @@ private static SetSuffix BuildBasicSetSuffix() [Test] public void CanCoerceType() { - var suffix = BuildBasicSetSuffix(); + var suffix = BuildBasicSetSuffix(); const double TEST_VALUE = 15.0d; Assert.IsNotNull(suffix); suffix.Set(TEST_VALUE); - var finalValue = suffix.Get(); - Assert.AreEqual(TEST_VALUE,finalValue); + var finalValue = suffix.Get().Value; + Assert.AreEqual(ScalarValue.Create(TEST_VALUE), finalValue); } [Test] public void CanCoerceAndTruncateType() { - var suffix = BuildBasicSetSuffix(); + var suffix = BuildBasicSetSuffix(); const double TEST_VALUE = 15.1234d; const double TEST_VALUE_TRUNCATED = 15; Assert.IsNotNull(suffix); suffix.Set(TEST_VALUE); - var finalValue = suffix.Get(); - Assert.AreEqual(TEST_VALUE_TRUNCATED,finalValue); + var finalValue = suffix.Get().Value; + Assert.AreEqual(ScalarValue.Create(TEST_VALUE_TRUNCATED), finalValue); } [Test] public void CanCoerceAndExtendType() { - var suffix = BuildBasicSetSuffix(); + var suffix = BuildBasicSetSuffix(); const int TEST_VALUE = 15; Assert.IsNotNull(suffix); suffix.Set(TEST_VALUE); - var finalValue = suffix.Get(); - Assert.AreEqual(TEST_VALUE,finalValue); + var finalValue = suffix.Get().Value; + Assert.AreEqual(ScalarValue.Create(TEST_VALUE), finalValue); } } } diff --git a/src/kOS.Safe.Test/Structure/StructureSuffixIntegrationTest.cs b/src/kOS.Safe.Test/Structure/StructureSuffixIntegrationTest.cs new file mode 100644 index 000000000..caf17a237 --- /dev/null +++ b/src/kOS.Safe.Test/Structure/StructureSuffixIntegrationTest.cs @@ -0,0 +1,98 @@ +using System.Runtime.CompilerServices; +using kOS.Safe.Encapsulation; +using kOS.Safe.Encapsulation.Suffixes; +using kOS.Safe.Exceptions; +using kOS.Safe.Utilities; +using NUnit.Framework; + +namespace kOS.Safe.Test.Structure +{ + [TestFixture] + public class StructureSuffixIntegrationTest + { + [TestFixtureSetUp] + public void Setup() + { + SafeHouse.Logger = new TestLogger(); + } + + [Test] + public void CanAddSuffix() + { + var structure = new StructureTest.TestStructure(); + var strongBox = new StrongBox(false); + structure.TestAddInstanceSuffix("FOO", new Suffix(BuildBasicGetter(strongBox))); + Assert.IsFalse((BooleanValue) structure.GetSuffix("FOO").Value); + } + + [Test] + public void CanReflectChangeInUnderlyingData() + { + var structure = new StructureTest.TestStructure(); + var strongBox = new StrongBox(false); + structure.TestAddInstanceSuffix("FOO", new Suffix(BuildBasicGetter(strongBox))); + + strongBox.Value = false; + Assert.IsFalse((BooleanValue) structure.GetSuffix("FOO").Value); + strongBox.Value = true; + Assert.IsTrue((BooleanValue) structure.GetSuffix("FOO").Value); + } + + [Test] + public void CanAddSetSuffix() + { + var structure = new StructureTest.TestStructure(); + var strongBox = new StrongBox(false); + structure.TestAddInstanceSuffix("FOO", new SetSuffix(BuildBasicGetter(strongBox), BuildBasicSetter(strongBox))); + + Assert.IsFalse((BooleanValue) structure.GetSuffix("FOO").Value); + } + + [Test] + public void CanSetSuffix() + { + const int TEST_VALUE = 12345; + var structure = new StructureTest.TestStructure(); + var strongBox = new StrongBox(TEST_VALUE); + structure.TestAddInstanceSuffix("FOO", new SetSuffix(BuildBasicGetter(strongBox), BuildBasicSetter(strongBox))); + structure.TestAddInstanceSuffix("BAR", new SetSuffix(BuildBasicGetter(strongBox), BuildBasicSetter(strongBox))); + + Assert.AreEqual(ScalarValue.Create(TEST_VALUE), structure.GetSuffix("FOO").Value); + structure.SetSuffix("FOO", TEST_VALUE - 10); + Assert.AreEqual(ScalarValue.Create(TEST_VALUE - 10), structure.GetSuffix("FOO").Value); + structure.SetSuffix("FOO", TEST_VALUE / 20); + Assert.AreEqual(ScalarValue.Create(TEST_VALUE / 20), structure.GetSuffix("FOO").Value); + } + + [Test] + public void TwoSuffixesCanShareAModel() + { + const int TEST_VALUE = 12345; + var structure = new StructureTest.TestStructure(); + var strongBox = new StrongBox(TEST_VALUE); + structure.TestAddInstanceSuffix("FOO", new SetSuffix(BuildBasicGetter(strongBox), BuildBasicSetter(strongBox))); + structure.TestAddInstanceSuffix("BAR", new SetSuffix(BuildBasicGetter(strongBox), BuildBasicSetter(strongBox))); + + Assert.AreEqual(ScalarValue.Create(TEST_VALUE), structure.GetSuffix("FOO").Value); + Assert.AreEqual(ScalarValue.Create(TEST_VALUE), structure.GetSuffix("BAR").Value); + structure.SetSuffix("FOO", TEST_VALUE - 10); + Assert.AreEqual(ScalarValue.Create(TEST_VALUE - 10), structure.GetSuffix("FOO").Value); + Assert.AreEqual(ScalarValue.Create(TEST_VALUE - 10), structure.GetSuffix("BAR").Value); + structure.SetSuffix("BAR", TEST_VALUE / 20); + Assert.AreEqual(ScalarValue.Create(TEST_VALUE / 20), structure.GetSuffix("BAR").Value); + Assert.AreEqual(ScalarValue.Create(TEST_VALUE / 20), structure.GetSuffix("FOO").Value); + } + + private static SuffixSetDlg BuildBasicSetter(StrongBox state) where TParam : Encapsulation.Structure + { + SuffixSetDlg setter = value => state.Value = value; + return setter; + } + + private static SuffixGetDlg BuildBasicGetter(StrongBox state) where TParam : Encapsulation.Structure + { + SuffixGetDlg getter = () => state.Value; + return getter; + } + } +} diff --git a/src/kOS.Safe.Test/StructureTest.cs b/src/kOS.Safe.Test/Structure/StructureTest.cs similarity index 89% rename from src/kOS.Safe.Test/StructureTest.cs rename to src/kOS.Safe.Test/Structure/StructureTest.cs index 7869860bc..f805b3f08 100644 --- a/src/kOS.Safe.Test/StructureTest.cs +++ b/src/kOS.Safe.Test/Structure/StructureTest.cs @@ -1,16 +1,17 @@ using System; -using NSubstitute; -using NUnit.Framework; using kOS.Safe.Encapsulation; +using kOS.Safe.Encapsulation.Suffixes; using kOS.Safe.Exceptions; using kOS.Safe.Utilities; +using NSubstitute; +using NUnit.Framework; -namespace kOS.Safe.Test +namespace kOS.Safe.Test.Structure { [TestFixture] public class StructureTest { - public class TestStructure: Structure + public class TestStructure: Encapsulation.Structure { public static void TestAddGlobal(string name, ISuffix suffix) { @@ -48,7 +49,7 @@ public void CanConstruct() [Test] public void CanAddGlobalSuffix() { - var testObject = new object(); + var testObject = Substitute.For(); var testSuffix = Substitute.For(); var testStuffixName = Guid.NewGuid().ToString(); testSuffix.Get().Returns(testObject); @@ -60,7 +61,7 @@ public void CanAddGlobalSuffix() [Test] public void CanAddGlobalSuffixWithTwoNames() { - var testObject = new object(); + var testObject = Substitute.For(); var testSuffix = Substitute.For(); var testStructure = new TestStructure(); var suffixName = Guid.NewGuid().ToString(); @@ -76,7 +77,7 @@ public void CanAddGlobalSuffixWithTwoNames() public void GlobalSuffixesAreInFactGlobal() { var suffixName = Guid.NewGuid().ToString(); - var testObject = new object(); + var testObject = Substitute.For(); var testSuffix = Substitute.For(); testSuffix.Get().Returns(testObject); @@ -88,7 +89,7 @@ public void GlobalSuffixesAreInFactGlobal() [Test] public void CanAddInstanceSuffix() { - var testObject = new object(); + var testObject = Substitute.For(); var testSuffix = Substitute.For(); var testStructure = new TestStructure(); var suffixName = Guid.NewGuid().ToString(); @@ -101,7 +102,7 @@ public void CanAddInstanceSuffix() [Test] public void CantFindSuffixThatDoesntExist() { - var testObject = new object(); + var testObject = Substitute.For(); var testSuffix = Substitute.For(); var testStructure = new TestStructure(); var suffixName = Guid.NewGuid().ToString(); @@ -118,7 +119,7 @@ public void CantFindSuffixThatDoesntExist() [Test] public void CantFindStaticSuffixThatDoesntExist() { - var testObject = new object(); + var testObject = Substitute.For(); var testSuffix = Substitute.For(); var testStructure = new TestStructure(); var suffixName = Guid.NewGuid().ToString(); @@ -135,7 +136,7 @@ public void CantFindStaticSuffixThatDoesntExist() [Test] public void InstanceSuffixesAreInFactInstanced() { - var testObject = new object(); + var testObject = Substitute.For(); var testSuffix = Substitute.For(); var testStructure = new TestStructure(); var suffixName = Guid.NewGuid().ToString(); @@ -155,11 +156,11 @@ public void InstanceSuffixesAreCaseInsensitive() { var testStructure = new TestStructure(); - var testObject1 = new object(); + var testObject1 = Substitute.For(); var testSuffix1 = Substitute.For(); testSuffix1.Get().Returns(testObject1); - var testObject2 = new object(); + var testObject2 = Substitute.For(); var testSuffix2 = Substitute.For(); testSuffix2.Get().Returns(testObject2); @@ -177,7 +178,7 @@ public void InstanceSuffixesAreCaseInsensitive() [Test] public void CanSetInstanceSuffix() { - var testObject = new object(); + var testObject = Substitute.For(); object internalStorage = null; var testSuffix = Substitute.For(); @@ -203,13 +204,13 @@ public void CanLetInstanceTakePrecedenceOverStatic() var testStructure = new TestStructure(); var suffixName = Guid.NewGuid().ToString(); - var testObject = new object(); + var testObject = Substitute.For(); var testSuffix = Substitute.For(); testSuffix.Get().ReturnsForAnyArgs(info => testObject); testStructure.TestAddInstanceSuffix(suffixName, testSuffix); var testSuffixStatic = Substitute.For(); - testSuffixStatic.Get().ReturnsForAnyArgs(info => int.MaxValue); + testSuffixStatic.Get().ReturnsForAnyArgs(new SuffixResult(ScalarIntValue.MaxValue())); TestStructure.TestAddGlobal(suffixName, testSuffixStatic); Assert.IsNotNull(testStructure.GetSuffix(suffixName)); @@ -219,8 +220,8 @@ public void CanLetInstanceTakePrecedenceOverStatic() [Test] public void CanSetSynonymInstanceSuffix() { - var testObject = new object(); - var testObject2 = new object(); + var testObject = Substitute.For(); + var testObject2 = Substitute.For(); object internalStorage = null; var testSuffix = Substitute.For(); diff --git a/src/kOS.Safe.Test/Structure/TwoArgsVoidSuffixTest.cs b/src/kOS.Safe.Test/Structure/TwoArgsVoidSuffixTest.cs new file mode 100644 index 000000000..b6f426bb8 --- /dev/null +++ b/src/kOS.Safe.Test/Structure/TwoArgsVoidSuffixTest.cs @@ -0,0 +1,43 @@ +using kOS.Safe.Encapsulation.Suffixes; +using NSubstitute; +using NUnit.Framework; +using System; + +namespace kOS.Safe.Test.Structure +{ + [TestFixture] + public class TwoArgsVoidSuffixTest + { + [Test] + public void CanCreate() + { + var suffix = new TwoArgsSuffix((one, two) => { }); + Assert.IsNotNull(suffix.Get()); + } + + [Test] + public void CanGetDelegate() + { + var suffix = new TwoArgsSuffix((one, two) => { }); + var del = suffix.Get() as DelegateSuffixResult; + Assert.IsNotNull(del); + var delegateAsDelegate = del.Del; + Assert.IsNotNull(delegateAsDelegate); + } + + [Test] + public void CanExecuteDelegate() + { + var mockDel = Substitute.For.Del>(); + + var suffix = new TwoArgsSuffix(mockDel); + var del = suffix.Get() as DelegateSuffixResult; + Assert.IsNotNull(del); + var delegateAsDelegate = del.Del; + Assert.IsNotNull(delegateAsDelegate); + delegateAsDelegate.DynamicInvoke(new object(), new object()); + + mockDel.ReceivedWithAnyArgs(1); + } + } +} \ No newline at end of file diff --git a/src/kOS.Safe.Test/StructureSuffixIntegrationTest.cs b/src/kOS.Safe.Test/StructureSuffixIntegrationTest.cs deleted file mode 100644 index 6b650a3b6..000000000 --- a/src/kOS.Safe.Test/StructureSuffixIntegrationTest.cs +++ /dev/null @@ -1,96 +0,0 @@ -using System.Runtime.CompilerServices; -using NUnit.Framework; -using kOS.Safe.Encapsulation.Suffixes; -using kOS.Safe.Utilities; - -namespace kOS.Safe.Test -{ - [TestFixture] - public class StructureSuffixIntegrationTest - { - [TestFixtureSetUp] - public void Setup() - { - SafeHouse.Logger = new TestLogger(); - } - - [Test] - public void CanAddSuffix() - { - var structure = new StructureTest.TestStructure(); - var strongBox = new StrongBox(false); - structure.TestAddInstanceSuffix("FOO", new Suffix(BuildBasicGetter(strongBox))); - Assert.IsFalse((bool) structure.GetSuffix("FOO")); - } - - [Test] - public void CanReflectChangeInUnderlyingData() - { - var structure = new StructureTest.TestStructure(); - var strongBox = new StrongBox(false); - structure.TestAddInstanceSuffix("FOO", new Suffix(BuildBasicGetter(strongBox))); - - strongBox.Value = false; - Assert.IsFalse((bool) structure.GetSuffix("FOO")); - strongBox.Value = true; - Assert.IsTrue((bool) structure.GetSuffix("FOO")); - } - - [Test] - public void CanAddSetSuffix() - { - var structure = new StructureTest.TestStructure(); - var strongBox = new StrongBox(false); - structure.TestAddInstanceSuffix("FOO", new SetSuffix(BuildBasicGetter(strongBox), BuildBasicSetter(strongBox))); - - Assert.IsFalse((bool) structure.GetSuffix("FOO")); - } - - [Test] - public void CanSetSuffix() - { - const int TEST_VALUE = 12345; - var structure = new StructureTest.TestStructure(); - var strongBox = new StrongBox(TEST_VALUE); - structure.TestAddInstanceSuffix("FOO", new SetSuffix(BuildBasicGetter(strongBox), BuildBasicSetter(strongBox))); - structure.TestAddInstanceSuffix("BAR", new SetSuffix(BuildBasicGetter(strongBox), BuildBasicSetter(strongBox))); - - Assert.AreEqual(TEST_VALUE, structure.GetSuffix("FOO")); - structure.SetSuffix("FOO", TEST_VALUE - 10); - Assert.AreEqual(TEST_VALUE - 10, structure.GetSuffix("FOO")); - structure.SetSuffix("FOO", TEST_VALUE / 20); - Assert.AreEqual(TEST_VALUE / 20, structure.GetSuffix("FOO")); - } - - [Test] - public void TwoSuffixesCanShareAModel() - { - const int TEST_VALUE = 12345; - var structure = new StructureTest.TestStructure(); - var strongBox = new StrongBox(TEST_VALUE); - structure.TestAddInstanceSuffix("FOO", new SetSuffix(BuildBasicGetter(strongBox), BuildBasicSetter(strongBox))); - structure.TestAddInstanceSuffix("BAR", new SetSuffix(BuildBasicGetter(strongBox), BuildBasicSetter(strongBox))); - - Assert.AreEqual(TEST_VALUE, structure.GetSuffix("FOO")); - Assert.AreEqual(TEST_VALUE, structure.GetSuffix("BAR")); - structure.SetSuffix("FOO", TEST_VALUE - 10); - Assert.AreEqual(TEST_VALUE - 10, structure.GetSuffix("FOO")); - Assert.AreEqual(TEST_VALUE - 10, structure.GetSuffix("BAR")); - structure.SetSuffix("BAR", TEST_VALUE / 20); - Assert.AreEqual(TEST_VALUE / 20, structure.GetSuffix("BAR")); - Assert.AreEqual(TEST_VALUE / 20, structure.GetSuffix("FOO")); - } - - private static SuffixSetDlg BuildBasicSetter(StrongBox state) - { - SuffixSetDlg setter = value => state.Value = value; - return setter; - } - - private static SuffixGetDlg BuildBasicGetter(StrongBox state) - { - SuffixGetDlg getter = () => state.Value; - return getter; - } - } -} diff --git a/src/kOS.Safe.Test/Structures/BooleanValueTest.cs b/src/kOS.Safe.Test/Structures/BooleanValueTest.cs new file mode 100644 index 000000000..6edec61b4 --- /dev/null +++ b/src/kOS.Safe.Test/Structures/BooleanValueTest.cs @@ -0,0 +1,129 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using kOS.Safe.Encapsulation; +using NUnit.Framework; + +namespace kOS.Safe.Test.Structures +{ + [TestFixture] + public class BooleanValueTest + { + [Test] + public void CanConstructFromBool() + { + bool b = true; + BooleanValue bv = new BooleanValue(b); + Assert.AreEqual(b, bv.Value); + Assert.IsTrue(b == bv); + Assert.IsFalse(b == !bv); + Assert.IsFalse(b != bv); + Assert.IsFalse(!b == bv); + } + + [Test] + public void CanImplicitlyConvertToBool() + { + bool b = true; + BooleanValue bv = new BooleanValue(b); + bool b2 = bv; + Assert.AreEqual(b, b2); + Assert.IsTrue(b == bv); + Assert.IsFalse(b != bv); + } + + [Test] + public void CanAddAsString() + { + bool b = true; + string string1 = "foo"; + var str1 = new StringValue(string1); + var bv = new BooleanValue(b); + var strResult = str1 + bv; + string stringResult = string1 + b.ToString(); + Assert.AreEqual(stringResult, (string)strResult); + } + + [Test] + public void CanNullCheck() + { + BooleanValue bv = null; + Assert.IsTrue(bv == null); + Assert.IsFalse(bv != null); + Assert.IsTrue(null == bv); + Assert.IsFalse(null != bv); + bv = new BooleanValue(true); + Assert.IsTrue(bv != null); + Assert.IsFalse(bv == null); + Assert.IsTrue(null != bv); + Assert.IsFalse(null == bv); + bv = new BooleanValue(false); + Assert.IsTrue(bv != null); + Assert.IsFalse(bv == null); + Assert.IsTrue(null != bv); + Assert.IsFalse(null == bv); + + bv = new BooleanValue(true); + Assert.IsTrue(bv != null); + Assert.IsFalse(bv == null); + Assert.IsTrue(null != bv); + Assert.IsFalse(null == bv); + bv = new BooleanValue(false); + Assert.IsTrue(bv != null); + Assert.IsFalse(bv == null); + Assert.IsTrue(null != bv); + Assert.IsFalse(null == bv); + } + + [Test] + public void CanCompareToScalar() + { + BooleanValue bv = new BooleanValue(true); + ScalarValue sv = ScalarValue.Create(1); + Assert.IsTrue(bv == sv); + Assert.IsFalse(bv != sv); + Assert.IsTrue(sv == bv); + Assert.IsFalse(sv != bv); + sv = ScalarValue.Create(0); + Assert.IsTrue(bv != sv); + Assert.IsFalse(bv == sv); + Assert.IsTrue(sv != bv); + Assert.IsFalse(sv == bv); + sv = ScalarValue.Create(3.1415926535897932384626433832795); + Assert.IsTrue(bv == sv); + Assert.IsFalse(bv != sv); + Assert.IsTrue(sv == bv); + Assert.IsFalse(sv != bv); + sv = ScalarValue.Create(0.0d); + Assert.IsTrue(bv != sv); + Assert.IsFalse(bv == sv); + Assert.IsTrue(sv != bv); + Assert.IsFalse(sv == bv); + + bv = new BooleanValue(false); + sv = ScalarValue.Create(1); + Assert.IsTrue(bv != sv); + Assert.IsFalse(bv == sv); + Assert.IsTrue(sv != bv); + Assert.IsFalse(sv == bv); + sv = ScalarValue.Create(0); + Assert.IsTrue(bv == sv); + Assert.IsFalse(bv != sv); + Assert.IsTrue(sv == bv); + Assert.IsFalse(sv != bv); + sv = ScalarValue.Create(3.1415926535897932384626433832795); + Assert.IsTrue(bv != sv); + Assert.IsFalse(bv == sv); + Assert.IsTrue(sv != bv); + Assert.IsFalse(sv == bv); + Assert.IsFalse(bv.Equals(sv)); + sv = ScalarValue.Create(0.0d); + Assert.IsTrue(bv == sv); + Assert.IsFalse(bv != sv); + Assert.IsTrue(sv == bv); + Assert.IsFalse(sv != bv); + Assert.IsFalse(bv.Equals(sv)); + } + } +} diff --git a/src/kOS.Safe.Test/Structures/ScalarValueTest.cs b/src/kOS.Safe.Test/Structures/ScalarValueTest.cs new file mode 100644 index 000000000..6fc6f7e15 --- /dev/null +++ b/src/kOS.Safe.Test/Structures/ScalarValueTest.cs @@ -0,0 +1,222 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using kOS.Safe.Encapsulation; +using NUnit.Framework; + +namespace kOS.Safe.Test.Structures +{ + [TestFixture] + public class ScalarValueTest + { + [Test] + public void CanConvertInt() + { + int i = 10; + var s = ScalarValue.Create(i); + Assert.IsTrue(s.IsInt); + Assert.IsFalse(s.IsDouble); + Assert.AreEqual(i, (int)s); + } + + [Test] + public void CanConvertDouble() + { + double d = 3.1415926535897932384626433832795; + var s = ScalarValue.Create(d); + Assert.IsFalse(s.IsInt); + Assert.IsTrue(s.IsDouble); + Assert.AreEqual(d, (double)s); + } + + [Test] + public void CanStructureFromPrimitiveInt() + { + int i = 10; + var s = kOS.Safe.Encapsulation.Structure.FromPrimitive(i); + Assert.AreEqual(i, (ScalarValue)s); + } + + [Test] + public void CanStructureFromPrimitiveDouble() + { + double d = 3.1415926535897932384626433832795; + var s = kOS.Safe.Encapsulation.Structure.FromPrimitive(d); + Assert.AreEqual(d, (ScalarValue)s, 0d); + } + + [Test] + public void CanStructureToPrimitiveInt() + { + int i = 10; + var s = ScalarValue.Create(i); + var iTest = kOS.Safe.Encapsulation.Structure.ToPrimitive(s); + Assert.AreEqual(i, (int)iTest); + } + + [Test] + public void CanStructureToPrimitiveDouble() + { + double d = 3.1415926535897932384626433832795; + var s = ScalarValue.Create(d); + var dTest = kOS.Safe.Encapsulation.Structure.ToPrimitive(s); + Assert.AreEqual(d, (double)dTest, 0d); + } + + [Test] + public void CanImplicitCastToInt() + { + int i = 10; + var s = ScalarValue.Create(i); + int iTest = s; + Assert.AreEqual(i, iTest); + } + + [Test] + public void CanImplicitCastToDouble() + { + double d = 3.1415926535897932384626433832795; + var s = ScalarValue.Create(d); + double dTest = s; + Assert.AreEqual(d, dTest); + } + + [Test] + public void CanImplicitCastFromInt() + { + int i = 10; + var s = ScalarValue.Create(i); + ScalarValue sTest = i; + Assert.AreEqual(s, sTest); + } + + [Test] + public void CanImplicitCastFromDouble() + { + double d = 3.1415926535897932384626433832795; + var s = ScalarValue.Create(d); + ScalarValue sTest = d; + Assert.AreEqual(s, sTest); + } + + [Test] + public void CanAdd() + { + double d1 = 10.5; + double d2 = 5.25; + var s1 = ScalarValue.Create(d1); + var s2 = ScalarValue.Create(d2); + double dResult = d1 + d2; + ScalarValue sResult = s1 + s2; + Assert.AreEqual(dResult, sResult, 0d); + } + + [Test] + public void CanAddMixedType() + { + double d1 = 10.5; + int i2 = 5; + var s1 = ScalarValue.Create(d1); + var s2 = ScalarValue.Create(i2); + double dResult = d1 + i2; + ScalarValue sResult = s1 + s2; + Assert.AreEqual(dResult, sResult, 0d); + } + + [Test] + public void CanSubtract() + { + double d1 = 10.5; + double d2 = 5.25; + var s1 = ScalarValue.Create(d1); + var s2 = ScalarValue.Create(d2); + double dResult = d1 - d2; + ScalarValue sResult = s1 - s2; + Assert.AreEqual(dResult, sResult, 0d); + } + + [Test] + public void CanMultiply() + { + double d1 = 10.5; + double d2 = 5.25; + var s1 = ScalarValue.Create(d1); + var s2 = ScalarValue.Create(d2); + double dResult = d1 * d2; + ScalarValue sResult = s1 * s2; + Assert.AreEqual(dResult, sResult, 0d); + } + + [Test] + public void CanDivide() + { + double d1 = 10.5; + double d2 = 5.25; + var s1 = ScalarValue.Create(d1); + var s2 = ScalarValue.Create(d2); + double dResult = d1 / d2; + ScalarValue sResult = s1 / s2; + Assert.AreEqual(dResult, sResult, 0d); + } + + [Test] + public void CanPower() + { + double d1 = 10.5; + double d2 = 5.25; + var s1 = ScalarValue.Create(d1); + var s2 = ScalarValue.Create(d2); + double dResult = Math.Pow(d1, d2); + ScalarValue sResult = s1 ^ s2; + Assert.AreEqual(dResult, sResult, 0d); + } + + [Test] + public void CanModulus() + { + double d1 = 10.5; + double d2 = 5.25; + var s1 = ScalarValue.Create(d1); + var s2 = ScalarValue.Create(d2); + double dResult = d1 % d2; + ScalarValue sResult = s1 % s2; + Assert.AreEqual(dResult, sResult, 0d); + } + + [Test] + public void CanAddAsString() + { + double d1 = 10.5; + string string1 = "foo"; + var str1 = new StringValue(string1); + var s1 = ScalarValue.Create(d1); + var strResult = str1 + s1; + string stringResult = string1 + d1.ToString(); + Assert.AreEqual(stringResult, (string)strResult); + } + + [Test] + public void CanNullCheck() + { + ScalarValue sv = null; + Assert.IsTrue(sv == null); + Assert.IsFalse(sv != null); + sv = ScalarValue.Create(1); + Assert.IsTrue(sv != null); + Assert.IsFalse(sv == null); + Assert.IsTrue(null != sv); + Assert.IsFalse(null == sv); + sv = ScalarValue.Create(0); + Assert.IsTrue(sv != null); + Assert.IsFalse(sv == null); + Assert.IsTrue(null != sv); + Assert.IsFalse(null == sv); + sv = ScalarValue.Create(3.1415926535897932384626433832795); + Assert.IsTrue(sv != null); + Assert.IsFalse(sv == null); + Assert.IsTrue(null != sv); + Assert.IsFalse(null == sv); + } + } +} diff --git a/src/kOS.Safe.Test/Structures/StringValueTest.cs b/src/kOS.Safe.Test/Structures/StringValueTest.cs new file mode 100644 index 000000000..698ee8b05 --- /dev/null +++ b/src/kOS.Safe.Test/Structures/StringValueTest.cs @@ -0,0 +1,169 @@ +using System.Collections.Generic; +using kOS.Safe.Encapsulation; +using NUnit.Framework; + +namespace kOS.Safe.Test.Structures +{ + [TestFixture] + public class StringValueTest + { + [Test] + public void CanMakeEmpty() + { + var sv = new StringValue(); + + Assert.AreEqual(string.Empty, sv.ToString()); + } + + [Test] + public void CanToString() + { + var testValue = "foobar"; + var sv = new StringValue(testValue); + + Assert.AreEqual(testValue, sv.ToString()); + } + + [Test] + public void CanPreserveCase() + { + var testValue = "FooBar"; + var sv = new StringValue(testValue); + + Assert.AreEqual(testValue, sv.ToString()); + } + + [Test] + public void CanStartsWith() + { + var testValue = "FooBar"; + var sv = new StringValue(testValue); + + //Case Sensitive + Assert.IsTrue(sv.StartsWith(testValue)); + + //Case Insensitive + Assert.IsTrue(sv.StartsWith(testValue.ToLower())); + Assert.IsTrue(sv.StartsWith(testValue.ToUpper())); + } + + [Test] + public void CanEndsWith() + { + var testValue = "FooBar"; + var sv = new StringValue(testValue); + + //Case Sensitive + Assert.IsTrue(sv.EndsWith(testValue)); + + //Case Insensitive + Assert.IsTrue(sv.EndsWith(testValue.ToLower())); + Assert.IsTrue(sv.EndsWith(testValue.ToUpper())); + } + + [Test] + public void CanContains() + { + var testValue = "FooBar"; + var sv = new StringValue(testValue); + + //Case Sensitive + Assert.IsTrue(sv.Contains(testValue)); + + //Case Insensitive + Assert.IsTrue(sv.Contains(testValue.ToLower())); + Assert.IsTrue(sv.Contains(testValue.ToUpper())); + } + + [Test] + public void CanFindAt() + { + var testValue = "FooBarFooBar"; + var findChar = "F"; + var expectedIndex = 6; + var sv = new StringValue(testValue); + + //Case Sensitive + Assert.AreEqual(expectedIndex, sv.FindAt(findChar, 4)); + + //Case Insensitive + Assert.AreEqual(expectedIndex, sv.FindAt(findChar.ToLower(), 4)); + } + + [Test] + public void CanFindLastAt() + { + var testValue = "FooBarFooBar"; + var findChar = "F"; + var expectedIndex = 6; + var sv = new StringValue(testValue); + + //Case Sensitive + Assert.AreEqual(expectedIndex, sv.FindLastAt(findChar, 8)); + + //Case Insensitive + Assert.AreEqual(expectedIndex, sv.FindLastAt(findChar.ToLower(), 8)); + } + + [Test] + public void CanSplit() + { + var testValue = "FooBarFooBar"; + var findChar = "F"; + var expectedList = new List { new StringValue(string.Empty), new StringValue("ooBar"), new StringValue("ooBar") }; + var sv = new StringValue(testValue); + + //Case Sensitive + CollectionAssert.AreEqual(expectedList, sv.SplitToList(findChar)); + + //Case Insensitive + CollectionAssert.AreEqual(expectedList, sv.SplitToList(findChar.ToLower())); + } + + [Test] + public void CanIndexOf() + { + var testValue = "FooBarFooBar"; + var findChar = "F"; + var expectedIndex = 0; + var sv = new StringValue(testValue); + + //Case Sensitive + Assert.AreEqual(expectedIndex, sv.IndexOf(findChar)); + + //Case Insensitive + Assert.AreEqual(expectedIndex, sv.IndexOf(findChar.ToLower())); + } + + [Test] + public void CanGetIndex() + { + var testValue = "FooBarFooBar"; + var findChar = 0; + var expectedIndex = new StringValue("F"); + var sv = new StringValue(testValue); + + //Case Sensitive + Assert.AreEqual(expectedIndex, sv.GetIndex(0)); + } + + [Test] + public void CanNullCheck() + { + StringValue testValue = null; + Assert.IsTrue(testValue == null); + Assert.IsFalse(testValue != null); + Assert.IsTrue(null == testValue); + Assert.IsFalse(null != testValue); + Assert.AreEqual(testValue, null); + Assert.AreEqual(null, testValue); + testValue = new StringValue("FooBar"); + Assert.IsTrue(testValue != null); + Assert.IsFalse(testValue == null); + Assert.IsTrue(null != testValue); + Assert.IsFalse(null == testValue); + Assert.AreNotEqual(testValue, null); + Assert.AreNotEqual(null, testValue); + } + } +} \ No newline at end of file diff --git a/src/kOS.Safe.Test/TwoArgsVoidSuffixTest.cs b/src/kOS.Safe.Test/TwoArgsVoidSuffixTest.cs deleted file mode 100644 index dcf4702f5..000000000 --- a/src/kOS.Safe.Test/TwoArgsVoidSuffixTest.cs +++ /dev/null @@ -1,44 +0,0 @@ -using System; -using NUnit.Framework; -using kOS.Safe.Encapsulation.Suffixes; -using NSubstitute; - -namespace kOS.Safe.Test -{ - [TestFixture] - public class TwoArgsVoidSuffixTest - { - [Test] - public void CanCreate() - { - var suffix = new TwoArgsSuffix((one, two) => { }); - Assert.IsNotNull(suffix.Get()); - } - - [Test] - public void CanGetDelegate() - { - var suffix = new TwoArgsSuffix((one, two) => { }); - var del = suffix.Get(); - Assert.IsNotNull(del); - var delegateAsDelegate = del as Delegate; - Assert.IsNotNull(delegateAsDelegate); - } - - [Test] - public void CanExecuteDelegate() - { - var mockDel = Substitute.For.Del>(); - - var suffix = new TwoArgsSuffix(mockDel); - var del = suffix.Get(); - Assert.IsNotNull(del); - var delegateAsDelegate = del as Delegate; - Assert.IsNotNull(delegateAsDelegate); - delegateAsDelegate.DynamicInvoke(new object(), new object()); - - mockDel.ReceivedWithAnyArgs(1); - } - - } -} diff --git a/src/kOS.Safe.Test/kOS.Safe.Test.csproj b/src/kOS.Safe.Test/kOS.Safe.Test.csproj index f81a9217e..95aaa7ce0 100644 --- a/src/kOS.Safe.Test/kOS.Safe.Test.csproj +++ b/src/kOS.Safe.Test/kOS.Safe.Test.csproj @@ -3,8 +3,6 @@ Debug AnyCPU - 8.0.30703 - 2.0 {C9A42A44-DDC8-4D6C-8A16-D7F30F494B46} Library Properties @@ -31,13 +29,13 @@ 4 - - False - ..\packages\NSubstitute.1.8.0.0\lib\net35\NSubstitute.dll + + ..\packages\NSubstitute.1.8.1.0\lib\net35\NSubstitute.dll + True - False ..\packages\NUnit.2.6.4\lib\nunit.framework.dll + True @@ -47,19 +45,33 @@ - - - - - - + + + + + + + + + + + + + + - + + + + + + + - {590ffda8-7b44-4bc3-a12a-5ffe2bb7d8fd} + {590FFDA8-7B44-4BC3-A12A-5FFE2BB7D8FD} kOS.Safe @@ -74,4 +86,11 @@ --> - \ No newline at end of file + + + + + + + + diff --git a/src/kOS.Safe.Test/packages.config b/src/kOS.Safe.Test/packages.config index f08b41f9e..7620a4afc 100644 --- a/src/kOS.Safe.Test/packages.config +++ b/src/kOS.Safe.Test/packages.config @@ -1,5 +1,5 @@  - + \ No newline at end of file diff --git a/src/kOS.Safe/Binding/BoundVariable.cs b/src/kOS.Safe/Binding/BoundVariable.cs index e00f3a7ff..5c9dd5b2e 100644 --- a/src/kOS.Safe/Binding/BoundVariable.cs +++ b/src/kOS.Safe/Binding/BoundVariable.cs @@ -1,5 +1,5 @@ -using System; -using kOS.Safe.Execution; +using kOS.Safe.Execution; +using kOS.Safe.Encapsulation; namespace kOS.Safe.Binding { @@ -14,23 +14,26 @@ public override object Value { get { - if (Get != null) - { - if (currentValue == null) - { - currentValue = Get(); - if (currentValue is float) - // promote floats to doubles - currentValue = Convert.ToDouble(currentValue); - } - return currentValue; - } - return null; + if (Get == null) return null; + + // This code used to simply elevate float variables to doubles. With the + // new primitive encapsulation types we instead encapsulate any value returned + // by the delegate. This makes it so that all of the getters for bound variables + // don't need to be modified to explicitly return the encapsulated types. + return currentValue ?? (currentValue = Structure.FromPrimitive(Get())); } set { if (Set == null) return; - Set(value); + // By converting to the primitive value of an encapsulated type, we can avoid a clash + // between unboxing and casting in the set delegate. While the new encapsulated types + // support implicit conversion to their primitive counterparts, .net and mono treat + // "(double)object" as an unboxing, and "(double)float" or "(double)ScalarValue" as + // a cast. As a result, the correct cast in the Set delegate would become + // "(double)(ScalarValue)object" since it will unbox the object, and then cast it. + // If the delegates supported typing, we could use "Convert" to do this unbox/conversion + // all at the same time. Instead, we pass the primitive value to avoid these conflicts. + Set(Structure.ToPrimitive(value)); } } diff --git a/src/kOS.Safe/Binding/IBindingManager.cs b/src/kOS.Safe/Binding/IBindingManager.cs new file mode 100644 index 000000000..a843b11e7 --- /dev/null +++ b/src/kOS.Safe/Binding/IBindingManager.cs @@ -0,0 +1,20 @@ +using System.Collections.Generic; + +namespace kOS.Safe.Binding +{ + public interface IBindingManager + { + void Load(); + void AddBoundVariable(string name, BindingGetDlg getDelegate, BindingSetDlg setDelegate); + void AddGetter(string name, BindingGetDlg dlg); + void AddGetter(IEnumerable names, BindingGetDlg dlg); + void AddSetter(string name, BindingSetDlg dlg); + void AddSetter(IEnumerable names, BindingSetDlg dlg); + void PreUpdate(); + void PostUpdate(); + void ToggleFlyByWire(string paramName, bool enabled); + void UnBindAll(); + void Dispose(); + void SelectAutopilotMode(string autopilotMode); + } +} \ No newline at end of file diff --git a/src/kOS.Safe/Compilation/Calculator.cs b/src/kOS.Safe/Compilation/Calculator.cs index 611e33ef1..a3110efa1 100644 --- a/src/kOS.Safe/Compilation/Calculator.cs +++ b/src/kOS.Safe/Compilation/Calculator.cs @@ -1,561 +1,46 @@ -using System; using kOS.Safe.Encapsulation; -using kOS.Safe.Exceptions; +using System; namespace kOS.Safe.Compilation { public abstract class Calculator { - public abstract object Add(object argument1, object argument2); - public abstract object Subtract(object argument1, object argument2); - public abstract object Multiply(object argument1, object argument2); - public abstract object Divide(object argument1, object argument2); - public abstract object Power(object argument1, object argument2); - public abstract object GreaterThan(object argument1, object argument2); - public abstract object LessThan(object argument1, object argument2); - public abstract object GreaterThanEqual(object argument1, object argument2); - public abstract object LessThanEqual(object argument1, object argument2); - public abstract object NotEqual(object argument1, object argument2); - public abstract object Equal(object argument1, object argument2); - public abstract object Min(object argument1, object argument2); - public abstract object Max(object argument1, object argument2); - - public static Calculator GetCalculator(object argument1, object argument2) - { - int intCount = 0; - int doubleCount = 0; - int stringCount = 0; - int specialCount = 0; - int boolCount = 0; - - // convert floats to doubles - if (argument1 is float) argument1 = Convert.ToDouble(argument1); - if (argument2 is float) argument2 = Convert.ToDouble(argument2); - - if (argument1 is int) intCount++; - if (argument1 is double) doubleCount++; - if (argument1 is string) stringCount++; - if (argument1 is ISuffixed) specialCount++; - if (argument1 is bool) boolCount++; - if (argument2 is int) intCount++; - if (argument2 is double) doubleCount++; - if (argument2 is string) stringCount++; - if (argument2 is ISuffixed) specialCount++; - if (argument2 is bool) boolCount++; - - if (intCount == 2) return new CalculatorIntInt(); - if (doubleCount == 2) return new CalculatorDoubleDouble(); - if (intCount == 1 && doubleCount == 1) return new CalculatorIntDouble(); + public abstract object Add(OperandPair pair); + public abstract object Subtract(OperandPair pair); + public abstract object Multiply(OperandPair pair); + public abstract object Divide(OperandPair pair); + public abstract object Power(OperandPair pair); + public abstract object GreaterThan(OperandPair pair); + public abstract object LessThan(OperandPair pair); + public abstract object GreaterThanEqual(OperandPair pair); + public abstract object LessThanEqual(OperandPair pair); + public abstract object NotEqual(OperandPair pair); + public abstract object Equal(OperandPair pair); + public abstract object Min(OperandPair pair); + public abstract object Max(OperandPair pair); + + public static Calculator GetCalculator(OperandPair operandPair) + { + var scalarCount = 0; + var stringCount = 0; + var specialCount = 0; + var boolCount = 0; + + if (operandPair.Left is ScalarValue) scalarCount++; + if (operandPair.Left is StringValue) stringCount++; + if (operandPair.Left is ISuffixed) specialCount++; + if (operandPair.Left is BooleanValue) boolCount++; + if (operandPair.Right is ScalarValue) scalarCount++; + if (operandPair.Right is StringValue) stringCount++; + if (operandPair.Right is ISuffixed) specialCount++; + if (operandPair.Right is BooleanValue) boolCount++; + + if (scalarCount == 2) return new CalculatorScalar(); if (stringCount > 0) return new CalculatorString(); if (boolCount > 0) return new CalculatorBool(); if (specialCount > 0) return new CalculatorStructure(); - throw new NotImplementedException(string.Format("Can't operate types {0} and {1}", argument1.GetType(), argument2.GetType())); - } - } - - public class CalculatorIntInt : Calculator - { - /// If result is too big to fit in an int32, then turn it - /// into a double (since kOS doesn't do long's): - /// The value to maybe promote. Use long so it - /// is capable of storing numbers too big for int. - /// the value, possibly promoted to double - private object PromoteIfTooBig(long result) - { - if (Math.Abs(result) <= int.MaxValue) return (int)result; - return (double)result; - } - - /// If result is too big to fit in an int32, then turn it - /// into a double (since kOS doesn't do long's): - /// The value to maybe promote. - /// the value, possibly promoted to double - private object PromoteIfTooBig(double result) - { - if (Math.Abs(result) <= int.MaxValue) return (int)result; - return (double)result; - } - - public override object Add(object argument1, object argument2) - { - // C# doesn't know how to both unbox the object and promote it in the same cast, thus the (long)(int) syntax: - return PromoteIfTooBig((long)(int)argument1 + (long)(int)argument2); - } - - public override object Subtract(object argument1, object argument2) - { - // C# doesn't know how to both unbox the object and promote it in the same cast, thus the (long)(int) syntax: - return PromoteIfTooBig((long)(int)argument1 - (long)(int)argument2); - } - - public override object Multiply(object argument1, object argument2) - { - // C# doesn't know how to both unbox the object and promote it in the same cast, thus the (long)(int) syntax: - return PromoteIfTooBig((long)(int)argument1 * (long)(int)argument2); - } - - public override object Divide(object argument1, object argument2) - { - // Avoid integer division truncation. Make double - // if there's a fractional part to preserve: - int remainder = (int)argument1 % (int)argument2; - if (remainder == 0) - return (int)argument1 / (int)argument2; - else - return Convert.ToDouble((int)argument1) /(int)argument2; - } - - public override object Power(object argument1, object argument2) - { - // If the exponent is negative, then integer power operations would normally - // round to zero (i.e. 4^(-2) is (1/16) which rounds to zero). This - // checks for that condition and if it happens it turns into a double operation: - if ((int)argument2 < 0) - return Math.Pow(Convert.ToDouble((int)argument1), Convert.ToDouble((int)argument2)); - else - // C# doesn't know how to both unbox the object and promote it in the same cast, thus the (long)(int) syntax: - return PromoteIfTooBig(Math.Pow((long)(int)argument1, (long)(int)argument2)); - } - - public override object GreaterThan(object argument1, object argument2) - { - return (int)argument1 > (int)argument2; - } - - public override object LessThan(object argument1, object argument2) - { - return (int)argument1 < (int)argument2; - } - - public override object GreaterThanEqual(object argument1, object argument2) - { - return (int)argument1 >= (int)argument2; - } - - public override object LessThanEqual(object argument1, object argument2) - { - return (int)argument1 <= (int)argument2; - } - - public override object NotEqual(object argument1, object argument2) - { - return (int)argument1 != (int)argument2; - } - - public override object Equal(object argument1, object argument2) - { - return (int)argument1 == (int)argument2; - } - - public override object Min(object argument1, object argument2) - { - return Math.Min((int)argument1, (int)argument2); - } - - public override object Max(object argument1, object argument2) - { - return Math.Max((int)argument1, (int)argument2); - } - } - - public class CalculatorDoubleDouble : Calculator - { - /// - /// Turn the double into an integer if the value is - /// a round number without a fractional component, - /// and it's small enough magnitude to fit in an int. - /// - /// the value to maybe demote - /// the value, possibly demoted - public object DemoteIfRound(double result) - { - if (Math.Floor(result) == result && (Math.Abs(result) <= int.MaxValue)) - return (int)result; - return (double)result; - } - - public override object Add(object argument1, object argument2) - { - return DemoteIfRound((double)argument1 + (double)argument2); - } - - public override object Subtract(object argument1, object argument2) - { - return DemoteIfRound((double)argument1 - (double)argument2); - } - - public override object Multiply(object argument1, object argument2) - { - return DemoteIfRound((double)argument1 * (double)argument2); - } - - public override object Divide(object argument1, object argument2) - { - return DemoteIfRound((double)argument1 / (double)argument2); - } - - public override object Power(object argument1, object argument2) - { - return DemoteIfRound(Math.Pow((double)argument1, (double)argument2)); - } - - public override object GreaterThan(object argument1, object argument2) - { - return (double)argument1 > (double)argument2; - } - - public override object LessThan(object argument1, object argument2) - { - return (double)argument1 < (double)argument2; - } - - public override object GreaterThanEqual(object argument1, object argument2) - { - return (double)argument1 >= (double)argument2; - } - - public override object LessThanEqual(object argument1, object argument2) - { - return (double)argument1 <= (double)argument2; - } - - public override object NotEqual(object argument1, object argument2) - { - return (double)argument1 != (double)argument2; - } - - public override object Equal(object argument1, object argument2) - { - return (double)argument1 == (double)argument2; - } - - public override object Min(object argument1, object argument2) - { - return Math.Min((double)argument1, (double)argument2); - } - - public override object Max(object argument1, object argument2) - { - return Math.Max((double)argument1, (double)argument2); - } - } - - public class CalculatorIntDouble : Calculator - { - /// - /// Turn the double into an integer if the value is - /// a round number without a fractional component, - /// and it's small enough magnitude to fit in an int. - /// - /// the value to maybe demote - /// the value, possibly demoted - public object DemoteIfRound(double result) - { - if (Math.Floor(result) == result && (Math.Abs(result) <= int.MaxValue)) - return (int)result; - return (double)result; - } - - public override object Add(object argument1, object argument2) - { - if (argument1 is int) return DemoteIfRound((int)argument1 + (double)argument2); - return DemoteIfRound((double)argument1 + (int)argument2); - } - - public override object Subtract(object argument1, object argument2) - { - if (argument1 is int) return DemoteIfRound((int)argument1 - (double)argument2); - return DemoteIfRound((double)argument1 - (int)argument2); - } - - public override object Multiply(object argument1, object argument2) - { - if (argument1 is int) return DemoteIfRound((int)argument1 * (double)argument2); - return DemoteIfRound((double)argument1 * (int)argument2); - } - - public override object Divide(object argument1, object argument2) - { - if (argument1 is int) return DemoteIfRound((int)argument1 / (double)argument2); - return DemoteIfRound((double)argument1 / (int)argument2); - } - - public override object Power(object argument1, object argument2) - { - if (argument1 is int) return DemoteIfRound(Math.Pow((int)argument1, (double)argument2)); - return DemoteIfRound(Math.Pow((double)argument1, (int)argument2)); - } - - public override object GreaterThan(object argument1, object argument2) - { - if (argument1 is int) return (int)argument1 > (double)argument2; - return (double)argument1 > (int)argument2; - } - - public override object LessThan(object argument1, object argument2) - { - if (argument1 is int) return (int)argument1 < (double)argument2; - return (double)argument1 < (int)argument2; - } - - public override object GreaterThanEqual(object argument1, object argument2) - { - if (argument1 is int) return (int)argument1 >= (double)argument2; - return (double)argument1 >= (int)argument2; - } - - public override object LessThanEqual(object argument1, object argument2) - { - if (argument1 is int) return (int)argument1 <= (double)argument2; - return (double)argument1 <= (int)argument2; - } - - public override object NotEqual(object argument1, object argument2) - { - if (argument1 is int) return (int)argument1 != (double)argument2; - return (double)argument1 != (int)argument2; - } - - public override object Equal(object argument1, object argument2) - { - if (argument1 is int) return (int)argument1 == (double)argument2; - return (double)argument1 == (int)argument2; - } - - public override object Min(object argument1, object argument2) - { - if (argument1 is int) return Math.Min((int)argument1, (double)argument2); - return Math.Min((double)argument1, (int)argument2); - } - - public override object Max(object argument1, object argument2) - { - if (argument1 is int) return Math.Max((int)argument1, (double)argument2); - return Math.Max((double)argument1, (int)argument2); - } - } - - public class CalculatorString : Calculator - { - public override object Add(object argument1, object argument2) - { - return argument1.ToString() + argument2.ToString(); - } - - public override object Subtract(object argument1, object argument2) - { - throw new KOSBinaryOperandTypeException(argument2, "subtract", "from", argument1); - } - - public override object Multiply(object argument1, object argument2) - { - throw new KOSBinaryOperandTypeException(argument1, "multiply", "by", argument2); - } - - public override object Divide(object argument1, object argument2) - { - throw new KOSBinaryOperandTypeException(argument1, "divide", "by", argument2); - } - - public override object Power(object argument1, object argument2) - { - throw new KOSBinaryOperandTypeException(argument1, "exponentiate", "by", argument2); - } - - public override object GreaterThan(object argument1, object argument2) - { - return argument1.ToString().Length > argument2.ToString().Length; - } - - public override object LessThan(object argument1, object argument2) - { - return argument1.ToString().Length < argument2.ToString().Length; - } - - public override object GreaterThanEqual(object argument1, object argument2) - { - return argument1.ToString().Length >= argument2.ToString().Length; - } - - public override object LessThanEqual(object argument1, object argument2) - { - return argument1.ToString().Length <= argument2.ToString().Length; - } - - public override object NotEqual(object argument1, object argument2) - { - return argument1.ToString().ToLower() != argument2.ToString().ToLower(); - } - - public override object Equal(object argument1, object argument2) - { - return argument1.ToString().ToLower() == argument2.ToString().ToLower(); - } - - public override object Min(object argument1, object argument2) - { - string arg1 = argument1.ToString(); - string arg2 = argument2.ToString(); - return (arg1.Length < arg2.Length) ? arg1 : arg2; - } - - public override object Max(object argument1, object argument2) - { - string arg1 = argument1.ToString(); - string arg2 = argument2.ToString(); - return (arg1.Length > arg2.Length) ? arg1 : arg2; - } - } - - public class CalculatorBool : Calculator - { - public override object Add(object argument1, object argument2) - { - return Convert.ToBoolean(argument1) | Convert.ToBoolean(argument2); - } - - public override object Subtract(object argument1, object argument2) - { - throw new KOSBinaryOperandTypeException(argument2, "subtract", "from", argument1); - } - - public override object Multiply(object argument1, object argument2) - { - return Convert.ToBoolean(argument1) & Convert.ToBoolean(argument2); - } - - public override object Divide(object argument1, object argument2) - { - throw new KOSBinaryOperandTypeException(argument1, "divide", "by", argument2); - } - - public override object Power(object argument1, object argument2) - { - throw new KOSBinaryOperandTypeException(argument1, "exponentiate", "by", argument2); - } - - public override object GreaterThan(object argument1, object argument2) - { - // true > false - return Convert.ToBoolean(argument1) & !Convert.ToBoolean(argument2); - } - - public override object LessThan(object argument1, object argument2) - { - return !Convert.ToBoolean(argument1) & Convert.ToBoolean(argument2); - } - - public override object GreaterThanEqual(object argument1, object argument2) - { - bool arg1 = Convert.ToBoolean(argument1); - bool arg2 = Convert.ToBoolean(argument2); - return (arg1 & !arg2) | (arg1 == arg2); - } - - public override object LessThanEqual(object argument1, object argument2) - { - bool arg1 = Convert.ToBoolean(argument1); - bool arg2 = Convert.ToBoolean(argument2); - return (!arg1 & arg2) | (arg1 == arg2); - } - - public override object NotEqual(object argument1, object argument2) - { - return Convert.ToBoolean(argument1) != Convert.ToBoolean(argument2); - } - - public override object Equal(object argument1, object argument2) - { - return Convert.ToBoolean(argument1) == Convert.ToBoolean(argument2); - } - - public override object Min(object argument1, object argument2) - { - bool arg1 = Convert.ToBoolean(argument1); - bool arg2 = Convert.ToBoolean(argument2); - return arg1 && arg2; - } - - public override object Max(object argument1, object argument2) - { - bool arg1 = Convert.ToBoolean(argument1); - bool arg2 = Convert.ToBoolean(argument2); - return arg1 || arg2; - } - } - - public class CalculatorStructure : Calculator - { - private object Calculate(string op, object argument1, object argument2) - { - if (argument1 is IOperable) return ((IOperable)argument1).TryOperation(op, argument2, false); - return ((IOperable)argument2).TryOperation(op, argument1, true); - } - - public override object Add(object argument1, object argument2) - { - return Calculate("+", argument1, argument2); - } - - public override object Subtract(object argument1, object argument2) - { - return Calculate("-", argument1, argument2); - } - - public override object Multiply(object argument1, object argument2) - { - return Calculate("*", argument1, argument2); - } - - public override object Divide(object argument1, object argument2) - { - return Calculate("/", argument1, argument2); - } - - public override object Power(object argument1, object argument2) - { - return null; - } - - public override object GreaterThan(object argument1, object argument2) - { - return Calculate(">", argument1, argument2); - } - - public override object LessThan(object argument1, object argument2) - { - return Calculate("<", argument1, argument2); - } - - public override object GreaterThanEqual(object argument1, object argument2) - { - return Calculate(">=", argument1, argument2); - } - - public override object LessThanEqual(object argument1, object argument2) - { - return Calculate("<=", argument1, argument2); - } - - public override object NotEqual(object argument1, object argument2) - { - return Calculate("<>", argument1, argument2); - } - - public override object Equal(object argument1, object argument2) - { - return Calculate("==", argument1, argument2); - } - - public override object Min(object argument1, object argument2) - { - return Calculate("min", argument1, argument2); - } - - public override object Max(object argument1, object argument2) - { - return Calculate("max", argument1, argument2); + throw new NotImplementedException(string.Format("Can't operate types {0} and {1}", operandPair.Left.GetType(), operandPair.Right.GetType())); } } -} +} \ No newline at end of file diff --git a/src/kOS.Safe/Compilation/CalculatorBool.cs b/src/kOS.Safe/Compilation/CalculatorBool.cs new file mode 100644 index 000000000..399c5bdd3 --- /dev/null +++ b/src/kOS.Safe/Compilation/CalculatorBool.cs @@ -0,0 +1,74 @@ +using System; +using kOS.Safe.Encapsulation; +using kOS.Safe.Exceptions; + +namespace kOS.Safe.Compilation +{ + public class CalculatorBool : Calculator + { + public override object Add(OperandPair pair) + { + throw new KOSBinaryOperandTypeException(pair, "add", "to"); + } + + public override object Subtract(OperandPair pair) + { + throw new KOSBinaryOperandTypeException(pair, "subtract", "from"); + } + + public override object Multiply(OperandPair pair) + { + throw new KOSBinaryOperandTypeException(pair, "multiply", "by"); + } + + public override object Divide(OperandPair pair) + { + throw new KOSBinaryOperandTypeException(pair, "divide", "by"); + } + + public override object Power(OperandPair pair) + { + throw new KOSBinaryOperandTypeException(pair, "exponentiate", "by"); + } + + public override object GreaterThan(OperandPair pair) + { + throw new KOSBinaryOperandTypeException(pair, "ordinate", ">"); + } + + public override object LessThan(OperandPair pair) + { + throw new KOSBinaryOperandTypeException(pair, "ordinate", "<"); + } + + public override object GreaterThanEqual(OperandPair pair) + { + throw new KOSBinaryOperandTypeException(pair, "ordinate", ">="); + } + + public override object LessThanEqual(OperandPair pair) + { + throw new KOSBinaryOperandTypeException(pair, "ordinate", "<="); + } + + public override object NotEqual(OperandPair pair) + { + return new BooleanValue(Convert.ToBoolean(pair.Left) != Convert.ToBoolean(pair.Right)); + } + + public override object Equal(OperandPair pair) + { + return new BooleanValue(Convert.ToBoolean(pair.Left) == Convert.ToBoolean(pair.Right)); + } + + public override object Min(OperandPair pair) + { + throw new KOSBinaryOperandTypeException(pair, "get minimum of", "and"); + } + + public override object Max(OperandPair pair) + { + throw new KOSBinaryOperandTypeException(pair, "get maximum of", "and"); + } + } +} \ No newline at end of file diff --git a/src/kOS.Safe/Compilation/CalculatorScalar.cs b/src/kOS.Safe/Compilation/CalculatorScalar.cs new file mode 100644 index 000000000..36eea44ae --- /dev/null +++ b/src/kOS.Safe/Compilation/CalculatorScalar.cs @@ -0,0 +1,72 @@ +using kOS.Safe.Encapsulation; + +namespace kOS.Safe.Compilation +{ + public class CalculatorScalar : Calculator + { + public override object Add(OperandPair pair) + { + return ScalarValue.Create(pair.Left) + ScalarValue.Create(pair.Right); + } + + public override object Subtract(OperandPair pair) + { + return ScalarValue.Create(pair.Left) - ScalarValue.Create(pair.Right); + } + + public override object Multiply(OperandPair pair) + { + return ScalarValue.Create(pair.Left) * ScalarValue.Create(pair.Right); + } + + public override object Divide(OperandPair pair) + { + return ScalarValue.Create(pair.Left) / ScalarValue.Create(pair.Right); + } + + public override object Power(OperandPair pair) + { + return ScalarValue.Create(pair.Left) ^ ScalarValue.Create(pair.Right); + } + + public override object GreaterThan(OperandPair pair) + { + return ScalarValue.Create(pair.Left) > ScalarValue.Create(pair.Right); + } + + public override object LessThan(OperandPair pair) + { + return ScalarValue.Create(pair.Left) < ScalarValue.Create(pair.Right); + } + + public override object GreaterThanEqual(OperandPair pair) + { + return ScalarValue.Create(pair.Left) >= ScalarValue.Create(pair.Right); + } + + public override object LessThanEqual(OperandPair pair) + { + return ScalarValue.Create(pair.Left) <= ScalarValue.Create(pair.Right); + } + + public override object NotEqual(OperandPair pair) + { + return ScalarValue.Create(pair.Left) != ScalarValue.Create(pair.Right); + } + + public override object Equal(OperandPair pair) + { + return ScalarValue.Create(pair.Left) == ScalarValue.Create(pair.Right); + } + + public override object Min(OperandPair pair) + { + return ScalarValue.Min(ScalarValue.Create(pair.Left), ScalarValue.Create(pair.Right)); + } + + public override object Max(OperandPair pair) + { + return ScalarValue.Max(ScalarValue.Create(pair.Left), ScalarValue.Create(pair.Right)); + } + } +} \ No newline at end of file diff --git a/src/kOS.Safe/Compilation/CalculatorString.cs b/src/kOS.Safe/Compilation/CalculatorString.cs new file mode 100644 index 000000000..430878525 --- /dev/null +++ b/src/kOS.Safe/Compilation/CalculatorString.cs @@ -0,0 +1,84 @@ +using System; +using kOS.Safe.Encapsulation; +using kOS.Safe.Exceptions; + +namespace kOS.Safe.Compilation +{ + public class CalculatorString : Calculator + { + public override object Add(OperandPair pair) + { + return new StringValue(string.Concat(pair.Left, pair.Right)); + } + + public override object Subtract(OperandPair pair) + { + throw new KOSBinaryOperandTypeException(pair, "subtract", "from"); + } + + public override object Multiply(OperandPair pair) + { + throw new KOSBinaryOperandTypeException(pair, "multiply", "by"); + } + + public override object Divide(OperandPair pair) + { + throw new KOSBinaryOperandTypeException(pair, "divide", "by"); + } + + public override object Power(OperandPair pair) + { + throw new KOSBinaryOperandTypeException(pair, "exponentiate", "by"); + } + + public override object GreaterThan(OperandPair pair) + { + int compareNum = string.Compare(pair.Left.ToString(), pair.Right.ToString(), StringComparison.OrdinalIgnoreCase); + return compareNum > 0; + } + + public override object LessThan(OperandPair pair) + { + int compareNum = string.Compare(pair.Left.ToString(), pair.Right.ToString(), StringComparison.OrdinalIgnoreCase); + return compareNum < 0; + } + + public override object GreaterThanEqual(OperandPair pair) + { + int compareNum = string.Compare(pair.Left.ToString(), pair.Right.ToString(), StringComparison.OrdinalIgnoreCase); + return compareNum >= 0; + } + + public override object LessThanEqual(OperandPair pair) + { + int compareNum = string.Compare(pair.Left.ToString(), pair.Right.ToString(), StringComparison.OrdinalIgnoreCase); + return compareNum <= 0; + } + + public override object NotEqual(OperandPair pair) + { + return !string.Equals(pair.Left.ToString(), pair.Right.ToString(), StringComparison.OrdinalIgnoreCase); + } + + public override object Equal(OperandPair pair) + { + return string.Equals(pair.Left.ToString(), pair.Right.ToString(), StringComparison.OrdinalIgnoreCase); + } + + public override object Min(OperandPair pair) + { + string arg1 = pair.Left.ToString(); + string arg2 = pair.Right.ToString(); + int compareNum = string.Compare(arg1, arg2, StringComparison.OrdinalIgnoreCase); + return (compareNum < 0) ? arg1 : arg2; + } + + public override object Max(OperandPair pair) + { + string arg1 = pair.Left.ToString(); + string arg2 = pair.Right.ToString(); + int compareNum = string.Compare(arg1, arg2, StringComparison.OrdinalIgnoreCase); + return (compareNum > 0) ? arg1 : arg2; + } + } +} \ No newline at end of file diff --git a/src/kOS.Safe/Compilation/CalculatorStructure.cs b/src/kOS.Safe/Compilation/CalculatorStructure.cs new file mode 100644 index 000000000..8c9bca1a3 --- /dev/null +++ b/src/kOS.Safe/Compilation/CalculatorStructure.cs @@ -0,0 +1,311 @@ +using kOS.Safe.Encapsulation; +using System; +using System.Reflection; + +namespace kOS.Safe.Compilation +{ + public class CalculatorStructure : Calculator + { + private const BindingFlags FLAGS = BindingFlags.FlattenHierarchy | BindingFlags.Static | BindingFlags.Public; + + public override object Add(OperandPair pair) + { + CheckPairForNull(pair, "Add"); + + object result; + if (TryInvokeExplicit(pair, "op_Addition", out result)) + { + return result; + } + + OperandPair resultPair; + if (TryCoerceImplicit(pair, out resultPair)) + { + return Add(resultPair); + } + + return Calculate("+", pair); + } + + public override object Subtract(OperandPair pair) + { + CheckPairForNull(pair, "Subtract"); + + object result; + if (TryInvokeExplicit(pair, "op_Subtraction", out result)) + { + return result; + } + + OperandPair resultPair; + if (TryCoerceImplicit(pair, out resultPair)) + { + return Subtract(resultPair); + } + + return Calculate("-", pair); + } + + public override object Multiply(OperandPair pair) + { + CheckPairForNull(pair, "Multiply"); + + object result; + if (TryInvokeExplicit(pair, "op_Multiply", out result)) + { + return result; + } + + OperandPair resultPair; + if (TryCoerceImplicit(pair, out resultPair)) + { + return Multiply(resultPair); + } + + return Calculate("*", pair); + } + + public override object Divide(OperandPair pair) + { + CheckPairForNull(pair, "Divide"); + + object result; + if (TryInvokeExplicit(pair, "op_Division", out result)) + { + return result; + } + + OperandPair resultPair; + if (TryCoerceImplicit(pair, out resultPair)) + { + return Divide(resultPair); + } + + return Calculate("/", pair); + } + + public override object Power(OperandPair pair) + { + CheckPairForNull(pair, "Power"); + + object result; + if (TryInvokeExplicit(pair, "op_ExclusiveOr", out result)) + { + return result; + } + + OperandPair resultPair; + if (TryCoerceImplicit(pair, out resultPair)) + { + return Power(resultPair); + } + + return Calculate("^", pair); + } + + public override object GreaterThan(OperandPair pair) + { + CheckPairForNull(pair, "GreaterThan"); + + object result; + if (TryInvokeExplicit(pair, "op_GreaterThan", out result)) + { + return result; + } + + OperandPair resultPair; + if (TryCoerceImplicit(pair, out resultPair)) + { + return GreaterThan(resultPair); + } + + return Calculate(">", pair); + } + + public override object LessThan(OperandPair pair) + { + CheckPairForNull(pair, "LessThan"); + + object result; + if (TryInvokeExplicit(pair, "op_LessThan", out result)) + { + return result; + } + + OperandPair resultPair; + if (TryCoerceImplicit(pair, out resultPair)) + { + return LessThan(resultPair); + } + + return Calculate("<", pair); + } + + public override object GreaterThanEqual(OperandPair pair) + { + CheckPairForNull(pair, "GreaterThanEqual"); + + object result; + if (TryInvokeExplicit(pair, "op_GreaterThanEqual", out result)) + { + return result; + } + + OperandPair resultPair; + if (TryCoerceImplicit(pair, out resultPair)) + { + return GreaterThanEqual(resultPair); + } + + return Calculate(">=", pair); + } + + public override object LessThanEqual(OperandPair pair) + { + CheckPairForNull(pair, "LessThanEqual"); + + object result; + if (TryInvokeExplicit(pair, "op_LessThanEqual", out result)) + { + return result; + } + + OperandPair resultPair; + if (TryCoerceImplicit(pair, out resultPair)) + { + return LessThanEqual(resultPair); + } + + return Calculate("<=", pair); + } + + public override object NotEqual(OperandPair pair) + { + CheckPairForNull(pair, "NotEqual"); + + object result; + if (TryInvokeExplicit(pair, "op_Inequality", out result)) + { + return result; + } + + OperandPair resultPair; + if (TryCoerceImplicit(pair, out resultPair)) + { + return NotEqual(resultPair); + } + + return Calculate("<>", pair); + } + + public override object Equal(OperandPair pair) + { + CheckPairForNull(pair, "Equal"); + + object result; + if (TryInvokeExplicit(pair, "op_Equality", out result)) + { + return result; + } + + OperandPair resultPair; + if (TryCoerceImplicit(pair, out resultPair)) + { + return Equal(pair); + } + + return Calculate("==", pair); + } + + public override object Min(OperandPair pair) + { + CheckPairForNull(pair, "min"); + return Calculate("min", pair); + } + + public override object Max(OperandPair pair) + { + CheckPairForNull(pair, "max"); + return Calculate("max", pair); + } + + private object Calculate(string op, OperandPair pair) + { + var operable = pair.Left as IOperable; + if (operable == null) + { + return ((IOperable)pair.Right).TryOperation(op, pair.Left, true); + } + + return operable.TryOperation(op, pair.Right, false); + } + + private static string GetMessage(string op, OperandPair pair) + { + string t1 = pair.Left == null ? "" : pair.Left.GetType().ToString(); + string t2 = pair.Right == null ? "" : pair.Right.GetType().ToString(); + return string.Format("Cannot perform the operation: {0} On Structures {1} and {2}", op, t1, t2); + } + + private bool TryInvokeExplicit(OperandPair pair, string methodName, out object result) + { + MethodInfo method1 = pair.LeftType.GetMethod(methodName, FLAGS, null, new[] { pair.LeftType, pair.RightType }, null); + if (method1 != null) + { + result = method1.Invoke(null, new[] {pair.Left, pair.Right}); + return true; + } + MethodInfo method2 = pair.RightType.GetMethod(methodName, FLAGS, null, new[] { pair.LeftType, pair.RightType }, null); + + if (method2 != null) + { + result = method2.Invoke(null, new[] {pair.Left, pair.Right}); + return true; + } + + result = null; + return false; + } + + private void CheckPairForNull(OperandPair pair, string opName) + { + if (pair.Left == null || pair.Right == null) + { + throw new InvalidOperationException(GetMessage(opName, pair)); + } + } + + private bool TryCoerceImplicit(OperandPair pair, out OperandPair resultPair) + { + bool couldCoerce = false; + object newLeft; + object newRight; + MethodInfo convert2 = pair.LeftType.GetMethod("op_Implicit", FLAGS | BindingFlags.ExactBinding, null, new[] { pair.RightType }, null); + if (convert2 != null) + { + couldCoerce = true; + newRight = convert2.Invoke(null, new[] { pair.Right }); + } + else + { + newRight = pair.Right; + } + + MethodInfo convert1 = pair.RightType.GetMethod("op_Implicit", FLAGS | BindingFlags.ExactBinding, null, new[] { pair.LeftType }, null); + if (convert1 != null) + { + couldCoerce = true; + newLeft = convert1.Invoke(null, new[] { pair.Left }); + } + else + { + newLeft = pair.Left; + } + + resultPair = new OperandPair(newLeft, newRight); + + return couldCoerce; + } + + } +} \ No newline at end of file diff --git a/src/kOS.Safe/Compilation/CompiledObject-doc.md b/src/kOS.Safe/Compilation/CompiledObject-doc.md index 30e35ceef..10e7f5a18 100644 --- a/src/kOS.Safe/Compilation/CompiledObject-doc.md +++ b/src/kOS.Safe/Compilation/CompiledObject-doc.md @@ -423,6 +423,7 @@ types supported is this: content of the string. kOS encodes the string as UTF-8. + 8 | The magic mark pushed on the stack to help count args | nonexistent - like nulls it has no data. CodePart sections: ------------------ diff --git a/src/kOS.Safe/Compilation/CompiledObject.cs b/src/kOS.Safe/Compilation/CompiledObject.cs index d90f9fc78..157628015 100644 --- a/src/kOS.Safe/Compilation/CompiledObject.cs +++ b/src/kOS.Safe/Compilation/CompiledObject.cs @@ -3,6 +3,8 @@ using System.Text.RegularExpressions; using System.IO; using System.Linq; +using kOS.Safe.Encapsulation; +using kOS.Safe.Execution; namespace kOS.Safe.Compilation { @@ -57,6 +59,11 @@ public static void InitTypeData() AddTypeData(5, typeof(float)); AddTypeData(6, typeof(double)); AddTypeData(7, typeof(string)); + AddTypeData(8, typeof(KOSArgMarkerType)); + AddTypeData(9, typeof(ScalarIntValue)); + AddTypeData(10, typeof(ScalarDoubleValue)); + AddTypeData(11, typeof(BooleanValue)); + AddTypeData(12, typeof(StringValue)); } private static void AddTypeData(int byteType, Type csType) @@ -377,6 +384,7 @@ private static int PackedArgumentLocation(object argument) private static void WriteSomeBinaryPrimitive(BinaryWriter writer, object obj) { if (obj is PseudoNull) { /* do nothing. for a null the type byte code is enough - no further data. */ } + else if (obj is KOSArgMarkerType) { /*do nothing, for this type has no data*/ } else if (obj is Boolean) writer.Write((bool)obj); else if (obj is Int32) writer.Write((Int32)obj); else if (obj is String) writer.Write((String)obj); @@ -391,8 +399,12 @@ private static void WriteSomeBinaryPrimitive(BinaryWriter writer, object obj) else if (obj is UInt32) writer.Write((UInt32)obj); else if (obj is UInt64) writer.Write((UInt64)obj); else if (obj is SByte) writer.Write((SByte)obj); + else if (obj is ScalarIntValue) writer.Write(((ScalarIntValue)obj).GetIntValue()); + else if (obj is ScalarDoubleValue) writer.Write(((ScalarDoubleValue)obj).GetDoubleValue()); + else if (obj is BooleanValue) writer.Write((BooleanValue)obj); + else if (obj is StringValue) writer.Write((StringValue)obj); else - throw new Exception( "Don't konw how to write this type of object to binary file: " + obj.GetType().Name ); + throw new Exception("Don't konw how to write this type of object to binary file: " + obj.GetType().Name); } /// /// It's surprising that BinaryWriter.Read doesn't have a method that does the @@ -405,6 +417,7 @@ private static object ReadSomeBinaryPrimitive(BinaryReader reader, Type cSharpTy object returnValue = null; if (cSharpType == typeof(PseudoNull)) { /* do nothing. for a null the type byte code is enough - no further data. */ } + else if (cSharpType == typeof(KOSArgMarkerType)) returnValue = new KOSArgMarkerType(); // no packed data - just make a default one. else if (cSharpType == typeof(Boolean)) returnValue = reader.ReadBoolean(); else if (cSharpType == typeof(Int32)) returnValue = reader.ReadInt32(); else if (cSharpType == typeof(String)) returnValue = reader.ReadString(); @@ -419,8 +432,12 @@ private static object ReadSomeBinaryPrimitive(BinaryReader reader, Type cSharpTy else if (cSharpType == typeof(UInt32)) returnValue = reader.ReadUInt32(); else if (cSharpType == typeof(UInt64)) returnValue = reader.ReadUInt64(); else if (cSharpType == typeof(SByte)) returnValue = reader.ReadSByte(); + else if (cSharpType == typeof(ScalarIntValue)) returnValue = ScalarValue.Create(reader.ReadInt32()); + else if (cSharpType == typeof(ScalarDoubleValue)) returnValue = ScalarValue.Create(reader.ReadDouble()); + else if (cSharpType == typeof(BooleanValue)) returnValue = new BooleanValue(reader.ReadBoolean()); + else if (cSharpType == typeof(StringValue)) returnValue = new StringValue(reader.ReadString()); else - throw new Exception( "Don't konw how to read this type of object from binary file: " + cSharpType.Name ); + throw new Exception("Don't know how to read this type of object from binary file: " + cSharpType.Name); return returnValue; } diff --git a/src/kOS.Safe/Compilation/CompilerOptions.cs b/src/kOS.Safe/Compilation/CompilerOptions.cs index cd7b59d94..32280c540 100644 --- a/src/kOS.Safe/Compilation/CompilerOptions.cs +++ b/src/kOS.Safe/Compilation/CompilerOptions.cs @@ -4,6 +4,15 @@ namespace kOS.Safe.Compilation public class CompilerOptions { public bool LoadProgramsInSameAddressSpace { get; set; } + /// + /// IsCalledFromRun is true when this compile is being made from + /// a context in which it was called from a RUN command such that there + /// is a chance of there being arguments passed as parameters. If it is + /// the interpreter context, then this should be false to instruct the + /// compiler NOT to attempt to look for an arg bottom marker because there + /// won't be one. + /// + public bool IsCalledFromRun { get; set; } public IFunctionManager FuncManager { get; set; } public CompilerOptions() { @@ -14,6 +23,7 @@ private void LoadDefaults() { LoadProgramsInSameAddressSpace = false; FuncManager = null; + IsCalledFromRun = true; } public bool BuiltInExists(string identifier) diff --git a/src/kOS.Safe/Compilation/KS/Compiler.cs b/src/kOS.Safe/Compilation/KS/Compiler.cs index 6fa8e53b4..96944f72f 100644 --- a/src/kOS.Safe/Compilation/KS/Compiler.cs +++ b/src/kOS.Safe/Compilation/KS/Compiler.cs @@ -3,6 +3,8 @@ using System.Linq; using kOS.Safe.Exceptions; using kOS.Safe.Utilities; +using kOS.Safe.Execution; +using kOS.Safe.Encapsulation; namespace kOS.Safe.Compilation.KS { @@ -32,16 +34,9 @@ class Compiler private Int16 braceNestLevel; private readonly List scopeStack = new List(); private readonly Dictionary scopeMap = new Dictionary(); - private readonly List programParameters = new List(); private CompilerOptions options; private const bool TRACE_PARSE = false; // set to true to Debug Log each ParseNode as it's visited. - private readonly Dictionary functionsOverloads = new Dictionary - { - { "round|1", "roundnearest" }, - { "round|2", "round"} - }; - private enum StorageModifier { /// The storage will definitely be at the localmost scope. LOCAL, @@ -78,7 +73,6 @@ private void InitCompileFlags() forcedNextLabel = String.Empty; scopeStack.Clear(); scopeMap.Clear(); - programParameters.Clear(); } public CodePart Compile(int startLineNum, ParseTree tree, Context context, CompilerOptions options) @@ -92,27 +86,11 @@ public CodePart Compile(int startLineNum, ParseTree tree, Context context, Compi ++context.NumCompilesSoFar; - try - { - if (tree.Nodes.Count > 0) - { - PreProcess(tree); - CompileProgram(tree); - } - } - catch (KOSException kosException) + if (tree.Nodes.Count > 0) { - if (lastNode != null) - { - throw; // TODO something more sophisticated will go here that will - // attach source/line information to the exception before throwing it upward. - // that's why this seemingly pointless "catch and then throw again" is here. - } - SafeHouse.Logger.Log("Exception in Compiler: " + kosException.Message); - SafeHouse.Logger.Log(kosException.StackTrace); - throw; // throw it up in addition to logging the stack trace, so the kOS terminal will also give the user some message. + PreProcess(tree); + CompileProgram(tree); } - return part; } @@ -120,10 +98,9 @@ private void CompileProgram(ParseTree tree) { currentCodeSection = part.MainCode; - PushReversedParameters(); VisitNode(tree.Nodes[0]); - if (addBranchDestination) + if (addBranchDestination || currentCodeSection.Count == 0) { AddOpcode(new OpcodeNOP()); } @@ -132,31 +109,45 @@ private void CompileProgram(ParseTree tree) /// /// Set the current line/column info and potentially also make a helpful /// debug trace useful when making syntax changes. - /// /// - /// true if a line number was found in this node. mostly used for internal recursion - /// and can be safely ignored when this is called. - private bool NodeStartHousekeeping(ParseNode node) + private void NodeStartHousekeeping(ParseNode node) { if (node == null) { throw new ArgumentNullException("node"); } if (TRACE_PARSE) SafeHouse.Logger.Log("traceParse: visiting node: " + node.Token.Type.ToString() + ", " + node.Token.Text); + LineCol location = GetLineCol(node); + lastLine = location.Line; + lastColumn = location.Column; + } + + /// + /// Get a line number and column for a given parse node. Handles the + /// fact that TinyPG does not provide line and col information for all + /// nodes - just the terminals. This means if you, say, ask for the + /// line or column of a complex node like an expression, you get the bogus answer 0,0 back + /// from TinyPG normally. This method performs a leftmost walk of the + /// parse tree to get the first instance where a token exists with actual + /// line and column information populated, and returns that. + /// + /// The node to get the line number for + /// line and column pair of the firstmost terminal within the parse node + private LineCol GetLineCol(ParseNode node) + { if (node.Token == null || node.Token.Line <= 0) { - // Only those nodes which are primitive tokens will have line number - // information. So perform a leftmost search of the subtree of nodes - // until a node with a token with a line number is found: - return node.Nodes.Any(NodeStartHousekeeping); + foreach (ParseNode child in node.Nodes) + { + LineCol candidate = GetLineCol(child); + if (candidate.Line >= 0) + return candidate; + } } - lastLine = (short)(node.Token.Line + (startLineNum - 1)); - lastColumn = (short)(node.Token.Column); - return true; - + return new LineCol( (node.Token.Line + (startLineNum - 1)), (node.Token.Column) ); } - + private Opcode AddOpcode(Opcode opcode, string destinationLabel) { opcode.Label = GetNextLabel(true); @@ -191,12 +182,54 @@ private string GetNextLabel(bool increment) private void PreProcess(ParseTree tree) { ParseNode rootNode = tree.Nodes[0]; + LowercaseConversions(rootNode); + RearrangeParseNodes(rootNode); TraverseScopeBranch(rootNode); IterateUserFunctions(rootNode, IdentifyUserFunctions); PreProcessStatements(rootNode); IterateUserFunctions(rootNode, PreProcessUserFunctionStatement); } + + /// + /// Lowercase every IDENTIFIER and FILEIDENT token in the parse. + /// + /// branch head to start from in the compiler + private void LowercaseConversions(ParseNode node) + { + switch (node.Token.Type) + { + case TokenType.IDENTIFIER: + case TokenType.FILEIDENT: + node.Token.Text = node.Token.Text.ToLower(); + break; + default: + foreach (ParseNode child in node.Nodes) + LowercaseConversions(child); + break; + } + } + + /// + /// Some of the parse rules in Kerboscript may be implemented on the back + /// of other rules. In this case all the compiler really does is just + /// re-arrange a more complex parse rule to be expressed in the form of + /// building blocks made of other simpler rules before continuing the compile that way. + /// + /// make the transformation from this point downward + private void RearrangeParseNodes(ParseNode node) + { + if (node.Token.Type == TokenType.fromloop_stmt) // change to switch stmt if more such rules get added later. + { + RearrangeLoopFromNode(node); + } + // Recurse children EVEN IF the node got re-arranged. If the node got re-arranged, then its children will now look + // different than they did before, but they still need to be iterated over to look for other rearrangements. + // (for example, a loopfrom loop nested inside another loopfrom loop). + foreach (ParseNode child in node.Nodes) + RearrangeParseNodes(child); + } + private void IterateUserFunctions(ParseNode node, Action action) { switch (node.Token.Type) @@ -209,7 +242,9 @@ private void IterateUserFunctions(ParseNode node, Action action) case TokenType.instruction_block: case TokenType.instruction: case TokenType.if_stmt: + case TokenType.fromloop_stmt: case TokenType.until_stmt: + case TokenType.for_stmt: case TokenType.on_stmt: case TokenType.when_stmt: case TokenType.declare_function_clause: @@ -232,6 +267,105 @@ private void IterateUserFunctions(ParseNode node, Action action) break; } } + + /// + /// Edit the parse branch for a loopfrom statement, rearranging its component + /// parts into a simpler unrolled form.
+ /// When given this rule:
+ ///
+ /// FROM {(init statements)} UNTIL expr STEP {(inc statements)} DO {(body statements)}
+ ///
+ /// It will edit its own child nodes and transform them into a new parse tree branch as if this had + /// been what was in the source code instead:
+ ///
+ /// { (init statements) UNTIL expr { (body statements) (inc statements) } }
+ ///
+ /// Thus any variables declared inside (init statements) are in scope during the body of the loop.
+ /// The actual logic of doing an UNTIL loop will fall upon VisitUntilNode to deal with later in the compile.
+ ///
+ /// + private void RearrangeLoopFromNode(ParseNode node) + { + // Safety check to see if I've already been rearranged into my final form, just in case + // the recursion logic is messed up and this gets called twice on the same node: + if (node.Nodes.Count == 1 && node.Nodes[0].Token.Type == TokenType.instruction_block) + return; + + // ReSharper disable RedundantDefaultFieldInitializer + ParseNode initBlock = null; + ParseNode checkExpression = null; + ParseNode untilTokenNode = null; + ParseNode stepBlock = null; + ParseNode doBlock = null; + // ReSharper enable RedundantDefaultFieldInitializer + + for( int index = 0 ; index < node.Nodes.Count - 1 ; index += 2 ) + { + switch (node.Nodes[index].Token.Type) + { + case TokenType.FROM: + initBlock = node.Nodes[index+1]; + break; + case TokenType.UNTIL: + untilTokenNode = node.Nodes[index]; + checkExpression = node.Nodes[index+1]; + break; + case TokenType.STEP: + stepBlock = node.Nodes[index+1]; + break; + case TokenType.DO: + doBlock = node.Nodes[index+1]; + break; + // no default because anything else is a syntax error and it won't even get as far as this method in that case. + } + } + + // These probably can't happen because the parser would have barfed before it got to this method: + if (initBlock == null) + throw new KOSCompileException(node.Token, "Missing FROM block in FROM loop."); + if (checkExpression == null || untilTokenNode == null) + throw new KOSCompileException(node.Token, "Missing UNTIL check expression in FROM loop."); + if (stepBlock == null) + throw new KOSCompileException(node.Token, "Missing STEP block in FROM loop."); + if (doBlock == null) + throw new KOSCompileException(node.Token, "Missing loop body (DO block) in FROM loop."); + + // Append the step instructions to the tail end of the body block's instructions: + foreach (ParseNode child in stepBlock.Nodes) + doBlock.Nodes.Add(child); + + // Make a new empty until loop node, which will get added to the init block eventually: + var untilStatementTok = new Token + { + Type = TokenType.until_stmt, + Line = untilTokenNode.Token.Line, + Column = untilTokenNode.Token.Column, + File = untilTokenNode.Token.File + }; + + ParseNode untilNode = initBlock.CreateNode(untilStatementTok, untilStatementTok.ToString()); + + // (The direct manipulation of the tree's parent pointers, seen below, is bad form, + // but TinyPg doesn't seem to have given us good primitives to append an existing node to the tree to do it for us. + // CreateNode() makes a brand new empty node attached to the parent, but there seems to be no way to take an + // existing node and attach it elsewhere without directly changing the Parent property as seen in the lines below:) + + // Populate that until loop node with the parts from this rule: + untilNode.Nodes.Add(untilTokenNode); untilTokenNode.Parent = untilNode; + untilNode.Nodes.Add(checkExpression); checkExpression.Parent = untilNode; + untilNode.Nodes.Add(doBlock); doBlock.Parent = untilNode; + + // And now append that until loop to the tail end of the init block: + initBlock.Nodes.Add(untilNode); // parent already assigned by initBlock.CreateNode() above. + + // The init block is now actually the entire loop, having been exploded and unrolled into its + // new form, make that be our only node: + node.Nodes.Clear(); + node.Nodes.Add(initBlock); // initBlock's parent already points at node to begin with. + + // The FROM loop node is still in the parent's list, but it contains this new rearranged sub-tree + // instead of its original. + } private void PreProcessStatements(ParseNode node) { @@ -247,9 +381,11 @@ private void PreProcessStatements(ParseNode node) case TokenType.instruction_block: case TokenType.instruction: case TokenType.if_stmt: + case TokenType.fromloop_stmt: case TokenType.until_stmt: case TokenType.for_stmt: case TokenType.declare_function_clause: + case TokenType.declare_stmt: PreProcessChildNodes(node); break; case TokenType.on_stmt: @@ -260,10 +396,6 @@ private void PreProcessStatements(ParseNode node) PreProcessChildNodes(node); PreProcessWhenStatement(node); break; - case TokenType.declare_stmt: - PreProcessChildNodes(node); - PreProcessProgramParameters(node); - break; case TokenType.run_stmt: PreProcessRunStatement(node); break; @@ -429,7 +561,27 @@ private Int16 GetContainingScopeId(ParseNode node) return hitScope.ScopeId; current = current.Parent; } - return (Int16)0; + return 0; + } + + /// + /// Much like UserFunctionCollection.GetUserFunction(), except that it won't + /// generate a function if one doesn't exist. Instead it will try to walk up + /// the parent scopes until it finds a func or lock with the given name. If it + /// cannot find an existing function, it will return null rather than make one. + /// + /// identifier for the lock or function + /// ParseNode to begin looking from (for scope reasons). It will walk the parents looking for scopes that have the ident. + /// The found UserFunction, or null if none found + private UserFunction FindExistingUserFunction(string funcIdentifier, ParseNode node) + { + for (ParseNode containingNode = node ; containingNode != null ; containingNode = containingNode.Parent) + { + Int16 thisNodeScope = GetContainingScopeId(containingNode); + if (context.UserFunctions.Contains(funcIdentifier, thisNodeScope)) + return context.UserFunctions.GetUserFunction(funcIdentifier, thisNodeScope, containingNode); + } + return null; } private bool IsLockStatement(ParseNode node) @@ -474,6 +626,7 @@ private void PreProcessUserFunctionStatement(ParseNode node) bool isLock = IsLockStatement(node); bool isDefFunc = IsDefineFunctionStatement(node); + bool needImplicitArgBottom = false; StorageModifier storageType = GetStorageModifierFor(node); ParseNode lastSubNode = node.Nodes[node.Nodes.Count-1]; @@ -481,6 +634,7 @@ private void PreProcessUserFunctionStatement(ParseNode node) { userFuncIdentifier = lastSubNode.Nodes[1].Token.Text; // The IDENT of: LOCK IDENT TO EXPR. bodyNode = lastSubNode.Nodes[3]; // The EXPR of: LOCK IDENT TO EXPR. + needImplicitArgBottom = true; } else if (isDefFunc) { @@ -531,8 +685,9 @@ private void PreProcessUserFunctionStatement(ParseNode node) // build default dummy function to be used when this is a LOCK: currentCodeSection = userFuncObject.GetUserFunctionOpcodes(0); - AddOpcode(new OpcodePush("$" + userFuncObject.ScopelessIdentifier)).Label = userFuncObject.DefaultLabel; - AddOpcode(new OpcodeReturn()); + AddOpcode(new OpcodeArgBottom()).Label = userFuncObject.DefaultLabel;; + AddOpcode(new OpcodePush("$" + userFuncObject.ScopelessIdentifier)); + AddOpcode(new OpcodeReturn(0)); } // lock expression's or function body's code @@ -546,22 +701,29 @@ private void PreProcessUserFunctionStatement(ParseNode node) BeginScope(bodyNode); if (isDefFunc) nextBraceIsFunction = true; + if (needImplicitArgBottom) + AddOpcode(new OpcodeArgBottom()); VisitNode(bodyNode); + Int16 implicitReturnScopeDepth = 0; + if (isDefFunc) nextBraceIsFunction = false; if (isLock) // locks need to behave as if they had braces even though they don't - so they get lexical scope ids for closure reasons: - EndScope(bodyNode); + { + EndScope(bodyNode, false); + implicitReturnScopeDepth = 1; + } if (needImplicitReturn) { if (isDefFunc) AddOpcode(new OpcodePush(0)); // Functions must push a dummy return val when making implicit returns. Locks already leave an expr atop the stack. - AddOpcode(new OpcodeReturn()); + AddOpcode(new OpcodeReturn(implicitReturnScopeDepth)); } userFuncObject.ScopeNode = GetContainingBlockNode(node); // This limits the scope of the function to the instruction_block the DEFINE was in. - userFuncObject.IsFunction = !(isLock);; + userFuncObject.IsFunction = !(isLock); } } @@ -584,7 +746,7 @@ private void BuildSystemTrigger(UserFunction func) List rememberCurrentCodeSection = currentCodeSection; currentCodeSection = triggerObject.Code; AddOpcode(new OpcodePush("$" + func.ScopelessIdentifier)); - AddOpcode(new OpcodePush(OpcodeCall.ARG_MARKER_STRING)); // need these for all locks now. + AddOpcode(new OpcodePush(new KOSArgMarkerType())); // need these for all locks now. AddOpcode(new OpcodeCall(func.ScopelessPointerIdentifier)); AddOpcode(new OpcodeStoreGlobal()); AddOpcode(new OpcodeEOF()); @@ -603,34 +765,20 @@ private ParseNode GetContainingBlockNode(ParseNode node) return node; } - private void PreProcessProgramParameters(ParseNode node) - { - NodeStartHousekeeping(node); - ParseNode lastSubNode = node.Nodes[node.Nodes.Count-1]; - // if the declaration is a parameter, - // and this is NOT contained inside a DEFINE FUNCTION block and - // is therefore a global program paramter (for the run statement): - if (lastSubNode.Token.Type == TokenType.declare_parameter_clause && - (!(IsInsideDefineFunctionStatement(node)))) - { - for (int index = 1; index < lastSubNode.Nodes.Count; index += 2) - { - programParameters.Add(lastSubNode.Nodes[index]); - } - } - // If it's any other sort of Declare statement, do nothing and instead - // allow the PreProcessChildNodes handle all the work. - } - private void PreProcessRunStatement(ParseNode node) { NodeStartHousekeeping(node); if (options.LoadProgramsInSameAddressSpace) { - bool hasON = node.Nodes.Any(cn => cn.Token.Type == TokenType.ON); - if (!hasON) + int progNameIndex = 1; + if (node.Nodes[1].Token.Type == TokenType.ONCE) { - string subprogramName = node.Nodes[1].Token.Text; // It assumes it already knows at compile-time how many unique program filenames exist, + ++progNameIndex; + } + bool hasOn = node.Nodes.Any(cn => cn.Token.Type == TokenType.ON); + if (!hasOn) + { + string subprogramName = node.Nodes[progNameIndex].Token.Text; // It assumes it already knows at compile-time how many unique program filenames exist, if (!context.Subprograms.Contains(subprogramName)) // which it uses to decide how many of these blocks to make, { // which is why we can't defer run filenames until runtime like we can with the others. Subprogram subprogramObject = context.Subprograms.GetSubprogram(subprogramName); @@ -638,13 +786,33 @@ private void PreProcessRunStatement(ParseNode node) currentCodeSection = subprogramObject.FunctionCode; // verify if the program has been loaded Opcode functionStart = AddOpcode(new OpcodePush(subprogramObject.PointerIdentifier)); + // Becuse of Cpu.SaveAndClearPointers(), the subprogram's pointer identifier won't + // exist in this program context until it has been compiled once. If it does exist, + // then skip the compiling step and just run the code that's already there: + AddOpcode(new OpcodeExists()); + // branch to where the compiler loads the code: + OpcodeBranchIfFalse branchToLoad = new OpcodeBranchIfFalse(); + AddOpcode(branchToLoad); + // Now the top of the stack should be the argument pushed by + // VisitRunStatement that flags if there was a 'once' keyword: + // If there was no 'once', then branch to where the already + // loaded code gets run, even though it's been run before: + OpcodeBranchIfFalse branchToRun = new OpcodeBranchIfFalse(); + AddOpcode(branchToRun); + // If it falls through to here, that means the code was already + // loaded, AND the 'once' keyword was present in the instance + // where this loading function got called, so just do nothing + // and return. AddOpcode(new OpcodePush(0)); - AddOpcode(new OpcodeCompareEqual()); - OpcodeBranchIfFalse branchOpcode = new OpcodeBranchIfFalse(); - AddOpcode(branchOpcode); - // if it wasn't then load it now + AddOpcode(new OpcodeReturn(0)); + // if it wasn't then load it now: + // First throw away the 'once' argument since it doesn't matter when + // we're going to be compiling regardless: + OpcodePop firstOpcodeOfLoadSection = new OpcodePop(); + AddOpcode(firstOpcodeOfLoadSection); + branchToLoad.DestinationLabel = firstOpcodeOfLoadSection.Label; AddOpcode(new OpcodePush(subprogramObject.PointerIdentifier)); - AddOpcode(new OpcodePush(OpcodeCall.ARG_MARKER_STRING)); + AddOpcode(new OpcodePush(new KOSArgMarkerType())); AddOpcode(new OpcodePush(subprogramObject.SubprogramName)); AddOpcode(new OpcodePush(null)); // The output filename - only used for compile-to-file rather than for running. AddOpcode(new OpcodeCall("load()")); @@ -655,46 +823,30 @@ private void PreProcessRunStatement(ParseNode node) // call the program Opcode callOpcode = AddOpcode(new OpcodeCall(subprogramObject.PointerIdentifier)); // set the call opcode as the destination of the previous branch - branchOpcode.DestinationLabel = callOpcode.Label; + branchToRun.DestinationLabel = callOpcode.Label; // return to the caller address, after adding a dummy return val: - + // maybe TODO? Right now the RETURN command is being prevented from being used outside // a function declaration. But in principle we could have programs return exit codes - // using the same archetecture, and in fact that is why this dummy return value is needed, + // using the same architecture, and in fact that is why this dummy return value is needed, // because OpcodeReturn now expects such a return value to exist and throws an exception when it // does not. // If an EXIT command was implemented, it would maybe allow an exit code that can be read here: AddOpcode(new OpcodePop()); // for now: throw away return code from subprogram. AddOpcode(new OpcodePush(0)); // Replace it with new dummy return code. - AddOpcode(new OpcodeReturn()); // return that. + AddOpcode(new OpcodeReturn(0)); // return that. // set the function start label subprogramObject.FunctionLabel = functionStart.Label; // Initialization code currentCodeSection = subprogramObject.InitializationCode; - // initialize the pointer to zero - AddOpcode(new OpcodePush(subprogramObject.PointerIdentifier)); - AddOpcode(new OpcodePush(0)); - AddOpcode(new OpcodeStore()); + // removed pointer initialization since it overwrote any existing values when loading ksm files. } } } } - private void PushReversedParameters() - { - // reverse the order of parameters so the stack - // is popped in the correct order - programParameters.Reverse(); - foreach (ParseNode node in programParameters) - { - VisitNode(node); - AddOpcode(new OpcodeSwap()); - AddOpcode(new OpcodeStore()); - } - } - private void PushTriggerRemoveName(string newLabel) { triggerRemoveNames.Add(newLabel); @@ -737,21 +889,20 @@ private void PopBreakList(string label) if (breakList.Count > 0) { BreakInfo list = breakList[breakList.Count - 1]; - if (list != null) + if (list == null) return; + + breakList.Remove(list); + foreach (Opcode opcode in list.Opcodes) { - breakList.Remove(list); - foreach (Opcode opcode in list.Opcodes) - { - OpcodePopScope popScopeOp = opcode as OpcodePopScope; - if (popScopeOp != null) - // calculate how many nesting levels it needs to really pop - // by comparing the nest level where the break statement was to - // the nest level where the break context started: - popScopeOp.NumLevels = (Int16)(popScopeOp.NumLevels - list.NestLevel); - - else // assume all others are branch opcodes of some sort: - opcode.DestinationLabel = label; - } + OpcodePopScope popScopeOp = opcode as OpcodePopScope; + if (popScopeOp != null) + // calculate how many nesting levels it needs to really pop + // by comparing the nest level where the break statement was to + // the nest level where the break context started: + popScopeOp.NumLevels = (Int16)(popScopeOp.NumLevels - list.NestLevel); + + else // assume all others are branch opcodes of some sort: + opcode.DestinationLabel = label; } } } @@ -800,8 +951,11 @@ private void BeginScope(ParseNode node) /// /// Insert the Opcode to finish a lexical scope /// Call upon every close brace "}" + /// Should this code insert its own popscope. Only say false when + /// you intend to immediately do a return statement and have the return statement be + /// responsible for the popscope itself. /// - private void EndScope(ParseNode node) + private void EndScope(ParseNode node, bool withPopScope = true) { node = node.Parent; @@ -819,13 +973,14 @@ private void EndScope(ParseNode node) braceNestLevel = 0; } - AddOpcode(new OpcodePopScope()); + if (withPopScope) + AddOpcode(new OpcodePopScope()); } /// /// Because the compile occurs a bit out of order (doing the most deeply nested function /// first, then working out from there) it walks the scope nesting in the wrong order. - /// Therefore before doing the complie, run through in one pass just recording the nesting + /// Therefore before doing the compile, run through in one pass just recording the nesting /// levels and lexical parent tree of the scoping before we begin, so we can /// use that information later in the parse: /// @@ -899,6 +1054,9 @@ private void VisitNode(ParseNode node) case TokenType.until_stmt: VisitUntilStatement(node); break; + case TokenType.fromloop_stmt: + VisitChildNodes(node); // The loopfrom should have been altered by now, in RearrangeParseNodes(). + break; case TokenType.return_stmt: VisitReturnStatement(node); break; @@ -986,13 +1144,17 @@ private void VisitNode(ParseNode node) case TokenType.arglist: VisitArgList(node); break; - case TokenType.expr: case TokenType.compare_expr: // for issue #20 - case TokenType.and_expr: case TokenType.arith_expr: case TokenType.multdiv_expr: case TokenType.factor: - VisitExpression(node); + VisitExpressionChain(node); + break; + case TokenType.expr: // expr is really the rule for doing an expression with optional trailing or-expression. + // 'or' just happens to have the lowest operator precedence level so it ends up being + // the outermost expression rule, thus getting the generic name 'expr'. + case TokenType.and_expr: + VisitShortCircuitBoolean(node); break; case TokenType.suffix: VisitSuffix(node); @@ -1030,9 +1192,9 @@ private void VisitNode(ParseNode node) case TokenType.varidentifier: VisitVarIdentifier(node); break; - case TokenType.suffixterm: - VisitSuffixTerm(node); - break; + case TokenType.suffixterm: // TODO: If the exception in VisitSuffixTerm never gets + VisitSuffixTerm(node); // thrown during our testing, we can then safely remove + break; // this clause from the switch. case TokenType.IDENTIFIER: VisitIdentifier(node); break; @@ -1069,7 +1231,17 @@ private void VisitNode(ParseNode node) private void VisitStartStatement(ParseNode node) { AddFunctionJumpVars(null); - VisitChildNodes(node); + int argbottomSpot = (options.IsCalledFromRun) ? FindArgBottomSpot(node) : -1; + + // For each child node, but interrupting for the spot + // where to insert the argbottom opcode: + for (int i = 0 ; i < node.Nodes.Count ; ++i) + { + if (i == argbottomSpot) + AddOpcode(new OpcodeArgBottom()); + + VisitNode(node.Nodes[i]); // nextBraceIsFunction state would get incorrectly inherited by my children here if it wasn't turned off up above. + } } private void VisitChildNodes(ParseNode node) @@ -1089,7 +1261,22 @@ private void VisitVariableNode(ParseNode node) identifierIsVariable = false; } - private void VisitExpression(ParseNode node) + /// + /// Performs the work for a number of different expressions that all + /// share the following universal basic properties:
+ /// - They contain optional binary operators.
+ /// - The terms are all at the same precedence level.
+ /// - Because of the tie of precedence level, the terms are to be evaluated left-to-right.
+ /// - No special extra work is needed, such that simply doing "push expr1, push expr2, then do operator" is all that's needed.
+ ///
+ /// Examples:
+ /// 5 + 4 - x + 2 // because + and - are in the same parse rule, these all get the same flat precedence.
+ /// x * y * z
+ /// In cases like that where all the operators "tie", the entire chain of terms lives in the same ParseNode,
+ /// and we have to unroll those terms and presume left-to-right precedence. That is what this method does.
+ ///
+ /// + private void VisitExpressionChain(ParseNode node) { NodeStartHousekeeping(node); if (node.Nodes.Count > 1) @@ -1097,26 +1284,102 @@ private void VisitExpression(ParseNode node) // it should always be odd, two arguments and one operator if ((node.Nodes.Count % 2) != 1) return; - VisitNode(node.Nodes[0]); + VisitNode(node.Nodes[0]); // pushes lefthand side on stack. int nodeIndex = 2; while (nodeIndex < node.Nodes.Count) { - VisitNode(node.Nodes[nodeIndex]); + VisitNode(node.Nodes[nodeIndex]); // pushes righthand side on stack. nodeIndex -= 1; - VisitNode(node.Nodes[nodeIndex]); - nodeIndex += 3; + VisitNode(node.Nodes[nodeIndex]); // operator, i.e '*', '+', '-', '/', etc. + nodeIndex += 3; // Move to the next term over (if there's more than 2 terms in the chain). + + // If there are more terms to process, then the value that the operation leaves behind on the stack + // from operating on these two terms will become the 'lefthand side' for the next iteration of this loop. } } - else + else if (node.Nodes.Count == 1) { - if (node.Nodes.Count == 1) + VisitNode(node.Nodes[0]); // This ParseNode isn't *realy* an expression of binary operators, because + // the regex chain of "zero or more" righthand terms.. had zero such terms. + // So just delve in deeper to compile whatever part of speech it is further down. + } + } + + /// + /// Handles the short-circuit logic of boolean OR and boolean AND + /// chains. It is like VisitExpressionChain (see elsewhere) but + /// in this case it has the special logic to short circuit and skip + /// executing the righthand expression if it can. (The generic VisitExpressionXhain + /// always evaluates both the left and right sides of the operator first, then + /// does the operation). + /// + /// + private void VisitShortCircuitBoolean(ParseNode node) + { + NodeStartHousekeeping(node); + + if (node.Nodes.Count > 1) + { + // it should always be odd, two arguments and one operator + if ((node.Nodes.Count % 2) != 1) return; + + // Determine if this is a chain of ANDs or a chain or ORs. The parser will + // never mix ANDs and ORs into the same ParseNode level. We are guaranteed + // that all the operators in this chain match the first operator in the chain: + // That guarantee is important. Without it, we can't do short-circuiting like this + // because you can't short-circuit a mix of AND and OR at the same precedence. + TokenType operation = node.Nodes[1].Token.Type; // Guaranteed to be either TokenType.AND or TokenType.OR + + // For remembering the instruction pointers from which short-circuit branch jumps came: + List shortCircuitFromIndeces = new List(); + + int nodeIndex = 0; + while (nodeIndex < node.Nodes.Count) + { + if (nodeIndex > 0) // After each term, insert the branch test (which consumes the expr from the stack regardless of if it branches): + { + shortCircuitFromIndeces.Add(currentCodeSection.Count()); + if (operation == TokenType.AND) + AddOpcode(new OpcodeBranchIfFalse()); + else if (operation == TokenType.OR) + AddOpcode(new OpcodeBranchIfTrue()); + else + throw new KOSException("Assertion check: Broken kerboscript compiler (VisitShortCircuitBoolean). See kOS devs"); + } + + VisitNode(node.Nodes[nodeIndex]); // pushes the next term onto the stack. + nodeIndex += 2; // Skip the operator, moving to the next term over. + } + // If it gets to the end of all that and it still hasn't aborted, then the whole expression's + // Boolean value is just the value of its lastmost term, that's already gotten pushed atop the stack. + // Leave the lastmost term there, and just skip ahead past the short-circuit landing target: + OpcodeBranchJump skipShortCircuitTarget = new OpcodeBranchJump(); + skipShortCircuitTarget.Distance = 2; // Hardcoded +2 jump distance skips the upcoming OpcodePush and just lands on + // whatever comes next after this VisitNode. Avoids using DestinationLabel + // for later relocation because it would be messy to reassign this label later + // in whatever VisitNode happens to come up next, when that could be anything. + AddOpcode(skipShortCircuitTarget); + + // Build the instruction all the short circuit checks will jump to if aborting partway through. + // (AND's abort when they're false. OR's abort when they're true.) + AddOpcode(operation == TokenType.AND ? new OpcodePush(false) : new OpcodePush(true)); + string shortCircuitTargetLabel = currentCodeSection[currentCodeSection.Count()-1].Label; + + // Retroactively re-assign the jump labels of all the short circuit branch operations: + foreach (int index in shortCircuitFromIndeces) { - VisitNode(node.Nodes[0]); + currentCodeSection[index].DestinationLabel = shortCircuitTargetLabel; } } + else if (node.Nodes.Count == 1) + { + VisitNode(node.Nodes[0]); // This ParseNode isn't *realy* an expression of AND or OR operators, because + // the regex chain of "zero or more" righthand terms.. had zero such terms. + // So just delve in deeper to compile whatever part of speech it is further down. + } } - + private void VisitUnaryExpression(ParseNode node) { NodeStartHousekeeping(node); @@ -1124,6 +1387,7 @@ private void VisitUnaryExpression(ParseNode node) bool addNegation = false; bool addNot = false; + bool addDefined = false; int nodeIndex = 0; if (node.Nodes[0].Token.Type == TokenType.PLUSMINUS) @@ -1139,6 +1403,11 @@ private void VisitUnaryExpression(ParseNode node) nodeIndex++; addNot = true; } + else if (node.Nodes[0].Token.Type == TokenType.DEFINED) + { + nodeIndex++; + addDefined = true; + } VisitNode(node.Nodes[nodeIndex]); @@ -1150,6 +1419,10 @@ private void VisitUnaryExpression(ParseNode node) { AddOpcode(new OpcodeLogicNot()); } + if (addDefined) + { + AddOpcode(new OpcodeExists()); + } } private void VisitAtom(ParseNode node) @@ -1214,7 +1487,7 @@ private void VisitInteger(ParseNode node) number = double.Parse(node.Token.Text); } - AddOpcode(new OpcodePush(number)); + AddOpcode(new OpcodePush(ScalarValue.Create(number))); } private void VisitDouble(ParseNode node) @@ -1222,7 +1495,7 @@ private void VisitDouble(ParseNode node) NodeStartHousekeeping(node); object number = double.Parse(node.Token.Text); - AddOpcode(new OpcodePush(number)); + AddOpcode(new OpcodePush(ScalarValue.Create(number))); } private void VisitTrueFalse(ParseNode node) @@ -1231,7 +1504,7 @@ private void VisitTrueFalse(ParseNode node) bool boolValue; if (bool.TryParse(node.Token.Text, out boolValue)) { - AddOpcode(new OpcodePush(boolValue)); + AddOpcode(new OpcodePush(new BooleanValue(boolValue))); } } @@ -1247,28 +1520,34 @@ private void VisitOnOffTrailer(ParseNode node) /// parse node for the function term of the parse tree. /// true if it should make an OpcodeCall that is Direct, false if it should make an indirect one. /// See the documentation for OpcodeCall.Direct for the full explanation of the difference. If isDirect is true, then - /// the name to the left of the parentheses will be the name of the function call. If isDirect is false, then it will - /// ignore the name to the left of the parentheses and presume the function name, delegate, or branch index was - /// already placed atop the stack by other parts of this compiler. + /// the name to the left of the parentheses will be the name of the function call or the name of the + /// identifier variable that holds the function's jump address in the case of user functions. But in either case + /// the important thing is that when isDirect is true, that means the OpcodeCall uses the Opcode's argument to + /// decide where to call. On the other hand, if isDirect is false, then it will + /// presume the function name, delegate, or branch index was + /// already placed atop the stack by other parts of this compiler, rather than encoding it into the + /// OpcodeCall's argument itself. /// In the case where it's a direct function, what's the name of it? In the case /// where it's not direct, this argument doesn't matter. private void VisitActualFunction(ParseNode node, bool isDirect, string directName = "") { NodeStartHousekeeping(node); - int parameterCount = 0; ParseNode trailerNode = node; // the function_trailer rule is here. + if (trailerNode.Nodes.Count > 0 && trailerNode.Nodes[0].Token.Type == TokenType.ATSIGN) + { + BuildFunctionDelegate(isDirect, directName); + return; + } + // Need to tell OpcodeCall where in the stack the bottom of the arg list is. // Even if there are no arguments, it still has to be TOLD that by showing // it the marker atop the stack with nothing above it. - AddOpcode(new OpcodePush(OpcodeCall.ARG_MARKER_STRING)); + AddOpcode(new OpcodePush(new KOSArgMarkerType())); if (trailerNode.Nodes[1].Token.Type == TokenType.arglist) { - - parameterCount = (trailerNode.Nodes[1].Nodes.Count / 2) + 1; - bool remember = identifierIsSuffix; identifierIsSuffix = false; @@ -1279,39 +1558,80 @@ private void VisitActualFunction(ParseNode node, bool isDirect, string directNam if (isDirect) { - string functionName = directName; - - string overloadedFunctionName = GetFunctionOverload(functionName, parameterCount); - if (options.FuncManager.Exists(overloadedFunctionName)) // if the name is a built-in, then add the "()" after it. - overloadedFunctionName += "()"; - AddOpcode(new OpcodeCall(overloadedFunctionName)); + if (options.FuncManager.Exists(directName)) // if the name is a built-in, then add the "()" after it. + directName += "()"; + AddOpcode(new OpcodeCall(directName)); } else { - OpcodeCall op = new OpcodeCall(string.Empty) { Direct = false }; + var op = new OpcodeCall(string.Empty) { Direct = false }; AddOpcode(op); } } - private string GetFunctionOverload(string functionName, int parameterCount) + private void VisitArgList(ParseNode node) { - string functionKey = string.Format("{0}|{1}", functionName, parameterCount); - if (functionsOverloads.ContainsKey(functionKey)) + NodeStartHousekeeping(node); + int nodeIndex = 0; + while (nodeIndex < node.Nodes.Count) { - return functionsOverloads[functionKey]; + VisitNode(node.Nodes[nodeIndex]); + nodeIndex += 2; } - return functionName; } - private void VisitArgList(ParseNode node) + // For the case where you wish to eval the args lastmost-first, such + // that they'll push onto the stack like so: + // arg1 <-- top + // arg2 + // arg3 <-- bottom + // + // instead of the usual stack order of: + // arg3 <-- top + // arg2 + // arg1 <-- bottom + private void VisitArgListReversed(ParseNode node) { NodeStartHousekeeping(node); - int nodeIndex = 0; - while (nodeIndex < node.Nodes.Count) + int nodeIndex = node.Nodes.Count - 1; + while (nodeIndex >= 0) { VisitNode(node.Nodes[nodeIndex]); - nodeIndex += 2; + nodeIndex -= 2; + } + } + + /// + /// When a function identifier or suffix ends in '@' where parentheses could have gone, + /// then its not really being called like a function. Instead it's being asked to generate + /// a delegate of itself to be put atop the stack. + /// This builds the code that does that. + /// + /// If true, then the directName is the name of the function being called or the user + /// variable holding the function delegate to be called. If false, then the compiler should have built code + /// that will have left a suffix or function reference atop the stack already. + /// only needed when isDirect is true + private void BuildFunctionDelegate(bool isDirect, string directName = "") + { + if (isDirect) + { + if (options.FuncManager.Exists(directName)) // if the name is a built-in, then make a BuiltInDelegate + { + AddOpcode(new OpcodePush(new KOSArgMarkerType())); + AddOpcode(new OpcodePush(directName)); + AddOpcode(new OpcodeCall("makebuiltindelegate()")); + } + else + { + // It is not a built-in, so instead get its value as a user function pointer variable, despite + // the fact that it's being called AS IF it was direct. + if (!directName.EndsWith("*")) directName = directName + "*"; + if (!directName.StartsWith("$")) directName = "$" + directName; + AddOpcode(new OpcodePush(directName)); + } } + // Else we shouldn't have to do any work because the thing atop the stack will already + // be a suffix delegate. } private void VisitVarIdentifier(ParseNode node) @@ -1395,12 +1715,13 @@ private void VisitSuffix(ParseNode node) ParseNode trailerTerm = suffixTerm.Nodes[trailerIndex].Nodes[0]; bool isFunc = (trailerTerm.Token.Type == TokenType.function_trailer); bool isArray = (trailerTerm.Token.Type == TokenType.array_trailer); + bool thisTermIsDirect = (isDirect && trailerIndex == 1); // only the firstmost term in a chain can be direct. if (isFunc || isUserFunc) { // direct if it's just one term like foo(aaa) but indirect // if it's a list of suffixes like foo:bar(aaa): - VisitActualFunction(trailerTerm, isDirect, firstIdentifier); + VisitActualFunction(trailerTerm, thisTermIsDirect, firstIdentifier); } if (isArray) { @@ -1408,12 +1729,12 @@ private void VisitSuffix(ParseNode node) } } - // In the case of a lock function withiout parentheses, it needs this special case: + // In the case of a lock function without parentheses, it needs this special case: if (suffixTerm.Nodes.Count <= 1) { if (isDirect && isUserFunc) { - AddOpcode(new OpcodePush(OpcodeCall.ARG_MARKER_STRING)); + AddOpcode(new OpcodePush(new KOSArgMarkerType())); AddOpcode(new OpcodeCall(firstIdentifier)); } } @@ -1442,12 +1763,18 @@ private void VisitActualArray(ParseNode node) ++nodeIndex; } - bool remember = identifierIsSuffix; + // Temporarily turn off these flags while evaluating the expression inside + // the array index square brackets. These flags apply to this outer containing + // thing, the array access, not to the expression in the index brackets: + bool rememberIdentIsSuffix = identifierIsSuffix; identifierIsSuffix = false; + bool rememberCompSetDest = compilingSetDestination; + compilingSetDestination = false; + + VisitNode(trailerNode.Nodes[nodeIndex]); // pushes the result of expression inside square brackets. - VisitNode(trailerNode.Nodes[nodeIndex]); - - identifierIsSuffix = remember; + compilingSetDestination = rememberCompSetDest; + identifierIsSuffix = rememberIdentIsSuffix; // Two ways to check if this is the last index (i.e. the 'k' in arr[i][j][k]'), // depending on whether using the "#" syntax or the "[..]" syntax: @@ -1520,8 +1847,26 @@ private string GetIdentifierText(ParseNode node) return string.Empty; } + private void VisitSuffixTerm(ParseNode node) { + // TODO: DELETE THIS METHOD BEFORE RELEASE OF 0.19.0 + // + // NOTE: I suspect this method never ever gets called anymore, + // having been superceeded by the work in VisitSuffix() quite a few + // months ago. But with the tree walk of the compiler and its frequent + // use of the open-ended VisitNode(), it's quite hard to prove by + // eyeball that this is never called. + // + // Therefore I added this exception to complain loudly if any test + // program happens to make the compiler walk a path that uses this + // method. + + throw new KOSCompileException(node.Token, + "TESTING TESTING TESTING. TELL @dunbaratu IMMEDIATELY IF YOU SEE THIS ERROR. " + + "THIS MESSAGE IS A CHECK TO ENSURE THAT VisitSuffixTerm IS NEVER REALLY GETTING CALLED. " + + "IF NONE OF THE KOS DEVS EVER SEE THIS DURING OUR TESTS OF 0.19.0, THEN VisitSuffixTerm " + + "SHOULD BE DELETED BEFORE RELEASING 0.19.0" ); NodeStartHousekeeping(node); if (node.Nodes.Count > 1 && @@ -1607,7 +1952,7 @@ private void VisitFileIdent(ParseNode node) private void VisitString(ParseNode node) { NodeStartHousekeeping(node); - AddOpcode(new OpcodePush(node.Token.Text.Trim('"'))); + AddOpcode(new OpcodePush(new StringValue(node.Token.Text.Trim('"')))); } /// @@ -1893,13 +2238,115 @@ private void VisitInstructionBlock(ParseNode node) PushReturnList(); AddFunctionJumpVars(node); - VisitChildNodes(node); // nextBraceIsFunction state would get incorrectly inherited by my children here if it wasn't turned off up above. + + int argbottomSpot = -1; + if (nextBraceWasFunction) + argbottomSpot = FindArgBottomSpot(node); + + // For each child node, but interrupting for the spot + // where to insert the argbottom opcode: + for (int i = 0 ; i < node.Nodes.Count ; ++i) + { + if (i == argbottomSpot) + AddOpcode(new OpcodeArgBottom()); + + VisitNode(node.Nodes[i]); // nextBraceIsFunction state would get incorrectly inherited by my children here if it wasn't turned off up above. + } if (nextBraceWasFunction) PopReturnList(); EndScope(node); } + + /// + /// Checks whether or not the given ParseNode contains a declare parameter statment + /// inside it that pertains to this function. Note, parameters inside functions + /// nested inside the current one don't count. This method performs a recursive + /// walk. + ///

+ /// While it does this walk, it also tests for whether or not there exists a + /// non-defaulted parameter after a defaulted one, which is illegal and throws an error. + ///
+ /// The node to check + /// true once a parameter without a default clause occurs. + private bool HasParameterStmtNested(ParseNode node, ref bool sawMandatoryParam) + { + // Base case: + if (node.Token.Type == TokenType.declare_parameter_clause) + { + // found one, double check that we don't have an undefaulted param after a defaulted one while we're at it: + // The logic counts backward here. + for (int i = node.Nodes.Count-2 ; i > 0 ; i -= 2) + { + // If this is an expression, then we have a defaultable optional arg. + // else we have a mandatory arg. + TokenType tType = node.Nodes[i].Token.Type; + bool isOptionalParam = (tType == TokenType.expr); + if (isOptionalParam) + { + if (sawMandatoryParam) + { + LineCol location = GetLineCol(node); + throw new KOSDefaultParamNotAtEndException(location); + } + + i -= 2; // skip back a bit further to pass over the extra terms a defaulter has. + } + else + { + sawMandatoryParam = true; + } + } + + return true; + } + + + // Recursive case - make sure to walk backward, and don't abort the scan when a thing is found: + bool rememberReturnVal = false; + for (int i = node.Nodes.Count - 1 ; i >= 0 ; --i) + { + ParseNode child = node.Nodes[i]; + if (child.Token.Type != TokenType.declare_function_clause) // functions nested in functions don't count + { + if (HasParameterStmtNested(child, ref sawMandatoryParam)) + rememberReturnVal = true; + } + } + + return rememberReturnVal; + } + + /// + /// When parsing a function, we need to mark the spot where the lastmost PARAMETER + /// statement occurred, so it knows that that's the point during runtime where it + /// should assert all the arguments passed in have been consumed by the function. + ///

+ /// This is done by inserting a fake extra __ARGBOTTOM "statement" into the parse tree just after + /// the last parameter, or if no parameters existed then right at the very top. + ///
+ /// + private int FindArgBottomSpot(ParseNode node) + { + int lastmostDefParamStmt = -1; + bool sawMandatoryParam = false; + for (int i = node.Nodes.Count-1 ; i >= 0 ; --i) + { + if (HasParameterStmtNested(node.Nodes[i], ref sawMandatoryParam)) + { + // Only set this the very fist time a hit is seen - counting backward from the + // end that will be the lastmost parameter statement: + if (lastmostDefParamStmt == -1) + lastmostDefParamStmt = i; + + // Would break here but instead need to keep checking for defaulted params prior to + // mandatory ones for throwing KOSDefaultParamNotAtEndException + } + } + + return lastmostDefParamStmt+1; + } /// /// Add all the variables at this local scope for holding the jump addresses to go to @@ -1922,7 +2369,7 @@ private void AddFunctionJumpVars(ParseNode node) // a global function in another script are the same scope, since we don't nest files in their own scope. // If we ever change the design to create file scoping, the lastmost check above can probably go away. // - // That last check deliberately takes advantage of short-curcuiting to avoid the expense of IsNew() if it can. + // That last check deliberately takes advantage of short-circuiting to avoid the expense of IsNew() if it can. foreach (UserFunction func in theseFuncs) { @@ -1930,15 +2377,22 @@ private void AddFunctionJumpVars(ParseNode node) // By storing the mapping from identifier name to instruction jump point in // a local variable, we're masking the function from view when its variable // identifier is out of scope. (For example if a function's body of Opcodes - // is stored at locations K100_021 trhough K100_141, then those 100 opcodes + // is stored at locations K100_021 through K100_141, then those 100 opcodes // are compiled statically and are always present in memory in a way that ignores scope, // but the variable "$MyFunc*" that contains the value K100_021 to tell you where - // to jump to to start the function will stop existing once MyFunc is out of scope). - // This is typical of an OOP langauge. The physical code is always static for all + // to jump to start the function will stop existing once MyFunc is out of scope). + // This is typical of an OOP language. The physical code is always static for all // methods and functions, and always has exactly one copy in memory whether there are // one, many, or zero "instances" of it present in scope at the moment. + // + // Note that because we now allow the capture of UserDelegates in user-land variables + // to be called later perhaps from a different scope, we now store a closure context + // for all functions just in case they may get used this way. It's unneded overhead + // to do so most of the time, but it makes the algorithm simple for the few cases + // where it is needed. + AddOpcode(new OpcodePush(func.ScopelessPointerIdentifier)); - AddOpcode(new OpcodePushDelegateRelocateLater(null,false), func.GetFuncLabel()); + AddOpcode(new OpcodePushDelegateRelocateLater(null,true), func.GetFuncLabel()); if (node == null) // global scope, so unconditionally use a normal Store: AddOpcode(new OpcodeStore()); // else @@ -1980,7 +2434,7 @@ private void VisitLockStatement(ParseNode node, StorageModifier whereToStore) } // enable this FlyByWire parameter - AddOpcode(new OpcodePush(OpcodeCall.ARG_MARKER_STRING)); + AddOpcode(new OpcodePush(new KOSArgMarkerType())); AddOpcode(new OpcodePush(lockIdentifier)); AddOpcode(new OpcodePush(true)); AddOpcode(new OpcodeCall("toggleflybywire()")); @@ -2002,44 +2456,47 @@ private void VisitUnlockStatement(ParseNode node) else { string lockIdentifier = node.Nodes[1].Token.Text; - UserFunction lockObject = context.UserFunctions.GetUserFunction(lockIdentifier, GetContainingScopeId(node), node); + UserFunction lockObject = FindExistingUserFunction(lockIdentifier, node); + if (lockObject == null) + { + // If it is null, it's okay to silently do nothing. It just means someone tried to unlock + // an identifier that was never locked in the first place, at least not in this scope or a parent scope. + return; + } UnlockIdentifier(lockObject); } } private void UnlockIdentifier(UserFunction lockObject) { - if (lockObject.IsInitialized()) + if (lockObject.IsSystemLock()) { - if (lockObject.IsSystemLock()) + // disable this FlyByWire parameter + AddOpcode(new OpcodePush(new KOSArgMarkerType())); + AddOpcode(new OpcodePush(lockObject.ScopelessIdentifier)); + AddOpcode(new OpcodePush(false)); + AddOpcode(new OpcodeCall("toggleflybywire()")); + // add a pop to clear out the dummy return value from toggleflybywire() + AddOpcode(new OpcodePop()); + + // remove update trigger + string triggerIdentifier = "lock-" + lockObject.ScopelessIdentifier; + if (context.Triggers.Contains(triggerIdentifier)) { - // disable this FlyByWire parameter - AddOpcode(new OpcodePush(OpcodeCall.ARG_MARKER_STRING)); - AddOpcode(new OpcodePush(lockObject.ScopelessIdentifier)); - AddOpcode(new OpcodePush(false)); - AddOpcode(new OpcodeCall("toggleflybywire()")); - // add a pop to clear out the dummy return value from toggleflybywire() - AddOpcode(new OpcodePop()); - - // remove update trigger - string triggerIdentifier = "lock-" + lockObject.ScopelessIdentifier; - if (context.Triggers.Contains(triggerIdentifier)) - { - Trigger triggerObject = context.Triggers.GetTrigger(triggerIdentifier); - AddOpcode(new OpcodePushRelocateLater(null), triggerObject.GetFunctionLabel()); - AddOpcode(new OpcodeRemoveTrigger()); - } + Trigger triggerObject = context.Triggers.GetTrigger(triggerIdentifier); + AddOpcode(new OpcodePushRelocateLater(null), triggerObject.GetFunctionLabel()); + AddOpcode(new OpcodeRemoveTrigger()); } - - // unlock variable - // Really, we should unlock a variable by unsetting it's pointer var so it's an error to use it: - AddOpcode(new OpcodePush(lockObject.ScopelessPointerIdentifier)); - AddOpcode(new OpcodePushRelocateLater(null), lockObject.DefaultLabel); - if (allowLazyGlobal) - AddOpcode(new OpcodeStore()); - else - AddOpcode(new OpcodeStoreExist()); } + + // unlock variable + // Really, we should unlock a variable by unsetting it's pointer var so it's an error to use it: + AddOpcode(new OpcodePush(lockObject.ScopelessPointerIdentifier)); + AddOpcode(new OpcodePushRelocateLater(null), lockObject.DefaultLabel); + if (allowLazyGlobal) + AddOpcode(new OpcodeStore()); + else + AddOpcode(new OpcodeStoreExist()); } private void VisitOnStatement(ParseNode node) @@ -2078,7 +2535,7 @@ private void VisitWaitStatement(ParseNode node) NodeStartHousekeeping(node); if (nowCompilingTrigger) - throw new KOSWaitInvalidHereException(); + throw new KOSWaitInvalidHereException(new LineCol(lastLine, lastColumn)); if (node.Nodes.Count == 3) { @@ -2116,18 +2573,25 @@ private void VisitDeclareStatement(ParseNode node) // If the declare statement is of the form: // DECLARE PARAMETER ident. // or + // DECLARE PARAMETER ident IS expr. + // or // DECLARE PARAMETER ident,ident,ident... - // AND this is inside a function definition rather than being at the global script level. - // (at the global script level a DEFINE PARAMETER statement is for RUN parameters, which - // get handled differently.) - else if (lastSubNode.Token.Type == TokenType.declare_parameter_clause && - IsInsideDefineFunctionStatement(node)) + // or + // DECLARE PARAMETER ident,ident,ident IS expr, ident IS EXPR... + else if (lastSubNode.Token.Type == TokenType.declare_parameter_clause) { for (int i = 1 ; i < lastSubNode.Nodes.Count ; i += 2) { - VisitNode(lastSubNode.Nodes[i]); - AddOpcode(new OpcodeSwap()); - AddOpcode(CreateAppropriateStoreCode(whereToStore, true)); + bool hasInit = ( i < lastSubNode.Nodes.Count - 2 && + ( lastSubNode.Nodes[i+1].Token.Type == TokenType.IS || + lastSubNode.Nodes[i+1].Token.Type == TokenType.TO ) + ); + ParseNode initExpressionNode = hasInit ? lastSubNode.Nodes[i+2] : null; + VisitDeclareOneParameter(whereToStore, lastSubNode.Nodes[i], initExpressionNode); + if (hasInit) + { + i += 2; // skip the "TO expr" part when looking for the next param. + } } } @@ -2142,6 +2606,41 @@ private void VisitDeclareStatement(ParseNode node) // PreprocessDeclareStatement, with nothing for VisitNode to do. } + /// + /// Process a single parameter from the parameter list for a + /// function or program. i.e. if encountering the statement + /// "DECLARE PARAMETER AA, BB, CC is 0." , then this method needs to be + /// called 3 times, once for AA, once for BB, and once for "CC is 0": + /// + /// is it local or global or lazyglobal + /// Parse node holding the identifier of the param + /// Parse node holding the expression to initialize to if + /// this is a defaultable parameter. If it is not a defaultable parameter, pass null here + private void VisitDeclareOneParameter(StorageModifier whereToStore, ParseNode identifierNode, ParseNode expressionNode) + { + if (expressionNode != null) + { + // This tests each defaultable parameter to see if it's at arg bottom. + // The test must be repeated for each parameter rather than optimizing by + // falling through to all subsequent defaulter expressions for the rest of + // the parameters once the first one finds arg bottom. + // This is because kerboscript does not require the declare parameters to + // be contiguous statements so there may be code in between them you're + // not supposed to skip over. + + AddOpcode(new OpcodeTestArgBottom()); + OpcodeBranchIfFalse branchSkippingInit = new OpcodeBranchIfFalse(); + AddOpcode(branchSkippingInit); + + VisitNode(expressionNode); // evals init expression on the top of the stack where the arg would have been + + branchSkippingInit.DestinationLabel = GetNextLabel(false); + } + VisitNode(identifierNode); + AddOpcode(new OpcodeSwap()); + AddOpcode(CreateAppropriateStoreCode(whereToStore, true)); + } + /// /// Make the right sort of opcodestore-ish opcode for what storage /// mode we're in. @@ -2161,9 +2660,9 @@ private Opcode CreateAppropriateStoreCode(StorageModifier kind, bool lazyGlobal) return new OpcodeStoreGlobal(); default: if (lazyGlobal) - return AddOpcode(new OpcodeStore()); + return new OpcodeStore(); else - return AddOpcode(new OpcodeStoreExist()); + return new OpcodeStoreExist(); } } @@ -2175,12 +2674,12 @@ private StorageModifier GetStorageModifierFor(ParseNode node) { // The default case for anything not explicitly mentioned below. // i.e. if you call this on a SET statement, you'll get this: - StorageModifier modifier = StorageModifier.LAZYGLOBAL; + var modifier = StorageModifier.LAZYGLOBAL; if (node.Nodes.Count == 0) // sanity check - really should never be called on terminal nodes like this. return modifier; - // It may look wierd to do this as a switch when there's only one condition and it + // It may look weird to do this as a switch when there's only one condition and it // looks like it should be an if. It's leaving room for expansion later if the need // arises: switch (node.Token.Type) @@ -2206,9 +2705,9 @@ private StorageModifier GetStorageModifierForDeclare(ParseNode node) (lastSubNode.Token.Type == TokenType.declare_lock_clause ? StorageModifier.GLOBAL : StorageModifier.LOCAL); bool storageKeywordMissing = true; - for (int i = 0 ; i < node.Nodes.Count ; ++i) + foreach (ParseNode t in node.Nodes) { - switch (node.Nodes[i].Token.Type) + switch (t.Token.Type) { case TokenType.GLOBAL: modifier = StorageModifier.GLOBAL; @@ -2226,14 +2725,23 @@ private StorageModifier GetStorageModifierForDeclare(ParseNode node) lastSubNode.Token.Type == TokenType.declare_identifier_clause && !allowLazyGlobal) { - throw new KOSCommandInvalidHere("a bare DECLARE identifier, without a GLOBAL or LOCAL keyword", - "in an identifier initialization while under a @LAZYGLOBAL OFF directive", - "in a file where the default @LAZYGLOBAL behavior is on"); + LineCol location = GetLineCol(node); + throw new KOSCommandInvalidHereException(location, + "a bare DECLARE identifier, without a GLOBAL or LOCAL keyword", + "in an identifier initialization while under a @LAZYGLOBAL OFF directive", + "in a file where the default @LAZYGLOBAL behavior is on"); } if (modifier == StorageModifier.GLOBAL && lastSubNode.Token.Type == TokenType.declare_function_clause) - throw new KOSCommandInvalidHere("GLOBAL", "in a function declaration", "in a variable declaration"); + { + LineCol location = GetLineCol(node); + throw new KOSCommandInvalidHereException(location, "GLOBAL", + "in a function declaration", "in a variable declaration"); + } if (modifier == StorageModifier.GLOBAL && lastSubNode.Token.Type == TokenType.declare_parameter_clause) - throw new KOSCommandInvalidHere("GLOBAL", "in a parameter declaration", "in a variable declaration"); + { + LineCol location = GetLineCol(node); + throw new KOSCommandInvalidHereException(location, "GLOBAL", "in a parameter declaration", "in a variable declaration"); + } return modifier; } @@ -2256,14 +2764,14 @@ private void VisitPrintStatement(ParseNode node) NodeStartHousekeeping(node); if (node.Nodes.Count == 3) { - AddOpcode(new OpcodePush(OpcodeCall.ARG_MARKER_STRING)); + AddOpcode(new OpcodePush(new KOSArgMarkerType())); VisitNode(node.Nodes[1]); AddOpcode(new OpcodeCall("print()")); AddOpcode(new OpcodePop()); // all functions now return a value even if it's a dummy we ignore. } else { - AddOpcode(new OpcodePush(OpcodeCall.ARG_MARKER_STRING)); + AddOpcode(new OpcodePush(new KOSArgMarkerType())); VisitNode(node.Nodes[1]); VisitNode(node.Nodes[4]); VisitNode(node.Nodes[6]); @@ -2275,7 +2783,7 @@ private void VisitPrintStatement(ParseNode node) private void VisitStageStatement(ParseNode node) { NodeStartHousekeeping(node); - AddOpcode(new OpcodePush(OpcodeCall.ARG_MARKER_STRING)); + AddOpcode(new OpcodePush(new KOSArgMarkerType())); AddOpcode(new OpcodeCall("stage()")); AddOpcode(new OpcodePop()); // all functions now return a value even if it's a dummy we ignore. } @@ -2283,7 +2791,7 @@ private void VisitStageStatement(ParseNode node) private void VisitAddStatement(ParseNode node) { NodeStartHousekeeping(node); - AddOpcode(new OpcodePush(OpcodeCall.ARG_MARKER_STRING)); + AddOpcode(new OpcodePush(new KOSArgMarkerType())); VisitNode(node.Nodes[1]); AddOpcode(new OpcodeCall("add()")); AddOpcode(new OpcodePop()); // all functions now return a value even if it's a dummy we ignore. @@ -2292,7 +2800,7 @@ private void VisitAddStatement(ParseNode node) private void VisitRemoveStatement(ParseNode node) { NodeStartHousekeeping(node); - AddOpcode(new OpcodePush(OpcodeCall.ARG_MARKER_STRING)); + AddOpcode(new OpcodePush(new KOSArgMarkerType())); VisitNode(node.Nodes[1]); AddOpcode(new OpcodeCall("remove()")); AddOpcode(new OpcodePop()); // all functions now return a value even if it's a dummy we ignore. @@ -2301,7 +2809,7 @@ private void VisitRemoveStatement(ParseNode node) private void VisitClearStatement(ParseNode node) { NodeStartHousekeeping(node); - AddOpcode(new OpcodePush(OpcodeCall.ARG_MARKER_STRING)); + AddOpcode(new OpcodePush(new KOSArgMarkerType())); AddOpcode(new OpcodeCall("clearscreen()")); AddOpcode(new OpcodePop()); // all functions now return a value even if it's a dummy we ignore. } @@ -2309,7 +2817,7 @@ private void VisitClearStatement(ParseNode node) private void VisitEditStatement(ParseNode node) { NodeStartHousekeeping(node); - AddOpcode(new OpcodePush(OpcodeCall.ARG_MARKER_STRING)); + AddOpcode(new OpcodePush(new KOSArgMarkerType())); VisitNode(node.Nodes[1]); AddOpcode(new OpcodeCall("edit()")); AddOpcode(new OpcodePop()); // all functions now return a value even if it's a dummy we ignore. @@ -2319,28 +2827,57 @@ private void VisitRunStatement(ParseNode node) { NodeStartHousekeeping(node); int volumeIndex = 3; + int argListIndex = 3; + int progNameIndex = 1; + bool hasOnce = false; + if (node.Nodes[1].Token.Type == TokenType.ONCE) + { + hasOnce = true; + ++volumeIndex; + ++argListIndex; + ++progNameIndex; + } + if (hasOnce && ! options.LoadProgramsInSameAddressSpace) + throw new KOSOnceInvalidHereException(new LineCol(lastLine, lastColumn)); // process program arguments - AddOpcode(new OpcodePush(OpcodeCall.ARG_MARKER_STRING)); // regardless of whether it's called directly or indirectly, we still need at least one. - bool hasON = node.Nodes.Any(cn => cn.Token.Type == TokenType.ON); - if (!hasON && options.LoadProgramsInSameAddressSpace) + AddOpcode(new OpcodePush(new KOSArgMarkerType())); // regardless of whether it's called directly or indirectly, we still need at least one. + bool hasOn = node.Nodes.Any(cn => cn.Token.Type == TokenType.ON); + if (!hasOn && options.LoadProgramsInSameAddressSpace) { // When running in the same address space, we need an extra arg marker under the args, because // of the double-indirect call where we call the subroutine that was built in PreProcessRunStatement, // and IT in turn calls the actual subprogram (after deciding whether or not it needs to compile it // into existence). - AddOpcode(new OpcodePush(OpcodeCall.ARG_MARKER_STRING)); + AddOpcode(new OpcodePush(new KOSArgMarkerType())); } - - if (node.Nodes.Count > 3 && node.Nodes[3].Token.Type == TokenType.arglist) + + // Needs to push a true/false onto the stack to record whether or not there was a "once" + // associated with this run (i.e. "run" versus "run once"). This has to go + // underneath the actual args. This arg, and them, will get reversed by OpcodeCall, thus this + // boolean will end up atop the stack by the time the 'once' checker built in + // PreprocessRunStatement() gets to it: + if (!hasOn && options.LoadProgramsInSameAddressSpace) { - VisitNode(node.Nodes[3]); + string subprogramName = node.Nodes[progNameIndex].Token.Text; // This assumption that the filenames are known at compile-time is why we can't do RUN expr + if (context.Subprograms.Contains(subprogramName)) + { + AddOpcode(new OpcodePush(hasOnce)); // tell that routine whether or not to skip the run when already compiled. + } + } + + if (node.Nodes.Count > argListIndex && node.Nodes[argListIndex].Token.Type == TokenType.arglist) + { + // Run args need to get pushed to the stack in the opposite order to how + // function args do, because they pass through two levels of OpcodeCall, and + // thus get reversed twice, whereas function args only get reversed once: + VisitArgListReversed(node.Nodes[argListIndex]); volumeIndex += 3; } - if (!hasON && options.LoadProgramsInSameAddressSpace) + if (!hasOn && options.LoadProgramsInSameAddressSpace) { - string subprogramName = node.Nodes[1].Token.Text; // This assumption that the filenames are known at compile-time is why we can't do RUN expr + string subprogramName = node.Nodes[progNameIndex].Token.Text; // This assumption that the filenames are known at compile-time is why we can't do RUN expr if (context.Subprograms.Contains(subprogramName)) // and instead have to do RUN FILEIDENT, in the parser def. { Subprogram subprogramObject = context.Subprograms.GetSubprogram(subprogramName); @@ -2353,10 +2890,10 @@ private void VisitRunStatement(ParseNode node) // When running in a new address space, we also need a second arg marker, but in this // case it has to go over the top of the other args, not under them, to tell the RUN // builtin function where its arguments end and the progs arguments start: - AddOpcode(new OpcodePush(OpcodeCall.ARG_MARKER_STRING)); + AddOpcode(new OpcodePush(new KOSArgMarkerType())); // program name - VisitNode(node.Nodes[1]); + VisitNode(node.Nodes[progNameIndex]); // volume where program should be executed (null means local) if (volumeIndex < node.Nodes.Count) @@ -2376,7 +2913,7 @@ private void VisitRunStatement(ParseNode node) private void VisitCompileStatement(ParseNode node) { NodeStartHousekeeping(node); - AddOpcode(new OpcodePush(OpcodeCall.ARG_MARKER_STRING)); // for the load() function. + AddOpcode(new OpcodePush(new KOSArgMarkerType())); // for the load() function. VisitNode(node.Nodes[1]); if (node.Nodes.Count > 3) { @@ -2397,7 +2934,7 @@ private void VisitCompileStatement(ParseNode node) private void VisitSwitchStatement(ParseNode node) { NodeStartHousekeeping(node); - AddOpcode(new OpcodePush(OpcodeCall.ARG_MARKER_STRING)); + AddOpcode(new OpcodePush(new KOSArgMarkerType())); VisitNode(node.Nodes[2]); AddOpcode(new OpcodeCall("switch()")); AddOpcode(new OpcodePop()); // all functions now return a value even if it's a dummy we ignore. @@ -2406,7 +2943,7 @@ private void VisitSwitchStatement(ParseNode node) private void VisitCopyStatement(ParseNode node) { NodeStartHousekeeping(node); - AddOpcode(new OpcodePush(OpcodeCall.ARG_MARKER_STRING)); + AddOpcode(new OpcodePush(new KOSArgMarkerType())); VisitNode(node.Nodes[1]); AddOpcode(new OpcodePush(node.Nodes[2].Token.Type == TokenType.FROM ? "from" : "to")); @@ -2422,7 +2959,7 @@ private void VisitRenameStatement(ParseNode node) int oldNameIndex = 2; int newNameIndex = 4; - AddOpcode(new OpcodePush(OpcodeCall.ARG_MARKER_STRING)); + AddOpcode(new OpcodePush(new KOSArgMarkerType())); if (node.Nodes.Count == 5) { oldNameIndex--; @@ -2431,7 +2968,7 @@ private void VisitRenameStatement(ParseNode node) } else { - AddOpcode(new OpcodePush(node.Nodes[2].Token.Type == TokenType.FROM ? "file" : "volume")); + AddOpcode(new OpcodePush(node.Nodes[1].Token.Type == TokenType.FILE ? "file" : "volume")); } VisitNode(node.Nodes[oldNameIndex]); @@ -2443,7 +2980,7 @@ private void VisitRenameStatement(ParseNode node) private void VisitDeleteStatement(ParseNode node) { NodeStartHousekeeping(node); - AddOpcode(new OpcodePush(OpcodeCall.ARG_MARKER_STRING)); + AddOpcode(new OpcodePush(new KOSArgMarkerType())); VisitNode(node.Nodes[1]); if (node.Nodes.Count == 5) @@ -2466,7 +3003,7 @@ private void VisitListStatement(ParseNode node) // destination variable VisitVariableNode(node.Nodes[3]); // list type - AddOpcode(new OpcodePush(OpcodeCall.ARG_MARKER_STRING)); + AddOpcode(new OpcodePush(new KOSArgMarkerType())); VisitNode(node.Nodes[1]); // build list AddOpcode(new OpcodeCall("buildlist()")); @@ -2477,7 +3014,7 @@ private void VisitListStatement(ParseNode node) } else { - AddOpcode(new OpcodePush(OpcodeCall.ARG_MARKER_STRING)); + AddOpcode(new OpcodePush(new KOSArgMarkerType())); // list type if (hasIdentifier) VisitNode(node.Nodes[1]); else AddOpcode(new OpcodePush("files")); @@ -2490,7 +3027,7 @@ private void VisitListStatement(ParseNode node) private void VisitLogStatement(ParseNode node) { NodeStartHousekeeping(node); - AddOpcode(new OpcodePush(OpcodeCall.ARG_MARKER_STRING)); + AddOpcode(new OpcodePush(new KOSArgMarkerType())); VisitNode(node.Nodes[1]); VisitNode(node.Nodes[3]); AddOpcode(new OpcodeCall("logfile()")); @@ -2502,7 +3039,7 @@ private void VisitBreakStatement(ParseNode node) NodeStartHousekeeping(node); if (!nowInALoop) - throw new KOSBreakInvalidHereException(); + throw new KOSBreakInvalidHereException(new LineCol(lastLine, lastColumn)); // Will need to pop out the number of variables scopes equal to the // number of braces we're skipping out of. For now just record the @@ -2511,7 +3048,7 @@ private void VisitBreakStatement(ParseNode node) // in the final program. The reason for not just doing it now is // that we have to wait until the bottom of the nested braces to // find out where to jump to anyway, so this opcode will have to be - // revisted then anyway: + // revisited then anyway: Opcode popScope = AddOpcode(new OpcodePopScope(braceNestLevel)); AddToBreakList(popScope); @@ -2526,18 +3063,16 @@ private void VisitReturnStatement(ParseNode node) { NodeStartHousekeeping(node); - int nestLevelOfFuncBraces = GetReturnNestLevel(); + var nestLevelOfFuncBraces = (Int16)GetReturnNestLevel(); if (nestLevelOfFuncBraces < 0) - throw new KOSReturnInvalidHereException(); - + throw new KOSReturnInvalidHereException(new LineCol(lastLine, lastColumn)); + // Push the return expression onto the stack, or if it was a naked RETURN // keyword with no expression, then push a secret dummy return value of zero: - if (node.Nodes.Count > 1) + if (node.Nodes.Count > 2) { VisitNode(node.Nodes[1]); - AddOpcode(new OpcodeEval()); // vital because we can't return a local var to the caller, - // we must return the value it contained instead. } else { @@ -2548,8 +3083,8 @@ private void VisitReturnStatement(ParseNode node) // simpler than the BREAK case because RETURN already knows to use the function // call stack to figure out where to return to, so we don't have to wait until // later to decide where to jump to like we do in BREAK: - AddOpcode(new OpcodePopScope(1 + braceNestLevel - nestLevelOfFuncBraces)); - AddOpcode(new OpcodeReturn()); + int depth = 1 + braceNestLevel - nestLevelOfFuncBraces; + AddOpcode(new OpcodeReturn((Int16)depth)); } private void VisitPreserveStatement(ParseNode node) @@ -2557,7 +3092,7 @@ private void VisitPreserveStatement(ParseNode node) NodeStartHousekeeping(node); if (!nowCompilingTrigger) - throw new KOSPreserveInvalidHereException(); + throw new KOSPreserveInvalidHereException(new LineCol(lastLine, lastColumn)); string flagName = PeekTriggerRemoveName(); AddOpcode(new OpcodePush(flagName)); @@ -2568,7 +3103,7 @@ private void VisitPreserveStatement(ParseNode node) private void VisitRebootStatement(ParseNode node) { NodeStartHousekeeping(node); - AddOpcode(new OpcodePush(OpcodeCall.ARG_MARKER_STRING)); + AddOpcode(new OpcodePush(new KOSArgMarkerType())); AddOpcode(new OpcodeCall("reboot()")); AddOpcode(new OpcodePop()); // all functions now return a value even if we ignore it. Not sure it matters in the case of reboot() though. } @@ -2576,7 +3111,7 @@ private void VisitRebootStatement(ParseNode node) private void VisitShutdownStatement(ParseNode node) { NodeStartHousekeeping(node); - AddOpcode(new OpcodePush(OpcodeCall.ARG_MARKER_STRING)); + AddOpcode(new OpcodePush(new KOSArgMarkerType())); AddOpcode(new OpcodeCall("shutdown()")); AddOpcode(new OpcodePop()); // all functions now return a value even if we ignore it. Not sure it matters in the case of shutdown() though. } @@ -2693,6 +3228,8 @@ private void VisitIdentifierLedExpression(ParseNode node) public void VisitDirective(ParseNode node) { + NodeStartHousekeeping(node); + // For now, let the compiler decide if the compiler directive is in the wrong place, // not the parser. Therefore the parser treats it like a normal statement and here in // the compiler we'll decide per-directive which directives can go where: @@ -2700,7 +3237,7 @@ public void VisitDirective(ParseNode node) ParseNode directiveNode = node.Nodes[0]; // a directive contains the exact directive node nested one step inside it. if (directiveNode.Nodes.Count < 2) - throw new KOSCompileException("Kerboscript compiler directive ('@') without a keyword after it."); + throw new KOSCompileException(new LineCol(lastLine, lastColumn), "Kerboscript compiler directive ('@') without a keyword after it."); switch (directiveNode.Nodes[1].Token.Type) @@ -2712,14 +3249,14 @@ public void VisitDirective(ParseNode node) // There is room for expansion here if we want to add more compiler directives. default: - throw new KOSCompileException("Kerboscript compiler directive @"+directiveNode.Nodes[1].Text+" is unknown."); + throw new KOSCompileException(new LineCol(lastLine, lastColumn), "Kerboscript compiler directive @"+directiveNode.Nodes[1].Text+" is unknown."); } } public void VisitLazyGlobalDirective(ParseNode node) { if (node.Nodes.Count < 3 || node.Nodes[2].Token.Type != TokenType.onoff_trailer) - throw new KOSCompileException("Kerboscript compiler directive @LAZYGLOBAL requires an ON or an OFF keyword."); + throw new KOSCompileException(new LineCol(lastLine, lastColumn), "Kerboscript compiler directive @LAZYGLOBAL requires an ON or an OFF keyword."); // This particular directive is only allowed up at the top of a file, prior to any other non-directive statements. // --------------------------------------------------------------------------------------------------------------- @@ -2749,14 +3286,14 @@ public void VisitLazyGlobalDirective(ParseNode node) } ancestor = ancestor.Parent; } - // Check 2 - see if I am at the top. The only statements allowed to preceed me are other directives: + // Check 2 - see if I am at the top. The only statements allowed to precede me are other directives: if (validLocation && ancestor != null && ancestor.Token.Type == TokenType.Start) { // ancestor is now the Start node for the compile: int myInstructionIndex = ancestor.Nodes.IndexOf(myInstructionContainer); // would be an expensive walk - except this should only exist once, near the top. for (int i = 0; validLocation && i < myInstructionIndex; ++i) { - // if a statement preceeding me is anything other than another directive, it's wrong: + // if a statement preceding me is anything other than another directive, it's wrong: if (ancestor.Nodes[i].Token.Type != TokenType.directive || (ancestor.Nodes[i].Token.Type == TokenType.instruction && ancestor.Nodes[i].Nodes[0].Token.Type != TokenType.directive) @@ -2765,7 +3302,7 @@ public void VisitLazyGlobalDirective(ParseNode node) } } if (!validLocation) - throw new KOSCommandInvalidHere("@LAZYGLOBAL", + throw new KOSCommandInvalidHereException(new LineCol(node.Token.Line, node.Token.Column), "@LAZYGLOBAL", "after the first command in the file", "at the start of a script file, prior to any other statements"); diff --git a/src/kOS.Safe/Compilation/KS/KSScript.cs b/src/kOS.Safe/Compilation/KS/KSScript.cs index d597edb5e..d40622836 100644 --- a/src/kOS.Safe/Compilation/KS/KSScript.cs +++ b/src/kOS.Safe/Compilation/KS/KSScript.cs @@ -1,5 +1,5 @@ -using System.Collections.Generic; using kOS.Safe.Exceptions; +using System.Collections.Generic; namespace kOS.Safe.Compilation.KS { @@ -19,50 +19,46 @@ public KSScript() public override List Compile(string filePath, int startLineNum, string scriptText, string contextId, CompilerOptions options) { - List parts = null; - - // make the code lowercase - scriptText = MakeLowerCase(scriptText); - scriptText = ReplaceIdentifiers(scriptText); - - //if (contextId != "interpreter") parts = _cache.GetFromCache(scriptText); - - // if parts is null means the code doesn't exists in the cache - if (parts == null) + var parts = new List(); + ParseTree parseTree = parser.Parse(scriptText); + if (parseTree.Errors.Count == 0) { - parts = new List(); - ParseTree parseTree = parser.Parse(scriptText); - if (parseTree.Errors.Count == 0) - { - var compiler = new Compiler(); - LoadContext(contextId); + var compiler = new Compiler(); + LoadContext(contextId); - // TODO: handle compile errors (e.g. wrong run parameter count) - CodePart mainPart = compiler.Compile(startLineNum, parseTree, currentContext, options); + CodePart mainPart; + try + { + mainPart = compiler.Compile(startLineNum, parseTree, currentContext, options); + } + catch (KOSCompileException e) + { + e.AddSourceText((short)startLineNum, scriptText); + throw; + } - // add locks and triggers - parts.AddRange(currentContext.UserFunctions.GetNewParts()); - parts.AddRange(currentContext.Triggers.GetNewParts()); - parts.AddRange(currentContext.Subprograms.GetNewParts()); + // add locks and triggers + parts.AddRange(currentContext.UserFunctions.GetNewParts()); + parts.AddRange(currentContext.Triggers.GetNewParts()); + parts.AddRange(currentContext.Subprograms.GetNewParts()); - parts.Add(mainPart); + parts.Add(mainPart); - AssignSourceId(parts, filePath); + AssignSourceId(parts, filePath); - //if (contextId != "interpreter") _cache.AddToCache(scriptText, parts); - } - else - { - // TODO: Come back here and check on the possiblity of reporting more - // errors than just the first one. It appears that TinyPG builds a - // whole array of error messages so people could see multiple syntax - // errors in one go if we supported the reporting of it. It may be that - // it was deliberately not done because it might be too verbose that way - // for the small text terminal. - - ParseError error = parseTree.Errors[0]; - throw new KOSParseException(error, scriptText); - } + //if (contextId != "interpreter") _cache.AddToCache(scriptText, parts); + } + else + { + // TODO: Come back here and check on the possibility of reporting more + // errors than just the first one. It appears that TinyPG builds a + // whole array of error messages so people could see multiple syntax + // errors in one go if we supported the reporting of it. It may be that + // it was deliberately not done because it might be too verbose that way + // for the small text terminal. + + ParseError error = parseTree.Errors[0]; + throw new KOSParseException(error, scriptText); } return parts; @@ -109,33 +105,78 @@ public override bool IsCommandComplete(string command) { char[] commandChars = command.ToCharArray(); int length = commandChars.Length; - int openCurlyBrackets = 0; - int openParentheses = 0; - + bool inQuotes = false; + bool inCommentToEoln = false; + bool waitForMoreTokens = false; + char curChar; + char prevChar = '\0'; + + // First, we have to check manually for unterminated string literals because + // they are a continuation in the midst of a token, rather than between tokens, + // and thus the parser doesn't quite catch them the same way. for (int n = 0; n < length; n++) { - switch (commandChars[n]) + curChar = commandChars[n]; + switch (curChar) { - // match curly brackets - case '{': - openCurlyBrackets++; + // Track if we are in a string literal that didn't close, + // and make sure it's not a string literal inside a comment, + // because those don't count: + case '\"': + if (! inCommentToEoln) + inQuotes = !(inQuotes); break; - case '}': - openCurlyBrackets--; + case '/': + if (prevChar == '/' && !inQuotes ) + inCommentToEoln = true; break; - // match parentheses - case '(': - openParentheses++; + case '\n': + case '\r': + inCommentToEoln = false; break; - case ')': - openParentheses--; + } + prevChar = curChar; + } + + // Second, if we aren't in an unterminated literal string, then let + // the parser do the rest of the checking by seeing if it reports + // Unexpected Token 'EOF', and looking at what it was expecting instead. + + // - Possible future refactor - + // The string comparison of the human-readable message is the only way + // to find out if the error is the exact one we're looking for, which + // is what the code below does, and that's a bit fragile. + // Making it use a more robust check would first require editing the + // TinyPG C# source code and changing the way it encodes a ParseError + // so it stores that sort of thing as separate pieces of data in its members. + + if (!inQuotes) + { + ParseTree parseTree = parser.Parse(command); + + foreach (ParseError err in parseTree.Errors) + { + if (err.Message.StartsWith("Unexpected token 'EOF'")) + { + if (err.Message.Contains("Expected CURLYCLOSE") || + err.Message.Contains("Expected BRACKETCLOSE")) + { + waitForMoreTokens = true; + } + } + else + { + // If ANY parse errors are NOT of the form "Unexpected Token 'EOF' ... yadda yadda" then that + // automatically means we should fail and not continue regardless of whether or not the other + // parse errors may have indicated a continuation is needed. We want to let the user see + // the error happen instead. + waitForMoreTokens = false; break; + } } } - // returns true even if you wrote extra closing curly brackets/parentheses - return (openCurlyBrackets <= 0) - && (openParentheses <= 0); + return (!waitForMoreTokens) && (!inQuotes); } } -} +} \ No newline at end of file diff --git a/src/kOS.Safe/Compilation/KS/LineCol.cs b/src/kOS.Safe/Compilation/KS/LineCol.cs new file mode 100644 index 000000000..757c19d1f --- /dev/null +++ b/src/kOS.Safe/Compilation/KS/LineCol.cs @@ -0,0 +1,30 @@ +namespace kOS.Safe.Compilation.KS +{ + /// + /// Just a dumb simple tuple of line and column, to be returned in + /// places where the compiler needs to treat the pair of them like + /// a single return value from a method. + /// + public class LineCol + { + public short Line { get; private set; } + public short Column { get; private set; } + + public LineCol(short line, short column) + { + Line = line; + Column = column; + } + + public LineCol(int line, int column) + { + Line = (short)line; + Column = (short)column; + } + + public static LineCol Unknown() + { + return new LineCol(-1,-1); + } + } +} diff --git a/src/kOS.Safe/Compilation/KS/ParseTree.cs b/src/kOS.Safe/Compilation/KS/ParseTree.cs index d0de9e327..1cf1e9c50 100644 --- a/src/kOS.Safe/Compilation/KS/ParseTree.cs +++ b/src/kOS.Safe/Compilation/KS/ParseTree.cs @@ -202,6 +202,9 @@ internal object Eval(ParseTree tree, params object[] paramlist) case TokenType.until_stmt: Value = Evaluntil_stmt(tree, paramlist); break; + case TokenType.fromloop_stmt: + Value = Evalfromloop_stmt(tree, paramlist); + break; case TokenType.unlock_stmt: Value = Evalunlock_stmt(tree, paramlist); break; @@ -423,6 +426,13 @@ protected virtual object Evaluntil_stmt(ParseTree tree, params object[] paramlis return null; } + protected virtual object Evalfromloop_stmt(ParseTree tree, params object[] paramlist) + { + foreach (var node in Nodes) + node.Eval(tree, paramlist); + return null; + } + protected virtual object Evalunlock_stmt(ParseTree tree, params object[] paramlist) { foreach (var node in Nodes) diff --git a/src/kOS.Safe/Compilation/KS/Parser.cs b/src/kOS.Safe/Compilation/KS/Parser.cs index 84d245e64..9096a494c 100644 --- a/src/kOS.Safe/Compilation/KS/Parser.cs +++ b/src/kOS.Safe/Compilation/KS/Parser.cs @@ -47,10 +47,11 @@ private void ParseStart(ParseNode parent) - tok = scanner.LookAhead(TokenType.SET, TokenType.IF, TokenType.UNTIL, TokenType.UNLOCK, TokenType.PRINT, TokenType.ON, TokenType.TOGGLE, TokenType.WAIT, TokenType.WHEN, TokenType.STAGE, TokenType.CLEARSCREEN, TokenType.ADD, TokenType.REMOVE, TokenType.LOG, TokenType.BREAK, TokenType.PRESERVE, TokenType.PARAMETER, TokenType.FUNCTION, TokenType.LOCK, TokenType.DECLARE, TokenType.LOCAL, TokenType.GLOBAL, TokenType.RETURN, TokenType.SWITCH, TokenType.COPY, TokenType.RENAME, TokenType.DELETE, TokenType.EDIT, TokenType.RUN, TokenType.COMPILE, TokenType.LIST, TokenType.REBOOT, TokenType.SHUTDOWN, TokenType.FOR, TokenType.UNSET, TokenType.CURLYOPEN, TokenType.INTEGER, TokenType.DOUBLE, TokenType.TRUEFALSE, TokenType.IDENTIFIER, TokenType.FILEIDENT, TokenType.BRACKETOPEN, TokenType.STRING, TokenType.ATSIGN); + tok = scanner.LookAhead(TokenType.SET, TokenType.IF, TokenType.UNTIL, TokenType.FROM, TokenType.UNLOCK, TokenType.PRINT, TokenType.ON, TokenType.TOGGLE, TokenType.WAIT, TokenType.WHEN, TokenType.STAGE, TokenType.CLEARSCREEN, TokenType.ADD, TokenType.REMOVE, TokenType.LOG, TokenType.BREAK, TokenType.PRESERVE, TokenType.PARAMETER, TokenType.FUNCTION, TokenType.LOCK, TokenType.DECLARE, TokenType.LOCAL, TokenType.GLOBAL, TokenType.RETURN, TokenType.SWITCH, TokenType.COPY, TokenType.RENAME, TokenType.DELETE, TokenType.EDIT, TokenType.RUN, TokenType.COMPILE, TokenType.LIST, TokenType.REBOOT, TokenType.SHUTDOWN, TokenType.FOR, TokenType.UNSET, TokenType.CURLYOPEN, TokenType.INTEGER, TokenType.DOUBLE, TokenType.TRUEFALSE, TokenType.IDENTIFIER, TokenType.FILEIDENT, TokenType.BRACKETOPEN, TokenType.STRING, TokenType.ATSIGN); while (tok.Type == TokenType.SET || tok.Type == TokenType.IF || tok.Type == TokenType.UNTIL + || tok.Type == TokenType.FROM || tok.Type == TokenType.UNLOCK || tok.Type == TokenType.PRINT || tok.Type == TokenType.ON @@ -94,7 +95,7 @@ private void ParseStart(ParseNode parent) || tok.Type == TokenType.ATSIGN) { Parseinstruction(node); - tok = scanner.LookAhead(TokenType.SET, TokenType.IF, TokenType.UNTIL, TokenType.UNLOCK, TokenType.PRINT, TokenType.ON, TokenType.TOGGLE, TokenType.WAIT, TokenType.WHEN, TokenType.STAGE, TokenType.CLEARSCREEN, TokenType.ADD, TokenType.REMOVE, TokenType.LOG, TokenType.BREAK, TokenType.PRESERVE, TokenType.PARAMETER, TokenType.FUNCTION, TokenType.LOCK, TokenType.DECLARE, TokenType.LOCAL, TokenType.GLOBAL, TokenType.RETURN, TokenType.SWITCH, TokenType.COPY, TokenType.RENAME, TokenType.DELETE, TokenType.EDIT, TokenType.RUN, TokenType.COMPILE, TokenType.LIST, TokenType.REBOOT, TokenType.SHUTDOWN, TokenType.FOR, TokenType.UNSET, TokenType.CURLYOPEN, TokenType.INTEGER, TokenType.DOUBLE, TokenType.TRUEFALSE, TokenType.IDENTIFIER, TokenType.FILEIDENT, TokenType.BRACKETOPEN, TokenType.STRING, TokenType.ATSIGN); + tok = scanner.LookAhead(TokenType.SET, TokenType.IF, TokenType.UNTIL, TokenType.FROM, TokenType.UNLOCK, TokenType.PRINT, TokenType.ON, TokenType.TOGGLE, TokenType.WAIT, TokenType.WHEN, TokenType.STAGE, TokenType.CLEARSCREEN, TokenType.ADD, TokenType.REMOVE, TokenType.LOG, TokenType.BREAK, TokenType.PRESERVE, TokenType.PARAMETER, TokenType.FUNCTION, TokenType.LOCK, TokenType.DECLARE, TokenType.LOCAL, TokenType.GLOBAL, TokenType.RETURN, TokenType.SWITCH, TokenType.COPY, TokenType.RENAME, TokenType.DELETE, TokenType.EDIT, TokenType.RUN, TokenType.COMPILE, TokenType.LIST, TokenType.REBOOT, TokenType.SHUTDOWN, TokenType.FOR, TokenType.UNSET, TokenType.CURLYOPEN, TokenType.INTEGER, TokenType.DOUBLE, TokenType.TRUEFALSE, TokenType.IDENTIFIER, TokenType.FILEIDENT, TokenType.BRACKETOPEN, TokenType.STRING, TokenType.ATSIGN); } @@ -129,10 +130,11 @@ private void Parseinstruction_block(ParseNode parent) } - tok = scanner.LookAhead(TokenType.SET, TokenType.IF, TokenType.UNTIL, TokenType.UNLOCK, TokenType.PRINT, TokenType.ON, TokenType.TOGGLE, TokenType.WAIT, TokenType.WHEN, TokenType.STAGE, TokenType.CLEARSCREEN, TokenType.ADD, TokenType.REMOVE, TokenType.LOG, TokenType.BREAK, TokenType.PRESERVE, TokenType.PARAMETER, TokenType.FUNCTION, TokenType.LOCK, TokenType.DECLARE, TokenType.LOCAL, TokenType.GLOBAL, TokenType.RETURN, TokenType.SWITCH, TokenType.COPY, TokenType.RENAME, TokenType.DELETE, TokenType.EDIT, TokenType.RUN, TokenType.COMPILE, TokenType.LIST, TokenType.REBOOT, TokenType.SHUTDOWN, TokenType.FOR, TokenType.UNSET, TokenType.CURLYOPEN, TokenType.INTEGER, TokenType.DOUBLE, TokenType.TRUEFALSE, TokenType.IDENTIFIER, TokenType.FILEIDENT, TokenType.BRACKETOPEN, TokenType.STRING, TokenType.ATSIGN); + tok = scanner.LookAhead(TokenType.SET, TokenType.IF, TokenType.UNTIL, TokenType.FROM, TokenType.UNLOCK, TokenType.PRINT, TokenType.ON, TokenType.TOGGLE, TokenType.WAIT, TokenType.WHEN, TokenType.STAGE, TokenType.CLEARSCREEN, TokenType.ADD, TokenType.REMOVE, TokenType.LOG, TokenType.BREAK, TokenType.PRESERVE, TokenType.PARAMETER, TokenType.FUNCTION, TokenType.LOCK, TokenType.DECLARE, TokenType.LOCAL, TokenType.GLOBAL, TokenType.RETURN, TokenType.SWITCH, TokenType.COPY, TokenType.RENAME, TokenType.DELETE, TokenType.EDIT, TokenType.RUN, TokenType.COMPILE, TokenType.LIST, TokenType.REBOOT, TokenType.SHUTDOWN, TokenType.FOR, TokenType.UNSET, TokenType.CURLYOPEN, TokenType.INTEGER, TokenType.DOUBLE, TokenType.TRUEFALSE, TokenType.IDENTIFIER, TokenType.FILEIDENT, TokenType.BRACKETOPEN, TokenType.STRING, TokenType.ATSIGN); while (tok.Type == TokenType.SET || tok.Type == TokenType.IF || tok.Type == TokenType.UNTIL + || tok.Type == TokenType.FROM || tok.Type == TokenType.UNLOCK || tok.Type == TokenType.PRINT || tok.Type == TokenType.ON @@ -176,7 +178,7 @@ private void Parseinstruction_block(ParseNode parent) || tok.Type == TokenType.ATSIGN) { Parseinstruction(node); - tok = scanner.LookAhead(TokenType.SET, TokenType.IF, TokenType.UNTIL, TokenType.UNLOCK, TokenType.PRINT, TokenType.ON, TokenType.TOGGLE, TokenType.WAIT, TokenType.WHEN, TokenType.STAGE, TokenType.CLEARSCREEN, TokenType.ADD, TokenType.REMOVE, TokenType.LOG, TokenType.BREAK, TokenType.PRESERVE, TokenType.PARAMETER, TokenType.FUNCTION, TokenType.LOCK, TokenType.DECLARE, TokenType.LOCAL, TokenType.GLOBAL, TokenType.RETURN, TokenType.SWITCH, TokenType.COPY, TokenType.RENAME, TokenType.DELETE, TokenType.EDIT, TokenType.RUN, TokenType.COMPILE, TokenType.LIST, TokenType.REBOOT, TokenType.SHUTDOWN, TokenType.FOR, TokenType.UNSET, TokenType.CURLYOPEN, TokenType.INTEGER, TokenType.DOUBLE, TokenType.TRUEFALSE, TokenType.IDENTIFIER, TokenType.FILEIDENT, TokenType.BRACKETOPEN, TokenType.STRING, TokenType.ATSIGN); + tok = scanner.LookAhead(TokenType.SET, TokenType.IF, TokenType.UNTIL, TokenType.FROM, TokenType.UNLOCK, TokenType.PRINT, TokenType.ON, TokenType.TOGGLE, TokenType.WAIT, TokenType.WHEN, TokenType.STAGE, TokenType.CLEARSCREEN, TokenType.ADD, TokenType.REMOVE, TokenType.LOG, TokenType.BREAK, TokenType.PRESERVE, TokenType.PARAMETER, TokenType.FUNCTION, TokenType.LOCK, TokenType.DECLARE, TokenType.LOCAL, TokenType.GLOBAL, TokenType.RETURN, TokenType.SWITCH, TokenType.COPY, TokenType.RENAME, TokenType.DELETE, TokenType.EDIT, TokenType.RUN, TokenType.COMPILE, TokenType.LIST, TokenType.REBOOT, TokenType.SHUTDOWN, TokenType.FOR, TokenType.UNSET, TokenType.CURLYOPEN, TokenType.INTEGER, TokenType.DOUBLE, TokenType.TRUEFALSE, TokenType.IDENTIFIER, TokenType.FILEIDENT, TokenType.BRACKETOPEN, TokenType.STRING, TokenType.ATSIGN); } @@ -213,7 +215,7 @@ private void Parseinstruction(ParseNode parent) ParseNode node = parent.CreateNode(scanner.GetToken(TokenType.instruction), "instruction"); parent.Nodes.Add(node); - tok = scanner.LookAhead(TokenType.SET, TokenType.IF, TokenType.UNTIL, TokenType.UNLOCK, TokenType.PRINT, TokenType.ON, TokenType.TOGGLE, TokenType.WAIT, TokenType.WHEN, TokenType.STAGE, TokenType.CLEARSCREEN, TokenType.ADD, TokenType.REMOVE, TokenType.LOG, TokenType.BREAK, TokenType.PRESERVE, TokenType.PARAMETER, TokenType.FUNCTION, TokenType.LOCK, TokenType.DECLARE, TokenType.LOCAL, TokenType.GLOBAL, TokenType.RETURN, TokenType.SWITCH, TokenType.COPY, TokenType.RENAME, TokenType.DELETE, TokenType.EDIT, TokenType.RUN, TokenType.COMPILE, TokenType.LIST, TokenType.REBOOT, TokenType.SHUTDOWN, TokenType.FOR, TokenType.UNSET, TokenType.CURLYOPEN, TokenType.INTEGER, TokenType.DOUBLE, TokenType.TRUEFALSE, TokenType.IDENTIFIER, TokenType.FILEIDENT, TokenType.BRACKETOPEN, TokenType.STRING, TokenType.ATSIGN); + tok = scanner.LookAhead(TokenType.SET, TokenType.IF, TokenType.UNTIL, TokenType.FROM, TokenType.UNLOCK, TokenType.PRINT, TokenType.ON, TokenType.TOGGLE, TokenType.WAIT, TokenType.WHEN, TokenType.STAGE, TokenType.CLEARSCREEN, TokenType.ADD, TokenType.REMOVE, TokenType.LOG, TokenType.BREAK, TokenType.PRESERVE, TokenType.PARAMETER, TokenType.FUNCTION, TokenType.LOCK, TokenType.DECLARE, TokenType.LOCAL, TokenType.GLOBAL, TokenType.RETURN, TokenType.SWITCH, TokenType.COPY, TokenType.RENAME, TokenType.DELETE, TokenType.EDIT, TokenType.RUN, TokenType.COMPILE, TokenType.LIST, TokenType.REBOOT, TokenType.SHUTDOWN, TokenType.FOR, TokenType.UNSET, TokenType.CURLYOPEN, TokenType.INTEGER, TokenType.DOUBLE, TokenType.TRUEFALSE, TokenType.IDENTIFIER, TokenType.FILEIDENT, TokenType.BRACKETOPEN, TokenType.STRING, TokenType.ATSIGN); switch (tok.Type) { case TokenType.SET: @@ -225,6 +227,9 @@ private void Parseinstruction(ParseNode parent) case TokenType.UNTIL: Parseuntil_stmt(node); break; + case TokenType.FROM: + Parsefromloop_stmt(node); + break; case TokenType.UNLOCK: Parseunlock_stmt(node); break; @@ -538,6 +543,83 @@ private void Parseuntil_stmt(ParseNode parent) parent.Token.UpdateRange(node.Token); } + private void Parsefromloop_stmt(ParseNode parent) + { + Token tok; + ParseNode n; + ParseNode node = parent.CreateNode(scanner.GetToken(TokenType.fromloop_stmt), "fromloop_stmt"); + parent.Nodes.Add(node); + + + + tok = scanner.Scan(TokenType.FROM); + n = node.CreateNode(tok, tok.ToString() ); + node.Token.UpdateRange(tok); + node.Nodes.Add(n); + if (tok.Type != TokenType.FROM) { + tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.FROM.ToString(), 0x1001, tok)); + return; + } + + + Parseinstruction_block(node); + + + tok = scanner.Scan(TokenType.UNTIL); + n = node.CreateNode(tok, tok.ToString() ); + node.Token.UpdateRange(tok); + node.Nodes.Add(n); + if (tok.Type != TokenType.UNTIL) { + tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.UNTIL.ToString(), 0x1001, tok)); + return; + } + + + Parseexpr(node); + + + tok = scanner.Scan(TokenType.STEP); + n = node.CreateNode(tok, tok.ToString() ); + node.Token.UpdateRange(tok); + node.Nodes.Add(n); + if (tok.Type != TokenType.STEP) { + tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.STEP.ToString(), 0x1001, tok)); + return; + } + + + Parseinstruction_block(node); + + + tok = scanner.Scan(TokenType.DO); + n = node.CreateNode(tok, tok.ToString() ); + node.Token.UpdateRange(tok); + node.Nodes.Add(n); + if (tok.Type != TokenType.DO) { + tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.DO.ToString(), 0x1001, tok)); + return; + } + + + Parseinstruction(node); + + + tok = scanner.LookAhead(TokenType.EOI); + if (tok.Type == TokenType.EOI) + { + tok = scanner.Scan(TokenType.EOI); + n = node.CreateNode(tok, tok.ToString() ); + node.Token.UpdateRange(tok); + node.Nodes.Add(n); + if (tok.Type != TokenType.EOI) { + tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.EOI.ToString(), 0x1001, tok)); + return; + } + } + + parent.Token.UpdateRange(node.Token); + } + private void Parseunlock_stmt(ParseNode parent) { Token tok; @@ -1254,6 +1336,45 @@ private void Parsedeclare_parameter_clause(ParseNode parent) } + tok = scanner.LookAhead(TokenType.TO, TokenType.IS); + if (tok.Type == TokenType.TO + || tok.Type == TokenType.IS) + { + + + tok = scanner.LookAhead(TokenType.TO, TokenType.IS); + switch (tok.Type) + { + case TokenType.TO: + tok = scanner.Scan(TokenType.TO); + n = node.CreateNode(tok, tok.ToString() ); + node.Token.UpdateRange(tok); + node.Nodes.Add(n); + if (tok.Type != TokenType.TO) { + tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.TO.ToString(), 0x1001, tok)); + return; + } + break; + case TokenType.IS: + tok = scanner.Scan(TokenType.IS); + n = node.CreateNode(tok, tok.ToString() ); + node.Token.UpdateRange(tok); + node.Nodes.Add(n); + if (tok.Type != TokenType.IS) { + tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.IS.ToString(), 0x1001, tok)); + return; + } + break; + default: + tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found.", 0x0002, tok)); + break; + } + + + Parseexpr(node); + } + + tok = scanner.LookAhead(TokenType.COMMA); while (tok.Type == TokenType.COMMA) { @@ -1277,6 +1398,45 @@ private void Parsedeclare_parameter_clause(ParseNode parent) tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.IDENTIFIER.ToString(), 0x1001, tok)); return; } + + + tok = scanner.LookAhead(TokenType.TO, TokenType.IS); + if (tok.Type == TokenType.TO + || tok.Type == TokenType.IS) + { + + + tok = scanner.LookAhead(TokenType.TO, TokenType.IS); + switch (tok.Type) + { + case TokenType.TO: + tok = scanner.Scan(TokenType.TO); + n = node.CreateNode(tok, tok.ToString() ); + node.Token.UpdateRange(tok); + node.Nodes.Add(n); + if (tok.Type != TokenType.TO) { + tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.TO.ToString(), 0x1001, tok)); + return; + } + break; + case TokenType.IS: + tok = scanner.Scan(TokenType.IS); + n = node.CreateNode(tok, tok.ToString() ); + node.Token.UpdateRange(tok); + node.Nodes.Add(n); + if (tok.Type != TokenType.IS) { + tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.IS.ToString(), 0x1001, tok)); + return; + } + break; + default: + tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found.", 0x0002, tok)); + break; + } + + + Parseexpr(node); + } tok = scanner.LookAhead(TokenType.COMMA); } @@ -1551,9 +1711,10 @@ private void Parsereturn_stmt(ParseNode parent) } - tok = scanner.LookAhead(TokenType.PLUSMINUS, TokenType.NOT, TokenType.INTEGER, TokenType.DOUBLE, TokenType.TRUEFALSE, TokenType.IDENTIFIER, TokenType.FILEIDENT, TokenType.BRACKETOPEN, TokenType.STRING); + tok = scanner.LookAhead(TokenType.PLUSMINUS, TokenType.NOT, TokenType.DEFINED, TokenType.INTEGER, TokenType.DOUBLE, TokenType.TRUEFALSE, TokenType.IDENTIFIER, TokenType.FILEIDENT, TokenType.BRACKETOPEN, TokenType.STRING); if (tok.Type == TokenType.PLUSMINUS || tok.Type == TokenType.NOT + || tok.Type == TokenType.DEFINED || tok.Type == TokenType.INTEGER || tok.Type == TokenType.DOUBLE || tok.Type == TokenType.TRUEFALSE @@ -1875,6 +2036,20 @@ private void Parserun_stmt(ParseNode parent) } + tok = scanner.LookAhead(TokenType.ONCE); + if (tok.Type == TokenType.ONCE) + { + tok = scanner.Scan(TokenType.ONCE); + n = node.CreateNode(tok, tok.ToString() ); + node.Token.UpdateRange(tok); + node.Nodes.Add(n); + if (tok.Type != TokenType.ONCE) { + tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.ONCE.ToString(), 0x1001, tok)); + return; + } + } + + tok = scanner.Scan(TokenType.FILEIDENT); n = node.CreateNode(tok, tok.ToString() ); node.Token.UpdateRange(tok); @@ -2487,11 +2662,12 @@ private void Parseunary_expr(ParseNode parent) - tok = scanner.LookAhead(TokenType.PLUSMINUS, TokenType.NOT); + tok = scanner.LookAhead(TokenType.PLUSMINUS, TokenType.NOT, TokenType.DEFINED); if (tok.Type == TokenType.PLUSMINUS - || tok.Type == TokenType.NOT) + || tok.Type == TokenType.NOT + || tok.Type == TokenType.DEFINED) { - tok = scanner.LookAhead(TokenType.PLUSMINUS, TokenType.NOT); + tok = scanner.LookAhead(TokenType.PLUSMINUS, TokenType.NOT, TokenType.DEFINED); switch (tok.Type) { case TokenType.PLUSMINUS: @@ -2514,6 +2690,16 @@ private void Parseunary_expr(ParseNode parent) return; } break; + case TokenType.DEFINED: + tok = scanner.Scan(TokenType.DEFINED); + n = node.CreateNode(tok, tok.ToString() ); + node.Token.UpdateRange(tok); + node.Nodes.Add(n); + if (tok.Type != TokenType.DEFINED) { + tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.DEFINED.ToString(), 0x1001, tok)); + return; + } + break; default: tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found.", 0x0002, tok)); break; @@ -2618,13 +2804,14 @@ private void Parsesuffixterm(ParseNode parent) Parseatom(node); - tok = scanner.LookAhead(TokenType.BRACKETOPEN, TokenType.ARRAYINDEX, TokenType.SQUAREOPEN); + tok = scanner.LookAhead(TokenType.BRACKETOPEN, TokenType.ATSIGN, TokenType.ARRAYINDEX, TokenType.SQUAREOPEN); while (tok.Type == TokenType.BRACKETOPEN + || tok.Type == TokenType.ATSIGN || tok.Type == TokenType.ARRAYINDEX || tok.Type == TokenType.SQUAREOPEN) { Parsesuffixterm_trailer(node); - tok = scanner.LookAhead(TokenType.BRACKETOPEN, TokenType.ARRAYINDEX, TokenType.SQUAREOPEN); + tok = scanner.LookAhead(TokenType.BRACKETOPEN, TokenType.ATSIGN, TokenType.ARRAYINDEX, TokenType.SQUAREOPEN); } parent.Token.UpdateRange(node.Token); @@ -2637,10 +2824,11 @@ private void Parsesuffixterm_trailer(ParseNode parent) ParseNode node = parent.CreateNode(scanner.GetToken(TokenType.suffixterm_trailer), "suffixterm_trailer"); parent.Nodes.Add(node); - tok = scanner.LookAhead(TokenType.BRACKETOPEN, TokenType.ARRAYINDEX, TokenType.SQUAREOPEN); + tok = scanner.LookAhead(TokenType.BRACKETOPEN, TokenType.ATSIGN, TokenType.ARRAYINDEX, TokenType.SQUAREOPEN); switch (tok.Type) { case TokenType.BRACKETOPEN: + case TokenType.ATSIGN: Parsefunction_trailer(node); break; case TokenType.ARRAYINDEX: @@ -2662,40 +2850,60 @@ private void Parsefunction_trailer(ParseNode parent) ParseNode node = parent.CreateNode(scanner.GetToken(TokenType.function_trailer), "function_trailer"); parent.Nodes.Add(node); + tok = scanner.LookAhead(TokenType.BRACKETOPEN, TokenType.ATSIGN); + switch (tok.Type) + { + case TokenType.BRACKETOPEN: - - tok = scanner.Scan(TokenType.BRACKETOPEN); - n = node.CreateNode(tok, tok.ToString() ); - node.Token.UpdateRange(tok); - node.Nodes.Add(n); - if (tok.Type != TokenType.BRACKETOPEN) { - tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.BRACKETOPEN.ToString(), 0x1001, tok)); - return; - } + + tok = scanner.Scan(TokenType.BRACKETOPEN); + n = node.CreateNode(tok, tok.ToString() ); + node.Token.UpdateRange(tok); + node.Nodes.Add(n); + if (tok.Type != TokenType.BRACKETOPEN) { + tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.BRACKETOPEN.ToString(), 0x1001, tok)); + return; + } - - tok = scanner.LookAhead(TokenType.PLUSMINUS, TokenType.NOT, TokenType.INTEGER, TokenType.DOUBLE, TokenType.TRUEFALSE, TokenType.IDENTIFIER, TokenType.FILEIDENT, TokenType.BRACKETOPEN, TokenType.STRING); - if (tok.Type == TokenType.PLUSMINUS - || tok.Type == TokenType.NOT - || tok.Type == TokenType.INTEGER - || tok.Type == TokenType.DOUBLE - || tok.Type == TokenType.TRUEFALSE - || tok.Type == TokenType.IDENTIFIER - || tok.Type == TokenType.FILEIDENT - || tok.Type == TokenType.BRACKETOPEN - || tok.Type == TokenType.STRING) - { - Parsearglist(node); - } + + tok = scanner.LookAhead(TokenType.PLUSMINUS, TokenType.NOT, TokenType.DEFINED, TokenType.INTEGER, TokenType.DOUBLE, TokenType.TRUEFALSE, TokenType.IDENTIFIER, TokenType.FILEIDENT, TokenType.BRACKETOPEN, TokenType.STRING); + if (tok.Type == TokenType.PLUSMINUS + || tok.Type == TokenType.NOT + || tok.Type == TokenType.DEFINED + || tok.Type == TokenType.INTEGER + || tok.Type == TokenType.DOUBLE + || tok.Type == TokenType.TRUEFALSE + || tok.Type == TokenType.IDENTIFIER + || tok.Type == TokenType.FILEIDENT + || tok.Type == TokenType.BRACKETOPEN + || tok.Type == TokenType.STRING) + { + Parsearglist(node); + } - - tok = scanner.Scan(TokenType.BRACKETCLOSE); - n = node.CreateNode(tok, tok.ToString() ); - node.Token.UpdateRange(tok); - node.Nodes.Add(n); - if (tok.Type != TokenType.BRACKETCLOSE) { - tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.BRACKETCLOSE.ToString(), 0x1001, tok)); - return; + + tok = scanner.Scan(TokenType.BRACKETCLOSE); + n = node.CreateNode(tok, tok.ToString() ); + node.Token.UpdateRange(tok); + node.Nodes.Add(n); + if (tok.Type != TokenType.BRACKETCLOSE) { + tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.BRACKETCLOSE.ToString(), 0x1001, tok)); + return; + } + break; + case TokenType.ATSIGN: + tok = scanner.Scan(TokenType.ATSIGN); + n = node.CreateNode(tok, tok.ToString() ); + node.Token.UpdateRange(tok); + node.Nodes.Add(n); + if (tok.Type != TokenType.ATSIGN) { + tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.ATSIGN.ToString(), 0x1001, tok)); + return; + } + break; + default: + tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found.", 0x0002, tok)); + break; } parent.Token.UpdateRange(node.Token); diff --git a/src/kOS.Safe/Compilation/KS/Scanner.cs b/src/kOS.Safe/Compilation/KS/Scanner.cs index 5f8204488..00816030a 100644 --- a/src/kOS.Safe/Compilation/KS/Scanner.cs +++ b/src/kOS.Safe/Compilation/KS/Scanner.cs @@ -54,23 +54,23 @@ public Scanner() Patterns.Add(TokenType.POWER, regex); Tokens.Add(TokenType.POWER); - regex = new Regex(@"\be\b"); + regex = new Regex(@"(?i)\be\b"); Patterns.Add(TokenType.E, regex); Tokens.Add(TokenType.E); - regex = new Regex(@"\bnot\b"); + regex = new Regex(@"(?i)\bnot\b"); Patterns.Add(TokenType.NOT, regex); Tokens.Add(TokenType.NOT); - regex = new Regex(@"\band\b"); + regex = new Regex(@"(?i)\band\b"); Patterns.Add(TokenType.AND, regex); Tokens.Add(TokenType.AND); - regex = new Regex(@"\bor\b"); + regex = new Regex(@"(?i)\bor\b"); Patterns.Add(TokenType.OR, regex); Tokens.Add(TokenType.OR); - regex = new Regex(@"\btrue\b|\bfalse\b"); + regex = new Regex(@"(?i)\btrue\b|\bfalse\b"); Patterns.Add(TokenType.TRUEFALSE, regex); Tokens.Add(TokenType.TRUEFALSE); @@ -78,179 +78,195 @@ public Scanner() Patterns.Add(TokenType.COMPARATOR, regex); Tokens.Add(TokenType.COMPARATOR); - regex = new Regex(@"\bset\b"); + regex = new Regex(@"(?i)\bset\b"); Patterns.Add(TokenType.SET, regex); Tokens.Add(TokenType.SET); - regex = new Regex(@"\bto\b"); + regex = new Regex(@"(?i)\bto\b"); Patterns.Add(TokenType.TO, regex); Tokens.Add(TokenType.TO); - regex = new Regex(@"\bis\b"); + regex = new Regex(@"(?i)\bis\b"); Patterns.Add(TokenType.IS, regex); Tokens.Add(TokenType.IS); - regex = new Regex(@"\bif\b"); + regex = new Regex(@"(?i)\bif\b"); Patterns.Add(TokenType.IF, regex); Tokens.Add(TokenType.IF); - regex = new Regex(@"\belse\b"); + regex = new Regex(@"(?i)\belse\b"); Patterns.Add(TokenType.ELSE, regex); Tokens.Add(TokenType.ELSE); - regex = new Regex(@"\buntil\b"); + regex = new Regex(@"(?i)\buntil\b"); Patterns.Add(TokenType.UNTIL, regex); Tokens.Add(TokenType.UNTIL); - regex = new Regex(@"\block\b"); + regex = new Regex(@"(?i)\bstep\b"); + Patterns.Add(TokenType.STEP, regex); + Tokens.Add(TokenType.STEP); + + regex = new Regex(@"(?i)\bdo\b"); + Patterns.Add(TokenType.DO, regex); + Tokens.Add(TokenType.DO); + + regex = new Regex(@"(?i)\block\b"); Patterns.Add(TokenType.LOCK, regex); Tokens.Add(TokenType.LOCK); - regex = new Regex(@"\bunlock\b"); + regex = new Regex(@"(?i)\bunlock\b"); Patterns.Add(TokenType.UNLOCK, regex); Tokens.Add(TokenType.UNLOCK); - regex = new Regex(@"\bprint\b"); + regex = new Regex(@"(?i)\bprint\b"); Patterns.Add(TokenType.PRINT, regex); Tokens.Add(TokenType.PRINT); - regex = new Regex(@"\bat\b"); + regex = new Regex(@"(?i)\bat\b"); Patterns.Add(TokenType.AT, regex); Tokens.Add(TokenType.AT); - regex = new Regex(@"\bon\b"); + regex = new Regex(@"(?i)\bon\b"); Patterns.Add(TokenType.ON, regex); Tokens.Add(TokenType.ON); - regex = new Regex(@"\btoggle\b"); + regex = new Regex(@"(?i)\btoggle\b"); Patterns.Add(TokenType.TOGGLE, regex); Tokens.Add(TokenType.TOGGLE); - regex = new Regex(@"\bwait\b"); + regex = new Regex(@"(?i)\bwait\b"); Patterns.Add(TokenType.WAIT, regex); Tokens.Add(TokenType.WAIT); - regex = new Regex(@"\bwhen\b"); + regex = new Regex(@"(?i)\bwhen\b"); Patterns.Add(TokenType.WHEN, regex); Tokens.Add(TokenType.WHEN); - regex = new Regex(@"\bthen\b"); + regex = new Regex(@"(?i)\bthen\b"); Patterns.Add(TokenType.THEN, regex); Tokens.Add(TokenType.THEN); - regex = new Regex(@"\boff\b"); + regex = new Regex(@"(?i)\boff\b"); Patterns.Add(TokenType.OFF, regex); Tokens.Add(TokenType.OFF); - regex = new Regex(@"\bstage\b"); + regex = new Regex(@"(?i)\bstage\b"); Patterns.Add(TokenType.STAGE, regex); Tokens.Add(TokenType.STAGE); - regex = new Regex(@"\bclearscreen\b"); + regex = new Regex(@"(?i)\bclearscreen\b"); Patterns.Add(TokenType.CLEARSCREEN, regex); Tokens.Add(TokenType.CLEARSCREEN); - regex = new Regex(@"\badd\b"); + regex = new Regex(@"(?i)\badd\b"); Patterns.Add(TokenType.ADD, regex); Tokens.Add(TokenType.ADD); - regex = new Regex(@"\bremove\b"); + regex = new Regex(@"(?i)\bremove\b"); Patterns.Add(TokenType.REMOVE, regex); Tokens.Add(TokenType.REMOVE); - regex = new Regex(@"\blog\b"); + regex = new Regex(@"(?i)\blog\b"); Patterns.Add(TokenType.LOG, regex); Tokens.Add(TokenType.LOG); - regex = new Regex(@"\bbreak\b"); + regex = new Regex(@"(?i)\bbreak\b"); Patterns.Add(TokenType.BREAK, regex); Tokens.Add(TokenType.BREAK); - regex = new Regex(@"\bpreserve\b"); + regex = new Regex(@"(?i)\bpreserve\b"); Patterns.Add(TokenType.PRESERVE, regex); Tokens.Add(TokenType.PRESERVE); - regex = new Regex(@"\bdeclare\b"); + regex = new Regex(@"(?i)\bdeclare\b"); Patterns.Add(TokenType.DECLARE, regex); Tokens.Add(TokenType.DECLARE); - regex = new Regex(@"\blocal\b"); + regex = new Regex(@"(?i)\bdefined\b"); + Patterns.Add(TokenType.DEFINED, regex); + Tokens.Add(TokenType.DEFINED); + + regex = new Regex(@"(?i)\blocal\b"); Patterns.Add(TokenType.LOCAL, regex); Tokens.Add(TokenType.LOCAL); - regex = new Regex(@"\bglobal\b"); + regex = new Regex(@"(?i)\bglobal\b"); Patterns.Add(TokenType.GLOBAL, regex); Tokens.Add(TokenType.GLOBAL); - regex = new Regex(@"\bparameter\b"); + regex = new Regex(@"(?i)\bparameter\b"); Patterns.Add(TokenType.PARAMETER, regex); Tokens.Add(TokenType.PARAMETER); - regex = new Regex(@"\bfunction\b"); + regex = new Regex(@"(?i)\bfunction\b"); Patterns.Add(TokenType.FUNCTION, regex); Tokens.Add(TokenType.FUNCTION); - regex = new Regex(@"\breturn\b"); + regex = new Regex(@"(?i)\breturn\b"); Patterns.Add(TokenType.RETURN, regex); Tokens.Add(TokenType.RETURN); - regex = new Regex(@"\bswitch\b"); + regex = new Regex(@"(?i)\bswitch\b"); Patterns.Add(TokenType.SWITCH, regex); Tokens.Add(TokenType.SWITCH); - regex = new Regex(@"\bcopy\b"); + regex = new Regex(@"(?i)\bcopy\b"); Patterns.Add(TokenType.COPY, regex); Tokens.Add(TokenType.COPY); - regex = new Regex(@"\bfrom\b"); + regex = new Regex(@"(?i)\bfrom\b"); Patterns.Add(TokenType.FROM, regex); Tokens.Add(TokenType.FROM); - regex = new Regex(@"\brename\b"); + regex = new Regex(@"(?i)\brename\b"); Patterns.Add(TokenType.RENAME, regex); Tokens.Add(TokenType.RENAME); - regex = new Regex(@"\bvolume\b"); + regex = new Regex(@"(?i)\bvolume\b"); Patterns.Add(TokenType.VOLUME, regex); Tokens.Add(TokenType.VOLUME); - regex = new Regex(@"\bfile\b"); + regex = new Regex(@"(?i)\bfile\b"); Patterns.Add(TokenType.FILE, regex); Tokens.Add(TokenType.FILE); - regex = new Regex(@"\bdelete\b"); + regex = new Regex(@"(?i)\bdelete\b"); Patterns.Add(TokenType.DELETE, regex); Tokens.Add(TokenType.DELETE); - regex = new Regex(@"\bedit\b"); + regex = new Regex(@"(?i)\bedit\b"); Patterns.Add(TokenType.EDIT, regex); Tokens.Add(TokenType.EDIT); - regex = new Regex(@"\brun\b"); + regex = new Regex(@"(?i)\brun\b"); Patterns.Add(TokenType.RUN, regex); Tokens.Add(TokenType.RUN); - regex = new Regex(@"\bcompile\b"); + regex = new Regex(@"(?i)\bonce\b"); + Patterns.Add(TokenType.ONCE, regex); + Tokens.Add(TokenType.ONCE); + + regex = new Regex(@"(?i)\bcompile\b"); Patterns.Add(TokenType.COMPILE, regex); Tokens.Add(TokenType.COMPILE); - regex = new Regex(@"\blist\b"); + regex = new Regex(@"(?i)\blist\b"); Patterns.Add(TokenType.LIST, regex); Tokens.Add(TokenType.LIST); - regex = new Regex(@"\breboot\b"); + regex = new Regex(@"(?i)\breboot\b"); Patterns.Add(TokenType.REBOOT, regex); Tokens.Add(TokenType.REBOOT); - regex = new Regex(@"\bshutdown\b"); + regex = new Regex(@"(?i)\bshutdown\b"); Patterns.Add(TokenType.SHUTDOWN, regex); Tokens.Add(TokenType.SHUTDOWN); - regex = new Regex(@"\bfor\b"); + regex = new Regex(@"(?i)\bfor\b"); Patterns.Add(TokenType.FOR, regex); Tokens.Add(TokenType.FOR); - regex = new Regex(@"\bunset\b"); + regex = new Regex(@"(?i)\bunset\b"); Patterns.Add(TokenType.UNSET, regex); Tokens.Add(TokenType.UNSET); @@ -286,7 +302,7 @@ public Scanner() Patterns.Add(TokenType.COLON, regex); Tokens.Add(TokenType.COLON); - regex = new Regex(@"\bin\b"); + regex = new Regex(@"(?i)\bin\b"); Patterns.Add(TokenType.IN, regex); Tokens.Add(TokenType.IN); @@ -294,15 +310,15 @@ public Scanner() Patterns.Add(TokenType.ARRAYINDEX, regex); Tokens.Add(TokenType.ARRAYINDEX); - regex = new Regex(@"\ball\b"); + regex = new Regex(@"(?i)\ball\b"); Patterns.Add(TokenType.ALL, regex); Tokens.Add(TokenType.ALL); - regex = new Regex(@"[a-z_][a-z0-9_]*"); + regex = new Regex(@"(?i)[a-z_][a-z0-9_]*"); Patterns.Add(TokenType.IDENTIFIER, regex); Tokens.Add(TokenType.IDENTIFIER); - regex = new Regex(@"[a-z_][a-z0-9_]*(\.[a-z0-9_][a-z0-9_]*)*"); + regex = new Regex(@"(?i)[a-z_][a-z0-9_]*(\.[a-z0-9_][a-z0-9_]*)*"); Patterns.Add(TokenType.FILEIDENT, regex); Tokens.Add(TokenType.FILEIDENT); @@ -326,7 +342,7 @@ public Scanner() Patterns.Add(TokenType.ATSIGN, regex); Tokens.Add(TokenType.ATSIGN); - regex = new Regex(@"\blazyglobal\b"); + regex = new Regex(@"(?i)\blazyglobal\b"); Patterns.Add(TokenType.LAZYGLOBAL, regex); Tokens.Add(TokenType.LAZYGLOBAL); @@ -510,137 +526,142 @@ public enum TokenType set_stmt= 7, if_stmt = 8, until_stmt= 9, - unlock_stmt= 10, - print_stmt= 11, - on_stmt = 12, - toggle_stmt= 13, - wait_stmt= 14, - when_stmt= 15, - onoff_stmt= 16, - onoff_trailer= 17, - stage_stmt= 18, - clear_stmt= 19, - add_stmt= 20, - remove_stmt= 21, - log_stmt= 22, - break_stmt= 23, - preserve_stmt= 24, - declare_identifier_clause= 25, - declare_parameter_clause= 26, - declare_function_clause= 27, - declare_lock_clause= 28, - declare_stmt= 29, - return_stmt= 30, - switch_stmt= 31, - copy_stmt= 32, - rename_stmt= 33, - delete_stmt= 34, - edit_stmt= 35, - run_stmt= 36, - compile_stmt= 37, - list_stmt= 38, - reboot_stmt= 39, - shutdown_stmt= 40, - for_stmt= 41, - unset_stmt= 42, - arglist = 43, - expr = 44, - and_expr= 45, - compare_expr= 46, - arith_expr= 47, - multdiv_expr= 48, - unary_expr= 49, - factor = 50, - suffix = 51, - suffix_trailer= 52, - suffixterm= 53, - suffixterm_trailer= 54, - function_trailer= 55, - array_trailer= 56, - atom = 57, - sci_number= 58, - number = 59, - varidentifier= 60, - identifier_led_stmt= 61, - identifier_led_expr= 62, + fromloop_stmt= 10, + unlock_stmt= 11, + print_stmt= 12, + on_stmt = 13, + toggle_stmt= 14, + wait_stmt= 15, + when_stmt= 16, + onoff_stmt= 17, + onoff_trailer= 18, + stage_stmt= 19, + clear_stmt= 20, + add_stmt= 21, + remove_stmt= 22, + log_stmt= 23, + break_stmt= 24, + preserve_stmt= 25, + declare_identifier_clause= 26, + declare_parameter_clause= 27, + declare_function_clause= 28, + declare_lock_clause= 29, + declare_stmt= 30, + return_stmt= 31, + switch_stmt= 32, + copy_stmt= 33, + rename_stmt= 34, + delete_stmt= 35, + edit_stmt= 36, + run_stmt= 37, + compile_stmt= 38, + list_stmt= 39, + reboot_stmt= 40, + shutdown_stmt= 41, + for_stmt= 42, + unset_stmt= 43, + arglist = 44, + expr = 45, + and_expr= 46, + compare_expr= 47, + arith_expr= 48, + multdiv_expr= 49, + unary_expr= 50, + factor = 51, + suffix = 52, + suffix_trailer= 53, + suffixterm= 54, + suffixterm_trailer= 55, + function_trailer= 56, + array_trailer= 57, + atom = 58, + sci_number= 59, + number = 60, + varidentifier= 61, + identifier_led_stmt= 62, + identifier_led_expr= 63, //Terminal tokens: - PLUSMINUS= 63, - MULT = 64, - DIV = 65, - POWER = 66, - E = 67, - NOT = 68, - AND = 69, - OR = 70, - TRUEFALSE= 71, - COMPARATOR= 72, - SET = 73, - TO = 74, - IS = 75, - IF = 76, - ELSE = 77, - UNTIL = 78, - LOCK = 79, - UNLOCK = 80, - PRINT = 81, - AT = 82, - ON = 83, - TOGGLE = 84, - WAIT = 85, - WHEN = 86, - THEN = 87, - OFF = 88, - STAGE = 89, - CLEARSCREEN= 90, - ADD = 91, - REMOVE = 92, - LOG = 93, - BREAK = 94, - PRESERVE= 95, - DECLARE = 96, - LOCAL = 97, - GLOBAL = 98, - PARAMETER= 99, - FUNCTION= 100, - RETURN = 101, - SWITCH = 102, - COPY = 103, - FROM = 104, - RENAME = 105, - VOLUME = 106, - FILE = 107, - DELETE = 108, - EDIT = 109, - RUN = 110, - COMPILE = 111, - LIST = 112, - REBOOT = 113, - SHUTDOWN= 114, - FOR = 115, - UNSET = 116, - BRACKETOPEN= 117, - BRACKETCLOSE= 118, - CURLYOPEN= 119, - CURLYCLOSE= 120, - SQUAREOPEN= 121, - SQUARECLOSE= 122, - COMMA = 123, - COLON = 124, - IN = 125, - ARRAYINDEX= 126, - ALL = 127, - IDENTIFIER= 128, - FILEIDENT= 129, - INTEGER = 130, - DOUBLE = 131, - STRING = 132, - EOI = 133, - ATSIGN = 134, - LAZYGLOBAL= 135, - EOF = 136, - WHITESPACE= 137, - COMMENTLINE= 138 + PLUSMINUS= 64, + MULT = 65, + DIV = 66, + POWER = 67, + E = 68, + NOT = 69, + AND = 70, + OR = 71, + TRUEFALSE= 72, + COMPARATOR= 73, + SET = 74, + TO = 75, + IS = 76, + IF = 77, + ELSE = 78, + UNTIL = 79, + STEP = 80, + DO = 81, + LOCK = 82, + UNLOCK = 83, + PRINT = 84, + AT = 85, + ON = 86, + TOGGLE = 87, + WAIT = 88, + WHEN = 89, + THEN = 90, + OFF = 91, + STAGE = 92, + CLEARSCREEN= 93, + ADD = 94, + REMOVE = 95, + LOG = 96, + BREAK = 97, + PRESERVE= 98, + DECLARE = 99, + DEFINED = 100, + LOCAL = 101, + GLOBAL = 102, + PARAMETER= 103, + FUNCTION= 104, + RETURN = 105, + SWITCH = 106, + COPY = 107, + FROM = 108, + RENAME = 109, + VOLUME = 110, + FILE = 111, + DELETE = 112, + EDIT = 113, + RUN = 114, + ONCE = 115, + COMPILE = 116, + LIST = 117, + REBOOT = 118, + SHUTDOWN= 119, + FOR = 120, + UNSET = 121, + BRACKETOPEN= 122, + BRACKETCLOSE= 123, + CURLYOPEN= 124, + CURLYCLOSE= 125, + SQUAREOPEN= 126, + SQUARECLOSE= 127, + COMMA = 128, + COLON = 129, + IN = 130, + ARRAYINDEX= 131, + ALL = 132, + IDENTIFIER= 133, + FILEIDENT= 134, + INTEGER = 135, + DOUBLE = 136, + STRING = 137, + EOI = 138, + ATSIGN = 139, + LAZYGLOBAL= 140, + EOF = 141, + WHITESPACE= 142, + COMMENTLINE= 143 } public class Token diff --git a/src/kOS.Safe/Compilation/KS/kRISC.tpg b/src/kOS.Safe/Compilation/KS/kRISC.tpg index e7d6dcb7f..ecf7007e7 100644 --- a/src/kOS.Safe/Compilation/KS/kRISC.tpg +++ b/src/kOS.Safe/Compilation/KS/kRISC.tpg @@ -7,58 +7,63 @@ PLUSMINUS -> @"(\+|-)"; MULT -> @"\*"; DIV -> @"/"; POWER -> @"\^"; -E -> @"\be\b"; +E -> @"(?i)\be\b"; //Logic -NOT -> @"\bnot\b"; -AND -> @"\band\b"; -OR -> @"\bor\b"; -TRUEFALSE -> @"\btrue\b|\bfalse\b"; +NOT -> @"(?i)\bnot\b"; +AND -> @"(?i)\band\b"; +OR -> @"(?i)\bor\b"; +TRUEFALSE -> @"(?i)\btrue\b|\bfalse\b"; COMPARATOR -> @"<>|>=|<=|=|>|<"; //Instructions tokens -SET -> @"\bset\b"; -TO -> @"\bto\b"; -IS -> @"\bis\b"; -IF -> @"\bif\b"; -ELSE -> @"\belse\b"; -UNTIL -> @"\buntil\b"; -LOCK -> @"\block\b"; -UNLOCK -> @"\bunlock\b"; -PRINT -> @"\bprint\b"; -AT -> @"\bat\b"; -ON -> @"\bon\b"; -TOGGLE -> @"\btoggle\b"; -WAIT -> @"\bwait\b"; -WHEN -> @"\bwhen\b"; -THEN -> @"\bthen\b"; -OFF -> @"\boff\b"; -STAGE -> @"\bstage\b"; -CLEARSCREEN -> @"\bclearscreen\b"; -ADD -> @"\badd\b"; -REMOVE -> @"\bremove\b"; -LOG -> @"\blog\b"; -BREAK -> @"\bbreak\b"; -PRESERVE -> @"\bpreserve\b"; -DECLARE -> @"\bdeclare\b"; -LOCAL -> @"\blocal\b"; -GLOBAL -> @"\bglobal\b"; -PARAMETER -> @"\bparameter\b"; -FUNCTION -> @"\bfunction\b"; -RETURN -> @"\breturn\b"; -SWITCH -> @"\bswitch\b"; -COPY -> @"\bcopy\b"; -FROM -> @"\bfrom\b"; -RENAME -> @"\brename\b"; -VOLUME -> @"\bvolume\b"; -FILE -> @"\bfile\b"; -DELETE -> @"\bdelete\b"; -EDIT -> @"\bedit\b"; -RUN -> @"\brun\b"; -COMPILE -> @"\bcompile\b"; -LIST -> @"\blist\b"; -REBOOT -> @"\breboot\b"; -SHUTDOWN -> @"\bshutdown\b"; -FOR -> @"\bfor\b"; -UNSET -> @"\bunset\b"; +SET -> @"(?i)\bset\b"; +TO -> @"(?i)\bto\b"; +IS -> @"(?i)\bis\b"; +IF -> @"(?i)\bif\b"; +ELSE -> @"(?i)\belse\b"; +UNTIL -> @"(?i)\buntil\b"; +STEP -> @"(?i)\bstep\b"; +DO -> @"(?i)\bdo\b"; +LOCK -> @"(?i)\block\b"; +UNLOCK -> @"(?i)\bunlock\b"; +PRINT -> @"(?i)\bprint\b"; +AT -> @"(?i)\bat\b"; +ON -> @"(?i)\bon\b"; +TOGGLE -> @"(?i)\btoggle\b"; +WAIT -> @"(?i)\bwait\b"; +WHEN -> @"(?i)\bwhen\b"; +THEN -> @"(?i)\bthen\b"; +OFF -> @"(?i)\boff\b"; +STAGE -> @"(?i)\bstage\b"; +CLEARSCREEN -> @"(?i)\bclearscreen\b"; +ADD -> @"(?i)\badd\b"; +REMOVE -> @"(?i)\bremove\b"; +LOG -> @"(?i)\blog\b"; +BREAK -> @"(?i)\bbreak\b"; +PRESERVE -> @"(?i)\bpreserve\b"; +DECLARE -> @"(?i)\bdeclare\b"; +DEFINED -> @"(?i)\bdefined\b"; +LOCAL -> @"(?i)\blocal\b"; +GLOBAL -> @"(?i)\bglobal\b"; +PARAMETER -> @"(?i)\bparameter\b"; +FUNCTION -> @"(?i)\bfunction\b"; +RETURN -> @"(?i)\breturn\b"; +SWITCH -> @"(?i)\bswitch\b"; +COPY -> @"(?i)\bcopy\b"; +FROM -> @"(?i)\bfrom\b"; +RENAME -> @"(?i)\brename\b"; +VOLUME -> @"(?i)\bvolume\b"; +FILE -> @"(?i)\bfile\b"; +DELETE -> @"(?i)\bdelete\b"; +EDIT -> @"(?i)\bedit\b"; +RUN -> @"(?i)\brun\b"; +ONCE -> @"(?i)\bonce\b"; +COMPILE -> @"(?i)\bcompile\b"; +LIST -> @"(?i)\blist\b"; +REBOOT -> @"(?i)\breboot\b"; +SHUTDOWN -> @"(?i)\bshutdown\b"; +FOR -> @"(?i)\bfor\b"; +UNSET -> @"(?i)\bunset\b"; + //Generic BRACKETOPEN -> @"\("; BRACKETCLOSE -> @"\)"; @@ -68,18 +73,18 @@ SQUAREOPEN -> @"\["; SQUARECLOSE -> @"\]"; COMMA -> @","; COLON -> @":"; -IN -> @"\bin\b"; +IN -> @"(?i)\bin\b"; ARRAYINDEX -> @"#"; -ALL -> @"\ball\b"; -IDENTIFIER -> @"[a-z_][a-z0-9_]*"; -FILEIDENT -> @"[a-z_][a-z0-9_]*(\.[a-z0-9_][a-z0-9_]*)*"; +ALL -> @"(?i)\ball\b"; +IDENTIFIER -> @"(?i)[a-z_][a-z0-9_]*"; +FILEIDENT -> @"(?i)[a-z_][a-z0-9_]*(\.[a-z0-9_][a-z0-9_]*)*"; INTEGER -> @"[0-9]+"; DOUBLE -> @"[0-9]*\.[0-9]+"; STRING -> @"@?\""(\""\""|[^\""])*\"""; EOI -> @"\."; //Compiler Directives ATSIGN -> @"@"; -LAZYGLOBAL -> @"\blazyglobal\b"; +LAZYGLOBAL -> @"(?i)\blazyglobal\b"; //Special EOF -> @"^$"; [Skip] @@ -94,6 +99,7 @@ instruction_block -> CURLYOPEN instruction* CURLYCLOSE EOI?; instruction -> set_stmt | if_stmt | until_stmt | + fromloop_stmt | unlock_stmt | print_stmt | on_stmt | @@ -134,6 +140,7 @@ directive -> lazyglobal_directive; // Add to this list later if we ma set_stmt -> SET varidentifier TO expr EOI; if_stmt -> IF expr instruction (ELSE instruction)? EOI?; until_stmt -> UNTIL expr instruction EOI?; +fromloop_stmt -> FROM instruction_block UNTIL expr STEP instruction_block DO instruction EOI?; unlock_stmt -> UNLOCK (IDENTIFIER | ALL) EOI; print_stmt -> PRINT expr (AT BRACKETOPEN expr COMMA expr BRACKETCLOSE)? EOI; on_stmt -> ON varidentifier instruction EOI?; @@ -150,7 +157,7 @@ log_stmt -> LOG expr TO expr EOI; break_stmt -> BREAK EOI; preserve_stmt -> PRESERVE EOI; declare_identifier_clause -> IDENTIFIER (TO|IS) expr EOI; -declare_parameter_clause -> PARAMETER IDENTIFIER (COMMA IDENTIFIER)* EOI; +declare_parameter_clause -> PARAMETER IDENTIFIER ((TO|IS) expr)? (COMMA IDENTIFIER ((TO|IS) expr)?)* EOI; declare_function_clause -> FUNCTION IDENTIFIER instruction_block EOI?; declare_lock_clause -> LOCK IDENTIFIER TO expr EOI; declare_stmt -> // declare|global|local are all optional for function and parameter, @@ -180,7 +187,7 @@ copy_stmt -> COPY expr (FROM | TO) expr EOI; rename_stmt -> RENAME (VOLUME | FILE)? expr TO expr EOI; delete_stmt -> DELETE expr (FROM expr)? EOI; edit_stmt -> EDIT expr EOI; -run_stmt -> RUN FILEIDENT (BRACKETOPEN arglist BRACKETCLOSE)? (ON expr)? EOI; +run_stmt -> RUN (ONCE)? FILEIDENT (BRACKETOPEN arglist BRACKETCLOSE)? (ON expr)? EOI; compile_stmt -> COMPILE expr (TO expr)? EOI; list_stmt -> LIST (IDENTIFIER (IN IDENTIFIER)?)? EOI; reboot_stmt -> REBOOT EOI; @@ -197,7 +204,7 @@ and_expr -> compare_expr (AND compare_expr)*; compare_expr -> arith_expr (COMPARATOR arith_expr)*; arith_expr -> multdiv_expr (PLUSMINUS multdiv_expr)*; multdiv_expr -> unary_expr ((MULT|DIV) unary_expr)*; -unary_expr -> (PLUSMINUS|NOT)? factor; +unary_expr -> (PLUSMINUS|NOT|DEFINED)? factor; factor -> suffix (POWER suffix)*; suffix -> suffixterm (suffix_trailer)*; suffix_trailer -> (COLON suffixterm); @@ -205,7 +212,7 @@ suffix_trailer -> (COLON suffixterm); suffixterm -> atom suffixterm_trailer*; suffixterm_trailer -> (function_trailer | array_trailer); -function_trailer -> (BRACKETOPEN arglist? BRACKETCLOSE); +function_trailer -> (BRACKETOPEN arglist? BRACKETCLOSE) | ATSIGN; array_trailer -> ( (ARRAYINDEX (IDENTIFIER | INTEGER)) | (SQUAREOPEN expr SQUARECLOSE) ); atom -> ( sci_number | diff --git a/src/kOS.Safe/Compilation/Opcode.cs b/src/kOS.Safe/Compilation/Opcode.cs index 31db676c9..c6143cacb 100644 --- a/src/kOS.Safe/Compilation/Opcode.cs +++ b/src/kOS.Safe/Compilation/Opcode.cs @@ -3,9 +3,11 @@ using System.Linq; using System.Collections.Generic; using kOS.Safe.Encapsulation; +using kOS.Safe.Encapsulation.Suffixes; using kOS.Safe.Execution; using kOS.Safe.Exceptions; using kOS.Safe.Utilities; + namespace kOS.Safe.Compilation { /// A very short numerical ID for the opcode.
@@ -19,7 +21,7 @@ namespace kOS.Safe.Compilation /// the compiled files. Try to only tack values onto the end of the list, /// if possible: /// - public enum ByteCode :byte + public enum ByteCode :byte { // It's good practice to always have a zero value in an enum, even if not used: BOGUS = 0, @@ -33,7 +35,7 @@ public enum ByteCode :byte // The explicit picking of the hex numbers is not strictly necessary, // but it's being done to aid in debugging the ML load/unload process, // as it makes it possible to look at hexdumps of the machine code - // and comapre that to this list: + // and compare that to this list: EOF = 0x31, EOP = 0x32, NOP = 0x33, @@ -79,6 +81,11 @@ public enum ByteCode :byte POPSCOPE = 0x5b, STOREEXIST = 0x5c, PUSHDELEGATE = 0x5d, + BRANCHTRUE = 0x5e, + EXISTS = 0x5f, + ARGBOTTOM = 0x60, + TESTARGBOTTOM = 0x61, + // Augmented bogus placeholder versions of the normal // opcodes: These only exist in the program temporarily @@ -173,10 +180,10 @@ public abstract class Opcode /// /// The short coded value that indicates what kind of instruction this is. /// Hopefully one byte will be enough, and we won't have more than 256 different opcodes. - /// + ///
public abstract /*SHOULD-BE-STATIC*/ ByteCode Code { get; } - // A mapping of CodeName to Opcode type, built at initialization time: + // A mapping of CodeName to Opcode type, built at initialization time: private static Dictionary mapCodeToType; // will init this later. // A mapping of Name to Opcode type, built at initialization time: @@ -185,8 +192,8 @@ public abstract class Opcode // A table describing the arguments in machine language form that each opcode needs. // This is populated by using Reflection to scan all the Opcodes for their MLField Attributes. private static Dictionary> mapOpcodeToArgs; - - private static string forceDefaultConstructorMsg = + + private const string FORCE_DEFAULT_CONSTRUCTOR_MSG = "+----------- ERROR IN OPCODE DEFINITION ----------------------------------+\n" + "| |\n" + "| This is a message that only developers of the kOS mod are |\n" + @@ -207,15 +214,19 @@ public abstract class Opcode "+-------------------------------------------------------------------------+\n"; public int Id { get { return id; } } - public int DeltaInstructionPointer { get; protected set; } + public int DeltaInstructionPointer { get; protected set; } public int MLIndex { get; set; } // index into the Machine Language code file for the COMPILE command. public string Label {get{return label;} set {label = value;} } - private string label = ""; public virtual string DestinationLabel {get;set;} public string SourceName; public short SourceLine { get; set; } // line number in the source code that this was compiled from. public short SourceColumn { get; set; } // column number of the token nearest the cause of this Opcode. + + private string label = string.Empty; + + public bool AbortProgram { get; set; } + public bool AbortContext { get; set; } public virtual void Execute(ICpu cpu) { @@ -229,6 +240,8 @@ public override string ToString() protected Opcode() { DeltaInstructionPointer = 1; + AbortProgram = false; + AbortContext = false; } /// @@ -262,7 +275,7 @@ public virtual void PopulateFromMLFields(List fields) /// /// This is intended to be called once, during the mod's initialization, and never again. - /// It builds the Dictionaries that look up the type of opcode given its string name or code. + /// It builds the Dictionaries that look up the type of opcode given its string name or code. /// public static void InitMachineCodeData() { @@ -294,7 +307,7 @@ public static void InitMachineCodeData() } catch (MissingMethodException) { - SafeHouse.Logger.Log( String.Format(forceDefaultConstructorMsg, opType.Name) ); + SafeHouse.Logger.Log( String.Format(FORCE_DEFAULT_CONSTRUCTOR_MSG, opType.Name) ); Debug.AddNagMessage( Debug.NagType.NAGFOREVER, "ERROR IN OPCODE DEFINITION " + opType.Name ); return; } @@ -313,7 +326,7 @@ public static void InitMachineCodeData() { // Add to the map from codename to Opcode type: var opCodeName = (ByteCode) pInfo.GetValue(dummyInstance, null); - mapCodeToType.Add(opCodeName, opType); + mapCodeToType.Add(opCodeName, opType); } else if (pInfo.Name == "Name") { @@ -373,7 +386,7 @@ public static Type TypeFromCode(ByteCode code) if (! mapCodeToType.TryGetValue(code, out returnValue)) { returnValue = typeof(PseudoNull); // flag telling the caller "not found". - } + } return returnValue; } @@ -401,23 +414,54 @@ public IEnumerable GetArgumentDefs() { return mapOpcodeToArgs[GetType()]; } - } + /// + /// A utility function that will do a cpu.PopValue, but with an additional check to ensure + /// the value atop the stack isn't the arg bottom marker. + /// + /// object popped if it all worked fine + protected object PopValueAssert(ICpu cpu, bool barewordOkay = false) + { + object returnValue = cpu.PopValue(barewordOkay); + if (returnValue != null && returnValue.GetType() == OpcodeCall.ArgMarkerType) + throw new KOSArgumentMismatchException("Called with not enough arguments."); + return returnValue; + } + + /// + /// A utility function that will do the same as a cpu.PopValueEncapsulated, but with an additional check to ensure + /// the value atop the stack isn't the arg bottom marker. + /// + /// object popped if it all worked fine + protected object PopValueAssertEncapsulated(ICpu cpu, bool barewordOkay = false) + { + return Structure.FromPrimitive(PopValueAssert(cpu, barewordOkay)); + } + + /// + /// A utility function that will do the same as a cpu.PopStructureEncapsulated, but with an additional check to ensure + /// the value atop the stack isn't the arg bottom marker. + /// + /// object popped if it all worked fine + protected Structure PopStructureAssertEncapsulated(ICpu cpu, bool barewordOkay = false) + { + return Structure.FromPrimitiveWithAssert(PopValueAssert(cpu, barewordOkay)); + } + } + public abstract class BinaryOpcode : Opcode { - protected object Argument1 { get; private set; } - protected object Argument2 { get; private set; } + protected OperandPair Operands { get; private set; } public override void Execute(ICpu cpu) - { - Argument2 = cpu.PopValue(); - Argument1 = cpu.PopValue(); + { + object right = cpu.PopValue(); + object left = cpu.PopValue(); - // convert floats to doubles - if (Argument1 is float) Argument1 = Convert.ToDouble(Argument1); - if (Argument2 is float) Argument2 = Convert.ToDouble(Argument2); + var operands = new OperandPair(left, right); - Calculator calc = Calculator.GetCalculator(Argument1, Argument2); + Calculator calc = Calculator.GetCalculator(operands); + Operands = operands; object result = ExecuteCalculation(calc); cpu.PushStack(result); } @@ -456,12 +500,42 @@ public class OpcodeStore : Opcode public override void Execute(ICpu cpu) { - object value = cpu.PopValue(); - var identifier = (string)cpu.PopStack(); + Structure value = PopStructureAssertEncapsulated(cpu); + // Convert to string instead of cast in case the identifier is stored + // as an encapsulated StringValue, preventing an unboxing collision. + var identifier = Convert.ToString(cpu.PopStack()); cpu.SetValue(identifier, value); } } + /// + /// Tests if the identifier atop the stack is an identifier that exists in the system + /// and is accessible in scope at the moment. If the identifier doesn't + /// exist, or if it does but it's out of scope right now, then it results in + /// a FALSE, else it results in a TRUE. The result is pushed onto the stack + /// for reading. + /// Note that the ident atop the stack must be formatted like a variable + /// name (i.e. have the leading '$'). + /// + public class OpcodeExists : Opcode + { + protected override string Name { get { return "exists"; } } + public override ByteCode Code { get { return ByteCode.EXISTS; } } + + public override void Execute(ICpu cpu) + { + bool result = false; //pessimistic default + // Convert to string instead of cast in case the identifier is stored + // as an encapsulated StringValue, preventing an unboxing collision. + string ident = Convert.ToString(cpu.PopStack()); + if (ident != null && cpu.IdentifierExistsInScope(ident)) + { + result = true; + } + cpu.PushStack(result); + } + } + /// /// Consumes the topmost 2 values of the stack, storing the topmost stack /// value into a variable described by the next value down the stack.
@@ -478,12 +552,14 @@ public class OpcodeStoreExist : Opcode public override void Execute(ICpu cpu) { - object value = cpu.PopValue(); - var identifier = (string)cpu.PopStack(); + Structure value = PopStructureAssertEncapsulated(cpu); + // Convert to string instead of cast in case the identifier is stored + // as an encapsulated StringValue, preventing an unboxing collision. + var identifier = Convert.ToString(cpu.PopStack()); cpu.SetValueExists(identifier, value); } } - + /// /// Consumes the topmost 2 values of the stack, storing the topmost stack /// value into a variable described by the next value down the stack.
@@ -511,8 +587,10 @@ public class OpcodeStoreLocal : Opcode public override void Execute(ICpu cpu) { - object value = cpu.PopValue(); - var identifier = (string)cpu.PopStack(); + Structure value = PopStructureAssertEncapsulated(cpu); + // Convert to string instead of cast in case the identifier is stored + // as an encapsulated StringValue, preventing an unboxing collision. + var identifier = Convert.ToString(cpu.PopStack()); cpu.SetNewLocal(identifier, value); } } @@ -538,8 +616,10 @@ public class OpcodeStoreGlobal : Opcode public override void Execute(ICpu cpu) { - object value = cpu.PopValue(); - var identifier = (string)cpu.PopStack(); + Structure value = PopStructureAssertEncapsulated(cpu); + // Convert to string instead of cast in case the identifier is stored + // as an encapsulated StringValue, preventing an unboxing collision. + var identifier = Convert.ToString(cpu.PopStack()); cpu.SetGlobal(identifier, value); } } @@ -567,31 +647,52 @@ public class OpcodeGetMember : Opcode { protected override string Name { get { return "getmember"; } } public override ByteCode Code { get { return ByteCode.GETMEMBER; } } - protected bool isMethodCallAttempt = false; + protected bool IsMethodCallAttempt = false; public override void Execute(ICpu cpu) { string suffixName = cpu.PopStack().ToString().ToUpper(); - object popValue = cpu.PopValue(); + object popValue = cpu.PopValueEncapsulated(); var specialValue = popValue as ISuffixed; + if (specialValue == null) { throw new Exception(string.Format("Values of type {0} cannot have suffixes", popValue.GetType())); } - object value = specialValue.GetSuffix(suffixName); - if (value is Delegate && !isMethodCallAttempt) + ISuffixResult result = specialValue.GetSuffix(suffixName); + + // If the result is a suffix that is still in need of being invoked and hasn't resolved to a value yet: + if (result != null && !IsMethodCallAttempt && !result.HasValue) { // This is what happens when someone tries to call a suffix method as if // it wasn't a method (i.e. leaving the parentheses off the call). The // member returned is a delegate that needs to be called to get its actual // value. Borrowing the same routine that OpcodeCall uses for its method calls: - cpu.PushStack(OpcodeCall.ARG_MARKER_STRING); - value = OpcodeCall.ExecuteDelegate(cpu, (Delegate)value); + + cpu.PushStack(result); + cpu.PushStack(new KOSArgMarkerType()); + OpcodeCall.StaticExecute(cpu, false, "", false); // this will push the return value on the stack for us. } + else + { + if (result.HasValue) + { + // Push the already calculated value. - cpu.PushStack(value); + cpu.PushStack(result.Value); + } + else + { + // Push the indirect suffix delegate, but don't execute it yet + // because we need to put the upcoming arg list above it on the stack. + // Eventually an OpcodeCall will occur further down the program which + // will actually execute this. + + cpu.PushStack(result); + } + } } } @@ -609,7 +710,7 @@ public class OpcodeGetMethod : OpcodeGetMember public override ByteCode Code { get { return ByteCode.GETMETHOD; } } public override void Execute(ICpu cpu) { - isMethodCallAttempt = true; + IsMethodCallAttempt = true; base.Execute(cpu); } } @@ -622,9 +723,14 @@ public class OpcodeSetMember : Opcode public override void Execute(ICpu cpu) { - object value = cpu.PopValue(); - string suffixName = cpu.PopStack().ToString().ToUpper(); - object popValue = cpu.PopValue(); + Structure value = cpu.PopStructureEncapsulated(); // new value to set it to + string suffixName = cpu.PopStack().ToString().ToUpper(); // name of suffix being set + Structure popValue = cpu.PopStructureEncapsulated(); // object to which the suffix is attached. + + // We aren't converting the popValue to a Scalar, Boolean, or String structure here because + // the referenced variable wouldn't be updated. The primitives themselves are treated as value + // types instead of reference types. This is also why I removed the string unboxing + // from the ISuffixed check below. var specialValue = popValue as ISuffixed; if (specialValue == null) @@ -632,7 +738,10 @@ public override void Execute(ICpu cpu) throw new Exception(string.Format("Values of type {0} cannot have suffixes", popValue.GetType())); } - if (!specialValue.SetSuffix(suffixName, value)) + // TODO: When we refactor to make every structure use the new suffix style, this conversion + // to primative can be removed. Right now there are too many structures that override the + // SetSuffix method while relying on unboxing the object rahter than using Convert + if (!specialValue.SetSuffix(suffixName, Structure.ToPrimitive(value))) { throw new Exception(string.Format("Suffix {0} not found on object", suffixName)); } @@ -647,18 +756,22 @@ public class OpcodeGetIndex : Opcode public override void Execute(ICpu cpu) { - object index = cpu.PopValue(); - if (index is double || index is float) + Structure index = cpu.PopStructureEncapsulated(); + Structure collection = cpu.PopStructureEncapsulated(); + + Structure result; + + var indexable = collection as IIndexable; + if (indexable != null) { - index = Convert.ToInt32(index); // allow expressions like (1.0) to be indexes + result = indexable.GetIndex(index); + } + else + { + throw new Exception(string.Format("Can't iterate on an object of type {0}", collection.GetType())); } - object list = cpu.PopValue(); - - if (!(list is IIndexable)) throw new Exception(string.Format("Can't iterate on an object of type {0}", list.GetType())); - if (!(index is int)) throw new Exception("The index must be an integer number"); - object value = ((IIndexable)list).GetIndex((int)index); - cpu.PushStack(value); + cpu.PushStack(result); } } @@ -670,28 +783,34 @@ public class OpcodeSetIndex : Opcode public override void Execute(ICpu cpu) { - object value = cpu.PopValue(); - object index = cpu.PopValue(); - object list = cpu.PopValue(); - if (index is double || index is float) + Structure value = cpu.PopStructureEncapsulated(); + Structure index = cpu.PopStructureEncapsulated(); + Structure list = cpu.PopStructureEncapsulated(); + + if (index == null || value == null) { - index = Convert.ToInt32(index); // allow expressions like (1.0) to be indexes + throw new KOSException("Neither the key nor the index of a collection may be null"); } - if (!(list is IIndexable)) throw new Exception(string.Format("Can't iterate on an object of type {0}", list.GetType())); - if (!(index is int)) throw new Exception("The index must be an integer number"); - if (value != null) + var indexable = list as IIndexable; + if (indexable == null) { - ((IIndexable)list).SetIndex((int)index, value); + throw new KOSException(string.Format("Can't set indexed elements on an object of type {0}", list.GetType())); } + indexable.SetIndex(index, value); } } + public class OpcodeEOF : Opcode { protected override string Name { get { return "EOF"; } } public override ByteCode Code { get { return ByteCode.EOF; } } + public override void Execute(ICpu cpu) + { + AbortContext = true; + } } @@ -699,6 +818,10 @@ public class OpcodeEOP : Opcode { protected override string Name { get { return "EOP"; } } public override ByteCode Code { get { return ByteCode.EOP; } } + public override void Execute(ICpu cpu) + { + AbortProgram = true; + } } @@ -728,10 +851,20 @@ public class OpcodeBogus : Opcode public abstract class BranchOpcode : Opcode { - // This is identical to the base DestinationLabel, except that it has - // the MLFIeld attached to it: + // This stores EITHER the label OR the relative distance, + // depending, in the KSM packed file. Only if the label is + // an empty string does it store the integer distance instead. [MLField(1,true)] - public override string DestinationLabel {get;set;} + public object KSMLabelOrDistance + { + get + { + if (DestinationLabel == string.Empty) + return Distance; + else + return DestinationLabel; + } + } public int Distance { get; set; } @@ -740,12 +873,19 @@ public override void PopulateFromMLFields(List fields) // Expect fields in the same order as the [MLField] properties of this class: if (fields == null || fields.Count<1) throw new Exception("Saved field in ML file for BranchOpcode seems to be missing. Version mismatch?"); - DestinationLabel = (string)(fields[0]); // should throw exception if not an integer-ish type. + // This class does something strange - it expects the KSM file to encode EITHER a string label OR an integer, + // but never both. Therefore it has to determine the type of the arg to decide which it was: + if (fields[0] is string) + DestinationLabel = (string)fields[0]; + else + Distance = (int)fields[0]; } public override string ToString() { - return string.Format("{0} {1}", Name, Distance); + // Format string forces printing of '+/-' sign always, even for positive numbers. + // The intent is to make it more clear that this is a relative, not absolute jump: + return string.Format("{0} {1:+#;-#;+0}", Name, Distance); } } @@ -758,9 +898,22 @@ public class OpcodeBranchIfFalse : BranchOpcode public override void Execute(ICpu cpu) { bool condition = Convert.ToBoolean(cpu.PopValue()); + DeltaInstructionPointer = !condition ? Distance : 1; } } + + public class OpcodeBranchIfTrue : BranchOpcode + { + protected override string Name { get { return "br.true"; } } + public override ByteCode Code { get { return ByteCode.BRANCHTRUE; } } + + public override void Execute(ICpu cpu) + { + bool condition = Convert.ToBoolean(cpu.PopValue()); + DeltaInstructionPointer = condition ? Distance : 1; + } + } public class OpcodeBranchJump : BranchOpcode @@ -809,7 +962,7 @@ public override void PopulateFromMLFields(List fields) // Expect fields in the same order as the [MLField] properties of this class: if (fields == null || fields.Count<1) throw new Exception("Saved field in ML file for OpcodePushRelocateLater seems to be missing. Version mismatch?"); - UpcomingLabel = (string)( fields[0] ); + UpcomingLabel = (string)fields[0]; } public override void Execute(ICpu cpu) @@ -820,7 +973,7 @@ public override void Execute(ICpu cpu) public override string ToString() { return Name + " Label of next thing = {" + UpcomingLabel +"}"; - } + } } #endregion @@ -835,7 +988,7 @@ public class OpcodeCompareGT : BinaryOpcode protected override object ExecuteCalculation(Calculator calc) { - return calc.GreaterThan(Argument1, Argument2); + return calc.GreaterThan(Operands); } } @@ -847,7 +1000,7 @@ public class OpcodeCompareLT : BinaryOpcode protected override object ExecuteCalculation(Calculator calc) { - return calc.LessThan(Argument1, Argument2); + return calc.LessThan(Operands); } } @@ -859,7 +1012,7 @@ public class OpcodeCompareGTE : BinaryOpcode protected override object ExecuteCalculation(Calculator calc) { - return calc.GreaterThanEqual(Argument1, Argument2); + return calc.GreaterThanEqual(Operands); } } @@ -871,7 +1024,7 @@ public class OpcodeCompareLTE : BinaryOpcode protected override object ExecuteCalculation(Calculator calc) { - return calc.LessThanEqual(Argument1, Argument2); + return calc.LessThanEqual(Operands); } } @@ -883,7 +1036,7 @@ public class OpcodeCompareNE : BinaryOpcode protected override object ExecuteCalculation(Calculator calc) { - return calc.NotEqual(Argument1, Argument2); + return calc.NotEqual(Operands); } } @@ -895,14 +1048,14 @@ public class OpcodeCompareEqual : BinaryOpcode protected override object ExecuteCalculation(Calculator calc) { - return calc.Equal(Argument1, Argument2); + return calc.Equal(Operands); } } #endregion #region Math - + public class OpcodeMathNegate : Opcode { @@ -911,29 +1064,29 @@ public class OpcodeMathNegate : Opcode public override void Execute(ICpu cpu) { - object value = cpu.PopValue(); - object result; + Structure value = cpu.PopStructureEncapsulated(); - if (value is int) - result = -((int)value); - else if (value is float) - result = -(Convert.ToDouble(value)); - else if (value is double) - result = -((double)value); - else + var scalarValue = value as ScalarValue; + + if (scalarValue != null && scalarValue.IsValid) { - // Generic last-ditch to catch any sort of object that has - // overloaded the unary negate operator '-'. - // (For example, kOS.Suffixed.Vector and kOS.Suffixed.Direction) - Type t = value.GetType(); - MethodInfo negateMe = t.GetMethod("op_UnaryNegation", BindingFlags.Static | BindingFlags.Public); // C#'s alternate name for '-' operator - if (negateMe != null) - result = negateMe.Invoke(null, new[]{value}); // value is an arg, not the 'this'. (Method is static.) - else - throw new KOSUnaryOperandTypeException("negate", value); + cpu.PushStack(-scalarValue); + return; } - cpu.PushStack(result); + // Generic last-ditch to catch any sort of object that has + // overloaded the unary negate operator '-'. + // (For example, kOS.Suffixed.Vector and kOS.Suffixed.Direction) + Type t = value.GetType(); + MethodInfo negateMe = t.GetMethod("op_UnaryNegation", BindingFlags.FlattenHierarchy |BindingFlags.Static | BindingFlags.Public); + if (negateMe != null) + { + object result = negateMe.Invoke(null, new[]{value}); + cpu.PushStack(result); + } + else + throw new KOSUnaryOperandTypeException("negate", value); + } } @@ -945,9 +1098,9 @@ public class OpcodeMathAdd : BinaryOpcode protected override object ExecuteCalculation(Calculator calc) { - object result = calc.Add(Argument1, Argument2); + object result = calc.Add(Operands); if (result == null) - throw new KOSBinaryOperandTypeException(Argument1, "add", "to", Argument2); + throw new KOSBinaryOperandTypeException(Operands, "add", "to"); return result; } } @@ -960,7 +1113,7 @@ public class OpcodeMathSubtract : BinaryOpcode protected override object ExecuteCalculation(Calculator calc) { - return calc.Subtract(Argument1, Argument2); + return calc.Subtract(Operands); } } @@ -972,7 +1125,7 @@ public class OpcodeMathMultiply : BinaryOpcode protected override object ExecuteCalculation(Calculator calc) { - return calc.Multiply(Argument1, Argument2); + return calc.Multiply(Operands); } } @@ -984,11 +1137,12 @@ public class OpcodeMathDivide : BinaryOpcode protected override object ExecuteCalculation(Calculator calc) { - return calc.Divide(Argument1, Argument2); + return calc.Divide(Operands); } } + public class OpcodeMathPower : BinaryOpcode { protected override string Name { get { return "pow"; } } @@ -996,14 +1150,13 @@ public class OpcodeMathPower : BinaryOpcode protected override object ExecuteCalculation(Calculator calc) { - return calc.Power(Argument1, Argument2); + return calc.Power(Operands); } } #endregion - + #region Logic - public class OpcodeLogicToBool : Opcode { @@ -1012,12 +1165,17 @@ public class OpcodeLogicToBool : Opcode public override void Execute(ICpu cpu) { + // This may look like it's just pointlessly converting from a + // ScalarBoolean to a primitive boolean and then back into a + // ScalarBoolean, and in the case where the operand was already + // a ScalarBoolean that would be true. But the purpose of this opcode + // is to also change integers and floats into booleans. Thus the call to + // Convert.ToBoolean(): object value = cpu.PopValue(); bool result = Convert.ToBoolean(value); - cpu.PushStack(result); + cpu.PushStack(Structure.FromPrimitive(result)); } } - public class OpcodeLogicNot : Opcode { @@ -1029,16 +1187,19 @@ public override void Execute(ICpu cpu) object value = cpu.PopValue(); object result; - if (value is bool) - result = !((bool)value); - else if (value is int) - result = Convert.ToBoolean(value) ? 0 : 1; - else if ((value is double) || (value is float)) - result = Convert.ToBoolean(value) ? 0.0 : 1.0; - else - throw new KOSUnaryOperandTypeException("boolean-not", value); - - cpu.PushStack(result); + // Convert to bool instead of cast in case the identifier is stored + // as an encapsulated BooleanValue, preventing an unboxing collision. + // Wrapped in a try/catch since the Convert framework doesn't have a + // way to determine if a type can be converted. + try + { + result = !Convert.ToBoolean(value); + } + catch + { + throw new KOSCastException(value.GetType(), typeof(BooleanValue)); + } + cpu.PushStack(Structure.FromPrimitive(result)); } } @@ -1052,8 +1213,8 @@ public override void Execute(ICpu cpu) { bool argument2 = Convert.ToBoolean(cpu.PopValue()); bool argument1 = Convert.ToBoolean(cpu.PopValue()); - object result = argument1 & argument2; - cpu.PushStack(result); + object result = argument1 && argument2; + cpu.PushStack(Structure.FromPrimitive(result)); } } @@ -1067,8 +1228,8 @@ public override void Execute(ICpu cpu) { bool argument2 = Convert.ToBoolean(cpu.PopValue()); bool argument1 = Convert.ToBoolean(cpu.PopValue()); - object result = argument1 | argument2; - cpu.PushStack(result); + object result = argument1 || argument2; + cpu.PushStack(Structure.FromPrimitive(result)); } } @@ -1089,7 +1250,7 @@ public class OpcodeCall : Opcode protected override string Name { get { return "call"; } } public override ByteCode Code { get { return ByteCode.CALL; } } - public const string ARG_MARKER_STRING = "$"; // guaranteed to not be a legal variable name. + public static Type ArgMarkerType { get; private set; } // Don't query with reflection at runtime - get the type just once and keep it here. /// /// The Direct property flags which mode the opcode will be operating in:
@@ -1109,19 +1270,19 @@ public class OpcodeCall : Opcode /// Calling a function called "somefunc", which takes 2 parameters:
/// If the OpcodeCall is Direct, then the stack should look like this when it's executed:
///
- /// (arg2) < -- top of stack
+ /// (arg2) < -- top of stack
/// (arg1)
///
/// If the OpcodeCall is Indirect, then the stack should look like this when it's executed:
///
- /// (arg2) < -- top of stack
+ /// (arg2) < -- top of stack
/// (arg1)
/// (ArgMarkerString)
/// ("somefunc" (or a delegate))
///
public bool Direct { - // Behind the scenes this is implemented as a flag value in the + // Behind the scenes this is implemented as a flag value in the // Destination field. The Opcode is only indirect if the Destination // is a string equal to indirectPlaceholder. get @@ -1147,26 +1308,58 @@ public OpcodeCall(object destination) /// This variant of the constructor is just for machine language file read/write to use. /// protected OpcodeCall() { } - + + static OpcodeCall() + { + ArgMarkerType = typeof(KOSArgMarkerType); + } + public override void PopulateFromMLFields(List fields) { // Expect fields in the same order as the [MLField] properties of this class: if (fields == null || fields.Count<1) throw new Exception("Saved field in ML file for OpcodeCall seems to be missing. Version mismatch?"); - DestinationLabel = (string)fields[0]; + // Convert to string instead of cast in case the identifier is stored + // as an encapsulated StringValue, preventing an unboxing collision. + DestinationLabel = Convert.ToString(fields[0]); Destination = fields[1]; } public override void Execute(ICpu cpu) + { + int absoluteJumpTo = StaticExecute(cpu, Direct, Destination, false); + if (absoluteJumpTo >= 0) + DeltaInstructionPointer = absoluteJumpTo - cpu.InstructionPointer; + } + + /// + /// Performs the actual execution of a subroutine call, either from this opcode or externally from elsewhere. + /// All "call a routine" logic should shunt through this code here, which handles all the complex cases, + /// or at least it should. + /// Note that in the case of a user function, this does not *ACTUALLY* execute the function yet. It just + /// arranges the stack correctly for the call and returns the new location that the IP should be jumped to + /// on the next instruction to begin the subroutine. For all built-in cases, it actually executes the + /// call right now and doesn't return until it's done. But for User functions it can't do that - it can only + /// advise on where to jump on the next instruction to begin the function. + /// + /// the cpu its running on + /// same meaning as OpcodeCall.Direct + /// if direct, then this is the function name + /// true if KOSDelegate.Call() brought us here. If true that + /// means any pre-bound args are already on the stack. If false it means they aren't and this will have to + /// put them there. + /// new IP to jump to, if this should be followed up by a jump. If -1 then it means don't jump. + public static int StaticExecute(ICpu cpu, bool direct, object destination, bool calledFromKOSDelegateCall) { object functionPointer; object delegateReturn = null; + int newIP = -1; // new instruction pointer to jump to, next, if any. - if (Direct) + if (direct) { - functionPointer = cpu.GetValue(Destination); + functionPointer = cpu.GetValue(destination); if (functionPointer == null) - throw new KOSException("Attempt to call function failed - Value of function pointer for " + Destination + " is null."); + throw new KOSException("Attempt to call function failed - Value of function pointer for " + destination + " is null."); } else // for indirect calls, dig down to find what's underneath the argument list in the stack and use that: { @@ -1176,13 +1369,13 @@ public override void Execute(ICpu cpu) for (digDepth = 0; (! foundBottom) && digDepth < cpu.GetStackSize() ; ++digDepth) { object arg = cpu.PeekValue(digDepth); - if (arg is string && arg.ToString() == ARG_MARKER_STRING) + if (arg != null && arg.GetType() == ArgMarkerType) foundBottom = true; else ++argsCount; } functionPointer = cpu.PeekValue(digDepth); - if (! ( functionPointer is Delegate)) + if (! ( functionPointer is Delegate || functionPointer is KOSDelegate || functionPointer is ISuffixResult)) { // Indirect calls are meant to be delegates. If they are not, then that means the // function parentheses were put on by the user when they weren't required. Just dig @@ -1197,37 +1390,57 @@ public override void Execute(ICpu cpu) 0, argsCount, "\n(In fact in this case the parentheses are entirely optional)"); } cpu.PopValue(); // pop the ArgMarkerString too. - return; + return -1; } } - + // If it's a string it might not really be a built-in, it might still be a user func. // Detect whether it's built-in, and if it's not, then convert it into the equivalent // user func call by making it be an integer instruction pointer instead: - if (functionPointer is string) + if (functionPointer is string || functionPointer is StringValue) { - string functionName = functionPointer as string; + string functionName = functionPointer.ToString(); if (functionName.EndsWith("()")) functionName = functionName.Substring(0, functionName.Length - 2); if (!(cpu.BuiltInExists(functionName))) { - // It is not a built-in, so instead get its value as a user function pointer variable, despite + // It is not a built-in, so instead get its value as a user function pointer variable, despite // the fact that it's being called AS IF it was direct. if (!functionName.EndsWith("*")) functionName = functionName + "*"; if (!functionName.StartsWith("$")) functionName = "$" + functionName; functionPointer = cpu.GetValue(functionName); } } + + KOSDelegate kosDelegate = functionPointer as KOSDelegate; + if (kosDelegate != null) + { + if (! calledFromKOSDelegateCall) + kosDelegate.InsertPreBoundArgs(); + } + IUserDelegate userDelegate = functionPointer as IUserDelegate; if (userDelegate != null) functionPointer = userDelegate.EntryPoint; - if (functionPointer is int) + BuiltinDelegate builtinDel = functionPointer as BuiltinDelegate; + if (builtinDel != null && (! calledFromKOSDelegateCall) ) + functionPointer = builtinDel.Name; + + // If the IP for a jump location got encapsulated as a user int when it got stored + // into the internal variable, then get the primitive int back out of it again: + ScalarIntValue userInt = functionPointer as ScalarIntValue; + if (userInt != null) + functionPointer = userInt.GetIntValue(); + + // Convert to int instead of cast in case the identifier is stored + // as an encapsulated ScalarValue, preventing an unboxing collision. + if (functionPointer is int || functionPointer is ScalarValue) { - ReverseStackArgs(cpu); - int currentPointer = cpu.InstructionPointer; - DeltaInstructionPointer = (int)functionPointer - currentPointer; - var contextRecord = new SubroutineContext(currentPointer+1); + CpuUtility.ReverseStackArgs(cpu, direct); + var contextRecord = new SubroutineContext(cpu.InstructionPointer+1); + newIP = Convert.ToInt32(functionPointer); + cpu.PushAboveStack(contextRecord); if (userDelegate != null) { @@ -1247,152 +1460,44 @@ public override void Execute(ICpu cpu) if (functionName.EndsWith("()")) functionName = functionName.Substring(0, functionName.Length - 2); cpu.CallBuiltinFunction(functionName); - } - else if (functionPointer is Delegate) - { - delegateReturn = ExecuteDelegate(cpu, (Delegate)functionPointer); - } - else - { - // This is one of those "the user had better NEVER see this error" sorts of messages that's here to keep us in check: - throw new Exception( - string.Format("kOS internal error: OpcodeCall calling a function described using {0} which is of type {1} and kOS doesn't know how to call that.", functionPointer, functionPointer.GetType().Name) - ); - } - if (! Direct) - { - cpu.PopValue(); // consume function name, branch index, or delegate - } - if (functionPointer is Delegate) - { - cpu.PushStack(delegateReturn); // And now leave the return value on the stack to be read. - } - } - - /// - /// Call this when executing a delegate function whose delegate object was stored on - /// the stack underneath the arguments. The code here is using reflection and complex - /// enough that it needed to be separated from the main Execute method. - /// - /// the cpu this opcode is being called on - /// the delegate object this opcode is being called for. - /// whatever object the delegate method returned - public static object ExecuteDelegate(ICpu cpu, Delegate dlg) - { - MethodInfo methInfo = dlg.Method; - ParameterInfo[] paramArray = methInfo.GetParameters(); - var args = new List(); - - // Iterating over parameter signature backward because stack: - for (int i = paramArray.Length - 1 ; i >= 0 ; --i) - { - object arg = cpu.PopValue(); - if (arg is string && ((string)arg) == ARG_MARKER_STRING) - throw new KOSArgumentMismatchException(paramArray.Length, paramArray.Length - (i+1)); - Type argType = arg.GetType(); - ParameterInfo paramInfo = paramArray[i]; - Type paramType = paramInfo.ParameterType; - - // Parameter type-safe checking: - bool inheritable = paramType.IsAssignableFrom(argType); - if (! inheritable) + // If this was indirect, we need to consume the thing under the return value. + // as that was the indirect BuiltInDelegate: + if ((! direct) && builtinDel != null) { - bool castError = false; - // If it's not directly assignable to the expected type, maybe it's "castable" to it: - try - { - arg = Convert.ChangeType(arg, Type.GetTypeCode(paramType)); - } - catch (InvalidCastException) - { - throw new KOSCastException(argType, paramType); - } - catch (FormatException) { - castError = true; - } - if (castError) { - throw new Exception(string.Format("Argument {0}({1}) to method {2} should be {3} instead of {4}.", (paramArray.Length - i), arg, methInfo.Name, paramType.Name, argType)); - } + object topThing = cpu.PopStack(); + cpu.PopStack(); // remove BuiltInDelegate object. + cpu.PushStack(topThing); // put return value back. } - - args.Add(arg); } - // Consume the bottom marker under the args, which had better be - // immediately under the args we just popped, or the count was off: - bool foundArgMarker = false; - int numExtraArgs = 0; - while (cpu.GetStackSize() > 0 && !foundArgMarker) + else if (functionPointer is ISuffixResult) { - object marker = cpu.PopValue(); - if (marker is string && ((string)marker) == ARG_MARKER_STRING) - foundArgMarker = true; - else - ++numExtraArgs; - } - if (numExtraArgs > 0) - throw new KOSArgumentMismatchException(paramArray.Length, paramArray.Length + numExtraArgs); - - args.Reverse(); // Put back in normal order instead of stack order. - - // Dialog.DynamicInvoke expects a null, rather than an array of zero length, when - // there are no arguments to pass: - object[] argArray = (args.Count>0) ? args.ToArray() : null; + var result = (ISuffixResult) functionPointer; - try - { - // I could find no documentation on what DynamicInvoke returns when the delegate - // is a function returning void. Does it return a null? I don't know. So to avoid the - // problem, I split this into these two cases: - if (methInfo.ReturnType == typeof(void)) + if (!result.HasValue) { - dlg.DynamicInvoke(argArray); - return null; // So that the compiler building the opcodes for a function call statement doesn't - // have to know the function prototype to decide whether or - // not it needs to pop a value from the stack for the return value. By adding this, - // it can unconditionally assume there will be exactly 1 value left behind on the stack - // regardless of what function it was that was being called. + result.Invoke(cpu); } - return dlg.DynamicInvoke(argArray); + + delegateReturn = result.Value; } - catch (TargetInvocationException e) + // TODO:erendrake This else if is likely never used anymore + else if (functionPointer is Delegate) { - // Annoyingly, calling DynamicInvoke on a delegate wraps any exceptions the delegate throws inside - // this TargetInvocationException, which hides them from the kOS user unless we do this: - if (e.InnerException != null) - throw e.InnerException; - throw; + throw new KOSYouShouldNeverSeeThisException("OpcodeCall unexpected function pointer delegate"); } - } - - /// - /// Take the topmost arguments down to the ARG_MARKER_STRING, pop them off, and then - /// put them back again in reversed order so a function can read them in normal order. - /// - public void ReverseStackArgs(ICpu cpu) - { - List args = new List(); - object arg = cpu.PopValue(); - while (arg != null && (!(arg.ToString().Equals(ARG_MARKER_STRING)))) + else + { + throw new KOSNotInvokableException(functionPointer); + } + + if (functionPointer is ISuffixResult) { - args.Add(arg); - - // It's important to dereference with PopValue, not using PopStack, because the function - // being called might not even be able to see the variable in scope anyway. - // In other words, if calling a function like so: - // declare foo to 3. - // myfunc(foo). - // The code inside myfunc needs to see that as being identical to just saying: - // myfunc(3). - // It has to be unaware of the fact that the name of the argument was 'foo'. It just needs to - // see the contents that were inside foo. - arg = cpu.PopValue(); + if (! (delegateReturn is KOSPassThruReturn)) + cpu.PushStack(delegateReturn); // And now leave the return value on the stack to be read. } - // Push the arg marker back on again. - cpu.PushStack(ARG_MARKER_STRING); - // Push the arguments back on again, which will invert their order: - foreach (object item in args) - cpu.PushStack(item); + + return newIP; } public override string ToString() @@ -1400,14 +1505,94 @@ public override string ToString() return string.Format("{0} {1}", Name, Destination); } } - + + /// + /// Returns from an OpcodeCall, popping a number of scope depths off + /// the stack as it does so. It evals the topmost thing on the stack. + /// to remove any local variable references and replace them with their + /// current values, and then performs the equivalent of a popscope, then + /// jumps back to where the routine was called from. + /// It also checks to ensure that the argument stack contains the arg + /// bottom marker. If it does not, that proves the number of parameters + /// consumed did not match the number of arguments passed and it throws + /// an exception (to avoid stack misalignment that would happen if it + /// tried to continue). + /// public class OpcodeReturn : Opcode { protected override string Name { get { return "return"; } } public override ByteCode Code { get { return ByteCode.RETURN; } } + + [MLField(0,true)] + public Int16 Depth { get; private set; } // Determines how many levels to popscope. + public override void PopulateFromMLFields(List fields) + { + // Expect fields in the same order as the [MLField] properties of this class: + if (fields == null || fields.Count<1) + throw new Exception("Saved field in ML file for OpcodeCall seems to be missing. Version mismatch?"); + Depth = (Int16)fields[0]; + } + + // Default constructor is needed for PopulateFromMLFields but shouldn't be used outside the KSM file handler: + private OpcodeReturn() + { + } + + /// + /// Make a return, telling it how many levels of the scope stack it should + /// be popping as it does so. It combines the behavior of a PopScope inside + /// itself, AFTER it reads and evaluates the thing atop the stack for return + /// purposes (that way it evals the top thing BEFORE it pops the scope and forgets + /// what variables exist).
+ ///
+ /// Doing this:
+ /// push $val
+ /// return 2 deep
+ /// is the same as this:
+ /// push $val
+ /// eval
+ /// popscope 2
+ /// return 0 deep
+ ///
+ ///
+ /// the number of levels to be popped + public OpcodeReturn(Int16 depth) + { + Depth = depth; + } + public override void Execute(ICpu cpu) { + // Return value should be atop the stack. + // Pop it, eval it, and push it back, + // i.e. if the statement was RETURN X, and X is 2, then you want + // it to return the number 2, not the variable name $x, which could + // be a variable local to this function which is about to go out of scope + // so the caller can't access it: + object returnVal = cpu.PopValue(); + + // Now dig down through the stack until the argbottom is found. + // anything still leftover above that should be unread parameters we + // should throw away: + object shouldBeArgMarker = 0; // just a temp to force the loop to execute at least once. + while (shouldBeArgMarker == null || (shouldBeArgMarker.GetType() != OpcodeCall.ArgMarkerType)) + { + if (cpu.GetStackSize() <= 0) + { + throw new KOSArgumentMismatchException( + string.Format("Something is wrong with the stack - no arg bottom mark when doing a return. This is an internal problem with kOS") + ); + } + shouldBeArgMarker = cpu.PopStack(); + } + + cpu.PushStack(Structure.FromPrimitive(returnVal)); + + // Now, after the eval was done, NOW finally pop the scope, after we don't need local vars anymore: + if( Depth > 0 ) + OpcodePopScope.DoPopScope(cpu, Depth); + // The only thing on the "above stack" now that is allowed to get in the way of // finding the context record that tells us where to jump back to, are the potential // closure scope frames that might have been pushed if this subroutine was @@ -1427,27 +1612,6 @@ public override void Execute(ICpu cpu) // This should never happen with any user code: throw new Exception( "kOS internal error: Stack misalignment detected when returning from routine."); } - - // Return value should be atop the stack - we have to pop it so that - // we can reach the arg start marker under it: - object returnVal = cpu.PopValue(); - - // The next thing on the stack under the return value should be the marker that indicated where - // the parameters started. It should be thrown away now. If the next thing is NOT the marker - // of where the parameters started, that is proof the stack is misaligned, probably because the - // number of args passed didn't match the number of DECLARE PARAMETER statements in the function: - string shouldBeArgMarker = cpu.PopStack() as string; - - if ( (shouldBeArgMarker == null) || (!(shouldBeArgMarker.Equals(OpcodeCall.ARG_MARKER_STRING))) ) - { - throw new KOSArgumentMismatchException( - string.Format("(detected when returning from function and the stack still had {0} on it)", - (shouldBeArgMarker ?? "a non-string value")) - ); - } - // If the proper argument marker was found, then it's all okay, so put the return value - // back, where it belongs, now that the arg start marker was popped off: - cpu.PushStack(returnVal); var contextRecord = shouldBeContextRecord as SubroutineContext; @@ -1455,12 +1619,15 @@ public override void Execute(ICpu cpu) int currentPointer = cpu.InstructionPointer; DeltaInstructionPointer = destinationPointer - currentPointer; } - } + public override string ToString() + { + return String.Format("{0} {1} deep", Name, Depth); + } + } #endregion #region Stack - public class OpcodePush : Opcode { @@ -1511,7 +1678,7 @@ public override string ToString() /// 1. In some cases, like setting up locks, Compiler would create an OpcodePush with Argument = null, /// and a DestinationLabel = something. /// 2. ProgramBuilder would rebuild the OpcodePush's Argument by copying it from the DestinationLabel - /// as part of ReplaceLabels at runtime. + /// as part of ReplaceLabels at runtime. /// /// The Problem: When storing this in the ML file, BOTH the Argument AND the DestinationLabel would /// need to be stored as [MLFields] even though they are never BOTH populated at the same time, which @@ -1530,7 +1697,7 @@ public override string ToString() /// public class OpcodePushRelocateLater : Opcode { - [MLField(1,true)] + [MLField(0,true)] public override sealed string DestinationLabel {get;set;} protected override string Name { get { return "PushRelocateLater"; } } @@ -1562,7 +1729,7 @@ public override void Execute(ICpu cpu) public override string ToString() { return Name + " Dest{" + DestinationLabel +"}"; - } + } } @@ -1585,6 +1752,55 @@ public override void Execute(ICpu cpu) } } + /// + /// Asserts that the next thing on the stack is the argument bottom marker. + /// If it's not the argument bottom, it throws an error. + /// This does NOT pop the value from the stack - it merely peeks at the stack top. + /// The actual popping of the arg bottom value comes later when doing a return, + /// or a program bottom exit. + /// + public class OpcodeArgBottom : Opcode + { + protected override string Name { get { return "argbottom"; } } + public override ByteCode Code { get { return ByteCode.ARGBOTTOM; } } + + public override void Execute(ICpu cpu) + { + bool worked; + object shouldBeArgMarker = cpu.PeekRaw(0,out worked); + + if ( !worked || (shouldBeArgMarker == null) || (shouldBeArgMarker.GetType() != OpcodeCall.ArgMarkerType) ) + { + throw new KOSArgumentMismatchException("Called with too many arguments."); + } + } + } + + /// + /// Tests whether or not the next thing on the stack is the argument bottom marker. + /// It pushes a true on top if it is, or false if it is not. In either case it does + /// NOT consume the arg bottom marker, but just peeks for it. + /// + public class OpcodeTestArgBottom : Opcode + { + protected override string Name { get { return "testargbottom"; } } + public override ByteCode Code { get { return ByteCode.TESTARGBOTTOM; } } + + public override void Execute(ICpu cpu) + { + bool worked; + object shouldBeArgMarker = cpu.PeekRaw(0,out worked); + + if ( !worked || (shouldBeArgMarker == null) || (shouldBeArgMarker.GetType() != OpcodeCall.ArgMarkerType) ) + { + cpu.PushStack(false); // these are internally used, so no Strucutre.FromPrimitive wrapper call. + } + else + { + cpu.PushStack(true); // these are internally used, so no Strucutre.FromPrimitive wrapper call. + } + } + } public class OpcodeDup : Opcode { @@ -1628,7 +1844,7 @@ public class OpcodeEval : Opcode public override void Execute(ICpu cpu) { - cpu.PushStack(cpu.PopValue()); + cpu.PushStack(cpu.PopValueEncapsulated()); } } @@ -1686,7 +1902,7 @@ public override string ToString() { return String.Format("{0} {1} {2}", Name, ScopeId, ParentScopeId); } - + } /// @@ -1726,14 +1942,28 @@ public override void PopulateFromMLFields(List fields) public override void Execute(ICpu cpu) { - cpu.PopAboveStack(NumLevels); + DoPopScope(cpu, NumLevels); + } + + /// + /// Do the actual work of the Execute() method. This was pulled out + /// to a separate static method so that others can call it without needing + /// an actual popscope object. Everything OpcodePopScope.Execute() does + /// should actually be done here, so as to ensure that external callers of + /// this get exactly the same behaviour as a full popstack opcode. + /// + /// the shared.cpu to operate on. + /// number of levels to popscope. + public static void DoPopScope(ICpu cpuObj, Int16 levels) + { + cpuObj.PopAboveStack(levels); } public override string ToString() { return Name + " " + NumLevels; } - + } public class OpcodePushDelegate : Opcode @@ -1762,8 +1992,8 @@ public override void PopulateFromMLFields(List fields) // Expect fields in the same order as the [MLField] properties of this class: if (fields == null || fields.Count<2) throw new Exception("Saved field in ML file for OpcodePushDelegate seems to be missing. Version mismatch?"); - EntryPoint = (int)fields[0]; - WithClosure = (bool)fields[1]; + EntryPoint = Convert.ToInt32(fields[0]); + WithClosure = Convert.ToBoolean(fields[1]); } public override void Execute(ICpu cpu) @@ -1777,14 +2007,14 @@ public override string ToString() return Name + " " + EntryPoint.ToString(); } } - + /// /// This serves the same purpose as OpcodePushRelocateLater, except it's for /// use with UserDelegates instead of raw integer IP calls. /// public class OpcodePushDelegateRelocateLater : OpcodePushRelocateLater { - [MLField(1,false)] + [MLField(100,false)] public bool WithClosure { get; set; } protected override string Name { get { return "PushDelegateRelocateLater"; } } @@ -1798,14 +2028,16 @@ public OpcodePushDelegateRelocateLater(string destLabel, bool withClosure) : bas /// /// This variant of the constructor is just for ML file save/load to use. /// - protected OpcodePushDelegateRelocateLater() : base() {} + protected OpcodePushDelegateRelocateLater() + {} public override void PopulateFromMLFields(List fields) { // Expect fields in the same order as the [MLField] properties of this class: if (fields == null || fields.Count<1) throw new Exception("Saved field in ML file for OpcodePushDelegateRelocatelater seems to be missing. Version mismatch?"); - WithClosure = (bool)fields[0]; + DestinationLabel = Convert.ToString(fields[0]); // this is really from the base class. + WithClosure = Convert.ToBoolean(fields[1]); } } @@ -1821,7 +2053,7 @@ public class OpcodeAddTrigger : Opcode public override void Execute(ICpu cpu) { - var functionPointer = (int)cpu.PopValue(); + int functionPointer = Convert.ToInt32(cpu.PopValue()); // in case it got wrapped in a ScalarIntValue cpu.AddTrigger(functionPointer); } @@ -1839,7 +2071,7 @@ public class OpcodeRemoveTrigger : Opcode public override void Execute(ICpu cpu) { - var functionPointer = (int)cpu.PopValue(); + var functionPointer = Convert.ToInt32(cpu.PopValue()); // in case it got wrapped in a ScalarIntValue cpu.RemoveTrigger(functionPointer); } } diff --git a/src/kOS.Safe/Compilation/OperandPair.cs b/src/kOS.Safe/Compilation/OperandPair.cs new file mode 100644 index 000000000..6551ccb4d --- /dev/null +++ b/src/kOS.Safe/Compilation/OperandPair.cs @@ -0,0 +1,39 @@ +using System; +using kOS.Safe.Encapsulation; + +namespace kOS.Safe.Compilation +{ + public class OperandPair + { + public object Left { get; private set; } + + public Type LeftType + { + get { return Left.GetType(); } + } + + public object Right { get; private set; } + + public Type RightType + { + get { return Right.GetType(); } + } + + public OperandPair(object left, object right) + { + Left = left; + Right = right; + CoerceTypes(); + } + + private void CoerceTypes() + { + // convert floats to doubles + if (Right is float) Right = Convert.ToDouble(Right); + if (Left is float) Left = Convert.ToDouble(Left); + + Left = Structure.FromPrimitive(Left); + Right = Structure.FromPrimitive(Right); + } + } +} \ No newline at end of file diff --git a/src/kOS.Safe/Compilation/ProgramBuilder.cs b/src/kOS.Safe/Compilation/ProgramBuilder.cs index d4a3f70ce..fdf3a3e3e 100644 --- a/src/kOS.Safe/Compilation/ProgramBuilder.cs +++ b/src/kOS.Safe/Compilation/ProgramBuilder.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using kOS.Safe.Compilation.KS; namespace kOS.Safe.Compilation { @@ -79,8 +80,11 @@ private void AddJumpToEntryPoint(CodePart linkedObject) { if (linkedObject.MainCode.Count <= 0) return; - var jumpOpcode = new OpcodeBranchJump(); - jumpOpcode.DestinationLabel = GetEntryPointLabel(linkedObject); + var jumpOpcode = new OpcodeBranchJump + { + DestinationLabel = GetEntryPointLabel(linkedObject) + }; + linkedObject.FunctionsCode.Insert(0, jumpOpcode); } @@ -92,19 +96,27 @@ private string GetEntryPointLabel(CodePart linkedObject) protected virtual void AddEndOfProgram(CodePart linkedObject, bool isMainProgram) { + // possible refactor: this logic needs to be moved into the compiler + // itself eventually, so that we can make an "exit" statement. As it stands, + // the fact that the final exit code is only dealt with here outside the + // compiler, and the fact that it changes depending on if it's called from + // the interpreter or from another program (the interpreter doesn't expect an exit + // code, and won't pop it, which is the reason for this if/else below), is + // what makes that non-trivial. if (isMainProgram) { + linkedObject.MainCode.Add(new OpcodePop()); // to consume the argbottom mark. linkedObject.MainCode.Add(new OpcodeEOP()); } else { linkedObject.MainCode.Add(new OpcodePush(0)); // all Returns now need a dummy return value on them. - linkedObject.MainCode.Add(new OpcodeReturn()); + linkedObject.MainCode.Add(new OpcodeReturn(0)); } } private void ReplaceLabels(List program) - { + { var labels = new Dictionary(); // get the index of every label @@ -112,6 +124,18 @@ private void ReplaceLabels(List program) { if (program[index].Label != string.Empty) { + if (labels.ContainsKey(program[index].Label)) + { + // This is one of those "should never happen" errors that if it happens + // it means kOS devs screwed up - so dump the partially relabeled program + // to the log just to help in diagnosing the bug report that may happen: + // + Utilities.SafeHouse.Logger.LogError("=====Relabeled Program so far is: ========="); + Utilities.SafeHouse.Logger.LogError(Utilities.Debug.GetCodeFragment(program)); + + throw new Exceptions.KOSCompileException(LineCol.Unknown(), string.Format( + "ProgramBuilder.ReplaceLabels: Cannot add label {0}, label already exists. Opcode: {1}", program[index].Label, program[index].ToString())); + } labels.Add(program[index].Label, index); } } diff --git a/src/kOS.Safe/Compilation/Script.cs b/src/kOS.Safe/Compilation/Script.cs index 9f1bd05b7..0606f02b4 100644 --- a/src/kOS.Safe/Compilation/Script.cs +++ b/src/kOS.Safe/Compilation/Script.cs @@ -1,20 +1,9 @@ -using System; using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Text.RegularExpressions; namespace kOS.Safe.Compilation { public abstract class Script { - private readonly Dictionary identifierReplacements = new Dictionary { { "alt:radar", "alt_radar" }, - { "alt:apoapsis", "alt_apoapsis" }, - { "alt:periapsis", "alt_periapsis" }, - { "eta:apoapsis", "eta_apoapsis" }, - { "eta:periapsis", "eta_periapsis" }, - { "eta:transition", "eta_transition" }}; - protected CompileCache Cache { get; set; } protected Script() @@ -79,57 +68,5 @@ public virtual bool IsCommandComplete(string command) { return true; } - - protected virtual string MakeLowerCase(string scriptText) - { - Dictionary stringsLiterals = ExtractStrings(scriptText); - string modifiedScriptText = scriptText; - - if (stringsLiterals.Count > 0) - { - // replace strings with tokens - modifiedScriptText = stringsLiterals.Aggregate(modifiedScriptText, (current, kvp) => current.Replace(kvp.Value, kvp.Key)); - - // make lowercase - modifiedScriptText = modifiedScriptText.ToLower(); - - // restore strings - modifiedScriptText = stringsLiterals.Aggregate(modifiedScriptText, (current, kvp) => current.Replace(kvp.Key, kvp.Value)); - } - else - { - // make lowercase - modifiedScriptText = modifiedScriptText.ToLower(); - } - - return modifiedScriptText; - } - - - protected virtual string ReplaceIdentifiers(string scriptText) - { - return identifierReplacements.Aggregate(scriptText, (current, kvp) => current.Replace(kvp.Key, kvp.Value)); - } - - private Dictionary ExtractStrings(string scriptText) - { - var stringsLiterals = new Dictionary(); - int stringIndex = 0; - - var regex = new Regex("\".+?\""); - MatchCollection matches = regex.Matches(scriptText); - - foreach (Match match in matches) - { - if (match.Success) - { - string token = string.Format("[s{0}]", ++stringIndex); - stringsLiterals.Add(token, match.Value); - } - } - - return stringsLiterals; - } - } } \ No newline at end of file diff --git a/src/kOS.Safe/Encapsulation/ArchiveFile.cs b/src/kOS.Safe/Encapsulation/ArchiveFile.cs new file mode 100644 index 000000000..77361d3cf --- /dev/null +++ b/src/kOS.Safe/Encapsulation/ArchiveFile.cs @@ -0,0 +1,49 @@ +using kOS.Safe.Persistence; +using System; +using System.IO; + +namespace kOS.Safe.Encapsulation +{ + [kOS.Safe.Utilities.KOSNomenclature("VolumeFile", KOSToCSharp = false)] + public class ArchiveFile : VolumeFile + { + private readonly FileInfo fileInfo; + public override int Size { get { fileInfo.Refresh(); return (int)fileInfo.Length; } } + + public ArchiveFile(FileInfo fileInfo) : base(fileInfo.Name) + { + this.fileInfo = fileInfo; + } + + public override FileContent ReadAll() + { + byte[] bytes = File.ReadAllBytes(fileInfo.FullName); + + bytes = Archive.ConvertFromWindowsNewlines(bytes); + + return new FileContent(bytes); + } + + public override bool Write(byte[] content) + { + if (!fileInfo.Exists) + { + throw new KOSFileException("File does not exist: " + fileInfo.Name); + } + + byte[] bytes = Archive.ConvertToWindowsNewlines(content); + using (FileStream stream = fileInfo.Open(FileMode.Append, FileAccess.Write)) + { + stream.Write(bytes, 0, bytes.Length); + stream.Flush(); + } + + return true; + } + + public override void Clear() + { + File.WriteAllText(fileInfo.FullName, string.Empty); + } + } +} \ No newline at end of file diff --git a/src/kOS.Safe/Encapsulation/BooleanValue.cs b/src/kOS.Safe/Encapsulation/BooleanValue.cs new file mode 100644 index 000000000..23ba24bc1 --- /dev/null +++ b/src/kOS.Safe/Encapsulation/BooleanValue.cs @@ -0,0 +1,256 @@ +using kOS.Safe.Exceptions; +using System; +using System.Reflection; + +namespace kOS.Safe.Encapsulation +{ + [kOS.Safe.Utilities.KOSNomenclature("Boolean")] + public class BooleanValue : Structure, IConvertible + { + private readonly bool internalValue; + + public bool Value { get { return internalValue; } } + + public BooleanValue(bool value) + { + internalValue = value; + InitializeSuffixes(); + } + + public void InitializeSuffixes() + { + // TODO: Add suffixes as needed + } + + public override string ToString() + { + return Value.ToString(); + } + + public override bool Equals(object obj) + { + if (obj == null) return false; + var val = obj as BooleanValue; + if (val != null) + { + if (Value == val.Value) return true; + } + else + { + BindingFlags flags = BindingFlags.ExactBinding | BindingFlags.Static | BindingFlags.Public; + MethodInfo converter = typeof(BooleanValue).GetMethod("op_Implicit", flags, null, new[] { obj.GetType() }, null); + if (converter != null) + { + val = (BooleanValue)converter.Invoke(null, new[] { obj }); + if (Value == val.Value) return true; + } + } + return false; + } + + public static bool NullSafeEquals(object obj1, object obj2) + { + if (obj1 == null) + { + if (obj2 == null) return true; + return false; + } + if (obj2 == null) return false; + var val1 = obj1 as BooleanValue; + if (val1 != null) + { + return val1.Equals(obj2); + } + var val2 = obj2 as BooleanValue; + if (val2 != null) + { + return val2.Equals(obj1); + } + return false; + } + + public static BooleanValue True + { + get { return new BooleanValue(true);} + } + + public static BooleanValue False + { + get { return new BooleanValue(false);} + } + + public override int GetHashCode() + { + return internalValue.GetHashCode(); + } + + public static BooleanValue operator !(BooleanValue val) + { + return new BooleanValue(!val.Value); + } + + public static bool operator ==(BooleanValue val1, BooleanValue val2) + { + return NullSafeEquals(val1, val2); + } + + public static bool operator ==(BooleanValue val1, bool val2) + { + return NullSafeEquals(val1, new BooleanValue(val2)); + } + + public static bool operator ==(bool val1, BooleanValue val2) + { + return NullSafeEquals(new BooleanValue(val1), val2); + } + + public static bool operator ==(BooleanValue val1, Structure val2) + { + val2 = new BooleanValue(Convert.ToBoolean(val2)); + return NullSafeEquals(val1, val2); + } + + public static bool operator ==(Structure val1, BooleanValue val2) + { + val1 = new BooleanValue(Convert.ToBoolean(val1)); + return NullSafeEquals(val1, val2); + } + + public static bool operator !=(BooleanValue val1, BooleanValue val2) + { + return !NullSafeEquals(val1, val2); + } + + public static bool operator !=(BooleanValue val1, bool val2) + { + return !NullSafeEquals(val1, new BooleanValue(val2)); + } + + public static bool operator !=(bool val1, BooleanValue val2) + { + return !NullSafeEquals(new BooleanValue(val1), val2); + } + + public static bool operator !=(BooleanValue val1, Structure val2) + { + val2 = new BooleanValue(Convert.ToBoolean(val2)); + return !NullSafeEquals(val1, val2); + } + + public static bool operator !=(Structure val1, BooleanValue val2) + { + if (val2 == null) throw new ArgumentNullException("val2"); + val1 = new BooleanValue(Convert.ToBoolean(val1)); + return !NullSafeEquals(val1, val2); + } + + public static bool operator &(BooleanValue val1, BooleanValue val2) + { + return val1.Value && val2.Value; + } + + public static bool operator |(BooleanValue val1, BooleanValue val2) + { + return val1.Value || val2.Value; + } + + public static implicit operator bool(BooleanValue val) + { + return val.Value; + } + + public static implicit operator BooleanValue(bool val) + { + return new BooleanValue(val); + } + + TypeCode IConvertible.GetTypeCode() + { + return TypeCode.Object; + } + + bool IConvertible.ToBoolean(IFormatProvider provider) + { + return internalValue; + } + + byte IConvertible.ToByte(IFormatProvider provider) + { + throw new KOSCastException(typeof(BooleanValue), typeof(byte)); + } + + char IConvertible.ToChar(IFormatProvider provider) + { + throw new KOSCastException(typeof(BooleanValue), typeof(char)); + } + + DateTime IConvertible.ToDateTime(IFormatProvider provider) + { + throw new KOSCastException(typeof(BooleanValue), typeof(DateTime)); + } + + decimal IConvertible.ToDecimal(IFormatProvider provider) + { + throw new KOSCastException(typeof(BooleanValue), typeof(decimal)); + } + + double IConvertible.ToDouble(IFormatProvider provider) + { + throw new KOSCastException(typeof(BooleanValue), typeof(double)); + } + + short IConvertible.ToInt16(IFormatProvider provider) + { + throw new KOSCastException(typeof(BooleanValue), typeof(short)); + } + + int IConvertible.ToInt32(IFormatProvider provider) + { + throw new KOSCastException(typeof(BooleanValue), typeof(int)); + } + + long IConvertible.ToInt64(IFormatProvider provider) + { + throw new KOSCastException(typeof(BooleanValue), typeof(long)); + } + + sbyte IConvertible.ToSByte(IFormatProvider provider) + { + throw new KOSCastException(typeof(BooleanValue), typeof(sbyte)); + } + + float IConvertible.ToSingle(IFormatProvider provider) + { + throw new KOSCastException(typeof(BooleanValue), typeof(float)); + } + + string IConvertible.ToString(IFormatProvider provider) + { + return ToString(); + } + + object IConvertible.ToType(Type conversionType, IFormatProvider provider) + { + if (conversionType == GetType()) + return this; + else if (conversionType.IsSubclassOf(typeof(Structure))) + throw new KOSCastException(typeof(BooleanValue), conversionType); + return Convert.ChangeType(internalValue, conversionType); + } + + ushort IConvertible.ToUInt16(IFormatProvider provider) + { + throw new KOSCastException(typeof(BooleanValue), typeof(ushort)); + } + + uint IConvertible.ToUInt32(IFormatProvider provider) + { + throw new KOSCastException(typeof(BooleanValue), typeof(uint)); + } + + ulong IConvertible.ToUInt64(IFormatProvider provider) + { + throw new KOSCastException(typeof(BooleanValue), typeof(ulong)); + } + } +} \ No newline at end of file diff --git a/src/kOS.Safe/Encapsulation/BuiltinDelegate.cs b/src/kOS.Safe/Encapsulation/BuiltinDelegate.cs new file mode 100644 index 000000000..4326b1535 --- /dev/null +++ b/src/kOS.Safe/Encapsulation/BuiltinDelegate.cs @@ -0,0 +1,50 @@ +using kOS.Safe.Compilation; +using kOS.Safe.Execution; + +namespace kOS.Safe.Encapsulation +{ + /// + /// A callback reference to a built-in function, (one of the kinds derived from kOS.Function.FunctionBase).
+ ///
+ ///
+ [kOS.Safe.Utilities.KOSNomenclature("BuiltinDelegate")] + public class BuiltinDelegate : KOSDelegate + { + public string Name { get; set; } + + public BuiltinDelegate(ICpu cpu, string name) : + base(cpu) + { + Name = name; + } + + public BuiltinDelegate(BuiltinDelegate oldCopy) : base(oldCopy) + { + Name = oldCopy.Name; + } + + public override KOSDelegate Clone() + { + return new BuiltinDelegate(this); + } + + public override string ToString() + { + return string.Format("BuiltinDelegate(cpu={0}, Name={1},\n {2})", + Cpu, Name, base.ToString()); + } + + public override void PushUnderArgs() + { + // do nothing. + } + + public override Structure Call() + { + int throwAway = OpcodeCall.StaticExecute(Cpu, true, Name, true); + // throwAway will be -1 for cases where it's a builtin function. + // and the return value will be left atop the stack by StaticExecute. + return new KOSPassThruReturn(); + } + } +} diff --git a/src/kOS.Safe/Encapsulation/CollectionValue.cs b/src/kOS.Safe/Encapsulation/CollectionValue.cs new file mode 100644 index 000000000..79da072e3 --- /dev/null +++ b/src/kOS.Safe/Encapsulation/CollectionValue.cs @@ -0,0 +1,29 @@ +using System; +using kOS.Safe.Encapsulation; +using System.Collections.Generic; +using System.Collections; +using System.Linq; +using kOS.Safe.Encapsulation.Suffixes; +using kOS.Safe.Serialization; + +namespace kOS.Safe +{ + [kOS.Safe.Utilities.KOSNomenclature("Collection")] + public abstract class CollectionValue : EnumerableValue where C : ICollection where T : Structure + { + protected readonly C Collection; + + public CollectionValue(string label, C collection) : base(label, collection) + { + this.Collection = collection; + + InitializeCollectionSuffixes(); + } + + private void InitializeCollectionSuffixes() + { + AddSuffix("CLEAR", new NoArgsVoidSuffix(Collection.Clear)); + } + } +} + diff --git a/src/kOS.Safe/Encapsulation/ConstantValue.cs b/src/kOS.Safe/Encapsulation/ConstantValue.cs index ac98d938b..2bc3b0dbd 100644 --- a/src/kOS.Safe/Encapsulation/ConstantValue.cs +++ b/src/kOS.Safe/Encapsulation/ConstantValue.cs @@ -3,14 +3,28 @@ namespace kOS.Safe.Encapsulation { + [kOS.Safe.Utilities.KOSNomenclature("Constant")] public class ConstantValue : Structure { + /// + /// kiloPascals to atmospheres + /// + public const double KpaToAtm = 0.00986923266716012830002467308167; + static ConstantValue() { - AddGlobalSuffix("G", new StaticSuffix(() => 6.67384*Math.Pow(10,-11))); - AddGlobalSuffix("E", new StaticSuffix(() => Math.E)); - AddGlobalSuffix("e", new StaticSuffix(() => Math.E)); - AddGlobalSuffix("PI", new StaticSuffix(() => Math.PI)); + AddGlobalSuffix("G", new StaticSuffix(() => 6.67384*Math.Pow(10,-11))); + AddGlobalSuffix("E", new StaticSuffix(() => Math.E)); + AddGlobalSuffix("PI", new StaticSuffix(() => Math.PI)); + AddGlobalSuffix("C", new StaticSuffix(() => 299792458.0, "Speed of light in m/s")); + AddGlobalSuffix("ATMTOKPA", new StaticSuffix(() => 101.325, "atmospheres to kiloPascals" )); + AddGlobalSuffix("KPATOATM", new StaticSuffix(() => KpaToAtm, "kiloPascals to atmospheres")); + + // pi/180 : + AddGlobalSuffix("DEGTORAD", new StaticSuffix(() => 0.01745329251994329576923690768489, "degrees to radians")); + + // 180/pi : + AddGlobalSuffix("RADTODEG", new StaticSuffix(() => 57.295779513082320876798154814105, "radians to degrees")); } public override string ToString() diff --git a/src/kOS.Safe/Encapsulation/EnumerableValue.cs b/src/kOS.Safe/Encapsulation/EnumerableValue.cs new file mode 100644 index 000000000..6a39083ae --- /dev/null +++ b/src/kOS.Safe/Encapsulation/EnumerableValue.cs @@ -0,0 +1,77 @@ +using kOS.Safe.Encapsulation.Suffixes; +using kOS.Safe.Serialization; +using System.Collections; +using System.Collections.Generic; +using System.Linq; + +namespace kOS.Safe.Encapsulation +{ + [kOS.Safe.Utilities.KOSNomenclature("Enumerable")] + public abstract class EnumerableValue : SerializableStructure, IEnumerable + where TE : IEnumerable + where T : Structure + { + protected TE InnerEnumerable { get; private set; } + private readonly string label; + + protected EnumerableValue(string label, TE enumerable) + { + this.label = label; + InnerEnumerable = enumerable; + + InitializeEnumerableSuffixes(); + } + + public virtual IEnumerator GetEnumerator() + { + return InnerEnumerable.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + + public bool Contains(T item) + { + return InnerEnumerable.Contains(item); + } + + public int Count() + { + return InnerEnumerable.Count(); + } + + public override string ToString() + { + return new SafeSerializationMgr().ToString(this); + } + + public override Dump Dump() + { + var result = new DumpWithHeader + { + Header = label + " of " + InnerEnumerable.Count() + " items:" + }; + + int i = 0; + foreach (T item in this) + { + result.Add(i, item); + i++; + } + + return result; + } + + private void InitializeEnumerableSuffixes() + { + AddSuffix("ITERATOR", new NoArgsSuffix(() => new Enumerator(InnerEnumerable.GetEnumerator()))); + AddSuffix("REVERSEITERATOR", new NoArgsSuffix(() => new Enumerator(Enumerable.Reverse(InnerEnumerable).GetEnumerator()))); + AddSuffix("LENGTH", new NoArgsSuffix(() => InnerEnumerable.Count())); + AddSuffix("CONTAINS", new OneArgsSuffix((n) => Contains(n))); + AddSuffix("EMPTY", new NoArgsSuffix(() => !InnerEnumerable.Any())); + AddSuffix("DUMP", new NoArgsSuffix(() => new StringValue(ToString()))); + } + } +} \ No newline at end of file diff --git a/src/kOS.Safe/Encapsulation/Enumerator.cs b/src/kOS.Safe/Encapsulation/Enumerator.cs index fc1688b30..c789118de 100644 --- a/src/kOS.Safe/Encapsulation/Enumerator.cs +++ b/src/kOS.Safe/Encapsulation/Enumerator.cs @@ -3,6 +3,8 @@ namespace kOS.Safe.Encapsulation { + [kOS.Safe.Utilities.KOSNomenclature("Iterator")] + [kOS.Safe.Utilities.KOSNomenclature("Enumerator", CSharpToKOS = false)] // one-way mapping makes it just another alias, not canonical. public class Enumerator : Structure { private readonly IEnumerator enumerator; @@ -17,21 +19,21 @@ public Enumerator(IEnumerator enumerator) private void EnumeratorInitializeSuffixes() { - AddSuffix("RESET", new NoArgsSuffix(() => + AddSuffix("RESET", new NoArgsVoidSuffix(() => { index = -1; status = false; enumerator.Reset(); })); - AddSuffix("NEXT", new NoArgsSuffix(() => + AddSuffix("NEXT", new NoArgsSuffix(() => { status = enumerator.MoveNext(); index++; return status; })); - AddSuffix("ATEND", new NoArgsSuffix(() => !status)); - AddSuffix("INDEX", new NoArgsSuffix(() => index)); - AddSuffix("VALUE", new NoArgsSuffix(() => enumerator.Current)); + AddSuffix("ATEND", new NoArgsSuffix(() => !status)); + AddSuffix("INDEX", new NoArgsSuffix(() => index)); + AddSuffix("VALUE", new NoArgsSuffix(() => FromPrimitiveWithAssert(enumerator.Current))); } public override string ToString() diff --git a/src/kOS.Safe/Encapsulation/FileInfo.cs b/src/kOS.Safe/Encapsulation/FileInfo.cs deleted file mode 100644 index 5030966f4..000000000 --- a/src/kOS.Safe/Encapsulation/FileInfo.cs +++ /dev/null @@ -1,50 +0,0 @@ -using System.Linq; -using kOS.Safe.Encapsulation.Suffixes; - -namespace kOS.Safe.Encapsulation -{ - public class FileInfo : Structure - { - private string name; - - public string Name - { - get { return name; } - private set - { - name = value; - - var fileParts = name.Split('.'); - Extension = fileParts.Count() > 1 ? fileParts.Last() : string.Empty; - } - } - - public int Size { get; private set; } - public string Extension { get; private set; } - - public FileInfo(string name, int size) - { - Name = name; - Size = size; - InitializeSuffixes(); - } - - private void InitializeSuffixes() - { - AddSuffix("NAME", new Suffix(() => Name)); - AddSuffix("SIZE", new Suffix(() => Size)); - AddSuffix("FILETYPE", new Suffix(() => Extension)); - } - - public FileInfo(System.IO.FileInfo fileInfo) - { - Name = fileInfo.Name; - Size = (int) fileInfo.Length; - } - - public override string ToString() - { - return Name; - } - } -} diff --git a/src/kOS.Safe/Encapsulation/HarddiskFile.cs b/src/kOS.Safe/Encapsulation/HarddiskFile.cs new file mode 100644 index 000000000..7ad813093 --- /dev/null +++ b/src/kOS.Safe/Encapsulation/HarddiskFile.cs @@ -0,0 +1,40 @@ +using kOS.Safe.Persistence; + +namespace kOS.Safe.Encapsulation +{ + [kOS.Safe.Utilities.KOSNomenclature("VolumeFile", KOSToCSharp = false)] + public class HarddiskFile : VolumeFile + { + private readonly Harddisk harddisk; + + public override int Size { get { return ReadAll().Size; } } + + public HarddiskFile(Harddisk harddisk, string name) : base(name) + { + this.harddisk = harddisk; + } + + private FileContent GetFileContent() + { + return harddisk.GetFileContent(Name); + } + + public override FileContent ReadAll() + { + return new FileContent((byte[])GetFileContent().Bytes.Clone()); + } + + public override bool Write(byte[] content) + { + if (harddisk.FreeSpace <= content.Length) return false; + + GetFileContent().Write(content); + return true; + } + + public override void Clear() + { + GetFileContent().Clear(); + } + } +} \ No newline at end of file diff --git a/src/kOS.Safe/Encapsulation/IConfig.cs b/src/kOS.Safe/Encapsulation/IConfig.cs index a53e235c3..a7e8d3982 100644 --- a/src/kOS.Safe/Encapsulation/IConfig.cs +++ b/src/kOS.Safe/Encapsulation/IConfig.cs @@ -1,3 +1,7 @@ +using System; +using System.Collections.Generic; +using kOS.Safe.Encapsulation.Suffixes; + namespace kOS.Safe.Encapsulation { public interface IConfig: ISuffixed, IOperable @@ -7,10 +11,25 @@ public interface IConfig: ISuffixed, IOperable bool ShowStatistics { get; set; } bool EnableRTIntegration { get; set; } bool StartOnArchive { get; set; } + bool ObeyHideUI { get; set; } bool EnableSafeMode { get; set; } bool VerboseExceptions { get; set; } bool EnableTelnet { get; set; } int TelnetPort { get; set; } + bool AudibleExceptions { get; set; } + bool TelnetLoopback { get; set; } + bool UseBlizzyToolbarOnly { get; set; } + + /// + /// Return the moment in time when the most recent change to any of the + /// config values happened. Used by KOSTollBarWindow to decide whether or not + /// it needs to assume its cached values are stale and need re-loading. + /// + DateTime TimeStamp { get; } + + bool DebugEachOpcode { get; set; } + void SaveConfig(); + IList GetConfigKeys(); } } \ No newline at end of file diff --git a/src/kOS.Safe/Encapsulation/IIndexable.cs b/src/kOS.Safe/Encapsulation/IIndexable.cs index d31830a41..715e3c81c 100644 --- a/src/kOS.Safe/Encapsulation/IIndexable.cs +++ b/src/kOS.Safe/Encapsulation/IIndexable.cs @@ -2,7 +2,27 @@ namespace kOS.Safe.Encapsulation { public interface IIndexable { - object GetIndex(int index); - void SetIndex(int index, object value); + Structure GetIndex(Structure index); + void SetIndex(Structure index, Structure value); + + /// + /// This should redirect to GetIndex(Structure index), and is provided as + /// a convenient shorthand for GetIndex(Structure.FromPrimitive(someInt)), + /// because of the large number of places in the code that were written to + /// assume integer indeces: + /// + /// + /// + Structure GetIndex(int index); + + /// + /// This should redirect to SetIndex(Structure index, Structure value), and is provided as + /// a convenient shorthand for SetIndex(Structure.FromPrimitive(someInt), someValue) + /// because of the large number of places in the code that were written to + /// assume integer indeces: + /// + /// + /// + void SetIndex(int index, Structure value); } } diff --git a/src/kOS.Safe/Encapsulation/ISerializableValue.cs b/src/kOS.Safe/Encapsulation/ISerializableValue.cs new file mode 100644 index 000000000..deca95bef --- /dev/null +++ b/src/kOS.Safe/Encapsulation/ISerializableValue.cs @@ -0,0 +1,9 @@ +using System; + +namespace kOS.Safe.Encapsulation +{ + public interface ISerializableValue + { + } +} + diff --git a/src/kOS.Safe/Encapsulation/ISuffix.cs b/src/kOS.Safe/Encapsulation/ISuffix.cs index 85a5710e0..9cfc7cb5f 100644 --- a/src/kOS.Safe/Encapsulation/ISuffix.cs +++ b/src/kOS.Safe/Encapsulation/ISuffix.cs @@ -1,8 +1,10 @@ -namespace kOS.Safe.Encapsulation +using kOS.Safe.Encapsulation.Suffixes; + +namespace kOS.Safe.Encapsulation { public interface ISuffix { - object Get(); + ISuffixResult Get(); string Description { get; } } } \ No newline at end of file diff --git a/src/kOS.Safe/Encapsulation/ISuffixed.cs b/src/kOS.Safe/Encapsulation/ISuffixed.cs index 336252eb2..1f781550a 100644 --- a/src/kOS.Safe/Encapsulation/ISuffixed.cs +++ b/src/kOS.Safe/Encapsulation/ISuffixed.cs @@ -1,8 +1,10 @@ -namespace kOS.Safe.Encapsulation +using kOS.Safe.Encapsulation.Suffixes; + +namespace kOS.Safe.Encapsulation { public interface ISuffixed { bool SetSuffix(string suffixName, object value); - object GetSuffix(string suffixName); + ISuffixResult GetSuffix(string suffixName); } } \ No newline at end of file diff --git a/src/kOS.Safe/Encapsulation/KOSDelegate.cs b/src/kOS.Safe/Encapsulation/KOSDelegate.cs new file mode 100644 index 000000000..c7a1bec5b --- /dev/null +++ b/src/kOS.Safe/Encapsulation/KOSDelegate.cs @@ -0,0 +1,156 @@ +using kOS.Safe.Encapsulation.Suffixes; +using kOS.Safe.Exceptions; +using kOS.Safe.Execution; +using System.Collections.Generic; +using System.Text; + +namespace kOS.Safe.Encapsulation +{ + /// + /// Any situation where a function of any type is referenced as the + /// value of a variable or suffix, it will be a variant of this class, + /// which is the base class underneath references to user functions, + /// built-in functions, or suffix methods. + /// + [kOS.Safe.Utilities.KOSNomenclature("Delegate")] + public abstract class KOSDelegate : Structure + { + protected IList PreBoundArgs { get; set; } + + protected ICpu Cpu { get; set; } + + protected KOSDelegate(ICpu cpu) + { + Cpu = cpu; + PreBoundArgs = new List(); + InitializeSuffixes(); + } + + protected KOSDelegate(KOSDelegate oldCopy) + { + Cpu = oldCopy.Cpu; + PreBoundArgs = new List(); + InitializeSuffixes(); + foreach (Structure ca in oldCopy.PreBoundArgs) + PreBoundArgs.Add(ca); + } + + private void InitializeSuffixes() + { + AddSuffix("CALL", new VarArgsSuffix(Call)); + AddSuffix("BIND", new VarArgsSuffix(Bind)); + } + + public void AddPreBoundArg(Structure arg) + { + PreBoundArgs.Add(arg); + } + + public Structure Call(params Structure[] args) + { + PushUnderArgs(); + Cpu.PushStack(new KOSArgMarkerType()); + foreach (Structure arg in PreBoundArgs) + { + Cpu.PushStack(arg); + } + foreach (Structure arg in args) + { + Cpu.PushStack(arg); + } + return Call(); + } + + /// + /// Assuming normal args are already on the stack, + /// then the prebound args would have to be inserted + /// underneath them, which slightly violates the + /// stack access rules. So do it through this method + /// if it's needed. (If Call() was used, then it's not needed + /// because Call() does this for you. But if Call() was + /// not used and someone just used bare parentheses like so: + /// function y { parameter a,b,c. print a+b+c. } + /// set x to y@:bind(1,2). + /// x(). // instead of saying x:call(). + /// then the prebound args don't get pushed by doing that, and they + /// have to get pushed under the top by calling this.) + /// + public void InsertPreBoundArgs() + { + Stack aboveArgs = new Stack(); + object arg = ""; // doesn't matter what it is as long as it's non-null for the while check below. + while (arg != null && !(arg is KOSArgMarkerType)) + { + arg = Cpu.PopStack(); + if (!(arg is KOSArgMarkerType)) + aboveArgs.Push(arg); + } + if (arg == null) + throw new KOSException("KOSDelegate.InsertPreBoundArgs: Stack arg bottom missing.\n" + + "Contact the kOS devs. This message should 'never' happen."); + // Now re-push the args back, putting the preBound ones at the bottom + // where they belong: + Cpu.PushStack(new KOSArgMarkerType()); + foreach (Structure item in PreBoundArgs) + { + Cpu.PushStack(item); + } + foreach (object item in aboveArgs) // Because this was pushed to a stack, this should show in reverse order. + { + Cpu.PushStack(item); + } + } + + /// + /// Assuming the args have been pushed onto the stack already, with + /// the argbottom marker under them, do the call of this delegate. + /// + public abstract Structure Call(); + + /// + /// If the derivative class needs to put anything on the stack underneath the + /// KOSArgMarkerType and the args, it's given an opportunity to do so here by + /// overriding this method. + /// + public abstract void PushUnderArgs(); + + /// + /// Should return a new instance of self, with all fields copied. + /// + /// Should return whatever the actual derived type is, not a raw KOSDelegate + public abstract KOSDelegate Clone(); + + /// + /// This returns a new variant of the delegate that has the first + /// parameters hardcoded. If you call :bind(1,2,3) on a delegate that takes 5 arguments, you get + /// a variant of the delegate that now only takes the lastmost 2 arguments, with the first two + /// having been hardcoded to 1,2,3. + /// This is actually the technique known as "partial function application" in C#'s terms. + /// + /// the arguments to be hardcoded at the front of the list of arguments, going left to right + /// a delegate that now takes fewer arguments, just the leftover ones that weren't hardcoded + public KOSDelegate Bind(params Structure[] args) + { + KOSDelegate preBoundDel = Clone(); + + foreach (Structure arg in args) + { + preBoundDel.AddPreBoundArg(arg); + } + + return preBoundDel; + } + + public override string ToString() + { + StringBuilder str = new StringBuilder(); + str.Append("KOSDelegate("); + foreach (Structure arg in PreBoundArgs) + { + str.Append("pre-bound arg " + arg + " "); + } + str.Append(")"); + return str.ToString(); + } + } +} \ No newline at end of file diff --git a/src/kOS.Safe/Encapsulation/Lexicon.cs b/src/kOS.Safe/Encapsulation/Lexicon.cs new file mode 100644 index 000000000..38d4f054a --- /dev/null +++ b/src/kOS.Safe/Encapsulation/Lexicon.cs @@ -0,0 +1,304 @@ +using kOS.Safe.Encapsulation.Suffixes; +using kOS.Safe.Exceptions; +using kOS.Safe.Serialization; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using kOS.Safe.Utilities; + +namespace kOS.Safe.Encapsulation +{ + [kOS.Safe.Utilities.KOSNomenclature("Lexicon")] + [kOS.Safe.Utilities.KOSNomenclature("Lex", CSharpToKOS = false) ] + public class Lexicon : SerializableStructure, IDictionary, IIndexable + { + public class LexiconComparer : IEqualityComparer + { + public bool Equals(TI x, TI y) + { + if (x == null || y == null) + { + return false; + } + + if (x.GetType() != y.GetType()) + { + return false; + } + + if ((x is string || x is StringValue) && (y is string || y is StringValue)) + { + var compare = string.Compare(x.ToString(), y.ToString(), StringComparison.InvariantCultureIgnoreCase); + return compare == 0; + } + + return x.Equals(y); + } + + public int GetHashCode(TI obj) + { + if (obj is string || obj is StringValue) + { + return obj.ToString().ToLower().GetHashCode(); + } + return obj.GetHashCode(); + } + } + + private IDictionary internalDictionary; + private bool caseSensitive; + + public Lexicon() + { + internalDictionary = new Dictionary(new LexiconComparer()); + caseSensitive = false; + InitalizeSuffixes(); + } + + public Lexicon(IEnumerable values) : this() + { + FillWithEnumerableValues(values); + } + + public Lexicon(IEnumerable> lexicon) + : this() + { + foreach (KeyValuePair u in lexicon) + { + internalDictionary.Add(u); + } + } + + private void FillWithEnumerableValues(IEnumerable values) + { + if ((values.Count() == 1) && (values.First() is IEnumerable)) { + FillWithEnumerableValues(values.First() as IEnumerable); + return; + } + + if (values.Count() % 2 == 1) { + throw new KOSException("Lexicon constructor expects an even number of arguments or a single enumerable type"); + } + + values.Select((value, index) => new {Index = index, Value = value}) + .GroupBy(x => x.Index / 2).ForEach(g => internalDictionary[g.ElementAt(0).Value] = g.ElementAt(1).Value); + + } + + private void InitalizeSuffixes() + { + AddSuffix("CLEAR", new NoArgsVoidSuffix(Clear, "Removes all items from Lexicon")); + AddSuffix("KEYS", new Suffix>(GetKeys, "Returns the lexicon keys")); + AddSuffix("HASKEY", new OneArgsSuffix(HasKey, "Returns true if a key is in the Lexicon")); + AddSuffix("HASVALUE", new OneArgsSuffix(HasValue, "Returns true if value is in the Lexicon")); + AddSuffix("VALUES", new Suffix>(GetValues, "Returns the lexicon values")); + AddSuffix("COPY", new NoArgsSuffix(() => new Lexicon(this), "Returns a copy of Lexicon")); + AddSuffix("LENGTH", new NoArgsSuffix(() => internalDictionary.Count, "Returns the number of elements in the collection")); + AddSuffix("REMOVE", new OneArgsSuffix(one => Remove(one), "Removes the value at the given key")); + AddSuffix("ADD", new TwoArgsSuffix(Add, "Adds a new item to the lexicon, will error if the key already exists")); + AddSuffix("DUMP", new NoArgsSuffix(() => ToString(), "Serializes the collection to a string for printing")); + AddSuffix(new[] { "CASESENSITIVE", "CASE" }, new SetSuffix(() => caseSensitive, SetCaseSensitivity, "Lets you get/set the case sensitivity on the collection, changing sensitivity will clear the collection")); + } + + private void SetCaseSensitivity(BooleanValue value) + { + bool newCase = value.Value; + if (newCase == caseSensitive) + { + return; + } + caseSensitive = newCase; + + internalDictionary = newCase ? + new Dictionary() : + new Dictionary(new LexiconComparer()); + } + + private BooleanValue HasValue(Structure value) + { + return internalDictionary.Values.Contains(value); + } + + private BooleanValue HasKey(Structure key) + { + return internalDictionary.ContainsKey(key); + } + + public ListValue GetValues() + { + return ListValue.CreateList(Values); + } + + public ListValue GetKeys() + { + return ListValue.CreateList(Keys); + } + + public IEnumerator> GetEnumerator() + { + return internalDictionary.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + + public void Add(KeyValuePair item) + { + if (internalDictionary.ContainsKey(item.Key)) + { + throw new KOSDuplicateKeyException(item.Key.ToString(), caseSensitive); + } + internalDictionary.Add(item); + } + + public void Clear() + { + internalDictionary.Clear(); + } + + public bool Contains(KeyValuePair item) + { + return internalDictionary.Contains(item); + } + + public void CopyTo(KeyValuePair[] array, int arrayIndex) + { + internalDictionary.CopyTo(array, arrayIndex); + } + + public bool Remove(KeyValuePair item) + { + return internalDictionary.Remove(item); + } + + public int Count + { + get { return internalDictionary.Count; } + } + + public bool IsReadOnly + { + get { return internalDictionary.IsReadOnly; } + } + + public bool ContainsKey(Structure key) + { + return internalDictionary.ContainsKey(key); + } + + public void Add(Structure key, Structure value) + { + if (internalDictionary.ContainsKey(key)) + { + throw new KOSDuplicateKeyException(key.ToString(), caseSensitive); + } + internalDictionary.Add(key, value); + } + + public bool Remove(Structure key) + { + return internalDictionary.Remove(key); + } + + public bool TryGetValue(Structure key, out Structure value) + { + return internalDictionary.TryGetValue(key, out value); + } + + public Structure this[Structure key] + { + get + { + if (internalDictionary.ContainsKey(key)) + { + return internalDictionary[key]; + } + throw new KOSKeyNotFoundException(key.ToString(), caseSensitive); + } + set + { + internalDictionary[key] = value; + } + } + + public ICollection Keys + { + get + { + return internalDictionary.Keys; + } + } + + public ICollection Values + { + get + { + return internalDictionary.Values; + } + } + + public Structure GetIndex(Structure key) + { + return internalDictionary[key]; + } + + // Only needed because IIndexable demands it. For a lexicon, none of the code is + // actually trying to call this: + public Structure GetIndex(int index) + { + return internalDictionary[FromPrimitiveWithAssert(index)]; + } + + public void SetIndex(Structure index, Structure value) + { + internalDictionary[index] = value; + } + + // Only needed because IIndexable demands it. For a lexicon, none of the code is + // actually trying to call this: + public void SetIndex(int index, Structure value) + { + internalDictionary[FromPrimitiveWithAssert(index)] = value; + } + + public override string ToString() + { + return new SafeSerializationMgr().ToString(this); + } + + public override Dump Dump() + { + var result = new DumpWithHeader + { + Header = "LEXICON of " + internalDictionary.Count() + " items:" + }; + + List list = new List(); + + foreach (KeyValuePair entry in internalDictionary) + { + list.Add(entry.Key); + list.Add(entry.Value); + } + + result.Add(kOS.Safe.Dump.Entries, list); + + return result; + } + + public override void LoadDump(Dump dump) + { + internalDictionary.Clear(); + + List values = (List)dump[kOS.Safe.Dump.Entries]; + + for (int i = 0; 2 * i < values.Count; i++) + { + internalDictionary.Add(Structure.FromPrimitiveWithAssert(values[2 * i]), Structure.FromPrimitiveWithAssert(values[2 * i + 1])); + } + } + } +} \ No newline at end of file diff --git a/src/kOS.Safe/Encapsulation/ListValue.cs b/src/kOS.Safe/Encapsulation/ListValue.cs index 0d92d1e1a..9794d8b0a 100644 --- a/src/kOS.Safe/Encapsulation/ListValue.cs +++ b/src/kOS.Safe/Encapsulation/ListValue.cs @@ -1,292 +1,163 @@ -using kOS.Safe.Encapsulation.Suffixes; -using kOS.Safe.Properties; using System; -using System.Collections; using System.Collections.Generic; -using System.Diagnostics; using System.Linq; -using System.Text; +using kOS.Safe.Encapsulation.Suffixes; +using kOS.Safe.Exceptions; +using kOS.Safe.Properties; +using kOS.Safe.Serialization; namespace kOS.Safe.Encapsulation { - public class ListValue : Structure, IList, IIndexable + [kOS.Safe.Utilities.KOSNomenclature("List")] + public class ListValue : CollectionValue>, IIndexable + where T : Structure { - private readonly IList internalList; - public ListValue() : this(new List()) { } - public ListValue(IEnumerable listValue) + public ListValue(IEnumerable listValue) : base("LIST", new List(listValue)) { - internalList = listValue.ToList(); ListInitializeSuffixes(); } - public IEnumerator GetEnumerator() - { - return internalList.GetEnumerator(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - public void Add(T item) { - internalList.Add(item); - } - - public void Clear() - { - internalList.Clear(); - } - - public bool Contains(T item) - { - return internalList.Contains(item); + Collection.Add(item); } public void CopyTo(T[] array, int arrayIndex) { - internalList.CopyTo(array, arrayIndex); + Collection.CopyTo(array, arrayIndex); } public bool Remove(T item) { - return internalList.Remove(item); + return Collection.Remove(item); } - public int Count + public void Clear() { - get { return internalList.Count; } + Collection.Clear(); } - public bool IsReadOnly + public void RemoveAt(int index) { - get { return internalList.IsReadOnly; } + Collection.RemoveAt(index); } - public int IndexOf(T item) + public T this[int index] { - return internalList.IndexOf(item); + get { return Collection[index]; } + set { Collection[index] = value; } } - - public void Insert(int index, T item) + + public override Dump Dump() { - internalList.Insert(index, item); + var result = new DumpWithHeader + { + Header = "LIST of " + Collection.Count() + " items:" + }; + + // This conversion is needed because TerminalFormatter.WriteIndented() demands to only + // work with exactly List and bombs out on List's: + List list = new List(); + foreach (object entry in Collection) + list.Add(entry); + + result.Add(kOS.Safe.Dump.Items, list); + return result; } - public void RemoveAt(int index) + public override void LoadDump(Dump dump) { - internalList.RemoveAt(index); - } + Collection.Clear(); - public T this[int index] - { - get { return internalList[index]; } - set { internalList[index] = value; } + List values = (List)dump[kOS.Safe.Dump.Items]; + + foreach (object item in values) + { + Collection.Add((T)FromPrimitive(item)); + } } private void ListInitializeSuffixes() { - AddSuffix("ADD", new OneArgsSuffix (toAdd => internalList.Add(toAdd), Resources.ListAddDescription)); - AddSuffix("INSERT", new TwoArgsSuffix ((index, toAdd) => internalList.Insert(index, toAdd))); - AddSuffix("REMOVE", new OneArgsSuffix (toRemove => internalList.RemoveAt(toRemove))); - AddSuffix("CLEAR", new NoArgsSuffix (() => internalList.Clear())); - AddSuffix("LENGTH", new NoArgsSuffix (() => internalList.Count)); - AddSuffix("ITERATOR", new NoArgsSuffix (() => new Enumerator(internalList.GetEnumerator()))); AddSuffix("COPY", new NoArgsSuffix> (() => new ListValue(this))); - AddSuffix("CONTAINS", new OneArgsSuffix (item => internalList.Contains(item))); - AddSuffix("SUBLIST", new TwoArgsSuffix(SubListMethod)); - AddSuffix("EMPTY", new NoArgsSuffix (() => !internalList.Any())); - AddSuffix("DUMP", new NoArgsSuffix (ListDumpDeep)); - } + AddSuffix("ADD", new OneArgsSuffix (toAdd => Collection.Add(toAdd), Resources.ListAddDescription)); + AddSuffix("INSERT", new TwoArgsSuffix ((index, toAdd) => Collection.Insert(index, toAdd))); + AddSuffix("REMOVE", new OneArgsSuffix (toRemove => Collection.RemoveAt(toRemove))); + AddSuffix("SUBLIST", new TwoArgsSuffix(SubListMethod)); + AddSuffix("JOIN", new OneArgsSuffix(Join)); + } // This test case was added to ensure there was an example method with more than 1 argument. - private ListValue SubListMethod(int start, int runLength) + private ListValue SubListMethod(ScalarValue start, ScalarValue runLength) { var subList = new ListValue(); - for (int i = start; i < internalList.Count && i < start + runLength; ++i) + for (int i = start; i < Collection.Count && i < start + runLength; ++i) { - subList.Add(internalList[i]); + subList.Add(Collection[i]); } return subList; } - public override bool SetSuffix(string suffixName, object value) + public static ListValue CreateList(IEnumerable list) { - //These were deprecated in v0.15. Text here it to assist in upgrading scripts - switch (suffixName) - { - case "ADD": - throw new Exception("Old syntax \n" + - " SET _somelist_:ADD TO _value_\n" + - "is no longer supported. Try replacing it with: \n" + - " _somelist_:ADD(_value_).\n"); - case "CONTAINS": - throw new Exception("Old syntax \n" + - " SET _somelist_:CONTAINS TO _value_\n" + - "is no longer supported. Try replacing it with: \n" + - " SET _somelist_:CONTAINS(_value_) TO _value_\n"); - case "REMOVE": - throw new Exception("Old syntax \n" + - " SET _somelist_:REMOVE TO _number_\n" + - "is no longer supported. Try replacing it with: \n" + - " _somelist_:REMOVE(_number_).\n"); - default: - return false; - } + return new ListValue(list.Cast()); } - // Using Statics for this is not thread-safe, but kOS doesn't do threads at the moment. - // TODO: find a better way later to track the nesting level through all the messy - // calls of nested objects' ToStrings. - private static int currentNestDepth; - private static int maxVerboseDepth; - - public override string ToString() + public Structure GetIndex(int index) { - // If toString is nested inside another object's toString that was - // called from another list, then honor the verbosity of that - // original topmost call by not explicitly saying it's shallow or - // nested here. otherwise explicitly say it's shallow if it's the outermost - // ToString() call: - return CalledFrom("ListDump") ? ListDump() : ListDumpShallow(); + return Collection[index]; } - /// - /// Returns whether or not the current method was called from the given method name - /// by examining the callstack downward from the current level's parent. Assumes the - /// method in question is a method of this class (ListValue) itself. Examines all - /// the nesting levels, so if A called B called C called D, then during D, a call to - /// calledFrom("A") would still return true. - /// - /// Test if this method called me - /// True if the current method was called from the given method name - private bool CalledFrom(string methodName) + public Structure GetIndex(Structure index) { - StackFrame[] callStack = new StackTrace().GetFrames(); // get call stack - - if (callStack == null) return false; - var declaringType = callStack[0].GetMethod().DeclaringType; - if (declaringType == null) return false; - - string thisDeclaringType = declaringType.Name; - - // Find out whether or not this method call was nested inside - // another method call of itself which was not meant to recurse. - // If so, then set a flag that will avoid doing the full dump: - - // (i starts at 1 not 0 deliberately. That's not a bug - skipping to top stack - // frame on purpose because the top stack frame is the current method we're in - // the middle of executing): - for (int i = 1; i < callStack.Length; ++i) + if (index is ScalarValue) { - var type = callStack[i].GetMethod().DeclaringType; - if (type == null) continue; - - var matchingName = callStack[i].GetMethod().Name == methodName; - var matchingType = type.Name == thisDeclaringType; - if (matchingName && matchingType) - { - return true; - } + int i = Convert.ToInt32(index); // allow expressions like (1.0) to be indexes + return GetIndex(i); } - return false; - } - - /// - /// Show the contents of the string as tersely as possible, as just - /// a "this is a list and it has this many things int it" message. - /// - /// short string without eoln - private string TerseDump() - { - return "LIST of " + internalList.Count + " item" + (internalList.Count == 1 ? "" : "s"); - } - - /// - /// Dump the contents of the list in a shallow way, without recursing down - /// into any sublists inside the topmost list:
- ///
- /// Warning: If you Ever change the name of this, then change the value of the two - /// static variables "shallowDumpName" and "deepDumpName", or the ListDump algorithm - /// will break: - /// long string including eolns, ready for printing - private string ListDumpShallow() - { - maxVerboseDepth = 1; - return ListDump(); - } - - /// - /// Dump the contents of the list into a string, by descending through the - /// list and appending the "ToString"'s of all the elements in the list.
- ///
- /// Warning: If you Ever change the name of this, then change the value of the two - /// static variables "shallowDumpName" and "deepDumpName", or the ListDump algorithm - /// will break: - /// long string including eolns, ready for printing - private string ListDumpDeep() - { - maxVerboseDepth = 99; - return ListDump(); + // Throw cast exception with ScalarIntValue, instead of just any ScalarValue + throw new KOSCastException(index.GetType(), typeof(ScalarIntValue)); } - /// - /// This is the engine underneath ListDump shallow/deep. - /// - /// string dump of the list - private string ListDump() + public void SetIndex(Structure index, Structure value) { - const int SPACES_PER_INDENT = 2; - - ++currentNestDepth; - bool truncateHere = currentNestDepth > maxVerboseDepth; - - if (truncateHere) + int idx; + try { - --currentNestDepth; - return TerseDump(); + idx = Convert.ToInt32(index); } - var contents = new StringBuilder(); - contents.AppendLine(TerseDump() + ":"); - var indent = new string(' ', currentNestDepth * SPACES_PER_INDENT); - for (int i = 0; i < internalList.Count; ++i) + catch { - contents.AppendLine(string.Format("{0}[{1,2}]= {2}", indent, i, internalList[i])); + throw new KOSException("The index must be an integer number"); } - --currentNestDepth; - return contents.ToString(); - } - - public static ListValue CreateList(IEnumerable list) - { - return new ListValue(list.Cast()); + Collection[idx] = (T)value; } - public object GetIndex(int index) + public void SetIndex(int index, Structure value) { - return internalList[index]; + Collection[index] = (T)value; } - public void SetIndex(int index, object value) + private StringValue Join(StringValue separator) { - internalList[index] = (T)value; + return string.Join(separator, Collection.Select(i => i.ToString()).ToArray()); } } - public class ListValue : ListValue + [kOS.Safe.Utilities.KOSNomenclature("List", KOSToCSharp = false)] // one-way because the generic templated ListValue is the canonical one. + public class ListValue : ListValue { public ListValue() { InitializeSuffixes(); } - public ListValue(IEnumerable toCopy) + public ListValue(IEnumerable toCopy) : base(toCopy) { InitializeSuffixes(); @@ -299,7 +170,7 @@ private void InitializeSuffixes() public new static ListValue CreateList(IEnumerable toCopy) { - return new ListValue(toCopy.Cast()); + return new ListValue(toCopy.Select(x => FromPrimitiveWithAssert(x))); } } } \ No newline at end of file diff --git a/src/kOS.Safe/Encapsulation/PIDLoop.cs b/src/kOS.Safe/Encapsulation/PIDLoop.cs new file mode 100644 index 000000000..ee97329ac --- /dev/null +++ b/src/kOS.Safe/Encapsulation/PIDLoop.cs @@ -0,0 +1,215 @@ +using System; +using kOS.Safe.Encapsulation.Suffixes; + +namespace kOS.Safe.Encapsulation +{ + [kOS.Safe.Utilities.KOSNomenclature("PIDLoop")] + public class PIDLoop : Structure + { + public static PIDLoop DeepCopy(PIDLoop source) + { + PIDLoop newLoop = new PIDLoop + { + LastSampleTime = source.LastSampleTime, + Kp = source.Kp, + Ki = source.Ki, + Kd = source.Kd, + Input = source.Input, + Setpoint = source.Setpoint, + Error = source.Error, + Output = source.Output, + MaxOutput = source.MaxOutput, + ErrorSum = source.ErrorSum, + PTerm = source.PTerm, + ITerm = source.ITerm, + DTerm = source.DTerm, + ExtraUnwind = source.ExtraUnwind, + ChangeRate = source.ChangeRate, + unWinding = source.unWinding + }; + return newLoop; + } + + public double LastSampleTime { get; set; } + + public double Kp { get; set; } + + public double Ki { get; set; } + + public double Kd { get; set; } + + public double Input { get; set; } + + public double Setpoint { get; set; } + + public double Error { get; set; } + + public double Output { get; set; } + + public double MaxOutput { get; set; } + + public double MinOutput { get; set; } + + public double ErrorSum { get; set; } + + public double PTerm { get; set; } + + public double ITerm { get; set; } + + public double DTerm { get; set; } + + public bool ExtraUnwind { get; set; } + + public double ChangeRate { get; set; } + + private bool unWinding; + + public PIDLoop() + : this(1, 0, 0) + { + } + + public PIDLoop(double kp, double ki, double kd, double maxoutput = double.MaxValue, double minoutput = double.MinValue, bool extraUnwind = false) + { + LastSampleTime = double.MaxValue; + Kp = kp; + Ki = ki; + Kd = kd; + Input = 0; + Setpoint = 0; + Error = 0; + Output = 0; + MaxOutput = maxoutput; + MinOutput = minoutput; + ErrorSum = 0; + PTerm = 0; + ITerm = 0; + DTerm = 0; + ExtraUnwind = extraUnwind; + InitializeSuffixes(); + } + + public void InitializeSuffixes() + { + AddSuffix("LASTSAMPLETIME", new Suffix(() => LastSampleTime)); + AddSuffix("KP", new SetSuffix(() => Kp, value => Kp = value)); + AddSuffix("KI", new SetSuffix(() => Ki, value => Ki = value)); + AddSuffix("KD", new SetSuffix(() => Kd, value => Kd = value)); + AddSuffix("INPUT", new Suffix(() => Input)); + AddSuffix("SETPOINT", new SetSuffix(() => Setpoint, value => Setpoint = value)); + AddSuffix("ERROR", new Suffix(() => Error)); + AddSuffix("OUTPUT", new Suffix(() => Output)); + AddSuffix("MAXOUTPUT", new SetSuffix(() => MaxOutput, value => MaxOutput = value)); + AddSuffix("MINOUTPUT", new SetSuffix(() => MinOutput, value => MinOutput = value)); + AddSuffix("ERRORSUM", new Suffix(() => ErrorSum)); + AddSuffix("PTERM", new Suffix(() => PTerm)); + AddSuffix("ITERM", new Suffix(() => ITerm)); + AddSuffix("DTERM", new Suffix(() => DTerm)); + AddSuffix("CHANGERATE", new Suffix(() => ChangeRate)); + AddSuffix("RESET", new NoArgsVoidSuffix(ResetI)); + AddSuffix("UPDATE", new TwoArgsSuffix(Update)); + } + + public double Update(double sampleTime, double input, double setpoint, double minOutput, double maxOutput) + { + MaxOutput = maxOutput; + MinOutput = minOutput; + Setpoint = setpoint; + return Update(sampleTime, input); + } + + public double Update(double sampleTime, double input, double setpoint, double maxOutput) + { + return Update(sampleTime, input, setpoint, -maxOutput, maxOutput); + } + + public ScalarValue Update(ScalarValue sampleTime, ScalarValue input) + { + double error = Setpoint - input; + double pTerm = error * Kp; + double iTerm = 0; + double dTerm = 0; + if (LastSampleTime < sampleTime) + { + double dt = sampleTime - LastSampleTime; + if (dt < 1) + { + if (Ki != 0) + { + if (ExtraUnwind) + { + if (Math.Sign(error) != Math.Sign(ErrorSum)) + { + if (!unWinding) + { + Ki *= 2; + unWinding = true; + } + } + else if (unWinding) + { + Ki /= 2; + unWinding = false; + } + } + iTerm = ITerm + error * dt * Ki; + } + ChangeRate = (input - Input) / dt; + if (Kd != 0) + { + dTerm = -ChangeRate * Kd; + } + } + } + Output = pTerm + iTerm + dTerm; + if (Output > MaxOutput) + { + Output = MaxOutput; + if (Ki != 0 && LastSampleTime < sampleTime) + { + iTerm = Output - Math.Min(pTerm + dTerm, MaxOutput); + } + } + if (Output < MinOutput) + { + Output = MinOutput; + if (Ki != 0 && LastSampleTime < sampleTime) + { + iTerm = Output - Math.Max(pTerm + dTerm, MinOutput); + } + } + LastSampleTime = sampleTime; + Input = input; + Error = error; + PTerm = pTerm; + ITerm = iTerm; + DTerm = dTerm; + if (Ki != 0) ErrorSum = iTerm / Ki; + else ErrorSum = 0; + return Output; + } + + public void ResetI() + { + ErrorSum = 0; + LastSampleTime = double.MaxValue; + } + + public override string ToString() + { + return string.Format("PIDLoop(Kp:{0}, Ki:{1}, Kd:{2}, Setpoint:{3}, Error:{4}, Output:{5})", + Kp, Ki, Kd, Setpoint, Error, Output); + } + + public string ToCSVString() + { + return string.Format("{0},{1},{2},{3},{4},{5},{6},{7}", + LastSampleTime, Error, ErrorSum, Output, Kp, Ki, Kd, MaxOutput); + } + + public string ConstrutorString() + { + return string.Format("pidloop({0}, {1}, {2}, {3}, {4})", Ki, Kp, Kd, MaxOutput, ExtraUnwind); + } + } +} \ No newline at end of file diff --git a/src/kOS.Safe/Encapsulation/Part/IModuleEngine.cs b/src/kOS.Safe/Encapsulation/Part/IModuleEngine.cs index 52f9f6b5f..2535ef977 100644 --- a/src/kOS.Safe/Encapsulation/Part/IModuleEngine.cs +++ b/src/kOS.Safe/Encapsulation/Part/IModuleEngine.cs @@ -6,6 +6,7 @@ public interface IModuleEngine void Shutdown(); float ThrustPercentage { get; set; } float MaxThrust { get; } + float AvailableThrust { get; } float FinalThrust { get; } float FuelFlow { get; } float SpecificImpulse { get; } @@ -16,5 +17,8 @@ public interface IModuleEngine bool AllowRestart { get; } bool AllowShutdown { get; } bool ThrottleLock { get; } + float IspAtAtm(double atmPressure); + float MaxThrustAtAtm(double atmPressure); + float AvailableThrustAtAtm(double atmPressure); } } \ No newline at end of file diff --git a/src/kOS.Safe/Encapsulation/QueueValue.cs b/src/kOS.Safe/Encapsulation/QueueValue.cs new file mode 100644 index 000000000..be73a3a17 --- /dev/null +++ b/src/kOS.Safe/Encapsulation/QueueValue.cs @@ -0,0 +1,95 @@ +using System.Collections.Generic; +using System.Linq; +using kOS.Safe.Encapsulation.Suffixes; +using kOS.Safe.Serialization; + +namespace kOS.Safe.Encapsulation +{ + [kOS.Safe.Utilities.KOSNomenclature("Queue")] + public class QueueValue : EnumerableValue> + where T : Structure + { + public QueueValue() : this(new Queue()) + { + } + + public QueueValue(IEnumerable queueValue) : base("QUEUE", new Queue(queueValue)) + { + QueueInitializeSuffixes(); + } + + public T Pop() + { + return InnerEnumerable.Dequeue(); + } + + public void Push(T val) + { + InnerEnumerable.Enqueue(val); + } + + public override Dump Dump() + { + var result = new DumpWithHeader + { + Header = "QUEUE of " + InnerEnumerable.Count() + " items:" + }; + + result.Add(kOS.Safe.Dump.Items, InnerEnumerable.Cast().ToList()); + + return result; + } + + public override void LoadDump(Dump dump) + { + InnerEnumerable.Clear(); + + List values = (List)dump[kOS.Safe.Dump.Items]; + + foreach (object item in values) + { + InnerEnumerable.Enqueue((T)FromPrimitive(item)); + } + } + + private void QueueInitializeSuffixes() + { + AddSuffix("COPY", new NoArgsSuffix> (() => new QueueValue(this))); + + AddSuffix("PUSH", new OneArgsSuffix (toPush => InnerEnumerable.Enqueue(toPush))); + AddSuffix("POP", new NoArgsSuffix (() => InnerEnumerable.Dequeue())); + AddSuffix("PEEK", new NoArgsSuffix (() => InnerEnumerable.Peek())); + AddSuffix("CLEAR", new NoArgsVoidSuffix (() => InnerEnumerable.Clear())); + } + + public static QueueValue CreateQueue(IEnumerable list) + { + return new QueueValue(list.Cast()); + } + } + + [kOS.Safe.Utilities.KOSNomenclature("Queue", KOSToCSharp = false)] // one-way because the generic templated QueueValue is the canonical one. + public class QueueValue : QueueValue + { + public QueueValue() + { + InitializeSuffixes(); + } + + public QueueValue(IEnumerable toCopy) + : base(toCopy) + { + InitializeSuffixes(); + } + + private void InitializeSuffixes() + { + AddSuffix("COPY", new NoArgsSuffix(() => new QueueValue(this))); + } + + public new static QueueValue CreateQueue(IEnumerable toCopy) + { + return new QueueValue(toCopy.Select(x => FromPrimitiveWithAssert(x))); + } + } +} \ No newline at end of file diff --git a/src/kOS.Safe/Encapsulation/RangeValue.cs b/src/kOS.Safe/Encapsulation/RangeValue.cs new file mode 100644 index 000000000..6ed62bef6 --- /dev/null +++ b/src/kOS.Safe/Encapsulation/RangeValue.cs @@ -0,0 +1,117 @@ +using kOS.Safe.Encapsulation; +using kOS.Safe.Encapsulation.Suffixes; +using kOS.Safe.Exceptions; +using kOS.Safe.Serialization; +using System; +using System.Collections.Generic; + +namespace kOS.Safe +{ + [kOS.Safe.Utilities.KOSNomenclature("Range")] + public class RangeValue : EnumerableValue + { + private const string DumpStart = "start"; + private const string DumpStop = "stop"; + private const string DumpStep = "step"; + private const string Label = "RANGE"; + + public static readonly int DEFAULT_START = 0; + public static readonly int DEFAULT_STOP = 1; + public static readonly int DEFAULT_STEP = 1; + + public RangeValue() + : this(DEFAULT_STOP) + { + } + + public RangeValue(int stop) + : this(DEFAULT_START, stop) + { + } + + public RangeValue(int start, int stop) + : this(start, stop, DEFAULT_STEP) + { + } + + public RangeValue(int start, int stop, int step) + : base(Label, new Range(start, stop, step)) + { + InitializeRangeSuffixes(); + + if (step < 1) + { + throw new KOSException("Step must be a positive integer"); + } + } + + private void InitializeRangeSuffixes() + { + AddSuffix("START", new NoArgsSuffix(() => InnerEnumerable.Start)); + AddSuffix("STOP", new NoArgsSuffix(() => InnerEnumerable.Stop)); + AddSuffix("STEP", new NoArgsSuffix(() => InnerEnumerable.Step)); + } + + public override void LoadDump(Dump dump) + { + InnerEnumerable.Stop = Convert.ToInt32(dump[DumpStop]); + InnerEnumerable.Start = Convert.ToInt32(dump[DumpStart]); + InnerEnumerable.Step = Convert.ToInt32(dump[DumpStep]); + } + + public override Dump Dump() + { + DumpWithHeader result = new DumpWithHeader(); + + result.Header = "RANGE"; + + result.Add(DumpStop, InnerEnumerable.Stop); + result.Add(DumpStart, InnerEnumerable.Start); + result.Add(DumpStep, InnerEnumerable.Step); + + return result; + } + + public override string ToString() + { + return "RANGE(" + InnerEnumerable.Start + ", " + InnerEnumerable.Stop + ", " + InnerEnumerable.Step + ")"; + } + } + + public class Range : IEnumerable + { + public int Start { get; set; } + public int Stop { get; set; } + public int Step { get; set; } + + public Range(int start, int stop, int step) + { + Start = start; + Stop = stop; + Step = step; + } + + IEnumerator IEnumerable.GetEnumerator() + { + if (Start < Stop) + { + for (int i = Start; i < Stop; i += Step) + { + yield return i; + } + } + else + { + for (int i = Start; i > Stop; i -= Step) + { + yield return i; + } + } + } + + public System.Collections.IEnumerator GetEnumerator() + { + return GetEnumerator(); + } + } +} \ No newline at end of file diff --git a/src/kOS.Safe/Encapsulation/ScalarDoubleValue.cs b/src/kOS.Safe/Encapsulation/ScalarDoubleValue.cs new file mode 100644 index 000000000..d4d884c3c --- /dev/null +++ b/src/kOS.Safe/Encapsulation/ScalarDoubleValue.cs @@ -0,0 +1,38 @@ +namespace kOS.Safe.Encapsulation +{ + [kOS.Safe.Utilities.KOSNomenclature("Scalar", KOSToCSharp = false)] + public class ScalarDoubleValue : ScalarValue + { + public static ScalarDoubleValue Zero = new ScalarDoubleValue(0); + + public override bool IsDouble + { + get { return true; } + } + + public override bool IsInt + { + get { return false; } + } + + public ScalarDoubleValue(double value) + { + Value = value; + } + + public static implicit operator ScalarDoubleValue(double val) + { + return new ScalarDoubleValue(val); + } + + public static ScalarDoubleValue MinValue() + { + return new ScalarDoubleValue(double.MinValue); + } + + public static ScalarDoubleValue MaxValue() + { + return new ScalarDoubleValue(double.MaxValue); + } + } +} \ No newline at end of file diff --git a/src/kOS.Safe/Encapsulation/ScalarIntValue.cs b/src/kOS.Safe/Encapsulation/ScalarIntValue.cs new file mode 100644 index 000000000..8c41128fb --- /dev/null +++ b/src/kOS.Safe/Encapsulation/ScalarIntValue.cs @@ -0,0 +1,42 @@ +namespace kOS.Safe.Encapsulation +{ + [kOS.Safe.Utilities.KOSNomenclature("Scalar", KOSToCSharp = false)] + public class ScalarIntValue : ScalarValue + { + // those are handy especially in tests + public static ScalarIntValue Zero = new ScalarIntValue(0); + public static ScalarIntValue One = new ScalarIntValue(1); + public static ScalarIntValue Two = new ScalarIntValue(2); + + public override bool IsDouble + { + get { return false; } + } + + public override bool IsInt + { + get { return true; } + } + + public ScalarIntValue(int value) + { + Value = value; + } + + public static implicit operator ScalarIntValue(int val) + { + return new ScalarIntValue(val); + } + + public static ScalarIntValue MinValue() + { + return new ScalarIntValue(int.MinValue); + } + + public static ScalarIntValue MaxValue() + { + return new ScalarIntValue(int.MaxValue); + } + + } +} \ No newline at end of file diff --git a/src/kOS.Safe/Encapsulation/ScalarValue.cs b/src/kOS.Safe/Encapsulation/ScalarValue.cs new file mode 100644 index 000000000..fd3096b71 --- /dev/null +++ b/src/kOS.Safe/Encapsulation/ScalarValue.cs @@ -0,0 +1,440 @@ +using kOS.Safe.Exceptions; +using System; +using System.Reflection; + +namespace kOS.Safe.Encapsulation +{ + [kOS.Safe.Utilities.KOSNomenclature("Scalar")] + abstract public class ScalarValue : Structure, IConvertible, ISerializableValue + { + abstract public bool IsInt { get; } + + abstract public bool IsDouble { get; } + + public bool IsValid + { + get + { + if (IsInt) return true; + if (IsDouble) + { + double d = GetDoubleValue(); + if (double.IsInfinity(d) || double.IsNaN(d)) return false; + return true; + } + return false; + } + } + + public object Value { get; protected set; } + + protected ScalarValue() + { + InitializeSuffixes(); + } + + public void InitializeSuffixes() + { + // TODO: Commented suffixes until the introduction of kOS types to the user. + //AddSuffix("ISINTEGER", new Suffix(() => IsInt)); + //AddSuffix("ISVALID", new Suffix(() => IsValid)); + } + + public static ScalarValue Create(object value) + { + if (value is float) + value = Convert.ToDouble(value); + if (value is double) + { + bool inBounds = int.MinValue < (double)value && (double)value < int.MaxValue; + if (inBounds && !double.IsNaN((double)value)) + { + // Convert the double to an int, and check and see if they are still equal. + // if so, treat the double as if it was an int. + int intPart = Convert.ToInt32(value); + + // ReSharper disable once CompareOfFloatsByEqualityOperator + if ((double)value == intPart) + { + return new ScalarIntValue(intPart); + } + } + return new ScalarDoubleValue((double)value); + } + + if (value is int) + { + return new ScalarIntValue((int)value); + } + + var scalarValue = value as ScalarValue; + if (scalarValue != null) + { + return Create(scalarValue.Value); + } + + throw new KOSException(string.Format("Failed to set scalar value. Passed type {0}, expected Double or Int", value.GetType().Name)); + } + + public int GetIntValue() + { + return Convert.ToInt32(Value); + } + + public double GetDoubleValue() + { + return Convert.ToDouble(Value); + } + + public override string ToString() + { + if (IsInt) return GetIntValue().ToString(); + else if (IsDouble) return GetDoubleValue().ToString(); + return "NaN"; + } + + public override bool Equals(object obj) + { + if (obj == null) return false; + var val = obj as ScalarValue; + if (val != null) + { + if (IsInt && val.IsDouble) + { + return false; + } + if (IsInt && val.IsInt) + { + return GetIntValue() == val.GetIntValue(); + } + // ReSharper disable once CompareOfFloatsByEqualityOperator + return GetDoubleValue() == val.GetDoubleValue(); + } + else + { + const BindingFlags FLAGS = BindingFlags.ExactBinding | BindingFlags.Static | BindingFlags.Public; + MethodInfo converter = typeof(ScalarValue).GetMethod("op_Implicit", FLAGS, null, new[] { obj.GetType() }, null); + if (converter != null) + { + val = (ScalarValue)converter.Invoke(null, new[] { obj }); + if (Value == val.Value) return true; + } + } + return false; + } + + public static bool NullSafeEquals(object obj1, object obj2) + { + if (obj1 == null) + { + if (obj2 == null) return true; + return false; + } + if (obj2 == null) return false; + ScalarValue val1 = Create(obj1); + return val1.Equals(obj2); + } + + public override int GetHashCode() + { + return Value.GetHashCode(); + } + + public static ScalarValue Add(ScalarValue val1, ScalarValue val2) + { + if (val1.IsInt && val2.IsInt) + { + return Create(val1.GetIntValue() + val2.GetIntValue()); + } + return Create(val1.GetDoubleValue() + val2.GetDoubleValue()); + } + + public static ScalarValue Subtract(ScalarValue val1, ScalarValue val2) + { + if (val1.IsInt && val2.IsInt) + { + return Create(val1.GetIntValue() - val2.GetIntValue()); + } + return Create(val1.GetDoubleValue() - val2.GetDoubleValue()); + } + + public static ScalarValue Multiply(ScalarValue val1, ScalarValue val2) + { + if (val1.IsInt && val2.IsInt) + { + return Create(val1.GetIntValue() * val2.GetIntValue()); + } + return Create(val1.GetDoubleValue() * val2.GetDoubleValue()); + } + + public static ScalarValue Divide(ScalarValue val1, ScalarValue val2) + { + return Create(val1.GetDoubleValue() / val2.GetDoubleValue()); + } + + public static ScalarValue Modulus(ScalarValue val1, ScalarValue val2) + { + if (val1.IsInt && val2.IsInt) + { + return Create(val1.GetIntValue() % val2.GetIntValue()); + } + return Create(val1.GetDoubleValue() % val2.GetDoubleValue()); + } + + public static ScalarValue Power(ScalarValue val1, ScalarValue val2) + { + return Create(Math.Pow(val1.GetDoubleValue(), val2.GetDoubleValue())); + } + + public static bool GreaterThan(ScalarValue val1, ScalarValue val2) + { + if (val1.IsInt && val2.IsInt) + { + return val1.GetIntValue() > val2.GetIntValue(); + } + return val1.GetDoubleValue() > val2.GetDoubleValue(); + } + + public static bool LessThan(ScalarValue val1, ScalarValue val2) + { + if (val1.IsInt && val2.IsInt) + { + return val1.GetIntValue() < val2.GetIntValue(); + } + return val1.GetDoubleValue() < val2.GetDoubleValue(); + } + + public static ScalarValue Max(ScalarValue val1, ScalarValue val2) + { + if (val1.IsInt && val2.IsInt) + { + return Create(Math.Max(val1.GetIntValue(), val2.GetIntValue())); + } + return Create(Math.Max(val1.GetDoubleValue(), val2.GetDoubleValue())); + } + + public static ScalarValue Min(ScalarValue val1, ScalarValue val2) + { + if (val1.IsInt && val2.IsInt) + { + return new ScalarIntValue(Math.Min(val1.GetIntValue(), val2.GetIntValue())); + } + return Create(Math.Min(val1.GetDoubleValue(), val2.GetDoubleValue())); + } + + public static ScalarValue Abs(ScalarValue val) + { + if (val.IsInt) + { + return new ScalarIntValue(Math.Abs(val.GetIntValue())); + } + return Create(Math.Abs(val.GetDoubleValue())); + } + + public static ScalarValue operator +(ScalarValue val1, ScalarValue val2) + { + return Add(val1, val2); + } + + public static ScalarValue operator ++(ScalarValue val) + { + return Add(val, 1); + } + + public static ScalarValue operator -(ScalarValue val1, ScalarValue val2) + { + return Subtract(val1, val2); + } + + public static ScalarValue operator --(ScalarValue val) + { + return Subtract(val, 1); + } + + public static ScalarValue operator *(ScalarValue val1, ScalarValue val2) + { + return Multiply(val1, val2); + } + + public static ScalarValue operator +(ScalarValue val) + { + return Create(val.Value); + } + + public static ScalarValue operator -(ScalarValue val) + { + return Multiply(val, -1); + } + + public static ScalarValue operator /(ScalarValue val1, ScalarValue val2) + { + return Divide(val1, val2); + } + + public static ScalarValue operator %(ScalarValue val1, ScalarValue val2) + { + return Modulus(val1, val2); + } + + public static ScalarValue operator ^(ScalarValue val1, ScalarValue val2) + { + return Power(val1, val2); + } + + public static bool operator ==(ScalarValue val1, ScalarValue val2) + { + return NullSafeEquals(val1, val2); + } + + public static bool operator !=(ScalarValue val1, ScalarValue val2) + { + return !NullSafeEquals(val1, val2); + } + + public static bool operator >(ScalarValue val1, ScalarValue val2) + { + return GreaterThan(val1, val2); + } + + public static bool operator <(ScalarValue val1, ScalarValue val2) + { + return LessThan(val1, val2); + } + + public static bool operator >=(ScalarValue val1, ScalarValue val2) + { + return GreaterThan(val1, val2) || val1.Equals(val2); + } + + public static bool operator <=(ScalarValue val1, ScalarValue val2) + { + return LessThan(val1, val2) || val1.Equals(val2); + } + + public static implicit operator ScalarValue(int val) + { + return Create(val); + } + + public static implicit operator ScalarValue(double val) + { + return Create(val); + } + + public static implicit operator int(ScalarValue val) + { + return val.GetIntValue(); + } + + public static implicit operator double(ScalarValue val) + { + return val.GetDoubleValue(); + } + + public static implicit operator float(ScalarValue val) + { + return (float)val.GetDoubleValue(); + } + + TypeCode IConvertible.GetTypeCode() + { + return TypeCode.Object; + } + + bool IConvertible.ToBoolean(IFormatProvider provider) + { + if (GetIntValue() == 0) return false; + return true; + } + + byte IConvertible.ToByte(IFormatProvider provider) + { + throw new KOSCastException(typeof(ScalarValue), typeof(byte)); + } + + char IConvertible.ToChar(IFormatProvider provider) + { + throw new KOSCastException(typeof(ScalarValue), typeof(char)); + } + + DateTime IConvertible.ToDateTime(IFormatProvider provider) + { + throw new KOSCastException(typeof(ScalarValue), typeof(DateTime)); + } + + decimal IConvertible.ToDecimal(IFormatProvider provider) + { + return Convert.ToDecimal(GetDoubleValue()); + } + + double IConvertible.ToDouble(IFormatProvider provider) + { + return GetDoubleValue(); + } + + short IConvertible.ToInt16(IFormatProvider provider) + { + return Convert.ToInt16(GetIntValue()); + } + + int IConvertible.ToInt32(IFormatProvider provider) + { + return GetIntValue(); + } + + long IConvertible.ToInt64(IFormatProvider provider) + { + return Convert.ToInt64(GetIntValue()); + } + + sbyte IConvertible.ToSByte(IFormatProvider provider) + { + throw new KOSCastException(typeof(ScalarValue), typeof(sbyte)); + } + + float IConvertible.ToSingle(IFormatProvider provider) + { + return Convert.ToSingle(GetDoubleValue()); + } + + string IConvertible.ToString(IFormatProvider provider) + { + return ToString(); + } + + object IConvertible.ToType(Type conversionType, IFormatProvider provider) + { + // These can't be handled by ScalarValue.Create() because they MUST coerce into the asked-for type, + // ignoring the logic used in Create() to vary the type depending on content. + if (conversionType == GetType()) + return this; // no conversion needed + else if (conversionType == typeof(ScalarValue)) + return this; // no conversion needed + else if (conversionType == typeof(ScalarDoubleValue)) + return new ScalarDoubleValue(GetDoubleValue()); + else if (conversionType == typeof(ScalarIntValue)) + return new ScalarIntValue(GetIntValue()); + else if (conversionType == typeof(BooleanValue)) + return new BooleanValue(GetIntValue() == 0 ? false : true); + else if (conversionType.IsSubclassOf(typeof(Structure))) + throw new KOSCastException(typeof(ScalarValue), conversionType); + else + return Convert.ChangeType(GetDoubleValue(), conversionType); + } + + ushort IConvertible.ToUInt16(IFormatProvider provider) + { + return Convert.ToUInt16(GetIntValue()); + } + + uint IConvertible.ToUInt32(IFormatProvider provider) + { + return Convert.ToUInt32(GetIntValue()); + } + + ulong IConvertible.ToUInt64(IFormatProvider provider) + { + return Convert.ToUInt64(GetIntValue()); + } + } +} \ No newline at end of file diff --git a/src/kOS.Safe/Encapsulation/StackValue.cs b/src/kOS.Safe/Encapsulation/StackValue.cs new file mode 100644 index 000000000..0030c58ce --- /dev/null +++ b/src/kOS.Safe/Encapsulation/StackValue.cs @@ -0,0 +1,102 @@ +using System.Collections.Generic; +using System.Linq; +using kOS.Safe.Encapsulation.Suffixes; +using kOS.Safe.Serialization; + +namespace kOS.Safe.Encapsulation +{ + [kOS.Safe.Utilities.KOSNomenclature("Stack")] + public class StackValue : EnumerableValue> + where T : Structure + { + public StackValue() : this(new Stack()) + { + } + + public StackValue(IEnumerable stackValue) : base("STACK", new Stack(stackValue)) + { + StackInitializeSuffixes(); + } + + public override IEnumerator GetEnumerator() + { + return InnerEnumerable.Reverse().GetEnumerator(); + } + + public T Pop() + { + return InnerEnumerable.Pop(); + } + + public void Push(T val) + { + InnerEnumerable.Push(val); + } + + public override Dump Dump() + { + var result = new DumpWithHeader + { + Header = "STACK of " + InnerEnumerable.Count() + " items:" + }; + + result.Add(kOS.Safe.Dump.Items, InnerEnumerable.Cast().ToList()); + + return result; + } + + public override void LoadDump(Dump dump) + { + InnerEnumerable.Clear(); + + List values = ((List)dump[kOS.Safe.Dump.Items]); + + values.Reverse(); + + foreach (object item in values) + { + InnerEnumerable.Push((T)Structure.FromPrimitive(item)); + } + } + + + private void StackInitializeSuffixes() + { + AddSuffix("COPY", new NoArgsSuffix> (() => new StackValue(this))); + AddSuffix("PUSH", new OneArgsSuffix (toPush => InnerEnumerable.Push(toPush))); + AddSuffix("POP", new NoArgsSuffix (() => InnerEnumerable.Pop())); + AddSuffix("PEEK", new NoArgsSuffix (() => InnerEnumerable.Peek())); + AddSuffix("CLEAR", new NoArgsVoidSuffix (() => InnerEnumerable.Clear())); + } + + public static StackValue CreateStack(IEnumerable list) + { + return new StackValue(list.Cast()); + } + } + + [kOS.Safe.Utilities.KOSNomenclature("Stack", KOSToCSharp = false)] // one-way because the generic templated StackValue is the canonical one. + public class StackValue : StackValue + { + public StackValue() + { + InitializeSuffixes(); + } + + public StackValue(IEnumerable toCopy) + : base(toCopy) + { + InitializeSuffixes(); + } + + private void InitializeSuffixes() + { + AddSuffix("COPY", new NoArgsSuffix(() => new StackValue(this))); + } + + public new static StackValue CreateStack(IEnumerable toCopy) + { + return new StackValue(toCopy.Select(x => Structure.FromPrimitiveWithAssert(x))); + } + } +} \ No newline at end of file diff --git a/src/kOS.Safe/Encapsulation/StringValue.cs b/src/kOS.Safe/Encapsulation/StringValue.cs new file mode 100644 index 000000000..1a2efb505 --- /dev/null +++ b/src/kOS.Safe/Encapsulation/StringValue.cs @@ -0,0 +1,394 @@ +using System; +using System.Globalization; +using System.Text.RegularExpressions; +using kOS.Safe.Encapsulation.Suffixes; +using kOS.Safe.Exceptions; +using kOS.Safe.Utilities; +using System.Collections.Generic; +using System.Collections; + +namespace kOS.Safe.Encapsulation +{ + /// + /// The class is a simple wrapper around the string class to + /// implement the Structure and IIndexable interface on + /// strings. Currently, strings are only boxed with this + /// class temporarily when suffix/indexing support is + /// necessary. + /// + [KOSNomenclature("String")] + public class StringValue : Structure, IIndexable, IConvertible, ISerializableValue, IEnumerable + { + private readonly string internalString; + + public StringValue(): + this (string.Empty) + { + } + + public StringValue(string stringValue) + { + internalString = stringValue; + StringInitializeSuffixes(); + } + + public StringValue(StringValue stringValue) + { + internalString = stringValue.ToString(); + StringInitializeSuffixes(); + } + + public StringValue(char ch) + { + internalString = new string(new char[] {ch}); + StringInitializeSuffixes(); + } + + public ScalarValue Length + { + get { return internalString.Length; } + } + + public string Substring(ScalarValue start, ScalarValue count) + { + return internalString.Substring(start, count); + } + + public bool Contains(string s) + { + return internalString.IndexOf(s, StringComparison.OrdinalIgnoreCase) >= 0; + } + + public bool EndsWith(string s) + { + return internalString.EndsWith(s, StringComparison.OrdinalIgnoreCase); + } + + public ScalarValue IndexOf(string s) + { + return internalString.IndexOf(s, StringComparison.OrdinalIgnoreCase); + } + + // IndexOf with a start position. + // This was named FindAt because IndexOfAt made little sense. + public ScalarValue FindAt(string s, ScalarValue start) + { + return internalString.IndexOf(s, start, StringComparison.OrdinalIgnoreCase); + } + + public string Insert(ScalarValue location, string s) + { + return internalString.Insert(location, s); + } + + public int LastIndexOf(string s) + { + return internalString.LastIndexOf(s, StringComparison.OrdinalIgnoreCase); + } + + public int FindLastAt(string s, int start) + { + return internalString.LastIndexOf(s, start, StringComparison.OrdinalIgnoreCase); + } + + public string PadLeft(int width) + { + return internalString.PadLeft(width); + } + + public string PadRight(int width) + { + return internalString.PadRight(width); + } + + public string Remove(int start, int count) + { + return internalString.Remove(start, count); + } + + public string Replace(string oldString, string newString) + { + return Regex.Replace(internalString, Regex.Escape(oldString), newString, RegexOptions.IgnoreCase); + } + + public string ToLower() + { + return internalString.ToLower(); + } + + public string ToUpper() + { + return internalString.ToUpper(); + } + + public bool StartsWith(string s) + { + return internalString.StartsWith(s, StringComparison.OrdinalIgnoreCase); + } + + public string Trim() + { + return internalString.Trim(); + } + + public string TrimEnd() + { + return internalString.TrimEnd(); + } + + public string TrimStart() + { + return internalString.TrimStart(); + } + + public Structure GetIndex(int index) + { + return new StringValue(internalString[index]); + } + + public Structure GetIndex(Structure index) + { + if (index is ScalarValue) + { + int i = Convert.ToInt32(index); // allow expressions like (1.0) to be indexes + return new StringValue(internalString[i]); + } + throw new KOSCastException(index.GetType(), typeof(ScalarValue)); + + } + + // Required by the interface but unimplemented, because strings are immutable. + public void SetIndex(Structure index, Structure value) + { + throw new KOSException("String are immutable; they can not be modified using the syntax \"SET string[1] TO 'a'\", etc."); + } + // Required by the interface but unimplemented, because strings are immutable. + public void SetIndex(int index, Structure value) + { + throw new KOSException("String are immutable; they can not be modified using the syntax \"SET string[1] TO 'a'\", etc."); + } + + public IEnumerator GetEnumerator () + { + for (int i = 0; i < internalString.Length; i++) { + yield return internalString[i].ToString(); + } + + } + + System.Collections.IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + + // As the regular Split, except returning a ListValue rather than an array. + public ListValue SplitToList(string separator) + { + string[] split = Regex.Split(internalString, Regex.Escape(separator), RegexOptions.IgnoreCase); + ListValue returnList = new ListValue(); + foreach (string s in split) + returnList.Add(new StringValue(s)); + return returnList; + } + + private void StringInitializeSuffixes() + { + AddSuffix("LENGTH", new NoArgsSuffix( () => Length)); + AddSuffix("SUBSTRING", new TwoArgsSuffix( (one, two) => Substring(one, two))); + AddSuffix("CONTAINS", new OneArgsSuffix( one => Contains(one))); + AddSuffix("ENDSWITH", new OneArgsSuffix( one => EndsWith(one))); + AddSuffix("FINDAT", new TwoArgsSuffix( (one, two) => FindAt(one, two))); + AddSuffix("INSERT", new TwoArgsSuffix( (one, two) => Insert(one, two))); + AddSuffix("FINDLASTAT", new TwoArgsSuffix( (one, two) => FindLastAt(one, two))); + AddSuffix("PADLEFT", new OneArgsSuffix( one => PadLeft(one))); + AddSuffix("PADRIGHT", new OneArgsSuffix( one => PadRight(one))); + AddSuffix("REMOVE", new TwoArgsSuffix( (one, two) => Remove(one, two))); + AddSuffix("REPLACE", new TwoArgsSuffix( (one, two) => Replace(one, two))); + AddSuffix("SPLIT", new OneArgsSuffix, StringValue>( one => SplitToList(one))); + AddSuffix("STARTSWITH", new OneArgsSuffix( one => StartsWith(one))); + AddSuffix("TOLOWER", new NoArgsSuffix(() => ToLower())); + AddSuffix("TOUPPER", new NoArgsSuffix(() => ToUpper())); + AddSuffix("TRIM", new NoArgsSuffix(() => Trim())); + AddSuffix("TRIMEND", new NoArgsSuffix(() => TrimEnd())); + AddSuffix("TRIMSTART", new NoArgsSuffix(() => TrimStart())); + + // Aliased "IndexOf" with "Find" to match "FindAt" (since IndexOfAt doesn't make sense, but I wanted to stick with common/C# names when possible) + AddSuffix(new[] { "INDEXOF", "FIND" }, new OneArgsSuffix ( one => IndexOf(one))); + AddSuffix(new[] { "LASTINDEXOF", "FINDLAST" }, new OneArgsSuffix ( s => LastIndexOf(s))); + + } + + public static bool operator ==(StringValue val1, StringValue val2) + { + if ((object)val1 == null) return ((object)val2 == null); + return val1.Equals(val2); + } + + public static bool operator !=(StringValue val1, StringValue val2) + { + return !(val1 == val2); + } + + public static bool operator >(StringValue val1, StringValue val2) + { + int compareNum = string.Compare(val1, val2, StringComparison.OrdinalIgnoreCase); + return compareNum > 0; + } + + public static bool operator <(StringValue val1, StringValue val2) + { + int compareNum = string.Compare(val1, val2, StringComparison.OrdinalIgnoreCase); + return compareNum < 0; + } + + public static bool operator >=(StringValue val1, StringValue val2) + { + int compareNum = string.Compare(val1, val2, StringComparison.OrdinalIgnoreCase); + return compareNum >= 0; + } + + public static bool operator <=(StringValue val1, StringValue val2) + { + int compareNum = string.Compare(val1, val2, StringComparison.OrdinalIgnoreCase); + return compareNum <= 0; + } + + // Implicitly converts to a string (i.e., unboxes itself automatically) + public static implicit operator string(StringValue value) + { + return value.internalString; + } + + public static implicit operator StringValue(string value) + { + return new StringValue(value); + } + + public static StringValue operator +(StringValue val1, StringValue val2) + { + return new StringValue(val1.ToString() + val2.ToString()); + } + + public static StringValue operator +(StringValue val1, Structure val2) + { + return new StringValue(val1.ToString() + val2.ToString()); + } + + public static StringValue operator +(Structure val1, StringValue val2) + { + return new StringValue(val1.ToString() + val2.ToString()); + } + + public override string ToString() + { + return this; + } + + public override bool Equals(object obj) + { + if (obj == null) return false; + if (obj is StringValue || obj is string) + { + return string.Equals(internalString, obj.ToString(), StringComparison.OrdinalIgnoreCase); + } + return false; + } + + public override int GetHashCode() + { + return internalString.GetHashCode(); + } + + TypeCode IConvertible.GetTypeCode() + { + return TypeCode.Object; + } + + bool IConvertible.ToBoolean(IFormatProvider provider) + { + if (string.IsNullOrEmpty(internalString)) return false; + return true; + } + + byte IConvertible.ToByte(IFormatProvider provider) + { + throw new KOSCastException(typeof(StringValue), typeof(byte)); + } + + char IConvertible.ToChar(IFormatProvider provider) + { + throw new KOSCastException(typeof(StringValue), typeof(char)); + } + + DateTime IConvertible.ToDateTime(IFormatProvider provider) + { + throw new KOSCastException(typeof(StringValue), typeof(DateTime)); + } + + decimal IConvertible.ToDecimal(IFormatProvider provider) + { + throw new KOSCastException(typeof(StringValue), typeof(Decimal)); + } + + double IConvertible.ToDouble(IFormatProvider provider) + { + throw new KOSCastException(typeof(StringValue), typeof(Double)); + } + + short IConvertible.ToInt16(IFormatProvider provider) + { + throw new KOSCastException(typeof(StringValue), typeof(Int16)); + } + + int IConvertible.ToInt32(IFormatProvider provider) + { + throw new KOSCastException(typeof(StringValue), typeof(Int32)); + } + + long IConvertible.ToInt64(IFormatProvider provider) + { + throw new KOSCastException(typeof(StringValue), typeof(Int64)); + } + + sbyte IConvertible.ToSByte(IFormatProvider provider) + { + throw new KOSCastException(typeof(StringValue), typeof(SByte)); + } + + float IConvertible.ToSingle(IFormatProvider provider) + { + throw new KOSCastException(typeof(StringValue), typeof(Single)); + } + + string IConvertible.ToString(IFormatProvider provider) + { + return internalString; + } + + object IConvertible.ToType(Type conversionType, IFormatProvider provider) + { + if (conversionType == typeof(StringValue)) + return this; + else if (conversionType == typeof(BooleanValue)) + return new BooleanValue(string.IsNullOrEmpty(internalString) ? false : true); + else if (conversionType.IsSubclassOf(typeof(Structure))) + throw new KOSCastException(typeof(StringValue), conversionType); + return Convert.ChangeType(internalString, conversionType); + } + + ushort IConvertible.ToUInt16(IFormatProvider provider) + { + throw new KOSCastException(typeof(StringValue), typeof(UInt16)); + } + + uint IConvertible.ToUInt32(IFormatProvider provider) + { + throw new KOSCastException(typeof(StringValue), typeof(UInt32)); + } + + ulong IConvertible.ToUInt64(IFormatProvider provider) + { + throw new KOSCastException(typeof(StringValue), typeof(UInt64)); + } + } +} diff --git a/src/kOS.Safe/Encapsulation/Structure.cs b/src/kOS.Safe/Encapsulation/Structure.cs index 77b740f6d..46c010781 100644 --- a/src/kOS.Safe/Encapsulation/Structure.cs +++ b/src/kOS.Safe/Encapsulation/Structure.cs @@ -1,10 +1,16 @@ using System; +using System.Linq; +using System.Text; using System.Collections.Generic; +using System.Globalization; +using kOS.Safe.Encapsulation.Suffixes; using kOS.Safe.Exceptions; using kOS.Safe.Utilities; +using kOS.Safe.Serialization; namespace kOS.Safe.Encapsulation { + [KOSNomenclature("Structure")] public abstract class Structure : ISuffixed, IOperable { private static readonly IDictionary> globalSuffixes; @@ -14,11 +20,31 @@ public abstract class Structure : ISuffixed, IOperable static Structure() { globalSuffixes = new Dictionary>(); + } protected Structure() { instanceSuffixes = new Dictionary(StringComparer.OrdinalIgnoreCase); + InitializeInstanceSuffixes(); + } + + public string KOSName { get { return KOSNomenclature.GetKOSName(GetType()); } } + + + private void InitializeInstanceSuffixes() + { + // Need to choose what sort of naming scheme to return before + // enabling this one: + // AddSuffix("TYPENAME", new NoArgsSuffix(() => GetType().ToString())); + + AddSuffix("TOSTRING", new NoArgsSuffix(() => ToString())); + AddSuffix("HASSUFFIX", new OneArgsSuffix(HasSuffix)); + AddSuffix("SUFFIXNAMES", new NoArgsSuffix>(GetSuffixNames)); + AddSuffix("ISSERIALIZABLE", new NoArgsSuffix(() => this is SerializableStructure)); + AddSuffix("TYPENAME", new NoArgsSuffix(() => new StringValue(KOSName))); + AddSuffix("ISTYPE", new OneArgsSuffix(GetKOSIsType)); + AddSuffix("INHERITANCE", new NoArgsSuffix(GetKOSInheritance)); } protected void AddSuffix(string suffixName, ISuffix suffixToAdd) @@ -62,7 +88,10 @@ protected static void AddGlobalSuffix(IEnumerable suffixNames, ISuffi typeSuffixes.Add(suffixName, suffixToAdd); } } - globalSuffixes[type] = typeSuffixes; + lock (globalSuffixLock) + { + globalSuffixes[type] = typeSuffixes; + } } private static IDictionary GetStaticSuffixesForType(Type currentType) @@ -105,7 +134,7 @@ private bool ProcessSetSuffix(IDictionary suffixes, string suff return false; } - public virtual object GetSuffix(string suffixName) + public virtual ISuffixResult GetSuffix(string suffixName) { ISuffix suffix; if (instanceSuffixes.TryGetValue(suffixName, out suffix)) @@ -121,6 +150,82 @@ public virtual object GetSuffix(string suffixName) } return suffix.Get(); } + + public virtual BooleanValue HasSuffix(StringValue suffixName) + { + if (instanceSuffixes.ContainsKey(suffixName.ToString())) + return true; + if (GetStaticSuffixesForType(GetType()).ContainsKey(suffixName.ToString())) + return true; + return false; + } + + public virtual ListValue GetSuffixNames() + { + List names = new List(); + + names.AddRange(instanceSuffixes.Keys.Select(item => (StringValue)item)); + names.AddRange(GetStaticSuffixesForType(GetType()).Keys.Select(item => (StringValue)item)); + + // Return the list alphabetized by suffix name. The key lookups above, since they're coming + // from a hashed dictionary, won't be in any predictable ordering: + return new ListValue(names.OrderBy(item => item.ToString())); + } + + public virtual BooleanValue GetKOSIsType(StringValue queryTypeName) + { + // We can't use Reflection's IsAssignableFrom because of the annoying way Generics work under Reflection. + + for (Type t = GetType() ; t != null ; t = t.BaseType) + { + // Our KOSNomenclature mapping can't store a Dictionary mapping for all + // the new generics types that get made on the fly and weren't present when the static constructor was made. + // So instead we ask Reflection to get the base from which it came so we can look that up instead. + if (t.IsGenericType) + t = t.GetGenericTypeDefinition(); + + if (KOSNomenclature.HasKOSName(t)) + { + string kOSname = KOSNomenclature.GetKOSName(t); + if (kOSname == queryTypeName) + return true; + if (t == typeof(Structure)) + break; // don't bother walking further up - there won't be any more KOS types above this. + } + } + return false; + } + + public virtual StringValue GetKOSInheritance() + { + StringBuilder sb = new StringBuilder(); + + string prevKosName = ""; + + for (Type t = GetType() ; t != null ; t = t.BaseType) + { + // Our KOSNomenclature mapping can't store a Dictionary mapping for all + // the new generics types that get made on the fly and weren't present when the static constructor was made. + // So instead we ask Reflection to get the base from which it came so we can look that up instead. + if (t.IsGenericType) + t = t.GetGenericTypeDefinition(); + + if (KOSNomenclature.HasKOSName(t)) + { + string kOSname = KOSNomenclature.GetKOSName(t); + if (kOSname != prevKosName) // skip extra iterations where we mash parent C# types and child C# types into the same KOS type. + { + if (prevKosName != "") + sb.Append(" derived from "); + sb.Append(kOSname); + } + prevKosName = kOSname; + if (t == typeof(Structure)) + break; // don't bother walking further up - there won't be any more KOS types above this. + } + } + return sb.ToString(); + } public virtual object TryOperation(string op, object other, bool reverseOrder) { @@ -157,5 +262,98 @@ public override string ToString() { return "Structure "; } + + public static StringValue operator +(Structure val1, Structure val2) + { + return new StringValue(string.Concat(val1, val2)); + } + + /// + /// Attempt to convert the given object into a kOS encapsulation type (something + /// derived from kOS.Safe.Encapsulation.Structure), returning that instead. + /// This never throws exception or complains in any way if the conversion cannot happen. + /// Insted in that case it just silently ignores the request and returns the original object + /// reference unchanged. Thus it is safe to call it "just in case", even in places where it won't + /// always be necessary, or have an effect at all. You should use in anywhere you need to + /// ensure that a value a user's script might see on the stack or in a script variable is properly + /// wrapped in a kOS Structure, and not just a raw primitive like int or double. + /// + /// value to convert + /// new converted value, or original value if conversion couldn't happen or was unnecesary + public static object FromPrimitive(object value) + { + if (value == null) + return value; // If a null exists, let it pass through so it will bomb elsewhere, not here in FromPrimitive() where the exception message would be obtuse. + + if (value is Structure) + return value; // Conversion is unnecessary - it's already a Structure. + + var convert = value as IConvertible; + if (convert == null) + return value; // Conversion isn't even theoretically possible. + + TypeCode code = convert.GetTypeCode(); + switch (code) + { + case TypeCode.Boolean: + return new BooleanValue(Convert.ToBoolean(convert)); + case TypeCode.Decimal: + case TypeCode.Double: + case TypeCode.Single: + return ScalarValue.Create(Convert.ToDouble(convert)); + case TypeCode.Byte: + case TypeCode.Int16: + case TypeCode.Int32: + case TypeCode.Int64: + case TypeCode.SByte: + case TypeCode.UInt16: + case TypeCode.UInt32: + case TypeCode.UInt64: + return ScalarValue.Create(Convert.ToInt32(convert)); + case TypeCode.String: + return new StringValue(Convert.ToString(convert, CultureInfo.CurrentCulture)); + default: + break; + } + return value; // Conversion is one this method didn't implement. + } + + /// + /// This is identical to FromPrimitive, except that it WILL throw an exception + /// if it was unable to guarantee that the result became (or already was) a kOS Structure. + /// + /// value to convert + /// value after conversion, or original value if conversion unnecessary + public static Structure FromPrimitiveWithAssert(object value) + { + object convertedVal = FromPrimitive(value); + Structure returnValue = convertedVal as Structure; + if (returnValue == null) + throw new KOSException( + string.Format("Internal Error. Contact the kOS developers with the phrase 'impossible FromPrimitiveWithAssert({0}) was attempted'.\nAlso include the output log if you can.", + value == null ? "" : value.GetType().ToString())); + return returnValue; + } + + public static object ToPrimitive(object value) + { + var scalarValue = value as ScalarValue; + if (scalarValue != null) + { + return scalarValue.Value; + } + var booleanValue = value as BooleanValue; + if (booleanValue != null) + { + return booleanValue.Value; + } + var stringValue = value as StringValue; + if (stringValue != null) + { + return stringValue.ToString(); + } + + return value; + } } } diff --git a/src/kOS.Safe/Encapsulation/Suffixes/ClampSetSuffix.cs b/src/kOS.Safe/Encapsulation/Suffixes/ClampSetSuffix.cs index 327ea56d3..2dbfbf423 100644 --- a/src/kOS.Safe/Encapsulation/Suffixes/ClampSetSuffix.cs +++ b/src/kOS.Safe/Encapsulation/Suffixes/ClampSetSuffix.cs @@ -2,7 +2,7 @@ namespace kOS.Safe.Encapsulation.Suffixes { - public class ClampSetSuffix : SetSuffix + public class ClampSetSuffix : SetSuffix where TValue : ScalarValue { private readonly double min; private readonly double max; @@ -23,8 +23,7 @@ public ClampSetSuffix(SuffixGetDlg getter, SuffixSetDlg setter, public override void Set(object value) { - //HACK, this is assumes the value parses as a double - var dblValue = double.Parse(value.ToString()); + var dblValue = System.Convert.ToDouble(value); base.Set(System.Math.Abs(stepIncrement) < 0.0001 ? Math.Clamp(dblValue, min, max) diff --git a/src/kOS.Safe/Encapsulation/Suffixes/ConfigKey.cs b/src/kOS.Safe/Encapsulation/Suffixes/ConfigKey.cs new file mode 100644 index 000000000..680ef5863 --- /dev/null +++ b/src/kOS.Safe/Encapsulation/Suffixes/ConfigKey.cs @@ -0,0 +1,64 @@ +using System; + +namespace kOS.Safe.Encapsulation.Suffixes +{ + [kOS.Safe.Utilities.KOSNomenclature("ConfigKey")] // not even sure when anyone will ever see this in a script. + public class ConfigKey : Structure + { + private object val; + public string StringKey {get;private set;} + public string Alias {get;private set;} + public string Name {get; private set;} + public Type ValType {get;private set;} + public object Value {get{return val;} set{ val = SafeSetValue(value); } } + public object MinValue {get;private set;} + public object MaxValue {get;private set;} + + public ConfigKey(string stringKey, string alias, string name, object defaultValue, object min, object max, Type type) + { + StringKey = stringKey; + Alias = alias; + Name = name; + val = defaultValue; + MinValue = min; + MaxValue = max; + ValType = type; + } + + + /// + /// Return the new value after it's been altered or the change was denied. + /// + /// attempted new value + /// new value to actually use, maybe constrained or even unchanged if the attempted value is disallowed + private object SafeSetValue(object newValue) + { + object returnValue = Value; + if (newValue==null || (! ValType.IsInstanceOfType(newValue))) + return returnValue; + + if (Value is int) + { + if ((int)newValue < (int)MinValue) + returnValue = MinValue; + else if ((int)newValue > (int)MaxValue) + returnValue = MaxValue; + else + returnValue = newValue; + + // TODO: If and when we end up making warning-level exceptions that don't break + // the execution but still get logged, then log such a warning here mentioning + // if the value attempted was denied and changed if it was. + } + else if (Value is bool) + { + returnValue = newValue; + } + else + { + throw new Exception( "kOS CONFIG has new type that wasn't supported yet: contact kOS developers" ); + } + return returnValue; + } + } +} \ No newline at end of file diff --git a/src/kOS.Safe/Encapsulation/Suffixes/DelegateSuffixResult.cs b/src/kOS.Safe/Encapsulation/Suffixes/DelegateSuffixResult.cs new file mode 100644 index 000000000..65bf2ae52 --- /dev/null +++ b/src/kOS.Safe/Encapsulation/Suffixes/DelegateSuffixResult.cs @@ -0,0 +1,168 @@ +using kOS.Safe.Exceptions; +using kOS.Safe.Execution; +using kOS.Safe.Utilities; +using System; +using System.Collections.Generic; +using System.Reflection; + +namespace kOS.Safe.Encapsulation.Suffixes +{ + public class DelegateSuffixResult : ISuffixResult + { + private readonly Delegate del; + private Structure value; + + public Delegate Del + { + get { return del; } + } + + public Structure Value + { + get { return value; } + } + + public DelegateSuffixResult(Delegate del) + { + this.del = del; + } + + public bool HasValue + { + get { return value != null; } + } + + public void Invoke(ICpu cpu) + { + MethodInfo methInfo = del.Method; + ParameterInfo[] paramArray = methInfo.GetParameters(); + var args = new List(); + var paramArrayArgs = new List(); + + // Will be true iff the lastmost parameter of the delegate is using the C# 'param' keyword and thus + // expects the remainder of the arguments marshalled together into one array object. + bool isParamArrayArg = false; + + CpuUtility.ReverseStackArgs(cpu, false); + for (int i = 0; i < paramArray.Length; ++i) + { + object arg = cpu.PopValue(); + Type argType = arg.GetType(); + ParameterInfo paramInfo = paramArray[i]; + + // If this is the lastmost parameter then it might be a 'param' array which expects all the rest of + // the arguments to be collected together into one single array parameter when invoking the method: + isParamArrayArg = (i == paramArray.Length - 1 && Attribute.IsDefined(paramInfo, typeof(ParamArrayAttribute))); + + if (arg != null && arg.GetType() == CpuUtility.ArgMarkerType) + { + if (isParamArrayArg) + break; // with param arguments, you want to consume everything to the arg bottom - it's normal. + else + throw new KOSArgumentMismatchException(paramArray.Length, paramArray.Length - (i + 1)); + } + + // Either the expected type of this one parameter, or if it's a 'param' array as the last arg, then + // the expected type of that array's elements: + Type paramType = (isParamArrayArg ? paramInfo.ParameterType.GetElementType() : paramInfo.ParameterType); + + // Parameter type-safe checking: + bool inheritable = paramType.IsAssignableFrom(argType); + if (!inheritable) + { + bool castError = false; + // If it's not directly assignable to the expected type, maybe it's "castable" to it: + try + { + arg = Convert.ChangeType(arg, Type.GetTypeCode(paramType)); + } + catch (InvalidCastException) + { + throw new KOSCastException(argType, paramType); + } + catch (FormatException) + { + castError = true; + } + if (castError) + { + throw new Exception(string.Format("Argument {0}({1}) to method {2} should be {3} instead of {4}.", (paramArray.Length - i), arg, methInfo.Name, paramType.Name, argType)); + } + } + + if (isParamArrayArg) + { + paramArrayArgs.Add(Structure.FromPrimitiveWithAssert(arg)); + --i; // keep hitting the last item in the param list again and again until a forced break because of arg bottom marker. + } + else + { + args.Add(Structure.FromPrimitiveWithAssert(arg)); + } + } + if (isParamArrayArg) + { + // collect the param array args that were at the end into the one single + // array item that will be sent to the method when invoked: + args.Add(paramArrayArgs.ToArray()); + } + // Consume the bottom marker under the args, which had better be + // immediately under the args we just popped, or the count was off. + if (!isParamArrayArg) // A param array arg will have already consumed the arg bottom mark. + { + bool foundArgMarker = false; + int numExtraArgs = 0; + while (cpu.GetStackSize() > 0 && !foundArgMarker) + { + object marker = cpu.PopValue(); + if (marker != null && marker.GetType() == CpuUtility.ArgMarkerType) + foundArgMarker = true; + else + ++numExtraArgs; + } + if (numExtraArgs > 0) + throw new KOSArgumentMismatchException(paramArray.Length, paramArray.Length + numExtraArgs); + } + + // Delegate.DynamicInvoke expects a null, rather than an array of zero length, when + // there are no arguments to pass: + object[] argArray = (args.Count > 0) ? args.ToArray() : null; + + try + { + // I could find no documentation on what DynamicInvoke returns when the delegate + // is a function returning void. Does it return a null? I don't know. So to avoid the + // problem, I split this into these two cases: + if (methInfo.ReturnType == typeof(void)) + { + del.DynamicInvoke(argArray); + value = ScalarValue.Create(0); + // By adding this we can unconditionally assume all functionshave a return value + // to be used or popped away, even if "void". In order to mainain consistency with + // the void return value of functions, and to ensure that we don't accidentally pass + // a value back to the user that they cannot interact with (null), we return zero. + } + else + { + // Convert a primitive return type to a structure. This is done in the opcode, since + // the opcode calls the deligate directly and cannot be (quickly) intercepted + value = Structure.FromPrimitiveWithAssert(del.DynamicInvoke(argArray)); + } + } + catch (TargetInvocationException e) + { + // Annoyingly, calling DynamicInvoke on a delegate wraps any exceptions the delegate throws inside + // this TargetInvocationException, which hides them from the kOS user unless we do this: + if (e.InnerException != null) + throw e.InnerException; + throw; + } + } + + // Not something the user should ever see, but still useful for our debugging when we dump the stack: + public override string ToString() + { + return string.Format("[DelegateSuffixResult Del={0}, Value={1}]", del, (HasValue ? value.ToString() : "")); + } + } +} \ No newline at end of file diff --git a/src/kOS.Safe/Encapsulation/Suffixes/GlobalSuffix.cs b/src/kOS.Safe/Encapsulation/Suffixes/GlobalSuffix.cs index 534f0e5f1..5169fcfdf 100644 --- a/src/kOS.Safe/Encapsulation/Suffixes/GlobalSuffix.cs +++ b/src/kOS.Safe/Encapsulation/Suffixes/GlobalSuffix.cs @@ -1,7 +1,7 @@ namespace kOS.Safe.Encapsulation.Suffixes { - public class StaticSuffix : SuffixBase + public class StaticSuffix : SuffixBase where TReturn : Structure { private readonly StaticSuffixGetDlg getter; @@ -10,9 +10,9 @@ public StaticSuffix(StaticSuffixGetDlg getter, string description = "") this.getter = getter; } - public override object Get() + public override ISuffixResult Get() { - return getter.Invoke(); + return new SuffixResult(getter.Invoke()); } } } \ No newline at end of file diff --git a/src/kOS.Safe/Encapsulation/Suffixes/ISuffixResult.cs b/src/kOS.Safe/Encapsulation/Suffixes/ISuffixResult.cs new file mode 100644 index 000000000..045bbef09 --- /dev/null +++ b/src/kOS.Safe/Encapsulation/Suffixes/ISuffixResult.cs @@ -0,0 +1,14 @@ +using System; +using kOS.Safe.Execution; + +namespace kOS.Safe.Encapsulation.Suffixes +{ + public interface ISuffixResult + { + Structure Value { get; } + + bool HasValue { get; } + + void Invoke(ICpu cpu); + } +} \ No newline at end of file diff --git a/src/kOS.Safe/Encapsulation/Suffixes/NoArgsSuffix.cs b/src/kOS.Safe/Encapsulation/Suffixes/NoArgsSuffix.cs index 1363f5522..d363272d6 100644 --- a/src/kOS.Safe/Encapsulation/Suffixes/NoArgsSuffix.cs +++ b/src/kOS.Safe/Encapsulation/Suffixes/NoArgsSuffix.cs @@ -1,19 +1,20 @@ namespace kOS.Safe.Encapsulation.Suffixes { - public class NoArgsSuffix : SuffixBase + public class NoArgsSuffix : SuffixBase where TReturn : Structure { private readonly Del del; - public delegate TInnerReturn Del(); + public delegate TInnerReturn Del() where TInnerReturn : Structure; public NoArgsSuffix(Del del, string description = ""):base(description) { this.del = del; } - public override object Get() + public override ISuffixResult Get() { - return del; + return new DelegateSuffixResult(del); } } + } \ No newline at end of file diff --git a/src/kOS.Safe/Encapsulation/Suffixes/NoArgsVoidSuffix.cs b/src/kOS.Safe/Encapsulation/Suffixes/NoArgsVoidSuffix.cs index 3a3daca75..70a494933 100644 --- a/src/kOS.Safe/Encapsulation/Suffixes/NoArgsVoidSuffix.cs +++ b/src/kOS.Safe/Encapsulation/Suffixes/NoArgsVoidSuffix.cs @@ -1,19 +1,25 @@ namespace kOS.Safe.Encapsulation.Suffixes { - public class NoArgsSuffix : SuffixBase + /// + /// Although we always have a dummy return from every call in the VM, + /// in the underlying C# a suffix might be backed by a Delegate that + /// returns void. Use this construct for suffixes that take no args + /// and return nothing. (that are only called for their effect). + /// + public class NoArgsVoidSuffix : SuffixBase { private readonly Del del; public delegate void Del(); - public NoArgsSuffix(Del del, string description = ""):base(description) + public NoArgsVoidSuffix(Del del, string description = ""):base(description) { this.del = del; } - public override object Get() + public override ISuffixResult Get() { - return del; + return new DelegateSuffixResult(del); } } } \ No newline at end of file diff --git a/src/kOS.Safe/Encapsulation/Suffixes/OneArgsSuffix.cs b/src/kOS.Safe/Encapsulation/Suffixes/OneArgsSuffix.cs index ab687c262..e899ed855 100644 --- a/src/kOS.Safe/Encapsulation/Suffixes/OneArgsSuffix.cs +++ b/src/kOS.Safe/Encapsulation/Suffixes/OneArgsSuffix.cs @@ -1,19 +1,19 @@ namespace kOS.Safe.Encapsulation.Suffixes { - public class OneArgsSuffix : SuffixBase + public class OneArgsSuffix : SuffixBase where TReturn : Structure where TParam : Structure { private readonly Del del; - public delegate TInnerReturn Del(TInnerParam one); + public delegate TInnerReturn Del(TInnerParam one) where TInnerReturn : Structure; public OneArgsSuffix(Del del,string description = "") :base(description) { this.del = del; } - public override object Get() + public override ISuffixResult Get() { - return del; + return new DelegateSuffixResult(del); } } } \ No newline at end of file diff --git a/src/kOS.Safe/Encapsulation/Suffixes/OneArgsVoidSuffix.cs b/src/kOS.Safe/Encapsulation/Suffixes/OneArgsVoidSuffix.cs index 6126a6150..150ad0330 100644 --- a/src/kOS.Safe/Encapsulation/Suffixes/OneArgsVoidSuffix.cs +++ b/src/kOS.Safe/Encapsulation/Suffixes/OneArgsVoidSuffix.cs @@ -1,19 +1,19 @@ namespace kOS.Safe.Encapsulation.Suffixes { - public class OneArgsSuffix : SuffixBase + public class OneArgsSuffix : SuffixBase where TParam : Structure { private readonly Del del; - public delegate void Del(TInnerParam argOne); + public delegate void Del(TInnerParam argOne) where TInnerParam : Structure; public OneArgsSuffix(Del del, string description = ""):base(description) { this.del = del; } - public override object Get() + public override ISuffixResult Get() { - return del; + return new DelegateSuffixResult(del); } } } \ No newline at end of file diff --git a/src/kOS.Safe/Encapsulation/Suffixes/SetSuffix.cs b/src/kOS.Safe/Encapsulation/Suffixes/SetSuffix.cs index f939f5a5d..62be26917 100644 --- a/src/kOS.Safe/Encapsulation/Suffixes/SetSuffix.cs +++ b/src/kOS.Safe/Encapsulation/Suffixes/SetSuffix.cs @@ -2,7 +2,7 @@ namespace kOS.Safe.Encapsulation.Suffixes { - public class SetSuffix : Suffix, ISetSuffix + public class SetSuffix : Suffix, ISetSuffix where TValue : Structure { private readonly SuffixSetDlg setter; @@ -13,7 +13,7 @@ public SetSuffix(SuffixGetDlg getter, SuffixSetDlg setter, strin } public virtual void Set(object value) - { + { TValue toSet; if (value is TValue) { @@ -21,7 +21,8 @@ public virtual void Set(object value) } else { - toSet = (TValue)Convert.ChangeType(value, typeof(TValue)); + Structure newValue = Structure.FromPrimitiveWithAssert(value); // Handles converting built in types to Structures that Convert.ChangeType() can't. + toSet = (TValue)Convert.ChangeType(newValue, typeof(TValue)); } setter.Invoke(toSet); } diff --git a/src/kOS.Safe/Encapsulation/Suffixes/Suffix.cs b/src/kOS.Safe/Encapsulation/Suffixes/Suffix.cs index e352b9667..9be95f0d4 100644 --- a/src/kOS.Safe/Encapsulation/Suffixes/Suffix.cs +++ b/src/kOS.Safe/Encapsulation/Suffixes/Suffix.cs @@ -1,6 +1,6 @@ namespace kOS.Safe.Encapsulation.Suffixes { - public class Suffix : SuffixBase + public class Suffix : SuffixBase where TReturn : Structure { private readonly SuffixGetDlg getter; @@ -9,10 +9,9 @@ public Suffix(SuffixGetDlg getter, string description = ""):base(descri this.getter = getter; } - public override object Get() + public override ISuffixResult Get() { - return getter.Invoke(); + return new SuffixResult(getter.Invoke()); } } - } diff --git a/src/kOS.Safe/Encapsulation/Suffixes/SuffixBase.cs b/src/kOS.Safe/Encapsulation/Suffixes/SuffixBase.cs index 1688bc4f7..30cf451bb 100644 --- a/src/kOS.Safe/Encapsulation/Suffixes/SuffixBase.cs +++ b/src/kOS.Safe/Encapsulation/Suffixes/SuffixBase.cs @@ -6,7 +6,7 @@ protected SuffixBase(string description) { Description = description; } - public abstract object Get(); + public abstract ISuffixResult Get(); public string Description { get; private set; } } diff --git a/src/kOS.Safe/Encapsulation/Suffixes/SuffixResult.cs b/src/kOS.Safe/Encapsulation/Suffixes/SuffixResult.cs new file mode 100644 index 000000000..de8c98cdb --- /dev/null +++ b/src/kOS.Safe/Encapsulation/Suffixes/SuffixResult.cs @@ -0,0 +1,40 @@ +using System; +using kOS.Safe.Execution; + +namespace kOS.Safe.Encapsulation.Suffixes +{ + public class SuffixResult : ISuffixResult + { + private readonly Structure structure; + + public SuffixResult(Structure structure) + { + this.structure = structure; + } + + public Structure Value + { + get + { + return structure; + } + } + + public bool HasValue + { + get { return true; } + } + + public void Invoke(ICpu cpu) + { + throw new NotImplementedException(); + } + + // Not something the user should ever see, but still useful for our debugging when we dump the stack: + public override string ToString() + { + return string.Format("[SuffixResult Structure={0}]", (HasValue ? structure.ToString() : "") ); + } + + } +} \ No newline at end of file diff --git a/src/kOS.Safe/Encapsulation/Suffixes/TwoArgsSuffix.cs b/src/kOS.Safe/Encapsulation/Suffixes/TwoArgsSuffix.cs index 3e54b6b8e..a91a77184 100644 --- a/src/kOS.Safe/Encapsulation/Suffixes/TwoArgsSuffix.cs +++ b/src/kOS.Safe/Encapsulation/Suffixes/TwoArgsSuffix.cs @@ -1,6 +1,6 @@ namespace kOS.Safe.Encapsulation.Suffixes { - public class TwoArgsSuffix : SuffixBase + public class TwoArgsSuffix : SuffixBase where TReturn : Structure where TParam : Structure where TParam2 : Structure { private readonly Del del; @@ -12,13 +12,13 @@ public TwoArgsSuffix(Del del, string description = "") this.del = del; } - public override object Get() + public override ISuffixResult Get() { - return del; + return new DelegateSuffixResult(del); } } - public class TwoArgsSuffix : SuffixBase + public class TwoArgsSuffix : SuffixBase where TParam : Structure where TParam2 : Structure { private readonly Del del; @@ -30,9 +30,9 @@ public TwoArgsSuffix(Del del, string description = "") this.del = del; } - public override object Get() + public override ISuffixResult Get() { - return del; + return new DelegateSuffixResult(del); } } } \ No newline at end of file diff --git a/src/kOS.Safe/Encapsulation/Suffixes/VarArgsSuffix.cs b/src/kOS.Safe/Encapsulation/Suffixes/VarArgsSuffix.cs new file mode 100644 index 000000000..87c7e06a5 --- /dev/null +++ b/src/kOS.Safe/Encapsulation/Suffixes/VarArgsSuffix.cs @@ -0,0 +1,19 @@ +namespace kOS.Safe.Encapsulation.Suffixes +{ + public class VarArgsSuffix : SuffixBase where TReturn : Structure where TParam : Structure + { + private readonly Del del; + + public delegate TInnerReturn Del(params TInnerParam[] arguments); + + public VarArgsSuffix(Del del, string description = "") : base(description) + { + this.del = del; + } + + public override ISuffixResult Get() + { + return new DelegateSuffixResult(del); + } + } +} \ No newline at end of file diff --git a/src/kOS.Safe/Encapsulation/TerminalStruct.cs b/src/kOS.Safe/Encapsulation/TerminalStruct.cs index a66fa4ae0..b48a01413 100644 --- a/src/kOS.Safe/Encapsulation/TerminalStruct.cs +++ b/src/kOS.Safe/Encapsulation/TerminalStruct.cs @@ -2,6 +2,7 @@ namespace kOS.Safe.Encapsulation { + [kOS.Safe.Utilities.KOSNomenclature("Terminal")] public class TerminalStruct : Structure { private readonly SharedObjects shared; @@ -13,6 +14,9 @@ public class TerminalStruct : Structure protected const int MAXROWS = 160; protected const int MINCOLUMNS = 15; protected const int MAXCOLUMNS = 255; + + protected const int MINCHARPIXELS = 4; + protected const int MAXCHARPIXELS = 24; // TODO: To implement IsOpen, we'd have to make a kOS.Safe interface wrapper around TermWindow first. // That's more than I want to do in this update, I'm leaving it as a TODO for me or someone else: @@ -34,17 +38,40 @@ protected internal SharedObjects Shared private void InitializeSuffixes() { // TODO: Uncomment the following if IsOpen gets implemented later: - // AddSuffix("ISOPEN", new SetSuffix(() => IsOpen, Isopen = value, "true=open, false=closed. You can set it to open/close the window.")); - AddSuffix("HEIGHT", new ClampSetSuffix(() => Shared.Screen.RowCount, + // AddSuffix("ISOPEN", new SetSuffix(() => IsOpen, Isopen = value, "true=open, false=closed. You can set it to open/close the window.")); + AddSuffix("HEIGHT", new ClampSetSuffix(() => Shared.Screen.RowCount, value => Shared.Screen.SetSize(value, Shared.Screen.ColumnCount), MINROWS, MAXROWS, "Get or Set the number of rows on the screen. Value is limited to the range [" + MINROWS + "," + MAXROWS + "]")); - AddSuffix("WIDTH", new ClampSetSuffix(() => Shared.Screen.ColumnCount, + AddSuffix("WIDTH", new ClampSetSuffix(() => Shared.Screen.ColumnCount, value => Shared.Screen.SetSize(Shared.Screen.RowCount, value), MINCOLUMNS, MAXCOLUMNS, "Get or Set the number of columns on the screen. Value is limited to the range [" + MINCOLUMNS + "," + MAXCOLUMNS + "]")); + AddSuffix("REVERSE", new SetSuffix(() => Shared.Screen.ReverseScreen, + value => Shared.Screen.ReverseScreen = value, + "Get or set the value of whether or not the terminal is in reversed mode.")); + AddSuffix("VISUALBEEP", new SetSuffix(() => Shared.Screen.VisualBeep, + value => Shared.Screen.VisualBeep = value, + "Get or set the value of whether or not the terminal shows beeps silently with a visual flash.")); + AddSuffix("BRIGHTNESS", new ClampSetSuffix(() => Shared.Screen.Brightness, + value => Shared.Screen.Brightness = (float)value, + 0f, + 1f, + "Screen Brightness, between 0.0 and 1.0")); + AddSuffix("CHARWIDTH", new ClampSetSuffix(() => Shared.Screen.CharacterPixelWidth, + value => Shared.Screen.CharacterPixelWidth = (int)value, + MINCHARPIXELS, + MAXCHARPIXELS, + 2, + "Character width on in-game terminal screen in pixels")); + AddSuffix("CHARHEIGHT", new ClampSetSuffix(() => Shared.Screen.CharacterPixelHeight, + value => Shared.Screen.CharacterPixelHeight = (int)value, + MINCHARPIXELS, + MAXCHARPIXELS, + 2, + "Character height on in-game terminal screen in pixels")); } public override string ToString() diff --git a/src/kOS.Safe/Encapsulation/UserDelegate.cs b/src/kOS.Safe/Encapsulation/UserDelegate.cs new file mode 100644 index 000000000..97de1e8a6 --- /dev/null +++ b/src/kOS.Safe/Encapsulation/UserDelegate.cs @@ -0,0 +1,86 @@ +using System.Collections.Generic; +using kOS.Safe.Execution; +using kOS.Safe.Compilation; + +namespace kOS.Safe.Encapsulation +{ + /// + /// A callback reference to a user-land function, implemented in kRISC code
+ ///
+ /// (As opposed to being a C# delegate, implemented in C# code).
+ ///
+ [kOS.Safe.Utilities.KOSNomenclature("UserDelegate")] + public class UserDelegate : KOSDelegate, IUserDelegate + { + public IProgramContext ProgContext {get; private set;} + public int EntryPoint {get; private set;} + public List Closure {get; private set;} + + /// + /// Make a new UserDelegate given the current state of the CPU and its stack, and + /// the entry point location of the function to call. + /// + /// the CPU on which this program is running. + /// The IProgramContext in which the entryPoint is stored. Entry point 27 in the interpreter is not the same as entrypoint 27 in program context. + /// instruction address where OpcodeCall should jump to to call the function. + /// If true, then a snapshot of the current scoping stack, and thus a persistent ref to its variables, + /// will be kept in the delegate so it can be called later as a callback with closure. Set to false if the + /// function is only getting called instantly using whatever the scope is at the time of the call. + public UserDelegate(ICpu cpu, IProgramContext context, int entryPoint, bool useClosure) : + base(cpu) + { + ProgContext = context; + EntryPoint = entryPoint; + if (useClosure) + CaptureClosure(); + else + Closure = new List(); // make sure it exists as an empty list so we don't have to have 'if null' checks everwywhere. + } + + public UserDelegate(UserDelegate oldCopy) : base(oldCopy) + { + ProgContext = oldCopy.ProgContext; + EntryPoint = oldCopy.EntryPoint; + Closure = oldCopy.Closure; + } + + public override KOSDelegate Clone() + { + return new UserDelegate(this); + } + + private void CaptureClosure() + { + Closure = Cpu.GetCurrentClosure(); + } + + public override string ToString() + { + return string.Format("UserDelegate(cpu={0}, entryPoint={1}, Closure={2},\n {3})", + Cpu, EntryPoint, Closure, base.ToString()); + } + + public override void PushUnderArgs() + { + // Going to do an indirect call of myself, and indirect calls need + // to have the delegate underneath the args. That's how + // OpcodeCall.StaticExecute() expects to see it. + Cpu.PushStack(this); + } + + public override Structure Call() + { + int absoluteJumpTo = OpcodeCall.StaticExecute(Cpu, false, "", true); + if (absoluteJumpTo >= 0) + Cpu.InstructionPointer = absoluteJumpTo - 1; // -1 because it increments by 1 automatically between instructions. + + // Remember this is just a special flag telling OpcodeCall to never place + // this suffix's C# delegate return value on the stack. It's like saying + // "even more void that void", because normally even a void suffix gets a + // dummy return value. This says to not even do that - just offload the + // responsibility for pushing a return value onto the user code that is + // about to be jumped into. + return new KOSPassThruReturn(); + } + } +} diff --git a/src/kOS.Safe/Encapsulation/VersionInfo.cs b/src/kOS.Safe/Encapsulation/VersionInfo.cs index 4a1491643..cb836a49c 100644 --- a/src/kOS.Safe/Encapsulation/VersionInfo.cs +++ b/src/kOS.Safe/Encapsulation/VersionInfo.cs @@ -2,6 +2,7 @@ namespace kOS.Safe.Encapsulation { + [kOS.Safe.Utilities.KOSNomenclature("Version")] public class VersionInfo : Structure { private readonly int major; @@ -18,9 +19,9 @@ public VersionInfo(int major, int minor, int build) private void VersionInitializeSuffixes() { - AddSuffix("MAJOR", new StaticSuffix(() => major)); - AddSuffix("MINOR", new StaticSuffix(() => minor)); - AddSuffix("BUILD", new StaticSuffix(() => build)); + AddSuffix("MAJOR", new StaticSuffix(() => major)); + AddSuffix("MINOR", new StaticSuffix(() => minor)); + AddSuffix("BUILD", new StaticSuffix(() => build)); } public override string ToString() diff --git a/src/kOS.Safe/Encapsulation/VolumeFile.cs b/src/kOS.Safe/Encapsulation/VolumeFile.cs new file mode 100644 index 000000000..5def238bb --- /dev/null +++ b/src/kOS.Safe/Encapsulation/VolumeFile.cs @@ -0,0 +1,82 @@ +using kOS.Safe.Encapsulation.Suffixes; +using kOS.Safe.Exceptions; +using System.Linq; +using kOS.Safe.Persistence; + +namespace kOS.Safe.Encapsulation +{ + [kOS.Safe.Utilities.KOSNomenclature("VolumeFile")] + public abstract class VolumeFile : Structure + { + public string Name { get; private set; } + + public abstract int Size { get; } + + public string Extension + { + get + { + var fileParts = Name.Split('.'); + + return fileParts.Length > 1 ? fileParts.Last() : string.Empty; + } + } + + protected VolumeFile(string name) + { + Name = name; + + InitializeSuffixes(); + } + + public abstract FileContent ReadAll(); + + public abstract bool Write(byte[] content); + + public bool Write(string content) + { + return Write(FileContent.EncodeString(content)); + } + + public bool WriteLn(string content) + { + return Write(content + FileContent.NEW_LINE); + } + + public abstract void Clear(); + + public override string ToString() + { + return Name; + } + + private void InitializeSuffixes() + { + AddSuffix("NAME", new Suffix(() => Name)); + AddSuffix("SIZE", new Suffix(() => new ScalarIntValue(Size))); + AddSuffix("EXTENSION", new Suffix(() => Extension)); + + AddSuffix("READALL", new Suffix(ReadAll)); + AddSuffix("WRITE", new OneArgsSuffix(str => WriteObject(str))); + AddSuffix("WRITELN", new OneArgsSuffix(str => new BooleanValue(WriteLn(str)))); + AddSuffix("CLEAR", new NoArgsVoidSuffix(Clear)); + } + + private bool WriteObject(Structure content) + { + if (content is StringValue) + { + return Write(content.ToString()); + } + + var stringValue = content as FileContent; + if (stringValue != null) + { + FileContent fileContent = stringValue; + return Write(fileContent.Bytes); + } + + throw new KOSException("Only instances of string and FileContent can be written"); + } + } +} \ No newline at end of file diff --git a/src/kOS.Safe/Exceptions/KOSArgumentMismatchException.cs b/src/kOS.Safe/Exceptions/KOSArgumentMismatchException.cs index 8316b6470..367a1ee24 100644 --- a/src/kOS.Safe/Exceptions/KOSArgumentMismatchException.cs +++ b/src/kOS.Safe/Exceptions/KOSArgumentMismatchException.cs @@ -1,9 +1,11 @@ using System; +using System.Collections.Generic; +using System.Linq; namespace kOS.Safe.Exceptions { /// - /// Indicates that a method or function was called with the + /// Indicates that a method or function was called with the /// wrong number of arguments. /// public class KOSArgumentMismatchException : KOSException @@ -17,51 +19,58 @@ public override string HelpURL { get { return string.Empty; } } - - private int expectedNum; - private int actualNum; - + /// /// Describe an error in the number of arguments. /// /// number of expected arguments /// number of actual arguments /// optional message - public KOSArgumentMismatchException(int expected, int actual, string message = "" ) : - base( BuildTerseMessage(expected,actual) + message ) + public KOSArgumentMismatchException(int expected, int actual, string message = "") : + this(new[] { expected }, actual, message) + { + } + + /// + /// Describe an error in the number of arguments. + /// + /// a list of the expected arguments + /// number of actual arguments + /// optional message + public KOSArgumentMismatchException(IList expected, int actual, string message = "") : + base(string.Format("{0} {1}", BuildTerseMessage(expected, actual), message)) { - expectedNum = expected; - actualNum = actual; } /// - /// Describe an error in the number of arguments, without knowing the number of args + /// Describe an error in the number of arguments, without knowing the number of arguments /// /// optional message public KOSArgumentMismatchException(string message = "") : - base( BuildTerseMessage() + " " + message ) + base(string.Format("{0} {1}", BuildTerseMessage(), message)) { - expectedNum = 0; - actualNum = 0; } - - private static string BuildTerseMessage(int expected, int actual) + + private static string BuildTerseMessage(IList expected, int actual) { - return String.Format("Incorrect number of arguments. Expected {0} argument{1}, but found {2}", - (expected==0?"no":expected.ToString()), (expected==1?"":"s"), (actual==0?"none":actual.ToString()) - ); + var expectedDisplay = (expected.Any() ? String.Join(", ", new List(expected).ConvertAll(i => i.ToString()).ToArray()) : "no"); + var pluralDecorator = (expected.Count() == 1 ? "" : "s"); + var actualArgs = (actual == 0 ? "none" : actual.ToString()); + + return string.Format("Incorrect number of arguments. Expected {0} argument{1}, but found {2}.", + expectedDisplay, pluralDecorator, actualArgs); } private static string BuildTerseMessage() { - return String.Format("Number of arguments passed to the function didn't match the number of DECLARE PARAMETERs encountered."); + return String.Format("Number of arguments passed in didn't match the number of DECLARE PARAMETERs.\n"); } - + private string BuildVerboseMessage() { return Message + "\n" + - "The number of arguments being passed into a function call is not correct.\n"; + "The number of arguments being passed into a function or program call is not correct.\n"; } } } \ No newline at end of file diff --git a/src/kOS.Safe/Exceptions/KOSBadJumpException.cs b/src/kOS.Safe/Exceptions/KOSBadJumpException.cs new file mode 100644 index 000000000..6a327afa5 --- /dev/null +++ b/src/kOS.Safe/Exceptions/KOSBadJumpException.cs @@ -0,0 +1,25 @@ +using System; + +namespace kOS.Safe.Exceptions +{ + public class KOSBadJumpException : Exception + { + public KOSBadJumpException(int destination, string message): + base( String.Format("Can't jump to instruction {0}. No opcode there: {1}: {2} ", + destination, + message, + "If you see this message, something is broken about how this program got compiled.")) + { + } + + public virtual string VerboseMessage + { + get { return base.Message; } + } + + public virtual string HelpURL + { + get { return string.Empty; } + } + } +} \ No newline at end of file diff --git a/src/kOS.Safe/Exceptions/KOSBinaryOperandTypeException.cs b/src/kOS.Safe/Exceptions/KOSBinaryOperandTypeException.cs index 915a940d7..c8cd52b22 100644 --- a/src/kOS.Safe/Exceptions/KOSBinaryOperandTypeException.cs +++ b/src/kOS.Safe/Exceptions/KOSBinaryOperandTypeException.cs @@ -1,4 +1,5 @@ using System; +using kOS.Safe.Compilation; namespace kOS.Safe.Exceptions { @@ -11,7 +12,7 @@ public class KOSBinaryOperandTypeException: KOSException private const string TERSE_MSG_FMT = "Cannot {0} {1} {2} {3}"; // for now just put a placeholder in using the terse message as the verbose one: - public override string VerboseMessage { get{ return base.Message;} } + public override string VerboseMessage { get{ return Message;} } public override string HelpURL { get{ return "";} } @@ -19,12 +20,11 @@ public class KOSBinaryOperandTypeException: KOSException /// Describe the error in terms of the two operands and the verb/preposition /// being done with them. For example: /// - /// operand object on the left side of the preposition + /// the left and right objects of the preposition /// present-tense singular conjugation of the operation's verb, i.e "add" /// preposition usually used with the verb, i.e you add "to", but divide "by". - /// operand object on the right side of the preposition - public KOSBinaryOperandTypeException(object leftSide, string verb, string preposition, object rightSide) : - base(String.Format(TERSE_MSG_FMT, verb, leftSide.GetType().Name, preposition, rightSide.GetType().Name)) + public KOSBinaryOperandTypeException(OperandPair pair, string verb, string preposition) : + base(String.Format(TERSE_MSG_FMT, verb, pair.Left.GetType().Name, preposition, pair.Right.GetType().Name)) { } } diff --git a/src/kOS.Safe/Exceptions/KOSBreakInvalidHereException.cs b/src/kOS.Safe/Exceptions/KOSBreakInvalidHereException.cs index 118f2ccbd..c2e3cc01d 100644 --- a/src/kOS.Safe/Exceptions/KOSBreakInvalidHereException.cs +++ b/src/kOS.Safe/Exceptions/KOSBreakInvalidHereException.cs @@ -1,10 +1,12 @@ -namespace kOS.Safe.Exceptions +using kOS.Safe.Compilation.KS; + +namespace kOS.Safe.Exceptions { /// /// A version of KOSCommandInvalidHere describing an attempt to use /// the BREAK command when not in the body of a loop. /// - public class KOSBreakInvalidHereException : KOSCommandInvalidHere + public class KOSBreakInvalidHereException : KOSCommandInvalidHereException { public override string HelpURL { @@ -18,8 +20,8 @@ public override string HelpURL "it doesn't mean anything when it's not inside a\n" + "loop.\n"; - public KOSBreakInvalidHereException() : - base("BREAK", "outside a loop", "in a loop body") + public KOSBreakInvalidHereException(LineCol location) : + base(location, "BREAK", "outside a loop", "in a loop body") { } } diff --git a/src/kOS.Safe/Exceptions/KOSCastException.cs b/src/kOS.Safe/Exceptions/KOSCastException.cs index 000e00436..95badfda8 100644 --- a/src/kOS.Safe/Exceptions/KOSCastException.cs +++ b/src/kOS.Safe/Exceptions/KOSCastException.cs @@ -1,4 +1,5 @@ using System; +using kOS.Safe.Utilities; namespace kOS.Safe.Exceptions { @@ -13,15 +14,21 @@ public class KOSCastException: KOSException public override string VerboseMessage { get{ return BuildVerboseMessage(); } } public override string HelpURL { get{ return "";} } - - private readonly Type typeFrom; - private readonly Type typeTo; + + private readonly string typeFrom; + private readonly string typeTo; /// /// Make an exception when an attempt to convert from one type to another failed. /// - public KOSCastException(Type typeFrom, Type typeTo) : - base(String.Format(TERSE_MSG_FMT, typeFrom.Name, typeTo.Name)) + public KOSCastException(Type typeFrom, Type typeTo) + : this(KOSNomenclature.GetKOSName(typeFrom), KOSNomenclature.GetKOSName(typeTo)) + { + + } + + public KOSCastException(string typeFrom, string typeTo) : + base(String.Format(TERSE_MSG_FMT, typeFrom, typeTo)) { this.typeFrom = typeFrom; this.typeTo = typeTo; @@ -49,7 +56,7 @@ private string BuildVerboseMessage() "in a place where it needed to use some type of:{0}" + " {2}{0}"; - return String.Format(VERBOSE_TEXT, Environment.NewLine, typeFrom.Name, typeTo.Name); + return String.Format(VERBOSE_TEXT, Environment.NewLine, typeFrom, typeTo); } } } diff --git a/src/kOS.Safe/Exceptions/KOSCommandInvalidHere.cs b/src/kOS.Safe/Exceptions/KOSCommandInvalidHereException.cs similarity index 76% rename from src/kOS.Safe/Exceptions/KOSCommandInvalidHere.cs rename to src/kOS.Safe/Exceptions/KOSCommandInvalidHereException.cs index ec8f71e5c..b289419fb 100644 --- a/src/kOS.Safe/Exceptions/KOSCommandInvalidHere.cs +++ b/src/kOS.Safe/Exceptions/KOSCommandInvalidHereException.cs @@ -1,4 +1,5 @@ using System; +using kOS.Safe.Compilation.KS; namespace kOS.Safe.Exceptions { @@ -8,7 +9,7 @@ namespace kOS.Safe.Exceptions /// semantic reason that it can't be used WHERE it's being used. /// Example: Trying to PRESERVE when *not* in a trigger body. /// - public class KOSCommandInvalidHere: KOSCompileException + public class KOSCommandInvalidHereException : KOSCompileException { private const string TERSE_MSG_FMT = "'{0}' command found {1}. It only works {2}."; @@ -19,20 +20,22 @@ public class KOSCommandInvalidHere: KOSCompileException "places of the code. This is one of those cases.\n"; // Just nothing by default: - public override string HelpURL { get{ return "";} } + public override string HelpURL { get { return ""; } } + public override string VerboseMessage { get { return VerbosePrefix; } } /// /// Describe the condition under which the invalidity is happening. /// + /// current line and column position of the problem /// string name of the invalid command /// describing where in code the it's not being allowed. /// Use a phrasing that starts with a preposition, i.e. "in a loop", "outside a loop" /// describing what sort of code the it is meant to be used in instead. /// Use a phrasing that starts with a preposition, i.e. "in a loop", "outside a loop" - public KOSCommandInvalidHere(string command, string badPlace, string goodPlace) : - base(String.Format(TERSE_MSG_FMT, command, badPlace, goodPlace)) + public KOSCommandInvalidHereException(LineCol location, string command, string badPlace, string goodPlace) : + base(location, string.Format(TERSE_MSG_FMT, command, badPlace, goodPlace)) { } } -} +} \ No newline at end of file diff --git a/src/kOS.Safe/Exceptions/KOSCompileException.cs b/src/kOS.Safe/Exceptions/KOSCompileException.cs index 2b3a35634..5dd1ce082 100644 --- a/src/kOS.Safe/Exceptions/KOSCompileException.cs +++ b/src/kOS.Safe/Exceptions/KOSCompileException.cs @@ -1,4 +1,6 @@ -namespace kOS.Safe.Exceptions +using kOS.Safe.Compilation.KS; + +namespace kOS.Safe.Exceptions { /// /// Thrown whenever KOS compiler encounters something it does not like. @@ -8,16 +10,76 @@ /// occur *prior* to actually letting the CPU start executing the /// program's opcodes. /// - public class KOSCompileException: KOSException + public class KOSCompileException : KOSException { + public LineCol Location { get; private set; } + + // In order to make the Message property of an Exception not be read-only, you have + // to do it this way - make a writable field underneath the get-only property. This + // is being done so the message of this exception can be altered later after it was + // constructed, as the source text information isn't available when the exception + // is first constructed. (See AddSourceText() below). + private string message; + + public override string Message + { + get { return message; } + } + // Just default the Verbose message to return the terse message: - public override string VerboseMessage { get{return base.Message;} } + public override string VerboseMessage { get { return Message; } } // Just nothing by default: - public override string HelpURL { get{ return "";} } + public override string HelpURL { get { return ""; } } + + public KOSCompileException(Token token, string message) + : this(new LineCol(token.Line, token.Column), message) + { + } + + public KOSCompileException(LineCol location, string message) + { + Location = location; + + this.message = message; + } - public KOSCompileException(string message) : base(message) + /// + /// Skims through the source text looking for the line snippet + /// where the problem is. This will prepend the source line + /// info to the existing message in the exception. + /// + /// Text of the entire file that was compiled + public void AddSourceText(int startline, string sourceText) { + // special case for when the exception cannot show its source line: + if (Location.Line <= 0 || Location.Column <= 0) + return; + // Have to skim through the source text looking for the right line: + int sourceLine = startline; + int startIndex = 0; + int endIndex = sourceText.Length; // endIndex is one past the end, actually. + for (int i = 0; i < sourceText.Length; ++i) + { + if (sourceText[i] == '\n') + { + ++sourceLine; + if (sourceLine == Location.Line) + { + startIndex = i + 1; + } + else if (sourceLine == Location.Column + 1) + { + endIndex = i; + break; + } + } + } + message = string.Format( + "{0}\n{1}\nline {2}, col {3}: {4}", + sourceText.Substring(startIndex, (endIndex - startIndex)), + "^".PadLeft(Location.Column), // put the caret under the right column of the source line + Location.Line, Location.Column, message); } } -} +} \ No newline at end of file diff --git a/src/kOS.Safe/Exceptions/KOSDefaultParamNotAtEndException.cs b/src/kOS.Safe/Exceptions/KOSDefaultParamNotAtEndException.cs new file mode 100644 index 000000000..0a93446dc --- /dev/null +++ b/src/kOS.Safe/Exceptions/KOSDefaultParamNotAtEndException.cs @@ -0,0 +1,39 @@ +using kOS.Safe.Compilation.KS; + +namespace kOS.Safe.Exceptions +{ + /// + /// A version of KOSCommandInvalidHere describing a situation where the + /// function parameter list intermingled defaultable optional parameters + /// with undefaultable mandatory ones. All the mandatory ones must come + /// prior to all the optional ones. + /// + public class KOSDefaultParamNotAtEndException : KOSCommandInvalidHereException + { + public override string HelpURL + { + get { return "http://ksp-kos.github.io/KOS_DOC/language/variables/index.html#DECLARE_PARAMETER"; } + } + + public override string VerboseMessage { get { return VerbosePrefix + APPEND_TEXT;} } + + private const string APPEND_TEXT = "\n" + + "All defaultable parameters must come at the\n" + + "end of the list of all parameters for a\n" + + "program or a function.\n" + + "For example, this is legal:\n" + + " declare x, y is 0.\n" + + "but this is not:\n" + + " declare x is 0, y.\n" + + "because when x had a default then all other\n" + + "parameters that came after it had to have one.\n"; + + public KOSDefaultParamNotAtEndException(LineCol location) : + base(location, + "An optional parameter (one with a default initializer)", + "before a mandatory parameter (one without a default initializer)", + "when all mandatory parameters come before all optional parameters") + { + } + } +} \ No newline at end of file diff --git a/src/kOS.Safe/Exceptions/KOSDuplicateKeyException.cs b/src/kOS.Safe/Exceptions/KOSDuplicateKeyException.cs new file mode 100644 index 000000000..fbb1ea451 --- /dev/null +++ b/src/kOS.Safe/Exceptions/KOSDuplicateKeyException.cs @@ -0,0 +1,12 @@ +namespace kOS.Safe.Exceptions +{ + public class KOSDuplicateKeyException : KOSException + { + private const string MSG = "The given key, ({0}), is already present in the case-{1} collection. Use :HASKEY for checking safety."; + + public KOSDuplicateKeyException(string key, bool caseSensitive) : base(string.Format(MSG, key, caseSensitive ? "sensitive" : "insensitive")) + { + + } + } +} \ No newline at end of file diff --git a/src/kOS.Safe/Exceptions/KOSException.cs b/src/kOS.Safe/Exceptions/KOSException.cs index a94a025c8..a4bcf9ea8 100644 --- a/src/kOS.Safe/Exceptions/KOSException.cs +++ b/src/kOS.Safe/Exceptions/KOSException.cs @@ -7,6 +7,10 @@ public class KOSException : Exception public KOSException(string message):base(message) { } + + public KOSException() // a default constructor is needed for how KOSCompileException works + { + } public virtual string VerboseMessage { diff --git a/src/kOS.Safe/Exceptions/KOSInvalidDelegateContext.cs b/src/kOS.Safe/Exceptions/KOSInvalidDelegateContextException.cs similarity index 67% rename from src/kOS.Safe/Exceptions/KOSInvalidDelegateContext.cs rename to src/kOS.Safe/Exceptions/KOSInvalidDelegateContextException.cs index 63d5fc426..eac5cbf1e 100644 --- a/src/kOS.Safe/Exceptions/KOSInvalidDelegateContext.cs +++ b/src/kOS.Safe/Exceptions/KOSInvalidDelegateContextException.cs @@ -1,24 +1,22 @@ -using System; - -namespace kOS.Safe.Exceptions +namespace kOS.Safe.Exceptions { /// /// Thrown when you attempt to call a user delegate from an invalid context /// where it cannot access the delegate from. /// - public class KOSInvalidDelegateContext : KOSException + public class KOSInvalidDelegateContextException : KOSException { private const string TERSE_MSG_FMT = "Cannot call this lock or function from {0} when it was declared in {1}."; private const string HELP_URL = "http://ksp-kos.github.io/KOS_DOC/language/user_functions.html#functions-and-the-terminal-interpreter"; - - public KOSInvalidDelegateContext(string currentContextName, string intendedContextName) : - base(String.Format(TERSE_MSG_FMT, currentContextName, intendedContextName)) + + public KOSInvalidDelegateContextException(string currentContextName, string intendedContextName) : + base(string.Format(TERSE_MSG_FMT, currentContextName, intendedContextName)) { } public override string VerboseMessage { - get { return base.Message; } + get { return Message; } } public override string HelpURL @@ -26,4 +24,4 @@ public override string HelpURL get { return HELP_URL; } } } -} +} \ No newline at end of file diff --git a/src/kOS.Safe/Exceptions/KOSKeyNotFoundException.cs b/src/kOS.Safe/Exceptions/KOSKeyNotFoundException.cs new file mode 100644 index 000000000..623414780 --- /dev/null +++ b/src/kOS.Safe/Exceptions/KOSKeyNotFoundException.cs @@ -0,0 +1,12 @@ +namespace kOS.Safe.Exceptions +{ + public class KOSKeyNotFoundException : KOSException + { + private const string MSG = "The given key, ({0}), was not present in the case-{1} collection. Use :HASKEY for checking safety."; + + public KOSKeyNotFoundException(string key, bool caseSensitive) : base(string.Format(MSG, key, caseSensitive ? "sensitive" : "insensitive")) + { + + } + } +} diff --git a/src/kOS.Safe/Exceptions/KOSNotInvokableException.cs b/src/kOS.Safe/Exceptions/KOSNotInvokableException.cs new file mode 100644 index 000000000..04bab0b2f --- /dev/null +++ b/src/kOS.Safe/Exceptions/KOSNotInvokableException.cs @@ -0,0 +1,26 @@ +namespace kOS.Safe.Exceptions +{ + /// + /// Thrown when you attempt to make a function call like:
+ /// identifier(). + /// and the identifier doesn't resolve to an invokable thing. + /// (not a user function, suffix, or built-in function). + ///
+ public class KOSNotInvokableException : KOSException + { + private const string TERSE_MSG_FMT = "Attempted to make a function call on a non-invokable object:\n {0}"; + public object objAttempted; + + public KOSNotInvokableException(object objAttempted) : + base(string.Format(TERSE_MSG_FMT,objAttempted.ToString())) + { + this.objAttempted = objAttempted; + } + + public override string VerboseMessage + { + get { return Message; } + } + + } +} \ No newline at end of file diff --git a/src/kOS.Safe/Exceptions/KOSOnceInvalidHereException.cs b/src/kOS.Safe/Exceptions/KOSOnceInvalidHereException.cs new file mode 100644 index 000000000..4f6d5a588 --- /dev/null +++ b/src/kOS.Safe/Exceptions/KOSOnceInvalidHereException.cs @@ -0,0 +1,30 @@ +using kOS.Safe.Compilation.KS; + +namespace kOS.Safe.Exceptions +{ + /// + /// A version of KOSCommandInvalidHere describing an attempt to use + /// the WAIT keyword when in a trigger. + /// + public class KOSOnceInvalidHereException : KOSCommandInvalidHereException + { + public override string HelpURL + { + get { return "http://ksp-kos.github.io/KOS_DOC/summary_topics/CPU_hardware/index.html#WAIT"; } + } + + public override string VerboseMessage { get { return VerbosePrefix + APPEND_TEXT;} } + + private const string APPEND_TEXT = "\n" + + "The ONCE keyword only works inside\n" + + "a program, not from the interpreter\n" + + "because the interpreter always\n" + + "recompiles and re-runs the program\n" + + "each run.\n"; + + public KOSOnceInvalidHereException(LineCol location) : + base(location, "ONCE", "from the terminal interpreter", "inside a program" ) + { + } + } +} diff --git a/src/kOS.Safe/Exceptions/KOSPreserveInvalidHereException.cs b/src/kOS.Safe/Exceptions/KOSPreserveInvalidHereException.cs index cef0a0f93..06eab4249 100644 --- a/src/kOS.Safe/Exceptions/KOSPreserveInvalidHereException.cs +++ b/src/kOS.Safe/Exceptions/KOSPreserveInvalidHereException.cs @@ -1,10 +1,12 @@ -namespace kOS.Safe.Exceptions +using kOS.Safe.Compilation.KS; + +namespace kOS.Safe.Exceptions { /// - /// A version of KOSCommandInvalidHere describing an attempt to use + /// A version of KOSCommandInvalidHereException describing an attempt to use /// the PRESERVE keyword when not in a trigger. /// - public class KOSPreserveInvalidHereException : KOSCommandInvalidHere + public class KOSPreserveInvalidHereException : KOSCommandInvalidHereException { public override string HelpURL { @@ -19,8 +21,8 @@ public override string HelpURL "anything when it's not inside a trigger like\n" + "WHEN or ON.\n"; - public KOSPreserveInvalidHereException() : - base( "PRESERVE", "not in a trigger body", "in triggers" ) + public KOSPreserveInvalidHereException(LineCol location) : + base(location, "PRESERVE", "not in a trigger body", "in triggers" ) { } } diff --git a/src/kOS.Safe/Exceptions/KOSReturnInvalidHereException.cs b/src/kOS.Safe/Exceptions/KOSReturnInvalidHereException.cs index c1c6cae1a..ff407cb5f 100644 --- a/src/kOS.Safe/Exceptions/KOSReturnInvalidHereException.cs +++ b/src/kOS.Safe/Exceptions/KOSReturnInvalidHereException.cs @@ -1,10 +1,12 @@ -namespace kOS.Safe.Exceptions +using kOS.Safe.Compilation.KS; + +namespace kOS.Safe.Exceptions { /// /// A version of KOSCommandInvalidHere describing an attempt to use /// the RETURN command when not in the body of a user function. /// - public class KOSReturnInvalidHereException : KOSCommandInvalidHere + public class KOSReturnInvalidHereException : KOSCommandInvalidHereException { public override string HelpURL { @@ -18,8 +20,8 @@ public override string HelpURL "it doesn't mean anything when it's not inside a\n" + "user function.\n"; - public KOSReturnInvalidHereException() : - base("RETURN", "outside a FUNCTION", "in a FUNCTION body") + public KOSReturnInvalidHereException(LineCol location) : + base(location, "RETURN", "outside a FUNCTION", "in a FUNCTION body") { } } diff --git a/src/kOS.Safe/Exceptions/KOSSerializationException.cs b/src/kOS.Safe/Exceptions/KOSSerializationException.cs new file mode 100644 index 000000000..0e6902efc --- /dev/null +++ b/src/kOS.Safe/Exceptions/KOSSerializationException.cs @@ -0,0 +1,12 @@ +using System; + +namespace kOS.Safe.Exceptions +{ + public class KOSSerializationException : KOSException + { + public KOSSerializationException(string message) : base(message) + { + } + } +} + diff --git a/src/kOS.Safe/Exceptions/KOSSituationallyInvalidException.cs b/src/kOS.Safe/Exceptions/KOSSituationallyInvalidException.cs new file mode 100644 index 000000000..f4c2c4e8f --- /dev/null +++ b/src/kOS.Safe/Exceptions/KOSSituationallyInvalidException.cs @@ -0,0 +1,30 @@ +namespace kOS.Safe.Exceptions +{ + /// + /// To be thrown whenever a command cannot be used or is going to + /// give bogus data due to the KSP GAME situation it's being called from + /// being invalid.
+ /// This is to be distinguished from various compile + /// exceptions about commands being disallowed in certain parts of the + /// code.
+ /// This is for runtime situations where it's not kOS that prevents + /// things from working, but KSP itself, according to the game + /// rules.
+ /// Examples of the sorts of things where it might be + /// appropriate to throw this include:
+ /// - Trying to use time warp (not phys warp) when in atmosphere.
+ /// - Trying to deploy a parachute that is broken.
+ /// - Trying to see the manuever nodes of a vessel that is not the active vessel. (KSP only + /// attaches a patchedConicSolver to the current ActiveVessel. It's null for all others.) + ///
+ public class KOSSituationallyInvalidException : KOSException + { + + public override string VerboseMessage { get { return Message; } } + + public KOSSituationallyInvalidException(string msg) : + base(msg) + { + } + } +} \ No newline at end of file diff --git a/src/kOS.Safe/Exceptions/KOSWaitInValidHereException.cs b/src/kOS.Safe/Exceptions/KOSWaitInValidHereException.cs index b21ef1eab..d4edc95d0 100644 --- a/src/kOS.Safe/Exceptions/KOSWaitInValidHereException.cs +++ b/src/kOS.Safe/Exceptions/KOSWaitInValidHereException.cs @@ -1,10 +1,12 @@ -namespace kOS.Safe.Exceptions +using kOS.Safe.Compilation.KS; + +namespace kOS.Safe.Exceptions { /// /// A version of KOSCommandInvalidHere describing an attempt to use /// the WAIT keyword when in a trigger. /// - public class KOSWaitInvalidHereException : KOSCommandInvalidHere + public class KOSWaitInvalidHereException : KOSCommandInvalidHereException { public override string HelpURL { @@ -19,8 +21,8 @@ public override string HelpURL "work inside a trigger body, which must complete\n" + "its work within one update tick.\n"; - public KOSWaitInvalidHereException() : - base( "WAIT", "in a trigger body", "outside of triggers" ) + public KOSWaitInvalidHereException(LineCol location) : + base(location, "WAIT", "in a trigger body", "outside of triggers" ) { } } diff --git a/src/kOS.Safe/Exceptions/KOSWrongCPUVesselException.cs b/src/kOS.Safe/Exceptions/KOSWrongCPUVesselException.cs new file mode 100644 index 000000000..e25d2d40e --- /dev/null +++ b/src/kOS.Safe/Exceptions/KOSWrongCPUVesselException.cs @@ -0,0 +1,26 @@ +namespace kOS.Safe.Exceptions +{ + public class KOSWrongCPUVesselException : KOSException + { + public KOSWrongCPUVesselException() + : base("Access to requested suffix or structure is limited to the vessel on which this processor is mounted.") + { + } + + public KOSWrongCPUVesselException(string suffix) + : base(string.Format("Access to {0} is limited to the vessel on which this processor is mounted.", suffix)) + { + } + + public override string VerboseMessage + { + get + { + return "The suffix or structure you requested is only accessible from the current " + + "CPU vessel. Common examples include trying to access the CONTROL suffix " + + "on another vessel, or the DOEVENT suffix on a part from another vessel. " + + "Make sure you are not caching the value prior to a staging or docking event."; + } + } + } +} \ No newline at end of file diff --git a/src/kOS.Safe/Exceptions/KOSWrongControlValueTypeException.cs b/src/kOS.Safe/Exceptions/KOSWrongControlValueTypeException.cs new file mode 100644 index 000000000..2b46a26c4 --- /dev/null +++ b/src/kOS.Safe/Exceptions/KOSWrongControlValueTypeException.cs @@ -0,0 +1,36 @@ +using System; + +namespace kOS.Safe.Exceptions +{ + /// + /// To be thrown whenever the script attempted to perform a + /// cooked control "LOCK", or a raw control "SET", to a value
+ /// that's of an unusable type for that particular control bound variable. + ///
+ /// Examples:
+ /// - attempting to LOCK THROTTLE TO a string, or a LIST.
+ /// - attempting to SET SHIP:CONTROL:PITCH to a string, or a RGBA color.
+ ///
+ public class KOSWrongControlValueTypeException : KOSException + { + public KOSWrongControlValueTypeException(string controlType, string didUse, string shouldUse) : + base( string.Format("Cannot use a {0} as the value for the {1}. Should use {2} instead.", + didUse, controlType, shouldUse)) + { + } + + public override string VerboseMessage + { + get { return Message + "\n" + + "When setting a special control variable\n" + + "the type of the value has to match what\n" + + "the kOS computer expects that value to be."; } + } + + public override string HelpURL + { + get { return string.Empty; } + } + } +} + diff --git a/src/kOS.Safe/Exceptions/KOSYouShouldNeverSeeThisException.cs b/src/kOS.Safe/Exceptions/KOSYouShouldNeverSeeThisException.cs new file mode 100644 index 000000000..a43dac36a --- /dev/null +++ b/src/kOS.Safe/Exceptions/KOSYouShouldNeverSeeThisException.cs @@ -0,0 +1,12 @@ +using System; +using kOS.Safe.Exceptions; + +namespace kOS.Safe.Compilation +{ + public class KOSYouShouldNeverSeeThisException : KOSException + { + public KOSYouShouldNeverSeeThisException(string message) : base("This is an error endusers should never see, if you see this please report it to the kOS devs:\r\n " + message) + { + } + } +} \ No newline at end of file diff --git a/src/kOS/Execution/CPU.cs b/src/kOS.Safe/Execution/CPU.cs similarity index 70% rename from src/kOS/Execution/CPU.cs rename to src/kOS.Safe/Execution/CPU.cs index 5dfd2e54c..721402806 100644 --- a/src/kOS/Execution/CPU.cs +++ b/src/kOS.Safe/Execution/CPU.cs @@ -1,20 +1,18 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Diagnostics; -using kOS.Safe.Binding; +using kOS.Safe.Binding; using kOS.Safe.Compilation; -using kOS.Safe.Execution; +using kOS.Safe.Encapsulation; using kOS.Safe.Exceptions; -using kOS.Safe.Persistence; using kOS.Safe.Utilities; -using kOS.Suffixed; -using kOS.Persistence; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using Debug = kOS.Safe.Utilities.Debug; -namespace kOS.Execution +namespace kOS.Safe.Execution { - public class CPU: ICpu + public class CPU : ICpu { private enum Status { @@ -33,12 +31,18 @@ private enum Status private VariableScope savedPointers; private int instructionsSoFarInUpdate; private int instructionsPerUpdate; - + + public int InstructionsThisUpdate { get { return instructionsSoFarInUpdate; } } + // statistics private double totalCompileTime; + private double totalUpdateTime; private double totalTriggersTime; private double totalExecutionTime; + private double maxUpdateTime; + private double maxTriggersTime; + private double maxExecutionTime; private int maxMainlineInstructionsSoFar; private int maxTriggerInstructionsSoFar; private readonly StringBuilder executeLog = new StringBuilder(); @@ -51,7 +55,6 @@ public int InstructionPointer public double SessionTime { get { return currentTime; } } - public CPU(SharedObjects shared) { this.shared = shared; @@ -71,6 +74,9 @@ public void Boot() currentStatus = Status.Running; currentTime = 0; timeWaitUntil = 0; + maxUpdateTime = 0.0; + maxTriggersTime = 0.0; + maxExecutionTime = 0.0; // clear stack (which also orphans all local variables so they can get garbage collected) stack.Clear(); // clear global variables @@ -78,15 +84,15 @@ public void Boot() // clear interpreter if (shared.Interpreter != null) shared.Interpreter.Reset(); // load functions - if(shared.FunctionManager != null)shared.FunctionManager.Load(); + if (shared.FunctionManager != null) shared.FunctionManager.Load(); // load bindings if (shared.BindingMgr != null) shared.BindingMgr.Load(); // Booting message if (shared.Screen != null) { shared.Screen.ClearScreen(); - string bootMessage = string.Format("kOS Operating System\n" + "KerboScript v{0}\n \n" + "Proceed.\n", Core.VersionInfo); - Listnags = Safe.Utilities.Debug.GetPendingNags(); + string bootMessage = string.Format("kOS Operating System\n" + "KerboScript v{0}\n \n" + "Proceed.\n", SafeHouse.Version); + List nags = Debug.GetPendingNags(); if (nags.Count > 0) { bootMessage += @@ -100,23 +106,36 @@ public void Boot() bootMessage = nags.Aggregate(bootMessage, (current, msg) => current + (msg + "\n")); bootMessage += "##################################################\n"; + shared.Processor.SetMode(Module.ProcessorModes.OFF); } shared.Screen.Print(bootMessage); } - if (shared.VolumeMgr == null) { SafeHouse.Logger.Log("No volume mgr"); } - else if (!shared.VolumeMgr.CheckCurrentVolumeRange(shared.Vessel)) { SafeHouse.Logger.Log("Boot volume not in range"); } - else if (shared.VolumeMgr.CurrentVolume == null) { SafeHouse.Logger.Log("No current volume"); } - else if (shared.ScriptHandler == null) { SafeHouse.Logger.Log("No script handler"); } - else if (shared.VolumeMgr.CurrentVolume.GetByName("boot") == null) { SafeHouse.Logger.Log("Boot File is Missing"); } - else { - shared.ScriptHandler.ClearContext("program"); + if (!shared.Processor.CheckCanBoot()) return; + + string filename = shared.Processor.BootFilename; + // Check to make sure the boot file name is valid, and then that the boot file exists. + if (string.IsNullOrEmpty(filename)) { SafeHouse.Logger.Log("Boot file name is empty, skipping boot script"); } + else if (filename.Equals("None", StringComparison.InvariantCultureIgnoreCase)) { SafeHouse.Logger.Log("Boot file name is \"None\", skipping boot script"); } + else if (shared.VolumeMgr.CurrentVolume.Open(filename) == null) { SafeHouse.Logger.Log(string.Format("Boot file \"{0}\" is missing, skipping boot script", filename)); } + else + { + var bootContext = "program"; + string bootCommand = string.Format("run {0}.", filename); + + var options = new CompilerOptions + { + LoadProgramsInSameAddressSpace = true, + FuncManager = shared.FunctionManager, + IsCalledFromRun = false + }; - var programContext = ((CPU)shared.Cpu).SwitchToProgramContext(); + shared.ScriptHandler.ClearContext(bootContext); + List parts = shared.ScriptHandler.Compile( + "sys:boot", 1, bootCommand, bootContext, options); + + IProgramContext programContext = SwitchToProgramContext(); programContext.Silent = true; - var options = new CompilerOptions { LoadProgramsInSameAddressSpace = true }; - string filePath = shared.VolumeMgr.GetVolumeRawIdentifier(shared.VolumeMgr.CurrentVolume) + "/" + "boot"; - List parts = shared.ScriptHandler.Compile(filePath, 1, "run boot.", "program", options); programContext.AddParts(parts); } } @@ -148,7 +167,7 @@ private void PopContext() if (contexts.Any()) { // remove the last context - var contextRemove = contexts.Last(); + ProgramContext contextRemove = contexts.Last(); contexts.Remove(contextRemove); contextRemove.DisableActiveFlyByWire(shared.BindingMgr); SafeHouse.Logger.Log("Removed Context " + contextRemove.GetCodeFragment(0).FirstOrDefault()); @@ -171,16 +190,16 @@ private void PopContext() } } } - + /// /// Push a single thing onto the secret "over" stack. /// public void PushAboveStack(object thing) { PushStack(thing); - MoveStackPointer(-1); + MoveStackPointer(-1); } - + /// /// Pop one or more things from the secret "over" stack, only returning the /// finalmost thing popped. (i.e if you pop 3 things then you get: @@ -188,7 +207,7 @@ public void PushAboveStack(object thing) /// public object PopAboveStack(int howMany) { - object returnVal = new Int32(); // bogus return val if given a bogus "pop zero things" request. + object returnVal = new int(); // bogus return val if given a bogus "pop zero things" request. while (howMany > 0) { MoveStackPointer(1); @@ -205,14 +224,14 @@ private void PopFirstContext() PopContext(); } } - + /// /// Build a clone of the current state of the scope stack, for the sake of capturing a closure. /// /// A stripped down copy of the stack with just the relevant closure frames in it. public List GetCurrentClosure() { - List closureList = new List(); + var closureList = new List(); GetNestedDictionary("", closureList); // The closure's variable scopes need to be marked as such, so the // 'popscope' opcode knows to pop them off in one go when it hits @@ -221,13 +240,13 @@ public List GetCurrentClosure() scope.IsClosure = true; return closureList; } - + /// /// Build a delegate call for the given function entry point, in which it will capture a closure of the current /// runtime scoping state to be used when that function gets called later by OpcodeCall: /// /// Integer location in memory to jump to to start the call - /// Should the closure be captured for this delegate or ignored + /// Should the closure be captured for this delegate or ignored /// The delegate object you can store in a variable. public IUserDelegate MakeUserDelegate(int entryPoint, bool withClosure) { @@ -239,7 +258,7 @@ public IProgramContext GetInterpreterContext() { return contexts[0]; } - + public IProgramContext SwitchToProgramContext() { if (contexts.Count == 1) @@ -248,12 +267,12 @@ public IProgramContext SwitchToProgramContext() } return currentContext; } - + public Opcode GetCurrentOpcode() { return currentContext.Program[currentContext.InstructionPointer]; } - + public Opcode GetOpcodeAt(int instructionPtr) { if (instructionPtr < 0 || instructionPtr >= currentContext.Program.Count) @@ -265,17 +284,19 @@ public Opcode GetOpcodeAt(int instructionPtr) private void SaveAndClearPointers() { - // To be honest, I'm a little afraid of this. It appears to be doing - // something with locks (and now user functions) whenever you - // switch contexts from interpreter to program and it seems to be - // presuming the only such pointers that need to exist are going to be - // global. This was written by marianoapp before I added locals, - // and I don't understand what it's for -- Dunbaratu - - savedPointers = new VariableScope(0,-1); + // Any global variable that ends in an asterisk (*) is a system pointer + // that shouldn't be inherited by other program contexts. These sorts of + // variables should only exist for the current program context. + // This method stashes all such variables in a storage area for the program + // context, then clears them. The stash can be used later by RestorePointers() + // to bring them back into existence when coming back to this program context again. + // Pointer variables include: + // IP jump location for subprograms. + // IP jump location for functions. + savedPointers = new VariableScope(0, -1); var pointers = new List(globalVariables.Variables.Keys.Where(v => v.Contains('*'))); - foreach (var pointerName in pointers) + foreach (string pointerName in pointers) { savedPointers.Variables.Add(pointerName, globalVariables.Variables[pointerName]); globalVariables.Variables.Remove(pointerName); @@ -285,17 +306,14 @@ private void SaveAndClearPointers() private void RestorePointers() { - // To be honest, I'm a little afraid of this. It appears to be doing - // something with locks (and now user functions) whenever you - // switch contexts from program to interpreter and it seems to be - // presuming the only such pointers that need to exist are going to be - // global. This was written by marianoapp before I added locals, - // and I don't understand what it's for -- Dunbaratu - - int restoredPointers = 0; - int deletedPointers = 0; - - foreach (var item in savedPointers.Variables) + // Pointer variables that were stashed by SaveAndClearPointers() get brought + // back again by this method when returning to the previous programming + // programming context. + + var restoredPointers = 0; + var deletedPointers = 0; + + foreach (KeyValuePair item in savedPointers.Variables) { if (globalVariables.Variables.ContainsKey(item.Key)) { @@ -377,20 +395,21 @@ public void MoveStackPointer(int delta) { stack.MoveStackPointer(delta); } - + /// Throw exception if the user delegate is not one the CPU can call right now. /// The userdelegate being checked - /// thrown if the cpu is in a state where it can't call this delegate. + /// thrown if the cpu is in a state where it can't call this delegate. public void AssertValidDelegateCall(IUserDelegate userDelegate) { - if (userDelegate.ProgContext != currentContext) { - throw new KOSInvalidDelegateContext( - (currentContext == contexts[0] ? "the interpreter" : "a program" ), - (currentContext == contexts[0] ? "a program" : "the interpreter" ) + if (userDelegate.ProgContext != currentContext) + { + throw new KOSInvalidDelegateContextException( + (currentContext == contexts[0] ? "the interpreter" : "a program"), + (currentContext == contexts[0] ? "a program" : "the interpreter") ); } } - + /// /// Gets the dictionary N levels of nesting down the dictionary stack, /// where zero is the current localmost level. @@ -404,7 +423,7 @@ public void AssertValidDelegateCall(IUserDelegate userDelegate) private VariableScope GetNestedDictionary(int peekDepth) { object stackItem = true; // any non-null value will do here, just to get the loop started. - for (int rawStackDepth = 0 ; stackItem != null && peekDepth >= 0; ++rawStackDepth) + for (var rawStackDepth = 0; stackItem != null && peekDepth >= 0; ++rawStackDepth) { stackItem = stack.Peek(-1 - rawStackDepth); if (stackItem is VariableScope) @@ -412,9 +431,11 @@ private VariableScope GetNestedDictionary(int peekDepth) if (stackItem is SubroutineContext) stackItem = null; // once we hit the bottom of the current subroutine on the runtime stack - jump all the way out to global. } - return stackItem == null ? globalVariables : (VariableScope) stackItem; + + var scope = stackItem as VariableScope; + return scope ?? globalVariables; } - + /// /// Gets the dictionary that contains the given identifier, starting the /// search at the local level and scanning the scopes upward all the @@ -424,7 +445,7 @@ private VariableScope GetNestedDictionary(int peekDepth) /// of the parse tree. (i.e. if a function calls a function elsewhere).
/// Returns null when no hit was found.
///
- /// identifier name to search for. Pass an empty string to guarentee no hits will + /// identifier name to search for. Pass an empty string to guarantee no hits will /// be found (which is useful to do when using the searchReport argument). /// If you want to see the list of all the scopes that constituted the search /// path, not just the final hit, pass an empty list here and this method will fill it for you with @@ -432,16 +453,16 @@ private VariableScope GetNestedDictionary(int peekDepth) /// The dictionary found, or null if no dictionary contains the identifier. private VariableScope GetNestedDictionary(string identifier, List searchReport = null) { - if (searchReport != null) + if (searchReport != null) searchReport.Clear(); - Int16 rawStackDepth = 0 ; + short rawStackDepth = 0; while (true) /*all of this loop's exits are explicit break or return statements*/ { object stackItem; bool stackExhausted = !(stack.PeekCheck(-1 - rawStackDepth, out stackItem)); - if (stackExhausted) + if (stackExhausted) break; - VariableScope localDict = stackItem as VariableScope; + var localDict = stackItem as VariableScope; if (localDict == null) // some items on the stack might not be variable scopes. skip them. { ++rawStackDepth; @@ -450,20 +471,20 @@ private VariableScope GetNestedDictionary(string identifier, List if (searchReport != null) searchReport.Add(localDict); - + if (localDict.Variables.ContainsKey(identifier)) return localDict; - + // Get the next VariableScope that is valid, where valid means: // It is the lexical (not runtime) parent of this scope. // ------------------------------------------------------------------------------- // Scan the stack until the variable scope with the right parent ID is seen: - Int16 skippedLevels = 0; - while ( !(stackExhausted)) + short skippedLevels = 0; + while (!(stackExhausted)) { - bool needsIncrement = true; - VariableScope scopeFrame = stackItem as VariableScope; + var needsIncrement = true; + var scopeFrame = stackItem as VariableScope; if (scopeFrame != null) // skip cases where the thing on the stack isn't a variable scope. { // If the scope id of this frame is my parent ID, then we found it and are done. @@ -488,7 +509,7 @@ private VariableScope GetNestedDictionary(string identifier, List } stackExhausted = !(stack.PeekCheck(-1 - rawStackDepth, out stackItem)); } - + // Record how many levels had to be skipped for that to work. In future calls of this // method, it will know how far to jump in the stack without doing that scan. This can // be quite a speedup when dealing with nested recursion, where the runtime stack might @@ -522,20 +543,33 @@ public List GetCallTrace() /// private Variable GetOrCreateVariable(string identifier) { - Variable variable = GetVariable(identifier,false,true); + Variable variable = GetVariable(identifier, false, true); if (variable == null) { - variable = new Variable {Name = identifier}; + variable = new Variable { Name = identifier }; AddVariable(variable, identifier, false); } return variable; } - + + /// + /// Test if an identifier is a variable you can get the value of + /// at the moment (var name exists and is in scope). Return + /// true if you can, false if you can't. + /// + /// + /// + public bool IdentifierExistsInScope(string identifier) + { + Variable dummyVal = GetVariable(identifier, false, true); + return (dummyVal != null); + } + public string DumpVariables() { var msg = new StringBuilder(); msg.AppendLine("============== STACK VARIABLES ==============="); - msg.AppendLine(stack.Dump()); + DumpStack(); msg.AppendLine("============== GLOBAL VARIABLES =============="); foreach (string ident in globalVariables.Variables.Keys) { @@ -545,7 +579,7 @@ public string DumpVariables() Variable v = globalVariables.Variables[ident]; line = ident; if (v == null || v.Value == null) - line += "is "; + line += " is "; else line += " is a " + v.Value.GetType().FullName + " with value = " + v.Value; } @@ -553,7 +587,7 @@ public string DumpVariables() { // This is necessary because of the deprecation exceptions that // get raised by FlightStats when you try to print all of them out: - line = ident + "= \n " + e.Message; + line = ident + " is \n " + e.Message; } msg.AppendLine(line); } @@ -561,6 +595,11 @@ public string DumpVariables() return "Variable dump is in the output log"; } + public string DumpStack() + { + return stack.Dump(); + } + /// /// Get the variable's contents, performing a lookup through all nesting levels /// up to global. @@ -580,12 +619,23 @@ private Variable GetVariable(string identifier, bool barewordOkay = false, bool if (barewordOkay) { string strippedIdent = identifier.TrimStart('$'); - return new Variable {Name = strippedIdent, Value = strippedIdent}; + return new Variable { Name = strippedIdent, Value = strippedIdent }; } if (failOkay) return null; - else - throw new KOSUndefinedIdentifierException(identifier.TrimStart('$'),""); + // In the case where we were looking for a function pointer but didn't find one, and would + // have failed with exception, then it's still acceptable to find a hit that isn't a function + // pointer (has no trailing asterisk '*') but only if it's a delegate of some sort: + if (identifier.EndsWith("*")) + { + string trimmedTail = identifier.TrimEnd('*'); + Variable retryVal = GetVariable(trimmedTail, barewordOkay, failOkay); + string trimmedLeader = trimmedTail.TrimStart('$'); + if (retryVal.Value is KOSDelegate) + return retryVal; + throw new KOSNotInvokableException(trimmedLeader); + } + throw new KOSUndefinedIdentifierException(identifier.TrimStart('$'), ""); } /// @@ -601,17 +651,13 @@ private Variable GetVariable(string identifier, bool barewordOkay = false, bool public void AddVariable(Variable variable, string identifier, bool local, bool overwrite = false) { identifier = identifier.ToLower(); - + if (!identifier.StartsWith("$")) { identifier = "$" + identifier; } - - VariableScope whichDict; - if (local) - whichDict = GetNestedDictionary(0); - else - whichDict = globalVariables; + + VariableScope whichDict = local ? GetNestedDictionary(0) : globalVariables; if (whichDict.Variables.ContainsKey(identifier)) { if (whichDict.Variables[identifier].Value is BoundVariable) @@ -640,10 +686,10 @@ public void RemoveVariable(string identifier) VariableScope foundDict = GetNestedDictionary(identifier); if (foundDict != null && VariableIsRemovable(foundDict.Variables[identifier])) { - // Tell Variable to orphan its old value now. Faster than relying + // Tell Variable to orphan its old value now. Faster than relying // on waiting several seconds for GC to eventually call ~Variable() foundDict.Variables[identifier].Value = null; - + foundDict.Variables.Remove(identifier); } } @@ -669,16 +715,17 @@ public object GetValue(object testValue, bool barewordOkay = false) // If it's a variable, meaning it starts with "$" but // does NOT have a value like $<.....>, which are special // flags used internally: - if (testValue is string && - ((string)testValue).Length > 1 && - ((string)testValue)[0] == '$' && - ((string)testValue)[1] != '<' ) + var identifier = testValue as string; + if (identifier == null || + identifier.Length <= 1 || + identifier[0] != '$' || + identifier[1] == '<') { - var identifier = (string)testValue; - Variable variable = GetVariable(identifier, barewordOkay); - return variable.Value; + return testValue; } - return testValue; + + Variable variable = GetVariable(identifier, barewordOkay); + return variable.Value; } /// @@ -689,7 +736,7 @@ public object GetValue(object testValue, bool barewordOkay = false) /// This does NOT scan up the scoping stack like SetValue() does. /// It operates at the local level only.
///
- /// This is the normal way to make a new local variable. You cannot make a + /// This is the normal way to make a new local variable. You cannot make a /// local variable without attempting to give it a value. ///
/// variable name to attempt to store into @@ -698,10 +745,10 @@ public void SetNewLocal(string identifier, object value) { Variable variable; VariableScope localDict = GetNestedDictionary(0); - if (! localDict.Variables.TryGetValue(identifier, out variable)) + if (!localDict.Variables.TryGetValue(identifier, out variable)) { - variable = new Variable {Name = identifier}; - AddVariable(variable, identifier, true); + variable = new Variable { Name = identifier }; + AddVariable(variable, identifier, true); } variable.Value = value; } @@ -722,10 +769,10 @@ public void SetGlobal(string identifier, object value) // Attempt to get it as a global. Make a new one if it's not found. // This preserves the "bound-ness" of the variable if it's a // BoundVariable, whereas unconditionally making a new Variable wouldn't: - if (! globalVariables.Variables.TryGetValue(identifier, out variable)) + if (!globalVariables.Variables.TryGetValue(identifier, out variable)) { - variable = new Variable {Name = identifier}; - AddVariable(variable, identifier, false, true); + variable = new Variable { Name = identifier }; + AddVariable(variable, identifier, false, true); } variable.Value = value; } @@ -739,7 +786,7 @@ public void SetGlobal(string identifier, object value) /// If no such value is found, all the way up to the global level, /// then it resorts to making a global variable with the name and using that.
///
- /// This is the normal way to make a new global variable. You cannot make a + /// This is the normal way to make a new global variable. You cannot make a /// global variable without attempting to give it a value. ///
/// variable name to attempt to store into @@ -749,7 +796,7 @@ public void SetValue(string identifier, object value) Variable variable = GetOrCreateVariable(identifier); variable.Value = value; } - + /// /// Try to set the value of the identifier at the localmost /// level possible, by scanning up the scope stack to find @@ -780,7 +827,7 @@ public object PopValue(bool barewordOkay = false) { return GetValue(PopStack(), barewordOkay); } - + /// /// Peek at a value atop the stack without popping it, and if it's a variable name then get its value, /// else just return it as it is.
@@ -799,6 +846,102 @@ public object PeekValue(int digDepth, bool barewordOkay = false) return GetValue(stack.Peek(digDepth), barewordOkay); } + /// + /// Identical to PopValue(), except that it guarantees the return value is either already a Structure, + /// or it converts it into a Structure if it's a primitive. + /// It bombs out with an exception if it can't be converted thusly. + ///
+ /// Use this in places where the stack value *must* come out as an encapsulated value and something + /// has gone seriously wrong if it can't. This applies to cases where you are attempting to store + /// its value inside a user's variable, mostly. + ///
+ /// Is this a context in which it's acceptable for + /// a variable not existing error to occur (in which case the identifier itself + /// should therefore become a string object returned)? + /// value off the stack + public Structure PopStructureEncapsulated(bool barewordOkay = false) + { + return Structure.FromPrimitiveWithAssert( PopValue(barewordOkay) ); + } + + /// + /// Identical to PeekValue(), except that it guarantees the return value is either already a Structure, + /// or it converts it into a Structure if it's a primitive. + /// It bombs out with an exception if it can't be converted thusly. + ///
+ /// Use this in places where the stack value *must* come out as an encapsulated value and something + /// has gone seriously wrong if it can't. This applies to cases where you are attempting to store + /// its value inside a user's variable, mostly. + ///
+ /// Peek at the element this far down the stack (0 means top, 1 means just under the top, etc) + /// Is this a context in which it's acceptable for + /// a variable not existing error to occur (in which case the identifier itself + /// should therefore become a string object returned)? + /// value off the stack + public Structure PeekStructureEncapsulated(int digDepth, bool barewordOkay = false) + { + return Structure.FromPrimitiveWithAssert(PeekValue(digDepth, barewordOkay)); + } + + /// + /// Identical to GetValue(), except that it guarantees the return value is either already a Structure, + /// or it converts it into a Structure if it's a primitive. + /// It bombs out with an exception if it can't be converted thusly. + ///
+ /// Use this in places where the stack value *must* come out as an encapsulated value and something + /// has gone seriously wrong if it can't. This applies to cases where you are attempting to store + /// its value inside another user's variable, mostly. + ///
+ /// Hypothetically this should never really be required, as the value is coming FROM a user varible + /// in the first place. + ///
+ /// the object which might be a variable name + /// + /// Is this a case in which it's acceptable for the + /// variable not to exist, and if it doesn't exist then the variable name itself + /// is the value? + /// + /// The value after the steps described have been performed. + public Structure GetStructureEncapsulated(Structure testValue, bool barewordOkay = false) + { + return Structure.FromPrimitiveWithAssert(GetValue(testValue, barewordOkay)); + } + + /// + /// Identical to PopStructureEncapsulated(), except that it doesn't complain if the + /// result can't be converted to a Structure. It's acceptable for it to not be + /// a Structure, in which case the original object is returned as-is. + ///
+ /// Use this in places where the stack value *should* come out as an encapsulated value if it can, + /// but there are some valid cases where it might not be. + ///
+ /// Is this a context in which it's acceptable for + /// a variable not existing error to occur (in which case the identifier itself + /// should therefore become a string object returned)? + /// value off the stack + public object PopValueEncapsulated(bool barewordOkay = false) + { + return Structure.FromPrimitive( PopValue(barewordOkay) ); + } + + /// + /// Identical to PeekStructureEncapsulated(), except that it doesn't complain if the + /// result can't be converted to a Structure. It's acceptable for it to not be + /// a Structure, in which case the original object is returned as-is. + ///
+ /// Use this in places where the stack value *should* come out as an encapsulated value if it can, + /// but there are some valid cases where it might not be. + ///
+ /// Peek at the element this far down the stack (0 means top, 1 means just under the top, etc) + /// Is this a context in which it's acceptable for + /// a variable not existing error to occur (in which case the identifier itself + /// should therefore become a string object returned)? + /// value off the stack + public object PeekValueEncapsulated(int digDepth, bool barewordOkay = false) + { + return Structure.FromPrimitive(PeekValue(digDepth, barewordOkay)); + } + /// /// Peek at a value atop the stack without popping it, and without evaluating it to get the variable's /// value. (i.e. if the thing in the stack is $foo, and the variable foo has value 5, you'll get the string @@ -806,14 +949,14 @@ public object PeekValue(int digDepth, bool barewordOkay = false) /// /// Peek at the element this far down the stack (0 means top, 1 means just under the top, etc) /// Tells you whether or not the stack was exhausted. If it's false, then the peek went too deep. - /// value off the stack + /// value off the stack public object PeekRaw(int digDepth, out bool checkOkay) { object returnValue; - checkOkay = stack.PeekCheck(digDepth,out returnValue); + checkOkay = stack.PeekCheck(digDepth, out returnValue); return returnValue; } - + public int GetStackSize() { return stack.GetLogicalSize(); @@ -849,20 +992,22 @@ public void EndWait() public void KOSFixedUpdate(double deltaTime) { - bool showStatistics = Config.Instance.ShowStatistics; + bool showStatistics = SafeHouse.Config.ShowStatistics; Stopwatch updateWatch = null; Stopwatch triggerWatch = null; Stopwatch executionWatch = null; - + var triggerElapsed = 0.0; + var executionElapsed = 0.0; + // If the script changes config value, it doesn't take effect until next update: - instructionsPerUpdate = Config.Instance.InstructionsPerUpdate; + instructionsPerUpdate = SafeHouse.Config.InstructionsPerUpdate; instructionsSoFarInUpdate = 0; - int numTriggerInstructions = 0; - int numMainlineInstructions = 0; + var numTriggerInstructions = 0; + var numMainlineInstructions = 0; if (showStatistics) updateWatch = Stopwatch.StartNew(); - currentTime = shared.UpdateHandler.CurrentTime; + currentTime = shared.UpdateHandler.CurrentFixedTime; try { @@ -876,7 +1021,8 @@ public void KOSFixedUpdate(double deltaTime) if (showStatistics) { triggerWatch.Stop(); - totalTriggersTime += triggerWatch.ElapsedMilliseconds; + triggerElapsed = triggerWatch.ElapsedMilliseconds; + totalTriggersTime += triggerElapsed; } ProcessWait(); @@ -889,14 +1035,17 @@ public void KOSFixedUpdate(double deltaTime) if (showStatistics) { executionWatch.Stop(); - totalExecutionTime += executionWatch.ElapsedMilliseconds; + executionElapsed = executionWatch.ElapsedMilliseconds; + totalExecutionTime += executionElapsed; } } } + if (showStatistics) + { + } PostUpdateBindings(); } - catch (Exception e) { if (shared.Logger != null) @@ -922,11 +1071,18 @@ public void KOSFixedUpdate(double deltaTime) if (showStatistics) { updateWatch.Stop(); - totalUpdateTime += updateWatch.ElapsedMilliseconds; + double updateElapsed = updateWatch.ElapsedMilliseconds; + totalUpdateTime += updateElapsed; if (maxTriggerInstructionsSoFar < numTriggerInstructions) maxTriggerInstructionsSoFar = numTriggerInstructions; if (maxMainlineInstructionsSoFar < numMainlineInstructions) maxMainlineInstructionsSoFar = numMainlineInstructions; + if (maxUpdateTime < updateElapsed) + maxUpdateTime = updateElapsed; + if (maxTriggersTime < triggerElapsed) + maxTriggersTime = triggerElapsed; + if (maxExecutionTime < executionElapsed) + maxExecutionTime = executionElapsed; } } @@ -960,6 +1116,7 @@ private void ProcessWait() private void ProcessTriggers() { if (currentContext.Triggers.Count <= 0) return; + int oldCount = currentContext.Program.Count; int currentInstructionPointer = currentContext.InstructionPointer; var triggerList = new List(currentContext.Triggers); @@ -968,17 +1125,22 @@ private void ProcessTriggers() { try { - currentContext.InstructionPointer = triggerPointer; - - bool executeNext = true; - executeLog.Remove(0,executeLog.Length); // why doesn't StringBuilder just have a Clear() operator? - while (executeNext && instructionsSoFarInUpdate < instructionsPerUpdate) + // If the program is ended from within a trigger, the trigger list will be empty and the pointer + // will be invalid. Only execute the trigger if it still exists. + if (currentContext.Triggers.Contains(triggerPointer)) { - executeNext = ExecuteInstruction(currentContext); - instructionsSoFarInUpdate++; + currentContext.InstructionPointer = triggerPointer; + + var executeNext = true; + executeLog.Remove(0, executeLog.Length); // why doesn't StringBuilder just have a Clear() operator? + while (executeNext && instructionsSoFarInUpdate < instructionsPerUpdate) + { + executeNext = ExecuteInstruction(currentContext); + instructionsSoFarInUpdate++; + } + if (executeLog.Length > 0) + SafeHouse.Logger.Log(executeLog.ToString()); } - if (executeLog.Length > 0) - SafeHouse.Logger.Log(executeLog.ToString()); } catch (Exception e) { @@ -991,14 +1153,19 @@ private void ProcessTriggers() } } - currentContext.InstructionPointer = currentInstructionPointer; + // since `run` opcodes don't work in triggers, we can use the opcode count to determine if the + // program has been aborted. If the count isn't right, leave the pointer where it is. + if (oldCount == currentContext.Program.Count) + { + currentContext.InstructionPointer = currentInstructionPointer; + } } private void ContinueExecution() { - bool executeNext = true; - executeLog.Remove(0,executeLog.Length); // why doesn't StringBuilder just have a Clear() operator? - while (currentStatus == Status.Running && + var executeNext = true; + executeLog.Remove(0, executeLog.Length); // why doesn't StringBuilder just have a Clear() operator? + while (currentStatus == Status.Running && instructionsSoFarInUpdate < instructionsPerUpdate && executeNext && currentContext != null) @@ -1012,27 +1179,38 @@ private void ContinueExecution() private bool ExecuteInstruction(IProgramContext context) { - bool DEBUG_EACH_OPCODE = false; - Opcode opcode = context.Program[context.InstructionPointer]; - if (DEBUG_EACH_OPCODE) + + if (SafeHouse.Config.DebugEachOpcode) { - executeLog.Append(String.Format("Executing Opcode {0:0000}/{1:0000} {2} {3}\n", - context.InstructionPointer, context.Program.Count, opcode.Label, opcode.ToString())); + executeLog.Append(string.Format("Executing Opcode {0:0000}/{1:0000} {2} {3}\n", context.InstructionPointer, context.Program.Count, opcode.Label, opcode)); + executeLog.Append(string.Format("Prior to exeucting, stack looks like this:\n{0}\n", DumpStack())); } try { - if (!(opcode is OpcodeEOF || opcode is OpcodeEOP)) - { - opcode.Execute(this); - context.InstructionPointer += opcode.DeltaInstructionPointer; - return true; - } - if (opcode is OpcodeEOP) + opcode.AbortContext = false; + opcode.AbortProgram = false; + opcode.Execute(this); + if (opcode.AbortProgram) { BreakExecution(false); SafeHouse.Logger.Log("Execution Broken"); + return false; + } + + if (opcode.AbortContext) + { + return false; + } + + int prevPointer = context.InstructionPointer; + context.InstructionPointer += opcode.DeltaInstructionPointer; + if (context.InstructionPointer < 0 || context.InstructionPointer >= context.Program.Count) + { + throw new KOSBadJumpException( + context.InstructionPointer, string.Format("after executing {0:0000} {1} {2}", prevPointer, opcode.Label, opcode)); } + return true; } catch (Exception) { @@ -1042,7 +1220,6 @@ private bool ExecuteInstruction(IProgramContext context) SafeHouse.Logger.Log(executeLog.ToString()); throw; } - return false; } private void SkipCurrentInstructionId() @@ -1051,7 +1228,7 @@ private void SkipCurrentInstructionId() string currentSourceName = currentContext.Program[currentContext.InstructionPointer].SourceName; - while (currentContext.InstructionPointer < currentContext.Program.Count && + while (currentContext.InstructionPointer < currentContext.Program.Count && currentContext.Program[currentContext.InstructionPointer].SourceName == currentSourceName) { currentContext.InstructionPointer++; @@ -1062,7 +1239,7 @@ public void CallBuiltinFunction(string functionName) { shared.FunctionManager.CallFunction(functionName); } - + public bool BuiltInExists(string functionName) { return shared.FunctionManager.Exists(functionName); @@ -1088,12 +1265,15 @@ public List GetCodeFragment(int contextLines) public void PrintStatistics() { - if (!Config.Instance.ShowStatistics) return; + if (!SafeHouse.Config.ShowStatistics) return; shared.Screen.Print(string.Format("Total compile time: {0:F3}ms", totalCompileTime)); shared.Screen.Print(string.Format("Total update time: {0:F3}ms", totalUpdateTime)); shared.Screen.Print(string.Format("Total triggers time: {0:F3}ms", totalTriggersTime)); shared.Screen.Print(string.Format("Total execution time: {0:F3}ms", totalExecutionTime)); + shared.Screen.Print(string.Format("Maximum update time: {0:F3}ms", maxUpdateTime)); + shared.Screen.Print(string.Format("Maximum triggers time: {0:F3}ms", maxTriggersTime)); + shared.Screen.Print(string.Format("Maximum execution time: {0:F3}ms", maxExecutionTime)); shared.Screen.Print(string.Format("Most Trigger instructions in one update: {0}", maxTriggerInstructionsSoFar)); shared.Screen.Print(string.Format("Most Mainline instructions in one update: {0}", maxMainlineInstructionsSoFar)); shared.Screen.Print(" "); @@ -1102,100 +1282,16 @@ public void PrintStatistics() totalUpdateTime = 0D; totalTriggersTime = 0D; totalExecutionTime = 0D; + maxUpdateTime = 0.0; + maxTriggersTime = 0.0; + maxExecutionTime = 0.0; maxMainlineInstructionsSoFar = 0; maxTriggerInstructionsSoFar = 0; } - public void OnSave(ConfigNode node) - { - try - { - var contextNode = new ConfigNode("context"); - - // Save variables - if (globalVariables.Variables.Count > 0) - { - var varNode = new ConfigNode("variables"); - - foreach (var kvp in globalVariables.Variables) - { - if (!(kvp.Value is BoundVariable) && - (kvp.Value.Name.IndexOfAny(new[] { '*', '-' }) == -1)) // variables that have this characters are internal and shouldn't be persisted - { - if (kvp.Value.Value.GetType().ToString() == "System.String") // if the variable is a string, enclose the value in "" - { - varNode.AddValue(kvp.Key.TrimStart('$'), (char)34 + PersistenceUtilities.EncodeLine(kvp.Value.Value.ToString()) + (char)34); - } - else - { - varNode.AddValue(kvp.Key.TrimStart('$'), PersistenceUtilities.EncodeLine(kvp.Value.Value.ToString())); - } - } - } - - contextNode.AddNode(varNode); - } - - node.AddNode(contextNode); - } - catch (Exception e) - { - if (shared.Logger != null) shared.Logger.Log(e); - } - } - - public void OnLoad(ConfigNode node) - { - try - { - var scriptBuilder = new StringBuilder(); - - foreach (ConfigNode contextNode in node.GetNodes("context")) - { - foreach (ConfigNode varNode in contextNode.GetNodes("variables")) - { - foreach (ConfigNode.Value value in varNode.values) - { - string varValue = PersistenceUtilities.DecodeLine(value.value); - scriptBuilder.AppendLine(string.Format("set {0} to {1}.", value.name, varValue)); - } - } - } - - if (shared.ScriptHandler == null || scriptBuilder.Length <= 0) return; - - var programBuilder = new ProgramBuilder(); - // TODO: figure out how to store the filename and reload it for arg 1 below: - // (Possibly all of OnLoad needs work because it never seemed to bring - // back the context fully right anyway, which is why this hasn't been - // addressed yet). - try - { - SafeHouse.Logger.Log("Parsing Context:\n\n" + scriptBuilder); - - // TODO - make this set up compiler options and pass them in properly, so we can detect built-ins properly. - // (for the compiler to detect the difference between a user function call and a built-in, it needs to be - // passed the FunctionManager object from Shared.) - // this isn't fixed mainly because this OnLoad() code is a major bug fire already anyway and needs to be - // fixed, but that's way out of scope for the moment: - programBuilder.AddRange(shared.ScriptHandler.Compile("reloaded file", 1, scriptBuilder.ToString())); - List program = programBuilder.BuildProgram(); - RunProgram(program, true); - } - catch (NullReferenceException ex) - { - SafeHouse.Logger.Log("program builder failed on load. " + ex.Message); - } - } - catch (Exception e) - { - if (shared.Logger != null) shared.Logger.Log(e); - } - } - public void Dispose() { shared.UpdateHandler.RemoveFixedObserver(this); } } -} +} \ No newline at end of file diff --git a/src/kOS.Safe/Execution/ICpu.cs b/src/kOS.Safe/Execution/ICpu.cs index 60664fc0c..7be3dad0d 100644 --- a/src/kOS.Safe/Execution/ICpu.cs +++ b/src/kOS.Safe/Execution/ICpu.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using kOS.Safe.Compilation; +using kOS.Safe.Encapsulation; namespace kOS.Safe.Execution { @@ -15,14 +16,21 @@ public interface ICpu : IFixedUpdateObserver void AssertValidDelegateCall(IUserDelegate userDelegate); object GetValue(object testValue, bool barewordOkay = false); object PopValue(bool barewordOkay = false); - object PeekValue(int digDepth, bool barewordOkay = false); + object PeekValue(int digDepth, bool barewordOkay = false); object PeekRaw(int digDepth, out bool checkOkay); + object PopValueEncapsulated(bool barewordOkay = false); + object PeekValueEncapsulated(int digDepth, bool barewordOkay = false); + Structure GetStructureEncapsulated(Structure testValue, bool barewordOkay = false); + Structure PopStructureEncapsulated(bool barewordOkay = false); + Structure PeekStructureEncapsulated(int digDepth, bool barewordOkay = false); int GetStackSize(); void SetValue(string identifier, object value); void SetValueExists(string identifier, object value); void SetNewLocal(string identifier, object value); void SetGlobal(string identifier, object value); + bool IdentifierExistsInScope(string identifier); string DumpVariables(); + string DumpStack(); void RemoveVariable(string identifier); int InstructionPointer { get; set; } double SessionTime { get; } @@ -36,6 +44,7 @@ public interface ICpu : IFixedUpdateObserver void AddVariable(Variable variable, string identifier, bool local, bool overwrite = false); Opcode GetOpcodeAt(int instructionPtr); void Boot(); + int InstructionsThisUpdate { get; } /// /// Return the subroutine call trace of how the code got to where it is right now. diff --git a/src/kOS.Safe/Execution/KOSArgMarkerType.cs b/src/kOS.Safe/Execution/KOSArgMarkerType.cs new file mode 100644 index 000000000..db081402b --- /dev/null +++ b/src/kOS.Safe/Execution/KOSArgMarkerType.cs @@ -0,0 +1,18 @@ +using System; + +namespace kOS.Safe.Execution +{ + /// + /// ArgMarkerType literally serves no purpose whatsoever other + /// than to just be a mark of where on the stack is the bottom of + /// the aruments to something. If an object is of this type, then + /// that means it's the argument botttom marker. + /// + public class KOSArgMarkerType + { + public override string ToString() + { + return "_KOSArgMarker_"; + } + } +} diff --git a/src/kOS.Safe/Execution/KOSPassThruReturn.cs b/src/kOS.Safe/Execution/KOSPassThruReturn.cs new file mode 100644 index 000000000..2855eca21 --- /dev/null +++ b/src/kOS.Safe/Execution/KOSPassThruReturn.cs @@ -0,0 +1,48 @@ +using kOS.Safe.Encapsulation; + +namespace kOS.Safe.Execution +{ + /// + /// This is a special "type" used as a dummy return type for + /// KOS suffixes and built-ins to indicate that when executing + /// them in OpcodeCall, their return value should not even exist + /// on the stack at all.
+ ///
+ /// Normally, kOS puts a dummy return on the + /// stack even for "void" suffixes, that will get popped off by an + /// OpcodePop as the next instruction. But in the case where the suffix + /// is meant to wait for user code to finish executing in order to get + /// the return value (such as the suffix KOSDelegate:CALL()), this makes + /// a problem.
+ ///
+ /// The problem is that user code like a user function won't actually start + /// executing until after the OpcodeGetMember or OpcodeGetMethod that was + /// calling the suffix finishes its current opcode. So if they push a return + /// value onto the stack before they finish, then that return value gets in + /// the way of the arguments being sent to the user function that hasn't + /// had a chance to start yet.
+ ///
+ /// This must ONLY be ever used by suffixes that intend to let some other + /// part of their call push a return value onto the cpu stack rather than + /// having it be returned by the suffix call itself.
+ ///
+ /// (For example, when performing user delegate calls with :CALL). + ///
+ [kOS.Safe.Utilities.KOSNomenclature("ScriptsShouldntSeeThisType_KOSPassThruReturn")] + public class KOSPassThruReturn : Structure + + // This is derived from Structure ONLY because it is + // a thing the :CALL() suffix can temporarily return + // on the stack, and suffixes have been changed so the + // thing they return MUST now be derived from Structure. + // Making this be derived from Structure was the easiest + // way to keep the CALL() suffix working. This is a dummy + // placeholder anyway, so the fact that it's derived from + // Suffix doesn't mean much, other than allowing it to + // be the value of DelegateSuffixResult.value. + { + public KOSPassThruReturn() + { + } + } +} diff --git a/src/kOS/Execution/ProgramContext.cs b/src/kOS.Safe/Execution/ProgramContext.cs similarity index 83% rename from src/kOS/Execution/ProgramContext.cs rename to src/kOS.Safe/Execution/ProgramContext.cs index 40f5081c7..a0857e6a8 100644 --- a/src/kOS/Execution/ProgramContext.cs +++ b/src/kOS.Safe/Execution/ProgramContext.cs @@ -1,10 +1,9 @@ using System; using System.Collections.Generic; -using kOS.Binding; +using kOS.Safe.Binding; using kOS.Safe.Compilation; -using kOS.Safe.Execution; -namespace kOS.Execution +namespace kOS.Safe.Execution { public class ProgramContext : IProgramContext { @@ -86,7 +85,7 @@ public void ToggleFlyByWire(string paramName, bool enabled) } } - public void DisableActiveFlyByWire(BindingManager manager) + public void DisableActiveFlyByWire(IBindingManager manager) { foreach (KeyValuePair kvp in flyByWire) { if (kvp.Value) { @@ -95,7 +94,7 @@ public void DisableActiveFlyByWire(BindingManager manager) } } - public void EnableActiveFlyByWire(BindingManager manager) + public void EnableActiveFlyByWire(IBindingManager manager) { foreach (KeyValuePair kvp in flyByWire) { manager.ToggleFlyByWire(kvp.Key, kvp.Value); @@ -111,13 +110,21 @@ public List GetCodeFragment(int start, int stop) { var codeFragment = new List(); - const string FORMAT_STR = "{0,-20} {1,4}:{2,-3} {3:0000} {4} {5}"; - codeFragment.Add(string.Format(FORMAT_STR, "File", "Line", "Col", "IP ", "opcode", "operand")); - codeFragment.Add(string.Format(FORMAT_STR, "----", "----", "---", "----", "---------------------", "")); + const string FORMAT_STR = "{0,-20} {1,4}:{2,-3} {3:0000} {4} {5} {6}"; + codeFragment.Add(string.Format(FORMAT_STR, "File", "Line", "Col", "IP ", "label", "opcode", "operand")); + codeFragment.Add(string.Format(FORMAT_STR, "----", "----", "---", "----", "-------------------------------", "", "")); for (int index = start; index <= stop; index++) { if (index >= 0 && index < Program.Count) { - codeFragment.Add(string.Format(FORMAT_STR, Program[index].SourceName, Program[index].SourceLine, Program[index].SourceColumn, index, Program[index], (index == InstructionPointer ? "<<--INSTRUCTION POINTER--" : ""))); + codeFragment.Add(string.Format( + FORMAT_STR, + Program[index].SourceName, + Program[index].SourceLine, + Program[index].SourceColumn, + index, + Program[index].Label, + Program[index], + (index == InstructionPointer ? "<<--INSTRUCTION POINTER--" : ""))); } } diff --git a/src/kOS/Execution/Stack.cs b/src/kOS.Safe/Execution/Stack.cs similarity index 81% rename from src/kOS/Execution/Stack.cs rename to src/kOS.Safe/Execution/Stack.cs index c6b69a1c3..ed987d56d 100644 --- a/src/kOS/Execution/Stack.cs +++ b/src/kOS.Safe/Execution/Stack.cs @@ -1,14 +1,14 @@ using System; using System.Collections.Generic; using System.Text; -using kOS.Safe.Execution; -using kOS.Suffixed; +using kOS.Safe.Utilities; +using kOS.Safe.Encapsulation; -namespace kOS.Execution +namespace kOS.Safe.Execution { public class Stack : IStack { - private const int MAX_STACK_SIZE = 1000; + private const int MAX_STACK_SIZE = 3000; private readonly List stack = new List(); private int stackPointer = -1; @@ -17,25 +17,31 @@ public void Push(object item) ThrowIfInvalid(item); stackPointer++; - if (stackPointer < MAX_STACK_SIZE) { + if (stack.Count < MAX_STACK_SIZE) + { stack.Insert(stackPointer, ProcessItem(item)); - } else + } + else // TODO: make an IKOSException for this: throw new Exception("Stack overflow!!"); } private void ThrowIfInvalid(object item) { - if (!Config.Instance.EnableSafeMode) + if (!SafeHouse.Config.EnableSafeMode) return; - if (!(item is double)) + if (!(item is double || item is float || item is ScalarValue)) return; - if (Double.IsNaN((double)item)) { + double unboxed = Convert.ToDouble(item); + + if (double.IsNaN(unboxed)) + { // TODO: make an IKOSException for this: throw new Exception("Tried to push NaN into the stack."); } - if (Double.IsInfinity((double)item)) { + if (double.IsInfinity(unboxed)) + { // TODO: make an IKOSException for this: throw new Exception("Tried to push Infinity into the stack."); } @@ -49,8 +55,22 @@ private void ThrowIfInvalid(object item) private object ProcessItem(object item) { if (item is float) + { // promote floats to doubles - return Convert.ToDouble(item); + item = Convert.ToDouble(item); + } + if (item is double) + { + var doubleItem = (double)item; + var outOfBounds = int.MinValue < doubleItem && doubleItem < int.MaxValue; + + if (!double.IsNaN(doubleItem) && outOfBounds) + { + int intItem = Convert.ToInt32(item); + if (doubleItem == intItem) + item = intItem; + } + } return item; } @@ -58,7 +78,8 @@ public object Pop() { object item = null; - if (stack.Count > 0) { + if (stack.Count > 0) + { item = stack[stackPointer]; stack.RemoveAt(stackPointer); stackPointer--; @@ -77,7 +98,7 @@ public object Pop() /// so on. Note you CAN peek a negative number, which looks at the secret stack above the /// stack - where the subroutine contexts and local variable contexts are. /// The object at that depth. Returns null when digDepth is too large and the stack isn't - /// big enough to dig that deep. Note that this conflates with the case where there really is a + /// big enough to dig that deep. Note that this conflates with the case where there really is a /// null stored on the stack and makes it impossible to tell the difference between peeking too far /// versus actually finding a null. If you need to know the difference, use PeekCheck. public object Peek(int digDepth) @@ -118,7 +139,7 @@ public int GetLogicalSize() { return stackPointer + 1; } - + public void MoveStackPointer(int delta) { stackPointer += delta; @@ -138,21 +159,25 @@ public string Dump() // Print in reverse order so the top of the stack is on top of the printout: // (actually given the double nature of the stack, one of the two sub-stacks // inside it will always be backwardly printed): - for (int index = stack.Count - 1; index >= 0; --index) { + for (int index = stack.Count - 1; index >= 0; --index) + { object item = stack[index]; - builder.AppendLine(string.Format("{0:000} {1,4} {2}", index, (index == stackPointer ? "SP->" : ""), item)); + builder.AppendLine(string.Format("{0:000} {1,4} {2} (type: {3})", index, (index == stackPointer ? "SP->" : ""), + (item == null ? "" : item.ToString()), + (item == null ? "" : item.GetType().ToString()))); VariableScope dict = item as VariableScope; - if (dict != null) { + if (dict != null) + { builder.AppendFormat(" ScopeId={0}, ParentScopeId={1}, ParentSkipLevels={2} IsClosure={3}", dict.ScopeId, dict.ParentScopeId, dict.ParentSkipLevels, dict.IsClosure); builder.AppendLine(); // Dump the local variable context stored here on the stack: - foreach (string varName in dict.Variables.Keys) { + foreach (string varName in dict.Variables.Keys) + { builder.AppendFormat(" local var {0} is {1} with value = {2}", varName, varName.GetType().FullName, dict.Variables[varName].Value); builder.AppendLine(); } } - } return builder.ToString(); @@ -166,12 +191,14 @@ public string Dump() public List GetCallTrace() { var trace = new List(); - for (int index = stackPointer + 1; index < stack.Count; ++index) { - if (stack[index] is SubroutineContext) { + for (int index = stackPointer + 1; index < stack.Count; ++index) + { + if (stack[index] is SubroutineContext) + { trace.Add(((SubroutineContext)(stack[index])).CameFromInstPtr - 1); } } return trace; } } -} +} \ No newline at end of file diff --git a/src/kOS.Safe/Execution/UserDelegate.cs b/src/kOS.Safe/Execution/UserDelegate.cs deleted file mode 100644 index d7fb62346..000000000 --- a/src/kOS.Safe/Execution/UserDelegate.cs +++ /dev/null @@ -1,49 +0,0 @@ -using System.Collections.Generic; - -namespace kOS.Safe.Execution -{ - /// - /// A callback reference to a user-land function, implemented in kRISC code
- ///
- /// (As opposed to being a C# delegate, implemented in C# code).
- ///
- public class UserDelegate : IUserDelegate - { - public IProgramContext ProgContext {get; private set;} - public int EntryPoint {get; private set;} - private readonly ICpu cpu; - public List Closure {get; private set;} - - /// - /// Make a new UserDelegate given the current state of the CPU and its stack, and - /// the entry point location of the function to call. - /// - /// the CPU on which this program is running. - /// The IProgramContext in which the entryPoint is stored. Entry point 27 in the interpreter is not the same as entrypoint 27 in program context. - /// instruction address where OpcodeCall should jump to to call the function. - /// If true, then a snapshot of the current scoping stack, and thus a persistent ref to its variables, - /// will be kept in the delegate so it can be called later as a callback with closure. Set to false if the - /// function is only getting called instantly using whatever the scope is at the time of the call. - public UserDelegate(ICpu cpu, IProgramContext context, int entryPoint, bool useClosure) - { - this.cpu = cpu; - ProgContext = context; - EntryPoint = entryPoint; - if (useClosure) - CaptureClosure(); - else - Closure = new List(); // make sure it exists as an empty list so we don't have to have 'if null' checks everwywhere. - } - - private void CaptureClosure() - { - Closure = cpu.GetCurrentClosure(); - } - - public override string ToString() - { - return "UserDelegate( cpu=" + cpu.ToString() + ", entryPoint=" + EntryPoint.ToString() + ", Closure=" + Closure.ToString(); - } - - } -} diff --git a/src/kOS.Safe/Module/IProcessor.cs b/src/kOS.Safe/Module/IProcessor.cs index 264872b84..c9430d5e1 100644 --- a/src/kOS.Safe/Module/IProcessor.cs +++ b/src/kOS.Safe/Module/IProcessor.cs @@ -3,6 +3,9 @@ namespace kOS.Safe.Module public interface IProcessor { void SetMode(ProcessorModes newProcessorMode); + string BootFilename { get; set; } + + bool CheckCanBoot(); } public enum ProcessorModes { READY, STARVED, OFF }; } \ No newline at end of file diff --git a/src/kOS.Safe/Persistence/Archive.cs b/src/kOS.Safe/Persistence/Archive.cs index 448b75e29..c9bffcd5b 100644 --- a/src/kOS.Safe/Persistence/Archive.cs +++ b/src/kOS.Safe/Persistence/Archive.cs @@ -1,14 +1,17 @@ +using kOS.Safe.Encapsulation; using kOS.Safe.Utilities; using System; using System.Collections.Generic; using System.IO; using System.Linq; -using FileInfo = kOS.Safe.Encapsulation.FileInfo; namespace kOS.Safe.Persistence { + [kOS.Safe.Utilities.KOSNomenclature("Archive")] public class Archive : Volume { + public const string ArchiveName = "Archive"; + private static string ArchiveFolder { get { return SafeHouse.ArchiveFolder; } @@ -18,49 +21,28 @@ public Archive() { Directory.CreateDirectory(ArchiveFolder); Renameable = false; - Name = "Archive"; + Name = ArchiveName; } - public override bool IsRoomFor(ProgramFile newFile) + public override float RequiredPower() { - return true; + const int MULTIPLIER = 5; + const float POWER_REQUIRED = BASE_POWER * MULTIPLIER; + + return POWER_REQUIRED; } - /// - /// Get a file given its name - /// - /// filename to get. if it has no filename extension, one will be guessed at, ".ks" usually. - /// true if a filename of .ksm is preferred in contexts where the extension was left off. The default is to prefer .ks - /// the file - public override ProgramFile GetByName(string name, bool ksmDefault = false) + public override VolumeFile Open(string name, bool ksmDefault = false) { try { - SafeHouse.Logger.Log("Archive: Getting File By Name: " + name); var fileInfo = FileSearch(name, ksmDefault); if (fileInfo == null) { return null; } - using (var infile = new BinaryReader(File.Open(fileInfo.FullName, FileMode.Open))) - { - byte[] fileBody = ProcessBinaryReader(infile); - - var retFile = new ProgramFile(fileInfo.Name); - FileCategory whatKind = PersistenceUtilities.IdentifyCategory(fileBody); - if (whatKind == FileCategory.KSM) - retFile.BinaryContent = fileBody; - else - retFile.StringContent = System.Text.Encoding.UTF8.GetString(fileBody); - - if (retFile.Category == FileCategory.ASCII || retFile.Category == FileCategory.KERBOSCRIPT) - retFile.StringContent = retFile.StringContent.Replace("\r\n", "\n"); - - base.Add(retFile, true); - - return retFile; - } + return new ArchiveFile(fileInfo); } catch (Exception e) { @@ -69,82 +51,21 @@ public override ProgramFile GetByName(string name, bool ksmDefault = false) } } - public override bool SaveFile(ProgramFile file) + public override bool Delete(string name) { - base.SaveFile(file); - - Directory.CreateDirectory(ArchiveFolder); - - try + var fullPath = FileSearch(name); + if (fullPath == null) { - SafeHouse.Logger.Log("Archive: Saving File Name: " + file.Filename); - byte[] fileBody; - string fileExtension; - switch (file.Category) - { - case FileCategory.OTHER: - case FileCategory.TOOSHORT: - case FileCategory.ASCII: - case FileCategory.KERBOSCRIPT: - string tempString = file.StringContent; - if (SafeHouse.IsWindows) - { - // Only evil windows gets evil windows line breaks, and only if this is some sort of ASCII: - tempString = tempString.Replace("\n", "\r\n"); - } - fileBody = System.Text.Encoding.UTF8.GetBytes(tempString.ToCharArray()); - fileExtension = KERBOSCRIPT_EXTENSION; - break; - - case FileCategory.KSM: - fileBody = file.BinaryContent; - fileExtension = KOS_MACHINELANGUAGE_EXTENSION; - break; - - default: - throw new ArgumentOutOfRangeException(); - } - var fileName = string.Format("{0}{1}", ArchiveFolder, PersistenceUtilities.CookedFilename(file.Filename, fileExtension, true)); - using (var outfile = new BinaryWriter(File.Open(fileName, FileMode.Create))) - { - outfile.Write(fileBody); - } - } - catch (Exception e) - { - SafeHouse.Logger.Log(e); return false; } - + File.Delete(fullPath.FullName); return true; } - public override bool DeleteByName(string name) - { - try - { - SafeHouse.Logger.Log("Archive: Deleting File Name: " + name); - base.DeleteByName(name); - - var fullPath = FileSearch(name); - if (fullPath == null) - { - return false; - } - File.Delete(fullPath.FullName); - return true; - } - catch (Exception) - { - return false; - } - } - public override bool RenameFile(string name, string newName) { try { - SafeHouse.Logger.Log(string.Format("Archive: Renaming: {0} To: {1}", name, newName)); var fullSourcePath = FileSearch(name); if (fullSourcePath == null) { @@ -166,35 +87,92 @@ public override bool RenameFile(string name, string newName) } } - public override List GetFileList() + public override VolumeFile Create(string name) { - var retList = new List(); + string filePath = Path.Combine(ArchiveFolder, name); + if (File.Exists(filePath)) + { + throw new KOSFileException("File already exists: " + name); + } - try + using (File.Create(filePath)) + { + // Do Nothing + } + + return new ArchiveFile(FileSearch(name)); + } + + public override VolumeFile Save(string name, FileContent content) + { + Directory.CreateDirectory(ArchiveFolder); + + byte[] fileBody = ConvertToWindowsNewlines(content.Bytes); + + using (var outfile = new BinaryWriter(File.Open(Path.Combine(ArchiveFolder, name), FileMode.Create))) + { + outfile.Write(fileBody); + } + + return new ArchiveFile(FileSearch(name)); + } + + public override Dictionary FileList + { + get { - SafeHouse.Logger.Log(string.Format("Archive: Listing Files")); var listFiles = Directory.GetFiles(ArchiveFolder); var filterHid = listFiles.Where(f => (File.GetAttributes(f) & FileAttributes.Hidden) != 0); var filterSys = listFiles.Where(f => (File.GetAttributes(f) & FileAttributes.System) != 0); var visFiles = listFiles.Except(filterSys).Except(filterHid); var kosFiles = visFiles.Except(Directory.GetFiles(ArchiveFolder, ".*")); - - retList.AddRange(kosFiles.Select(file => new System.IO.FileInfo(file)).Select(sysFileInfo => new FileInfo(sysFileInfo))); + return kosFiles.Select(file => new FileInfo(file)).Select(sysFileInfo => new ArchiveFile(sysFileInfo)). + Cast().ToDictionary(f => f.Name, f => f); } - catch (DirectoryNotFoundException) + } + + public override long Size + { + get { + return FileList.Values.Sum(i => i.Size); } + } - return retList; + public override bool Exists(string name) + { + return FileSearch(name) != null; } - public override float RequiredPower() + public static byte[] ConvertToWindowsNewlines(byte[] bytes) { - const int MULTIPLIER = 5; - const float POWER_REQUIRED = BASE_POWER * MULTIPLIER; + FileCategory category = PersistenceUtilities.IdentifyCategory(bytes); - return POWER_REQUIRED; + if (SafeHouse.IsWindows && !PersistenceUtilities.IsBinary(category)) + { + string asString = FileContent.DecodeString(bytes); + // Only evil windows gets evil windows line breaks, and only if this is some sort of ASCII: + asString = asString.Replace("\n", "\r\n"); + return FileContent.EncodeString(asString); + } + + return bytes; + } + + public static byte[] ConvertFromWindowsNewlines(byte[] bytes) + { + FileCategory category = PersistenceUtilities.IdentifyCategory(bytes); + + if (!PersistenceUtilities.IsBinary(category)) + { + string asString = FileContent.DecodeString(bytes); + // Only evil windows gets evil windows line breaks, and only if this is some sort of ASCII: + asString = asString.Replace("\r\n", "\n"); + return FileContent.EncodeString(asString); + } + + return bytes; } /// @@ -203,15 +181,15 @@ public override float RequiredPower() /// filename to look for /// if true, it prefers to use the KSM filename over the KS. The default is to prefer KS. /// the full fileinfo of the filename if found - private System.IO.FileInfo FileSearch(string name, bool ksmDefault = false) + private FileInfo FileSearch(string name, bool ksmDefault = false) { - var path = ArchiveFolder + name; - if (Path.HasExtension(path)) + var path = Path.Combine(ArchiveFolder, name); + if (File.Exists(path)) { - return File.Exists(path) ? new System.IO.FileInfo(path) : null; + return new FileInfo(path); } - var kerboscriptFile = new System.IO.FileInfo(PersistenceUtilities.CookedFilename(path, KERBOSCRIPT_EXTENSION, true)); - var kosMlFile = new System.IO.FileInfo(PersistenceUtilities.CookedFilename(path, KOS_MACHINELANGUAGE_EXTENSION, true)); + var kerboscriptFile = new FileInfo(PersistenceUtilities.CookedFilename(path, KERBOSCRIPT_EXTENSION, true)); + var kosMlFile = new FileInfo(PersistenceUtilities.CookedFilename(path, KOS_MACHINELANGUAGE_EXTENSION, true)); if (kerboscriptFile.Exists && kosMlFile.Exists) { @@ -227,48 +205,5 @@ private System.IO.FileInfo FileSearch(string name, bool ksmDefault = false) } return null; } - - private byte[] ProcessBinaryReader(BinaryReader infile) - { - const int BUFFER_SIZE = 4096; - using (var ms = new MemoryStream()) - { - var buffer = new byte[BUFFER_SIZE]; - int count; - while ((count = infile.Read(buffer, 0, buffer.Length)) != 0) - ms.Write(buffer, 0, count); - return ms.ToArray(); - } - } - - public override void AppendToFile(string name, string textToAppend) - { - SafeHouse.Logger.SuperVerbose("Archive: AppendToFile: " + name); - System.IO.FileInfo info = FileSearch(name); - - string fullPath = info == null ? string.Format("{0}{1}", ArchiveFolder, PersistenceUtilities.CookedFilename(name, KERBOSCRIPT_EXTENSION, true)) : info.FullName; - - // Using binary writer so we can bypass the OS behavior about ASCII end-of-lines and always use \n's no matter the OS: - // Deliberately not catching potential I/O exceptions from this, so they will percolate upward and be seen by the user: - using (var outfile = new BinaryWriter(File.Open(fullPath, FileMode.Append, FileAccess.Write, FileShare.ReadWrite))) - { - byte[] binaryLine = System.Text.Encoding.UTF8.GetBytes((textToAppend + "\n").ToCharArray()); - outfile.Write(binaryLine); - } - } - - public override void AppendToFile(string name, byte[] bytesToAppend) - { - SafeHouse.Logger.SuperVerbose("Archive: AppendToFile: " + name); - System.IO.FileInfo info = FileSearch(name); - - string fullPath = info == null ? string.Format("{0}{1}", ArchiveFolder, PersistenceUtilities.CookedFilename(name, KERBOSCRIPT_EXTENSION, true)) : info.FullName; - - // Deliberately not catching potential I/O exceptions from this, so they will percolate upward and be seen by the user: - using (var outfile = new BinaryWriter(File.Open(fullPath, FileMode.Append, FileAccess.Write, FileShare.ReadWrite))) - { - outfile.Write(bytesToAppend); - } - } } } \ No newline at end of file diff --git a/src/kOS.Safe/Persistence/FileCategory.cs b/src/kOS.Safe/Persistence/FileCategory.cs index bb59289be..393d23079 100644 --- a/src/kOS.Safe/Persistence/FileCategory.cs +++ b/src/kOS.Safe/Persistence/FileCategory.cs @@ -15,20 +15,13 @@ public enum FileCategory /// to know for sure it's not one of the supported types. /// TOOSHORT = 0, - + /// /// The default the type identifier will always assume as long
/// as the first few characters are printable ASCII. ///
ASCII, - /// - /// At the moment we won't be able to detect this
- /// and it will call scripts just ASCII, but this
- /// may change later and be used. - ///
- KERBOSCRIPT, - /// /// The ML compiled and packed file that came from a KerboScript. /// @@ -37,6 +30,6 @@ public enum FileCategory /// /// Is an unsupported type. /// - OTHER + BINARY } } \ No newline at end of file diff --git a/src/kOS.Safe/Persistence/FileContent.cs b/src/kOS.Safe/Persistence/FileContent.cs new file mode 100644 index 000000000..90f5b181f --- /dev/null +++ b/src/kOS.Safe/Persistence/FileContent.cs @@ -0,0 +1,136 @@ +using kOS.Safe.Compilation; +using kOS.Safe.Encapsulation; +using kOS.Safe.Encapsulation.Suffixes; +using kOS.Safe.Exceptions; +using kOS.Safe.Serialization; +using System; +using System.Collections; +using System.Collections.Generic; +using System.IO; +using System.Text; + +namespace kOS.Safe.Persistence +{ + [kOS.Safe.Utilities.KOSNomenclature("FileContent")] + public class FileContent : SerializableStructure, IEnumerable + { + private static readonly Encoding fileEncoding = Encoding.UTF8; + private const string DUMP_CONTENT = "content"; + public const string NEW_LINE = "\n"; + + public byte[] Bytes { get; private set; } + public string String { get { return fileEncoding.GetString(Bytes); } } + + public int Size { get { return Bytes.Length; } } + public FileCategory Category { get { return PersistenceUtilities.IdentifyCategory(Bytes); } } + + public FileContent() + { + Bytes = new byte[0]; + + InitializeSuffixes(); + } + + public FileContent(string content) : this() + { + Bytes = fileEncoding.GetBytes(content); + } + + public FileContent(byte[] content) : this() + { + Bytes = content; + } + + public FileContent(List parts) : this() + { + Bytes = CompiledObject.Pack(parts); + } + + private void InitializeSuffixes() + { + AddSuffix("LENGTH", new Suffix(() => Size)); + AddSuffix("EMPTY", new Suffix(() => Size == 0)); + AddSuffix("TYPE", new Suffix(() => Category.ToString())); + AddSuffix("STRING", new Suffix(() => String)); + AddSuffix("ITERATOR", new Suffix(() => new Enumerator(GetEnumerator()))); + } + + public override Dump Dump() + { + Dump dump = new Dump { { DUMP_CONTENT, PersistenceUtilities.EncodeBase64(Bytes) } }; + + return dump; + } + + public override void LoadDump(Dump dump) + { + string contentString = dump[DUMP_CONTENT] as string; + + if (contentString == null) + { + throw new KOSSerializationException("'content' field not found or invalid"); + } + + Bytes = PersistenceUtilities.DecodeBase64ToBinary(contentString); + } + + public List AsParts(string name, string prefix) + { + return CompiledObject.UnPack(name, prefix, Bytes); + } + + public static byte[] EncodeString(string content) + { + return fileEncoding.GetBytes(content); + } + + public static string DecodeString(byte[] content) + { + return fileEncoding.GetString(content); + } + + public void Write(string contentToWrite) + { + Write(EncodeString(contentToWrite)); + } + + public void Write(byte[] contentToWrite) + { + byte[] newContent = new byte[Bytes.Length + contentToWrite.Length]; + Buffer.BlockCopy(Bytes, 0, newContent, 0, Bytes.Length); + Buffer.BlockCopy(contentToWrite, 0, newContent, Bytes.Length, contentToWrite.Length); + Bytes = newContent; + } + + public void WriteLn(string content) + { + Write(content + NEW_LINE); + } + + public void Clear() + { + Bytes = new byte[0]; + } + + public IEnumerator GetEnumerator() + { + var reader = new StringReader(String); + string line; + + while ((line = reader.ReadLine()) != null) + { + yield return line; + } + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + + public override string ToString() + { + return "File content"; + } + } +} \ No newline at end of file diff --git a/src/kOS.Safe/Persistence/Harddisk.cs b/src/kOS.Safe/Persistence/Harddisk.cs index 9fdb041e7..42b102be6 100644 --- a/src/kOS.Safe/Persistence/Harddisk.cs +++ b/src/kOS.Safe/Persistence/Harddisk.cs @@ -1,36 +1,143 @@ -using kOS.Safe.Utilities; +using kOS.Safe.Encapsulation; +using kOS.Safe.Utilities; +using System; +using System.Collections.Generic; +using System.Linq; namespace kOS.Safe.Persistence { + [kOS.Safe.Utilities.KOSNomenclature("LocalVolume")] public sealed class Harddisk : Volume { + private readonly Dictionary files; + + public override Dictionary FileList + { + get + { + return files.ToDictionary(arg => arg.Key, arg => (VolumeFile)new HarddiskFile(this, arg.Key)); + } + } + + public override long Size + { + get + { + return files.Values.Sum(x => x.Size); + } + } + public Harddisk(int size) { Capacity = size; + files = new Dictionary(StringComparer.OrdinalIgnoreCase); } - public override bool SaveFile(ProgramFile file) + public FileContent GetFileContent(string name) { - SafeHouse.Logger.Log("HardDisk: SaveFile: " + file.Filename); - return IsRoomFor(file) && base.SaveFile(file); + if (!files.ContainsKey(name)) + { + throw new KOSFileException("File does not exist: " + name); + } + + return files[name]; } - public override int GetFreeSpace() + public override VolumeFile Open(string name, bool ksmDefault = false) { - return System.Math.Max(Capacity - GetUsedSpace(), 0); + return FileSearch(name, ksmDefault); } - public override bool IsRoomFor(ProgramFile newFile) + public override bool Delete(string name) { - int usedSpace = GetUsedSpace(); - ProgramFile existingFile = GetByName(newFile.Filename); + var fullPath = FileSearch(name); + if (fullPath == null) + { + return false; + } + return files.Remove(fullPath.Name); + } - if (existingFile != null) + public override bool RenameFile(string name, string newName) + { + VolumeFile file = Open(name); + if (file != null) { - usedSpace -= existingFile.GetSize(); + // Add the original file content under the new name + files.Add(newName, files[file.Name]); + // Then remove the old file content under the old name + files.Remove(file.Name); + return true; } + return false; + } - return ((Capacity - usedSpace) >= newFile.GetSize()); + public override VolumeFile Create(string name) + { + SafeHouse.Logger.Log("Creating file on harddisk " + name); + + if (files.ContainsKey(name)) + { + throw new KOSFileException("File already exists: " + name); + } + + files[name] = new FileContent(); + + SafeHouse.Logger.Log("Created file on harddisk " + name); + + return new HarddiskFile(this, name); + } + + public override VolumeFile Save(string name, FileContent content) + { + if (!IsRoomFor(name, content)) + { + return null; + } + + files[name] = content; + + return new HarddiskFile(this, name); + } + + public override bool Exists(string name) + { + return FileSearch(name) != null; + } + + private VolumeFile FileSearch(string name, bool ksmDefault = false) + { + if (files.ContainsKey(name)) + { + return new HarddiskFile(this, name); + } + else + { + var kerboscriptFilename = PersistenceUtilities.CookedFilename(name, KERBOSCRIPT_EXTENSION, true); + var kosMlFilename = PersistenceUtilities.CookedFilename(name, KOS_MACHINELANGUAGE_EXTENSION, true); + bool kerboscriptFileExists = files.ContainsKey(kerboscriptFilename); + bool kosMlFileExists = files.ContainsKey(kosMlFilename); + if (kerboscriptFileExists && kosMlFileExists) + { + if (ksmDefault) + { + return new HarddiskFile(this, kosMlFilename); + } + else + { + return new HarddiskFile(this, kerboscriptFilename); + } + } + if (kerboscriptFileExists) + { + return new HarddiskFile(this, kerboscriptFilename); + } + if (kosMlFileExists) + { + return new HarddiskFile(this, kosMlFilename); + } + } + return null; } } } diff --git a/src/kOS.Safe/Persistence/IVolumeManager.cs b/src/kOS.Safe/Persistence/IVolumeManager.cs new file mode 100644 index 000000000..2a4cf5f51 --- /dev/null +++ b/src/kOS.Safe/Persistence/IVolumeManager.cs @@ -0,0 +1,29 @@ +using System.Collections.Generic; + +namespace kOS.Safe.Persistence +{ + public interface IVolumeManager + { + Dictionary Volumes { get; } + Volume CurrentVolume { get; } + float CurrentRequiredPower { get; } + bool VolumeIsCurrent(Volume volume); + int GetVolumeId(Volume volume); + Volume GetVolume(object volumeId); + Volume GetVolume(string name); + Volume GetVolume(int id); + void Add(Volume volume); + void Remove(string name); + void Remove(int id); + void SwitchTo(Volume volume); + void UpdateVolumes(List attachedVolumes); + string GetVolumeBestIdentifier(Volume volume); + + /// + /// Like GetVolumeBestIdentifier, but without the extra string formatting. + /// + /// + /// The Volume's Identifier without pretty formatting + string GetVolumeRawIdentifier(Volume volume); + } +} \ No newline at end of file diff --git a/src/kOS.Safe/Persistence/PersistenceUtilities.cs b/src/kOS.Safe/Persistence/PersistenceUtilities.cs index 6cbccb7cc..a35014224 100644 --- a/src/kOS.Safe/Persistence/PersistenceUtilities.cs +++ b/src/kOS.Safe/Persistence/PersistenceUtilities.cs @@ -1,13 +1,21 @@ -using kOS.Safe.Compilation; -using kOS.Safe.Exceptions; -using System; +using System; +using System.IO; using System.Linq; using System.Text; +using ICSharpCode.SharpZipLib.GZip; +using kOS.Safe.Compilation; +using kOS.Safe.Exceptions; +using kOS.Safe.Utilities; namespace kOS.Safe.Persistence { public static class PersistenceUtilities { + public static bool IsBinary(FileCategory category) + { + return category == FileCategory.BINARY || category == FileCategory.KSM; + } + /// /// Given the first few bytes of content, decide what the FileCategory /// should be, based on what's in the Content.
@@ -17,10 +25,10 @@ public static class PersistenceUtilities /// The type that should be used to store this file. public static FileCategory IdentifyCategory(byte[] firstBytes) { - var firstFour = new Byte[4]; - int atMostFour = Math.Min(4, firstBytes.Length); + var firstFour = new byte[4]; + int atMostFour = System.Math.Min(4, firstBytes.Length); Array.Copy(firstBytes, 0, firstFour, 0, atMostFour); - var returnCat = (atMostFour < 4) ? FileCategory.TOOSHORT : FileCategory.OTHER; // default if none of the conditions pass + var returnCat = atMostFour < 4 ? FileCategory.TOOSHORT : FileCategory.BINARY; // default if none of the conditions pass if (firstFour.SequenceEqual(CompiledObject.MagicId)) { @@ -57,7 +65,7 @@ public static FileCategory IdentifyCategory(byte[] firstBytes) /// public static string CookedFilename(string fileName, string extensionName, bool trusted = false) { - if (String.IsNullOrEmpty(fileName)) + if (string.IsNullOrEmpty(fileName)) throw new KOSFileException("Attempted to use an empty filename."); int lastDotIndex = fileName.LastIndexOf('.'); @@ -103,7 +111,7 @@ public static string DecodeLine(string input) if (semicolonPos < 0) throw new KOSPersistenceException("Improperly encoded saved file contains '&' without closing ';'"); int charOrdinal; - if (!int.TryParse(input.Substring(inputPos + 2, (semicolonPos - (inputPos + 2))), out charOrdinal)) + if (!int.TryParse(input.Substring(inputPos + 2, semicolonPos - (inputPos + 2)), out charOrdinal)) throw new KOSPersistenceException("Improperly encoded saved file contains non-digits between the '&#' and the ';'"); output.Append((char)charOrdinal); inputPos = semicolonPos; // skip to the end of the encoding section, as if everything between '&' and ';' was one char of input. @@ -136,7 +144,60 @@ public static string EncodeLine(string input) /// true if the character needs protective encoding public static bool CharNeedsEncoding(char character) { - return !(Char.IsLetterOrDigit(character) || WHITELISTED_SYMBOLS.Contains(character)); + return !(char.IsLetterOrDigit(character) || WHITELISTED_SYMBOLS.Contains(character)); + } + + + public static string EncodeBase64(byte[] input) + { + using (var compressedStream = new MemoryStream()) + { + // mono requires an installed zlib library for GZipStream to work :( + // using (Stream csStream = new GZipStream(compressedStream, CompressionMode.Compress)) + using (Stream csStream = new GZipOutputStream(compressedStream)) + { + csStream.Write(input, 0, input.Length); + } + + string returnValue = Convert.ToBase64String(compressedStream.ToArray()); + + // Added the following to fix issue #429: Base64 content can include the slash character '/', and + // if it happens to have two of them contiguously, it forms a comment in the persistence file and + // truncates the value. So change them to a different character to protect the file. + // The comma ',' char is not used by base64 so it's a safe alternative to use as we'll be able to + // swap all of the commas back to slashes on reading, knowing that commas can only appear as the + // result of this swap on writing: + returnValue = returnValue.Replace('/',','); + + SafeHouse.Logger.SuperVerbose("About to store the following Base64 string:\n" + returnValue); + + return returnValue; + } + } + + public static byte[] DecodeBase64ToBinary(string input) + { + // Fix for issue #429. See comment up in EncodeBase64() method above for an explanation: + string massagedInput = input.Replace(',','/'); + + byte[] inputBuffer = Convert.FromBase64String(massagedInput); + + using (var inputStream = new MemoryStream(inputBuffer)) + // mono requires an installed zlib library for GZipStream to work :( + //using (var zipStream = new GZipStream(inputStream, CompressionMode.Decompress)) + using (var zipStream = new GZipInputStream(inputStream)) + using (var decompressedStream = new MemoryStream()) + { + var buffer = new byte[4096]; + int read; + + while ((read = zipStream.Read(buffer, 0, buffer.Length)) > 0) + { + decompressedStream.Write(buffer, 0, read); + } + + return decompressedStream.ToArray(); + } } // Note: deliberately missing from the whitelist are: diff --git a/src/kOS.Safe/Persistence/ProgramFile.cs b/src/kOS.Safe/Persistence/ProgramFile.cs deleted file mode 100644 index fcb18ac23..000000000 --- a/src/kOS.Safe/Persistence/ProgramFile.cs +++ /dev/null @@ -1,97 +0,0 @@ -using System; -using System.Linq; - -namespace kOS.Safe.Persistence -{ - public class ProgramFile - { - public string Filename - { - get { return filename; } - set - { - filename = PersistenceUtilities.CookedFilename(value, "ks", true); - - var fileParts = filename.Split('.'); - Extension = fileParts.Count() > 1 ? fileParts.Last() : string.Empty; - } - } - - public FileCategory Category { get; private set; } - public string Extension { get; private set; } - - public string StringContent - { - get - { - if (Category != FileCategory.ASCII && Category != FileCategory.KERBOSCRIPT && Category != FileCategory.TOOSHORT) - throw new KOSFileException(string.Format("File {0} is {1}, not ASCII. Should use BinaryContent instead.", Filename, Category)); - return stringContent; - } - set - { - Category = FileCategory.ASCII; - stringContent = value; - } - } - private string stringContent; - - public byte[] BinaryContent - { - get - { - if (Category == FileCategory.ASCII || Category == FileCategory.KERBOSCRIPT && Category != FileCategory.TOOSHORT) - throw new KOSFileException(string.Format("File {0} is {1}, not Binary. Should use StringContent instead.", Filename, Category)); - return binaryContent; - } - set - { - Category = FileCategory.KSM; - binaryContent = value; - } - } - private byte[] binaryContent; - private string filename; - - public ProgramFile(ProgramFile copy) - { - Filename = copy.Filename; - Category = copy.Category; - if (Category == FileCategory.KSM) - BinaryContent = copy.BinaryContent; - else - StringContent = copy.StringContent; - } - - public ProgramFile(string filename) - { - Filename = filename; - Category = FileCategory.TOOSHORT; - stringContent = string.Empty; - binaryContent = new byte[0]; - } - - public ProgramFile Copy() - { - return new ProgramFile(this); - } - - public int GetSize() - { - switch (Category) - { - case FileCategory.TOOSHORT: - return 0; - case FileCategory.KSM: - return BinaryContent.Length; - case FileCategory.OTHER: - case FileCategory.ASCII: - case FileCategory.KERBOSCRIPT: - return StringContent.Length; - default: - throw new ArgumentOutOfRangeException(); - } - - } - } -} diff --git a/src/kOS.Safe/Persistence/Volume.cs b/src/kOS.Safe/Persistence/Volume.cs index 98d34cd2a..17bf11402 100644 --- a/src/kOS.Safe/Persistence/Volume.cs +++ b/src/kOS.Safe/Persistence/Volume.cs @@ -1,42 +1,36 @@ -using System; using System.Collections.Generic; using System.Linq; -using kOS.Safe.Compilation; using kOS.Safe.Encapsulation; using kOS.Safe.Encapsulation.Suffixes; -using kOS.Safe.Utilities; -using FileInfo = kOS.Safe.Encapsulation.FileInfo; namespace kOS.Safe.Persistence { + [kOS.Safe.Utilities.KOSNomenclature("Volume")] public abstract class Volume : Structure { public const string TEXT_EXTENSION = "txt"; public const string KERBOSCRIPT_EXTENSION = "ks"; public const string KOS_MACHINELANGUAGE_EXTENSION = "ksm"; - protected const int BASE_CAPACITY = 10000; + protected const long BASE_CAPACITY = 10000; protected const float BASE_POWER = 0.04f; - private readonly Dictionary files; + public const int INFINITE_CAPACITY = -1; - public Dictionary FileList - { - get - { - SafeHouse.Logger.SuperVerbose("Volume: Get-FileList: " + files.Count); - return files.ToDictionary(pair => pair.Key, pair => pair.Value, StringComparer.OrdinalIgnoreCase); + public abstract Dictionary FileList { get; } + public string Name { get; set; } + public long Capacity { get; protected set; } + public abstract long Size { get; } + public long FreeSpace { + get { + return Capacity == INFINITE_CAPACITY ? INFINITE_CAPACITY : Capacity - Size; } } - public string Name { get; set; } - public int Capacity { get; protected set; } public bool Renameable { get; protected set; } protected Volume() { - SafeHouse.Logger.SuperVerbose("Volume: CONSTRUCT"); Renameable = true; Capacity = -1; Name = ""; - files = new Dictionary(StringComparer.OrdinalIgnoreCase); InitializeVolumeSuffixes(); } @@ -46,127 +40,56 @@ protected Volume() /// filename to get. if it has no filename extension, one will be guessed at, ".ks" usually. /// in the scenario where there is no filename extension, do we prefer the .ksm over the .ks? The default is to prefer .ks /// the file - public virtual ProgramFile GetByName(string name, bool ksmDefault = false ) - { - SafeHouse.Logger.SuperVerbose("Volume: GetByName: " + name); - var fullPath = FileSearch(name, ksmDefault); - if (fullPath == null) - { - return null; - } + public abstract VolumeFile Open(string name, bool ksmDefault = false); - return files.ContainsKey(fullPath.Filename) ? files[fullPath.Filename] : null; - } + public abstract VolumeFile Create(string name); + + public abstract bool Exists(string name); - public virtual bool DeleteByName(string name) + public VolumeFile OpenOrCreate(string name, bool ksmDefault = false) { - SafeHouse.Logger.SuperVerbose("Volume: DeleteByName: " + name); + var volumeFile = Open(name, ksmDefault); - var fullPath = FileSearch(name); - if (fullPath == null) + if (volumeFile != null) { - return false; + return volumeFile; } - if (files.ContainsKey(fullPath.Filename)) - { - files.Remove(fullPath.Filename); - return true; - } - return false; - } - public virtual bool RenameFile(string name, string newName) - { - SafeHouse.Logger.SuperVerbose("Volume: RenameFile: From: " + name + " To: " + newName); - ProgramFile file = GetByName(name); - if (file != null) - { - DeleteByName(name); - file.Filename = newName; - Add(file); - return true; - } - return false; + return Create(name); } - public virtual void AppendToFile(string name, string textToAppend) - { - SafeHouse.Logger.SuperVerbose("Volume: AppendToFile: " + name); - ProgramFile file = GetByName(name) ?? new ProgramFile(name); + public abstract bool Delete(string name); - if (file.StringContent.Length > 0 && !file.StringContent.EndsWith("\n")) - { - textToAppend = "\n" + textToAppend; - } + public abstract bool RenameFile(string name, string newName); - file.StringContent = file.StringContent + textToAppend; - SaveFile(file); - } + //public abstract bool AppendToFile(string name, string textToAppend); - public virtual void AppendToFile(string name, byte[] bytesToAppend) - { - SafeHouse.Logger.SuperVerbose("Volume: AppendToFile: " + name); - ProgramFile file = GetByName(name) ?? new ProgramFile(name); + //public abstract bool AppendToFile(string name, byte[] bytesToAppend); - file.BinaryContent = new byte[file.BinaryContent.Length + bytesToAppend.Length]; - Array.Copy(bytesToAppend, 0, file.BinaryContent, file.BinaryContent.Length, bytesToAppend.Length); - SaveFile(file); - } - - public virtual void Add(ProgramFile file, bool withReplacement = false) + public VolumeFile Save(VolumeFile volumeFile) { - SafeHouse.Logger.SuperVerbose("Volume: Add: " + file.Filename); - if (withReplacement) - { - files[file.Filename] = file; - } - else - { - files.Add(file.Filename, file); - } + return Save(volumeFile.Name, volumeFile.ReadAll()); } - public virtual bool SaveFile(ProgramFile file) - { - SafeHouse.Logger.SuperVerbose("Volume: SaveFile: " + file.Filename); - - Add(file, true); - return true; - } - - public virtual bool SaveObjectFile(string fileNameOut, List parts) - { - var newFile = new ProgramFile(fileNameOut) {BinaryContent = CompiledObject.Pack(parts)}; - SaveFile(newFile); - return true; - } + public abstract VolumeFile Save(string name, FileContent content); - public List LoadObjectFile(string filePath, string prefix, byte[] content) + public bool IsRoomFor(string name, FileContent fileContent) { - SafeHouse.Logger.SuperVerbose("Volume: LoadObjectFile: " + filePath); - List parts = CompiledObject.UnPack(filePath, prefix, content); - return parts; - } + VolumeFile existingFile = Open(name); - protected int GetUsedSpace() - { - return files.Values.Sum(file => file.GetSize()); - } + int usedByThisFile = 0; - public virtual int GetFreeSpace() { return -1; } - public virtual bool IsRoomFor(ProgramFile newFile) { return true; } + if (existingFile != null) + { + usedByThisFile = existingFile.ReadAll().Size; + } - public virtual List GetFileList() - { - SafeHouse.Logger.SuperVerbose("Volume: GetFileList: " + files.Count); - List returnList = files.Values.Select(file => new FileInfo(file.Filename, file.GetSize())).ToList(); - returnList.Sort(FileInfoComparer); // make sure files will print in sorted form. - return returnList; + return INFINITE_CAPACITY == FreeSpace || FreeSpace + usedByThisFile >= fileContent.Size; } public virtual float RequiredPower() { - var multiplier = ((float)Capacity) / BASE_CAPACITY; + var multiplier = (float)Capacity / BASE_CAPACITY; var powerRequired = BASE_POWER * multiplier; return powerRequired; @@ -179,42 +102,28 @@ public override string ToString() private void InitializeVolumeSuffixes() { - AddSuffix("FREESPACE" , new Suffix(() => GetFreeSpace())); - AddSuffix("CAPACITY" , new Suffix(() => Capacity)); - AddSuffix("NAME" , new Suffix(() => Name)); - AddSuffix("RENAMEABLE" , new Suffix(() => Renameable)); - AddSuffix("FILES" , new Suffix>(() => new ListValue(GetFileList()))); - AddSuffix("POWERREQUIREMENT" , new Suffix(RequiredPower)); + AddSuffix("FREESPACE" , new Suffix(() => FreeSpace)); + AddSuffix("CAPACITY" , new Suffix(() => Capacity)); + AddSuffix("NAME" , new Suffix(() => Name)); + AddSuffix("RENAMEABLE" , new Suffix(() => Renameable)); + AddSuffix("POWERREQUIREMENT" , new Suffix(() => RequiredPower())); + + AddSuffix("EXISTS" , new OneArgsSuffix(name => Exists(name))); + AddSuffix("FILES" , new Suffix(BuildFileLexicon)); + AddSuffix("CREATE" , new OneArgsSuffix(name => Create(name))); + AddSuffix("OPEN" , new OneArgsSuffix(name => Open(name))); + AddSuffix("DELETE" , new OneArgsSuffix(name => Delete(name))); } - private ProgramFile FileSearch(string name, bool ksmDefault = false) + private Lexicon BuildFileLexicon() { - SafeHouse.Logger.SuperVerbose("Volume: FileSearch: " + files.Count); - var kerboscriptFilename = PersistenceUtilities.CookedFilename(name, KERBOSCRIPT_EXTENSION, true); - var kosMlFilename = PersistenceUtilities.CookedFilename(name, KOS_MACHINELANGUAGE_EXTENSION, true); - - ProgramFile kerboscriptFile; - ProgramFile kosMlFile; - bool kerboscriptFileExists = files.TryGetValue(kerboscriptFilename, out kerboscriptFile); - bool kosMlFileExists = files.TryGetValue(kosMlFilename, out kosMlFile); - if (kerboscriptFileExists && kosMlFileExists) - { - return ksmDefault ? kosMlFile : kerboscriptFile; - } - if (kerboscriptFile != null) - { - return kerboscriptFile; - } - if (kosMlFile != null) - { - return kosMlFile; - } - return null; + return new Lexicon(FileList.ToDictionary(item => FromPrimitiveWithAssert(item.Key), item => (Structure) item.Value)); } - - private int FileInfoComparer(FileInfo a, FileInfo b) + + + private int FileInfoComparer(VolumeFile a, VolumeFile b) { - return String.CompareOrdinal(a.Name, b.Name); + return string.CompareOrdinal(a.Name, b.Name); } } } diff --git a/src/kOS.Safe/Persistence/VolumeManager.cs b/src/kOS.Safe/Persistence/VolumeManager.cs index 812075433..cd8bf0522 100644 --- a/src/kOS.Safe/Persistence/VolumeManager.cs +++ b/src/kOS.Safe/Persistence/VolumeManager.cs @@ -1,9 +1,10 @@ using System; using System.Collections.Generic; +using kOS.Safe.Encapsulation; namespace kOS.Safe.Persistence { - public class VolumeManager + public class VolumeManager : IVolumeManager { private readonly Dictionary volumes; private Volume currentVolume; @@ -31,7 +32,7 @@ private int GetVolumeId(string name) foreach (KeyValuePair kvp in volumes) { - if (String.Equals(kvp.Value.Name, name, StringComparison.CurrentCultureIgnoreCase)) + if (string.Equals(kvp.Value.Name, name, StringComparison.CurrentCultureIgnoreCase)) { volumeId = kvp.Key; break; @@ -41,7 +42,7 @@ private int GetVolumeId(string name) return volumeId; } - private int GetVolumeId(Volume volume) + public int GetVolumeId(Volume volume) { int volumeId = -1; @@ -59,11 +60,22 @@ private int GetVolumeId(Volume volume) public Volume GetVolume(object volumeId) { - if (volumeId is int) + if (volumeId is string || volumeId is StringValue) return GetVolume(volumeId.ToString()); + // Convert to int instead of cast in case the identifier is stored + // as an encapsulated ScalarValue, preventing an unboxing collision. + try { - return GetVolume((int)volumeId); + return GetVolume(Convert.ToInt32(volumeId)); + } + catch (InvalidCastException) + { + int id = GetVolumeId(volumeId.ToString()); + if (id >= 0) + { + return GetVolume(id); + } + throw new kOS.Safe.Exceptions.KOSCastException(volumeId.GetType().Name, "Scalar|String|Volume"); } - return GetVolume(volumeId.ToString()); } public Volume GetVolume(string name) @@ -135,7 +147,7 @@ public void UpdateVolumes(List attachedVolumes) { // Remove volumes that are no longer attached var removals = new List(); - foreach (KeyValuePair kvp in volumes) + foreach (var kvp in volumes) { if (!(kvp.Value is Archive) && !attachedVolumes.Contains(kvp.Value)) { diff --git a/src/kOS.Safe/Properties/AssemblyInfo.cs b/src/kOS.Safe/Properties/AssemblyInfo.cs index ef1aee829..55e7eea00 100644 --- a/src/kOS.Safe/Properties/AssemblyInfo.cs +++ b/src/kOS.Safe/Properties/AssemblyInfo.cs @@ -31,5 +31,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.17.2.0")] -[assembly: AssemblyFileVersion("1.17.2.0")] +[assembly: AssemblyVersion("1.19.1.0")] +[assembly: AssemblyFileVersion("1.19.1.0")] diff --git a/src/kOS.Safe/Screen/IInterpreter.cs b/src/kOS.Safe/Screen/IInterpreter.cs index 02f1c30de..71761805f 100644 --- a/src/kOS.Safe/Screen/IInterpreter.cs +++ b/src/kOS.Safe/Screen/IInterpreter.cs @@ -5,7 +5,7 @@ namespace kOS.Safe.Screen public interface IInterpreter : IScreenBuffer { void Type(char ch); - void SpecialKey(char key); + bool SpecialKey(char key); string GetCommandHistoryAbsolute(int absoluteIndex); void SetInputLock(bool isLocked); bool IsAtStartOfCommand(); diff --git a/src/kOS.Safe/Screen/IScreenBuffer.cs b/src/kOS.Safe/Screen/IScreenBuffer.cs index b8d8df285..bfd6dcc65 100644 --- a/src/kOS.Safe/Screen/IScreenBuffer.cs +++ b/src/kOS.Safe/Screen/IScreenBuffer.cs @@ -4,11 +4,17 @@ namespace kOS.Safe.Screen { public interface IScreenBuffer { + int CharacterPixelWidth { get; set; } + int CharacterPixelHeight { get; set; } + float Brightness { get; set; } int CursorRowShow { get; } int CursorColumnShow { get; } int RowCount { get; } int ColumnCount { get; } int AbsoluteCursorRow { get; set; } + int BeepsPending {get; set;} + bool ReverseScreen {get; set;} + bool VisualBeep {get; set;} int TopRow {get;} void SetSize(int rowCount, int columnCount); int ScrollVertical(int deltaRows); diff --git a/src/kOS.Safe/Screen/ScreenBuffer.cs b/src/kOS.Safe/Screen/ScreenBuffer.cs index ff4db8000..eca09c0de 100644 --- a/src/kOS.Safe/Screen/ScreenBuffer.cs +++ b/src/kOS.Safe/Screen/ScreenBuffer.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; +using kOS.Safe.UserIO; namespace kOS.Safe.Screen { @@ -12,7 +13,23 @@ public class ScreenBuffer : IScreenBuffer private int topRow; private readonly List buffer; private readonly List subBuffers; - + + public int BeepsPending {get; set;} + + // These next 6 things really belong in TermWindow, but then they can't be reached from + // TerminalStruct over in kOS.Safe because TermWindow is just too full of + // Unity stuff to move it to kOS.Safe, or even provide all its methods + // in an ITermWindow interface: + // --------------------------------------------------------------------------- + /// True means the terminal screen should be shown in reversed colors. + public bool ReverseScreen {get; set;} + /// True means a beep should make the terminal screen flash silently in lieu of an audio beep. + public bool VisualBeep {get; set;} + public int CharacterPixelWidth { get; set; } + public int CharacterPixelHeight { get; set; } + public float Brightness { get; set; } + + public int ColumnCount { get; private set; } public virtual int CursorRowShow { get { return CursorRow; } } @@ -85,10 +102,13 @@ public virtual int ScrollVertical(int deltaRows) /// in need of a diff check. ///
/// Starting with this row number - /// for this many rows + /// for this many rows, or up to the max row the buffer has if this number is too large public void MarkRowsDirty(int startRow, int numRows) { - for( int i = 0; i < numRows ; ++i) + // Mark fewer rows than asked to if the reqeusted number would have blown past the end of the buffer: + int numSafeRows = (numRows + startRow <= buffer.Count) ? numRows : buffer.Count - startRow; + + for( int i = 0; i < numSafeRows ; ++i) buffer[startRow + i].TouchTime(); } @@ -319,8 +339,29 @@ private void MoveColumn(int deltaPosition) private void PrintLine(string textToPrint) { IScreenBufferLine lineBuffer = buffer[AbsoluteCursorRow]; + textToPrint = StripUnprintables(textToPrint); lineBuffer.ArrayCopyFrom(textToPrint.ToCharArray(), 0, CursorColumn); MoveColumn(textToPrint.Length); } + + private string StripUnprintables(string textToPrint) + { + StringBuilder sb = new StringBuilder(); + foreach (char ch in textToPrint) + { + switch (ch) + { + case (char)0x0007: + case (char)UnicodeCommand.BEEP: + ++BeepsPending; + break; + default: + if (0x0020 <= ch) + sb.Append(ch); + break; + } + } + return sb.ToString(); + } } } \ No newline at end of file diff --git a/src/kOS.Safe/Screen/ScreenBufferLine.cs b/src/kOS.Safe/Screen/ScreenBufferLine.cs index fb2cd912f..4ad0bb740 100644 --- a/src/kOS.Safe/Screen/ScreenBufferLine.cs +++ b/src/kOS.Safe/Screen/ScreenBufferLine.cs @@ -59,7 +59,8 @@ public ScreenBufferLine(int size) /// /// Perform the Array.Copy() function. - /// Copies a subrange of values from a source array into this array. + /// Copies a subrange of values from a source array into this array, + /// with safety checks to truncate the copy length if it's out of range. /// copy from here /// starting at this index /// putting it into this index of me @@ -67,13 +68,22 @@ public ScreenBufferLine(int size) /// public void ArrayCopyFrom(char[] source, int sourceStart, int destinationStart, int length = -1) { - Array.Copy(source, sourceStart, charArray, destinationStart, (length >= 0 ? length : source.Length)); + int maxSafeLength = (charArray.Length - destinationStart); + + int effectiveLength = (length < 0 ? source.Length : length); + if (effectiveLength > maxSafeLength) + { + effectiveLength = maxSafeLength; + } + + Array.Copy(source, sourceStart, charArray, destinationStart, effectiveLength); TouchTime(); } /// /// Perform the Array.Copy() function. - /// Copies a subrange of values from a source array into this array. + /// Copies a subrange of values from a source array into this array, + /// with safety checks to truncate the copy length if it's out of range. /// /// copy from here /// starting at this index diff --git a/src/kOS.Safe/Screen/TextEditor.cs b/src/kOS.Safe/Screen/TextEditor.cs index b51a6d9a2..72ae75408 100644 --- a/src/kOS.Safe/Screen/TextEditor.cs +++ b/src/kOS.Safe/Screen/TextEditor.cs @@ -44,14 +44,19 @@ public virtual void Type(char ch) case 13: // enter NewLine(); break; + case 7: + case (char)UnicodeCommand.BEEP: + ++base.BeepsPending; + break; default: InsertChar(ch); break; } } - public virtual void SpecialKey(char key) + public virtual bool SpecialKey(char key) { + bool gotUsed = true; switch (key) { case (char)UnicodeCommand.LEFTCURSORONE: @@ -79,7 +84,15 @@ public virtual void SpecialKey(char key) case (char)UnicodeCommand.PAGEDOWNCURSOR: ScrollVertical(10); break; + case (char)0x007: + case (char)UnicodeCommand.BEEP: + ++base.BeepsPending; + break; + default: + gotUsed = false; + break; } + return gotUsed; } protected void SaveCursorPos() diff --git a/src/kOS.Safe/Serialization/Dump.cs b/src/kOS.Safe/Serialization/Dump.cs new file mode 100644 index 000000000..7480189c6 --- /dev/null +++ b/src/kOS.Safe/Serialization/Dump.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; + +namespace kOS.Safe +{ + public class Dump : Dictionary + { + public const string Items = "items"; + public const string Entries = "entries"; + + public Dump() + { + } + + public Dump(IDictionary dictionary) : base(dictionary) + { + } + + } + +} + diff --git a/src/kOS.Safe/Serialization/DumpWithHeader.cs b/src/kOS.Safe/Serialization/DumpWithHeader.cs new file mode 100644 index 000000000..e2275021e --- /dev/null +++ b/src/kOS.Safe/Serialization/DumpWithHeader.cs @@ -0,0 +1,18 @@ +using System.Collections.Generic; + +namespace kOS.Safe.Serialization +{ + public class DumpWithHeader : Dump + { + public string Header { get; set; } + + public DumpWithHeader() + { + } + + public DumpWithHeader(IDictionary dictionary) : base(dictionary) + { + } + } +} + diff --git a/src/kOS.Safe/Serialization/Formatter.cs b/src/kOS.Safe/Serialization/Formatter.cs new file mode 100644 index 000000000..81e1d3a3e --- /dev/null +++ b/src/kOS.Safe/Serialization/Formatter.cs @@ -0,0 +1,15 @@ +using System.Collections.Generic; + +namespace kOS.Safe.Serialization +{ + public interface IFormatWriter + { + string Write(Dump value); + } + + public interface IFormatReader + { + Dump Read(string input); + } +} + diff --git a/src/kOS.Safe/Serialization/JSONFormatter.cs b/src/kOS.Safe/Serialization/JSONFormatter.cs new file mode 100644 index 000000000..1af19e7bc --- /dev/null +++ b/src/kOS.Safe/Serialization/JSONFormatter.cs @@ -0,0 +1,172 @@ +using System.Collections.Generic; +using System; +using System.Linq; +using System.Text; +using kOS.Safe.Persistence; + +namespace kOS.Safe.Serialization +{ + public class JsonFormatter : IFormatWriter, IFormatReader + { + private static readonly JsonFormatter instance; + + public static IFormatReader ReaderInstance + { + get + { + return instance; + } + } + + public static IFormatWriter WriterInstance + { + get + { + return instance; + } + } + + private JsonFormatter() + { + } + + static JsonFormatter() + { + instance = new JsonFormatter(); + } + + private object WriteJsonObjects(object value) + { + var objects = value as IDictionary; + if (objects != null) { + var stringKeys = new JsonObject(); + + foreach (var entry in objects) { + stringKeys[entry.Key.ToString()] = WriteJsonObjects(entry.Value); + } + + return stringKeys; + } else if (value is List) + { + return (value as List).Select(item => WriteJsonObjects(item)).ToList(); + } + + return value; + } + + public string Write(Dump value) + { + return JsonHelper.FormatJson(SimpleJson.SerializeObject(WriteJsonObjects(value))); + } + + private Dump ReadJsonObject(JsonObject dictionary) + { + var result = new Dump(); + + foreach (var entry in dictionary) + { + result[entry.Key] = ReadValue(entry.Value); + } + + return result; + } + + private object ReadValue(object read) + { + var objects = read as JsonObject; + if (objects != null) + { + return ReadJsonObject(objects); + } if (read is List) { + return (read as List).Select(item => ReadValue(item)).ToList(); + } else + { + return read; + } + } + + public Dump Read(string input) + { + return ReadJsonObject(SimpleJson.DeserializeObject(input)); + } + + + /// + /// Handles JSON indentation. + /// + class JsonHelper + { + private const string INDENT_STRING = " "; + public static string FormatJson(string str) + { + var indent = 0; + var quoted = false; + var sb = new StringBuilder(); + for (var i = 0; i < str.Length; i++) + { + var ch = str[i]; + switch (ch) + { + case '{': + case '[': + sb.Append(ch); + if (!quoted) + { + sb.Append(FileContent.NEW_LINE); + Enumerable.Range(0, ++indent).ForEach(item => sb.Append(INDENT_STRING)); + } + break; + case '}': + case ']': + if (!quoted) + { + sb.Append(FileContent.NEW_LINE); + Enumerable.Range(0, --indent).ForEach(item => sb.Append(INDENT_STRING)); + } + sb.Append(ch); + break; + case '"': + sb.Append(ch); + bool escaped = false; + var index = i; + while (index > 0 && str[--index] == '\\') + escaped = !escaped; + if (!escaped) + quoted = !quoted; + break; + case ',': + sb.Append(ch); + if (!quoted) + { + sb.Append(FileContent.NEW_LINE); + Enumerable.Range(0, indent).ForEach(item => sb.Append(INDENT_STRING)); + } + break; + case ':': + sb.Append(ch); + if (!quoted) + sb.Append(" "); + break; + default: + sb.Append(ch); + break; + } + } + return sb.ToString(); + } + } + + } + + static class Extensions + { + public static void ForEach(this IEnumerable ie, Action action) + { + foreach (var i in ie) + { + action(i); + } + } + } +} + diff --git a/src/kOS.Safe/Serialization/SafeSerializationMgr.cs b/src/kOS.Safe/Serialization/SafeSerializationMgr.cs new file mode 100644 index 000000000..c7dca1a3c --- /dev/null +++ b/src/kOS.Safe/Serialization/SafeSerializationMgr.cs @@ -0,0 +1,128 @@ +using System; +using System.Collections.Generic; +using kOS.Safe.Encapsulation; +using kOS.Safe.Exceptions; +using System.Linq; + +namespace kOS.Safe.Serialization +{ + public class SafeSerializationMgr + { + public static string TYPE_KEY = "$type"; + + public static bool IsValue(object serialized) + { + return serialized.GetType().IsPrimitive || serialized is string; + } + + public static bool IsEncapsulatedValue(object serialized) + { + return serialized is ISerializableValue; + } + + private object DumpValue(object value, bool includeType) + { + var valueDumper = value as SerializableStructure; + + if (valueDumper != null) { + return Dump(valueDumper, includeType); + } else if (value is List) { + return (value as List).Select((v) => DumpValue(v, includeType)).ToList(); + } else if (IsEncapsulatedValue(value) || IsValue(value)) { + return Structure.ToPrimitive(value); + } else { + return value.ToString(); + } + } + + public Dump Dump(SerializableStructure dumper, bool includeType = true) + { + var dump = dumper.Dump(); + + List keys = new List(dump.Keys); + + foreach (object key in keys) + { + dump[key] = DumpValue(dump[key], includeType); + } + + if (includeType) + { + dump.Add(TYPE_KEY, dumper.GetType().Namespace + "." + dumper.GetType().Name); + } + + return dump; + } + + public string Serialize(SerializableStructure serialized, IFormatWriter formatter, bool includeType = true) + { + return formatter.Write(Dump(serialized, includeType)); + } + + public object CreateValue(object value) + { + var objects = value as Dump; + if (objects != null) + { + return CreateFromDump(objects); + } else if (value is List) + { + return (value as List).Select(item => CreateValue(item)).ToList(); + } + + return value; + } + + public SerializableStructure CreateFromDump(Dump dump) + { + var data = new Dump(); + foreach (KeyValuePair entry in dump) + { + if (entry.Key.Equals(TYPE_KEY)) + { + continue; + } + + data [entry.Key] = CreateValue (entry.Value); + } + + string typeFullName = dump[TYPE_KEY] as string; + + if (String.IsNullOrEmpty(typeFullName)) + { + throw new KOSSerializationException("Type information missing"); + } + + return CreateInstance(typeFullName, data); + } + + public virtual SerializableStructure CreateInstance(string typeFullName, Dump data) + { + var deserializedType = Type.GetType(typeFullName); + + if (deserializedType == null) + { + throw new KOSSerializationException("Unrecognized type: " + typeFullName); + } + + SerializableStructure instance = Activator.CreateInstance(deserializedType) as SerializableStructure; + + instance.LoadDump(data); + + return instance; + } + + public SerializableStructure Deserialize(string input, IFormatReader formatter) + { + Dump dump = formatter.Read(input); + + return dump == null ? null : CreateFromDump(dump); + } + + public string ToString(SerializableStructure dumper) + { + return Serialize(dumper, TerminalFormatter.Instance, false); + } + } +} + diff --git a/src/kOS.Safe/Serialization/SerializableStructure.cs b/src/kOS.Safe/Serialization/SerializableStructure.cs new file mode 100644 index 000000000..e81785110 --- /dev/null +++ b/src/kOS.Safe/Serialization/SerializableStructure.cs @@ -0,0 +1,13 @@ +using System; +using kOS.Safe.Encapsulation; + +namespace kOS.Safe.Serialization +{ + [kOS.Safe.Utilities.KOSNomenclature("Structure", KOSToCSharp = false)] // reports itself as "Structure" but won't be the canonical meaning of "Structure" + public abstract class SerializableStructure : Structure + { + public abstract Dump Dump(); + public abstract void LoadDump(Dump dump); + } +} + diff --git a/src/kOS.Safe/Serialization/TerminalFormatter.cs b/src/kOS.Safe/Serialization/TerminalFormatter.cs new file mode 100644 index 000000000..b14448b4a --- /dev/null +++ b/src/kOS.Safe/Serialization/TerminalFormatter.cs @@ -0,0 +1,132 @@ +using System; +using System.Collections.Generic; +using kOS.Safe.Encapsulation; +using System.Linq; + +namespace kOS.Safe.Serialization +{ + public class TerminalFormatter : IFormatWriter + { + private static int INDENT_SPACES = 2; + private static readonly TerminalFormatter instance; + + public static TerminalFormatter Instance + { + get + { + return instance; + } + } + + private TerminalFormatter() + { + + } + + static TerminalFormatter() + { + instance = new TerminalFormatter(); + } + + public string Write(Dump value) + { + string header = ""; + + var withHeader = value as DumpWithHeader; + if (withHeader != null) + { + header = withHeader.Header + Environment.NewLine; + } + + return header + WriteIndented(value); + } + + public string WriteIndented(Dump dump, int level = 0) + { + IDictionary printedDump; + + if (dump.Count == 1 && dump.ContainsKey(Dump.Items)) { + // special handling for enumerables + List list = dump[Dump.Items] as List; + printedDump = list.Select((x, i) => new { Item = x, Index = (object)i }) + .ToDictionary(x => x.Index, x => x.Item); + } else if (dump.Count == 1 && dump.ContainsKey(Dump.Entries)) { + // special handling for lexicons + List list = dump[Dump.Entries] as List; + + printedDump = new Dictionary(); + + for (int i = 0; 2 * i < list.Count; i++) + { + printedDump[list[2 * i]] = list[2 * i + 1]; + } + } else { + printedDump = dump; + } + + return WriteIndentedDump(printedDump, level); + } + + public string WriteIndentedDump(IDictionary dump, int level) + { + var result = new List(); + + foreach (KeyValuePair entry in dump) + { + var line = string.Empty.PadLeft(level * INDENT_SPACES); + var value = entry.Value; + string valueString; + + var objects = value as Dump; + if (objects != null) + { + string header = Environment.NewLine; + + var withHeader = value as DumpWithHeader; + if (withHeader != null) + { + header = withHeader.Header + Environment.NewLine; + } + + valueString = header + WriteIndented(objects, level + 1); + } else + { + valueString = value.ToString(); + } + + if (entry.Key is string || entry.Key is StringValue) + { + line += string.Format("[\"{0}\"] = ", entry.Key); + } else if (entry.Key is Dump) + { + string header = Environment.NewLine; + + var withHeader = entry.Key as DumpWithHeader; + if (withHeader != null) + { + header = withHeader.Header + Environment.NewLine; + } + + string keyString = header + WriteIndented(entry.Key as Dump, level + 1); + line += string.Format("[{0}] = ", keyString); + } else + { + line += string.Format("[{0}] = ", entry.Key.ToString()); + } + + if (entry.Value is string) + { + line += string.Format("\"{0}\"", valueString); + } else + { + line += string.Format("{0}", valueString); + } + + result.Add(line); + } + + return String.Join(Environment.NewLine, result.ToArray()); + } + } +} + diff --git a/src/kOS.Safe/SharedObjects.cs b/src/kOS.Safe/SharedObjects.cs index b84849348..c6fdab116 100644 --- a/src/kOS.Safe/SharedObjects.cs +++ b/src/kOS.Safe/SharedObjects.cs @@ -1,9 +1,11 @@ +using kOS.Safe.Binding; using kOS.Safe.Compilation; using kOS.Safe.Execution; using kOS.Safe.Function; using kOS.Safe.Module; using kOS.Safe.Persistence; using kOS.Safe.Screen; +using kOS.Safe.Sound; namespace kOS.Safe { @@ -12,11 +14,13 @@ public class SharedObjects public ICpu Cpu { get; set; } public IScreenBuffer Screen { get; set; } public IInterpreter Interpreter { get; set; } + public IBindingManager BindingMgr { get; set; } public Script ScriptHandler { get; set; } public ILogger Logger { get; set; } public IProcessor Processor { get; set; } public UpdateHandler UpdateHandler { get; set; } public IFunctionManager FunctionManager { get; set; } - public VolumeManager VolumeMgr { get; set; } + public IVolumeManager VolumeMgr { get; set; } + public ISoundMaker SoundMaker { get; set; } } } \ No newline at end of file diff --git a/src/kOS.Safe/SimpleJson.cs b/src/kOS.Safe/SimpleJson.cs new file mode 100644 index 000000000..cfbb25cba --- /dev/null +++ b/src/kOS.Safe/SimpleJson.cs @@ -0,0 +1,2127 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) 2011, The Outercurve Foundation. +// +// Licensed under the MIT License (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.opensource.org/licenses/mit-license.php +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Nathan Totten (ntotten.com), Jim Zimmerman (jimzimmerman.com) and Prabir Shrestha (prabir.me) +// https://github.com/facebook-csharp-sdk/simple-json +//----------------------------------------------------------------------- + +// VERSION: 0.38.0 + +// NOTE: uncomment the following line to make SimpleJson class internal. +//#define SIMPLE_JSON_INTERNAL + +// NOTE: uncomment the following line to make JsonArray and JsonObject class internal. +//#define SIMPLE_JSON_OBJARRAYINTERNAL + +// NOTE: uncomment the following line to enable dynamic support. +//#define SIMPLE_JSON_DYNAMIC + +// NOTE: uncomment the following line to enable DataContract support. +//#define SIMPLE_JSON_DATACONTRACT + +// NOTE: uncomment the following line to enable IReadOnlyCollection and IReadOnlyList support. +//#define SIMPLE_JSON_READONLY_COLLECTIONS + +// NOTE: uncomment the following line to disable linq expressions/compiled lambda (better performance) instead of method.invoke(). +// define if you are using .net framework <= 3.0 or < WP7.5 +//#define SIMPLE_JSON_NO_LINQ_EXPRESSION + +// NOTE: uncomment the following line if you are compiling under Window Metro style application/library. +// usually already defined in properties +//#define NETFX_CORE; + +// If you are targetting WinStore, WP8 and NET4.5+ PCL make sure to #define SIMPLE_JSON_TYPEINFO; + +// original json parsing code from http://techblog.procurios.nl/k/618/news/view/14605/14863/How-do-I-write-my-own-parser-for-JSON.html + +#if NETFX_CORE +#define SIMPLE_JSON_TYPEINFO +#endif + +using System; +using System.CodeDom.Compiler; +using System.Collections; +using System.Collections.Generic; +#if !SIMPLE_JSON_NO_LINQ_EXPRESSION +using System.Linq.Expressions; +#endif +using System.ComponentModel; +using System.Diagnostics.CodeAnalysis; +#if SIMPLE_JSON_DYNAMIC +using System.Dynamic; +#endif +using System.Globalization; +using System.Reflection; +using System.Runtime.Serialization; +using System.Text; +using kOS.Safe.Reflection; + +// ReSharper disable LoopCanBeConvertedToQuery +// ReSharper disable RedundantExplicitArrayCreation +// ReSharper disable SuggestUseVarKeywordEvident +namespace kOS.Safe +{ + /// + /// Represents the json array. + /// + [GeneratedCode("simple-json", "1.0.0")] + [EditorBrowsable(EditorBrowsableState.Never)] + [SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix")] +#if SIMPLE_JSON_OBJARRAYINTERNAL + internal +#else + public +#endif + class JsonArray : List + { + /// + /// Initializes a new instance of the class. + /// + public JsonArray() { } + + /// + /// Initializes a new instance of the class. + /// + /// The capacity of the json array. + public JsonArray(int capacity) : base(capacity) { } + + /// + /// The json representation of the array. + /// + /// The json representation of the array. + public override string ToString() + { + return SimpleJson.SerializeObject(this) ?? string.Empty; + } + } + + /// + /// Represents the json object. + /// + [GeneratedCode("simple-json", "1.0.0")] + [EditorBrowsable(EditorBrowsableState.Never)] + [SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix")] +#if SIMPLE_JSON_OBJARRAYINTERNAL + internal +#else + public +#endif + class JsonObject : +#if SIMPLE_JSON_DYNAMIC + DynamicObject, +#endif + IDictionary + { + /// + /// The internal member dictionary. + /// + private readonly Dictionary _members; + + /// + /// Initializes a new instance of . + /// + public JsonObject() + { + _members = new Dictionary(); + } + + /// + /// Initializes a new instance of . + /// + /// The implementation to use when comparing keys, or null to use the default for the type of the key. + public JsonObject(IEqualityComparer comparer) + { + _members = new Dictionary(comparer); + } + + /// + /// Gets the at the specified index. + /// + /// + public object this[int index] + { + get { return GetAtIndex(_members, index); } + } + + internal static object GetAtIndex(IDictionary obj, int index) + { + if (obj == null) + throw new ArgumentNullException("obj"); + if (index >= obj.Count) + throw new ArgumentOutOfRangeException("index"); + int i = 0; + foreach (KeyValuePair o in obj) + if (i++ == index) return o.Value; + return null; + } + + /// + /// Adds the specified key. + /// + /// The key. + /// The value. + public void Add(string key, object value) + { + _members.Add(key, value); + } + + /// + /// Determines whether the specified key contains key. + /// + /// The key. + /// + /// true if the specified key contains key; otherwise, false. + /// + public bool ContainsKey(string key) + { + return _members.ContainsKey(key); + } + + /// + /// Gets the keys. + /// + /// The keys. + public ICollection Keys + { + get { return _members.Keys; } + } + + /// + /// Removes the specified key. + /// + /// The key. + /// + public bool Remove(string key) + { + return _members.Remove(key); + } + + /// + /// Tries the get value. + /// + /// The key. + /// The value. + /// + public bool TryGetValue(string key, out object value) + { + return _members.TryGetValue(key, out value); + } + + /// + /// Gets the values. + /// + /// The values. + public ICollection Values + { + get { return _members.Values; } + } + + /// + /// Gets or sets the with the specified key. + /// + /// + public object this[string key] + { + get { return _members[key]; } + set { _members[key] = value; } + } + + /// + /// Adds the specified item. + /// + /// The item. + public void Add(KeyValuePair item) + { + _members.Add(item.Key, item.Value); + } + + /// + /// Clears this instance. + /// + public void Clear() + { + _members.Clear(); + } + + /// + /// Determines whether [contains] [the specified item]. + /// + /// The item. + /// + /// true if [contains] [the specified item]; otherwise, false. + /// + public bool Contains(KeyValuePair item) + { + return _members.ContainsKey(item.Key) && _members[item.Key] == item.Value; + } + + /// + /// Copies to. + /// + /// The array. + /// Index of the array. + public void CopyTo(KeyValuePair[] array, int arrayIndex) + { + if (array == null) throw new ArgumentNullException("array"); + int num = Count; + foreach (KeyValuePair kvp in this) + { + array[arrayIndex++] = kvp; + if (--num <= 0) + return; + } + } + + /// + /// Gets the count. + /// + /// The count. + public int Count + { + get { return _members.Count; } + } + + /// + /// Gets a value indicating whether this instance is read only. + /// + /// + /// true if this instance is read only; otherwise, false. + /// + public bool IsReadOnly + { + get { return false; } + } + + /// + /// Removes the specified item. + /// + /// The item. + /// + public bool Remove(KeyValuePair item) + { + return _members.Remove(item.Key); + } + + /// + /// Gets the enumerator. + /// + /// + public IEnumerator> GetEnumerator() + { + return _members.GetEnumerator(); + } + + /// + /// Returns an enumerator that iterates through a collection. + /// + /// + /// An object that can be used to iterate through the collection. + /// + IEnumerator IEnumerable.GetEnumerator() + { + return _members.GetEnumerator(); + } + + /// + /// Returns a json that represents the current . + /// + /// + /// A json that represents the current . + /// + public override string ToString() + { + return SimpleJson.SerializeObject(this); + } + +#if SIMPLE_JSON_DYNAMIC + /// + /// Provides implementation for type conversion operations. Classes derived from the class can override this method to specify dynamic behavior for operations that convert an object from one type to another. + /// + /// Provides information about the conversion operation. The binder.Type property provides the type to which the object must be converted. For example, for the statement (String)sampleObject in C# (CType(sampleObject, Type) in Visual Basic), where sampleObject is an instance of the class derived from the class, binder.Type returns the type. The binder.Explicit property provides information about the kind of conversion that occurs. It returns true for explicit conversion and false for implicit conversion. + /// The result of the type conversion operation. + /// + /// Alwasy returns true. + /// + public override bool TryConvert(ConvertBinder binder, out object result) + { + // + if (binder == null) + throw new ArgumentNullException("binder"); + // + Type targetType = binder.Type; + + if ((targetType == typeof(IEnumerable)) || + (targetType == typeof(IEnumerable>)) || + (targetType == typeof(IDictionary)) || + (targetType == typeof(IDictionary))) + { + result = this; + return true; + } + + return base.TryConvert(binder, out result); + } + + /// + /// Provides the implementation for operations that delete an object member. This method is not intended for use in C# or Visual Basic. + /// + /// Provides information about the deletion. + /// + /// Alwasy returns true. + /// + public override bool TryDeleteMember(DeleteMemberBinder binder) + { + // + if (binder == null) + throw new ArgumentNullException("binder"); + // + return _members.Remove(binder.Name); + } + + /// + /// Provides the implementation for operations that get a value by index. Classes derived from the class can override this method to specify dynamic behavior for indexing operations. + /// + /// Provides information about the operation. + /// The indexes that are used in the operation. For example, for the sampleObject[3] operation in C# (sampleObject(3) in Visual Basic), where sampleObject is derived from the DynamicObject class, is equal to 3. + /// The result of the index operation. + /// + /// Alwasy returns true. + /// + public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result) + { + if (indexes == null) throw new ArgumentNullException("indexes"); + if (indexes.Length == 1) + { + result = ((IDictionary)this)[(string)indexes[0]]; + return true; + } + result = null; + return true; + } + + /// + /// Provides the implementation for operations that get member values. Classes derived from the class can override this method to specify dynamic behavior for operations such as getting a value for a property. + /// + /// Provides information about the object that called the dynamic operation. The binder.Name property provides the name of the member on which the dynamic operation is performed. For example, for the Console.WriteLine(sampleObject.SampleProperty) statement, where sampleObject is an instance of the class derived from the class, binder.Name returns "SampleProperty". The binder.IgnoreCase property specifies whether the member name is case-sensitive. + /// The result of the get operation. For example, if the method is called for a property, you can assign the property value to . + /// + /// Alwasy returns true. + /// + public override bool TryGetMember(GetMemberBinder binder, out object result) + { + object value; + if (_members.TryGetValue(binder.Name, out value)) + { + result = value; + return true; + } + result = null; + return true; + } + + /// + /// Provides the implementation for operations that set a value by index. Classes derived from the class can override this method to specify dynamic behavior for operations that access objects by a specified index. + /// + /// Provides information about the operation. + /// The indexes that are used in the operation. For example, for the sampleObject[3] = 10 operation in C# (sampleObject(3) = 10 in Visual Basic), where sampleObject is derived from the class, is equal to 3. + /// The value to set to the object that has the specified index. For example, for the sampleObject[3] = 10 operation in C# (sampleObject(3) = 10 in Visual Basic), where sampleObject is derived from the class, is equal to 10. + /// + /// true if the operation is successful; otherwise, false. If this method returns false, the run-time binder of the language determines the behavior. (In most cases, a language-specific run-time exception is thrown. + /// + public override bool TrySetIndex(SetIndexBinder binder, object[] indexes, object value) + { + if (indexes == null) throw new ArgumentNullException("indexes"); + if (indexes.Length == 1) + { + ((IDictionary)this)[(string)indexes[0]] = value; + return true; + } + return base.TrySetIndex(binder, indexes, value); + } + + /// + /// Provides the implementation for operations that set member values. Classes derived from the class can override this method to specify dynamic behavior for operations such as setting a value for a property. + /// + /// Provides information about the object that called the dynamic operation. The binder.Name property provides the name of the member to which the value is being assigned. For example, for the statement sampleObject.SampleProperty = "Test", where sampleObject is an instance of the class derived from the class, binder.Name returns "SampleProperty". The binder.IgnoreCase property specifies whether the member name is case-sensitive. + /// The value to set to the member. For example, for sampleObject.SampleProperty = "Test", where sampleObject is an instance of the class derived from the class, the is "Test". + /// + /// true if the operation is successful; otherwise, false. If this method returns false, the run-time binder of the language determines the behavior. (In most cases, a language-specific run-time exception is thrown.) + /// + public override bool TrySetMember(SetMemberBinder binder, object value) + { + // + if (binder == null) + throw new ArgumentNullException("binder"); + // + _members[binder.Name] = value; + return true; + } + + /// + /// Returns the enumeration of all dynamic member names. + /// + /// + /// A sequence that contains dynamic member names. + /// + public override IEnumerable GetDynamicMemberNames() + { + foreach (var key in Keys) + yield return key; + } +#endif + } +} + +namespace kOS.Safe +{ + /// + /// This class encodes and decodes JSON strings. + /// Spec. details, see http://www.json.org/ + /// + /// JSON uses Arrays and Objects. These correspond here to the datatypes JsonArray(IList<object>) and JsonObject(IDictionary<string,object>). + /// All numbers are parsed to doubles. + /// + [GeneratedCode("simple-json", "1.0.0")] +#if SIMPLE_JSON_INTERNAL + internal +#else + public +#endif + static class SimpleJson + { + private const int TOKEN_NONE = 0; + private const int TOKEN_CURLY_OPEN = 1; + private const int TOKEN_CURLY_CLOSE = 2; + private const int TOKEN_SQUARED_OPEN = 3; + private const int TOKEN_SQUARED_CLOSE = 4; + private const int TOKEN_COLON = 5; + private const int TOKEN_COMMA = 6; + private const int TOKEN_STRING = 7; + private const int TOKEN_NUMBER = 8; + private const int TOKEN_TRUE = 9; + private const int TOKEN_FALSE = 10; + private const int TOKEN_NULL = 11; + private const int BUILDER_CAPACITY = 2000; + + private static readonly char[] EscapeTable; + private static readonly char[] EscapeCharacters = new char[] { '"', '\\', '\b', '\f', '\n', '\r', '\t' }; + private static readonly string EscapeCharactersString = new string(EscapeCharacters); + + static SimpleJson() + { + EscapeTable = new char[93]; + EscapeTable['"'] = '"'; + EscapeTable['\\'] = '\\'; + EscapeTable['\b'] = 'b'; + EscapeTable['\f'] = 'f'; + EscapeTable['\n'] = 'n'; + EscapeTable['\r'] = 'r'; + EscapeTable['\t'] = 't'; + } + + /// + /// Parses the string json into a value + /// + /// A JSON string. + /// An IList<object>, a IDictionary<string,object>, a double, a string, null, true, or false + public static object DeserializeObject(string json) + { + object obj; + if (TryDeserializeObject(json, out obj)) + return obj; + throw new SerializationException("Invalid JSON string"); + } + + /// + /// Try parsing the json string into a value. + /// + /// + /// A JSON string. + /// + /// + /// The object. + /// + /// + /// Returns true if successfull otherwise false. + /// + [SuppressMessage("Microsoft.Design", "CA1007:UseGenericsWhereAppropriate", Justification="Need to support .NET 2")] + public static bool TryDeserializeObject(string json, out object obj) + { + bool success = true; + if (json != null) + { + char[] charArray = json.ToCharArray(); + int index = 0; + obj = ParseValue(charArray, ref index, ref success); + } + else + obj = null; + + return success; + } + + public static object DeserializeObject(string json, Type type, IJsonSerializerStrategy jsonSerializerStrategy) + { + object jsonObject = DeserializeObject(json); + return type == null || jsonObject != null && ReflectionUtils.IsAssignableFrom(jsonObject.GetType(), type) + ? jsonObject + : (jsonSerializerStrategy ?? CurrentJsonSerializerStrategy).DeserializeObject(jsonObject, type); + } + + public static object DeserializeObject(string json, Type type) + { + return DeserializeObject(json, type, null); + } + + public static T DeserializeObject(string json, IJsonSerializerStrategy jsonSerializerStrategy) + { + return (T)DeserializeObject(json, typeof(T), jsonSerializerStrategy); + } + + public static T DeserializeObject(string json) + { + return (T)DeserializeObject(json, typeof(T), null); + } + + /// + /// Converts a IDictionary<string,object> / IList<object> object into a JSON string + /// + /// A IDictionary<string,object> / IList<object> + /// Serializer strategy to use + /// A JSON encoded string, or null if object 'json' is not serializable + public static string SerializeObject(object json, IJsonSerializerStrategy jsonSerializerStrategy) + { + StringBuilder builder = new StringBuilder(BUILDER_CAPACITY); + bool success = SerializeValue(jsonSerializerStrategy, json, builder); + return (success ? builder.ToString() : null); + } + + public static string SerializeObject(object json) + { + return SerializeObject(json, CurrentJsonSerializerStrategy); + } + + public static string EscapeToJavascriptString(string jsonString) + { + if (string.IsNullOrEmpty(jsonString)) + return jsonString; + + StringBuilder sb = new StringBuilder(); + char c; + + for (int i = 0; i < jsonString.Length; ) + { + c = jsonString[i++]; + + if (c == '\\') + { + int remainingLength = jsonString.Length - i; + if (remainingLength >= 2) + { + char lookahead = jsonString[i]; + if (lookahead == '\\') + { + sb.Append('\\'); + ++i; + } + else if (lookahead == '"') + { + sb.Append("\""); + ++i; + } + else if (lookahead == 't') + { + sb.Append('\t'); + ++i; + } + else if (lookahead == 'b') + { + sb.Append('\b'); + ++i; + } + else if (lookahead == 'n') + { + sb.Append('\n'); + ++i; + } + else if (lookahead == 'r') + { + sb.Append('\r'); + ++i; + } + } + } + else + { + sb.Append(c); + } + } + return sb.ToString(); + } + + static IDictionary ParseObject(char[] json, ref int index, ref bool success) + { + IDictionary table = new JsonObject(); + int token; + + // { + NextToken(json, ref index); + + bool done = false; + while (!done) + { + token = LookAhead(json, index); + if (token == TOKEN_NONE) + { + success = false; + return null; + } + else if (token == TOKEN_COMMA) + NextToken(json, ref index); + else if (token == TOKEN_CURLY_CLOSE) + { + NextToken(json, ref index); + return table; + } + else + { + // name + string name = ParseString(json, ref index, ref success); + if (!success) + { + success = false; + return null; + } + // : + token = NextToken(json, ref index); + if (token != TOKEN_COLON) + { + success = false; + return null; + } + // value + object value = ParseValue(json, ref index, ref success); + if (!success) + { + success = false; + return null; + } + table[name] = value; + } + } + return table; + } + + static JsonArray ParseArray(char[] json, ref int index, ref bool success) + { + JsonArray array = new JsonArray(); + + // [ + NextToken(json, ref index); + + bool done = false; + while (!done) + { + int token = LookAhead(json, index); + if (token == TOKEN_NONE) + { + success = false; + return null; + } + else if (token == TOKEN_COMMA) + NextToken(json, ref index); + else if (token == TOKEN_SQUARED_CLOSE) + { + NextToken(json, ref index); + break; + } + else + { + object value = ParseValue(json, ref index, ref success); + if (!success) + return null; + array.Add(value); + } + } + return array; + } + + static object ParseValue(char[] json, ref int index, ref bool success) + { + switch (LookAhead(json, index)) + { + case TOKEN_STRING: + return ParseString(json, ref index, ref success); + case TOKEN_NUMBER: + return ParseNumber(json, ref index, ref success); + case TOKEN_CURLY_OPEN: + return ParseObject(json, ref index, ref success); + case TOKEN_SQUARED_OPEN: + return ParseArray(json, ref index, ref success); + case TOKEN_TRUE: + NextToken(json, ref index); + return true; + case TOKEN_FALSE: + NextToken(json, ref index); + return false; + case TOKEN_NULL: + NextToken(json, ref index); + return null; + case TOKEN_NONE: + break; + } + success = false; + return null; + } + + static string ParseString(char[] json, ref int index, ref bool success) + { + StringBuilder s = new StringBuilder(BUILDER_CAPACITY); + char c; + + EatWhitespace(json, ref index); + + // " + c = json[index++]; + bool complete = false; + while (!complete) + { + if (index == json.Length) + break; + + c = json[index++]; + if (c == '"') + { + complete = true; + break; + } + else if (c == '\\') + { + if (index == json.Length) + break; + c = json[index++]; + if (c == '"') + s.Append('"'); + else if (c == '\\') + s.Append('\\'); + else if (c == '/') + s.Append('/'); + else if (c == 'b') + s.Append('\b'); + else if (c == 'f') + s.Append('\f'); + else if (c == 'n') + s.Append('\n'); + else if (c == 'r') + s.Append('\r'); + else if (c == 't') + s.Append('\t'); + else if (c == 'u') + { + int remainingLength = json.Length - index; + if (remainingLength >= 4) + { + // parse the 32 bit hex into an integer codepoint + uint codePoint; + if (!(success = UInt32.TryParse(new string(json, index, 4), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out codePoint))) + return ""; + + // convert the integer codepoint to a unicode char and add to string + if (0xD800 <= codePoint && codePoint <= 0xDBFF) // if high surrogate + { + index += 4; // skip 4 chars + remainingLength = json.Length - index; + if (remainingLength >= 6) + { + uint lowCodePoint; + if (new string(json, index, 2) == "\\u" && UInt32.TryParse(new string(json, index + 2, 4), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out lowCodePoint)) + { + if (0xDC00 <= lowCodePoint && lowCodePoint <= 0xDFFF) // if low surrogate + { + s.Append((char)codePoint); + s.Append((char)lowCodePoint); + index += 6; // skip 6 chars + continue; + } + } + } + success = false; // invalid surrogate pair + return ""; + } + s.Append(ConvertFromUtf32((int)codePoint)); + // skip 4 chars + index += 4; + } + else + break; + } + } + else + s.Append(c); + } + if (!complete) + { + success = false; + return null; + } + return s.ToString(); + } + + private static string ConvertFromUtf32(int utf32) + { + // http://www.java2s.com/Open-Source/CSharp/2.6.4-mono-.net-core/System/System/Char.cs.htm + if (utf32 < 0 || utf32 > 0x10FFFF) + throw new ArgumentOutOfRangeException("utf32", "The argument must be from 0 to 0x10FFFF."); + if (0xD800 <= utf32 && utf32 <= 0xDFFF) + throw new ArgumentOutOfRangeException("utf32", "The argument must not be in surrogate pair range."); + if (utf32 < 0x10000) + return new string((char)utf32, 1); + utf32 -= 0x10000; + return new string(new char[] { (char)((utf32 >> 10) + 0xD800), (char)(utf32 % 0x0400 + 0xDC00) }); + } + + static object ParseNumber(char[] json, ref int index, ref bool success) + { + EatWhitespace(json, ref index); + int lastIndex = GetLastIndexOfNumber(json, index); + int charLength = (lastIndex - index) + 1; + object returnNumber; + string str = new string(json, index, charLength); + if (str.IndexOf(".", StringComparison.OrdinalIgnoreCase) != -1 || str.IndexOf("e", StringComparison.OrdinalIgnoreCase) != -1) + { + double number; + success = double.TryParse(new string(json, index, charLength), NumberStyles.Any, CultureInfo.InvariantCulture, out number); + returnNumber = number; + } + else + { + long number; + success = long.TryParse(new string(json, index, charLength), NumberStyles.Any, CultureInfo.InvariantCulture, out number); + returnNumber = number; + } + index = lastIndex + 1; + return returnNumber; + } + + static int GetLastIndexOfNumber(char[] json, int index) + { + int lastIndex; + for (lastIndex = index; lastIndex < json.Length; lastIndex++) + if ("0123456789+-.eE".IndexOf(json[lastIndex]) == -1) break; + return lastIndex - 1; + } + + static void EatWhitespace(char[] json, ref int index) + { + for (; index < json.Length; index++) + if (" \t\n\r\b\f".IndexOf(json[index]) == -1) break; + } + + static int LookAhead(char[] json, int index) + { + int saveIndex = index; + return NextToken(json, ref saveIndex); + } + + [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")] + static int NextToken(char[] json, ref int index) + { + EatWhitespace(json, ref index); + if (index == json.Length) + return TOKEN_NONE; + char c = json[index]; + index++; + switch (c) + { + case '{': + return TOKEN_CURLY_OPEN; + case '}': + return TOKEN_CURLY_CLOSE; + case '[': + return TOKEN_SQUARED_OPEN; + case ']': + return TOKEN_SQUARED_CLOSE; + case ',': + return TOKEN_COMMA; + case '"': + return TOKEN_STRING; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case '-': + return TOKEN_NUMBER; + case ':': + return TOKEN_COLON; + } + index--; + int remainingLength = json.Length - index; + // false + if (remainingLength >= 5) + { + if (json[index] == 'f' && json[index + 1] == 'a' && json[index + 2] == 'l' && json[index + 3] == 's' && json[index + 4] == 'e') + { + index += 5; + return TOKEN_FALSE; + } + } + // true + if (remainingLength >= 4) + { + if (json[index] == 't' && json[index + 1] == 'r' && json[index + 2] == 'u' && json[index + 3] == 'e') + { + index += 4; + return TOKEN_TRUE; + } + } + // null + if (remainingLength >= 4) + { + if (json[index] == 'n' && json[index + 1] == 'u' && json[index + 2] == 'l' && json[index + 3] == 'l') + { + index += 4; + return TOKEN_NULL; + } + } + return TOKEN_NONE; + } + + static bool SerializeValue(IJsonSerializerStrategy jsonSerializerStrategy, object value, StringBuilder builder) + { + bool success = true; + string stringValue = value as string; + if (stringValue != null) + success = SerializeString(stringValue, builder); + else + { + IDictionary dict = value as IDictionary; + if (dict != null) + { + success = SerializeObject(jsonSerializerStrategy, dict.Keys, dict.Values, builder); + } + else + { + IDictionary stringDictionary = value as IDictionary; + if (stringDictionary != null) + { + success = SerializeObject(jsonSerializerStrategy, stringDictionary.Keys, stringDictionary.Values, builder); + } + else + { + IEnumerable enumerableValue = value as IEnumerable; + if (enumerableValue != null) + success = SerializeArray(jsonSerializerStrategy, enumerableValue, builder); + else if (IsNumeric(value)) + success = SerializeNumber(value, builder); + else if (value is bool) + builder.Append((bool)value ? "true" : "false"); + else if (value == null) + builder.Append("null"); + else + { + object serializedObject; + success = jsonSerializerStrategy.TrySerializeNonPrimitiveObject(value, out serializedObject); + if (success) + SerializeValue(jsonSerializerStrategy, serializedObject, builder); + } + } + } + } + return success; + } + + static bool SerializeObject(IJsonSerializerStrategy jsonSerializerStrategy, IEnumerable keys, IEnumerable values, StringBuilder builder) + { + builder.Append("{"); + IEnumerator ke = keys.GetEnumerator(); + IEnumerator ve = values.GetEnumerator(); + bool first = true; + while (ke.MoveNext() && ve.MoveNext()) + { + object key = ke.Current; + object value = ve.Current; + if (!first) + builder.Append(","); + string stringKey = key as string; + if (stringKey != null) + SerializeString(stringKey, builder); + else + if (!SerializeValue(jsonSerializerStrategy, value, builder)) return false; + builder.Append(":"); + if (!SerializeValue(jsonSerializerStrategy, value, builder)) + return false; + first = false; + } + builder.Append("}"); + return true; + } + + static bool SerializeArray(IJsonSerializerStrategy jsonSerializerStrategy, IEnumerable anArray, StringBuilder builder) + { + builder.Append("["); + bool first = true; + foreach (object value in anArray) + { + if (!first) + builder.Append(","); + if (!SerializeValue(jsonSerializerStrategy, value, builder)) + return false; + first = false; + } + builder.Append("]"); + return true; + } + + static bool SerializeString(string aString, StringBuilder builder) + { + // Happy path if there's nothing to be escaped. IndexOfAny is highly optimized (and unmanaged) + if (aString.IndexOfAny(EscapeCharacters) == -1) + { + builder.Append('"'); + builder.Append(aString); + builder.Append('"'); + + return true; + } + + builder.Append('"'); + int safeCharacterCount = 0; + char[] charArray = aString.ToCharArray(); + + for (int i = 0; i < charArray.Length; i++) + { + char c = charArray[i]; + + // Non ascii characters are fine, buffer them up and send them to the builder + // in larger chunks if possible. The escape table is a 1:1 translation table + // with \0 [default(char)] denoting a safe character. + if (c >= EscapeTable.Length || EscapeTable[c] == default(char)) + { + safeCharacterCount++; + } + else + { + if (safeCharacterCount > 0) + { + builder.Append(charArray, i - safeCharacterCount, safeCharacterCount); + safeCharacterCount = 0; + } + + builder.Append('\\'); + builder.Append(EscapeTable[c]); + } + } + + if (safeCharacterCount > 0) + { + builder.Append(charArray, charArray.Length - safeCharacterCount, safeCharacterCount); + } + + builder.Append('"'); + return true; + } + + static bool SerializeNumber(object number, StringBuilder builder) + { + if (number is long) + builder.Append(((long)number).ToString(CultureInfo.InvariantCulture)); + else if (number is ulong) + builder.Append(((ulong)number).ToString(CultureInfo.InvariantCulture)); + else if (number is int) + builder.Append(((int)number).ToString(CultureInfo.InvariantCulture)); + else if (number is uint) + builder.Append(((uint)number).ToString(CultureInfo.InvariantCulture)); + else if (number is decimal) + builder.Append(((decimal)number).ToString(CultureInfo.InvariantCulture)); + else if (number is float) + builder.Append(((float)number).ToString(CultureInfo.InvariantCulture)); + else + builder.Append(Convert.ToDouble(number, CultureInfo.InvariantCulture).ToString("r", CultureInfo.InvariantCulture)); + return true; + } + + /// + /// Determines if a given object is numeric in any way + /// (can be integer, double, null, etc). + /// + static bool IsNumeric(object value) + { + if (value is sbyte) return true; + if (value is byte) return true; + if (value is short) return true; + if (value is ushort) return true; + if (value is int) return true; + if (value is uint) return true; + if (value is long) return true; + if (value is ulong) return true; + if (value is float) return true; + if (value is double) return true; + if (value is decimal) return true; + return false; + } + + private static IJsonSerializerStrategy _currentJsonSerializerStrategy; + public static IJsonSerializerStrategy CurrentJsonSerializerStrategy + { + get + { + return _currentJsonSerializerStrategy ?? + (_currentJsonSerializerStrategy = +#if SIMPLE_JSON_DATACONTRACT + DataContractJsonSerializerStrategy +#else + PocoJsonSerializerStrategy +#endif +); + } + set + { + _currentJsonSerializerStrategy = value; + } + } + + private static PocoJsonSerializerStrategy _pocoJsonSerializerStrategy; + [EditorBrowsable(EditorBrowsableState.Advanced)] + public static PocoJsonSerializerStrategy PocoJsonSerializerStrategy + { + get + { + return _pocoJsonSerializerStrategy ?? (_pocoJsonSerializerStrategy = new PocoJsonSerializerStrategy()); + } + } + +#if SIMPLE_JSON_DATACONTRACT + + private static DataContractJsonSerializerStrategy _dataContractJsonSerializerStrategy; + [System.ComponentModel.EditorBrowsable(EditorBrowsableState.Advanced)] + public static DataContractJsonSerializerStrategy DataContractJsonSerializerStrategy + { + get + { + return _dataContractJsonSerializerStrategy ?? (_dataContractJsonSerializerStrategy = new DataContractJsonSerializerStrategy()); + } + } + +#endif + } + + [GeneratedCode("simple-json", "1.0.0")] +#if SIMPLE_JSON_INTERNAL + internal +#else + public +#endif + interface IJsonSerializerStrategy + { + [SuppressMessage("Microsoft.Design", "CA1007:UseGenericsWhereAppropriate", Justification="Need to support .NET 2")] + bool TrySerializeNonPrimitiveObject(object input, out object output); + object DeserializeObject(object value, Type type); + } + + [GeneratedCode("simple-json", "1.0.0")] +#if SIMPLE_JSON_INTERNAL + internal +#else + public +#endif + class PocoJsonSerializerStrategy : IJsonSerializerStrategy + { + internal IDictionary ConstructorCache; + internal IDictionary> GetCache; + internal IDictionary>> SetCache; + + internal static readonly Type[] EmptyTypes = new Type[0]; + internal static readonly Type[] ArrayConstructorParameterTypes = new Type[] { typeof(int) }; + + private static readonly string[] Iso8601Format = new string[] + { + @"yyyy-MM-dd\THH:mm:ss.FFFFFFF\Z", + @"yyyy-MM-dd\THH:mm:ss\Z", + @"yyyy-MM-dd\THH:mm:ssK" + }; + + public PocoJsonSerializerStrategy() + { + ConstructorCache = new ReflectionUtils.ThreadSafeDictionary(ContructorDelegateFactory); + GetCache = new ReflectionUtils.ThreadSafeDictionary>(GetterValueFactory); + SetCache = new ReflectionUtils.ThreadSafeDictionary>>(SetterValueFactory); + } + + protected virtual string MapClrMemberNameToJsonFieldName(string clrPropertyName) + { + return clrPropertyName; + } + + internal virtual ReflectionUtils.ConstructorDelegate ContructorDelegateFactory(Type key) + { + return ReflectionUtils.GetContructor(key, key.IsArray ? ArrayConstructorParameterTypes : EmptyTypes); + } + + internal virtual IDictionary GetterValueFactory(Type type) + { + IDictionary result = new Dictionary(); + foreach (PropertyInfo propertyInfo in ReflectionUtils.GetProperties(type)) + { + if (propertyInfo.CanRead) + { + MethodInfo getMethod = ReflectionUtils.GetGetterMethodInfo(propertyInfo); + if (getMethod.IsStatic || !getMethod.IsPublic) + continue; + result[MapClrMemberNameToJsonFieldName(propertyInfo.Name)] = ReflectionUtils.GetGetMethod(propertyInfo); + } + } + foreach (FieldInfo fieldInfo in ReflectionUtils.GetFields(type)) + { + if (fieldInfo.IsStatic || !fieldInfo.IsPublic) + continue; + result[MapClrMemberNameToJsonFieldName(fieldInfo.Name)] = ReflectionUtils.GetGetMethod(fieldInfo); + } + return result; + } + + internal virtual IDictionary> SetterValueFactory(Type type) + { + IDictionary> result = new Dictionary>(); + foreach (PropertyInfo propertyInfo in ReflectionUtils.GetProperties(type)) + { + if (propertyInfo.CanWrite) + { + MethodInfo setMethod = ReflectionUtils.GetSetterMethodInfo(propertyInfo); + if (setMethod.IsStatic || !setMethod.IsPublic) + continue; + result[MapClrMemberNameToJsonFieldName(propertyInfo.Name)] = new KeyValuePair(propertyInfo.PropertyType, ReflectionUtils.GetSetMethod(propertyInfo)); + } + } + foreach (FieldInfo fieldInfo in ReflectionUtils.GetFields(type)) + { + if (fieldInfo.IsInitOnly || fieldInfo.IsStatic || !fieldInfo.IsPublic) + continue; + result[MapClrMemberNameToJsonFieldName(fieldInfo.Name)] = new KeyValuePair(fieldInfo.FieldType, ReflectionUtils.GetSetMethod(fieldInfo)); + } + return result; + } + + public virtual bool TrySerializeNonPrimitiveObject(object input, out object output) + { + return TrySerializeKnownTypes(input, out output) || TrySerializeUnknownTypes(input, out output); + } + + [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")] + public virtual object DeserializeObject(object value, Type type) + { + if (type == null) throw new ArgumentNullException("type"); + string str = value as string; + + if (type == typeof (Guid) && string.IsNullOrEmpty(str)) + return default(Guid); + + if (value == null) + return null; + + object obj = null; + + if (str != null) + { + if (str.Length != 0) // We know it can't be null now. + { + if (type == typeof(DateTime) || (ReflectionUtils.IsNullableType(type) && Nullable.GetUnderlyingType(type) == typeof(DateTime))) + return DateTime.ParseExact(str, Iso8601Format, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal); + if (type == typeof(DateTimeOffset) || (ReflectionUtils.IsNullableType(type) && Nullable.GetUnderlyingType(type) == typeof(DateTimeOffset))) + return DateTimeOffset.ParseExact(str, Iso8601Format, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal); + if (type == typeof(Guid) || (ReflectionUtils.IsNullableType(type) && Nullable.GetUnderlyingType(type) == typeof(Guid))) + return new Guid(str); + if (type == typeof(Uri)) + { + bool isValid = Uri.IsWellFormedUriString(str, UriKind.RelativeOrAbsolute); + + Uri result; + if (isValid && Uri.TryCreate(str, UriKind.RelativeOrAbsolute, out result)) + return result; + + return null; + } + + if (type == typeof(string)) + return str; + + return Convert.ChangeType(str, type, CultureInfo.InvariantCulture); + } + else + { + if (type == typeof(Guid)) + obj = default(Guid); + else if (ReflectionUtils.IsNullableType(type) && Nullable.GetUnderlyingType(type) == typeof(Guid)) + obj = null; + else + obj = str; + } + // Empty string case + if (!ReflectionUtils.IsNullableType(type) && Nullable.GetUnderlyingType(type) == typeof(Guid)) + return str; + } + else if (value is bool) + return value; + + bool valueIsLong = value is long; + bool valueIsDouble = value is double; + if ((valueIsLong && type == typeof(long)) || (valueIsDouble && type == typeof(double))) + return value; + if ((valueIsDouble && type != typeof(double)) || (valueIsLong && type != typeof(long))) + { + obj = type == typeof(int) || type == typeof(long) || type == typeof(double) || type == typeof(float) || type == typeof(bool) || type == typeof(decimal) || type == typeof(byte) || type == typeof(short) + ? Convert.ChangeType(value, type, CultureInfo.InvariantCulture) + : value; + } + else + { + IDictionary objects = value as IDictionary; + if (objects != null) + { + IDictionary jsonObject = objects; + + if (ReflectionUtils.IsTypeDictionary(type)) + { + // if dictionary then + Type[] types = ReflectionUtils.GetGenericTypeArguments(type); + Type keyType = types[0]; + Type valueType = types[1]; + + Type genericType = typeof(Dictionary<,>).MakeGenericType(keyType, valueType); + + IDictionary dict = (IDictionary)ConstructorCache[genericType](); + + foreach (KeyValuePair kvp in jsonObject) + dict.Add(kvp.Key, DeserializeObject(kvp.Value, valueType)); + + obj = dict; + } + else + { + if (type == typeof(object)) + obj = value; + else + { + obj = ConstructorCache[type](); + foreach (KeyValuePair> setter in SetCache[type]) + { + object jsonValue; + if (jsonObject.TryGetValue(setter.Key, out jsonValue)) + { + jsonValue = DeserializeObject(jsonValue, setter.Value.Key); + setter.Value.Value(obj, jsonValue); + } + } + } + } + } + else + { + IList valueAsList = value as IList; + if (valueAsList != null) + { + IList jsonObject = valueAsList; + IList list = null; + + if (type.IsArray) + { + list = (IList)ConstructorCache[type](jsonObject.Count); + int i = 0; + foreach (object o in jsonObject) + list[i++] = DeserializeObject(o, type.GetElementType()); + } + else if (ReflectionUtils.IsTypeGenericeCollectionInterface(type) || ReflectionUtils.IsAssignableFrom(typeof(IList), type)) + { + Type innerType = ReflectionUtils.GetGenericListElementType(type); + list = (IList)(ConstructorCache[type] ?? ConstructorCache[typeof(List<>).MakeGenericType(innerType)])(jsonObject.Count); + foreach (object o in jsonObject) + list.Add(DeserializeObject(o, innerType)); + } + obj = list; + } + } + return obj; + } + if (ReflectionUtils.IsNullableType(type)) + return ReflectionUtils.ToNullableType(obj, type); + return obj; + } + + protected virtual object SerializeEnum(Enum p) + { + return Convert.ToDouble(p, CultureInfo.InvariantCulture); + } + + [SuppressMessage("Microsoft.Design", "CA1007:UseGenericsWhereAppropriate", Justification="Need to support .NET 2")] + protected virtual bool TrySerializeKnownTypes(object input, out object output) + { + bool returnValue = true; + if (input is DateTime) + output = ((DateTime)input).ToUniversalTime().ToString(Iso8601Format[0], CultureInfo.InvariantCulture); + else if (input is DateTimeOffset) + output = ((DateTimeOffset)input).ToUniversalTime().ToString(Iso8601Format[0], CultureInfo.InvariantCulture); + else if (input is Guid) + output = ((Guid)input).ToString("D"); + else if (input is Uri) + output = input.ToString(); + else + { + Enum inputEnum = input as Enum; + if (inputEnum != null) + output = SerializeEnum(inputEnum); + else + { + returnValue = false; + output = null; + } + } + return returnValue; + } + [SuppressMessage("Microsoft.Design", "CA1007:UseGenericsWhereAppropriate", Justification="Need to support .NET 2")] + protected virtual bool TrySerializeUnknownTypes(object input, out object output) + { + if (input == null) throw new ArgumentNullException("input"); + output = null; + Type type = input.GetType(); + if (type.FullName == null) + return false; + IDictionary obj = new JsonObject(); + IDictionary getters = GetCache[type]; + foreach (KeyValuePair getter in getters) + { + if (getter.Value != null) + obj.Add(MapClrMemberNameToJsonFieldName(getter.Key), getter.Value(input)); + } + output = obj; + return true; + } + } + +#if SIMPLE_JSON_DATACONTRACT + [GeneratedCode("simple-json", "1.0.0")] +#if SIMPLE_JSON_INTERNAL + internal +#else + public +#endif + class DataContractJsonSerializerStrategy : PocoJsonSerializerStrategy + { + public DataContractJsonSerializerStrategy() + { + GetCache = new ReflectionUtils.ThreadSafeDictionary>(GetterValueFactory); + SetCache = new ReflectionUtils.ThreadSafeDictionary>>(SetterValueFactory); + } + + internal override IDictionary GetterValueFactory(Type type) + { + bool hasDataContract = ReflectionUtils.GetAttribute(type, typeof(DataContractAttribute)) != null; + if (!hasDataContract) + return base.GetterValueFactory(type); + string jsonKey; + IDictionary result = new Dictionary(); + foreach (PropertyInfo propertyInfo in ReflectionUtils.GetProperties(type)) + { + if (propertyInfo.CanRead) + { + MethodInfo getMethod = ReflectionUtils.GetGetterMethodInfo(propertyInfo); + if (!getMethod.IsStatic && CanAdd(propertyInfo, out jsonKey)) + result[jsonKey] = ReflectionUtils.GetGetMethod(propertyInfo); + } + } + foreach (FieldInfo fieldInfo in ReflectionUtils.GetFields(type)) + { + if (!fieldInfo.IsStatic && CanAdd(fieldInfo, out jsonKey)) + result[jsonKey] = ReflectionUtils.GetGetMethod(fieldInfo); + } + return result; + } + + internal override IDictionary> SetterValueFactory(Type type) + { + bool hasDataContract = ReflectionUtils.GetAttribute(type, typeof(DataContractAttribute)) != null; + if (!hasDataContract) + return base.SetterValueFactory(type); + string jsonKey; + IDictionary> result = new Dictionary>(); + foreach (PropertyInfo propertyInfo in ReflectionUtils.GetProperties(type)) + { + if (propertyInfo.CanWrite) + { + MethodInfo setMethod = ReflectionUtils.GetSetterMethodInfo(propertyInfo); + if (!setMethod.IsStatic && CanAdd(propertyInfo, out jsonKey)) + result[jsonKey] = new KeyValuePair(propertyInfo.PropertyType, ReflectionUtils.GetSetMethod(propertyInfo)); + } + } + foreach (FieldInfo fieldInfo in ReflectionUtils.GetFields(type)) + { + if (!fieldInfo.IsInitOnly && !fieldInfo.IsStatic && CanAdd(fieldInfo, out jsonKey)) + result[jsonKey] = new KeyValuePair(fieldInfo.FieldType, ReflectionUtils.GetSetMethod(fieldInfo)); + } + // todo implement sorting for DATACONTRACT. + return result; + } + + private static bool CanAdd(MemberInfo info, out string jsonKey) + { + jsonKey = null; + if (ReflectionUtils.GetAttribute(info, typeof(IgnoreDataMemberAttribute)) != null) + return false; + DataMemberAttribute dataMemberAttribute = (DataMemberAttribute)ReflectionUtils.GetAttribute(info, typeof(DataMemberAttribute)); + if (dataMemberAttribute == null) + return false; + jsonKey = string.IsNullOrEmpty(dataMemberAttribute.Name) ? info.Name : dataMemberAttribute.Name; + return true; + } + } + +#endif + + namespace Reflection + { + // This class is meant to be copied into other libraries. So we want to exclude it from Code Analysis rules + // that might be in place in the target project. + [GeneratedCode("reflection-utils", "1.0.0")] +#if SIMPLE_JSON_REFLECTION_UTILS_PUBLIC + public +#else + internal +#endif + class ReflectionUtils + { + private static readonly object[] EmptyObjects = new object[] { }; + + public delegate object GetDelegate(object source); + public delegate void SetDelegate(object source, object value); + public delegate object ConstructorDelegate(params object[] args); + + public delegate TValue ThreadSafeDictionaryValueFactory(TKey key); + +#if SIMPLE_JSON_TYPEINFO + public static TypeInfo GetTypeInfo(Type type) + { + return type.GetTypeInfo(); + } +#else + public static Type GetTypeInfo(Type type) + { + return type; + } +#endif + + public static Attribute GetAttribute(MemberInfo info, Type type) + { +#if SIMPLE_JSON_TYPEINFO + if (info == null || type == null || !info.IsDefined(type)) + return null; + return info.GetCustomAttribute(type); +#else + if (info == null || type == null || !Attribute.IsDefined(info, type)) + return null; + return Attribute.GetCustomAttribute(info, type); +#endif + } + + public static Type GetGenericListElementType(Type type) + { + IEnumerable interfaces; +#if SIMPLE_JSON_TYPEINFO + interfaces = type.GetTypeInfo().ImplementedInterfaces; +#else + interfaces = type.GetInterfaces(); +#endif + foreach (Type implementedInterface in interfaces) + { + if (IsTypeGeneric(implementedInterface) && + implementedInterface.GetGenericTypeDefinition() == typeof (IList<>)) + { + return GetGenericTypeArguments(implementedInterface)[0]; + } + } + return GetGenericTypeArguments(type)[0]; + } + + public static Attribute GetAttribute(Type objectType, Type attributeType) + { + +#if SIMPLE_JSON_TYPEINFO + if (objectType == null || attributeType == null || !objectType.GetTypeInfo().IsDefined(attributeType)) + return null; + return objectType.GetTypeInfo().GetCustomAttribute(attributeType); +#else + if (objectType == null || attributeType == null || !Attribute.IsDefined(objectType, attributeType)) + return null; + return Attribute.GetCustomAttribute(objectType, attributeType); +#endif + } + + public static Type[] GetGenericTypeArguments(Type type) + { +#if SIMPLE_JSON_TYPEINFO + return type.GetTypeInfo().GenericTypeArguments; +#else + return type.GetGenericArguments(); +#endif + } + + public static bool IsTypeGeneric(Type type) + { + return GetTypeInfo(type).IsGenericType; + } + + public static bool IsTypeGenericeCollectionInterface(Type type) + { + if (!IsTypeGeneric(type)) + return false; + + Type genericDefinition = type.GetGenericTypeDefinition(); + + return (genericDefinition == typeof(IList<>) + || genericDefinition == typeof(ICollection<>) + || genericDefinition == typeof(IEnumerable<>) +#if SIMPLE_JSON_READONLY_COLLECTIONS + || genericDefinition == typeof(IReadOnlyCollection<>) + || genericDefinition == typeof(IReadOnlyList<>) +#endif + ); + } + + public static bool IsAssignableFrom(Type type1, Type type2) + { + return GetTypeInfo(type1).IsAssignableFrom(GetTypeInfo(type2)); + } + + public static bool IsTypeDictionary(Type type) + { +#if SIMPLE_JSON_TYPEINFO + if (typeof(IDictionary<,>).GetTypeInfo().IsAssignableFrom(type.GetTypeInfo())) + return true; +#else + if (typeof(System.Collections.IDictionary).IsAssignableFrom(type)) + return true; +#endif + if (!GetTypeInfo(type).IsGenericType) + return false; + + Type genericDefinition = type.GetGenericTypeDefinition(); + return genericDefinition == typeof(IDictionary<,>); + } + + public static bool IsNullableType(Type type) + { + return GetTypeInfo(type).IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>); + } + + public static object ToNullableType(object obj, Type nullableType) + { + return obj == null ? null : Convert.ChangeType(obj, Nullable.GetUnderlyingType(nullableType), CultureInfo.InvariantCulture); + } + + public static bool IsValueType(Type type) + { + return GetTypeInfo(type).IsValueType; + } + + public static IEnumerable GetConstructors(Type type) + { +#if SIMPLE_JSON_TYPEINFO + return type.GetTypeInfo().DeclaredConstructors; +#else + return type.GetConstructors(); +#endif + } + + public static ConstructorInfo GetConstructorInfo(Type type, params Type[] argsType) + { + IEnumerable constructorInfos = GetConstructors(type); + int i; + bool matches; + foreach (ConstructorInfo constructorInfo in constructorInfos) + { + ParameterInfo[] parameters = constructorInfo.GetParameters(); + if (argsType.Length != parameters.Length) + continue; + + i = 0; + matches = true; + foreach (ParameterInfo parameterInfo in constructorInfo.GetParameters()) + { + if (parameterInfo.ParameterType != argsType[i]) + { + matches = false; + break; + } + } + + if (matches) + return constructorInfo; + } + + return null; + } + + public static IEnumerable GetProperties(Type type) + { +#if SIMPLE_JSON_TYPEINFO + return type.GetRuntimeProperties(); +#else + return type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static); +#endif + } + + public static IEnumerable GetFields(Type type) + { +#if SIMPLE_JSON_TYPEINFO + return type.GetRuntimeFields(); +#else + return type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static); +#endif + } + + public static MethodInfo GetGetterMethodInfo(PropertyInfo propertyInfo) + { +#if SIMPLE_JSON_TYPEINFO + return propertyInfo.GetMethod; +#else + return propertyInfo.GetGetMethod(true); +#endif + } + + public static MethodInfo GetSetterMethodInfo(PropertyInfo propertyInfo) + { +#if SIMPLE_JSON_TYPEINFO + return propertyInfo.SetMethod; +#else + return propertyInfo.GetSetMethod(true); +#endif + } + + public static ConstructorDelegate GetContructor(ConstructorInfo constructorInfo) + { +#if SIMPLE_JSON_NO_LINQ_EXPRESSION + return GetConstructorByReflection(constructorInfo); +#else + return GetConstructorByExpression(constructorInfo); +#endif + } + + public static ConstructorDelegate GetContructor(Type type, params Type[] argsType) + { +#if SIMPLE_JSON_NO_LINQ_EXPRESSION + return GetConstructorByReflection(type, argsType); +#else + return GetConstructorByExpression(type, argsType); +#endif + } + + public static ConstructorDelegate GetConstructorByReflection(ConstructorInfo constructorInfo) + { + return delegate(object[] args) { return constructorInfo.Invoke(args); }; + } + + public static ConstructorDelegate GetConstructorByReflection(Type type, params Type[] argsType) + { + ConstructorInfo constructorInfo = GetConstructorInfo(type, argsType); + return constructorInfo == null ? null : GetConstructorByReflection(constructorInfo); + } + +#if !SIMPLE_JSON_NO_LINQ_EXPRESSION + + public static ConstructorDelegate GetConstructorByExpression(ConstructorInfo constructorInfo) + { + ParameterInfo[] paramsInfo = constructorInfo.GetParameters(); + ParameterExpression param = Expression.Parameter(typeof(object[]), "args"); + Expression[] argsExp = new Expression[paramsInfo.Length]; + for (int i = 0; i < paramsInfo.Length; i++) + { + Expression index = Expression.Constant(i); + Type paramType = paramsInfo[i].ParameterType; + Expression paramAccessorExp = Expression.ArrayIndex(param, index); + Expression paramCastExp = Expression.Convert(paramAccessorExp, paramType); + argsExp[i] = paramCastExp; + } + NewExpression newExp = Expression.New(constructorInfo, argsExp); + Expression> lambda = Expression.Lambda>(newExp, param); + Func compiledLambda = lambda.Compile(); + return delegate(object[] args) { return compiledLambda(args); }; + } + + public static ConstructorDelegate GetConstructorByExpression(Type type, params Type[] argsType) + { + ConstructorInfo constructorInfo = GetConstructorInfo(type, argsType); + return constructorInfo == null ? null : GetConstructorByExpression(constructorInfo); + } + +#endif + + public static GetDelegate GetGetMethod(PropertyInfo propertyInfo) + { +#if SIMPLE_JSON_NO_LINQ_EXPRESSION + return GetGetMethodByReflection(propertyInfo); +#else + return GetGetMethodByExpression(propertyInfo); +#endif + } + + public static GetDelegate GetGetMethod(FieldInfo fieldInfo) + { +#if SIMPLE_JSON_NO_LINQ_EXPRESSION + return GetGetMethodByReflection(fieldInfo); +#else + return GetGetMethodByExpression(fieldInfo); +#endif + } + + public static GetDelegate GetGetMethodByReflection(PropertyInfo propertyInfo) + { + MethodInfo methodInfo = GetGetterMethodInfo(propertyInfo); + return delegate(object source) { return methodInfo.Invoke(source, EmptyObjects); }; + } + + public static GetDelegate GetGetMethodByReflection(FieldInfo fieldInfo) + { + return delegate(object source) { return fieldInfo.GetValue(source); }; + } + +#if !SIMPLE_JSON_NO_LINQ_EXPRESSION + + public static GetDelegate GetGetMethodByExpression(PropertyInfo propertyInfo) + { + MethodInfo getMethodInfo = GetGetterMethodInfo(propertyInfo); + ParameterExpression instance = Expression.Parameter(typeof(object), "instance"); + UnaryExpression instanceCast = (!IsValueType(propertyInfo.DeclaringType)) ? Expression.TypeAs(instance, propertyInfo.DeclaringType) : Expression.Convert(instance, propertyInfo.DeclaringType); + Func compiled = Expression.Lambda>(Expression.TypeAs(Expression.Call(instanceCast, getMethodInfo), typeof(object)), instance).Compile(); + return delegate(object source) { return compiled(source); }; + } + + public static GetDelegate GetGetMethodByExpression(FieldInfo fieldInfo) + { + ParameterExpression instance = Expression.Parameter(typeof(object), "instance"); + MemberExpression member = Expression.Field(Expression.Convert(instance, fieldInfo.DeclaringType), fieldInfo); + GetDelegate compiled = Expression.Lambda(Expression.Convert(member, typeof(object)), instance).Compile(); + return delegate(object source) { return compiled(source); }; + } + +#endif + + public static SetDelegate GetSetMethod(PropertyInfo propertyInfo) + { +#if SIMPLE_JSON_NO_LINQ_EXPRESSION + return GetSetMethodByReflection(propertyInfo); +#else + return GetSetMethodByExpression(propertyInfo); +#endif + } + + public static SetDelegate GetSetMethod(FieldInfo fieldInfo) + { +#if SIMPLE_JSON_NO_LINQ_EXPRESSION + return GetSetMethodByReflection(fieldInfo); +#else + return GetSetMethodByExpression(fieldInfo); +#endif + } + + public static SetDelegate GetSetMethodByReflection(PropertyInfo propertyInfo) + { + MethodInfo methodInfo = GetSetterMethodInfo(propertyInfo); + return delegate(object source, object value) { methodInfo.Invoke(source, new object[] { value }); }; + } + + public static SetDelegate GetSetMethodByReflection(FieldInfo fieldInfo) + { + return delegate(object source, object value) { fieldInfo.SetValue(source, value); }; + } + +#if !SIMPLE_JSON_NO_LINQ_EXPRESSION + + public static SetDelegate GetSetMethodByExpression(PropertyInfo propertyInfo) + { + MethodInfo setMethodInfo = GetSetterMethodInfo(propertyInfo); + ParameterExpression instance = Expression.Parameter(typeof(object), "instance"); + ParameterExpression value = Expression.Parameter(typeof(object), "value"); + UnaryExpression instanceCast = (!IsValueType(propertyInfo.DeclaringType)) ? Expression.TypeAs(instance, propertyInfo.DeclaringType) : Expression.Convert(instance, propertyInfo.DeclaringType); + UnaryExpression valueCast = (!IsValueType(propertyInfo.PropertyType)) ? Expression.TypeAs(value, propertyInfo.PropertyType) : Expression.Convert(value, propertyInfo.PropertyType); + Action compiled = Expression.Lambda>(Expression.Call(instanceCast, setMethodInfo, valueCast), new ParameterExpression[] { instance, value }).Compile(); + return delegate(object source, object val) { compiled(source, val); }; + } + + public static SetDelegate GetSetMethodByExpression(FieldInfo fieldInfo) + { + ParameterExpression instance = Expression.Parameter(typeof(object), "instance"); + ParameterExpression value = Expression.Parameter(typeof(object), "value"); + Action compiled = Expression.Lambda>( + Assign(Expression.Field(Expression.Convert(instance, fieldInfo.DeclaringType), fieldInfo), Expression.Convert(value, fieldInfo.FieldType)), instance, value).Compile(); + return delegate(object source, object val) { compiled(source, val); }; + } + + public static BinaryExpression Assign(Expression left, Expression right) + { +#if SIMPLE_JSON_TYPEINFO + return Expression.Assign(left, right); +#else + MethodInfo assign = typeof(Assigner<>).MakeGenericType(left.Type).GetMethod("Assign"); + BinaryExpression assignExpr = Expression.Add(left, right, assign); + return assignExpr; +#endif + } + + private static class Assigner + { + public static T Assign(ref T left, T right) + { + return (left = right); + } + } + +#endif + + public sealed class ThreadSafeDictionary : IDictionary + { + private readonly object _lock = new object(); + private readonly ThreadSafeDictionaryValueFactory _valueFactory; + private Dictionary _dictionary; + + public ThreadSafeDictionary(ThreadSafeDictionaryValueFactory valueFactory) + { + _valueFactory = valueFactory; + } + + private TValue Get(TKey key) + { + if (_dictionary == null) + return AddValue(key); + TValue value; + if (!_dictionary.TryGetValue(key, out value)) + return AddValue(key); + return value; + } + + private TValue AddValue(TKey key) + { + TValue value = _valueFactory(key); + lock (_lock) + { + if (_dictionary == null) + { + _dictionary = new Dictionary(); + _dictionary[key] = value; + } + else + { + TValue val; + if (_dictionary.TryGetValue(key, out val)) + return val; + Dictionary dict = new Dictionary(_dictionary); + dict[key] = value; + _dictionary = dict; + } + } + return value; + } + + public void Add(TKey key, TValue value) + { + throw new NotImplementedException(); + } + + public bool ContainsKey(TKey key) + { + return _dictionary.ContainsKey(key); + } + + public ICollection Keys + { + get { return _dictionary.Keys; } + } + + public bool Remove(TKey key) + { + throw new NotImplementedException(); + } + + public bool TryGetValue(TKey key, out TValue value) + { + value = this[key]; + return true; + } + + public ICollection Values + { + get { return _dictionary.Values; } + } + + public TValue this[TKey key] + { + get { return Get(key); } + set { throw new NotImplementedException(); } + } + + public void Add(KeyValuePair item) + { + throw new NotImplementedException(); + } + + public void Clear() + { + throw new NotImplementedException(); + } + + public bool Contains(KeyValuePair item) + { + throw new NotImplementedException(); + } + + public void CopyTo(KeyValuePair[] array, int arrayIndex) + { + throw new NotImplementedException(); + } + + public int Count + { + get { return _dictionary.Count; } + } + + public bool IsReadOnly + { + get { throw new NotImplementedException(); } + } + + public bool Remove(KeyValuePair item) + { + throw new NotImplementedException(); + } + + public IEnumerator> GetEnumerator() + { + return _dictionary.GetEnumerator(); + } + + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() + { + return _dictionary.GetEnumerator(); + } + } + + } + } +} +// ReSharper restore LoopCanBeConvertedToQuery +// ReSharper restore RedundantExplicitArrayCreation +// ReSharper restore SuggestUseVarKeywordEvident diff --git a/src/kOS.Safe/Sound/ISoundMaker.cs b/src/kOS.Safe/Sound/ISoundMaker.cs new file mode 100644 index 000000000..a9651fd28 --- /dev/null +++ b/src/kOS.Safe/Sound/ISoundMaker.cs @@ -0,0 +1,37 @@ +using System; + +namespace kOS.Safe.Sound +{ + /// + /// The ISoundMaker is the interface which will handle all sound effects + /// for the whole mod, no matter how many kOS PartModules there are. + /// It consolidates all sound clips into this one instance. A non-Unity variant + /// can be made which will probably just ignore all these requests + /// and do nothing with them (but still be compilable), for use with + /// Safe testing. + /// + public interface ISoundMaker + { + /// + /// Load the given sound file into the set of sounds the soundmaker knows how to play, + /// giving it a name to refer to it in the future. + /// + /// name to refer to this sound in the future. + /// URL of where to obtain the sound clip file from. + void LoadSound(string soundName, string soundFileURL); + + /// + /// Attempt to play the given sound clip by its name. Note that + /// it is impossible to play the same sound clip multiple times on + /// top of itself, with the system ISoundMaker is using. Therefore + /// if the sound cannot be played yet because it's arleady being played, + /// it will return false. + /// This call is non-blocking. It will only begin the sound and let it + /// play in the background, returning immediately. It will not wait for + /// the sound clip to finish playing. + /// + /// string that was given to LoadSound() earlier + /// True if the sound has begun playing. False if it has to wait. + bool BeginSound(string soundName); + } +} diff --git a/src/kOS.Safe/UpdateHandler.cs b/src/kOS.Safe/UpdateHandler.cs index 677fcaa2c..c6ea78d27 100644 --- a/src/kOS.Safe/UpdateHandler.cs +++ b/src/kOS.Safe/UpdateHandler.cs @@ -1,4 +1,6 @@ using System.Collections.Generic; +using System.Linq; +using System; namespace kOS.Safe { @@ -59,5 +61,26 @@ public void UpdateFixedObservers(double deltaTime) observer.KOSFixedUpdate(deltaTime); } } + + /// + /// Return all the registered fixed update handlers of a particular type + /// + /// + /// + public IEnumerable GetAllFixedUpdatersOfType(Type t) + { + return fixedObservers.Where(item => t.IsAssignableFrom(item.GetType())); + } + + /// + /// Return all the registered update handlers of a particular type + /// + /// + /// + public IEnumerable GetAllUpdatersOfType(Type t) + { + return observers.Where(item => t.IsAssignableFrom(item.GetType())); + } + } } diff --git a/src/kOS.Safe/UserIO/UnicodeCommand.cs b/src/kOS.Safe/UserIO/UnicodeCommand.cs index aac31677d..13531fe57 100644 --- a/src/kOS.Safe/UserIO/UnicodeCommand.cs +++ b/src/kOS.Safe/UserIO/UnicodeCommand.cs @@ -221,6 +221,40 @@ public enum UnicodeCommand /// (For example a height of 66, which is hex 0x32 would end up being sent as the capital letter 'B' which is Unicode 0x0032.). /// RESIZESCREEN, + + /// + /// Our homemade unicode char that maps to the ascii BEL character that causes a terminal to beep. + /// + BEEP, + + /// + /// Send this char to put the terminal into reversed color mode. + /// + REVERSESCREENMODE, + + /// + /// Send this char to put the terminal into normal foreground color mode. + /// + NORMALSCREENMODE, + + /// + /// Send this char to put the terminal into visual beep (beeps flash the screen) mode. + /// NOTE that most terminals refuse to implement an escape code for this, setting the beep mode + /// is purely a client-side thing on the setup screen for them, so there's a good chance this will get ignored. + /// As of this writing, none of the Terminal Mappers in kOS actually use this, but it's here in case we + /// ever support a more modern terminal class in the future that does implement it. + /// + VISUALBEEPMODE, + + /// + /// Send this char to put the terminal into normal audio beep mode (beeps make a sound and don't flash the screen). + /// NOTE that most terminals refuse to implement an escape code for this, setting the beep mode + /// is purely a client-side thing on the setup screen for them, so there's a good chance this will get ignored. + /// As of this writing, none of the Terminal Mappers in kOS actually use this, but it's here in case we + /// ever support a more modern terminal class in the future that does implement it. + /// + AUDIOBEEPMODE + } // For tracking multiple-character input sequences to remember where it is in the sequence: diff --git a/src/kOS.Safe/Utilities/CpuUtility.cs b/src/kOS.Safe/Utilities/CpuUtility.cs new file mode 100644 index 000000000..6aecb2587 --- /dev/null +++ b/src/kOS.Safe/Utilities/CpuUtility.cs @@ -0,0 +1,50 @@ +using System; +using System.Collections.Generic; +using kOS.Safe.Execution; + +namespace kOS.Safe.Utilities +{ + public class CpuUtility + { + public static readonly Type ArgMarkerType = typeof (KOSArgMarkerType); + + /// + /// Take the topmost arguments down to the ARG_MARKER_STRING, pop them off, and then + /// put them back again in reversed order so a function can read them in normal order. + /// Note that if this is an indirect call, it will also consume the thing just under + /// the ARG_MARKER, since that's expected to be the delegate or KOSDelegate that we already + /// read and pulled the needed information from. + /// the cpu we are running on, fur stack manipulation purposes + /// need to know if this was a direct or indirect call. If indirect, + /// then that means it also needs to consume the indirect reference off the stack just under + /// the args + /// + public static void ReverseStackArgs(ICpu cpu, bool direct) + { + List args = new List(); + object arg = cpu.PopValue(); + while (cpu.GetStackSize() > 0 && arg.GetType() != ArgMarkerType) + { + args.Add(arg); + + // It's important to dereference with PopValue, not using PopStack, because the function + // being called might not even be able to see the variable in scope anyway. + // In other words, if calling a function like so: + // declare foo to 3. + // myfunc(foo). + // The code inside myfunc needs to see that as being identical to just saying: + // myfunc(3). + // It has to be unaware of the fact that the name of the argument was 'foo'. It just needs to + // see the contents that were inside foo. + arg = cpu.PopValue(); + } + if (! direct) + cpu.PopStack(); // throw away the delegate or KOSDelegate info - we already snarfed it by now. + // Push the arg marker back on again. + cpu.PushStack(new KOSArgMarkerType()); + // Push the arguments back on again, which will invert their order: + foreach (object item in args) + cpu.PushStack(item); + } + } +} diff --git a/src/kOS.Safe/Utilities/KOSNomenclature.cs b/src/kOS.Safe/Utilities/KOSNomenclature.cs new file mode 100644 index 000000000..bfccfa047 --- /dev/null +++ b/src/kOS.Safe/Utilities/KOSNomenclature.cs @@ -0,0 +1,180 @@ +using System; +using System.Text; +using System.Reflection; +using System.Collections.Generic; +using System.Linq; +using kOS.Safe.Encapsulation; +using kOS.Safe.Exceptions; +using kOS.Safe.Serialization; + +namespace kOS.Safe.Utilities +{ + /// + /// A class for the purpose of holding the mapping information that goes + /// back and forth between C# type names and thier KOS type name equivalents. + /// + /// Any time you add a new class derived from kOS.Safe.Encapsulated.Structure, you + /// should check to see if you should add a mapping to this class to go with it. + /// + /// This class is intended to be used "statically" without an actual instance of it + /// being necessary. There should be only one copy of its data, globally, across + /// the entire process. + /// + public class KOSNomenclature + { + private static HashSet seenAssemblies = new HashSet(); + private static Dictionary kosToCSharpMap = new Dictionary(StringComparer.OrdinalIgnoreCase); + private static Dictionary cSharpToKosMap = new Dictionary(); + + private static string NagHeader = + "***********************************************\n" + + "* The following C# types need a KOS name *\n" + + "* mapping defined in the C# code by use of a *\n" + + "* KOSNomenclatureAttribute. If you see this *\n" + + "* message it means a KOS developer added a *\n" + + "* new type without finishing the job. *\n" + + "* If you _ARE_ a kOS developer and see this *\n" + + "* message after you've just added a new class *\n" + + "* then you need to fix this. *\n" + + "***********************************************\n"; + + // Neither public nor private because a static constructore can't be called explicitly anyway. + static KOSNomenclature() + { + } + + public static void PopulateMapping(params Assembly[] assemblies) + { + foreach (Assembly a in assemblies) + { + // Ensure an Assembly is never run through this twice in the life of the program: + if (seenAssemblies.Contains(a)) + continue; + + PopulateOneAssemblyMapping(a); + seenAssemblies.Add(a); + } + } + + private static void PopulateOneAssemblyMapping(Assembly assembly) + { + // A bit slow, but only executes this once during the life of the program: + IEnumerable allStructureTypes = assembly.GetTypes().Where( t => t.IsSubclassOf(typeof(Structure)) || t == typeof(Structure) ); + + // The nomenclature mapping data is contained in KOSNomenclatureAttributes that are attached to the classes: + foreach (Type t in allStructureTypes) + { + object[] attribs = t.GetCustomAttributes(typeof(KOSNomenclatureAttribute), false); + foreach (object obj in attribs) + { + KOSNomenclatureAttribute attrib = obj as KOSNomenclatureAttribute; + if (attrib == null) + continue; // hypothetically impossible since GetCustomAttributes explicitly asked for only attributes of this type. + + try + { + if (attrib.CSharpToKOS) + cSharpToKosMap.Add(t, attrib.KOSName); + } + catch (ArgumentException) + { + // There can be a many-to-one map (given two different C# types, they both return the same KOS type), but + // not a one-to-many map (given one C# type, it has two kOS types it tries to return). + string msg = "kOS developer error: name clash in KOSNomenclature: two mappings from C# class " + t.FullName + " found."; + Debug.AddNagMessage(Debug.NagType.NAGFOREVER, msg); + } + + try + { + if (attrib.KOSToCSharp) + kosToCSharpMap.Add(attrib.KOSName, t); + } + catch (ArgumentException) + { + // There can be a many-to-one map (given two different kos types, they both return the same C# type), but + // not a one-to-many map (given one kos type, it has two C# types it tries to return). + string msg = "kOS developer error: name clash in KOSNomenclature: two mappings from KOS name " + attrib.KOSName + " found."; + Debug.AddNagMessage(Debug.NagType.NAGFOREVER, msg); + } + } + } + + NagCheck(allStructureTypes); + } + + /// + /// Report nag message on terminal if there is a C# type derived from kOS.Safe.Encapsulated.Structure + /// which was not given a KOSNomenclatureAttribute to work from. All Structure derivatives will need + /// to be given at least one KOS name by being given such an attribute. + /// + private static void NagCheck(IEnumerable checkTypes) + { + StringBuilder message = new StringBuilder(); + + foreach (Type t in checkTypes) + { + if (! cSharpToKosMap.ContainsKey(t)) + { + if (message.Length == 0) + message.Append(NagHeader); + else + message.Append("\n"); + + message.Append("\"" + t.FullName + "\""); + } + } + + if (message.Length > 0) + { + SafeHouse.Logger.Log(message.ToString()); + Debug.AddNagMessage(Debug.NagType.NAGFOREVER, message.ToString()); + } + } + + /// + /// Return the kOS type name corresponding to a C# type. Never bombs out, instead + /// returning the original type's name as-is if it wasn't found in the lookup. This is a + /// case-sensitive lookup because C# type names are case sensitive and there could + /// hypothetically be two different type names that differ by case only. + /// + /// + /// + public static string GetKOSName(Type cSharpType) + { + string kosName; + + if (cSharpToKosMap.TryGetValue(cSharpType,out kosName)) + return kosName; + else + return cSharpType.Name; + } + + /// + /// RReturns true if the cSharp type has a mapping in the table. + /// + /// + /// + public static bool HasKOSName(Type cSharpType) + { + if (cSharpToKosMap.ContainsKey(cSharpType)) + return true; + else + return false; + } + + /// + /// Return the C# type corresponding to a kOS type name. + /// + /// + /// + public static Type GetCSharpName(string kosName) + { + Type cSharpType; + + if (kosToCSharpMap.TryGetValue(kosName,out cSharpType)) + return cSharpType; + else + throw new KOSException("Not a known kos type name: " + kosName); + } + } +} diff --git a/src/kOS.Safe/Utilities/KOSNomenclatureAttribute.cs b/src/kOS.Safe/Utilities/KOSNomenclatureAttribute.cs new file mode 100644 index 000000000..4ec74b23b --- /dev/null +++ b/src/kOS.Safe/Utilities/KOSNomenclatureAttribute.cs @@ -0,0 +1,44 @@ +using System; + +namespace kOS.Safe.Utilities +{ + /// + /// Holds the KOS naming information for a Structure. Used in place of + /// a static name field because you cannot override static fields in C#. + ///
+ /// You are allowed to attach more than one instance of this attribute + /// to a class to declare multiple alias names for it, but only if you + /// set the one way properties such that there isn't a name clash. When + /// going from a CSHarp name to a KOS name there should be exactly 1 such + /// mapping. When going from a kOS name to a CSharp name there can be + /// more than one such mapping. + ///
+ [ + System.AttributeUsage((System.AttributeTargets.Class | + System.AttributeTargets.Struct), + Inherited = false, + AllowMultiple = true) + + ] + public class KOSNomenclatureAttribute : Attribute + { + public string KOSName { get; set;} + + /// + /// Set this to false to cause this to be a one-way mapping only, for aliasing purposes + /// + public bool CSharpToKOS { get; set;} + + /// + /// Set this to false to cause this to be a one-way mapping only, for aliasing purposes + /// + public bool KOSToCSharp { get; set;} + + public KOSNomenclatureAttribute(string kOSName) + { + this.KOSName = kOSName; + CSharpToKOS = true; + KOSToCSharp = true; + } + } +} \ No newline at end of file diff --git a/src/kOS.Safe/Utilities/MovingAverage.cs b/src/kOS.Safe/Utilities/MovingAverage.cs new file mode 100644 index 000000000..fe1ee5822 --- /dev/null +++ b/src/kOS.Safe/Utilities/MovingAverage.cs @@ -0,0 +1,88 @@ +using System.Collections.Generic; + +namespace kOS.Safe.Utilities +{ + public class MovingAverage + { + public List Values { get; set; } + + public double Mean { get; private set; } + + public int ValueCount { get { return Values.Count; } } + + public int SampleLimit { get; set; } + + public MovingAverage() + { + Reset(); + SampleLimit = 30; + } + + public void Reset() + { + Mean = 0; + if (Values == null) Values = new List(); + else Values.Clear(); + } + + public double Update(double value) + { + if (double.IsInfinity(value) || double.IsNaN(value)) return value; + + Values.Add(value); + while (Values.Count > SampleLimit) + { + Values.RemoveAt(0); + } + //if (Values.Count > 5) Mean = Values.OrderBy(e => e).Skip(1).Take(Values.Count - 2).Average(); + //else Mean = Values.Average(); + //Mean = Values.Average(); + double sum = 0; + double count = 0; + double max = double.MinValue; + double min = double.MaxValue; + for (int i = 0; i < Values.Count; i++) + { + double val = Values[i]; + if (val > max) + { + if (max != double.MinValue) + { + sum += max; + count++; + } + max = val; + } + else if (val < min) + { + if (min != double.MaxValue) + { + sum += min; + count++; + } + min = val; + } + else + { + sum += val; + count++; + } + } + if (count == 0) + { + if (max != double.MinValue) + { + sum += max; + count++; + } + if (min != double.MaxValue) + { + sum += min; + count++; + } + } + Mean = sum / count; + return Mean; + } + } +} \ No newline at end of file diff --git a/src/kOS.Safe/Utilities/SafeHouse.cs b/src/kOS.Safe/Utilities/SafeHouse.cs index 697de2502..6cd9223db 100644 --- a/src/kOS.Safe/Utilities/SafeHouse.cs +++ b/src/kOS.Safe/Utilities/SafeHouse.cs @@ -7,12 +7,14 @@ public static class SafeHouse public static IConfig Config { get; private set; } public static bool IsWindows { get; private set; } public static string ArchiveFolder { get; private set; } + public static VersionInfo Version { get; private set; } - public static void Init(IConfig config, bool isWindows, string archiveFolder) + public static void Init(IConfig config, VersionInfo versionInfo, bool isWindows, string archiveFolder) { Config = config; IsWindows = isWindows; ArchiveFolder = archiveFolder; + Version = versionInfo; } public static ILogger Logger { get; set; } diff --git a/src/kOS.Safe/kOS.Safe.csproj b/src/kOS.Safe/kOS.Safe.csproj index a59d26705..4427244d7 100644 --- a/src/kOS.Safe/kOS.Safe.csproj +++ b/src/kOS.Safe/kOS.Safe.csproj @@ -29,7 +29,19 @@ prompt 4 + + true + bin\Shell\ + DEBUG;TRACE + full + AnyCPU + prompt + MinimumRecommendedRules.ruleset + + + ..\..\Resources\GameData\kOS\Plugins\ICSharpCode.SharpZipLib.dll + @@ -41,14 +53,21 @@ + + + + + + + @@ -62,23 +81,35 @@ + + + + - + + + + + + + + + @@ -88,18 +119,27 @@ + + + + + + + + - + + - + @@ -112,18 +152,25 @@ + + + + + + + + - @@ -134,9 +181,9 @@ + - @@ -156,19 +203,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + @@ -178,6 +250,16 @@ + + + cp "$(TargetPath)" "$(SolutionDir)/../Resources/GameData/kOS/Plugins" + (test -h "$(SolutionDir)/../KSPdirlink" && cp "$(TargetPath)" "$(SolutionDir)/../KSPdirlink/GameData/kOS/Plugins") || true + + + xcopy "$(TargetPath)" "$(SolutionDir)\..\Resources\GameData\kOS\Plugins" /y + IF EXIST "$(SolutionDir)\..\KSPdirlink\" xcopy "$(TargetPath)" "$(SolutionDir)\..\KSPdirlink\GameData\kOS\Plugins" /y || exit /B 0 + + + \ No newline at end of file diff --git a/src/kOS.Safe/packages.config b/src/kOS.Safe/packages.config new file mode 100644 index 000000000..471dd20c2 --- /dev/null +++ b/src/kOS.Safe/packages.config @@ -0,0 +1,4 @@ + + + + diff --git a/src/kOS.sln b/src/kOS.sln index b84eeabf7..19ce9d9d9 100644 --- a/src/kOS.sln +++ b/src/kOS.sln @@ -2,7 +2,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 2012 # SharpDevelop 4.4 -VisualStudioVersion = 12.0.31101.0 +VisualStudioVersion = 14.0.23107.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "kOS", "kOS\kOS.csproj", "{465EC87D-723D-4A6C-B116-9777AC641DE3}" EndProject @@ -13,42 +13,34 @@ EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU - Debug|Mixed Platforms = Debug|Mixed Platforms - Debug|x86 = Debug|x86 Release|Any CPU = Release|Any CPU - Release|Mixed Platforms = Release|Mixed Platforms - Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {465EC87D-723D-4A6C-B116-9777AC641DE3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {465EC87D-723D-4A6C-B116-9777AC641DE3}.Debug|Any CPU.Build.0 = Debug|Any CPU - {465EC87D-723D-4A6C-B116-9777AC641DE3}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {465EC87D-723D-4A6C-B116-9777AC641DE3}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {465EC87D-723D-4A6C-B116-9777AC641DE3}.Debug|x86.ActiveCfg = Debug|Any CPU {465EC87D-723D-4A6C-B116-9777AC641DE3}.Release|Any CPU.ActiveCfg = Release|Any CPU {465EC87D-723D-4A6C-B116-9777AC641DE3}.Release|Any CPU.Build.0 = Release|Any CPU - {465EC87D-723D-4A6C-B116-9777AC641DE3}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {465EC87D-723D-4A6C-B116-9777AC641DE3}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {465EC87D-723D-4A6C-B116-9777AC641DE3}.Release|x86.ActiveCfg = Release|Any CPU {590FFDA8-7B44-4BC3-A12A-5FFE2BB7D8FD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {590FFDA8-7B44-4BC3-A12A-5FFE2BB7D8FD}.Debug|Any CPU.Build.0 = Debug|Any CPU - {590FFDA8-7B44-4BC3-A12A-5FFE2BB7D8FD}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {590FFDA8-7B44-4BC3-A12A-5FFE2BB7D8FD}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {590FFDA8-7B44-4BC3-A12A-5FFE2BB7D8FD}.Debug|x86.ActiveCfg = Debug|Any CPU {590FFDA8-7B44-4BC3-A12A-5FFE2BB7D8FD}.Release|Any CPU.ActiveCfg = Release|Any CPU {590FFDA8-7B44-4BC3-A12A-5FFE2BB7D8FD}.Release|Any CPU.Build.0 = Release|Any CPU - {590FFDA8-7B44-4BC3-A12A-5FFE2BB7D8FD}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {590FFDA8-7B44-4BC3-A12A-5FFE2BB7D8FD}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {590FFDA8-7B44-4BC3-A12A-5FFE2BB7D8FD}.Release|x86.ActiveCfg = Release|Any CPU {C9A42A44-DDC8-4D6C-8A16-D7F30F494B46}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {C9A42A44-DDC8-4D6C-8A16-D7F30F494B46}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C9A42A44-DDC8-4D6C-8A16-D7F30F494B46}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {C9A42A44-DDC8-4D6C-8A16-D7F30F494B46}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {C9A42A44-DDC8-4D6C-8A16-D7F30F494B46}.Debug|x86.ActiveCfg = Debug|Any CPU {C9A42A44-DDC8-4D6C-8A16-D7F30F494B46}.Release|Any CPU.ActiveCfg = Release|Any CPU {C9A42A44-DDC8-4D6C-8A16-D7F30F494B46}.Release|Any CPU.Build.0 = Release|Any CPU - {C9A42A44-DDC8-4D6C-8A16-D7F30F494B46}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {C9A42A44-DDC8-4D6C-8A16-D7F30F494B46}.Release|x86.ActiveCfg = Release|Any CPU + EndGlobalSection + GlobalSection(MonoDevelopProperties) = preSolution + Policies = $0 + $0.TextStylePolicy = $1 + $1.FileWidth = 120 + $1.inheritsSet = VisualStudio + $1.inheritsScope = text/plain + $1.scope = text/x-csharp + $0.CSharpFormattingPolicy = $2 + $2.AfterDelegateDeclarationParameterComma = True + $2.inheritsSet = Mono + $2.inheritsScope = text/x-csharp + $2.scope = text/x-csharp EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/kOS/AddOns/ActionGroupsExtended/Addon.cs b/src/kOS/AddOns/ActionGroupsExtended/Addon.cs index f91da9ae7..ea4178bcb 100644 --- a/src/kOS/AddOns/ActionGroupsExtended/Addon.cs +++ b/src/kOS/AddOns/ActionGroupsExtended/Addon.cs @@ -1,25 +1,23 @@ -using kOS.Safe.Encapsulation; -using kOS.Safe.Encapsulation.Suffixes; -using kOS.Suffixed; -using System; - -namespace kOS.AddOns.ActionGroupsExtended -{ - public class Addon : kOS.Suffixed.Addon - { - public Addon(SharedObjects shared) : base ("AGX", shared) - { - InitializeSuffixes(); - } - - private void InitializeSuffixes() - { - //AddSuffix("DELAY", new OneArgsSuffix(RTGetDelay, "Get current Shortest Signal Delay for Vessel")); - } - - public override bool Available() - { - return ActionGroupsExtendedAPI.Instance.Installed (); - } - } +using kOS.Safe.Encapsulation; + +namespace kOS.AddOns.ActionGroupsExtended +{ + [kOS.Safe.Utilities.KOSNomenclature("AGXAddon")] + public class Addon : Suffixed.Addon + { + public Addon(SharedObjects shared) : base ("AGX", shared) + { + InitializeSuffixes(); + } + + private void InitializeSuffixes() + { + //AddSuffix("DELAY", new OneArgsSuffix(RTGetDelay, "Get current Shortest Signal Delay for Vessel")); + } + + public override BooleanValue Available() + { + return ActionGroupsExtendedAPI.Instance.Installed (); + } + } } \ No newline at end of file diff --git a/src/kOS/AddOns/InfernalRobotics/Addon.cs b/src/kOS/AddOns/InfernalRobotics/Addon.cs index 5103a570d..6f216d983 100644 --- a/src/kOS/AddOns/InfernalRobotics/Addon.cs +++ b/src/kOS/AddOns/InfernalRobotics/Addon.cs @@ -1,85 +1,87 @@ -using kOS.Safe.Encapsulation; -using kOS.Safe.Encapsulation.Suffixes; -using kOS.Safe.Exceptions; - -namespace kOS.AddOns.InfernalRobotics -{ - public class Addon : Suffixed.Addon - { - public Addon(SharedObjects shared) : base ("IR", shared) - { - InitializeSuffixes(); - } - - private void InitializeSuffixes() - { - AddSuffix("GROUPS", new Suffix(GetServoGroups, "List all ServoGroups")); - AddSuffix("ALLSERVOS", new Suffix(GetAllServos, "List all Servos")); - } - - private ListValue GetServoGroups() - { - var list = new ListValue(); - - if (!IRWrapper.APIReady) - { - throw new KOSUnavailableAddonException("IR:GROUPS", "Infernal Robotics"); - } - - var controlGroups = IRWrapper.IRController.ServoGroups; - - if (controlGroups == null) - { - //Control Groups are somehow null, just return the empty list - return list; - } - - foreach (IRWrapper.IControlGroup cg in controlGroups) - { - list.Add(new IRControlGroupWrapper(cg, shared)); - } - - - return list; - } - - private ListValue GetAllServos() - { - var list = new ListValue(); - - if (!IRWrapper.APIReady) - { - throw new KOSUnavailableAddonException("IR:ALLSERVOS", "Infernal Robotics"); - } - - var controlGroups = IRWrapper.IRController.ServoGroups; - - if (controlGroups == null) - { - //Control Groups are somehow null, just return the empty list - return list; - } - - foreach (IRWrapper.IControlGroup cg in controlGroups) - { - if (cg.Servos == null) - continue; - - foreach (IRWrapper.IServo s in cg.Servos) - { - list.Add (new IRServoWrapper (s, shared)); - } - } - - - return list; - } - - public override bool Available() - { - return IRWrapper.APIReady; - } - - } -} - +using kOS.Safe.Encapsulation; +using kOS.Safe.Encapsulation.Suffixes; +using kOS.Safe.Exceptions; + +namespace kOS.AddOns.InfernalRobotics +{ + [kOS.Safe.Utilities.KOSNomenclature("IRAddon")] + public class Addon : Suffixed.Addon + { + public Addon(SharedObjects shared) : base ("IR", shared) + { + InitializeSuffixes(); + } + + private void InitializeSuffixes() + { + AddSuffix("GROUPS", new Suffix(GetServoGroups, "List all ServoGroups")); + AddSuffix("ALLSERVOS", new Suffix(GetAllServos, "List all Servos")); + } + + private ListValue GetServoGroups() + { + var list = new ListValue(); + + if (!IRWrapper.APIReady) + { + throw new KOSUnavailableAddonException("IR:GROUPS", "Infernal Robotics"); + } + + var controlGroups = IRWrapper.IRController.ServoGroups; + + if (controlGroups == null) + { + //Control Groups are somehow null, just return the empty list + return list; + } + + foreach (IRWrapper.IControlGroup cg in controlGroups) + { + if (cg.Vessel == null || cg.Vessel == shared.Vessel) + list.Add(new IRControlGroupWrapper(cg, shared)); + } + + + return list; + } + + private ListValue GetAllServos() + { + var list = new ListValue(); + + if (!IRWrapper.APIReady) + { + throw new KOSUnavailableAddonException("IR:ALLSERVOS", "Infernal Robotics"); + } + + var controlGroups = IRWrapper.IRController.ServoGroups; + + if (controlGroups == null) + { + //Control Groups are somehow null, just return the empty list + return list; + } + + foreach (IRWrapper.IControlGroup cg in controlGroups) + { + if (cg.Servos == null || (cg.Vessel!=null && cg.Vessel != shared.Vessel)) + continue; + + foreach (IRWrapper.IServo s in cg.Servos) + { + list.Add (new IRServoWrapper (s, shared)); + } + } + + + return list; + } + + public override BooleanValue Available() + { + return IRWrapper.APIReady; + } + + } +} + diff --git a/src/kOS/AddOns/InfernalRobotics/IRControlGroup.cs b/src/kOS/AddOns/InfernalRobotics/IRControlGroup.cs index 747876ade..84e6a5b8f 100644 --- a/src/kOS/AddOns/InfernalRobotics/IRControlGroup.cs +++ b/src/kOS/AddOns/InfernalRobotics/IRControlGroup.cs @@ -1,14 +1,11 @@ using kOS.Safe.Encapsulation; using kOS.Safe.Encapsulation.Suffixes; -using kOS.Safe.Utilities; using kOS.Suffixed; -using System; using System.Collections.Generic; -using System.Linq; -using kOS.AddOns.InfernalRobotics; namespace kOS.AddOns.InfernalRobotics { + [kOS.Safe.Utilities.KOSNomenclature("IRControlGroup")] public class IRControlGroupWrapper : Structure { private readonly IRWrapper.IControlGroup cg; @@ -23,20 +20,22 @@ public IRControlGroupWrapper(IRWrapper.IControlGroup init, SharedObjects shared) private void InitializeSuffixes() { - AddSuffix("NAME", new SetSuffix(() => cg.Name, value => cg.Name = value)); - AddSuffix("SPEED", new SetSuffix(() => cg.Speed, value => cg.Speed = value)); - AddSuffix("EXPANDED", new SetSuffix(() => cg.Expanded, value => cg.Expanded = value)); - AddSuffix("FORWARDKEY", new SetSuffix(() => cg.ForwardKey, value => cg.ForwardKey = value)); - AddSuffix("REVERSEKEY", new SetSuffix(() => cg.ReverseKey, value => cg.ReverseKey = value)); + AddSuffix("NAME", new SetSuffix(() => cg.Name, value => cg.Name = value)); + AddSuffix("SPEED", new SetSuffix(() => cg.Speed, value => cg.Speed = value)); + AddSuffix("EXPANDED", new SetSuffix(() => cg.Expanded, value => cg.Expanded = value)); + AddSuffix("FORWARDKEY", new SetSuffix(() => cg.ForwardKey, value => cg.ForwardKey = value)); + AddSuffix("REVERSEKEY", new SetSuffix(() => cg.ReverseKey, value => cg.ReverseKey = value)); AddSuffix("SERVOS", new NoArgsSuffix (GetServos)); - AddSuffix("MOVERIGHT", new NoArgsSuffix(MoveRight)); - AddSuffix("MOVELEFT", new NoArgsSuffix(MoveLeft)); - AddSuffix("MOVECENTER", new NoArgsSuffix(MoveCenter)); - AddSuffix("MOVENEXTPRESET", new NoArgsSuffix(MoveNextPreset)); - AddSuffix("MOVEPREVPRESET", new NoArgsSuffix(MovePrevPreset)); - AddSuffix("STOP", new NoArgsSuffix(Stop)); + AddSuffix("MOVERIGHT", new NoArgsVoidSuffix(MoveRight)); + AddSuffix("MOVELEFT", new NoArgsVoidSuffix(MoveLeft)); + AddSuffix("MOVECENTER", new NoArgsVoidSuffix(MoveCenter)); + AddSuffix("MOVENEXTPRESET", new NoArgsVoidSuffix(MoveNextPreset)); + AddSuffix("MOVEPREVPRESET", new NoArgsVoidSuffix(MovePrevPreset)); + AddSuffix("STOP", new NoArgsVoidSuffix(Stop)); + + AddSuffix("VESSEL", new Suffix(GetVessel)); } public ListValue GetServos() @@ -54,6 +53,18 @@ public ListValue GetServos() return ListValue.CreateList(list); } + public VesselTarget GetVessel() + { + if (IRWrapper.APIReady) + { + //IF IR version is 0.21.4 or below IR API may return null, but it also means that IR API only returns groups for ActiveVessel + //so returning the ActiveVessel should work + return cg.Vessel != null ? new VesselTarget (cg.Vessel, shared) : new VesselTarget(FlightGlobals.ActiveVessel, shared); + } + else + return new VesselTarget(shared.Vessel, shared); //user should not be able to get here anyway, but to avoid null will return shared.Vessel + } + public void MoveRight() { cg.MoveRight(); diff --git a/src/kOS/AddOns/InfernalRobotics/IRHandler.cs b/src/kOS/AddOns/InfernalRobotics/IRHandler.cs index 09eae83b1..9e6646c7e 100644 --- a/src/kOS/AddOns/InfernalRobotics/IRHandler.cs +++ b/src/kOS/AddOns/InfernalRobotics/IRHandler.cs @@ -1,25 +1,63 @@ using UnityEngine; -using Debug = UnityEngine.Debug; namespace kOS.AddOns.InfernalRobotics { - [KSPAddon(KSPAddon.Startup.EveryScene, false)] + [KSPAddon(KSPAddon.Startup.Flight, false)] public class IRHandler : MonoBehaviour { + private bool initPending = true; + + private void Awake() + { + GameEvents.onVesselChange.Add(OnVesselChange); + GameEvents.onVesselWasModified.Add(OnVesselWasModified); + GameEvents.onVesselLoaded.Add(OnVesselLoaded); + + } public void Start() { - IRWrapper.InitWrapper(); - if (IRWrapper.APIReady) + initPending = true; + } + + public void FixedUpdate() + { + //due to dll order incositency had to move initialization into FixedUpdate + if(initPending) { - + //if the scene was loaded on non-IR Vessel and then IR vessel became focused we might need to re-init the API + IRWrapper.InitWrapper(); + + UnityEngine.Debug.Log ("KOS-IR: FixedUpdate reinit: " + IRWrapper.APIReady); + + initPending = false; } } - public void OnDestroy() + private void OnVesselChange(Vessel v) { - if (IRWrapper.APIReady) + //if the scene was loaded on non-IR Vessel and then IR vessel became focused we might need to re-init the API + initPending = true; + } + + private void OnVesselLoaded(Vessel v) + { + initPending = true; + } + + private void OnVesselWasModified(Vessel v) + { + //in case some IR capable vessel docked with this one, we might need to re-init the IR API + if (v == FlightGlobals.ActiveVessel) { + OnVesselChange(v); } } + + public void OnDestroy() + { + GameEvents.onVesselChange.Remove(OnVesselChange); + GameEvents.onVesselWasModified.Remove(OnVesselWasModified); + GameEvents.onVesselLoaded.Remove(OnVesselLoaded); + } } } \ No newline at end of file diff --git a/src/kOS/AddOns/InfernalRobotics/IRServoWrapper.cs b/src/kOS/AddOns/InfernalRobotics/IRServoWrapper.cs index c0e22078f..d30f76431 100644 --- a/src/kOS/AddOns/InfernalRobotics/IRServoWrapper.cs +++ b/src/kOS/AddOns/InfernalRobotics/IRServoWrapper.cs @@ -1,12 +1,10 @@ using kOS.Safe.Encapsulation; using kOS.Safe.Encapsulation.Suffixes; -using kOS.Safe.Utilities; -using kOS.Suffixed; -using System; -using System.Linq; +using kOS.Suffixed.Part; namespace kOS.AddOns.InfernalRobotics { + [kOS.Safe.Utilities.KOSNomenclature("IRServo")] public class IRServoWrapper : Structure { private readonly IRWrapper.IServo servo; @@ -21,28 +19,35 @@ public IRServoWrapper(IRWrapper.IServo init, SharedObjects shared) private void InitializeSuffixes() { - AddSuffix("NAME", new SetSuffix(() => servo.Name, value => servo.Name = value)); - AddSuffix("UID", new Suffix(() => servo.UID)); - AddSuffix("HIGHLIGHT", new SetSuffix(() => true, value => servo.Highlight = value)); - - AddSuffix("POSITION", new Suffix(() => servo.Position)); - AddSuffix("MINCFGPOSITION", new Suffix(() => servo.MinConfigPosition)); - AddSuffix("MAXCFGPOSITION", new Suffix(() => servo.MaxConfigPosition)); - AddSuffix("MINPOSITION", new SetSuffix(() => servo.MinPosition, value => servo.MinPosition = value)); - AddSuffix("MAXPOSITION", new SetSuffix(() => servo.MaxPosition, value => servo.MaxPosition = value)); - AddSuffix("CONFIGSPEED", new Suffix(() => servo.ConfigSpeed)); - AddSuffix("CURRENTSPEED", new SetSuffix(() => servo.CurrentSpeed, value => servo.CurrentSpeed = value)); - AddSuffix("SPEED", new SetSuffix(() => servo.Speed, value => servo.Speed = value)); - AddSuffix("ACCELERATION", new SetSuffix(() => servo.Acceleration, value => servo.Acceleration = value)); - - AddSuffix("MOVERIGHT", new NoArgsSuffix(MoveRight)); - AddSuffix("MOVELEFT", new NoArgsSuffix(MoveLeft)); - AddSuffix("MOVECENTER", new NoArgsSuffix(MoveCenter)); - AddSuffix("MOVENEXTPRESET", new NoArgsSuffix(MoveNextPreset)); - AddSuffix("MOVEPREVPRESET", new NoArgsSuffix(MovePrevPreset)); - AddSuffix("STOP", new NoArgsSuffix(Stop)); - - AddSuffix("MOVETO", new TwoArgsSuffix(MoveTo)); + AddSuffix("NAME", new SetSuffix(() => servo.Name, value => servo.Name = value)); + AddSuffix("UID", new Suffix(() => ScalarValue.Create((int)servo.UID))); + AddSuffix("HIGHLIGHT", new SetSuffix(() => true, value => servo.Highlight = value)); + + AddSuffix("POSITION", new Suffix(() => servo.Position)); + AddSuffix("MINCFGPOSITION", new Suffix(() => servo.MinConfigPosition)); + AddSuffix("MAXCFGPOSITION", new Suffix(() => servo.MaxConfigPosition)); + AddSuffix("MINPOSITION", new SetSuffix(() => servo.MinPosition, value => servo.MinPosition = value)); + AddSuffix("MAXPOSITION", new SetSuffix(() => servo.MaxPosition, value => servo.MaxPosition = value)); + AddSuffix("CONFIGSPEED", new Suffix(() => servo.ConfigSpeed)); + AddSuffix("CURRENTSPEED", new SetSuffix(() => servo.CurrentSpeed, value => servo.CurrentSpeed = value)); + AddSuffix("SPEED", new SetSuffix(() => servo.Speed, value => servo.Speed = value)); + AddSuffix("ACCELERATION", new SetSuffix(() => servo.Acceleration, value => servo.Acceleration = value)); + + AddSuffix("ISMOVING", new Suffix(() => servo.IsMoving)); + AddSuffix("ISFREEMOVING", new Suffix(() => servo.IsFreeMoving)); + AddSuffix("LOCKED", new SetSuffix(() => servo.IsLocked, value => servo.IsLocked = value)); + AddSuffix("INVERTED", new SetSuffix(() => servo.IsAxisInverted, value => servo.IsAxisInverted = value)); + + AddSuffix("MOVERIGHT", new NoArgsVoidSuffix(MoveRight)); + AddSuffix("MOVELEFT", new NoArgsVoidSuffix(MoveLeft)); + AddSuffix("MOVECENTER", new NoArgsVoidSuffix(MoveCenter)); + AddSuffix("MOVENEXTPRESET", new NoArgsVoidSuffix(MoveNextPreset)); + AddSuffix("MOVEPREVPRESET", new NoArgsVoidSuffix(MovePrevPreset)); + AddSuffix("STOP", new NoArgsVoidSuffix(Stop)); + + AddSuffix("MOVETO", new TwoArgsSuffix(MoveTo)); + + AddSuffix("PART", new Suffix(GetPart)); } @@ -76,9 +81,19 @@ public void Stop() servo.Stop(); } - public void MoveTo(float position, float speed) + public void MoveTo(ScalarValue position, ScalarValue speed) { servo.MoveTo(position, speed); } + + public PartValue GetPart() + { + var v = shared.Vessel; + + var p = v.Parts.Find (s => s.craftID == servo.UID); + shared.Logger.LogError("Cannot find Infernal Robotics part with UID: " + servo.UID); + + return p != null ? new PartValue (p, shared) : null; + } } } \ No newline at end of file diff --git a/src/kOS/AddOns/InfernalRobotics/IRWrapper.cs b/src/kOS/AddOns/InfernalRobotics/IRWrapper.cs index 457d99cf7..fcc598a6d 100644 --- a/src/kOS/AddOns/InfernalRobotics/IRWrapper.cs +++ b/src/kOS/AddOns/InfernalRobotics/IRWrapper.cs @@ -4,7 +4,6 @@ using System.Linq; using System.Reflection; -// TODO: Change this namespace to something specific to your plugin here. namespace kOS.AddOns.InfernalRobotics { public class IRWrapper @@ -43,9 +42,9 @@ internal static bool InitWrapper() LogFormatted("IR Version:{0}", IRServoControllerType.Assembly.GetName().Version.ToString()); IRServoMechanismType = AssemblyLoader.loadedAssemblies - .Select(a => a.assembly.GetExportedTypes()) - .SelectMany(t => t) - .FirstOrDefault(t => t.FullName == "InfernalRobotics.Control.IMechanism"); + .Select(a => a.assembly.GetExportedTypes()) + .SelectMany(t => t) + .FirstOrDefault(t => t.FullName == "InfernalRobotics.Control.IMechanism"); if (IRServoMechanismType == null) { @@ -120,7 +119,7 @@ internal static bool InitWrapper() } LogFormatted("Got Instance, Creating Wrapper Objects"); - IRController = new InfernalRoboticsAPI(ActualServoController); + IRController = new InfernalRoboticsAPI(); isWrapped = true; return true; } @@ -132,22 +131,24 @@ private class InfernalRoboticsAPI : IRAPI private PropertyInfo apiReady; private object actualServoGroups; - public InfernalRoboticsAPI(object irServoController) + public InfernalRoboticsAPI() { DetermineReady(); - BuildServoGroups(irServoController); + BuildServoGroups(); } - private void BuildServoGroups(object irServoController) + private void BuildServoGroups() { - LogFormatted("Getting ServoGroups Object"); var servoGroupsField = IRServoControllerType.GetField("ServoGroups"); if (servoGroupsField == null) LogFormatted("Failed Getting ServoGroups fieldinfo"); + else if (IRWrapper.ActualServoController == null) + { + LogFormatted("ServoController Instance not found"); + } else { - actualServoGroups = servoGroupsField.GetValue(irServoController); - LogFormatted("Success: " + (actualServoGroups != null)); + actualServoGroups = servoGroupsField.GetValue(IRWrapper.ActualServoController); } } @@ -162,7 +163,7 @@ public bool Ready { get { - if (apiReady == null) + if (apiReady == null || actualServoGroups == null) return false; return (bool)apiReady.GetValue(null, null); @@ -173,6 +174,7 @@ public IList ServoGroups { get { + BuildServoGroups (); return ExtractServoGroups(actualServoGroups); } } @@ -205,6 +207,7 @@ private class IRControlGroup : IControlGroup private readonly object actualControlGroup; private PropertyInfo nameProperty; + private PropertyInfo vesselProperty; private PropertyInfo forwardKeyProperty; private PropertyInfo expandedProperty; private PropertyInfo speedProperty; @@ -227,6 +230,7 @@ public IRControlGroup(object cg) private void FindProperties() { nameProperty = IRControlGroupType.GetProperty("Name"); + vesselProperty = IRControlGroupType.GetProperty("Vessel"); forwardKeyProperty = IRControlGroupType.GetProperty("ForwardKey"); reverseKeyProperty = IRControlGroupType.GetProperty("ReverseKey"); speedProperty = IRControlGroupType.GetProperty("Speed"); @@ -252,6 +256,11 @@ public string Name set { nameProperty.SetValue(actualControlGroup, value, null); } } + public Vessel Vessel + { + get { return vesselProperty != null ? (Vessel)vesselProperty.GetValue(actualControlGroup, null) : null; } + } + public string ForwardKey { get { return (string)forwardKeyProperty.GetValue(actualControlGroup, null); } @@ -319,8 +328,8 @@ public void Stop() private IList ExtractServos(object actualServos) { var listToReturn = new List(); - - if (actualServos == null) + + if(actualServos == null) return listToReturn; try @@ -422,10 +431,6 @@ private void FindMethods() private readonly object actualServo; - public uint UID - { - get { return (uint)UIDProperty.GetValue(actualServo, null); } - } public string Name { @@ -433,6 +438,11 @@ public string Name set { nameProperty.SetValue(actualServo, value, null); } } + public uint UID + { + get { return (uint)UIDProperty.GetValue(actualServo, null); } + } + public bool Highlight { //get { return (bool)HighlightProperty.GetValue(actualServo, null); } @@ -594,6 +604,9 @@ public interface IControlGroup : IEquatable { string Name { get; set; } + //can only be used in Flight, null checking is mandatory + Vessel Vessel { get; } + string ForwardKey { get; set; } string ReverseKey { get; set; } @@ -619,10 +632,10 @@ public interface IControlGroup : IEquatable public interface IServo : IEquatable { - uint UID { get; } - string Name { get; set; } + uint UID { get; } + bool Highlight { set; } float Position { get; } diff --git a/src/kOS/AddOns/KerbalAlarmClock/Addon.cs b/src/kOS/AddOns/KerbalAlarmClock/Addon.cs index 1b7b8d80c..c16e37321 100644 --- a/src/kOS/AddOns/KerbalAlarmClock/Addon.cs +++ b/src/kOS/AddOns/KerbalAlarmClock/Addon.cs @@ -1,43 +1,44 @@ -using kOS.Safe.Encapsulation; -using kOS.Safe.Encapsulation.Suffixes; - -namespace kOS.AddOns.KerbalAlarmClock -{ - public class Addon : Suffixed.Addon - { - public Addon(SharedObjects shared) : base ("KAC", shared) - { - InitializeSuffixes(); - } - - private void InitializeSuffixes() - { - AddSuffix("ALARMS", new Suffix(GetAlarms, "List all alarms")); - } - - private ListValue GetAlarms() - { - var list = new ListValue(); - - if (!KACWrapper.APIReady) - { - return list; - } - - //Get the list of alarms from the KAC Object - KACWrapper.KACAPI.KACAlarmList alarms = KACWrapper.KAC.Alarms; - - foreach (KACWrapper.KACAPI.KACAlarm alarm in alarms) - { - list.Add(new KACAlarmWrapper(alarm)); - } - return list; - } - - public override bool Available() - { - return KACWrapper.APIReady; - } - - } +using kOS.Safe.Encapsulation; +using kOS.Safe.Encapsulation.Suffixes; + +namespace kOS.AddOns.KerbalAlarmClock +{ + [kOS.Safe.Utilities.KOSNomenclature("KACAddon")] + public class Addon : Suffixed.Addon + { + public Addon(SharedObjects shared) : base ("KAC", shared) + { + InitializeSuffixes(); + } + + private void InitializeSuffixes() + { + AddSuffix("ALARMS", new Suffix(GetAlarms, "List all alarms")); + } + + private ListValue GetAlarms() + { + var list = new ListValue(); + + if (!KACWrapper.APIReady) + { + return list; + } + + //Get the list of alarms from the KAC Object + KACWrapper.KACAPI.KACAlarmList alarms = KACWrapper.KAC.Alarms; + + foreach (KACWrapper.KACAPI.KACAlarm alarm in alarms) + { + list.Add(new KACAlarmWrapper(alarm)); + } + return list; + } + + public override BooleanValue Available() + { + return KACWrapper.APIReady; + } + + } } \ No newline at end of file diff --git a/src/kOS/AddOns/KerbalAlarmClock/KACAlarmWrapper.cs b/src/kOS/AddOns/KerbalAlarmClock/KACAlarmWrapper.cs index 6ea2fb82a..5b3677efd 100644 --- a/src/kOS/AddOns/KerbalAlarmClock/KACAlarmWrapper.cs +++ b/src/kOS/AddOns/KerbalAlarmClock/KACAlarmWrapper.cs @@ -1,74 +1,75 @@ -using kOS.Safe.Encapsulation; -using kOS.Safe.Encapsulation.Suffixes; -using kOS.Safe.Utilities; -using System; -using System.Linq; - -namespace kOS.AddOns.KerbalAlarmClock -{ - public class KACAlarmWrapper : Structure - { - private readonly KACWrapper.KACAPI.KACAlarm alarm; - - public KACAlarmWrapper(KACWrapper.KACAPI.KACAlarm init) - { - alarm = init; - InitializeSuffixes(); - } - - public KACAlarmWrapper(String alarmID) - { - alarm = KACWrapper.KAC.Alarms.First(z => z.ID == alarmID); - InitializeSuffixes(); - } - - private void InitializeSuffixes() - { - AddSuffix("ID", new Suffix(() => alarm.ID)); - AddSuffix("NAME", new SetSuffix(() => alarm.Name, value => alarm.Name = value)); - - AddSuffix("NOTES", new SetSuffix(() => alarm.Name, value => alarm.Name = value)); - - AddSuffix("ACTION", new SetSuffix(GetAlarmAction, SetAlarmAction)); - - AddSuffix("TYPE", new Suffix(alarm.AlarmType.ToString)); - - AddSuffix("REMAINING", new Suffix(GetTimeToAlarm)); - - AddSuffix("TIME", new SetSuffix(() => alarm.AlarmTime, value => alarm.AlarmTime = value)); - AddSuffix("MARGIN", new SetSuffix(() => alarm.AlarmMargin, value => alarm.AlarmMargin = value)); - - AddSuffix("REPEAT", new SetSuffix(() => alarm.RepeatAlarm, value => alarm.RepeatAlarm = value)); - - AddSuffix("REPEATPERIOD", new SetSuffix(() => alarm.RepeatAlarmPeriod, value => alarm.RepeatAlarmPeriod = value)); - - AddSuffix("ORIGINBODY", new SetSuffix(() => alarm.XferOriginBodyName, value => alarm.XferOriginBodyName = value)); - AddSuffix("TARGETBODY", new SetSuffix(() => alarm.XferTargetBodyName, value => alarm.XferTargetBodyName = value)); - } - - private double GetTimeToAlarm() - { - //workaround for alarm.Remaining type mismatch - return alarm.AlarmTime - Planetarium.GetUniversalTime(); - } - - private string GetAlarmAction() - { - //For some reason had to do it this way, otherwise ACTION suffix returned incorrect values - return alarm.AlarmAction.ToString(); - } - - private void SetAlarmAction(string newAlarmAction) - { - try - { - var result = (KACWrapper.KACAPI.AlarmActionEnum)Enum.Parse(typeof(KACWrapper.KACAPI.AlarmActionEnum), newAlarmAction); - alarm.AlarmAction = result; - } - catch (ArgumentException) - { - SafeHouse.Logger.LogWarning(string.Format("Failed parsing {0} into KACAPI.AlarmActionEnum", newAlarmAction)); - } - } - } +using kOS.Safe.Encapsulation; +using kOS.Safe.Encapsulation.Suffixes; +using kOS.Safe.Utilities; +using System; +using System.Linq; + +namespace kOS.AddOns.KerbalAlarmClock +{ + [kOS.Safe.Utilities.KOSNomenclature("KACAlarm")] + public class KACAlarmWrapper : Structure + { + private readonly KACWrapper.KACAPI.KACAlarm alarm; + + public KACAlarmWrapper(KACWrapper.KACAPI.KACAlarm init) + { + alarm = init; + InitializeSuffixes(); + } + + public KACAlarmWrapper(string alarmID) + { + alarm = KACWrapper.KAC.Alarms.First(z => z.ID == alarmID); + InitializeSuffixes(); + } + + private void InitializeSuffixes() + { + AddSuffix("ID", new Suffix(() => alarm.ID)); + AddSuffix("NAME", new SetSuffix(() => alarm.Name, value => alarm.Name = value)); + + AddSuffix("NOTES", new SetSuffix(() => alarm.Name, value => alarm.Name = value)); + + AddSuffix("ACTION", new SetSuffix(GetAlarmAction, SetAlarmAction)); + + AddSuffix("TYPE", new Suffix(() => alarm.AlarmType.ToString())); + + AddSuffix("REMAINING", new Suffix(GetTimeToAlarm)); + + AddSuffix("TIME", new SetSuffix(() => alarm.AlarmTime, value => alarm.AlarmTime = value)); + AddSuffix("MARGIN", new SetSuffix(() => alarm.AlarmMargin, value => alarm.AlarmMargin = value)); + + AddSuffix("REPEAT", new SetSuffix(() => alarm.RepeatAlarm, value => alarm.RepeatAlarm = value)); + + AddSuffix("REPEATPERIOD", new SetSuffix(() => alarm.RepeatAlarmPeriod, value => alarm.RepeatAlarmPeriod = value)); + + AddSuffix("ORIGINBODY", new SetSuffix(() => alarm.XferOriginBodyName, value => alarm.XferOriginBodyName = value)); + AddSuffix("TARGETBODY", new SetSuffix(() => alarm.XferTargetBodyName, value => alarm.XferTargetBodyName = value)); + } + + private ScalarValue GetTimeToAlarm() + { + //workaround for alarm.Remaining type mismatch + return alarm.AlarmTime - Planetarium.GetUniversalTime(); + } + + private StringValue GetAlarmAction() + { + //For some reason had to do it this way, otherwise ACTION suffix returned incorrect values + return alarm.AlarmAction.ToString(); + } + + private void SetAlarmAction(StringValue newAlarmAction) + { + try + { + var result = (KACWrapper.KACAPI.AlarmActionEnum)Enum.Parse(typeof(KACWrapper.KACAPI.AlarmActionEnum), newAlarmAction); + alarm.AlarmAction = result; + } + catch (ArgumentException) + { + SafeHouse.Logger.LogWarning(string.Format("Failed parsing {0} into KACAPI.AlarmActionEnum", newAlarmAction)); + } + } + } } \ No newline at end of file diff --git a/src/kOS/AddOns/KerbalAlarmClock/KACEventHandler.cs b/src/kOS/AddOns/KerbalAlarmClock/KACEventHandler.cs index 6e5d43f61..7f9e24452 100644 --- a/src/kOS/AddOns/KerbalAlarmClock/KACEventHandler.cs +++ b/src/kOS/AddOns/KerbalAlarmClock/KACEventHandler.cs @@ -1,37 +1,37 @@ -using UnityEngine; -using Debug = UnityEngine.Debug; - -namespace kOS.AddOns.KerbalAlarmClock -{ - [KSPAddon(KSPAddon.Startup.EveryScene, false)] - public class KACEventHandler : MonoBehaviour - { - public void Start() - { - KACWrapper.InitKACWrapper(); - if (KACWrapper.APIReady) - { - //All good to go - //register Event Handler - KACWrapper.KAC.onAlarmStateChanged += KAC_onAlarmStateChanged; - - Debug.Log(string.Format("{0} Kerbal Alarm Clock found, Alarms Count {1}", KSPLogger.LOGGER_PREFIX, KACWrapper.KAC.Alarms.Count)); - } - } - - public void OnDestroy() - { - if (KACWrapper.APIReady) - { - //destroy the event hook - KACWrapper.KAC.onAlarmStateChanged -= KAC_onAlarmStateChanged; - } - } - - private void KAC_onAlarmStateChanged(KACWrapper.KACAPI.AlarmStateChangedEventArgs e) - { - //output whats happened - Debug.Log(string.Format("{0}, caught Event from alarm {1}, event type {2}", KSPLogger.LOGGER_PREFIX, e.alarm.Name, e.eventType)); - } - } +using UnityEngine; +using Debug = UnityEngine.Debug; + +namespace kOS.AddOns.KerbalAlarmClock +{ + [KSPAddon(KSPAddon.Startup.EveryScene, false)] + public class KACEventHandler : MonoBehaviour + { + public void Start() + { + KACWrapper.InitKACWrapper(); + if (KACWrapper.APIReady) + { + //All good to go + //register Event Handler + KACWrapper.KAC.onAlarmStateChanged += KAC_onAlarmStateChanged; + + Debug.Log(string.Format("{0} Kerbal Alarm Clock found, Alarms Count {1}", KSPLogger.LOGGER_PREFIX, KACWrapper.KAC.Alarms.Count)); + } + } + + public void OnDestroy() + { + if (KACWrapper.APIReady) + { + //destroy the event hook + KACWrapper.KAC.onAlarmStateChanged -= KAC_onAlarmStateChanged; + } + } + + private void KAC_onAlarmStateChanged(KACWrapper.KACAPI.AlarmStateChangedEventArgs e) + { + //output whats happened + Debug.Log(string.Format("{0}, caught Event from alarm {1}, event type {2}", KSPLogger.LOGGER_PREFIX, e.alarm.Name, e.eventType)); + } + } } \ No newline at end of file diff --git a/src/kOS/AddOns/KerbalAlarmClock/KACFunctions.cs b/src/kOS/AddOns/KerbalAlarmClock/KACFunctions.cs index 5bb6c3cb4..30e1e6485 100644 --- a/src/kOS/AddOns/KerbalAlarmClock/KACFunctions.cs +++ b/src/kOS/AddOns/KerbalAlarmClock/KACFunctions.cs @@ -53,14 +53,14 @@ public override void Execute(SharedObjects shared) } else { - ReturnValue = string.Empty; + ReturnValue = new StringValue(string.Empty); SafeHouse.Logger.Log(string.Format("Failed creating KAC Alarm, UT={0}, Name={1}, Type= {2}", alarmUT, alarmName, alarmType)); } } else { //KAC integration not present. - ReturnValue = string.Empty; + ReturnValue = new StringValue(string.Empty); throw new KOSUnavailableAddonException("addAlarm()", "Kerbal Alarm Clock"); } } diff --git a/src/kOS/AddOns/OrbitalScience/DMBathymetryFields.cs b/src/kOS/AddOns/OrbitalScience/DMBathymetryFields.cs new file mode 100644 index 000000000..d2ce7e516 --- /dev/null +++ b/src/kOS/AddOns/OrbitalScience/DMBathymetryFields.cs @@ -0,0 +1,41 @@ +using kOS.Safe.Encapsulation.Suffixes; +using System.Reflection; + +namespace kOS.AddOns.OrbitalScience +{ + [kOS.Safe.Utilities.KOSNomenclature("ScienceExperimentModule", KOSToCSharp = false)] + public class DMBathymetryFields : DMModuleScienceAnimateFields + { + public DMBathymetryFields(ModuleScienceExperiment mod, SharedObjects shared) + : base(mod, shared) + { + InitializeSuffixes(); + } + + private void InitializeSuffixes() + { + AddSuffix("LIGHTSON", new NoArgsVoidSuffix(LightsOn, "Turn on the experiment lights")); + AddSuffix("LIGHTSOFF", new NoArgsVoidSuffix(LightsOff, "Turn off the experiment lights")); + } + + protected void LightsOn() + { + ThrowIfNotCPUVessel(); + + var lightsMethod = module.GetType().GetMethod("turnLightsOn", + BindingFlags.Public | BindingFlags.Instance); + + lightsMethod.Invoke(module, new object[] { }); + } + + protected void LightsOff() + { + ThrowIfNotCPUVessel(); + + var lightsMethod = module.GetType().GetMethod("turnLightsOff", + BindingFlags.Public | BindingFlags.Instance); + + lightsMethod.Invoke(module, new object[] { }); + } + } +} \ No newline at end of file diff --git a/src/kOS/AddOns/OrbitalScience/DMModuleScienceAnimateFields.cs b/src/kOS/AddOns/OrbitalScience/DMModuleScienceAnimateFields.cs new file mode 100644 index 000000000..ba24aeae9 --- /dev/null +++ b/src/kOS/AddOns/OrbitalScience/DMModuleScienceAnimateFields.cs @@ -0,0 +1,48 @@ +using kOS.Safe.Encapsulation.Suffixes; +using kOS.Suffixed.PartModuleField; +using System.Reflection; + +namespace kOS.AddOns.OrbitalScience +{ + [kOS.Safe.Utilities.KOSNomenclature("ScienceExperimentModule", KOSToCSharp = false)] + public class DMModuleScienceAnimateFields : StockScienceExperimentFields + { + public DMModuleScienceAnimateFields(ModuleScienceExperiment module, SharedObjects sharedObj) + : base(module, sharedObj) + { + InitializeSuffixes(); + } + + private void InitializeSuffixes() + { + AddSuffix("TOGGLE", new NoArgsVoidSuffix(ToggleExperiment, "Activate/deactivate the experiment")); + } + + public override bool Deployed() + { + var deployedField = module.GetType().GetField("IsDeployed"); + + return (bool)deployedField.GetValue(module); + } + + public void ToggleExperiment() + { + ThrowIfNotCPUVessel(); + + var toggleMethod = module.GetType().GetMethod("toggleEvent", + BindingFlags.Public | BindingFlags.Instance); + + toggleMethod.Invoke(module, new object[] { }); + } + + protected override void Deploy() + { + ThrowIfNotCPUVessel(); + + var gatherDataMethod = module.GetType().GetMethod("gatherScienceData", + BindingFlags.Public | BindingFlags.Instance); + + gatherDataMethod.Invoke(module, new object[] { true }); + } + } +} \ No newline at end of file diff --git a/src/kOS/AddOns/OrbitalScience/DMOrbitalScienceFieldsFactory.cs b/src/kOS/AddOns/OrbitalScience/DMOrbitalScienceFieldsFactory.cs new file mode 100644 index 000000000..3955d0e5c --- /dev/null +++ b/src/kOS/AddOns/OrbitalScience/DMOrbitalScienceFieldsFactory.cs @@ -0,0 +1,33 @@ +using kOS.Suffixed.PartModuleField; + +namespace kOS.AddOns.OrbitalScience +{ + public class DMOrbitalScienceFieldsFactory + { + private const string DMSCIENCEANIMATE = "DMModuleScienceAnimate"; + private const string DMASTEROIDSCANNER = "DMAsteroidScanner"; + private const string DMBATHYMETRY = "DMBathymetry"; + private const string DMBASICSCIENCEMODULE = "DMBasicScienceModule"; + + public static ScienceExperimentFields Construct(PartModule mod, SharedObjects shared) + { + var typeName = mod.GetType().Name; + var baseTypeName = mod.GetType().BaseType.Name; + + if (baseTypeName.Contains(DMBASICSCIENCEMODULE) || typeName.Contains(DMASTEROIDSCANNER)) + { + return new DMScienceExperimentFields(mod, shared); + } + else if (typeName.Contains(DMBATHYMETRY)) + { + return new DMBathymetryFields(mod as ModuleScienceExperiment, shared); + } + else if (typeName.Contains(DMSCIENCEANIMATE) || baseTypeName.Contains(DMSCIENCEANIMATE)) + { + return new DMModuleScienceAnimateFields(mod as ModuleScienceExperiment, shared); + } + + return null; + } + } +} \ No newline at end of file diff --git a/src/kOS/AddOns/OrbitalScience/DMScienceExperimentFields.cs b/src/kOS/AddOns/OrbitalScience/DMScienceExperimentFields.cs new file mode 100644 index 000000000..decf1b335 --- /dev/null +++ b/src/kOS/AddOns/OrbitalScience/DMScienceExperimentFields.cs @@ -0,0 +1,102 @@ +using kOS.Safe.Encapsulation.Suffixes; +using kOS.Safe.Exceptions; +using kOS.Suffixed.PartModuleField; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; + +namespace kOS.AddOns.OrbitalScience +{ + [kOS.Safe.Utilities.KOSNomenclature("ScienceExperimentModule", KOSToCSharp = false)] + public class DMScienceExperimentFields : ScienceExperimentFields + { + public DMScienceExperimentFields(PartModule mod, SharedObjects shared) + : base(mod, shared) + { + InitializeSuffixes(); + } + + private void InitializeSuffixes() + { + AddSuffix("TOGGLE", new NoArgsVoidSuffix(ToggleExperiment, "Activate/deactivate the experiment")); + } + + public void ToggleExperiment() + { + ThrowIfNotCPUVessel(); + + var toggleMethod = partModule.GetType().GetMethod("toggleEvent", + BindingFlags.Public | BindingFlags.Instance); + + toggleMethod.Invoke(partModule, new object[] { }); + } + + public override bool Deployed() + { + var deployedField = partModule.GetType().GetField("IsDeployed"); + + return (bool)deployedField.GetValue(partModule); + } + + public override bool Inoperable() + { + var inoperableField = partModule.GetType().GetField("Inoperable"); + + return (bool)inoperableField.GetValue(partModule); + } + + public override void DeployExperiment() + { + ThrowIfNotCPUVessel(); + + if (HasData()) + { + throw new KOSException("Experiment already contains data"); + } + + if (Inoperable()) + { + throw new KOSException("Experiment is inoperable"); + } + + var gatherDataMethod = partModule.GetType().GetMethod("gatherScienceData", + BindingFlags.Public | BindingFlags.Instance); + + gatherDataMethod.Invoke(partModule, new object[] { true }); + } + + public override void ResetExperiment() + { + ThrowIfNotCPUVessel(); + + if (Inoperable()) + { + throw new KOSException("Experiment is inoperable"); + } + + var gatherDataMethod = partModule.GetType().GetMethod("ResetExperiment", + BindingFlags.Public | BindingFlags.Instance); + + gatherDataMethod.Invoke(partModule, new object[] { }); + } + + public override void TransmitData() + { + ThrowIfNotCPUVessel(); + + IScienceDataContainer container = partModule as IScienceDataContainer; + + ScienceData[] data = container.GetData(); + + List tranList = partModule.vessel.FindPartModulesImplementing(); + if (tranList.Count() > 0 && data.Count() > 0) + { + tranList.OrderBy(ScienceUtil.GetTransmitterScore).First().TransmitData(new List(data)); + + DumpData(); + } + else + ScreenMessages.PostScreenMessage("No transmitters available on this vessel or no data to transmit.", 4f, ScreenMessageStyle.UPPER_LEFT); + } + } +} \ No newline at end of file diff --git a/src/kOS/AddOns/RemoteTech/Addon.cs b/src/kOS/AddOns/RemoteTech/Addon.cs index db123112c..ead718a19 100644 --- a/src/kOS/AddOns/RemoteTech/Addon.cs +++ b/src/kOS/AddOns/RemoteTech/Addon.cs @@ -1,79 +1,95 @@ -using kOS.Safe.Encapsulation.Suffixes; -using kOS.Suffixed; - -namespace kOS.AddOns.RemoteTech -{ - public class Addon : Suffixed.Addon - { - public Addon(SharedObjects shared) : base ("RT", shared) - { - InitializeSuffixes(); - } - - private void InitializeSuffixes() - { - AddSuffix("DELAY", new OneArgsSuffix(RTGetDelay, "Get current Shortest Signal Delay for Vessel")); - - AddSuffix("KSCDELAY", new OneArgsSuffix(RTGetKSCDelay, "Get current KSC Signal Delay")); - - AddSuffix("HASCONNECTION", new OneArgsSuffix(RTHasConnection, "True if ship has any connection")); - - AddSuffix("HASKSCCONNECTION", new OneArgsSuffix(RTHasKSCConnection, "True if ship has connection to KSC")); - - } - - private static double RTGetDelay(VesselTarget tgtVessel) - { - double waitTotal = 0; - - if (RemoteTechHook.IsAvailable(tgtVessel.Vessel.id) && tgtVessel.Vessel.GetVesselCrew().Count == 0) - { - waitTotal = RemoteTechHook.Instance.GetShortestSignalDelay(tgtVessel.Vessel.id); - } - - return waitTotal; - } - - private static double RTGetKSCDelay(VesselTarget tgtVessel) - { - double waitTotal = 0; - - if (RemoteTechHook.IsAvailable(tgtVessel.Vessel.id) && tgtVessel.Vessel.GetVesselCrew().Count == 0) - { - waitTotal = RemoteTechHook.Instance.GetSignalDelayToKSC(tgtVessel.Vessel.id); - } - - return waitTotal; - } - - private static bool RTHasConnection(VesselTarget tgtVessel) - { - bool result = false; - - if (RemoteTechHook.IsAvailable(tgtVessel.Vessel.id)) - { - result = RemoteTechHook.Instance.HasAnyConnection(tgtVessel.Vessel.id); - } - - return result; - } - - private static bool RTHasKSCConnection(VesselTarget tgtVessel) - { - bool result = false; - - if (RemoteTechHook.IsAvailable(tgtVessel.Vessel.id)) - { - result = RemoteTechHook.Instance.HasConnectionToKSC(tgtVessel.Vessel.id); - } - - return result; - } - - public override bool Available() - { - return RemoteTechHook.IsAvailable(); - } - - } +using kOS.Safe.Encapsulation; +using kOS.Safe.Encapsulation.Suffixes; +using kOS.Suffixed; + +namespace kOS.AddOns.RemoteTech +{ + [kOS.Safe.Utilities.KOSNomenclature("RTAddon")] + public class Addon : Suffixed.Addon + { + public Addon(SharedObjects shared) : base ("RT", shared) + { + InitializeSuffixes(); + } + + private void InitializeSuffixes() + { + AddSuffix("DELAY", new OneArgsSuffix(RTGetDelay, "Get current Shortest Signal Delay for Vessel")); + + AddSuffix("KSCDELAY", new OneArgsSuffix(RTGetKSCDelay, "Get current KSC Signal Delay")); + + AddSuffix("HASCONNECTION", new OneArgsSuffix(RTHasConnection, "True if ship has any connection")); + + AddSuffix("HASKSCCONNECTION", new OneArgsSuffix(RTHasKSCConnection, "True if ship has connection to KSC")); + + AddSuffix("HASLOCALCONTROL", new OneArgsSuffix(RTHasLocalControl, "True if ship has locacl control (i.e. a pilot in a command module)")); + + } + + private static ScalarValue RTGetDelay(VesselTarget tgtVessel) + { + double waitTotal = 0; + + if (RemoteTechHook.IsAvailable(tgtVessel.Vessel.id) && tgtVessel.Vessel.GetVesselCrew().Count == 0) + { + waitTotal = RemoteTechHook.Instance.GetShortestSignalDelay(tgtVessel.Vessel.id); + } + + return waitTotal; + } + + private static ScalarValue RTGetKSCDelay(VesselTarget tgtVessel) + { + double waitTotal = 0; + + if (RemoteTechHook.IsAvailable(tgtVessel.Vessel.id) && tgtVessel.Vessel.GetVesselCrew().Count == 0) + { + waitTotal = RemoteTechHook.Instance.GetSignalDelayToKSC(tgtVessel.Vessel.id); + } + + return waitTotal; + } + + private static BooleanValue RTHasConnection(VesselTarget tgtVessel) + { + bool result = false; + + if (RemoteTechHook.IsAvailable(tgtVessel.Vessel.id)) + { + result = RemoteTechHook.Instance.HasAnyConnection(tgtVessel.Vessel.id); + } + + return result; + } + + private static BooleanValue RTHasLocalControl(VesselTarget tgtVessel) + { + bool result = false; + + if (RemoteTechHook.IsAvailable(tgtVessel.Vessel.id)) + { + result = RemoteTechHook.Instance.HasLocalControl(tgtVessel.Vessel.id); + } + + return result; + } + + private static BooleanValue RTHasKSCConnection(VesselTarget tgtVessel) + { + bool result = false; + + if (RemoteTechHook.IsAvailable(tgtVessel.Vessel.id)) + { + result = RemoteTechHook.Instance.HasConnectionToKSC(tgtVessel.Vessel.id); + } + + return result; + } + + public override BooleanValue Available() + { + return RemoteTechHook.IsAvailable(); + } + + } } \ No newline at end of file diff --git a/src/kOS/AddOns/RemoteTech/IRemoteTechAPIv1.cs b/src/kOS/AddOns/RemoteTech/IRemoteTechAPIv1.cs index 3fa475e4c..0e3876a2c 100644 --- a/src/kOS/AddOns/RemoteTech/IRemoteTechAPIv1.cs +++ b/src/kOS/AddOns/RemoteTech/IRemoteTechAPIv1.cs @@ -4,6 +4,7 @@ namespace kOS.AddOns.RemoteTech { public interface IRemoteTechAPIv1 { + Func HasLocalControl { get; } Func HasFlightComputer { get; } Action> AddSanctionedPilot { get; } Action> RemoveSanctionedPilot { get; } @@ -12,5 +13,6 @@ public interface IRemoteTechAPIv1 Func GetShortestSignalDelay { get; } Func GetSignalDelayToKSC { get; } Func GetSignalDelayToSatellite { get; } + Action InvokeOriginalEvent { get; } } } diff --git a/src/kOS/AddOns/RemoteTech/RemoteTechAPI.cs b/src/kOS/AddOns/RemoteTech/RemoteTechAPI.cs index 5e5a7be86..a51554347 100644 --- a/src/kOS/AddOns/RemoteTech/RemoteTechAPI.cs +++ b/src/kOS/AddOns/RemoteTech/RemoteTechAPI.cs @@ -4,6 +4,7 @@ namespace kOS.AddOns.RemoteTech { internal class RemoteTechAPI : IRemoteTechAPIv1 { + public Func HasLocalControl { get; internal set; } public Func HasFlightComputer { get; internal set; } public Action> AddSanctionedPilot { get; internal set; } public Action> RemoveSanctionedPilot { get; internal set; } @@ -12,5 +13,6 @@ internal class RemoteTechAPI : IRemoteTechAPIv1 public Func GetShortestSignalDelay { get; internal set; } public Func GetSignalDelayToKSC { get; internal set; } public Func GetSignalDelayToSatellite { get; internal set; } + public Action InvokeOriginalEvent { get; internal set; } } } \ No newline at end of file diff --git a/src/kOS/AddOns/RemoteTech/RemoteTechAntennaModuleFields.cs b/src/kOS/AddOns/RemoteTech/RemoteTechAntennaModuleFields.cs new file mode 100644 index 000000000..2e694cbcf --- /dev/null +++ b/src/kOS/AddOns/RemoteTech/RemoteTechAntennaModuleFields.cs @@ -0,0 +1,208 @@ +using kOS.Safe.Encapsulation; +using kOS.Safe.Encapsulation.Suffixes; +using kOS.Safe.Exceptions; +using kOS.Suffixed; +using kOS.Suffixed.PartModuleField; +using System; +using System.Linq; +using System.Text; + +namespace kOS.AddOns.RemoteTech +{ + [kOS.Safe.Utilities.KOSNomenclature("RTAddonAntennaModule")] + public class RemoteTechAntennaModuleFields : PartModuleFields + { + // those Guids are hardcoded in RemoteTech + public const string NoTargetGuid = "00000000000000000000000000000000"; + + public const string ActiveVesselGuid = "35b89a0d664c43c6bec8d0840afc97b2"; + public const string MissionControlGuid = "5105f5a9d62841c6ad4b21154e8fc488"; + + public const string RTAntennaModule = "ModuleRTAntenna"; + public const string RTOriginalField = "RTAntennaTarget"; + public const string RTTargetField = "target"; + + public const string NoTargetString = "no-target"; + public const string ActiveVesselString = "active-vessel"; + public const string MissionControlString = "mission-control"; + + public RemoteTechAntennaModuleFields(PartModule partModule, SharedObjects shared) + : base(partModule, shared) + { + // overwrite suffixes with our own + InitializeSuffixesAfterConstruction(); + } + + private void InitializeSuffixesAfterConstruction() + { + AddSuffix("ALLFIELDS", new Suffix(() => AllFields("({0}) {1}, is {2}"))); + AddSuffix("ALLFIELDNAMES", new Suffix(AllFieldNames)); + AddSuffix("HASFIELD", new OneArgsSuffix(HasField)); + AddSuffix("GETFIELD", new OneArgsSuffix(GetKSPFieldValue)); + AddSuffix("SETFIELD", new TwoArgsSuffix(SetKSPFieldValue)); + } + + public override BooleanValue HasField(StringValue fieldName) + { + if (fieldName.Equals(RTTargetField)) return true; + return base.HasField(fieldName); + } + + protected override ListValue AllFields(string formatter) + { + var returnValue = base.AllFields(formatter); + + returnValue.Add(new StringValue(string.Format(formatter, "settable", + RTTargetField.ToLower(), "String | Body | Vessel"))); + + return returnValue; + } + + protected override ListValue AllFieldNames() + { + var returnValue = base.AllFieldNames(); + + returnValue.Add(new StringValue(RTTargetField.ToLower())); + + return returnValue; + } + + protected new BaseField GetField(string cookedGuiName) + { + return partModule.Fields.Cast(). + FirstOrDefault(field => string.Equals(field.guiName, cookedGuiName, StringComparison.CurrentCultureIgnoreCase)); + } + + protected new Structure GetKSPFieldValue(StringValue suffixName) + { + if (Equals(suffixName, new StringValue(RTTargetField))) + { + BaseField field = GetField(RTOriginalField); + Guid guid = (Guid)field.GetValue(partModule); + string guidString = guid.ToString("N"); + + if (guidString.Equals(NoTargetGuid)) + { + return new StringValue(NoTargetString); + } + else if (guidString.Equals(ActiveVesselGuid)) + { + return new StringValue(ActiveVesselString); + } + else if (guidString.Equals(MissionControlGuid)) + { + return new StringValue(MissionControlString); + } + + foreach (var body in FlightGlobals.Bodies) + { + if (CelestialBodyGuid(body).Equals(guid)) + { + return new BodyTarget(body, shared); + } + } + + foreach (var vessel in FlightGlobals.Vessels) + { + if (vessel.id.Equals(guid)) + { + return new VesselTarget(vessel, shared); + } + } + + // just print the guid if we can't figure out what it is + return new StringValue(guid.ToString()); + } + return base.GetKSPFieldValue(suffixName); + } + + private Guid GetTargetGuid(Structure target) + { + var str = target as StringValue; + if (str != null) + { + string targetString = str; + if (targetString.Equals(NoTargetString, StringComparison.InvariantCultureIgnoreCase)) + { + return new Guid(NoTargetGuid); + } + else if (targetString.Equals(ActiveVesselString, StringComparison.InvariantCultureIgnoreCase)) + { + return new Guid(ActiveVesselGuid); + } + else if (targetString.Equals(MissionControlString, StringComparison.InvariantCultureIgnoreCase)) + { + return new Guid(MissionControlGuid); + } + else + { + var body = FlightGlobals.Bodies.FirstOrDefault(b => b.bodyName.Equals(targetString, StringComparison.InvariantCultureIgnoreCase)); + if (body != null) + { + return CelestialBodyGuid(body); + } + else + { + var vessel = FlightGlobals.Vessels.FirstOrDefault(v => v.vesselName.Equals(targetString, StringComparison.InvariantCultureIgnoreCase)); + if (vessel != null) + { + if (partModule.vessel.id.Equals(vessel.id)) + { + throw new KOSInvalidFieldValueException("Current vessel can't be the target"); + } + + return vessel.id; + } + } + } + } + else if (target is BodyTarget) + { + BodyTarget targetBody = (BodyTarget)target; + return CelestialBodyGuid(targetBody.Body); + } + else if (target is VesselTarget) + { + VesselTarget targetVessel = (VesselTarget)target; + + if (partModule.vessel.id.Equals(targetVessel.Vessel.id)) + { + throw new KOSInvalidFieldValueException("Current vessel can't be the target"); + } + + return targetVessel.Vessel.id; + } + + throw new KOSInvalidFieldValueException("'" + NoTargetString + "', '" + ActiveVesselString + "', '" + MissionControlString + + "', Body or Vessel expected"); + } + + + protected override void SetKSPFieldValue(StringValue suffixName, Structure newValue) + { + if (Equals(suffixName, new StringValue(RTTargetField))) + { + Guid guid = GetTargetGuid(newValue); + + BaseField field = GetField(RTOriginalField); + field.SetValue(guid, partModule); + } + else + { + base.SetKSPFieldValue(suffixName, newValue); + } + } + + // taken from RemoteTech's RTUtil + public static Guid CelestialBodyGuid(CelestialBody cb) + { + char[] name = cb.GetName().ToCharArray(); + var s = new StringBuilder(); + for (int i = 0; i < 16; i++) + { + s.Append(((short)name[i % name.Length]).ToString("x")); + } + return new Guid(s.ToString()); + } + } +} \ No newline at end of file diff --git a/src/kOS/AddOns/RemoteTech/RemoteTechArchive.cs b/src/kOS/AddOns/RemoteTech/RemoteTechArchive.cs index 49bd70068..ee27a5a5b 100644 --- a/src/kOS/AddOns/RemoteTech/RemoteTechArchive.cs +++ b/src/kOS/AddOns/RemoteTech/RemoteTechArchive.cs @@ -2,6 +2,7 @@ namespace kOS.AddOns.RemoteTech { + [kOS.Safe.Utilities.KOSNomenclature("RTArchive")] public class RemoteTechArchive : Archive { public bool CheckRange(Vessel vessel) diff --git a/src/kOS/AddOns/RemoteTech/RemoteTechFactory.cs b/src/kOS/AddOns/RemoteTech/RemoteTechFactory.cs index 84330e49f..dba338219 100644 --- a/src/kOS/AddOns/RemoteTech/RemoteTechFactory.cs +++ b/src/kOS/AddOns/RemoteTech/RemoteTechFactory.cs @@ -16,7 +16,7 @@ public Archive CreateArchive() return new RemoteTechArchive(); } - public VolumeManager CreateVolumeManager(SharedObjects sharedObjects) + public IVolumeManager CreateVolumeManager(SharedObjects sharedObjects) { return new RemoteTechVolumeManager(sharedObjects); } diff --git a/src/kOS/AddOns/RemoteTech/RemoteTechHook.cs b/src/kOS/AddOns/RemoteTech/RemoteTechHook.cs index f23dd8012..381561310 100644 --- a/src/kOS/AddOns/RemoteTech/RemoteTechHook.cs +++ b/src/kOS/AddOns/RemoteTech/RemoteTechHook.cs @@ -44,7 +44,7 @@ public static bool IsAvailable(Guid vesselId) public static bool IsAvailable() { - var integrationEnabled = Config.Instance.EnableRTIntegration; + var integrationEnabled = SafeHouse.Config.EnableRTIntegration; if (!integrationEnabled) { return false; diff --git a/src/kOS/AddOns/RemoteTech/RemoteTechInterpreter.cs b/src/kOS/AddOns/RemoteTech/RemoteTechInterpreter.cs index b852527c2..4a56b53ab 100644 --- a/src/kOS/AddOns/RemoteTech/RemoteTechInterpreter.cs +++ b/src/kOS/AddOns/RemoteTech/RemoteTechInterpreter.cs @@ -69,7 +69,7 @@ private void ProcessDeployCommand() if (!BatchMode) throw new Exception("Batch mode is not active."); if (batchQueue.Count == 0) throw new Exception("There are no commands to deploy."); - waitTotal = RemoteTechUtility.GetTotalWaitTime(Shared.Vessel); + waitTotal = RemoteTechUtility.GetInputWaitTime(Shared.Vessel); if (double.IsPositiveInfinity(waitTotal)) throw new Exception("No connection available."); Print("Deploying..."); @@ -97,7 +97,7 @@ public void KOSUpdate(double deltaTime) { if (!deploymentInProgress && commandQueue.Count > 0 && !BatchMode) { - waitTotal = RemoteTechUtility.GetTotalWaitTime(Shared.Vessel); + waitTotal = RemoteTechUtility.GetInputWaitTime(Shared.Vessel); StartDeployment(); deltaTime = 0; // so the elapsed time is zero in this update } @@ -110,7 +110,7 @@ public void KOSUpdate(double deltaTime) private void UpdateDeployment(double deltaTime) { - if (!RemoteTechHook.Instance.HasAnyConnection(Shared.Vessel.id)) + if (!RemoteTechUtility.HasConnectionOrControl(Shared.Vessel)) { if (!signalLossWarning) { @@ -187,7 +187,7 @@ private void DrawBars(string bars) progressBarSubBuffer.Buffer[2].ArrayCopyFrom(bars.ToCharArray(), 0, 0); } - public override void SpecialKey(char key) + public override bool SpecialKey(char key) { if (key == (char)UnicodeCommand.BREAK && deploymentInProgress) { @@ -195,10 +195,11 @@ public override void SpecialKey(char key) else commandQueue.Clear(); StopDeployment(); + return true; } else { - base.SpecialKey(key); + return base.SpecialKey(key); } } diff --git a/src/kOS/AddOns/RemoteTech/RemoteTechUtility.cs b/src/kOS/AddOns/RemoteTech/RemoteTechUtility.cs index 8d5f7ee0e..85c74eae7 100644 --- a/src/kOS/AddOns/RemoteTech/RemoteTechUtility.cs +++ b/src/kOS/AddOns/RemoteTech/RemoteTechUtility.cs @@ -13,5 +13,14 @@ public static double GetTotalWaitTime(Vessel vessel) return waitTotal; } + public static double GetInputWaitTime(Vessel vessel) + { + if (RemoteTechHook.Instance.HasLocalControl(vessel.id)) return 0d; + else return GetTotalWaitTime(vessel); + } + public static bool HasConnectionOrControl(Vessel vessel) + { + return RemoteTechHook.Instance.HasAnyConnection(vessel.id) || RemoteTechHook.Instance.HasLocalControl(vessel.id); + } } } diff --git a/src/kOS/Binding/BindingConfig.cs b/src/kOS/Binding/BindingConfig.cs index 9486c1e90..f5b80048e 100644 --- a/src/kOS/Binding/BindingConfig.cs +++ b/src/kOS/Binding/BindingConfig.cs @@ -1,4 +1,5 @@ using kOS.Safe.Binding; +using kOS.Safe.Utilities; using kOS.Suffixed; namespace kOS.Binding @@ -8,7 +9,7 @@ public class BindingConfig : Binding { public override void AddTo(SharedObjects shared) { - shared.BindingMgr.AddGetter("CONFIG", () => Config.Instance); + shared.BindingMgr.AddGetter("CONFIG", () => SafeHouse.Config); shared.BindingMgr.AddGetter("ADDONS", () => new AddonList(shared)); } } diff --git a/src/kOS/Binding/BindingManager.cs b/src/kOS/Binding/BindingManager.cs index c9c5218c5..e7769316e 100644 --- a/src/kOS/Binding/BindingManager.cs +++ b/src/kOS/Binding/BindingManager.cs @@ -6,7 +6,7 @@ namespace kOS.Binding { - public class BindingManager : IDisposable + public class BindingManager : IDisposable, IBindingManager { private readonly SharedObjects shared; private readonly List bindings = new List(); @@ -77,11 +77,27 @@ public void AddGetter(string name, BindingGetDlg dlg) AddBoundVariable(name, dlg, null); } + public void AddGetter(IEnumerable names, BindingGetDlg dlg) + { + foreach (var name in names) + { + AddBoundVariable(name, dlg, null); + } + } + public void AddSetter(string name, BindingSetDlg dlg) { AddBoundVariable(name, null, dlg); } + public void AddSetter(IEnumerable names, BindingSetDlg dlg) + { + foreach (var name in names) + { + AddBoundVariable(name, null, dlg); + } + } + public void PreUpdate() { foreach (var variable in variables) @@ -110,7 +126,10 @@ public void ToggleFlyByWire(string paramName, bool enabled) public void UnBindAll() { - flightControl.UnBind(); + if (flightControl != null) + { + flightControl.UnBind (); + } } public void Dispose() @@ -121,7 +140,7 @@ public void Dispose() } } - internal void SelectAutopilotMode(string autopilotMode) + public void SelectAutopilotMode(string autopilotMode) { if (flightControl != null) { diff --git a/src/kOS/Binding/BindingsUniverse.cs b/src/kOS/Binding/BindingsUniverse.cs index 7acbb9051..c8c56e4d4 100644 --- a/src/kOS/Binding/BindingsUniverse.cs +++ b/src/kOS/Binding/BindingsUniverse.cs @@ -1,9 +1,11 @@ using kOS.Safe.Binding; using kOS.Safe.Utilities; +using kOS.Safe.Encapsulation; using kOS.Suffixed; using System; using System.Collections.Generic; using UnityEngine; +using kOS.Safe.Persistence; namespace kOS.Binding { @@ -14,6 +16,7 @@ public class BindingTimeWarp : Binding public override void AddTo(SharedObjects shared) { + shared.BindingMgr.AddGetter("KUNIVERSE", () => new KUniverseValue(shared)); shared.BindingMgr.AddGetter("QUICKSAVE", () => { if (!HighLogic.CurrentGame.Parameters.Flight.CanQuickSave) return false; @@ -56,28 +59,6 @@ public override void AddTo(SharedObjects shared) FlightDriver.StartAndFocusVessel(game, game.flightState.activeVesselIdx); }); - shared.BindingMgr.AddGetter("LOADDISTANCE", () => PhysicsGlobals.Instance.VesselRangesDefault.orbit.load); - shared.BindingMgr.AddSetter("LOADDISTANCE", val => - { - var distance = Convert.ToSingle(val); - PhysicsGlobals.Instance.VesselRangesDefault.landed.load = distance; - PhysicsGlobals.Instance.VesselRangesDefault.splashed.load = distance; - PhysicsGlobals.Instance.VesselRangesDefault.prelaunch.load = distance; - PhysicsGlobals.Instance.VesselRangesDefault.flying.load = distance; - PhysicsGlobals.Instance.VesselRangesDefault.orbit.load = distance; - PhysicsGlobals.Instance.VesselRangesDefault.subOrbital.load = distance; - PhysicsGlobals.Instance.VesselRangesDefault.escaping.load = distance; - - var unloadDistance = distance - 250; - PhysicsGlobals.Instance.VesselRangesDefault.landed.unload = unloadDistance; - PhysicsGlobals.Instance.VesselRangesDefault.splashed.unload = unloadDistance; - PhysicsGlobals.Instance.VesselRangesDefault.prelaunch.unload = unloadDistance; - PhysicsGlobals.Instance.VesselRangesDefault.flying.unload = unloadDistance; - PhysicsGlobals.Instance.VesselRangesDefault.orbit.unload = unloadDistance; - PhysicsGlobals.Instance.VesselRangesDefault.subOrbital.unload = unloadDistance; - PhysicsGlobals.Instance.VesselRangesDefault.escaping.unload = unloadDistance; - }); - shared.BindingMgr.AddGetter("WARPMODE", () => { switch (TimeWarp.WarpMode) @@ -124,7 +105,7 @@ public override void AddTo(SharedObjects shared) SetWarpRate(newRate, TimeWarp.fetch.warpRates.Length - 1); break; case TimeWarp.Modes.LOW: - SetWarpRate(newRate, TimeWarp.fetch.maxPhysicsRate_index); + SetWarpRate(newRate, TimeWarp.fetch.physicsWarpRates.Length - 1); break; default: throw new Exception(string.Format("WARPMODE '{0}' is unknown to kOS, please contact the devs", val)); @@ -143,6 +124,7 @@ public override void AddTo(SharedObjects shared) MapView.ExitMapView(); } }); + shared.BindingMgr.AddGetter("CONSTANT", () => new ConstantValue()); foreach (var body in FlightGlobals.fetch.bodies) { var cBody = body; @@ -150,16 +132,18 @@ public override void AddTo(SharedObjects shared) } shared.BindingMgr.AddGetter("VERSION", () => Core.VersionInfo); + shared.BindingMgr.AddGetter("SOLARPRIMEVECTOR", () => new Vector(Planetarium.right)); + shared.BindingMgr.AddGetter("ARCHIVE", () => shared.VolumeMgr.GetVolume(Archive.ArchiveName)); } private static void SetWarpRate(int newRate, int maxRate) { - var clampedValue = Mathf.Clamp(maxRate, 0, newRate); - if (clampedValue != maxRate) + var clampedValue = Mathf.Clamp(newRate, 0, maxRate); + if (clampedValue != newRate) { - SafeHouse.Logger.Log(string.Format("Clamped Timewarp rate. Was: {0} Is: {1}", clampedValue, maxRate)); + SafeHouse.Logger.Log(string.Format("Clamped Timewarp rate. Was: {0} Is: {1}", newRate, clampedValue)); } TimeWarp.SetRate(clampedValue, false); } } -} \ No newline at end of file +} diff --git a/src/kOS/Binding/ColorBinding.cs b/src/kOS/Binding/ColorBinding.cs index ad71d3ecb..86cb98bb1 100644 --- a/src/kOS/Binding/ColorBinding.cs +++ b/src/kOS/Binding/ColorBinding.cs @@ -19,13 +19,9 @@ public override void AddTo(SharedObjects shared) shared.BindingMgr.AddGetter("GREEN", () => new RgbaColor(0.0f, 1.0f, 0.0f)); shared.BindingMgr.AddGetter("BLUE", () => new RgbaColor(0.0f, 0.0f, 1.0f)); shared.BindingMgr.AddGetter("YELLOW", () => new RgbaColor(1.0f, 1.0f, 0.0f)); - shared.BindingMgr.AddGetter("MAGENTA", () => new RgbaColor(1.0f, 0.0f, 1.0f)); + shared.BindingMgr.AddGetter(new [] {"MAGENTA","PURPLE"}, () => new RgbaColor(1.0f, 0.0f, 1.0f)); shared.BindingMgr.AddGetter("CYAN", () => new RgbaColor(0.0f, 1.0f, 1.0f)); - shared.BindingMgr.AddGetter("GREY", () => new RgbaColor(0.5f, 0.5f, 0.5f)); - - // Other synonym spellings repeating the above colors: - shared.BindingMgr.AddGetter("PURPLE", () => new RgbaColor(1.0f, 0.0f, 1.0f)); - shared.BindingMgr.AddGetter("GRAY", () => new RgbaColor(0.5f, 0.5f, 0.5f)); + shared.BindingMgr.AddGetter(new [] {"GREY", "GRAY"}, () => new RgbaColor(0.5f, 0.5f, 0.5f)); } } diff --git a/src/kOS/Binding/FlightControlManager.cs b/src/kOS/Binding/FlightControlManager.cs index 213f977ad..b0d07d730 100644 --- a/src/kOS/Binding/FlightControlManager.cs +++ b/src/kOS/Binding/FlightControlManager.cs @@ -1,6 +1,7 @@ using kOS.AddOns.RemoteTech; using kOS.Safe.Binding; using kOS.Safe.Utilities; +using kOS.Safe.Exceptions; using kOS.Suffixed; using kOS.Utilities; using System; @@ -87,7 +88,7 @@ public override void Update() // If it gets this far, that means the part the kOSProcessor module is inside of // got disconnected from its original vessel and became a member - // of a new child vessel, either do to undocking, decoupling, or breakage. + // of a new child vessel, either due to undocking, decoupling, or breakage. // currentVessel is now a stale reference to the vessel this manager used to be a member of, // while Shared.Vessel is the new vessel it is now contained in. @@ -109,6 +110,12 @@ public override void Update() foreach (var param in flightParameters.Values) param.UpdateFlightControl(currentVessel); + + // If any paramers were removed in UnbindUnloaded, add them back here + AddMissingFlightParam("throttle", Shared); + AddMissingFlightParam("steering", Shared); + AddMissingFlightParam("wheelthrottle", Shared); + AddMissingFlightParam("wheelsteering", Shared); } public static FlightControl GetControllerByVessel(Vessel target) @@ -146,7 +153,15 @@ private static void UnbindUnloaded() private void AddNewFlightParam(string name, SharedObjects shared) { - flightParameters.Add(name, new FlightCtrlParam(name, shared)); + flightParameters[name] = new FlightCtrlParam(name, shared); + } + + private void AddMissingFlightParam(string name, SharedObjects shared) + { + if (!flightParameters.ContainsKey(name)) + { + AddNewFlightParam(name, shared); + } } public void UnBind() @@ -171,6 +186,7 @@ public void Dispose() UnBind(); flightControls.Remove(currentVessel.rootPart.flightID); + SteeringManagerProvider.RemoveInstance(currentVessel); } private bool VesselIsValid(Vessel vessel) @@ -237,10 +253,11 @@ public void SelectAutopilotMode(string autopilotMode) SelectAutopilotMode(VesselAutopilot.AutopilotMode.Antinormal); break; case "radialin": - SelectAutopilotMode(VesselAutopilot.AutopilotMode.RadialIn); + // TODO: As of KSP 1.0.4, RadialIn and RadialOut are swapped. Check if still true in future versions. + SelectAutopilotMode(VesselAutopilot.AutopilotMode.RadialOut); break; case "radialout": - SelectAutopilotMode(VesselAutopilot.AutopilotMode.RadialOut); + SelectAutopilotMode(VesselAutopilot.AutopilotMode.RadialIn); break; case "target": SelectAutopilotMode(VesselAutopilot.AutopilotMode.Target); @@ -254,7 +271,7 @@ public void SelectAutopilotMode(string autopilotMode) break; default: // If the mode is not recognised, thrown an exception rather than continuing or using a default setting - throw new Safe.Exceptions.KOSException( + throw new KOSException( string.Format("kOS does not recognize the SAS mode setting of {0}", autopilotMode)); } } @@ -264,19 +281,27 @@ private class FlightCtrlParam : IDisposable { private readonly string name; private FlightControl control; - private readonly BindingManager binding; + private readonly IBindingManager binding; private object value; private bool enabled; + private readonly SharedObjects shared; + private SteeringManager steeringManager; public FlightCtrlParam(string name, SharedObjects sharedObjects) { this.name = name; + shared = sharedObjects; control = GetControllerByVessel(sharedObjects.Vessel); binding = sharedObjects.BindingMgr; Enabled = false; value = null; + if (string.Equals(name, "steering", StringComparison.CurrentCultureIgnoreCase)) + { + steeringManager = SteeringManagerProvider.GetInstance(sharedObjects); + } + HookEvents(); } @@ -295,6 +320,12 @@ public bool Enabled SafeHouse.Logger.Log(string.Format("FlightCtrlParam: Enabled: {0} {1} => {2}", name, enabled, value)); enabled = value; + if (steeringManager != null) + { + if (enabled) steeringManager.EnableControl(shared); + else steeringManager.DisableControl(); + //steeringManager.Enabled = enabled; + } if (RemoteTechHook.IsAvailable(control.Vessel.id)) { HandleRemoteTechPilot(); @@ -369,37 +400,53 @@ private Action ChooseAction() private void UpdateThrottle(FlightCtrlState c) { if (!Enabled) return; - double doubleValue = Convert.ToDouble(value); - if (!double.IsNaN(doubleValue)) - c.mainThrottle = (float)Safe.Utilities.Math.Clamp(doubleValue, 0, 1); + try + { + double doubleValue = Convert.ToDouble(value); + if (!double.IsNaN(doubleValue)) + c.mainThrottle = (float)Safe.Utilities.Math.Clamp(doubleValue, 0, 1); + } + catch (InvalidCastException) // Note, very few types actually fail Convert.ToDouble(), so it's hard to get this to occur. + { + // perform the "unlock" so this message won't spew every FixedUpdate: + Enabled = false; + ClearValue(); + throw new KOSWrongControlValueTypeException( + "THROTTLE", value.GetType().Name, "Number in the range [0..1]"); + } } private void UpdateWheelThrottle(FlightCtrlState c) { if (!Enabled) return; - double doubleValue = Convert.ToDouble(value); - if (!double.IsNaN(doubleValue)) - c.wheelThrottle = (float)Safe.Utilities.Math.Clamp(doubleValue, -1, 1); + try + { + double doubleValue = Convert.ToDouble(value); + if (!double.IsNaN(doubleValue)) + c.wheelThrottle = (float)Safe.Utilities.Math.Clamp(doubleValue, -1, 1); + } + catch (InvalidCastException) // Note, very few types actually fail Convert.ToDouble(), so it's hard to get this to occur. + { + // perform the "unlock" so this message won't spew every FixedUpdate: + Enabled = false; + ClearValue(); + throw new KOSWrongControlValueTypeException( + "WHEELTHROTTLE", value.GetType().Name, "Number in the range [-1..1]"); + } } private void SteerByWire(FlightCtrlState c) { if (!Enabled) return; - if (value is string && ((string)value).ToUpper() == "KILL") + if (steeringManager.Enabled) { - SteeringHelper.KillRotation(c, control.Vessel); + steeringManager.Value = value; + steeringManager.OnFlyByWire(c); } - else if (value is Direction) - { - SteeringHelper.SteerShipToward((Direction)value, c, control.Vessel); - } - else if (value is Vector) - { - SteeringHelper.SteerShipToward(((Vector)value).ToDirection(), c, control.Vessel); - } - else if (value is Node) + else { - SteeringHelper.SteerShipToward(((Node)value).GetBurnVector().ToDirection(), c, control.Vessel); + Enabled = false; + ClearValue(); } } @@ -416,11 +463,28 @@ private void WheelSteer(FlightCtrlState c) { bearing = (float) ((GeoCoordinates)value).GetBearing(); } - else if (value is double) + else { - double doubleValue = Convert.ToDouble(value); - if (Utils.IsValidNumber(doubleValue)) - bearing = (float)(Math.Round(doubleValue) - Mathf.Round(FlightGlobals.ship_heading)); + try + { + double doubleValue = Convert.ToDouble(value); + if (Utils.IsValidNumber(doubleValue)) + { + bearing = (float)(Math.Round(doubleValue) - Mathf.Round(FlightGlobals.ship_heading)); + if (bearing < -180) + bearing += 360; // i.e. 359 degrees to the left is really 1 degree to the right. + else if (bearing > 180) + bearing -= 360; // i.e. 359 degrees to the right is really 1 degree to the left + } + } + catch (InvalidCastException) // Note, very few types actually fail Convert.ToDouble(), so it's hard to get this to occur. + { + // perform the "unlock" so this message won't spew every FixedUpdate: + Enabled = false; + ClearValue(); + throw new KOSWrongControlValueTypeException( + "WHEELSTEER", value.GetType().Name, "Vessel, LATLNG, or Number (compass heading)"); + } } if (!(control.Vessel.horizontalSrfSpeed > 0.1f)) return; @@ -438,11 +502,21 @@ private void WheelSteer(FlightCtrlState c) public void Dispose() { Enabled = false; + if (steeringManager != null) + { + SteeringManagerProvider.RemoveInstance(shared.Vessel); + steeringManager = null; + } } public void UpdateFlightControl(Vessel vessel) { control = GetControllerByVessel(vessel); + if (steeringManager != null) + { + steeringManager = SteeringManagerProvider.SwapInstance(shared, steeringManager); + steeringManager.Update(vessel); + } } public override string ToString() // added to aid in debugging. diff --git a/src/kOS/Binding/FlightStats.cs b/src/kOS/Binding/FlightStats.cs index c02e9da9b..f6ad96ba4 100644 --- a/src/kOS/Binding/FlightStats.cs +++ b/src/kOS/Binding/FlightStats.cs @@ -1,9 +1,8 @@ -using System; -using kOS.Safe.Binding; -using UnityEngine; +using kOS.Safe.Binding; +using kOS.Safe.Encapsulation.Suffixes; +using kOS.Safe.Exceptions; using kOS.Suffixed; using kOS.Utilities; -using TimeSpan = kOS.Suffixed.TimeSpan; namespace kOS.Binding { @@ -12,18 +11,14 @@ public class FlightStats : Binding { public override void AddTo(SharedObjects shared) { - shared.BindingMgr.AddGetter("ALT_APOAPSIS", () => shared.Vessel.orbit.ApA); - shared.BindingMgr.AddGetter("ALT_PERIAPSIS", () => shared.Vessel.orbit.PeA); - shared.BindingMgr.AddGetter("ALT_RADAR", () => Convert.ToDouble(shared.Vessel.heightFromTerrain > 0 ? Mathf.Min(shared.Vessel.heightFromTerrain, (float)shared.Vessel.altitude) : (float)shared.Vessel.altitude)); + shared.BindingMgr.AddGetter("ALT", () => new VesselAlt(shared)); shared.BindingMgr.AddGetter("ANGULARVELOCITY", () => shared.Vessel.transform.InverseTransformDirection(shared.Vessel.rigidbody.angularVelocity)); shared.BindingMgr.AddGetter("COMMRANGE", () => int.MaxValue); shared.BindingMgr.AddGetter("ENCOUNTER", () => VesselUtils.TryGetEncounter(shared.Vessel,shared)); - shared.BindingMgr.AddGetter("ETA_APOAPSIS", () => shared.Vessel.orbit.timeToAp); - shared.BindingMgr.AddGetter("ETA_PERIAPSIS", () => shared.Vessel.orbit.timeToPe); - shared.BindingMgr.AddGetter("ETA_TRANSITION", () => shared.Vessel.orbit.EndUT - Planetarium.GetUniversalTime()); - shared.BindingMgr.AddGetter("INCOMMRANGE", () => true); + shared.BindingMgr.AddGetter("ETA", () => new VesselEta(shared)); + shared.BindingMgr.AddGetter("INCOMMRANGE", () => { throw new KOSDeprecationException("0.17.0", "INCOMMRANGE", "ADDONS:RT:HASCONNECTION(VESSEL)", @"http://ksp-kos.github.io/KOS_DOC/addons/RemoteTech.html"); }); shared.BindingMgr.AddGetter("MISSIONTIME", () => shared.Vessel.missionTime); - shared.BindingMgr.AddGetter("OBT", () => new OrbitInfo(shared.Vessel.orbit,shared)); + shared.BindingMgr.AddGetter(new [] { "OBT" , "ORBIT"}, () => new OrbitInfo(shared.Vessel.orbit,shared)); shared.BindingMgr.AddGetter("TIME", () => new TimeSpan(Planetarium.GetUniversalTime())); shared.BindingMgr.AddGetter("SHIP", () => new VesselTarget(shared)); shared.BindingMgr.AddGetter("ACTIVESHIP", () => new VesselTarget(FlightGlobals.ActiveVessel, shared)); @@ -32,23 +27,42 @@ public override void AddTo(SharedObjects shared) shared.BindingMgr.AddSetter("SHIPNAME", value => shared.Vessel.vesselName = value.ToString()); + shared.BindingMgr.AddGetter("STEERINGMANAGER", () => SteeringManagerProvider.GetInstance(shared)); + shared.BindingMgr.AddGetter("NEXTNODE", () => { var vessel = shared.Vessel; + if (vessel.patchedConicSolver == null) + throw new KOSSituationallyInvalidException( + "A KSP limitation makes it impossible to access the manuever nodes of this vessel at this time. " + + "(perhaps it's not the active vessel?)"); if (vessel.patchedConicSolver.maneuverNodes.Count == 0) - { - throw new Exception("No maneuver nodes present!"); - } + throw new KOSSituationallyInvalidException("No maneuver nodes present!"); return Node.FromExisting(vessel, vessel.patchedConicSolver.maneuverNodes[0], shared); }); + shared.BindingMgr.AddGetter("HASNODE", () => + { + var vessel = shared.Vessel; + if (vessel.patchedConicSolver == null) + return false; // Since there is no solver, there can be no node. + return vessel.patchedConicSolver.maneuverNodes.Count > 0; + }); // These are now considered shortcuts to SHIP:suffix foreach (var scName in VesselTarget.ShortCuttableShipSuffixes) { var cName = scName; - shared.BindingMgr.AddGetter(scName, () => new VesselTarget(shared).GetSuffix(cName)); + shared.BindingMgr.AddGetter(scName, () => VesselShortcutGetter(shared, cName)); } } + + public object VesselShortcutGetter(SharedObjects shared, string name) + { + ISuffixResult suffix = new VesselTarget(shared).GetSuffix(name); + if (! suffix.HasValue) + suffix.Invoke(shared.Cpu); + return suffix.Value; + } } } diff --git a/src/kOS/Binding/MissionSettings.cs b/src/kOS/Binding/MissionSettings.cs index 314361f47..04d882db2 100644 --- a/src/kOS/Binding/MissionSettings.cs +++ b/src/kOS/Binding/MissionSettings.cs @@ -1,8 +1,8 @@ using kOS.Safe.Binding; -using kOS.Safe.Encapsulation; using kOS.Suffixed; using kOS.Suffixed.Part; using kOS.Utilities; +using kOS.Module; namespace kOS.Binding { @@ -11,8 +11,14 @@ public class MissionSettings : Binding { public override void AddTo(SharedObjects shared) { + shared.BindingMgr.AddGetter("CORE", () => new Core((kOSProcessor)shared.Processor, shared)); + shared.BindingMgr.AddSetter("TARGET", val => { + if (shared.Vessel != FlightGlobals.ActiveVessel) + { + throw new kOS.Safe.Exceptions.KOSSituationallyInvalidException("TARGET can only be set for the Active Vessel"); + } var targetable = val as IKOSTargetable; if (targetable != null) { @@ -20,18 +26,21 @@ public override void AddTo(SharedObjects shared) return; } - var body = VesselUtils.GetBodyByName(val.ToString()); - if (body != null) + if (!string.IsNullOrEmpty(val.ToString().Trim())) { - VesselUtils.SetTarget(body); - return; - } + var body = VesselUtils.GetBodyByName(val.ToString()); + if (body != null) + { + VesselUtils.SetTarget(body); + return; + } - var vessel = VesselUtils.GetVesselByName(val.ToString(), shared.Vessel); - if (vessel != null) - { - VesselUtils.SetTarget(vessel); - return; + var vessel = VesselUtils.GetVesselByName(val.ToString(), shared.Vessel); + if (vessel != null) + { + VesselUtils.SetTarget(vessel); + return; + } } //Target not found, if we have a target we clear it VesselUtils.UnsetTarget(); @@ -39,6 +48,10 @@ public override void AddTo(SharedObjects shared) shared.BindingMgr.AddGetter("TARGET", () => { + if (shared.Vessel != FlightGlobals.ActiveVessel) + { + throw new kOS.Safe.Exceptions.KOSSituationallyInvalidException("TARGET can only be returned for the Active Vessel"); + } var currentTarget = FlightGlobals.fetch.VesselTarget; var vessel = currentTarget as Vessel; @@ -57,8 +70,16 @@ public override void AddTo(SharedObjects shared) return new DockingPortValue(dockingNode, shared); } - return null; + throw new kOS.Safe.Exceptions.KOSSituationallyInvalidException("No TARGET is selected"); }); + + shared.BindingMgr.AddGetter("HASTARGET", () => + { + if (shared.Vessel != FlightGlobals.ActiveVessel) return false; + // the ship has a target if the object does not equal null. + return FlightGlobals.fetch.VesselTarget != null; + }); + } } } \ No newline at end of file diff --git a/src/kOS/Binding/SteeringManager.cs b/src/kOS/Binding/SteeringManager.cs new file mode 100644 index 000000000..cfeaad19d --- /dev/null +++ b/src/kOS/Binding/SteeringManager.cs @@ -0,0 +1,1638 @@ +using kOS.Safe.Encapsulation; +using kOS.Safe.Encapsulation.Suffixes; +using kOS.Safe.Utilities; +using kOS.Suffixed; +using System; +using System.Collections.Generic; +using System.Linq; +using UnityEngine; +using Math = System.Math; + +namespace kOS.Binding +{ + [kOS.Safe.Utilities.KOSNomenclature("SteeringManager")] + public class SteeringManager : Structure, IDisposable + { + public static SteeringManager DeepCopy(SteeringManager oldInstance, SharedObjects shared) + { + SteeringManager instance = SteeringManagerProvider.GetInstance(shared); + instance.ShowAngularVectors = oldInstance.ShowAngularVectors; + instance.ShowFacingVectors = oldInstance.ShowFacingVectors; + instance.ShowRCSVectors = oldInstance.ShowRCSVectors; + instance.ShowThrustVectors = oldInstance.ShowThrustVectors; + instance.ShowSteeringStats = oldInstance.ShowSteeringStats; + instance.WriteCSVFiles = oldInstance.WriteCSVFiles; + instance.MaxStoppingTime = oldInstance.MaxStoppingTime; + + instance.pitchPI.Ts = oldInstance.pitchPI.Ts; + instance.yawPI.Ts = oldInstance.yawPI.Ts; + instance.rollPI.Ts = oldInstance.rollPI.Ts; + instance.pitchPI.Loop = PIDLoop.DeepCopy(oldInstance.pitchPI.Loop); + instance.yawPI.Loop = PIDLoop.DeepCopy(oldInstance.yawPI.Loop); + instance.rollPI.Loop = PIDLoop.DeepCopy(oldInstance.rollPI.Loop); + + instance.pitchRatePI = PIDLoop.DeepCopy(oldInstance.pitchRatePI); + instance.yawRatePI = PIDLoop.DeepCopy(oldInstance.yawRatePI); + instance.rollRatePI = PIDLoop.DeepCopy(oldInstance.rollRatePI); + + instance.PitchTorqueAdjust = oldInstance.PitchTorqueAdjust; + instance.PitchTorqueFactor = oldInstance.PitchTorqueFactor; + instance.RollTorqueAdjust = oldInstance.RollTorqueAdjust; + instance.RollTorqueFactor = oldInstance.RollTorqueFactor; + instance.YawTorqueAdjust = oldInstance.YawTorqueAdjust; + instance.YawTorqueFactor = oldInstance.YawTorqueFactor; + return instance; + } + + public Vessel Vessel + { + get + { + return shared.Vessel; + } + } + + public List SubscribedParts = new List(); + + private SharedObjects shared; + + private uint partId = 0; + + public uint PartId { get { return partId; } } + + private bool enabled = false; + + public bool Enabled + { + get { return enabled; } + set + { + enabled = value; + if (enabled) + { + ResetIs(); + } + else + { + UpdateVectorRenders(); + + if (pitchRateWriter != null) pitchRateWriter.Dispose(); + if (yawRateWriter != null) yawRateWriter.Dispose(); + if (rollRateWriter != null) rollRateWriter.Dispose(); + if (pitchTorqueWriter != null) pitchTorqueWriter.Dispose(); + if (yawTorqueWriter != null) yawTorqueWriter.Dispose(); + if (rollTorqueWriter != null) rollTorqueWriter.Dispose(); + if (adjustTorqueWriter != null) adjustTorqueWriter.Dispose(); + + pitchRateWriter = null; + yawRateWriter = null; + rollRateWriter = null; + pitchTorqueWriter = null; + yawTorqueWriter = null; + rollTorqueWriter = null; + adjustTorqueWriter = null; + } + } + } + + public bool ShowFacingVectors { get; set; } + + public bool ShowAngularVectors { get; set; } + + public bool ShowThrustVectors { get; set; } + + public bool ShowRCSVectors { get; set; } + + public bool ShowSteeringStats { get; set; } + + public bool WriteCSVFiles { get; set; } + + private const string FILE_BASE_NAME = "{0}-{1}-{2}.csv"; + private readonly string fileDateString = DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss"); + + public object Value { get; set; } + + public Direction TargetDirection { get { return GetDirectionFromValue(); } } + + private Transform vesselTransform; + + private readonly TorquePI pitchPI = new TorquePI(); + private readonly TorquePI yawPI = new TorquePI(); + private readonly TorquePI rollPI = new TorquePI(); + + private PIDLoop pitchRatePI = new PIDLoop(1, 0.1, 0, extraUnwind: true); + private PIDLoop yawRatePI = new PIDLoop(1, 0.1, 0, extraUnwind: true); + private PIDLoop rollRatePI = new PIDLoop(1, 0.1, 0, extraUnwind: true); + + private KSP.IO.TextWriter pitchRateWriter; + private KSP.IO.TextWriter yawRateWriter; + private KSP.IO.TextWriter rollRateWriter; + + private KSP.IO.TextWriter pitchTorqueWriter; + private KSP.IO.TextWriter yawTorqueWriter; + private KSP.IO.TextWriter rollTorqueWriter; + + private KSP.IO.TextWriter adjustTorqueWriter; + + private readonly MovingAverage pitchTorqueCalc = new MovingAverage { SampleLimit = 15 }; + private readonly MovingAverage yawTorqueCalc = new MovingAverage { SampleLimit = 15 }; + private readonly MovingAverage rollTorqueCalc = new MovingAverage { SampleLimit = 15 }; + + private bool EnableTorqueAdjust { get; set; } + + private readonly MovingAverage pitchMOICalc = new MovingAverage { SampleLimit = 5 }; + private readonly MovingAverage yawMOICalc = new MovingAverage { SampleLimit = 5 }; + private readonly MovingAverage rollMOICalc = new MovingAverage { SampleLimit = 5 }; + + private bool enableMoiAdjust; + + public MovingAverage AverageDuration = new MovingAverage { SampleLimit = 60 }; + + #region doubles + + public const double RadToDeg = 180d / Math.PI; + + private const double EPSILON = 1e-16; + + private double sessionTime = double.MaxValue; + private double lastSessionTime = double.MaxValue; + + public double MaxStoppingTime { get; set; } + + private double accPitch = 0; + private double accYaw = 0; + private double accRoll = 0; + + private double phi; + private double phiPitch; + private double phiYaw; + private double phiRoll; + + private double maxPitchOmega; + private double maxYawOmega; + private double maxRollOmega; + + private double tgtPitchOmega; + private double tgtYawOmega; + private double tgtRollOmega; + + private double tgtPitchTorque; + private double tgtYawTorque; + private double tgtRollTorque; + + private const double RENDER_MULTIPLIER = 50; + + public double PitchTorqueAdjust { get; set; } + public double YawTorqueAdjust { get; set; } + public double RollTorqueAdjust { get; set; } + + public double PitchTorqueFactor { get; set; } + public double YawTorqueFactor { get; set; } + public double RollTorqueFactor { get; set; } + + private int vesselParts; + private double vesselMass = 0; + + #endregion doubles + + private readonly List reactionWheelModules = new List(); + private readonly List rcsModules = new List(); + private readonly List engineModules = new List(); + private readonly List gimbalModules = new List(); + + private Quaternion vesselRotation; + private Quaternion targetRot; + + #region Vectors + + private Vector3d centerOfMass; + private Vector3d vesselUp; + + private Vector3d vesselForward; + private Vector3d vesselTop; + private Vector3d vesselStarboard; + + private Vector3d targetForward; + private Vector3d targetTop; + private Vector3d targetStarboard; + + private Vector3d adjustTorque; + private Vector3d adjustMomentOfInertia; + + private Vector3d omega = Vector3d.zero; // x: pitch, y: yaw, z: roll + private Vector3d lastOmega = Vector3d.zero; + private Vector3d angularAcceleration = Vector3d.zero; + private Vector3d momentOfInertia = Vector3d.zero; // x: pitch, z: yaw, y: roll + private Vector3d measuredMomentOfInertia = Vector3d.zero; + private Vector3d measuredTorque = Vector3d.zero; + private Vector3d staticTorque = Vector3d.zero; // x: pitch, z: yaw, y: roll + private Vector3d controlTorque = Vector3d.zero; // x: pitch, z: yaw, y: roll + private Vector3d rawTorque = Vector3d.zero; // x: pitch, z: yaw, y: roll + private Vector3d staticEngineTorque = Vector3d.zero; // x: pitch, z: yaw, y: roll + private Vector3d controlEngineTorque = Vector3d.zero; // x: pitch, z: yaw, y: roll + + private readonly List rcsVectors = new List(); + private readonly List engineNeutVectors = new List(); + private readonly List enginePitchVectors = new List(); + private readonly List engineYawVectors = new List(); + private readonly List engineRollVectors = new List(); + + #endregion Vectors + + #region VectorRenderers + + private VectorRenderer vForward; + private VectorRenderer vTop; + private VectorRenderer vStarboard; + + private VectorRenderer vTgtForward; + private VectorRenderer vTgtTop; + private VectorRenderer vTgtStarboard; + + private VectorRenderer vWorldX; + private VectorRenderer vWorldY; + private VectorRenderer vWorldZ; + + private VectorRenderer vOmegaX; + private VectorRenderer vOmegaY; + private VectorRenderer vOmegaZ; + + private VectorRenderer vTgtTorqueX; + private VectorRenderer vTgtTorqueY; + private VectorRenderer vTgtTorqueZ; + + private readonly Dictionary vEngines = new Dictionary(); + private readonly Dictionary vRcs = new Dictionary(); + + #endregion VectorRenderers + + public SteeringManager(SharedObjects sharedObj) + { + shared = sharedObj; + ShowFacingVectors = false; + ShowAngularVectors = false; + ShowThrustVectors = false; + ShowRCSVectors = false; + ShowSteeringStats = false; + WriteCSVFiles = false; + + if (pitchRateWriter != null) pitchRateWriter.Dispose(); + if (yawRateWriter != null) yawRateWriter.Dispose(); + if (rollRateWriter != null) rollRateWriter.Dispose(); + + if (pitchTorqueWriter != null) pitchTorqueWriter.Dispose(); + if (yawTorqueWriter != null) yawTorqueWriter.Dispose(); + if (rollTorqueWriter != null) rollTorqueWriter.Dispose(); + + if (adjustTorqueWriter != null) adjustTorqueWriter.Dispose(); + + pitchRateWriter = null; + yawRateWriter = null; + rollRateWriter = null; + + pitchTorqueWriter = null; + yawTorqueWriter = null; + rollTorqueWriter = null; + + adjustTorqueWriter = null; + + adjustTorque = Vector3d.zero; + adjustMomentOfInertia = Vector3d.one; + + enableMoiAdjust = false; + EnableTorqueAdjust = true; + + MaxStoppingTime = 2; + + PitchTorqueAdjust = 0; + YawTorqueAdjust = 0; + RollTorqueAdjust = 0; + + PitchTorqueFactor = 1; + YawTorqueFactor = 1; + RollTorqueFactor = 1; + + InitializeSuffixes(); + } + + public void InitializeSuffixes() + { + AddSuffix("PITCHPID", new Suffix(() => pitchRatePI)); + AddSuffix("YAWPID", new Suffix(() => yawRatePI)); + AddSuffix("ROLLPID", new Suffix(() => rollRatePI)); + AddSuffix("ENABLED", new Suffix(() => Enabled)); + AddSuffix("TARGET", new Suffix(() => TargetDirection)); + AddSuffix("RESETPIDS", new NoArgsVoidSuffix(ResetIs)); + AddSuffix("SHOWFACINGVECTORS", new SetSuffix(() => ShowFacingVectors, value => ShowFacingVectors = value)); + AddSuffix("SHOWANGULARVECTORS", new SetSuffix(() => ShowAngularVectors, value => ShowAngularVectors = value)); + AddSuffix("SHOWTHRUSTVECTORS", new SetSuffix(() => ShowThrustVectors, value => ShowThrustVectors = value)); + AddSuffix("SHOWRCSVECTORS", new SetSuffix(() => ShowRCSVectors, value => ShowRCSVectors = value)); + AddSuffix("SHOWSTEERINGSTATS", new SetSuffix(() => ShowSteeringStats, value => ShowSteeringStats = value)); + AddSuffix("WRITECSVFILES", new SetSuffix(() => WriteCSVFiles, value => WriteCSVFiles = value)); + AddSuffix("PITCHTS", new SetSuffix(() => pitchPI.Ts, value => pitchPI.Ts = value)); + AddSuffix("YAWTS", new SetSuffix(() => yawPI.Ts, value => yawPI.Ts = value)); + AddSuffix("ROLLTS", new SetSuffix(() => rollPI.Ts, value => rollPI.Ts = value)); + AddSuffix("MAXSTOPPINGTIME", new SetSuffix(() => MaxStoppingTime, value => MaxStoppingTime = value)); + AddSuffix("ANGLEERROR", new Suffix(() => phi * RadToDeg)); + AddSuffix("PITCHERROR", new Suffix(() => phiPitch * RadToDeg)); + AddSuffix("YAWERROR", new Suffix(() => phiYaw * RadToDeg)); + AddSuffix("ROLLERROR", new Suffix(() => phiRoll * RadToDeg)); + AddSuffix("PITCHTORQUEADJUST", new SetSuffix(() => PitchTorqueAdjust, value => PitchTorqueAdjust = value)); + AddSuffix("YAWTORQUEADJUST", new SetSuffix(() => YawTorqueAdjust, value => YawTorqueAdjust = value)); + AddSuffix("ROLLTORQUEADJUST", new SetSuffix(() => RollTorqueAdjust, value => RollTorqueAdjust = value)); + AddSuffix("PITCHTORQUEFACTOR", new SetSuffix(() => PitchTorqueFactor, value => PitchTorqueFactor = value)); + AddSuffix("YAWTORQUEFACTOR", new SetSuffix(() => YawTorqueFactor, value => YawTorqueFactor = value)); + AddSuffix("ROLLTORQUEFACTOR", new SetSuffix(() => RollTorqueFactor, value => RollTorqueFactor = value)); + AddSuffix("AVERAGEDURATION", new Suffix(() => AverageDuration.Mean)); +#if DEBUG + AddSuffix("MOI", new Suffix(() => new Vector(momentOfInertia))); + AddSuffix("ACTUATION", new Suffix(() => new Vector(accPitch, accRoll, accYaw))); + AddSuffix("CONTROLTORQUE", new Suffix(() => new Vector(controlTorque))); + AddSuffix("MEASUREDTORQUE", new Suffix(() => new Vector(measuredTorque))); + AddSuffix("RAWTORQUE", new Suffix(() => new Vector(rawTorque))); + AddSuffix("TARGETTORQUE", new Suffix(() => new Vector(tgtPitchTorque, tgtRollTorque, tgtYawTorque))); + AddSuffix("ANGULARVELOCITY", new Suffix(() => new Vector(omega))); + AddSuffix("ANGULARACCELERATION", new Suffix(() => new Vector(angularAcceleration))); + AddSuffix("ENABLETORQUEADJUST", new SetSuffix(() => EnableTorqueAdjust, value => EnableTorqueAdjust = value)); + AddSuffix("ENABLEMOIADJUST", new SetSuffix(() => enableMoiAdjust, value => enableMoiAdjust = value)); +#endif + } + + public void EnableControl(SharedObjects sharedObj) + { + if (enabled && partId != sharedObj.KSPPart.flightID) + throw new Safe.Exceptions.KOSException("Steering Manager on this ship is already in use by another processor."); + shared = sharedObj; + partId = sharedObj.KSPPart.flightID; + ResetIs(); + Enabled = true; + lastSessionTime = double.MaxValue; + pitchTorqueCalc.Reset(); + rollTorqueCalc.Reset(); + yawTorqueCalc.Reset(); + + adjustTorque = Vector3d.zero; + adjustMomentOfInertia = Vector3d.one; + } + + public void DisableControl() + { + if (enabled && partId != shared.KSPPart.flightID) + throw new Safe.Exceptions.KOSException("Cannon unbind Steering Manager on this ship in use by another processor."); + partId = 0; + Enabled = false; + } + + public VectorRenderer InitVectorRenderer(Color c, double width, SharedObjects sharedObj) + { + VectorRenderer rend = new VectorRenderer(sharedObj.UpdateHandler, sharedObj) + { + Color = new RgbaColor(c.r, c.g, c.b), + Start = Vector3d.zero, + Vector = Vector3d.zero, + Width = width + }; + return rend; + } + + private void ResetIs() + { + pitchPI.ResetI(); + yawPI.ResetI(); + rollPI.ResetI(); + pitchRatePI.ResetI(); + yawRatePI.ResetI(); + rollRatePI.ResetI(); + } + + public void Update(Vessel vsl) + { + //if (vessel != vsl) vessel = vsl; + // Eventually I would like to update the vectors regardless of if flybywire is called, + // so that the vector renderers will still update in time warp, but it doesn't work now. + //UpdateStateVectors(); + //UpdateTorque(); + //UpdatePrediction(); + //UpdateVectorRenders(); + //PrintDebug(); + } + + public void OnFlyByWire(FlightCtrlState c) + { + Update(c); + } + + public void OnRemoteTechPilot(FlightCtrlState c) + { + Update(c); + } + + private readonly System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch(); + + private void Update(FlightCtrlState c) + { + if (Value == null) return; + + lastSessionTime = sessionTime; + sessionTime = Math.Round(Planetarium.GetUniversalTime(), 3); + //if (sessionTime > lastSessionTime) + //{ + //} + sw.Reset(); + sw.Start(); + UpdateStateVectors(); + UpdateControlParts(); + UpdateTorque(); + UpdatePredictionPI(); + UpdateControl(c); + if (ShowSteeringStats) PrintDebug(); + if (WriteCSVFiles) WriteCSVs(); + UpdateVectorRenders(); + sw.Stop(); + AverageDuration.Update((double)sw.ElapsedTicks / (double)System.TimeSpan.TicksPerMillisecond); + } + + private Direction GetDirectionFromValue() + { + if (Value is Direction) + return (Direction)Value; + else if (Value is Vector) + return Direction.LookRotation((Vector)Value, vesselUp); + else if (Value is Node) + return Direction.LookRotation(((Node)Value).GetBurnVector(), vesselUp); + else if (Value is string) + { + if (string.Equals((string)Value, "KILL", StringComparison.OrdinalIgnoreCase)) + { + return new Direction(vesselRotation); + } + } + DisableControl(); + throw new Safe.Exceptions.KOSWrongControlValueTypeException( + "STEERING", Value.GetType().Name, "Direction, Vector, Maneuver Node, or special string \"KILL\""); + } + + public void UpdateStateVectors() + { + Direction targetdir = GetDirectionFromValue(); + if (targetdir == null) + { + shared.Logger.LogWarning(string.Format("SteeringManager target direction is null, Value = {0}", Value)); + return; + } + + targetRot = targetdir.Rotation; + centerOfMass = shared.Vessel.findWorldCenterOfMass(); + + vesselTransform = shared.Vessel.ReferenceTransform; + // Found that the default rotation has top pointing forward, forward pointing down, and right pointing starboard. + // This fixes that rotation. + vesselRotation = vesselTransform.rotation * Quaternion.Euler(-90, 0, 0); + + vesselForward = vesselRotation * Vector3d.forward; + vesselTop = vesselRotation * Vector3d.up; + vesselStarboard = vesselRotation * Vector3d.right; + vesselUp = (centerOfMass - shared.Vessel.mainBody.position).normalized; + + targetForward = targetRot * Vector3d.forward; + targetTop = targetRot * Vector3d.up; + targetStarboard = targetRot * Vector3d.right; + + Vector3d oldOmega = omega; + // omega is angular rotation. need to correct the signs to agree with the facing axis + omega = Quaternion.Inverse(vesselRotation) * shared.Vessel.rigidbody.angularVelocity; + omega.x *= -1; //positive values pull the nose to the starboard. + //omega.y *= -1; // positive values pull the nose up. + omega.z *= -1; // positive values pull the starboard side up. + + // TODO: Currently adjustments to MOI are only enabled in debug compiles. Using this feature seems to be buggy, but it has potential + // to be more resilient against random spikes in angular velocity. + if (sessionTime > lastSessionTime) + { + double dt = sessionTime - lastSessionTime; + angularAcceleration = (omega - oldOmega) / dt; + angularAcceleration = new Vector3d(angularAcceleration.x, angularAcceleration.z, angularAcceleration.y); + if (enableMoiAdjust) + { + measuredMomentOfInertia = new Vector3d( + controlTorque.x * accPitch / angularAcceleration.x, + controlTorque.y * accRoll / angularAcceleration.y, + controlTorque.z * accYaw / angularAcceleration.z); + + if (Math.Abs(accPitch) > EPSILON) + { + adjustMomentOfInertia.x = pitchMOICalc.Update(Math.Abs(measuredMomentOfInertia.x) / momentOfInertia.x); + } + if (Math.Abs(accYaw) > EPSILON) + { + adjustMomentOfInertia.z = yawMOICalc.Update(Math.Abs(measuredMomentOfInertia.z) / momentOfInertia.z); + } + if (Math.Abs(accRoll) > EPSILON) + { + adjustMomentOfInertia.y = rollMOICalc.Update(Math.Abs(measuredMomentOfInertia.y) / momentOfInertia.y); + } + } + } + + momentOfInertia = shared.Vessel.findLocalMOI(centerOfMass); + momentOfInertia.Scale(adjustMomentOfInertia); + adjustTorque = Vector3d.zero; + measuredTorque = Vector3d.Scale(momentOfInertia, angularAcceleration); + + if (sessionTime > lastSessionTime && EnableTorqueAdjust) + { + if (Math.Abs(accPitch) > EPSILON) + { + adjustTorque.x = Math.Min(Math.Abs(pitchTorqueCalc.Update(measuredTorque.x / accPitch)) - rawTorque.x, 0); + //adjustTorque.x = Math.Abs(pitchTorqueCalc.Update(measuredTorque.x / accPitch) / rawTorque.x); + } + else adjustTorque.x = Math.Abs(pitchTorqueCalc.Update(pitchTorqueCalc.Mean)); + if (Math.Abs(accYaw) > EPSILON) + { + adjustTorque.z = Math.Min(Math.Abs(yawTorqueCalc.Update(measuredTorque.z / accYaw)) - rawTorque.z, 0); + //adjustTorque.z = Math.Abs(yawTorqueCalc.Update(measuredTorque.z / accYaw) / rawTorque.z); + } + else adjustTorque.z = Math.Abs(yawTorqueCalc.Update(yawTorqueCalc.Mean)); + if (Math.Abs(accRoll) > EPSILON) + { + adjustTorque.y = Math.Min(Math.Abs(rollTorqueCalc.Update(measuredTorque.y / accRoll)) - rawTorque.y, 0); + //adjustTorque.y = Math.Abs(rollTorqueCalc.Update(measuredTorque.y / accRoll) / rawTorque.y); + } + else adjustTorque.y = Math.Abs(rollTorqueCalc.Update(rollTorqueCalc.Mean)); + } + } + + public void UpdateControlParts() + { + if (shared.Vessel.parts.Count != vesselParts) + { + vesselParts = shared.Vessel.parts.Count; + reactionWheelModules.Clear(); + rcsModules.Clear(); + engineModules.Clear(); + gimbalModules.Clear(); + clearEngineRCSVectors(); + foreach (Part part in shared.Vessel.Parts) + { + int engineCount = 0; + ModuleGimbal partGimbal = null; + foreach (PartModule pm in part.Modules) + { + ModuleReactionWheel wheel = pm as ModuleReactionWheel; + if (wheel != null) + { + reactionWheelModules.Add(wheel); + continue; + } + ModuleRCS rcs = pm as ModuleRCS; + if (rcs != null) + { + rcsModules.Add(rcs); + continue; + } + ModuleGimbal gimbal = pm as ModuleGimbal; + if (gimbal != null) + { + partGimbal = gimbal; + if (engineCount > 0) + { + for (int i = 0; i < engineCount; i++) + { + gimbalModules[gimbalModules.Count - i - 1] = gimbal; + } + } + continue; + } + ModuleEngines engine = pm as ModuleEngines; + if (engine != null) + { + engineCount++; + engineModules.Add(engine); + gimbalModules.Add(partGimbal); + } + } + } + } + } + + public void UpdateTorque() + { + // staticTorque will represent engine torque due to imbalanced placement + staticTorque.Zero(); + // controlTorque is the maximum amount of torque applied by setting a control to 1.0. + controlTorque.Zero(); + rawTorque.Zero(); + staticEngineTorque.Zero(); + controlEngineTorque.Zero(); + Vector3d pitchControl = Vector3d.zero; + Vector3d yawControl = Vector3d.zero; + Vector3d rollControl = Vector3d.zero; + + rcsVectors.Clear(); + engineNeutVectors.Clear(); + enginePitchVectors.Clear(); + engineYawVectors.Clear(); + engineRollVectors.Clear(); + + foreach (ModuleReactionWheel wheel in reactionWheelModules) + { + if (wheel.isActiveAndEnabled && wheel.State == ModuleReactionWheel.WheelState.Active) + { + // TODO: Check to see if the component values depend on part orientation, and implement if needed. + rawTorque.x += wheel.PitchTorque; + rawTorque.z += wheel.YawTorque; + rawTorque.y += wheel.RollTorque; + } + } + if (shared.Vessel.ActionGroups[KSPActionGroup.RCS]) + { + foreach (ModuleRCS rcs in rcsModules) + { + if (rcs.rcsEnabled && !rcs.part.ShieldedFromAirstream) + { + for (int i = 0; i < rcs.thrusterTransforms.Count; i++) + { + Transform thrustdir = rcs.thrusterTransforms[i]; + ForceVector force = new ForceVector + { + Force = thrustdir.up * rcs.thrusterPower, + Position = thrustdir.position - centerOfMass, + // We need to adjust the relative center of mass because the rigid body + // will report the position of the parent part + ID = rcs.part.flightID.ToString() + "-" + i.ToString() + }; + Vector3d torque = force.Torque; + rcsVectors.Add(force); + + // component values of the local torque are calculated using the dot product with the rotation axis. + // Only using positive contributions, which is only valid when symmetric placement is assumed + rawTorque.x += Math.Max(Vector3d.Dot(torque, vesselStarboard), 0); + rawTorque.z += Math.Max(Vector3d.Dot(torque, vesselTop), 0); + rawTorque.y += Math.Max(Vector3d.Dot(torque, vesselForward), 0); + } + } + } + } + for (int i = 0; i < engineModules.Count; i++) + { + ModuleEngines engine = engineModules[i]; + ModuleGimbal gimbal = gimbalModules[i]; + if (engine.isActiveAndEnabled && engine.EngineIgnited) + { + // if the engine is active and ignited, calculate torque + float gimbalRange = 0; + List initRots = new List(); + if (gimbal != null && !gimbal.gimbalLock) + { + gimbalRange = gimbal.gimbalRange * gimbal.gimbalLimiter / 100; // grab the gimbal range + + // To determine the neutral thrust vector, we reset the gimbal transform to it's "initial" value + // from the initRots array and then read the direction from the thrustTransform. We do this for + // each gimbal object, and then return them to the previous value after calculating the thrust + // transforms, so that we don't inerupt the gimbal logic. + for (int gblIdx = 0; gblIdx < gimbal.gimbalTransforms.Count; gblIdx++) + { + initRots.Add(gimbal.gimbalTransforms[gblIdx].localRotation); // store the current rotation + gimbal.gimbalTransforms[gblIdx].localRotation = gimbal.initRots[gblIdx]; // set the rotation to the "initial" value + } + } + for (int xfrmIdx = 0; xfrmIdx < engine.thrustTransforms.Count; xfrmIdx++) + { + // iterate through each thrust transform. Some engines have multiple transforms for + // thrust and/or gimbal, so we need to be able to use as many as the part contains. + Transform thrustTransform = engine.thrustTransforms[xfrmIdx]; + Vector3d position = thrustTransform.position; + if (gimbal != null && !gimbal.gimbalLock) + { + Transform gimbalTransform = FindParentTransform(thrustTransform, gimbal.gimbalTransformName, engine.part.transform); + if (gimbalTransform != null) + { + // The gimbal position will not move as the gimbal rotates. As of KSP 1.0.5, the Vector engine appears + // to be the only engine that moves it's thrust transform location, because the transform itself is located + // at the end of the nozzel. Doing so means that our calculated available torque could very well be inaccurate + // specifically in the case of roll torque, where it may appear that an axial engine's thrust transform is offset from the + // vessel's axial centerline when in fact the axial engine can produce no roll torque. + // If there is ever an engine where the thrust transform does not align to the gimbal transform, this assumption + // will no longer be valid. + position = gimbalTransform.position; // use the gimbal position as the thrust position + } + } + Vector3d neut = -engine.thrustTransforms[xfrmIdx].forward * engine.finalThrust / engine.thrustTransforms.Count; // the neutral control thrust (force is opposite of exhaust direction) + Vector3d relCom = position - centerOfMass; + + string id = string.Format("{0}[{1}]", engine.part.flightID, xfrmIdx); + + // calculate the neutral gimbal force vector based on the neutral direction and thrust magnitude + ForceVector neutralForce = new ForceVector + { + Force = neut, + ID = id, + Position = relCom, + }; + engineNeutVectors.Add(neutralForce); + staticEngineTorque += neutralForce.Torque; + if (gimbalRange > EPSILON) // only do the gimbal calculation if the range allows it. + { + Vector3d pitchAxis = Vector3d.Exclude(neut, vesselStarboard); // pitch rotates about the starboard vector + Vector3d yawAxis = Vector3d.Exclude(neut, vesselTop); // yaw rotates about the top vector + Vector3d rollAxis = Vector3d.Exclude(vesselForward, relCom); // roll rotates about the forward vector + ForceVector pitchForce = new ForceVector + { + Force = Quaternion.AngleAxis(gimbalRange, pitchAxis) * neut, + ID = id, + Position = relCom + }; + enginePitchVectors.Add(pitchForce); + pitchControl += pitchForce.Torque; + ForceVector yawForce = new ForceVector + { + Force = Quaternion.AngleAxis(gimbalRange, yawAxis) * neut, + ID = id, + Position = relCom + }; + engineYawVectors.Add(yawForce); + yawControl += yawForce.Torque; + ForceVector rollForce; + + // because of deflection, sometimes an axial engine will look like it can + // generate roll torque when it cannot do so reliably. Ignore small offsets. + if (rollAxis.sqrMagnitude < 0.02) + { + rollForce = neutralForce; + rollForce = new ForceVector + { + Force = neutralForce.Force, + ID = id, + Position = neutralForce.Position + }; + } + else + { + rollForce = new ForceVector + { + Force = Quaternion.AngleAxis(gimbalRange, rollAxis) * neut, + ID = id, + Position = relCom + }; + } + engineRollVectors.Add(rollForce); + rollControl += rollForce.Torque; + } + else + { + // if there is no gimbal available, or it's too small, just clone the neutral thrust vector + enginePitchVectors.Add(new ForceVector + { + Force = neutralForce.Force, + ID = id, + Position = neutralForce.Position + }); + engineYawVectors.Add(new ForceVector + { + Force = neutralForce.Force, + ID = id, + Position = neutralForce.Position + }); + engineRollVectors.Add(new ForceVector + { + Force = neutralForce.Force, + ID = id, + Position = neutralForce.Position + }); + + pitchControl += neutralForce.Torque; + yawControl += neutralForce.Torque; + rollControl += neutralForce.Torque; + } + } + if (gimbal != null && !gimbal.gimbalLock) + { + // Reset each of the gimbal rotations back to their previous values. This prevents + // our calculations from interupting the internal gimbal logic, since some gimbals + // do not rotate instantly. + for (int gblIdx = 0; gblIdx < gimbal.gimbalTransforms.Count; gblIdx++) + { + gimbal.gimbalTransforms[gblIdx].localRotation = initRots[gblIdx]; // set the rotation to the previous value + } + } + } + else + { + // if an engine is disabled, hide the associated vectors (do this for all transforms) + for (int xfrmIdx = 0; xfrmIdx < engine.thrustTransforms.Count; xfrmIdx++) + { + string key = string.Format("{0}[{1}]", engine.part.flightID, xfrmIdx); + if (vEngines.Keys.Contains(key)) + { + vEngines[key].SetShow(false); + vEngines.Remove(key); + } + key = engine.part.flightID.ToString() + "gimbaled"; + if (vEngines.Keys.Contains(key)) + { + vEngines[key].SetShow(false); + vEngines.Remove(key); + } + key = engine.part.flightID.ToString() + "torque"; + if (vEngines.Keys.Contains(key)) + { + vEngines[key].SetShow(false); + vEngines.Remove(key); + } + key = engine.part.flightID.ToString() + "control"; + if (vEngines.Keys.Contains(key)) + { + vEngines[key].SetShow(false); + vEngines.Remove(key); + } + key = engine.part.flightID.ToString() + "position"; + if (vEngines.Keys.Contains(key)) + { + vEngines[key].SetShow(false); + vEngines.Remove(key); + } + } + } + } + + // Because the engines may generate torque about the other 2 axes when trying to rotate about one, + // use a dot product to get the component of the torque in the desired direction. Also subtract out + // the static engine torque, to account for offset placement. This still does not properly balance + // engines that are offset, since the available torque may be drastically different between the + // positive and negative limit. If there is a large static torque, it's also possible for the + // calculation to show that there is a small amount of available torque, even though the static + // torque will actually overpower the control torque. Eventually it would be nice to modify this + // calculation to properly handle asymetric gimbal torque, but for now it will need to be a + // constraint of ship design. + controlEngineTorque.x = Math.Abs(Vector3d.Dot(pitchControl - staticEngineTorque, vesselStarboard)); + controlEngineTorque.z = Math.Abs(Vector3d.Dot(yawControl - staticEngineTorque, vesselTop)); + controlEngineTorque.y = Math.Abs(Vector3d.Dot(rollControl - staticEngineTorque, vesselForward)); + + rawTorque.x += controlEngineTorque.x; + rawTorque.z += controlEngineTorque.z; + rawTorque.y += controlEngineTorque.y; + + rawTorque.x = (rawTorque.x + PitchTorqueAdjust) * PitchTorqueFactor; + rawTorque.z = (rawTorque.z + YawTorqueAdjust) * YawTorqueFactor; + rawTorque.y = (rawTorque.y + RollTorqueAdjust) * RollTorqueFactor; + + controlTorque = rawTorque + adjustTorque; + //controlTorque = Vector3d.Scale(rawTorque, adjustTorque); + //controlTorque = rawTorque; + + double minTorque = EPSILON; + if (controlTorque.x < minTorque) controlTorque.x = minTorque; + if (controlTorque.y < minTorque) controlTorque.y = minTorque; + if (controlTorque.z < minTorque) controlTorque.z = minTorque; + } + + public Transform FindParentTransform(Transform transform, string name, Transform topLevel) + { + if (transform.parent.name == name) return transform.parent; + else if (transform.parent == null) return null; + else if (transform.parent == topLevel) return null; + else return FindParentTransform(transform.parent, name, topLevel); + } + + // Update prediction based on PI controls, sets the target angular velocity and the target torque for the vessel + public void UpdatePredictionPI() + { + // calculate phi and pitch, yaw, roll components of phi (angular error) + phi = Vector3d.Angle(vesselForward, targetForward) / RadToDeg; + if (Vector3d.Angle(vesselTop, targetForward) > 90) + phi *= -1; + phiPitch = Vector3d.Angle(vesselForward, Vector3d.Exclude(vesselStarboard, targetForward)) / RadToDeg; + if (Vector3d.Angle(vesselTop, Vector3d.Exclude(vesselStarboard, targetForward)) > 90) + phiPitch *= -1; + phiYaw = Vector3d.Angle(vesselForward, Vector3d.Exclude(vesselTop, targetForward)) / RadToDeg; + if (Vector3d.Angle(vesselStarboard, Vector3d.Exclude(vesselTop, targetForward)) > 90) + phiYaw *= -1; + phiRoll = Vector3d.Angle(vesselTop, Vector3d.Exclude(vesselForward, targetTop)) / RadToDeg; + if (Vector3d.Angle(vesselStarboard, Vector3d.Exclude(vesselForward, targetTop)) > 90) + phiRoll *= -1; + + // Calculate the maximum allowable angular velocity and apply the limit, something we can stop in a reasonable amount of time + maxPitchOmega = controlTorque.x * MaxStoppingTime / momentOfInertia.x; + maxYawOmega = controlTorque.z * MaxStoppingTime / momentOfInertia.z; + maxRollOmega = controlTorque.y * MaxStoppingTime / momentOfInertia.y; + + double sampletime = shared.UpdateHandler.CurrentFixedTime; + // Because the value of phi is already error, we say the input is -error and the setpoint is 0 so the PID has the correct sign + tgtPitchOmega = pitchRatePI.Update(sampletime, -phiPitch, 0, maxPitchOmega); + tgtYawOmega = yawRatePI.Update(sampletime, -phiYaw, 0, maxYawOmega); + if (Math.Abs(phi) > 5 * Math.PI / 180d) + { + tgtRollOmega = 0; + rollRatePI.ResetI(); + } + else + { + tgtRollOmega = rollRatePI.Update(sampletime, -phiRoll, 0, maxRollOmega); + } + + // Calculate target torque based on PID + tgtPitchTorque = pitchPI.Update(sampletime, omega.x, tgtPitchOmega, momentOfInertia.x, controlTorque.x); + tgtYawTorque = yawPI.Update(sampletime, omega.y, tgtYawOmega, momentOfInertia.z, controlTorque.z); + tgtRollTorque = rollPI.Update(sampletime, omega.z, tgtRollOmega, momentOfInertia.y, controlTorque.y); + + //tgtPitchTorque = pitchPI.Update(sampletime, pitchRate.Update(omega.x), tgtPitchOmega, momentOfInertia.x, controlTorque.x); + //tgtYawTorque = yawPI.Update(sampletime, yawRate.Update(omega.y), tgtYawOmega, momentOfInertia.z, controlTorque.z); + //tgtRollTorque = rollPI.Update(sampletime, rollRate.Update(omega.z), tgtRollOmega, momentOfInertia.y, controlTorque.y); + } + + public void UpdateControl(FlightCtrlState c) + { + if (shared.Vessel.ActionGroups[KSPActionGroup.SAS]) + { + pitchPI.ResetI(); + yawPI.ResetI(); + rollPI.ResetI(); + pitchRatePI.ResetI(); + yawRatePI.ResetI(); + rollRatePI.ResetI(); + Quaternion target = TargetDirection.Rotation * Quaternion.Euler(90, 0, 0); + if (Quaternion.Angle(shared.Vessel.Autopilot.SAS.lockedHeading, target) > 15) + shared.Vessel.Autopilot.SAS.LockHeading(target, true); + else + shared.Vessel.Autopilot.SAS.lockedHeading = target; + } + else + { + //TODO: include adjustment for static torque (due to engines) + double clampAccPitch = Math.Max(Math.Abs(accPitch), 0.005) * 2; + accPitch = tgtPitchTorque / controlTorque.x; + if (Math.Abs(accPitch) < EPSILON) + accPitch = 0; + accPitch = Math.Max(Math.Min(accPitch, clampAccPitch), -clampAccPitch); + c.pitch = (float)accPitch; + double clampAccYaw = Math.Max(Math.Abs(accYaw), 0.005) * 2; + accYaw = tgtYawTorque / controlTorque.z; + if (Math.Abs(accYaw) < EPSILON) + accYaw = 0; + accYaw = Math.Max(Math.Min(accYaw, clampAccYaw), -clampAccYaw); + c.yaw = (float)accYaw; + double clampAccRoll = Math.Max(Math.Abs(accRoll), 0.005) * 2; + accRoll = tgtRollTorque / controlTorque.y; + if (Math.Abs(accRoll) < EPSILON) + accRoll = 0; + accRoll = Math.Max(Math.Min(accRoll, clampAccRoll), -clampAccRoll); + c.roll = (float)accRoll; + } + } + + public void UpdateVectorRenders() + { + if (ShowFacingVectors && enabled) + { + if (vForward == null) + { + vForward = InitVectorRenderer(Color.red, 1, shared); + } + if (vTop == null) + { + vTop = InitVectorRenderer(Color.red, 1, shared); + } + if (vStarboard == null) + { + vStarboard = InitVectorRenderer(Color.red, 1, shared); + } + + vForward.Vector = vesselForward * RENDER_MULTIPLIER; + vTop.Vector = vesselTop * RENDER_MULTIPLIER; + vStarboard.Vector = vesselStarboard * RENDER_MULTIPLIER; + + if (vTgtForward == null) + { + vTgtForward = InitVectorRenderer(Color.blue, 1, shared); + } + if (vTgtTop == null) + { + vTgtTop = InitVectorRenderer(Color.blue, 1, shared); + } + if (vTgtStarboard == null) + { + vTgtStarboard = InitVectorRenderer(Color.blue, 1, shared); + } + + vTgtForward.Vector = targetForward * RENDER_MULTIPLIER * 0.75f; + vTgtTop.Vector = targetTop * RENDER_MULTIPLIER * 0.75f; + vTgtStarboard.Vector = targetStarboard * RENDER_MULTIPLIER * 0.75f; + + if (vWorldX == null) + { + vWorldX = InitVectorRenderer(Color.white, 1, shared); + } + if (vWorldY == null) + { + vWorldY = InitVectorRenderer(Color.white, 1, shared); + } + if (vWorldZ == null) + { + vWorldZ = InitVectorRenderer(Color.white, 1, shared); + } + + vWorldX.Vector = new Vector3d(1, 0, 0) * RENDER_MULTIPLIER * 2; + vWorldY.Vector = new Vector3d(0, 1, 0) * RENDER_MULTIPLIER * 2; + vWorldZ.Vector = new Vector3d(0, 0, 1) * RENDER_MULTIPLIER * 2; + + if (!vForward.GetShow()) vForward.SetShow(true); + if (!vTop.GetShow()) vTop.SetShow(true); + if (!vStarboard.GetShow()) vStarboard.SetShow(true); + + if (!vTgtForward.GetShow()) vTgtForward.SetShow(true); + if (!vTgtTop.GetShow()) vTgtTop.SetShow(true); + if (!vTgtStarboard.GetShow()) vTgtStarboard.SetShow(true); + + if (!vWorldX.GetShow()) vWorldX.SetShow(true); + if (!vWorldY.GetShow()) vWorldY.SetShow(true); + if (!vWorldZ.GetShow()) vWorldZ.SetShow(true); + } + else + { + if (vForward != null) + { + if (vForward.GetShow()) vForward.SetShow(false); + vForward.Dispose(); + vForward = null; + } + if (vTop != null) + { + if (vTop.GetShow()) vTop.SetShow(false); + vTop.Dispose(); + vTop = null; + } + if (vStarboard != null) + { + if (vStarboard.GetShow()) vStarboard.SetShow(false); + vStarboard.Dispose(); + vStarboard = null; + } + + if (vTgtForward != null) + { + if (vTgtForward.GetShow()) vTgtForward.SetShow(false); + vTgtForward.Dispose(); + vTgtForward = null; + } + if (vTgtTop != null) + { + if (vTgtTop.GetShow()) vTgtTop.SetShow(false); + vTgtTop.Dispose(); + vTgtTop = null; + } + if (vTgtStarboard != null) + { + if (vTgtStarboard.GetShow()) vTgtStarboard.SetShow(false); + vTgtStarboard.Dispose(); + vTgtStarboard = null; + } + + if (vWorldX != null) + { + if (vWorldX.GetShow()) vWorldX.SetShow(false); + vWorldX.Dispose(); + vWorldX = null; + } + if (vWorldY != null) + { + if (vWorldY.GetShow()) vWorldY.SetShow(false); + vWorldY.Dispose(); + vWorldY = null; + } + if (vWorldZ != null) + { + if (vWorldZ.GetShow()) vWorldZ.SetShow(false); + vWorldZ.Dispose(); + vWorldZ = null; + } + } + + if (ShowAngularVectors && enabled) + { + if (vOmegaX == null) + { + vOmegaX = InitVectorRenderer(Color.cyan, 1, shared); + } + if (vOmegaY == null) + { + vOmegaY = InitVectorRenderer(Color.cyan, 1, shared); + } + if (vOmegaZ == null) + { + vOmegaZ = InitVectorRenderer(Color.cyan, 1, shared); + } + + vOmegaX.Vector = vesselTop * omega.x * RENDER_MULTIPLIER * 100f; + vOmegaX.Start = vesselForward * RENDER_MULTIPLIER; + vOmegaY.Vector = vesselStarboard * omega.y * RENDER_MULTIPLIER * 100f; + vOmegaY.Start = vesselForward * RENDER_MULTIPLIER; + vOmegaZ.Vector = vesselStarboard * omega.z * RENDER_MULTIPLIER * 100f; + vOmegaZ.Start = vesselTop * RENDER_MULTIPLIER; + + if (vTgtTorqueX == null) + { + vTgtTorqueX = InitVectorRenderer(Color.green, 1, shared); + } + if (vTgtTorqueY == null) + { + vTgtTorqueY = InitVectorRenderer(Color.green, 1, shared); + } + if (vTgtTorqueZ == null) + { + vTgtTorqueZ = InitVectorRenderer(Color.green, 1, shared); + } + + vTgtTorqueX.Vector = vesselTop * tgtPitchOmega * RENDER_MULTIPLIER * 100f; + vTgtTorqueX.Start = vesselForward * RENDER_MULTIPLIER; + //vTgtTorqueX.SetLabel("tgtPitchOmega: " + tgtPitchOmega); + vTgtTorqueY.Vector = vesselStarboard * tgtRollOmega * RENDER_MULTIPLIER * 100f; + vTgtTorqueY.Start = vesselTop * RENDER_MULTIPLIER; + //vTgtTorqueY.SetLabel("tgtRollOmega: " + tgtRollOmega); + vTgtTorqueZ.Vector = vesselStarboard * tgtYawOmega * RENDER_MULTIPLIER * 100f; + vTgtTorqueZ.Start = vesselForward * RENDER_MULTIPLIER; + //vTgtTorqueZ.SetLabel("tgtYawOmega: " + tgtYawOmega); + + if (!vOmegaX.GetShow()) vOmegaX.SetShow(true); + if (!vOmegaY.GetShow()) vOmegaY.SetShow(true); + if (!vOmegaZ.GetShow()) vOmegaZ.SetShow(true); + + if (!vTgtTorqueX.GetShow()) vTgtTorqueX.SetShow(true); + if (!vTgtTorqueY.GetShow()) vTgtTorqueY.SetShow(true); + if (!vTgtTorqueZ.GetShow()) vTgtTorqueZ.SetShow(true); + } + else + { + if (vOmegaX != null) + { + if (vOmegaX.GetShow()) vOmegaX.SetShow(false); + vOmegaX.Dispose(); + vOmegaX = null; + } + if (vOmegaY != null) + { + if (vOmegaY.GetShow()) vOmegaY.SetShow(false); + vOmegaY.Dispose(); + vOmegaY = null; + } + if (vOmegaZ != null) + { + if (vOmegaZ.GetShow()) vOmegaZ.SetShow(false); + vOmegaZ.Dispose(); + vOmegaZ = null; + } + + if (vTgtTorqueX != null) + { + if (vTgtTorqueX.GetShow()) vTgtTorqueX.SetShow(false); + vTgtTorqueX.Dispose(); + vTgtTorqueX = null; + } + if (vTgtTorqueY != null) + { + if (vTgtTorqueY.GetShow()) vTgtTorqueY.SetShow(false); + vTgtTorqueY.Dispose(); + vTgtTorqueY = null; + } + if (vTgtTorqueZ != null) + { + if (vTgtTorqueZ.GetShow()) vTgtTorqueZ.SetShow(false); + vTgtTorqueZ.Dispose(); + vTgtTorqueZ = null; + } + } + + if (ShowThrustVectors && enabled) + { + foreach (var fv in engineNeutVectors) + { + string key = fv.ID; + if (!vEngines.ContainsKey(key)) + { + var vecdraw = InitVectorRenderer(Color.yellow, 0.25, shared); + vEngines.Add(key, vecdraw); + vEngines[key].SetShow(true); + } + vEngines[key].Vector = -fv.Force; + vEngines[key].Start = fv.Position; + + key = fv.ID + "torque"; + if (!vEngines.ContainsKey(key)) + { + var vecdraw = InitVectorRenderer(Color.red, 0.25, shared); + vEngines.Add(key, vecdraw); + vEngines[key].SetShow(true); + } + vEngines[key].Vector = fv.Torque; + vEngines[key].Start = fv.Position; + + key = fv.ID + "position"; + if (!vEngines.ContainsKey(key)) + { + var vecdraw = InitVectorRenderer(Color.cyan, 0.25, shared); + vEngines.Add(key, vecdraw); + vEngines[key].SetShow(true); + } + vEngines[key].Vector = fv.Position; + } + foreach (var fv in engineRollVectors) + { + string key = fv.ID + "gimbaled"; + if (!vEngines.ContainsKey(key)) + { + var vecdraw = InitVectorRenderer(Color.magenta, 0.25, shared); + vEngines.Add(key, vecdraw); + vEngines[key].SetShow(true); + } + vEngines[key].Vector = -fv.Force; + vEngines[key].Start = fv.Position; + + key = fv.ID + "control"; + if (!vEngines.ContainsKey(key)) + { + var vecdraw = InitVectorRenderer(Color.blue, 0.25, shared); + vEngines.Add(key, vecdraw); + vEngines[key].SetShow(true); + } + vEngines[key].Vector = fv.Torque; + vEngines[key].Start = fv.Position; + } + } + else + { + foreach (string key in vEngines.Keys) + { + vEngines[key].SetShow(false); + } + vEngines.Clear(); + } + + if (ShowRCSVectors && enabled && Vessel.ActionGroups[KSPActionGroup.RCS]) + { + foreach (var force in rcsVectors) + { + string key = force.ID; + if (!vRcs.ContainsKey(key)) + { + var vecdraw = InitVectorRenderer(Color.magenta, 0.25, shared); + vecdraw.SetShow(true); + vRcs.Add(key, vecdraw); + } + vRcs[key].Vector = force.Force; + vRcs[key].Start = force.Position; + + key = force.ID + "torque"; + if (!vRcs.ContainsKey(key)) + { + var vecdraw = InitVectorRenderer(Color.yellow, 0.25, shared); + vecdraw.SetShow(true); + vRcs.Add(key, vecdraw); + } + vRcs[key].Vector = force.Torque; + vRcs[key].Start = force.Position; + } + } + else + { + foreach (string key in vRcs.Keys) + { + vRcs[key].SetShow(false); + } + vRcs.Clear(); + } + } + + private void clearEngineRCSVectors() + { + foreach (string key in vEngines.Keys) + { + vEngines[key].SetShow(false); + } + vEngines.Clear(); + foreach (string key in vRcs.Keys) + { + vRcs[key].SetShow(false); + } + vRcs.Clear(); + } + + public void PrintDebug() + { + shared.Screen.ClearScreen(); + shared.Screen.Print(string.Format("phi: {0}", phi * RadToDeg)); + shared.Screen.Print(string.Format("phiRoll: {0}", phiRoll * RadToDeg)); + shared.Screen.Print(" Pitch Values:"); + shared.Screen.Print(string.Format("phiPitch: {0}", phiPitch * RadToDeg)); + //shared.Screen.Print(string.Format("phiPitch: {0}", deltaRotation.eulerAngles.x)); + shared.Screen.Print(string.Format("I pitch: {0}", momentOfInertia.x)); + shared.Screen.Print(string.Format("torque pitch: {0}", controlTorque.x)); + shared.Screen.Print(string.Format("torque gimbal: {0}", controlEngineTorque.x)); + shared.Screen.Print(string.Format("maxPitchOmega: {0}", maxPitchOmega)); + shared.Screen.Print(string.Format("tgtPitchOmega: {0}", tgtPitchOmega)); + shared.Screen.Print(string.Format("pitchOmega: {0}", omega.x)); + shared.Screen.Print(string.Format("tgtPitchTorque: {0}", tgtPitchTorque)); + shared.Screen.Print(string.Format("accPitch: {0}", accPitch)); + shared.Screen.Print(" Yaw Values:"); + shared.Screen.Print(string.Format("phiYaw: {0}", phiYaw * RadToDeg)); + //shared.Screen.Print(string.Format("phiYaw: {0}", deltaRotation.eulerAngles.y)); + shared.Screen.Print(string.Format("I yaw: {0}", momentOfInertia.z)); + shared.Screen.Print(string.Format("torque yaw: {0}", controlTorque.z)); + shared.Screen.Print(string.Format("torque gimbal: {0}", controlEngineTorque.z)); + shared.Screen.Print(string.Format("maxYawOmega: {0}", maxYawOmega)); + shared.Screen.Print(string.Format("tgtYawOmega: {0}", tgtYawOmega)); + shared.Screen.Print(string.Format("yawOmega: {0}", omega.y)); + shared.Screen.Print(string.Format("tgtYawTorque: {0}", tgtYawTorque)); + shared.Screen.Print(string.Format("accYaw: {0}", accYaw)); + shared.Screen.Print(" Roll Values:"); + shared.Screen.Print(string.Format("phiRoll: {0}", phiRoll * RadToDeg)); + //shared.Screen.Print(string.Format("phiRoll: {0}", deltaRotation.eulerAngles.z)); + shared.Screen.Print(string.Format("I roll: {0}", momentOfInertia.y)); + shared.Screen.Print(string.Format("torque roll: {0}", controlTorque.y)); + shared.Screen.Print(string.Format("torque gimbal: {0}", controlEngineTorque.y)); + shared.Screen.Print(string.Format("maxRollOmega: {0}", maxRollOmega)); + shared.Screen.Print(string.Format("tgtRollOmega: {0}", tgtRollOmega)); + shared.Screen.Print(string.Format("rollOmega: {0}", omega.z)); + shared.Screen.Print(string.Format("tgtRollTorque: {0}", tgtRollTorque)); + shared.Screen.Print(string.Format("accRoll: {0}", accRoll)); + shared.Screen.Print(" Processing Stats:"); + shared.Screen.Print(string.Format("Average Duration: {0}", AverageDuration.Mean)); + shared.Screen.Print(string.Format("Based on count: {0}", AverageDuration.ValueCount)); + } + + public void WriteCSVs() + { + if (pitchRateWriter == null) + { + pitchRateWriter = KSP.IO.File.AppendText( + string.Format(FILE_BASE_NAME, fileDateString, shared.Vessel.vesselName, "pitchRate")); + pitchRateWriter.WriteLine("LastSampleTime,Error,ErrorSum,Output,Kp,Ki,Kd,MaxOutput"); + } + if (yawRateWriter == null) + { + yawRateWriter = KSP.IO.File.AppendText( + string.Format(FILE_BASE_NAME, fileDateString, shared.Vessel.vesselName, "yawRate")); + yawRateWriter.WriteLine("LastSampleTime,Error,ErrorSum,Output,Kp,Ki,Kd,MaxOutput"); + } + if (rollRateWriter == null) + { + rollRateWriter = KSP.IO.File.AppendText( + string.Format(FILE_BASE_NAME, fileDateString, shared.Vessel.vesselName, "rollRate")); + rollRateWriter.WriteLine("LastSampleTime,Error,ErrorSum,Output,Kp,Ki,Kd,MaxOutput"); + } + if (pitchTorqueWriter == null) + { + pitchTorqueWriter = KSP.IO.File.AppendText( + string.Format(FILE_BASE_NAME, fileDateString, shared.Vessel.vesselName, "pitchTorque")); + pitchTorqueWriter.WriteLine("LastSampleTime,Input,Setpoint,Error,ErrorSum,Output,Kp,Ki,Tr,Ts,I,MaxOutput"); + } + if (yawTorqueWriter == null) + { + yawTorqueWriter = KSP.IO.File.AppendText( + string.Format(FILE_BASE_NAME, fileDateString, shared.Vessel.vesselName, "yawTorque")); + yawTorqueWriter.WriteLine("LastSampleTime,Input,Setpoint,Error,ErrorSum,Output,Kp,Ki,Tr,Ts,I,MaxOutput"); + } + if (rollTorqueWriter == null) + { + rollTorqueWriter = KSP.IO.File.AppendText( + string.Format(FILE_BASE_NAME, fileDateString, shared.Vessel.vesselName, "rollTorque")); + rollTorqueWriter.WriteLine("LastSampleTime,Input,Setpoint,Error,ErrorSum,Output,Kp,Ki,Tr,Ts,I,MaxOutput"); + } + if (adjustTorqueWriter == null) + { + adjustTorqueWriter = KSP.IO.File.AppendText( + string.Format(FILE_BASE_NAME, fileDateString, shared.Vessel.vesselName, "adjustTorque")); + adjustTorqueWriter.WriteLine("LastSampleTime,Target Pitch,Measured Pitch,Average Adjust Pitch,Raw Pitch,Target Yaw,Measured Yaw,Average Adjust Yaw,Raw Yaw,Target Roll,Measured Roll,Average Adjust Roll,Raw Roll,Samples Roll"); + } + + pitchRateWriter.WriteLine(pitchRatePI.ToCSVString()); + yawRateWriter.WriteLine(yawRatePI.ToCSVString()); + rollRateWriter.WriteLine(rollRatePI.ToCSVString()); + + pitchTorqueWriter.WriteLine(pitchPI.ToCSVString()); + yawTorqueWriter.WriteLine(yawPI.ToCSVString()); + rollTorqueWriter.WriteLine(rollPI.ToCSVString()); + + adjustTorqueWriter.WriteLine(string.Join(",", new[] { + sessionTime.ToString(), + tgtPitchTorque.ToString(), + measuredTorque.x.ToString(), + pitchTorqueCalc.Mean.ToString(), + rawTorque.x.ToString(), + tgtYawTorque.ToString(), + measuredTorque.z.ToString(), + yawTorqueCalc.Mean.ToString(), + rawTorque.z.ToString(), + tgtRollTorque.ToString(), + measuredTorque.y.ToString(), + rollTorqueCalc.Mean.ToString(), + rawTorque.y.ToString(), + rollTorqueCalc.ValueCount.ToString() + })); + } + + public void DisposeVectorRenderers() + { + if (vForward != null) + { + vForward.Dispose(); + vForward = null; + } + if (vTop != null) + { + vTop.Dispose(); + vTop = null; + } + if (vStarboard != null) + { + vStarboard.Dispose(); + vStarboard = null; + } + + if (vTgtForward != null) + { + vTgtForward.Dispose(); + vTgtForward = null; + } + if (vTgtTop != null) + { + vTgtTop.Dispose(); + vTgtTop = null; + } + if (vTgtStarboard != null) + { + vTgtStarboard.Dispose(); + vTgtStarboard = null; + } + + if (vTgtTorqueX != null) + { + vTgtTorqueX.Dispose(); + vTgtTorqueX = null; + } + if (vTgtTorqueY != null) + { + vTgtTorqueY.Dispose(); + vTgtTorqueY = null; + } + if (vTgtTorqueZ != null) + { + vTgtTorqueZ.Dispose(); + vTgtTorqueZ = null; + } + + if (vWorldX != null) + { + vWorldX.Dispose(); + vWorldX = null; + } + if (vWorldY != null) + { + vWorldY.Dispose(); + vWorldY = null; + } + if (vWorldZ != null) + { + vWorldZ.Dispose(); + vWorldZ = null; + } + + if (vOmegaX != null) + { + vOmegaX.Dispose(); + vOmegaX = null; + } + if (vOmegaY != null) + { + vOmegaY.Dispose(); + vOmegaY = null; + } + if (vOmegaZ != null) + { + vOmegaZ.Dispose(); + vOmegaZ = null; + } + + foreach (string key in vEngines.Keys.ToArray()) + { + if (vEngines[key] != null) + { + vEngines[key].SetShow(false); + vEngines[key].Dispose(); + } + vEngines.Remove(key); + } + foreach (string key in vRcs.Keys.ToArray()) + { + if (vRcs[key] != null) + { + vRcs[key].SetShow(false); + vRcs[key].Dispose(); + } + vRcs.Remove(key); + } + } + + public void Dispose() + { + DisposeVectorRenderers(); + + if (pitchRateWriter != null) pitchRateWriter.Dispose(); + if (yawRateWriter != null) yawRateWriter.Dispose(); + if (rollRateWriter != null) rollRateWriter.Dispose(); + + if (pitchTorqueWriter != null) pitchTorqueWriter.Dispose(); + if (yawTorqueWriter != null) yawTorqueWriter.Dispose(); + if (rollTorqueWriter != null) rollTorqueWriter.Dispose(); + + if (adjustTorqueWriter != null) adjustTorqueWriter.Dispose(); + + pitchRateWriter = null; + yawRateWriter = null; + rollRateWriter = null; + + pitchTorqueWriter = null; + yawTorqueWriter = null; + rollTorqueWriter = null; + + adjustTorqueWriter = null; + + SteeringManagerProvider.RemoveInstance(shared.Vessel); + } + + private struct ForceVector + { + public Vector3d Force { get; set; } + + public Vector3d Position { get; set; } + + public Vector3d Torque { get { return Vector3d.Cross(Force, Position); } } + + public string ID { get; set; } + } + + public class TorquePI + { + public PIDLoop Loop { get; set; } + + public double I { get; private set; } + + public MovingAverage TorqueAdjust { get; set; } + + private double tr; + + public double Tr + { + get { return tr; } + set + { + tr = value; + ts = 4.0 * tr / 2.76; + } + } + + private double ts; + + public double Ts + { + get { return ts; } + set + { + ts = value; + tr = 2.76 * ts / 4.0; + } + } + + public TorquePI() + { + Loop = new PIDLoop(); + Ts = 2; + TorqueAdjust = new MovingAverage(); + } + + public double Update(double sampleTime, double input, double setpoint, double momentOfInertia, double maxOutput) + { + I = momentOfInertia; + + Loop.Ki = momentOfInertia * Math.Pow(4.0 / ts, 2); + Loop.Kp = 2 * Math.Pow(momentOfInertia * Loop.Ki, 0.5); + return Loop.Update(sampleTime, input, setpoint, maxOutput); + } + + public void ResetI() + { + Loop.ResetI(); + } + + public override string ToString() + { + return string.Format("TorquePI[Kp:{0}, Ki:{1}, Output:{2}, Error:{3}, ErrorSum:{4}, Tr:{5}, Ts:{6}", + Loop.Kp, Loop.Ki, Loop.Output, Loop.Error, Loop.ErrorSum, Tr, Ts); + } + + public string ToCSVString() + { + return string.Format("{0},{1},{2},{3},{4},{5},{6},{7},{8},{9},{10},{11}", + Loop.LastSampleTime, Loop.Input, Loop.Setpoint, Loop.Error, Loop.ErrorSum, Loop.Output, Loop.Kp, Loop.Ki, Tr, Ts, I, Loop.MaxOutput); + } + } + } +} \ No newline at end of file diff --git a/src/kOS/Binding/SteeringManagerProvider.cs b/src/kOS/Binding/SteeringManagerProvider.cs new file mode 100644 index 000000000..7ab98c6c6 --- /dev/null +++ b/src/kOS/Binding/SteeringManagerProvider.cs @@ -0,0 +1,59 @@ +using System.Collections.Generic; +using System.Linq; + +namespace kOS.Binding +{ + public static class SteeringManagerProvider + { + public static Dictionary AllInstances = new Dictionary(); + public static SteeringManager GetInstance(SharedObjects shared) + { + string key = shared.Vessel.id.ToString(); + if (AllInstances.Keys.Contains(key)) + { + SteeringManager instance = AllInstances[key]; + if (!instance.SubscribedParts.Contains(shared.KSPPart.flightID)) + { + AllInstances[key].SubscribedParts.Add(shared.KSPPart.flightID); + } + return AllInstances[key]; + } + + SteeringManager sm = new SteeringManager(shared); + + sm.SubscribedParts.Add(shared.KSPPart.flightID); + + AllInstances.Add(key, sm); + return sm; + } + + public static void RemoveInstance(Vessel vessel) + { + var id = vessel.id.ToString(); + if (AllInstances.ContainsKey(id)) + { + var instance = AllInstances[id]; + AllInstances.Remove(id); + instance.Dispose(); + } + } + + public static SteeringManager SwapInstance(SharedObjects shared, SteeringManager oldInstance) + { + if (shared.Vessel == oldInstance.Vessel) return oldInstance; + if (oldInstance.SubscribedParts.Contains(shared.KSPPart.flightID)) oldInstance.SubscribedParts.Remove(shared.KSPPart.flightID); + SteeringManager instance = SteeringManager.DeepCopy(oldInstance, shared); + + if (oldInstance.Enabled) + { + if (oldInstance.PartId == shared.KSPPart.flightID) + { + oldInstance.DisableControl(); + instance.EnableControl(shared); + instance.Value = oldInstance.Value; + } + } + return instance; + } + } +} \ No newline at end of file diff --git a/src/kOS/Core.cs b/src/kOS/Core.cs index 45edb7fdd..9952a7204 100644 --- a/src/kOS/Core.cs +++ b/src/kOS/Core.cs @@ -1,43 +1,50 @@ -using UnityEngine; -using kOS.Safe.Encapsulation; +using kOS.Safe.Encapsulation; +using kOS.Safe.Encapsulation.Suffixes; +using kOS.Safe.Persistence; +using kOS.Safe.Utilities; +using kOS.Module; +using kOS.Suffixed; +using kOS.Suffixed.Part; +using kOS.Suffixed.PartModuleField; +using kOS.Utilities; +using System.Linq; namespace kOS { - public class Core : MonoBehaviour + [kOS.Safe.Utilities.KOSNomenclature("Core")] + public class Core : kOSProcessorFields { - public static VersionInfo VersionInfo = new VersionInfo(0, 17, 2); + public static VersionInfo VersionInfo; - public static Core Fetch; - - public void Awake() + static Core() { - // This thing gets instantiated 4 times by KSP for some reason - if (Fetch != null) return; - Fetch = this; - + var ver = typeof(Core).Assembly.GetName().Version; + VersionInfo = new VersionInfo(ver.Major, ver.Minor, ver.Build); } - public void SaveSettings() + public Core(kOSProcessor processor, SharedObjects shared):base(processor, shared) { - //var writer = KSP.IO.BinaryReader.CreateForType(HighLogic.fetch.GameSaveFolder + "/"); + InitializeSuffixes(); } - public static void Debug(string line) + private void InitializeSuffixes() { + AddSuffix("VERSION", new Suffix(() => VersionInfo)); + AddSuffix("VESSEL", new Suffix(() => new VesselTarget(shared.KSPPart.vessel, shared))); + AddSuffix("ELEMENT", new Suffix(GetEelement)); + AddSuffix("CURRENTVOLUME", new Suffix(GetCurrentVolume, "The currently selected volume")); } - void OnGUI() + private ElementValue GetEelement() { + var elList = shared.KSPPart.vessel.PartList("elements", shared); + var part = new PartValue(shared.KSPPart, shared); + return elList.Cast().FirstOrDefault(el => el.Parts.Contains(part)); } - } - - public class CoreInitializer : KSP.Testing.UnitTest - { - public CoreInitializer() + private Volume GetCurrentVolume() { - var gameobject = new GameObject("kOSCore", typeof (Core)); - Object.DontDestroyOnLoad(gameobject); + return shared.VolumeMgr.CurrentVolume; } } -} +} \ No newline at end of file diff --git a/src/kOS/Factories/IFactory.cs b/src/kOS/Factories/IFactory.cs index 3a4fd287f..e1bdad64c 100644 --- a/src/kOS/Factories/IFactory.cs +++ b/src/kOS/Factories/IFactory.cs @@ -1,6 +1,5 @@ using kOS.Safe.Persistence; using kOS.Safe.Screen; -using kOS.Persistence; namespace kOS.Factories { @@ -8,6 +7,6 @@ public interface IFactory { IInterpreter CreateInterpreter(SharedObjects shared); Archive CreateArchive(); - VolumeManager CreateVolumeManager(SharedObjects sharedObjects); + IVolumeManager CreateVolumeManager(SharedObjects sharedObjects); } } diff --git a/src/kOS/Factories/StandardFactory.cs b/src/kOS/Factories/StandardFactory.cs index c1025deba..26b3d790c 100644 --- a/src/kOS/Factories/StandardFactory.cs +++ b/src/kOS/Factories/StandardFactory.cs @@ -1,7 +1,6 @@ using kOS.Safe.Persistence; using kOS.Safe.Screen; using kOS.Screen; -using kOS.Persistence; namespace kOS.Factories { @@ -17,7 +16,7 @@ public Archive CreateArchive() return new Archive(); } - public VolumeManager CreateVolumeManager(SharedObjects sharedObjects) + public IVolumeManager CreateVolumeManager(SharedObjects sharedObjects) { return new VolumeManager(); } diff --git a/src/kOS/Function/BuildList.cs b/src/kOS/Function/BuildList.cs index 2823d7b69..ff14d71a4 100644 --- a/src/kOS/Function/BuildList.cs +++ b/src/kOS/Function/BuildList.cs @@ -4,6 +4,7 @@ using kOS.Safe.Function; using kOS.Suffixed; using kOS.Utilities; +using kOS.Suffixed.PartModuleField; namespace kOS.Function { @@ -18,7 +19,10 @@ public override void Execute(SharedObjects shared) switch (listType) { case "bodies": - list = ListValue.CreateList(FlightGlobals.fetch.bodies); + foreach (CelestialBody cBody in FlightGlobals.fetch.bodies) + { + list.Add(new BodyTarget(cBody, shared)); + } break; case "targets": foreach (var vessel in FlightGlobals.Vessels) @@ -36,11 +40,14 @@ public override void Execute(SharedObjects shared) list = shared.Vessel.PartList(listType, shared); break; case "files": - list = ListValue.CreateList(shared.VolumeMgr.CurrentVolume.GetFileList()); + list = ListValue.CreateList(shared.VolumeMgr.CurrentVolume.FileList.Values.ToList()); break; case "volumes": list = ListValue.CreateList(shared.VolumeMgr.Volumes.Values.ToList()); break; + case "processors": + list = ListValue.CreateList(shared.ProcessorMgr.processors.Values.ToList().Select(processor => PartModuleFieldsFactory.Construct(processor, shared))); + break; default: throw new ArgumentOutOfRangeException(); } diff --git a/src/kOS/Function/FunctionBase.cs b/src/kOS/Function/FunctionBase.cs index 3d4a0cfdb..c9bd25839 100644 --- a/src/kOS/Function/FunctionBase.cs +++ b/src/kOS/Function/FunctionBase.cs @@ -4,6 +4,8 @@ using kOS.Safe.Exceptions; using kOS.Safe.Compilation; using kOS.Safe.Function; +using TimeSpan = kOS.Suffixed.TimeSpan; +using kOS.Safe.Encapsulation; namespace kOS.Function { @@ -20,7 +22,20 @@ public abstract class FunctionBase /// it onto the stack manually, as that would result in a double-push. /// If you decline to set ReturnValue, it will get a default value of zero anyway. /// - public object ReturnValue {get; set;} + public object ReturnValue + { + get + { + // Convert from primitive types to encapsulated types so that functions + // do not explicitly need to return the encapsulated type. + return Structure.FromPrimitive(internalReturn); + } + set + { + internalReturn = value; + } + } + private object internalReturn = 0; // really should be 'null', but kerboscript can't deal with that. /// /// In the *extremely* rare case where a built-in function is NOT supposed to @@ -53,7 +68,7 @@ protected double GetDouble(object argument) } catch(Exception) { - throw new KOSCastException(argument.GetType(),typeof(Double)); + throw new KOSCastException(argument.GetType(),typeof(ScalarValue)); } } @@ -65,7 +80,7 @@ protected int GetInt(object argument) } catch (Exception) { - throw new KOSCastException(argument.GetType(),typeof(Int32)); + throw new KOSCastException(argument.GetType(),typeof(ScalarValue)); } } @@ -89,24 +104,31 @@ protected RgbaColor GetRgba(object argument) throw new KOSCastException(argument.GetType(),typeof(RgbaColor)); } - protected Suffixed.TimeSpan GetTimeSpan(object argument) + protected TimeSpan GetTimeSpan(object argument) { - if (argument is Suffixed.TimeSpan) + var span = argument as TimeSpan; + if (span != null) + { + return span; + } + try { - return argument as Suffixed.TimeSpan; + // Convert to double instead of cast in case the identifier is stored + // as an encapsulated ScalarValue, preventing an unboxing collision. + return new TimeSpan(Convert.ToDouble(argument)); } - if (argument is Double || argument is int || argument is long || argument is float) + catch { - return new Suffixed.TimeSpan( Convert.ToDouble(argument) ); + throw new KOSCastException(argument.GetType(), typeof(TimeSpan)); } - throw new KOSCastException(argument.GetType(),typeof(Suffixed.TimeSpan)); } protected Orbitable GetOrbitable(object argument) { - if (argument is Orbitable) + var orbitable = argument as Orbitable; + if (orbitable != null) { - return argument as Orbitable; + return orbitable; } throw new KOSCastException(argument.GetType(),typeof(Orbitable)); } @@ -133,7 +155,7 @@ protected double RadiansToDegrees(double radians) protected void AssertArgBottomAndConsume(SharedObjects shared) { object shouldBeBottom = shared.Cpu.PopStack(); - if (shouldBeBottom is string && ((string)shouldBeBottom).Equals(OpcodeCall.ARG_MARKER_STRING)) + if (shouldBeBottom != null && shouldBeBottom.GetType() == OpcodeCall.ArgMarkerType) return; // Assert passed. throw new KOSArgumentMismatchException("Too many arguments were passed to " + GetFuncName()); @@ -153,7 +175,7 @@ protected int CountRemainingArgs(SharedObjects shared) while (stillInStack && !found) { object peekItem = shared.Cpu.PeekRaw(depth, out stillInStack); - if (stillInStack && peekItem is string && ((string)peekItem).Equals(OpcodeCall.ARG_MARKER_STRING)) + if (stillInStack && peekItem != null && peekItem.GetType() == OpcodeCall.ArgMarkerType) found = true; else ++depth; @@ -173,7 +195,7 @@ protected int CountRemainingArgs(SharedObjects shared) protected object PopValueAssert(SharedObjects shared, bool barewordOkay = false) { object returnValue = shared.Cpu.PopValue(barewordOkay); - if (returnValue is string && ((string)returnValue).Equals(OpcodeCall.ARG_MARKER_STRING)) + if (returnValue != null && returnValue.GetType() == OpcodeCall.ArgMarkerType) throw new KOSArgumentMismatchException("Too few arguments were passed to " + GetFuncName()); return returnValue; } @@ -187,10 +209,21 @@ protected object PopValueAssert(SharedObjects shared, bool barewordOkay = false) protected object PopStackAssert(SharedObjects shared) { object returnValue = shared.Cpu.PopStack(); - if (returnValue is string && ((string)returnValue).Equals(OpcodeCall.ARG_MARKER_STRING)) + if (returnValue != null && returnValue.GetType() == OpcodeCall.ArgMarkerType) throw new KOSArgumentMismatchException("Too few arguments were passed to " + GetFuncName()); return returnValue; } + + /// + /// Identical to PopValueAssert, but with the additional step of coercing the result + /// into a Structure to be sure, so it won't return primitives. + /// + /// value after coercion into a kOS Structure + protected Structure PopStructureAssertEncapsulated(SharedObjects shared, bool barewordOkay = false) + { + object returnValue = PopValueAssert(shared, barewordOkay); + return Structure.FromPrimitiveWithAssert(returnValue); + } protected string GetFuncName() { diff --git a/src/kOS/Function/HighlightStructure.cs b/src/kOS/Function/HighlightStructure.cs index b3fb9d906..377a2c633 100644 --- a/src/kOS/Function/HighlightStructure.cs +++ b/src/kOS/Function/HighlightStructure.cs @@ -9,6 +9,7 @@ namespace kOS.Function { + [kOS.Safe.Utilities.KOSNomenclature("HIGHLIGHT")] public class HighlightStructure : Structure, IUpdateObserver, IDisposable { private enum HighlightType @@ -43,7 +44,7 @@ private void InitializeSuffixes() color = value; stale = true; })); - AddSuffix("ENABLED", new SetSuffix(() => enabled, value => + AddSuffix("ENABLED", new SetSuffix(() => enabled, value => { enabled = value; stale = true; diff --git a/src/kOS/Function/Math.cs b/src/kOS/Function/Math.cs index 5ae582ff2..7484d0fa8 100644 --- a/src/kOS/Function/Math.cs +++ b/src/kOS/Function/Math.cs @@ -3,6 +3,7 @@ using kOS.Safe.Function; using kOS.Suffixed; using kOS.Safe.Exceptions; +using kOS.Safe.Encapsulation; namespace kOS.Function { @@ -55,24 +56,26 @@ public override void Execute(SharedObjects shared) } } - [Function("roundnearest")] - public class FunctionRoundNearest : FunctionBase - { - public override void Execute(SharedObjects shared) - { - double argument = GetDouble(PopValueAssert(shared)); - AssertArgBottomAndConsume(shared); - double result = Math.Round(argument); - ReturnValue = result; - } - } - [Function("round")] public class FunctionRound : FunctionBase { public override void Execute(SharedObjects shared) { - int decimals = GetInt(PopValueAssert(shared)); + int decimals; + int argCount = CountRemainingArgs(shared); + + switch (argCount) + { + case 1: + decimals = 0; + break; + case 2: + decimals = GetInt(PopValueAssert(shared)); + break; + default: + throw new KOSArgumentMismatchException(new []{1,2}, argCount); + } + double argument = GetDouble(PopValueAssert(shared)); AssertArgBottomAndConsume(shared); double result = Math.Round(argument, decimals); @@ -92,6 +95,7 @@ public override void Execute(SharedObjects shared) } } + [Function("ln")] public class FunctionLn : FunctionBase { @@ -124,9 +128,10 @@ public override void Execute(SharedObjects shared) object argument1 = PopValueAssert(shared); object argument2 = PopValueAssert(shared); AssertArgBottomAndConsume(shared); - - Calculator calculator = Calculator.GetCalculator(argument1, argument2); - object result = calculator.Min(argument1, argument2); + + var pair = new OperandPair(argument1, argument2); + Calculator calculator = Calculator.GetCalculator(pair); + object result = calculator.Min(pair); ReturnValue = result; } } @@ -140,8 +145,9 @@ public override void Execute(SharedObjects shared) object argument2 = PopValueAssert(shared); AssertArgBottomAndConsume(shared); - Calculator calculator = Calculator.GetCalculator(argument1, argument2); - object result = calculator.Max(argument1, argument2); + var pair = new OperandPair(argument1, argument2); + Calculator calculator = Calculator.GetCalculator(pair); + object result = calculator.Max(pair); ReturnValue = result; } } @@ -154,7 +160,7 @@ public class FunctionRandom : FunctionBase public override void Execute(SharedObjects shared) { AssertArgBottomAndConsume(shared); - ReturnValue = random.NextDouble(); + ReturnValue = Structure.FromPrimitive(random.NextDouble()); } } @@ -233,4 +239,29 @@ public override void Execute(SharedObjects shared) throw new KOSException("vector angle calculation attempted with a non-vector value"); } } + + + [Function("char")] + public class FunctionChar : FunctionBase + { + public override void Execute(SharedObjects shared) + { + double argument = GetDouble(PopValueAssert(shared)); + AssertArgBottomAndConsume(shared); + string result = new string((char) argument, 1); + ReturnValue = new StringValue(result); + } + } + + [Function("unchar")] + public class FunctionUnchar : FunctionBase + { + public override void Execute(SharedObjects shared) + { + string argument = PopValueAssert(shared).ToString(); + AssertArgBottomAndConsume(shared); + char result = argument.ToCharArray()[0]; + ReturnValue = ScalarValue.Create(result); + } + } } diff --git a/src/kOS/Function/Misc.cs b/src/kOS/Function/Misc.cs index 4185eb9ca..c9c9d2a85 100644 --- a/src/kOS/Function/Misc.cs +++ b/src/kOS/Function/Misc.cs @@ -1,13 +1,18 @@ -using System; -using System.Collections.Generic; -using kOS.Execution; +using kOS.Execution; using kOS.Safe.Compilation; using kOS.Safe.Exceptions; +using kOS.Safe.Execution; using kOS.Safe.Function; using kOS.Safe.Module; using kOS.Safe.Persistence; -using kOS.Suffixed; using kOS.Safe.Utilities; +using kOS.Suffixed; +using System; +using System.Collections.Generic; +using kOS.Suffixed.PartModuleField; +using kOS.Module; +using kOS.Safe.Compilation.KS; +using kOS.Safe.Encapsulation; namespace kOS.Function { @@ -31,45 +36,49 @@ public override void Execute(SharedObjects shared) shared.Screen.Print(textToPrint); } } - + [Function("hudtext")] public class FunctionHudText : FunctionBase { - public override void Execute (SharedObjects shared) - + public override void Execute(SharedObjects shared) { bool echo = Convert.ToBoolean(PopValueAssert(shared)); RgbaColor rgba = GetRgba(PopValueAssert(shared)); - int size = Convert.ToInt32 (PopValueAssert(shared)); - int style = Convert.ToInt32 (PopValueAssert(shared)); - int delay = Convert.ToInt32 (PopValueAssert(shared)); + int size = Convert.ToInt32(PopValueAssert(shared)); + int style = Convert.ToInt32(PopValueAssert(shared)); + int delay = Convert.ToInt32(PopValueAssert(shared)); string textToHud = PopValueAssert(shared).ToString(); AssertArgBottomAndConsume(shared); - string htmlColour = rgba.ToHexNotation(); + string htmlColour = rgba.ToHexNotation(); switch (style) { case 1: - ScreenMessages.PostScreenMessage("" + textToHud + "",delay,ScreenMessageStyle.UPPER_LEFT); + ScreenMessages.PostScreenMessage("" + textToHud + "", delay, ScreenMessageStyle.UPPER_LEFT); break; + case 2: - ScreenMessages.PostScreenMessage("" + textToHud + "",delay,ScreenMessageStyle.UPPER_CENTER); + ScreenMessages.PostScreenMessage("" + textToHud + "", delay, ScreenMessageStyle.UPPER_CENTER); break; + case 3: - ScreenMessages.PostScreenMessage("" + textToHud + "",delay,ScreenMessageStyle.UPPER_RIGHT); + ScreenMessages.PostScreenMessage("" + textToHud + "", delay, ScreenMessageStyle.UPPER_RIGHT); break; + case 4: - ScreenMessages.PostScreenMessage("" + textToHud + "",delay,ScreenMessageStyle.LOWER_CENTER); + ScreenMessages.PostScreenMessage("" + textToHud + "", delay, ScreenMessageStyle.LOWER_CENTER); break; + default: ScreenMessages.PostScreenMessage("*" + textToHud, 3f, ScreenMessageStyle.UPPER_CENTER); break; } - if (echo) { - shared.Screen.Print ("HUD: " + textToHud); + if (echo) + { + shared.Screen.Print("HUD: " + textToHud); } } } - + [Function("printat")] public class FunctionPrintAt : FunctionBase { @@ -122,7 +131,7 @@ public override void Execute(SharedObjects shared) } else if (!shared.Vessel.isActiveVessel) { - throw new KOSCommandInvalidHere("STAGE", "a non-active SHIP, KSP does not support this", "Core is on the active vessel"); + throw new KOSCommandInvalidHereException(LineCol.Unknown(), "STAGE", "a non-active SHIP, KSP does not support this", "Core is on the active vessel"); } } } @@ -137,18 +146,18 @@ public override void Execute(SharedObjects shared) object volumeId = PopValueAssert(shared, true); string fileName = PopValueAssert(shared, true).ToString(); AssertArgBottomAndConsume(shared); - + // Now the args it is going to be passing on to the program: - List prog_args = new List(); + var progArgs = new List(); int argc = CountRemainingArgs(shared); - for (int i = 0 ; i < argc ; ++i) - prog_args.Add(PopValueAssert(shared, true)); + for (int i = 0; i < argc; ++i) + progArgs.Add(PopValueAssert(shared, true)); AssertArgBottomAndConsume(shared); if (shared.VolumeMgr == null) return; if (shared.VolumeMgr.CurrentVolume == null) throw new Exception("Volume not found"); - ProgramFile file = shared.VolumeMgr.CurrentVolume.GetByName(fileName, true); + VolumeFile file = shared.VolumeMgr.CurrentVolume.Open(fileName, true); if (file == null) throw new Exception(string.Format("File '{0}' not found", fileName)); if (shared.ScriptHandler == null) return; @@ -159,9 +168,9 @@ public override void Execute(SharedObjects shared) { if (shared.ProcessorMgr != null) { - string filePath = string.Format("{0}/{1}", shared.VolumeMgr.GetVolumeRawIdentifier(targetVolume), fileName) ; - var options = new CompilerOptions {LoadProgramsInSameAddressSpace = true, FuncManager = shared.FunctionManager}; - List parts = shared.ScriptHandler.Compile(filePath, 1, file.StringContent, "program", options); + string filePath = string.Format("{0}/{1}", shared.VolumeMgr.GetVolumeRawIdentifier(targetVolume), fileName); + var options = new CompilerOptions { LoadProgramsInSameAddressSpace = true, FuncManager = shared.FunctionManager }; + List parts = shared.ScriptHandler.Compile(filePath, 1, file.ReadAll().String, "program", options); var builder = new ProgramBuilder(); builder.AddRange(parts); List program = builder.BuildProgram(); @@ -177,23 +186,24 @@ public override void Execute(SharedObjects shared) { // clear the "program" compilation context shared.ScriptHandler.ClearContext("program"); - string filePath = shared.VolumeMgr.GetVolumeRawIdentifier(shared.VolumeMgr.CurrentVolume) + "/" + fileName ; - var options = new CompilerOptions {LoadProgramsInSameAddressSpace = true, FuncManager = shared.FunctionManager}; + string filePath = shared.VolumeMgr.GetVolumeRawIdentifier(shared.VolumeMgr.CurrentVolume) + "/" + fileName; + var options = new CompilerOptions { LoadProgramsInSameAddressSpace = true, FuncManager = shared.FunctionManager }; var programContext = ((CPU)shared.Cpu).SwitchToProgramContext(); List codeParts; - if (file.Category == FileCategory.KSM) + FileContent content = file.ReadAll(); + if (content.Category == FileCategory.KSM) { string prefix = programContext.Program.Count.ToString(); - codeParts = shared.VolumeMgr.CurrentVolume.LoadObjectFile(filePath, prefix, file.BinaryContent); + codeParts = content.AsParts(fileName, prefix); } else { - try + try { - codeParts = shared.ScriptHandler.Compile(filePath, 1, file.StringContent, "program", options); + codeParts = shared.ScriptHandler.Compile(filePath, 1, content.String, "program", options); } - catch (Exception e) + catch (Exception) { // If it died due to a compile error, then we won't really be able to switch to program context // as was implied by calling Cpu.SwitchToProgramContext() up above. The CPU needs to be @@ -205,17 +215,18 @@ public override void Execute(SharedObjects shared) } programContext.AddParts(codeParts); } - + // Because run() returns FIRST, and THEN the CPU jumps to the new program's first instruction that it set up, - // it needs to put the return stack in a weird order. Its return value needs to be buried UNDER the args to the + // it needs to put the return stack in a weird order. Its return value needs to be buried UNDER the args to the // program it's calling: UsesAutoReturn = false; - + shared.Cpu.PushStack(0); // dummy return that all functions have. // Put the args for the program being called back on in the same order they were in before (so read the list backward): - for (int i = argc-1 ; i >= 0 ; --i) - shared.Cpu.PushStack(prog_args[i]); + shared.Cpu.PushStack(new KOSArgMarkerType()); + for (int i = argc - 1; i >= 0; --i) + shared.Cpu.PushStack(progArgs[i]); } } @@ -242,15 +253,16 @@ public override void Execute(SharedObjects shared) topStack = PopValueAssert(shared, true); if (topStack != null) fileName = topStack.ToString(); - + AssertArgBottomAndConsume(shared); if (fileName == null) throw new KOSFileException("No filename to load was given."); - - ProgramFile file = shared.VolumeMgr.CurrentVolume.GetByName(fileName, (! justCompiling)); // if running, look for KSM first. If compiling look for KS first. + + VolumeFile file = shared.VolumeMgr.CurrentVolume.Open(fileName, !justCompiling); // if running, look for KSM first. If compiling look for KS first. if (file == null) throw new KOSFileException(string.Format("Can't find file '{0}'.", fileName)); - fileName = file.Filename; // just in case GetByName picked an extension that changed it. + fileName = file.Name; // just in case GetByName picked an extension that changed it. + FileContent fileContent = file.ReadAll(); // filename is now guaranteed to have an extension. To make default output name, replace the extension with KSM: if (defaultOutput) @@ -270,21 +282,25 @@ public override void Execute(SharedObjects shared) // or to a file to save: if (justCompiling) { - List compileParts = shared.ScriptHandler.Compile(filePath, 1, file.StringContent, String.Empty, options); - shared.VolumeMgr.CurrentVolume.SaveObjectFile(fileNameOut, compileParts); + List compileParts = shared.ScriptHandler.Compile(filePath, 1, fileContent.String, string.Empty, options); + VolumeFile volumeFile = shared.VolumeMgr.CurrentVolume.Save(fileNameOut, new FileContent(compileParts)); + if (volumeFile == null) + { + throw new KOSFileException("Can't save compiled file: not enough space or access forbidden"); + } } else { var programContext = ((CPU)shared.Cpu).SwitchToProgramContext(); List parts; - if (file.Category == FileCategory.KSM) + if (fileContent.Category == FileCategory.KSM) { string prefix = programContext.Program.Count.ToString(); - parts = shared.VolumeMgr.CurrentVolume.LoadObjectFile(filePath, prefix, file.BinaryContent); + parts = fileContent.AsParts(filePath, prefix); } else { - parts = shared.ScriptHandler.Compile(filePath, 1, file.StringContent, "program", options); + parts = shared.ScriptHandler.Compile(filePath, 1, fileContent.String, "program", options); } int programAddress = programContext.AddObjectParts(parts); // push the entry point address of the new program onto the stack @@ -330,7 +346,12 @@ public override void Execute(SharedObjects shared) Volume volume = shared.VolumeMgr.CurrentVolume; if (volume != null) { - volume.AppendToFile(fileName, expressionResult); + VolumeFile volumeFile = volume.OpenOrCreate(fileName); + + if (volumeFile == null || !volumeFile.WriteLn(expressionResult)) + { + throw new KOSFileException("Can't append to file: not enough space or access forbidden"); + } } else { @@ -350,6 +371,7 @@ public override void Execute(SharedObjects shared) AssertArgBottomAndConsume(shared); // not sure if this matters when rebooting anwyway. shared.Processor.SetMode(ProcessorModes.OFF); shared.Processor.SetMode(ProcessorModes.READY); + ((CPU)shared.Cpu).GetCurrentOpcode().AbortProgram = true; } } } @@ -361,6 +383,7 @@ public override void Execute(SharedObjects shared) { AssertArgBottomAndConsume(shared); // not sure if this matters when shutting down anwyway. if (shared.Processor != null) shared.Processor.SetMode(ProcessorModes.OFF); + ((CPU)shared.Cpu).GetCurrentOpcode().AbortProgram = true; } } @@ -373,4 +396,106 @@ public override void Execute(SharedObjects shared) ReturnValue = shared.Cpu.DumpVariables(); } } + + [Function("warpto")] + public class WarpTo : FunctionBase + { + public override void Execute(SharedObjects shared) + { + // TODO: As of KSP v1.0.2, the maxTimeWarping and minTimeWarping parameters behave as time limiters, not actual warp limiters + int args = CountRemainingArgs(shared); + double ut; + switch (args) + { + case 1: + ut = GetDouble(PopValueAssert(shared)); + break; + + default: + throw new KOSArgumentMismatchException(new[] { 1 }, args); + } + AssertArgBottomAndConsume(shared); + TimeWarp.fetch.WarpTo(ut); + } + } + + [Function("processor")] + public class FunctionProcessor : FunctionBase + { + public override void Execute(SharedObjects shared) + { + object processorTagOrVolume = PopValueAssert(shared, true); + AssertArgBottomAndConsume(shared); + + kOSProcessor processor; + + if (processorTagOrVolume is Volume) { + processor = shared.ProcessorMgr.GetProcessor(processorTagOrVolume as Volume); + } else if (processorTagOrVolume is string || processorTagOrVolume is StringValue) { + processor = shared.ProcessorMgr.GetProcessor(processorTagOrVolume.ToString()); + } else { + throw new KOSInvalidArgumentException("processor", "processorId", "String or Volume expected"); + } + + if (processor == null) + { + throw new KOSInvalidArgumentException("processor", "processorId", "Processor with that volume or name was not found"); + } + + ReturnValue = PartModuleFieldsFactory.Construct(processor, shared); + } + } + + [Function("pidloop")] + public class PIDLoopConstructor : FunctionBase + { + public override void Execute(SharedObjects shared) + { + int args = CountRemainingArgs(shared); + double kd; + double ki; + double kp; + double maxoutput; + double minoutput; + switch (args) + { + case 0: + this.ReturnValue = new PIDLoop(); + break; + case 1: + kp = GetDouble(PopValueAssert(shared)); + this.ReturnValue = new PIDLoop(kp, 0, 0); + break; + case 3: + kd = GetDouble(PopValueAssert(shared)); + ki = GetDouble(PopValueAssert(shared)); + kp = GetDouble(PopValueAssert(shared)); + this.ReturnValue = new PIDLoop(kp, ki, kd); + break; + case 5: + maxoutput = GetDouble(PopValueAssert(shared)); + minoutput = GetDouble(PopValueAssert(shared)); + kd = GetDouble(PopValueAssert(shared)); + ki = GetDouble(PopValueAssert(shared)); + kp = GetDouble(PopValueAssert(shared)); + this.ReturnValue = new PIDLoop(kp, ki, kd, maxoutput, minoutput); + break; + default: + throw new KOSArgumentMismatchException(new[] { 0, 1, 3, 5 }, args); + } + AssertArgBottomAndConsume(shared); + } + } + + [Function("makebuiltindelegate")] + public class MakeBuiltinDelegate : FunctionBase + { + public override void Execute(SharedObjects shared) + { + string name = PopValueAssert(shared).ToString(); + AssertArgBottomAndConsume(shared); + + ReturnValue = new BuiltinDelegate(shared.Cpu, name); + } + } } diff --git a/src/kOS/Function/Persistence.cs b/src/kOS/Function/Persistence.cs index 9d953a276..75cab0d85 100644 --- a/src/kOS/Function/Persistence.cs +++ b/src/kOS/Function/Persistence.cs @@ -1,8 +1,11 @@ -using System; +using kOS.Safe.Encapsulation; +using kOS.Safe.Exceptions; using kOS.Safe.Function; using kOS.Safe.Persistence; +using kOS.Safe.Serialization; using kOS.Safe.Utilities; -using KSP.IO; +using kOS.Serialization; +using System; namespace kOS.Function { @@ -16,7 +19,7 @@ public override void Execute(SharedObjects shared) if (shared.VolumeMgr != null) { - Volume volume = shared.VolumeMgr.GetVolume(volumeId); + Volume volume = volumeId is Volume ? volumeId as Volume : shared.VolumeMgr.GetVolume(volumeId); if (volume != null) { shared.VolumeMgr.SwitchTo(volume); @@ -28,7 +31,7 @@ public override void Execute(SharedObjects shared) } } } - + [Function("edit")] public class FunctionEdit : FunctionBase { @@ -37,13 +40,11 @@ public override void Execute(SharedObjects shared) string fileName = PopValueAssert(shared, true).ToString(); AssertArgBottomAndConsume(shared); - // If no filename extension, then give it one: - fileName = PersistenceUtilities.CookedFilename(fileName, Volume.KERBOSCRIPT_EXTENSION); - if (shared.VolumeMgr != null) { Volume vol = shared.VolumeMgr.CurrentVolume; - shared.Window.OpenPopupEditor( vol, fileName ); + var volumeFile = vol.OpenOrCreate(fileName); + shared.Window.OpenPopupEditor(vol, volumeFile.Name); } } } @@ -67,13 +68,13 @@ public override void Execute(SharedObjects shared) if (direction == "from") { - origin = shared.VolumeMgr.GetVolume(volumeId); + origin = volumeId is Volume ? volumeId as Volume : shared.VolumeMgr.GetVolume(volumeId); destination = shared.VolumeMgr.CurrentVolume; } else { origin = shared.VolumeMgr.CurrentVolume; - destination = shared.VolumeMgr.GetVolume(volumeId); + destination = volumeId is Volume ? volumeId as Volume : shared.VolumeMgr.GetVolume(volumeId); } if (origin != null && destination != null) @@ -83,10 +84,10 @@ public override void Execute(SharedObjects shared) throw new Exception("Cannot copy from a volume to the same volume."); } - ProgramFile file = origin.GetByName(fileName); + VolumeFile file = origin.Open(fileName); if (file != null) { - if (!destination.SaveFile(new ProgramFile(file))) + if (destination.Save(file.Name, file.ReadAll()) == null) { throw new Exception("File copy failed"); } @@ -110,7 +111,8 @@ public class FunctionRename : FunctionBase public override void Execute(SharedObjects shared) { string newName = PopValueAssert(shared, true).ToString(); - object oldName = PopValueAssert(shared, true); + // old file name or, when we're renaming a volume, the old volume name or Volume instance + object volumeIdOrOldName = PopValueAssert(shared, true); string objectToRename = PopValueAssert(shared).ToString(); AssertArgBottomAndConsume(shared); @@ -121,11 +123,11 @@ public override void Execute(SharedObjects shared) Volume volume = shared.VolumeMgr.CurrentVolume; if (volume != null) { - if (volume.GetByName(newName) == null) + if (volume.Open(newName) == null) { - if (!volume.RenameFile(oldName.ToString(), newName)) + if (!volume.RenameFile(volumeIdOrOldName.ToString(), newName)) { - throw new Exception(string.Format("File '{0}' not found", oldName)); + throw new Exception(string.Format("File '{0}' not found", volumeIdOrOldName)); } } else @@ -140,7 +142,7 @@ public override void Execute(SharedObjects shared) } else { - Volume volume = shared.VolumeMgr.GetVolume(oldName); + Volume volume = volumeIdOrOldName is Volume ? volumeIdOrOldName as Volume : shared.VolumeMgr.GetVolume(volumeIdOrOldName); if (volume != null) { if (volume.Renameable) @@ -172,11 +174,11 @@ public override void Execute(SharedObjects shared) if (shared.VolumeMgr != null) { - Volume volume = volumeId != null ? shared.VolumeMgr.GetVolume(volumeId) : shared.VolumeMgr.CurrentVolume; + Volume volume = volumeId != null ? (volumeId is Volume ? volumeId as Volume : shared.VolumeMgr.GetVolume(volumeId)) : shared.VolumeMgr.CurrentVolume; if (volume != null) { - if (!volume.DeleteByName(fileName)) + if (!volume.Delete(fileName)) { throw new Exception(string.Format("File '{0}' not found", fileName)); } @@ -188,4 +190,95 @@ public override void Execute(SharedObjects shared) } } } -} + + [Function("writejson")] + public class FunctionWriteJson : FunctionBase + { + public override void Execute(SharedObjects shared) + { + string fileName = PopValueAssert(shared, true).ToString(); + SerializableStructure serialized = PopValueAssert(shared, true) as SerializableStructure; + AssertArgBottomAndConsume(shared); + + if (serialized == null) + { + throw new KOSException("This type is not serializable"); + } + + string serializedString = new SerializationMgr(shared).Serialize(serialized, JsonFormatter.WriterInstance); + + FileContent fileContent = new FileContent(serializedString); + + if (shared.VolumeMgr != null) + { + shared.VolumeMgr.CurrentVolume.Save(fileName, fileContent); + } + } + } + + [Function("readjson")] + public class FunctionReadJson : FunctionBase + { + public override void Execute(SharedObjects shared) + { + string fileName = PopValueAssert(shared, true).ToString(); + AssertArgBottomAndConsume(shared); + + VolumeFile volumeFile = shared.VolumeMgr.CurrentVolume.Open(fileName); + + if (volumeFile == null) + { + throw new KOSException("File does not exist: " + fileName); + } + + object read = new SerializationMgr(shared).Deserialize(volumeFile.ReadAll().String, JsonFormatter.ReaderInstance); + + ReturnValue = read; + } + } + + [Function("exists")] + public class FunctionExists : FunctionBase + { + public override void Execute(SharedObjects shared) + { + string fileName = PopValueAssert(shared, true).ToString(); + AssertArgBottomAndConsume(shared); + + ReturnValue = shared.VolumeMgr.CurrentVolume.Exists(fileName); + } + } + + [Function("open")] + public class FunctionOpen : FunctionBase + { + public override void Execute(SharedObjects shared) + { + string fileName = PopValueAssert(shared, true).ToString(); + AssertArgBottomAndConsume(shared); + + VolumeFile volumeFile = shared.VolumeMgr.CurrentVolume.Open(fileName); + + if (volumeFile == null) + { + throw new KOSException("File does not exist: " + fileName); + } + + ReturnValue = volumeFile; + } + } + + [Function("create")] + public class FunctionCreate : FunctionBase + { + public override void Execute(SharedObjects shared) + { + string fileName = PopValueAssert(shared, true).ToString(); + AssertArgBottomAndConsume(shared); + + VolumeFile volumeFile = shared.VolumeMgr.CurrentVolume.Create(fileName); + + ReturnValue = volumeFile; + } + } +} \ No newline at end of file diff --git a/src/kOS/Function/PrintList.cs b/src/kOS/Function/PrintList.cs index a40c299d9..f22c770e1 100644 --- a/src/kOS/Function/PrintList.cs +++ b/src/kOS/Function/PrintList.cs @@ -1,11 +1,15 @@ -using System; -using System.Collections.Generic; -using System.Text; +using kOS.Module; using kOS.Safe.Encapsulation; +using kOS.Safe.Encapsulation.Suffixes; using kOS.Safe.Function; using kOS.Safe.Persistence; using kOS.Suffixed; +using kOS.Suffixed.Part; +using System; +using System.Collections.Generic; +using System.Text; using kOS.Utilities; +using Math = System.Math; namespace kOS.Function { @@ -26,30 +30,43 @@ public override void Execute(SharedObjects shared) case "files": list = GetFileList(shared); break; + case "volumes": list = GetVolumeList(shared); break; + + case "processors": + list = GetProcessorList(shared); + break; + case "bodies": list = GetBodyList(shared); break; + case "targets": list = GetTargetList(shared); break; + case "resources": list = GetResourceList(shared); break; + case "parts": list = GetPartList(shared); break; + case "engines": list = GetEngineList(shared); break; + case "sensors": list = GetSensorList(shared); break; + case "config": list = GetConfigList(); break; + default: throw new Exception("List type not supported"); } @@ -62,7 +79,7 @@ public override void Execute(SharedObjects shared) } } - private kList GetFileList(SharedObjects shared) + private kList GetFileList(Safe.SharedObjects shared) { var list = new kList(); list.AddColumn("Name", 30, ColumnAlignment.Left); @@ -74,36 +91,54 @@ private kList GetFileList(SharedObjects shared) if (volume != null) { list.Title = "Volume " + shared.VolumeMgr.GetVolumeBestIdentifier(volume); - - foreach (FileInfo info in volume.GetFileList()) + + foreach (KeyValuePair pair in volume.FileList) { - list.AddItem(info.Name, info.Size); + list.AddItem(pair.Key, pair.Value.Size); } - int freeSpace = volume.GetFreeSpace(); - list.Footer = "Free space remaining: " + (freeSpace > -1 ? freeSpace.ToString() : " infinite"); + long freeSpace = volume.FreeSpace; + list.Footer = "Free space remaining: " + (freeSpace != Volume.INFINITE_CAPACITY ? freeSpace.ToString() : " infinite"); } } return list; } - private kList GetVolumeList(SharedObjects shared) + private kList GetVolumeList(Safe.SharedObjects shared) { - var list = new kList {Title = "Volumes"}; + var list = new kList { Title = "Volumes" }; list.AddColumn("ID", 6, ColumnAlignment.Left); list.AddColumn("Name", 24, ColumnAlignment.Left); list.AddColumn("Size", 7, ColumnAlignment.Right); - if (shared.VolumeMgr != null) + if (shared.VolumeMgr == null) return list; + + foreach (KeyValuePair kvp in shared.VolumeMgr.Volumes) { - foreach (KeyValuePair kvp in shared.VolumeMgr.Volumes) - { - Volume volume = kvp.Value; - string id = kvp.Key.ToString() + (shared.VolumeMgr.VolumeIsCurrent(volume) ? "*" : ""); - string size = volume.Capacity.ToString(); - list.AddItem(id, volume.Name, size); - } + Volume volume = kvp.Value; + string id = kvp.Key.ToString() + (shared.VolumeMgr.VolumeIsCurrent(volume) ? "*" : ""); + string size = volume.Capacity.ToString(); + list.AddItem(id, volume.Name, size); + } + + return list; + } + + private kList GetProcessorList(SharedObjects shared) + { + var list = new kList { Title = "Processors" }; + list.AddColumn("Name", 16, ColumnAlignment.Left); + list.AddColumn("Tag", 12, ColumnAlignment.Left); + list.AddColumn("Volume ID", 6, ColumnAlignment.Left); + + if (shared.VolumeMgr == null) return list; + + foreach (kOSProcessor processor in shared.ProcessorMgr.processors.Values) + { + string name = processor.name + (shared.Processor == processor ? "*" : ""); + int volumeId = shared.VolumeMgr.GetVolumeId(processor.HardDisk); + list.AddItem(name, processor.Tag, volumeId); } return list; @@ -114,7 +149,7 @@ private kList GetBodyList(SharedObjects shared) var list = new kList(); list.AddColumn("Name", 15, ColumnAlignment.Left); list.AddColumn("Distance", 22, ColumnAlignment.Right, "0"); - + foreach (var body in FlightGlobals.fetch.bodies) { list.AddItem(body.bodyName, Vector3d.Distance(body.position, shared.Vessel.findWorldCenterOfMass())); @@ -131,11 +166,10 @@ private kList GetTargetList(SharedObjects shared) foreach (Vessel vessel in FlightGlobals.Vessels) { - if (vessel != shared.Vessel) - { - var vT = new VesselTarget(vessel, shared); - list.AddItem(vT.Vessel.vesselName, vT.GetDistance()); - } + if (vessel == shared.Vessel) continue; + + var vT = new VesselTarget(vessel, shared); + list.AddItem(vT.Vessel.vesselName, vT.GetDistance()); } return list; @@ -175,7 +209,7 @@ private kList GetResourceList(SharedObjects shared) list.AddItem(stageStr, resourceName, kvp.Value); } - + return list; } @@ -200,20 +234,12 @@ private kList GetEngineList(SharedObjects shared) list.AddColumn("Stage", 8, ColumnAlignment.Left); list.AddColumn("Name", 28, ColumnAlignment.Left); - foreach (Part part in VesselUtils.GetListOfActivatedEngines(shared.Vessel)) - { - foreach (PartModule module in part.Modules) - { - var engineMod = module as ModuleEngines; - if (engineMod != null) { - list.AddItem(part.uid(), part.inverseStage, engineMod.moduleName); - } + ListValue partList = EngineValue.PartsToList(shared.Vessel.Parts, shared); - var engineModFx = module as ModuleEnginesFX; - if (engineModFx != null) { - list.AddItem(part.uid(), part.inverseStage, engineModFx.moduleName); - } - } + foreach (Structure structure in partList) + { + var part = (PartValue) structure; + list.AddItem(part.Part.uid(), part.Part.inverseStage, part.Part.partInfo.name); } return list; @@ -250,12 +276,11 @@ private kList GetConfigList() foreach (ConfigKey key in Config.Instance.GetConfigKeys()) { list.AddItem(key.Alias, key.Name, key.Value); - } + } return list; } - #region List class private class kList @@ -299,7 +324,7 @@ private void BuildFormatString() string alignment = columns[index].Alignment == ColumnAlignment.Left ? "-" : ""; string separator; - if (index < (columns.Count - 1)) + if (index < columns.Count - 1) { columns[index].ItemWidth = columns[index].Width - 1; separator = " "; @@ -342,7 +367,7 @@ fields[index] is double || { field = fields[index].ToString(); } - + stringFields[index] = field.Substring(0, Math.Min(columns[index].ItemWidth, field.Length)); } @@ -389,12 +414,16 @@ public kListColumn(string title, int width, ColumnAlignment alignment, string fo } public string Title { get; private set; } + public int Width { get; private set; } + public int ItemWidth { get; set; } + public ColumnAlignment Alignment { get; private set; } + public string Format { get; private set; } } - #endregion + #endregion List class } -} +} \ No newline at end of file diff --git a/src/kOS/Function/Suffixed.cs b/src/kOS/Function/Suffixed.cs index 753b2b8d4..d6d93acc5 100644 --- a/src/kOS/Function/Suffixed.cs +++ b/src/kOS/Function/Suffixed.cs @@ -8,6 +8,7 @@ using kOS.Suffixed; using kOS.Utilities; using FinePrint; +using kOS.Safe; namespace kOS.Function { @@ -188,15 +189,93 @@ public class FunctionList : FunctionBase { public override void Execute(SharedObjects shared) { - object[] argArray = new object[CountRemainingArgs(shared)]; + Structure[] argArray = new Structure[CountRemainingArgs(shared)]; for (int i = argArray.Length - 1 ; i >= 0 ; --i) - argArray[i] = PopValueAssert(shared); // fill array in reverse order because .. stack args. + argArray[i] = PopStructureAssertEncapsulated(shared); // fill array in reverse order because .. stack args. AssertArgBottomAndConsume(shared); var listValue = new ListValue(argArray.ToList()); ReturnValue = listValue; } } + [Function("queue")] + public class FunctionQueue : FunctionBase + { + public override void Execute(SharedObjects shared) + { + Structure[] argArray = new Structure[CountRemainingArgs(shared)]; + for (int i = argArray.Length - 1 ; i >= 0 ; --i) + argArray[i] = PopStructureAssertEncapsulated(shared); // fill array in reverse order because .. stack args. + AssertArgBottomAndConsume(shared); + var queueValue = new QueueValue(argArray.ToList()); + ReturnValue = queueValue; + } + } + + [Function("stack")] + public class FunctionStack : FunctionBase + { + public override void Execute(SharedObjects shared) + { + Structure[] argArray = new Structure[CountRemainingArgs(shared)]; + for (int i = argArray.Length - 1 ; i >= 0 ; --i) + argArray[i] = PopStructureAssertEncapsulated(shared); // fill array in reverse order because .. stack args. + AssertArgBottomAndConsume(shared); + var stackValue = new StackValue(argArray.ToList()); + ReturnValue = stackValue; + } + } + + [Function("range")] + public class FunctionRange : FunctionBase + { + public override void Execute(SharedObjects shared) + { + // Default values for parameters + int from = RangeValue.DEFAULT_START; + int to = RangeValue.DEFAULT_STOP; + int step = RangeValue.DEFAULT_STEP; + + int argCount = CountRemainingArgs(shared); + // assign parameter values from the stack, pop them in reverse order + switch (argCount) + { + case 1: + to = GetInt(PopStructureAssertEncapsulated(shared)); + break; + case 2: + to = GetInt(PopStructureAssertEncapsulated(shared)); + from = GetInt(PopStructureAssertEncapsulated(shared)); + break; + case 3: + step = GetInt(PopStructureAssertEncapsulated(shared)); + to = GetInt(PopStructureAssertEncapsulated(shared)); + from = GetInt(PopStructureAssertEncapsulated(shared)); + break; + default: + throw new KOSArgumentMismatchException(new int[] { 1, 2, 3 }, argCount, "Thrown from function RANGE()"); + } + AssertArgBottomAndConsume(shared); + + ReturnValue = new RangeValue(from, to, step); + } + } + + [Function("lex", "lexicon")] + public class FunctionLexicon : FunctionBase + { + public override void Execute(SharedObjects shared) + { + + Structure[] argArray = new Structure[CountRemainingArgs(shared)]; + for (int i = argArray.Length - 1 ; i >= 0 ; --i) + argArray[i] = PopStructureAssertEncapsulated(shared); // fill array in reverse order because .. stack args. + AssertArgBottomAndConsume(shared); + var lexicon = new Lexicon(argArray.ToList()); + ReturnValue = lexicon; + } + } + [Function("hsv")] public class FunctionHsv : FunctionBase { @@ -265,45 +344,28 @@ public class FunctionVecDrawNull : FunctionBase public override void Execute(SharedObjects shared) { int argc = CountRemainingArgs(shared); - // If I was called with arguments, then run the version of the constructor that takes args - if (argc == 6) - { - bool show = Convert.ToBoolean(PopValueAssert(shared)); - double scale = GetDouble(PopValueAssert(shared)); - string str = PopValueAssert(shared).ToString(); - RgbaColor rgba = GetRgba(PopValueAssert(shared)); - Vector vec = GetVector(PopValueAssert(shared)); - Vector start = GetVector(PopValueAssert(shared)); - AssertArgBottomAndConsume(shared); - DoExecuteWork(shared, start, vec, rgba, str, scale, show); - } - else if (argc == 0) - { - AssertArgBottomAndConsume(shared); // no args - DoExecuteWork(shared); // default constructor: - } - else - { - throw new KOSArgumentMismatchException("Vecdraw() expected either 0 or 6 arguments passed, but got " + argc +" instead."); - } + + // Handle the var args that might be passed in, or give defaults if fewer args: + double width = (argc >= 7) ? GetDouble(PopValueAssert(shared)) : 0.2; + bool show = (argc >= 6) ? Convert.ToBoolean(PopValueAssert(shared)) : false; + double scale = (argc >= 5) ? GetDouble(PopValueAssert(shared)) : 1.0; + string str = (argc >= 4) ? PopValueAssert(shared).ToString() : ""; + RgbaColor rgba = (argc >= 3) ? GetRgba(PopValueAssert(shared)) : new RgbaColor(1.0f, 1.0f, 1.0f); + Vector vec = (argc >= 2) ? GetVector(PopValueAssert(shared)) : new Vector(1.0, 0.0, 0.0); + Vector start = (argc >= 1) ? GetVector(PopValueAssert(shared)) : new Vector(0.0, 0.0, 0.0); + AssertArgBottomAndConsume(shared); + DoExecuteWork(shared, start, vec, rgba, str, scale, show, width); } - public void DoExecuteWork(SharedObjects shared) - { - var vRend = new VectorRenderer( shared.UpdateHandler, shared ); - vRend.SetShow( false ); - - ReturnValue = vRend; - } - - public void DoExecuteWork(SharedObjects shared, Vector start, Vector vec, RgbaColor rgba, string str, double scale, bool show) + public void DoExecuteWork(SharedObjects shared, Vector start, Vector vec, RgbaColor rgba, string str, double scale, bool show, double width) { var vRend = new VectorRenderer( shared.UpdateHandler, shared ) { Vector = vec, Start = start, Color = rgba, - Scale = scale + Scale = scale, + Width = width }; vRend.SetLabel( str ); vRend.SetShow( show ); @@ -312,6 +374,16 @@ public void DoExecuteWork(SharedObjects shared, Vector start, Vector vec, RgbaCo } } + [Function("clearvecdraws")] + public class FunctionHideAllVecdraws : FunctionBase + { + public override void Execute(SharedObjects shared) + { + AssertArgBottomAndConsume(shared); + VectorRenderer.ClearAll(shared.UpdateHandler); + } + } + [Function("positionat")] public class FunctionPositionAt : FunctionBase { @@ -423,24 +495,30 @@ public override void Execute(SharedObjects shared) AssertArgBottomAndConsume(shared); WaypointManager wpm = WaypointManager.Instance(); - if (wpm == null) // When zero waypoints exist, there might not even be a waypoint manager. - { - ReturnValue = null; - // I don't like returning null here without the user being able to test for that, but - // we don't have another way to communicate "no such waypoint". We really need to address - // that problem once and for all. - return; - } + + // If no contracts have been generated with waypoints in them, + // then sometimes the stock game's waypoint manager doesn't even + // exist yet either. (The base game seems not to instance one until the + // first time a contract with a waypoint is created). + if (wpm == null) + throw new KOSInvalidArgumentException("waypoint", "\""+pointName+"\"", "no waypoints exist"); string baseName; int index; bool hasGreek = WaypointValue.GreekToInteger(pointName, out index, out baseName); + if (hasGreek) + pointName = baseName; Waypoint point = wpm.AllWaypoints().FirstOrDefault( - p => String.Equals(p.name, baseName,StringComparison.CurrentCultureIgnoreCase) && (!hasGreek || p.index == index)); + p => String.Equals(p.name, pointName,StringComparison.CurrentCultureIgnoreCase) && (!hasGreek || p.index == index)); + + // We can't communicate the concept of a lookup fail to the script in a way it can catch (can't do + // nulls), so bomb out here: + if (point ==null) + throw new KOSInvalidArgumentException("waypoint", "\""+pointName+"\"", "no such waypoint"); ReturnValue = new WaypointValue(point, shared); } - } + } [Function("transferall")] public class FunctionTransferAll : FunctionBase diff --git a/src/kOS/Function/Trigonometry.cs b/src/kOS/Function/Trigonometry.cs index 5088736b2..bcb3e00b9 100644 --- a/src/kOS/Function/Trigonometry.cs +++ b/src/kOS/Function/Trigonometry.cs @@ -1,5 +1,6 @@ using System; using kOS.Safe.Function; +using kOS.Safe.Encapsulation; namespace kOS.Function { diff --git a/src/kOS/InterProcessor/ProcessorManager.cs b/src/kOS/InterProcessor/ProcessorManager.cs index d7eeac7d5..2476884b0 100644 --- a/src/kOS/InterProcessor/ProcessorManager.cs +++ b/src/kOS/InterProcessor/ProcessorManager.cs @@ -1,15 +1,17 @@ using System; using System.Collections.Generic; +using System.Linq; using kOS.Module; using kOS.Safe.Compilation; using kOS.Safe.Persistence; +using kOS.Safe.Utilities; namespace kOS.InterProcessor { public class ProcessorManager { // Use the attached volume as processor identifier - private readonly Dictionary processors; + public Dictionary processors { get; private set; } public ProcessorManager() { @@ -25,7 +27,20 @@ public void UpdateProcessors(List processorList) } } - private kOSProcessor GetProcessor(Volume volume) + public kOSProcessor GetProcessor(string name) + { + foreach (KeyValuePair pair in processors) + { + if (pair.Value.Tag != null && String.Equals(pair.Value.Tag, name, StringComparison.CurrentCultureIgnoreCase)) + { + return pair.Value; + } + } + + return null; + } + + public kOSProcessor GetProcessor(Volume volume) { if (processors.ContainsKey(volume)) { diff --git a/src/kOS/KSPLogger.cs b/src/kOS/KSPLogger.cs index 2a12b477c..dfce4fbf5 100644 --- a/src/kOS/KSPLogger.cs +++ b/src/kOS/KSPLogger.cs @@ -5,6 +5,7 @@ using System.Text.RegularExpressions; using kOS.Safe.Compilation; using kOS.Safe.Persistence; +using kOS.Safe.Encapsulation; namespace kOS { @@ -128,7 +129,7 @@ private string TraceLog() int numPadSpaces = useColumn-1; if (numPadSpaces < 0) numPadSpaces = 0; - msg += new String(' ', numPadSpaces) + "^" + "\n"; + msg += new string(' ', numPadSpaces) + "^" + "\n"; } } return msg; @@ -203,14 +204,14 @@ private string GetSourceLine(string filePath, int line) if (fileName == "interpreter history") return Shared.Interpreter.GetCommandHistoryAbsolute(line); - - ProgramFile file = vol.GetByName(fileName); + + VolumeFile file = vol.Open(fileName); if (file!=null) { - if (file.Category == FileCategory.KSM) + if (file.ReadAll().Category == FileCategory.KSM) return "<>"; - string[] splitLines = file.StringContent.Split('\n'); + string[] splitLines = file.ReadAll().String.Split('\n'); if (splitLines.Length >= line) { returnVal = splitLines[line-1]; diff --git a/src/kOS/Logger.cs b/src/kOS/Logger.cs index 85b6231fc..f9ad42fad 100644 --- a/src/kOS/Logger.cs +++ b/src/kOS/Logger.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using kOS.Suffixed; using kOS.Safe.Exceptions; +using kOS.Safe.Utilities; namespace kOS { @@ -35,7 +36,7 @@ public virtual void Log(Exception e) string message = e.Message; - if (Config.Instance.VerboseExceptions && e is KOSException ) + if (SafeHouse.Config.VerboseExceptions && e is KOSException ) { // As a first primitive attempt at excercising the verbose exceptions, // Just use a CONFIG setting for how verbose to be. This will need @@ -56,6 +57,10 @@ public virtual void Log(Exception e) message += "\n\nMore Information at:\n" + url + "\n"; message += LINE_RULE; } + + if (SafeHouse.Config.AudibleExceptions) + Shared.SoundMaker.BeginSound("error"); + LogToScreen(message); ExceptionHistory.Add(e); diff --git a/src/kOS/Module/Bootstrapper.cs b/src/kOS/Module/Bootstrapper.cs index bf6df2c12..50b112df0 100644 --- a/src/kOS/Module/Bootstrapper.cs +++ b/src/kOS/Module/Bootstrapper.cs @@ -24,12 +24,14 @@ public void Start() CheckForLegacyArchive(); + KOSNomenclature.PopulateMapping(typeof(kOS.Safe.Encapsulation.Structure).Assembly, this.GetType().Assembly); } private void BuildEnvironment() { - Safe.Utilities.SafeHouse.Init( + SafeHouse.Init( Config.Instance, + Core.VersionInfo, Application.platform == RuntimePlatform.WindowsPlayer, GameDatabase.Instance.PluginDataFolder + "/Ships/Script/" ); @@ -49,7 +51,7 @@ private void CheckForLegacyArchive() return; } - if (Directory.Exists(Safe.Utilities.SafeHouse.ArchiveFolder)) + if (Directory.Exists(SafeHouse.ArchiveFolder)) { return; } @@ -76,7 +78,7 @@ private void MigrateScripts() } SafeHouse.Logger.Log("ScriptMigrate START"); - Directory.CreateDirectory(Safe.Utilities.SafeHouse.ArchiveFolder); + Directory.CreateDirectory(SafeHouse.ArchiveFolder); var files = Directory.GetFiles(legacyArchiveFolder); diff --git a/src/kOS/Module/kOSLightModule.cs b/src/kOS/Module/kOSLightModule.cs new file mode 100644 index 000000000..c348a6389 --- /dev/null +++ b/src/kOS/Module/kOSLightModule.cs @@ -0,0 +1,163 @@ +using kOS.Safe.Utilities; +using UnityEngine; + +namespace kOS.Module +{ + internal class kOSLightModule : PartModule + { + [KSPField(isPersistant = true, guiName = "Required Power for Lights", guiActive = true)] + public float resourceAmount = 0.001f; + + [KSPField(isPersistant = true, guiActive = true, guiName = "Light R")] + [UI_FloatRange(maxValue = 1, minValue = 0, scene = UI_Scene.Flight, stepIncrement = 0.01f)] + protected float red = 1; + + [KSPField(isPersistant = true, guiActive = true, guiName = "Light G")] + [UI_FloatRange(maxValue = 1, minValue = 0, scene = UI_Scene.Flight, stepIncrement = 0.01f)] + protected float green = 1; + + [KSPField(isPersistant = true, guiActive = true, guiName = "Light B")] + [UI_FloatRange(maxValue = 1, minValue = 0, scene = UI_Scene.Flight, stepIncrement = 0.01f)] + protected float blue = 1; + + [KSPField(isPersistant = true, guiActive = true, guiName = "Power Starved")] + private bool powerStarved = false; + + [KSPField(isPersistant = false, guiName = "Last requested power", guiActive = true)] + public float lastResource = 0.2f; + + [KSPField(isPersistant = false, guiActive = false)] + public string animationName = ""; + + [KSPField(isPersistant = false, guiActive = false)] + public string pulseWidth = ""; + + [KSPField(isPersistant = false, guiActive = false)] + public string gapWidth = ""; + + private double lastTime = double.MaxValue; + + private readonly Color powerOffColor = new Color(0, 0, 0, 0); + + private ModuleLight lightModule; + private Light[] lights; + private Renderer[] renderers; + private Animation[] animations; + private bool lastLightModuleIsOn = false; + + public override void OnLoad(ConfigNode node) + { + updateReferences(); + } + + public void Update() + { + if (HighLogic.LoadedScene == GameScenes.EDITOR) + { + if (lightModule != null) + { + red = lightModule.lightR; + green = lightModule.lightG; + blue = lightModule.lightB; + } + else + { + updateReferences(); + } + } + updateColor(); + } + + public void FixedUpdate() + { + if (HighLogic.LoadedScene == GameScenes.FLIGHT) + { + if (lightModule != null && lightModule.isOn) + { + processElectricity(); + } + else + { + lastTime = double.MaxValue; + } + } + } + + public override string GetInfo() + { + string format = + "Configurable color.\n" + + "Maximum power consumption: {0}EC/s"; + return string.Format(format, resourceAmount); + } + + public void updateReferences() + { + lightModule = part.GetComponent(); + lightModule.resourceAmount = 0; + lightModule.Fields["resourceAmount"].guiActive = false; + lightModule.useResources = false; + lights = part.FindModelComponents(); + renderers = part.FindModelComponents(); + animations = part.FindModelAnimators(); + } + + private void processElectricity() + { + double currentTime = Planetarium.GetUniversalTime(); + double dt = currentTime - lastTime; + if (dt > 0) + { + double request = (red + green + blue) / 3 * resourceAmount * dt; + lastResource = (float)request; + double received = part.RequestResource("ElectricCharge", request); + if (received / request > 0.5) + { + powerStarved = false; + } + else + { + powerStarved = true; + } + } + lastTime = currentTime; + } + + private void updateColor() + { + if (lightModule != null) + { + Color currentColor = powerStarved || !lightModule.isOn ? powerOffColor : new Color(red, green, blue, 1); + if (lights != null) + { + foreach (Light lgt in lights) + { + lgt.color = currentColor; + } + } + if (renderers != null) + { + foreach (Renderer rnd in renderers) + { + rnd.material.SetColor("_EmissiveColor", currentColor); + } + } + if (animations != null && !string.IsNullOrEmpty(animationName)) + { + foreach (var animation in animations) + { + if (!animation.isPlaying && (lightModule.isOn & !lastLightModuleIsOn) && !powerStarved) // <<-- extra check + { + animation.Play(animationName); + } + else if (animation.isPlaying && (!lightModule.isOn || powerStarved)) + { + animation.Stop(); + } + } + lastLightModuleIsOn = lightModule.isOn; + } + } + } + } +} diff --git a/src/kOS/Module/kOSProcessor.cs b/src/kOS/Module/kOSProcessor.cs index 2c5f2b53c..675e25250 100644 --- a/src/kOS/Module/kOSProcessor.cs +++ b/src/kOS/Module/kOSProcessor.cs @@ -1,46 +1,62 @@ -using System; -using System.Collections.Generic; -using System.Linq; using kOS.AddOns.RemoteTech; +using kOS.Binding; using kOS.Execution; using kOS.Factories; using kOS.Function; -using kOS.Safe.Persistence; -using kOS.Safe.Utilities; -using kOS.Utilities; -using UnityEngine; -using KSP.IO; using kOS.InterProcessor; -using kOS.Binding; using kOS.Persistence; using kOS.Safe; using kOS.Safe.Compilation; using kOS.Safe.Compilation.KS; using kOS.Safe.Module; +using kOS.Safe.Persistence; using kOS.Safe.Screen; -using kOS.Suffixed; - +using kOS.Safe.Utilities; +using kOS.Utilities; +using KSP.IO; using KSPAPIExtensions; -using FileInfo = kOS.Safe.Encapsulation.FileInfo; +using System; +using System.Collections.Generic; +using System.Linq; +using kOS.Safe.Execution; +using UnityEngine; +using kOS.Safe.Encapsulation; namespace kOS.Module { public class kOSProcessor : PartModule, IProcessor, IPartCostModifier, IPartMassModifier { - public ProcessorModes ProcessorMode = ProcessorModes.READY; + public ProcessorModes ProcessorMode { get; private set; } public Harddisk HardDisk { get; private set; } + + public string Tag + { + get + { + KOSNameTag tag = part.Modules.OfType().FirstOrDefault(); + return tag == null ? string.Empty : tag.nameTag; + } + } + private int vesselPartCount; private SharedObjects shared; private static readonly List allMyInstances = new List(); private bool firstUpdate = true; + private MovingAverage averagePower = new MovingAverage(); + + // This is the "constant" byte count used when calculating the EC + // required by the archive volume (which has infinite space). + // TODO: This corresponds to the existing value and should be adjusted for balance. + private const int ARCHIVE_EFFECTIVE_BYTES = 50000; + //640K ought to be enough for anybody -sic private const int PROCESSOR_HARD_CAP = 655360; - [KSPField(isPersistant = true, guiActive = false, guiActiveEditor = true, guiName = "Boot File"), UI_ChooseOption(scene=UI_Scene.Editor)] + [KSPField(isPersistant = true, guiActive = false, guiActiveEditor = true, guiName = "Boot File"), UI_ChooseOption(scene = UI_Scene.Editor)] public string bootFile = "boot.ks"; - + [KSPField(isPersistant = true, guiName = "kOS Disk Space", guiActive = true)] public int diskSpace = 1024; @@ -62,7 +78,30 @@ public class kOSProcessor : PartModule, IProcessor, IPartCostModifier, IPartMass [KSPField(isPersistant = false, guiName = "CPU/Disk Upgrade Mass", guiActive = false, guiActiveEditor = true)] public float additionalMass = 0F; - [KSPField(isPersistant = true, guiActive = false)] public int MaxPartId = 100; + [KSPField(isPersistant = true, guiActive = false)] + public int MaxPartId = 100; + + // This represents how much EC to consume per executed instruction. + // This would be the "variable" component of the processor's power. + // Important: This value should be overriden in the part.cfg file + // for the kOS processor. The only reason it's being given a value + // here is as a fallback for those cases where an old legacy part + // might be loaded from before the part files had this value. + [KSPField(isPersistant = false, guiActive = false)] + public float ECPerInstruction = 0.000004F; + + // This represents how much EC to consume per Byte of the current volume, per second. + // This would be the "continuous" compoenent of the processor's power (though it varies + // when you change to another volume). + // IMPORTANT: The value defaults to zero and must be overriden in the module + // definition for any given part (within the part.cfg file). + [KSPField(isPersistant = false, guiActive = false)] + public float ECPerBytePerSecond = 0F; + + public kOSProcessor() + { + ProcessorMode = ProcessorModes.READY; + } [KSPEvent(guiActive = true, guiName = "Open Terminal", category = "skip_delay;")] public void Activate() @@ -71,8 +110,8 @@ public void Activate() OpenWindow(); } - [KSPField(isPersistant = true, guiName = "Required Power", guiActive = true)] - public float RequiredPower; + [KSPField(isPersistant = true, guiName = "kOS Average Power", guiActive = true, guiActiveEditor = true, guiUnits = "EC/s", guiFormat = "0.000")] + public float RequiredPower = 0; [KSPEvent(guiActive = true, guiName = "Toggle Power")] public void TogglePower() @@ -81,7 +120,7 @@ public void TogglePower() ProcessorModes newProcessorMode = (ProcessorMode != ProcessorModes.OFF) ? ProcessorModes.OFF : ProcessorModes.STARVED; SetMode(newProcessorMode); } - + [KSPAction("Open Terminal", actionGroup = KSPActionGroup.None)] public void Activate(KSPActionParam param) { @@ -109,7 +148,6 @@ public void TogglePower(KSPActionParam param) SafeHouse.Logger.Log("Toggle Power from ActionGroup"); TogglePower(); } - public void OpenWindow() { shared.Window.Open(); @@ -124,12 +162,12 @@ public void ToggleWindow() { shared.Window.Toggle(); } - + public bool WindowIsOpen() { return shared.Window.IsOpen; } - + public bool TelnetIsAttached() { return shared.Window.NumTelnets() > 0; @@ -139,7 +177,7 @@ public IScreenBuffer GetScreen() { return shared.Screen; } - + // TODO - later refactor making this kOS.Safer so it can work on ITermWindow, which also means moving all of UserIO's classes too. public Screen.TermWindow GetWindow() { @@ -149,19 +187,20 @@ public Screen.TermWindow GetWindow() //returns basic information on kOSProcessor module in Editor public override string GetInfo() { - const float MAXIMUM_POWER_CONSUMPTION = 0.2F; - string moduleInfo = "KOS Processor\n"; - - moduleInfo += "\nDefault disk capacity: " + diskSpace; - - moduleInfo += "\nMax Power consuption, EC/s : " + System.Math.Round(MAXIMUM_POWER_CONSUMPTION, 2); - - if (additionalCost > 0) - { - moduleInfo += "\nCost of probe CPU upgrade: " + System.Math.Round(additionalCost,0); - } - - return moduleInfo; + int defaultAvgInstructions = 200; + string format = + "Default disk capacity: {0}\n\n" + + "Requires:\n" + + " - ElectricCharge: {1}\n" + + "Example:\n" + + " - {2:N3}EC/s if IPU={3} and no wait instructions."; + // For the sake of GetInfo, prorate the EC usage based on the smallest physics frame currently selected + // Because this is called before the part is set, we need to manually calculate it instead of letting Update handle it. + double power = diskSpace * ECPerBytePerSecond + defaultAvgInstructions * ECPerInstruction / Time.fixedDeltaTime; + string chargeText = (ECPerInstruction == 0) ? + "None. It's powered by pure magic ... apparently." : // for cheaters who use MM or editing part.cfg, to get rid of it. + string.Format("1 per {0} instructions executed", (int)(1 / ECPerInstruction)); + return string.Format(format, diskSpace, chargeText, power, defaultAvgInstructions); } //implement IPartCostModifier component @@ -175,7 +214,7 @@ private void UpdateCostAndMass() const float DISK_SPACE_MASS_MULTIPLIER = 0.0000048829F; //implies approx 20kg for 4096bytes of diskSpace const float DISK_SPACE_COST_MULTIPLIER = 0.0244140625F; //implies approx 100funds for 4096bytes of diskSpace - additionalCost = baseModuleCost + (float)System.Math.Round((diskSpace - baseDiskSpace) * DISK_SPACE_COST_MULTIPLIER,0); + additionalCost = baseModuleCost + (float)System.Math.Round((diskSpace - baseDiskSpace) * DISK_SPACE_COST_MULTIPLIER, 0); additionalMass = (diskSpace - baseDiskSpace) * DISK_SPACE_MASS_MULTIPLIER; part.mass = basePartMass + additionalMass; @@ -193,15 +232,15 @@ public override void OnStart(StartState state) //if in Editor, populate boot script selector, diskSpace selector and etc. if (state == StartState.Editor) { - if (baseDiskSpace == 0) + if (baseDiskSpace == 0) baseDiskSpace = diskSpace; - if (System.Math.Abs (baseModuleCost) < 0.000001F) + if (System.Math.Abs(baseModuleCost) < 0.000001F) baseModuleCost = additionalCost; //remember module cost before tweaks else additionalCost = baseModuleCost; //reset module cost and update later in UpdateCostAndMass() - if (System.Math.Abs (basePartMass) < 0.000001F) + if (System.Math.Abs(basePartMass) < 0.000001F) basePartMass = part.mass; //remember part mass before tweaks else part.mass = basePartMass; //reset part mass to original value and update later in UpdateCostAndMass() @@ -209,7 +248,7 @@ public override void OnStart(StartState state) InitUI(); } - UpdateCostAndMass(); + UpdateCostAndMass(); //Do not start from editor and at KSP first loading if (state == StartState.Editor || state == StartState.None) @@ -220,6 +259,7 @@ public override void OnStart(StartState state) SafeHouse.Logger.Log(string.Format("OnStart: {0} {1}", state, ProcessorMode)); InitObjects(); } + private void InitUI() { //Populate selector for boot scripts @@ -229,13 +269,13 @@ private void InitUI() var bootFiles = new List(); var temp = new Archive(); - var files = temp.GetFileList(); + var files = temp.FileList; var maxchoice = 0; bootFiles.Add("None"); - foreach (FileInfo file in files) + foreach (KeyValuePair pair in files) { - if (!file.Name.StartsWith("boot", StringComparison.InvariantCultureIgnoreCase)) continue; - bootFiles.Add(file.Name); + if (!pair.Key.StartsWith("boot", StringComparison.InvariantCultureIgnoreCase)) continue; + bootFiles.Add(pair.Key); maxchoice++; } //no need to show the control if there are no files starting with boot @@ -249,10 +289,9 @@ private void InitUI() options = (UI_ChooseOption)field.uiControlEditor; var sizeOptions = new string[3]; sizeOptions[0] = baseDiskSpace.ToString(); - sizeOptions[1] = (baseDiskSpace*2).ToString(); - sizeOptions[2] = (baseDiskSpace*4).ToString(); + sizeOptions[1] = (baseDiskSpace * 2).ToString(); + sizeOptions[2] = (baseDiskSpace * 4).ToString(); options.options = sizeOptions; - } public void InitObjects() @@ -261,7 +300,7 @@ public void InitObjects() shared = new SharedObjects(); CreateFactory(); - + shared.Vessel = vessel; shared.Processor = this; shared.KSPPart = part; @@ -276,6 +315,7 @@ public void InitObjects() shared.FunctionManager = new FunctionManager(shared); shared.TransferManager = new TransferManager(shared); shared.Cpu = new CPU(shared); + shared.SoundMaker = Sound.SoundMaker.Instance; // Make the window that is going to correspond to this kOS part: var gObj = new GameObject("kOSTermWindow", typeof(Screen.TermWindow)); @@ -291,36 +331,54 @@ public void InitObjects() if (HardDisk == null) { HardDisk = new Harddisk(Mathf.Min(diskSpace, PROCESSOR_HARD_CAP)); + + if (!string.IsNullOrEmpty(Tag)) + { + HardDisk.Name = Tag; + } + // populate it with the boot file, but only if using a new disk and in PRELAUNCH situation: - if (vessel.situation == Vessel.Situations.PRELAUNCH && bootFile != "None") + if (vessel.situation == Vessel.Situations.PRELAUNCH && bootFile != "None" && !SafeHouse.Config.StartOnArchive) { - var bootProgramFile = archive.GetByName(bootFile); - if (bootProgramFile != null) + var bootVolumeFile = archive.Open(bootFile); + if (bootVolumeFile != null) { - // Copy to HardDisk as "boot". - var boot = new ProgramFile(bootProgramFile) { Filename = "boot.ks" }; - HardDisk.Add(boot); + FileContent content = bootVolumeFile.ReadAll(); + if (HardDisk.IsRoomFor(bootFile, content)) + { + HardDisk.Save(bootFile, content); + } + else + { + // Throwing an exception during InitObjects will break the initialization and won't show + // the error to the user. So we just log the error instead. At some point in the future + // it would be nice to queue up these init errors and display them to the user somewhere. + SafeHouse.Logger.LogError("Error copying boot file to local volume: not enough space."); + } } } } shared.VolumeMgr.Add(HardDisk); // process setting - if (!Config.Instance.StartOnArchive) + if (!SafeHouse.Config.StartOnArchive) { shared.VolumeMgr.SwitchTo(HardDisk); } - - InitProcessorTracking(); - // move Cpu.Boot() to within the first Update() to prevent boot script errors from killing OnStart - // shared.Cpu.Boot(); + // initialize processor mode if different than READY + if (ProcessorMode != ProcessorModes.READY) + { + ProcessorModeChanged(); + } + + InitProcessorTracking(); } private void InitProcessorTracking() { // Track a list of all instances of me that exist: - if (! allMyInstances.Contains(this)) + if (!allMyInstances.Contains(this)) { allMyInstances.Add(this); allMyInstances.Sort(delegate(kOSProcessor a, kOSProcessor b) @@ -331,7 +389,7 @@ private void InitProcessorTracking() if (b.part == null || b.part.vessel == null) return 1; // If on different vessels, sort by vessel name next: - int compare = String.Compare(a.part.vessel.vesselName, b.part.vessel.vesselName, + int compare = string.Compare(a.part.vessel.vesselName, b.part.vessel.vesselName, StringComparison.CurrentCultureIgnoreCase); // If on same vessel, sort by part UID last: if (compare != 0) @@ -349,11 +407,10 @@ private void OnDestroyingMyHardware(Part p) return; GetWindow().DetachAllTelnets(); - - allMyInstances.RemoveAll(m => m==this); + + allMyInstances.RemoveAll(m => m == this); } - - + /// /// Return a list of all existing runtime instances of this PartModule. /// The list is guaranteed to be ordered by the Vessel that it's on. @@ -376,7 +433,7 @@ private void CreateFactory() bool isAvailable; try { - isAvailable = RemoteTechHook.IsAvailable(vessel.id); + isAvailable = RemoteTechHook.IsAvailable(); } catch { @@ -400,7 +457,7 @@ public void RegisterkOSExternalFunction(object[] parameters) //SafeHouse.Logger.Log("*** External Function Registration Succeeded"); //cpu.RegisterkOSExternalFunction(parameters); } - + public static int AssignNewId() { var config = PluginConfiguration.CreateForType(); @@ -411,7 +468,7 @@ public static int AssignNewId() return id; } - + public void Update() { if (HighLogic.LoadedScene == GameScenes.EDITOR) @@ -422,25 +479,29 @@ public void Update() UpdateCostAndMass(); GameEvents.onEditorShipModified.Fire(EditorLogic.fetch.ship); } - + RequiredPower = this.diskSpace * ECPerBytePerSecond + SafeHouse.Config.InstructionsPerUpdate * ECPerInstruction / Time.fixedDeltaTime; } if (!IsAlive()) return; - if (firstUpdate) - { - SafeHouse.Logger.LogWarning("First Update()"); - firstUpdate = false; - shared.Cpu.Boot(); - } UpdateVessel(); UpdateObservers(); - ProcessElectricity(part, TimeWarp.fixedDeltaTime); } public void FixedUpdate() { if (!IsAlive()) return; - UpdateFixedObservers(); + if (!vessel.HoldPhysics) + { + if (firstUpdate) + { + SafeHouse.Logger.LogWarning("First Update()"); + firstUpdate = false; + shared.Cpu.Boot(); + } + UpdateVessel(); + UpdateFixedObservers(); + ProcessElectricity(part, TimeWarp.fixedDeltaTime); + } } private void UpdateVessel() @@ -455,7 +516,7 @@ private void UpdateObservers() { if (ProcessorMode == ProcessorModes.READY) { - if (shared.UpdateHandler != null) shared.UpdateHandler.UpdateObservers(Time.deltaTime); + if (shared.UpdateHandler != null) shared.UpdateHandler.UpdateObservers(TimeWarp.deltaTime); UpdateParts(); } } @@ -464,7 +525,7 @@ private void UpdateFixedObservers() { if (ProcessorMode == ProcessorModes.READY) { - if (shared.UpdateHandler != null) shared.UpdateHandler.UpdateFixedObservers(Time.deltaTime); + if (shared.UpdateHandler != null) shared.UpdateHandler.UpdateFixedObservers(TimeWarp.fixedDeltaTime); } } @@ -545,6 +606,11 @@ public override void OnLoad(ConfigNode node) // KSP Seems to want to make an instance of my partModule during initial load if (vessel == null) return; + if (node.HasValue("activated") && !bool.Parse(node.GetValue("activated"))) + { + ProcessorMode = ProcessorModes.OFF; + } + if (node.HasNode("harddisk")) { var newDisk = node.GetNode("harddisk").ToHardDisk(); @@ -553,10 +619,6 @@ public override void OnLoad(ConfigNode node) InitObjects(); - if (shared != null && shared.Cpu != null) - { - ((CPU)shared.Cpu).OnLoad(node); - } base.OnLoad(node); } catch (Exception ex) //Intentional Pokemon, if exceptions get out of here it can kill the craft @@ -570,6 +632,8 @@ public override void OnSave(ConfigNode node) { try { + node.AddValue("activated", ProcessorMode != ProcessorModes.OFF); + if (HardDisk != null) { ConfigNode hdNode = HardDisk.ToConfigNode("harddisk"); @@ -578,8 +642,7 @@ public override void OnSave(ConfigNode node) if (shared != null && shared.Cpu != null) { - ((CPU)shared.Cpu).OnSave(node); - Config.Instance.SaveConfig(); + SafeHouse.Config.SaveConfig(); } base.OnSave(node); @@ -590,13 +653,13 @@ public override void OnSave(ConfigNode node) SafeHouse.Logger.LogException(ex); } } - + // This is what KSP calls during the initial loading screen (the screen // with the progress bar and all of the "Turning correct end toward space" // funny messages.) This is where kOS *should* be putting all the // static initializing that does not change per-part, or per-vessel // or per-CPU. It might be true that some of what we're doing up above - // in OnLoad and OnStart might relly belong here. + // in OnLoad and OnStart might really belong here. // // At some future point it would be a really good idea to look very carefully // at *everything* being done during those initialzations and see if any of @@ -612,46 +675,105 @@ private void ProcessElectricity(Part partObj, float time) { if (ProcessorMode == ProcessorModes.OFF) return; - RequiredPower = shared.VolumeMgr.CurrentRequiredPower; - var electricReq = time * RequiredPower; - var result = partObj.RequestResource("ElectricCharge", electricReq) / electricReq; + double volumePower = 0; + var volume = shared.VolumeMgr.CurrentVolume; + if (volume.Name == "Archive") + { + volumePower = ARCHIVE_EFFECTIVE_BYTES * ECPerBytePerSecond; + } + else + { + volumePower = volume.Capacity * ECPerBytePerSecond; + } - var newMode = (result < 0.5f) ? ProcessorModes.STARVED : ProcessorModes.READY; - SetMode(newMode); + if (ProcessorMode == ProcessorModes.STARVED) + { + // If the processor is STARVED, check to see if there is enough EC to turn it back on. + var request = averagePower.Mean; // use the average power draw as a baseline of the power needed to restart. + if (request > 0) + { + var available = partObj.RequestResource("ElectricCharge", request); + if (available / request > 0.5) + { + SetMode(ProcessorModes.READY); + } + // Since we're just checking to see if there is enough power to restart, return + // the consumed EC. The actual demand value will be drawn on the next update after + // the cpu boots. This should give the ship a chance to collect a little more EC + // before the cpu actually boots. + partObj.RequestResource("ElectricCharge", -available); + } + else + { + // If there is no historical power request, simply turn the processor back on. This + // should not be possible, since it means that some how the processor got set to + // the STARVED mode, even though no power was requested. + SetMode(ProcessorModes.READY); + } + RequiredPower = (float)request; // Make sure RequiredPower matches the average. + } + else + { + // Because the processor is not STARVED, evaluate the power requirement based on actual operation. + // For EC drain purposes, always pretend atleast 1 instruction happened, so idle drain isn't quite zero: + int instructions = System.Math.Max(shared.Cpu.InstructionsThisUpdate, 1); + var request = volumePower * time + instructions * ECPerInstruction; + if (request > 0) + { + // only check the available EC if the request is greater than 0EC. If the request value + // is zero, then available will always be zero and it appears that mono/.net treat + // "0 / 0" as equaling "0", which prevents us from checking the ratio. Since getting + // "0" available of "0" requested is a valid state, the processor mode is only evaluated + // if request is greater than zero. + var available = partObj.RequestResource("ElectricCharge", request); + if (available / request < 0.5) + { + // 0.5 is an arbitrary ratio for triggering the STARVED mode. It allows for some + // fluctuation away from the exact requested EC, ando adds some fuzzy math to how + // we deal with the descreet physics frames. Essentially if there was enough power + // to run for half of a physics frame, the processor stays on. + SetMode(ProcessorModes.STARVED); + } + } + // Set RequiredPower to the average requested power. This should help "de-bounce" the value + // so that it doesn't fluctuate wildly (between 0.2 and 0.000001 in a single frame for example) + RequiredPower = (float)averagePower.Update(request) / TimeWarp.fixedDeltaTime; + } } public void SetMode(ProcessorModes newProcessorMode) { if (newProcessorMode != ProcessorMode) { - switch (newProcessorMode) - { - case ProcessorModes.READY: - if (Config.Instance.StartOnArchive) - { - shared.VolumeMgr.SwitchTo(shared.VolumeMgr.GetVolume(0)); - } - else - { - shared.VolumeMgr.SwitchTo(HardDisk); - } - if (shared.Cpu != null) shared.Cpu.Boot(); - if (shared.Interpreter != null) shared.Interpreter.SetInputLock(false); - if (shared.Window != null) shared.Window.IsPowered = true; - break; - - case ProcessorModes.OFF: - case ProcessorModes.STARVED: - if (shared.Interpreter != null) shared.Interpreter.SetInputLock(true); - if (shared.Window != null) shared.Window.IsPowered = false; - if (shared.BindingMgr != null) shared.BindingMgr.UnBindAll(); - break; - } - ProcessorMode = newProcessorMode; + + ProcessorModeChanged(); } } + private void ProcessorModeChanged() + { + switch (ProcessorMode) + { + case ProcessorModes.READY: + shared.VolumeMgr.SwitchTo(SafeHouse.Config.StartOnArchive + ? shared.VolumeMgr.GetVolume(0) + : HardDisk); + if (shared.Cpu != null) shared.Cpu.Boot(); + if (shared.Interpreter != null) shared.Interpreter.SetInputLock(false); + if (shared.Window != null) shared.Window.IsPowered = true; + break; + + case ProcessorModes.OFF: + case ProcessorModes.STARVED: + if (shared.Interpreter != null) shared.Interpreter.SetInputLock(true); + if (shared.Window != null) shared.Window.IsPowered = false; + if (shared.BindingMgr != null) shared.BindingMgr.UnBindAll(); + break; + } + + } + public void ExecuteInterProcCommand(InterProcCommand command) { if (command != null) @@ -665,5 +787,24 @@ public void SetAutopilotMode(int mode) RUIToggleButton[] modeButtons = FindObjectOfType().modeButtons; modeButtons.ElementAt(mode).SetTrue(); } + + public string BootFilename + { + get { return bootFile; } + set { bootFile = value; } + } + + public bool CheckCanBoot() + { + if (shared.VolumeMgr == null) { SafeHouse.Logger.Log("No volume mgr"); } + else if (!shared.VolumeMgr.CheckCurrentVolumeRange(shared.Vessel)) { SafeHouse.Logger.Log("Boot volume not in range"); } + else if (shared.VolumeMgr.CurrentVolume == null) { SafeHouse.Logger.Log("No current volume"); } + else if (shared.ScriptHandler == null) { SafeHouse.Logger.Log("No script handler"); } + else + { + return true; + } + return false; + } } -} +} \ No newline at end of file diff --git a/src/kOS/Persistence/PersistenceExtensions.cs b/src/kOS/Persistence/PersistenceExtensions.cs index a07881f88..dfc24f057 100644 --- a/src/kOS/Persistence/PersistenceExtensions.cs +++ b/src/kOS/Persistence/PersistenceExtensions.cs @@ -1,11 +1,9 @@ -using System; -using System.IO; -using System.Text; -using ICSharpCode.SharpZipLib.GZip; -using kOS.AddOns.RemoteTech; +using kOS.AddOns.RemoteTech; +using kOS.Safe.Encapsulation; using kOS.Safe.Persistence; using kOS.Safe.Utilities; -using kOS.Suffixed; +using System; +using System.Text; namespace kOS.Persistence { @@ -16,26 +14,28 @@ public static class PersistenceExtensions public static Harddisk ToHardDisk(this ConfigNode configNode) { var capacity = 10000; - if (configNode.HasValue("capacity")) capacity = int.Parse(configNode.GetValue("capacity")); + if (configNode.HasValue("capacity")) + capacity = int.Parse(configNode.GetValue("capacity")); var toReturn = new Harddisk(capacity); - - if (configNode.HasValue("volumeName")) toReturn.Name = configNode.GetValue("volumeName"); - + + if (configNode.HasValue("volumeName")) + toReturn.Name = configNode.GetValue("volumeName"); + foreach (ConfigNode fileNode in configNode.GetNodes("file")) { - toReturn.Add(fileNode.ToProgramFile()); + toReturn.Save(fileNode.ToHarddiskFile(toReturn)); } return toReturn; } - public static ProgramFile ToProgramFile(this ConfigNode configNode) + public static HarddiskFile ToHarddiskFile(this ConfigNode configNode, Harddisk harddisk) { var filename = configNode.GetValue(FILENAME_VALUE_STRING); - var toReturn = new ProgramFile(filename); - Decode(toReturn, configNode.GetValue("line")); - return toReturn; + FileContent fileContent = Decode(configNode.GetValue("line")); + harddisk.Save(filename, fileContent); + return new HarddiskFile(harddisk, filename); } public static ConfigNode ToConfigNode(this Harddisk harddisk, string nodeName) @@ -44,103 +44,51 @@ public static ConfigNode ToConfigNode(this Harddisk harddisk, string nodeName) node.AddValue("capacity", harddisk.Capacity); node.AddValue("volumeName", harddisk.Name); - foreach (ProgramFile file in harddisk.FileList.Values) + foreach (VolumeFile volumeFile in harddisk.FileList.Values) { + var file = (HarddiskFile) volumeFile; node.AddNode(file.ToConfigNode("file")); } - + return node; } - public static ConfigNode ToConfigNode(this ProgramFile programFile, string nodeName) + public static ConfigNode ToConfigNode(this HarddiskFile file, string nodeName) { var node = new ConfigNode(nodeName); - node.AddValue(FILENAME_VALUE_STRING, programFile.Filename); + node.AddValue(FILENAME_VALUE_STRING, file.Name); + + FileContent content = file.ReadAll(); - if (programFile.Category == FileCategory.KSM) + if (content.Category == FileCategory.KSM) { - node.AddValue("line", EncodeBase64(programFile.BinaryContent)); + node.AddValue("line", PersistenceUtilities.EncodeBase64(content.Bytes)); } else { - if (Config.Instance.UseCompressedPersistence) + if (SafeHouse.Config.UseCompressedPersistence) { - node.AddValue("line", EncodeBase64(programFile.StringContent)); + node.AddValue("line", EncodeBase64(content.String)); } else { - node.AddValue("line", PersistenceUtilities.EncodeLine(programFile.StringContent)); + node.AddValue("line", PersistenceUtilities.EncodeLine(content.String)); } } return node; } - private static string EncodeBase64(string input) - { - return EncodeBase64(Encoding.ASCII.GetBytes(input)); - } - - private static string EncodeBase64(byte[] input) - { - using (var compressedStream = new MemoryStream()) - { - // mono requires an installed zlib library for GZipStream to work :( - // using (Stream csStream = new GZipStream(compressedStream, CompressionMode.Compress)) - using (Stream csStream = new GZipOutputStream(compressedStream)) - { - csStream.Write(input, 0, input.Length); - } - - string returnValue = Convert.ToBase64String(compressedStream.ToArray()); - - // Added the following to fix issue #429: Base64 content can include the slash character '/', and - // if it happens to have two of them contiguously, it forms a comment in the persistence file and - // truncates the value. So change them to a different character to protect the file. - // The comma ',' char is not used by base64 so it's a safe alternative to use as we'll be able to - // swap all of the commas back to slashes on reading, knowing that commas can only appear as the - // result of this swap on writing: - returnValue = returnValue.Replace('/',','); - - SafeHouse.Logger.SuperVerbose("About to store the following Base64 string:\n" + returnValue); - - return returnValue; - } - } - - private static void Decode(ProgramFile programFile, string input) + private static FileContent Decode(string input) { try { - string decodedString; - try - { - // base64 encoding - - // Fix for issue #429. See comment up in EncodeBase64() method above for an explanation: - string massagedInput = input.Replace(',','/'); - - byte[] decodedBuffer = DecodeBase64ToBinary(massagedInput); - FileCategory whatKind = PersistenceUtilities.IdentifyCategory(decodedBuffer); - if (whatKind == FileCategory.ASCII || whatKind == FileCategory.KERBOSCRIPT) - { - decodedString = Encoding.ASCII.GetString(decodedBuffer); - programFile.StringContent = decodedString; - } - else - { - programFile.BinaryContent = decodedBuffer; - } - } - catch (FormatException) - { - // standard encoding - decodedString = PersistenceUtilities.DecodeLine(input); - programFile.StringContent = decodedString; - } + return new FileContent(PersistenceUtilities.DecodeBase64ToBinary(input)); } - catch (Exception e) + catch (FormatException) { - SafeHouse.Logger.Log(string.Format("Exception decoding: {0} | {1}", e, e.Message)); + // standard encoding + string decodedString = PersistenceUtilities.DecodeLine(input); + return new FileContent(decodedString); } } @@ -151,34 +99,17 @@ public static bool CheckRange(this Volume volume, Vessel vessel) } // Provide a way to check the range limit of the archive without requesting the current volume (which throws an error if not in range) - public static bool CheckCurrentVolumeRange(this VolumeManager volumeManager, Vessel vessel) + public static bool CheckCurrentVolumeRange(this IVolumeManager volumeManager, Vessel vessel) { var rtManager = volumeManager as RemoteTechVolumeManager; - if (rtManager == null) return true; + if (rtManager == null) + return true; return rtManager.CheckCurrentVolumeRange(vessel); } - private static byte[] DecodeBase64ToBinary(string input) + private static string EncodeBase64(string input) { - byte[] inputBuffer = Convert.FromBase64String(input); - - using (var inputStream = new MemoryStream(inputBuffer)) - // mono requires an installed zlib library for GZipStream to work :( - //using (var zipStream = new GZipStream(inputStream, CompressionMode.Decompress)) - using (var zipStream = new GZipInputStream(inputStream)) - using (var decompressedStream = new MemoryStream()) - { - var buffer = new byte[4096]; - int read; - - while ((read = zipStream.Read(buffer, 0, buffer.Length)) > 0) - { - decompressedStream.Write(buffer, 0, read); - } - - return decompressedStream.ToArray(); - } + return PersistenceUtilities.EncodeBase64(Encoding.ASCII.GetBytes(input)); } - } -} +} \ No newline at end of file diff --git a/src/kOS/Properties/AssemblyInfo.cs b/src/kOS/Properties/AssemblyInfo.cs index 1a5e79ba2..9ddc47f92 100644 --- a/src/kOS/Properties/AssemblyInfo.cs +++ b/src/kOS/Properties/AssemblyInfo.cs @@ -31,6 +31,6 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyFileVersion("0.17.2.0")] -[assembly: AssemblyVersion("0.17.2.0")] -[assembly: KSPAssembly("kOS", 0, 17)] +[assembly: AssemblyFileVersion("0.19.1.0")] +[assembly: AssemblyVersion("0.19.1.0")] +[assembly: KSPAssembly("kOS", 0, 19)] diff --git a/src/kOS/Screen/Interpreter.cs b/src/kOS/Screen/Interpreter.cs index 2b2945803..fe59b0ad0 100644 --- a/src/kOS/Screen/Interpreter.cs +++ b/src/kOS/Screen/Interpreter.cs @@ -3,6 +3,7 @@ using System.Text; using kOS.Execution; using kOS.Safe.Compilation; +using kOS.Safe.Execution; using kOS.Safe.Screen; using kOS.Safe.UserIO; @@ -59,14 +60,18 @@ public override void Type(char ch) } } - public override void SpecialKey(char key) + public override bool SpecialKey(char key) { if (key == (char)UnicodeCommand.BREAK) { Shared.Cpu.BreakExecution(true); + LineBuilder.Remove(0, LineBuilder.Length); // why isn't there a StringBuilder.Clear()? + + NewLine(); // process the now emptied line, to make it do all the updates it normally + // does to the screenbuffers on pressing enter. } - if (locked) return; + if (locked) return false; switch (key) { @@ -77,9 +82,10 @@ public override void SpecialKey(char key) ShowCommandHistoryEntry(1); break; default: - base.SpecialKey(key); + return base.SpecialKey(key); break; } + return true; } private void AddCommandHistoryEntry(string commandText) @@ -126,7 +132,13 @@ protected void CompileCommand(string commandText) try { - CompilerOptions options = new CompilerOptions { LoadProgramsInSameAddressSpace = false, FuncManager = Shared.FunctionManager }; + CompilerOptions options = new CompilerOptions + { + LoadProgramsInSameAddressSpace = false, + FuncManager = Shared.FunctionManager, + IsCalledFromRun = false + }; + List commandParts = Shared.ScriptHandler.Compile("interpreter history", commandHistoryIndex, commandText, "interpreter", options); if (commandParts == null) return; diff --git a/src/kOS/Screen/KOSTextEditPopup.cs b/src/kOS/Screen/KOSTextEditPopup.cs index 7f05f4a46..82383398f 100644 --- a/src/kOS/Screen/KOSTextEditPopup.cs +++ b/src/kOS/Screen/KOSTextEditPopup.cs @@ -1,6 +1,7 @@ -using System; -using System.Collections.Generic; +using kOS.Safe.Encapsulation; using kOS.Safe.Persistence; +using System; +using System.Collections.Generic; using UnityEngine; namespace kOS.Screen @@ -16,7 +17,7 @@ public class KOSTextEditPopup : KOSManagedWindow private const string EXIT_BUTTON_TEXT = "(E)xit"; private const string SAVE_BUTTON_TEXT = "(S)ave"; private const string RELOAD_BUTTON_TEXT = "(R)eload"; - + private Rect innerCoords; private Rect saveCoords; private Rect exitCoords; @@ -40,36 +41,36 @@ public class KOSTextEditPopup : KOSManagedWindow public KOSTextEditPopup() { - UniqueId = 100 ; // This is expected to be overridden, but Unity requires that - // KosTextEditPopup() be a constructor that takes zero arguments, - // so the real WindowId has to be set after construction. - WindowRect = new Rect(0,0,470,280); // bogus starting value will be changed later when attaching to a terminal. + UniqueId = 100; // This is expected to be overridden, but Unity requires that + // KosTextEditPopup() be a constructor that takes zero arguments, + // so the real WindowId has to be set after construction. + WindowRect = new Rect(0, 0, 470, 280); // bogus starting value will be changed later when attaching to a terminal. } public void Freeze(bool newVal) { frozen = newVal; } - + public void Awake() { - var gObj = new GameObject( "texteditConfirm", typeof(DelegateDialog) ); + var gObj = new GameObject("texteditConfirm", typeof(DelegateDialog)); DontDestroyOnLoad(gObj); - dialog = ((DelegateDialog)gObj.GetComponent(typeof(DelegateDialog))); - var urlGetter = new WWW( string.Format("file://{0}GameData/kOS/GFX/resize-button.png", KSPUtil.ApplicationRootPath.Replace("\\", "/")) ); - urlGetter.LoadImageIntoTexture( resizeImage ); + dialog = (DelegateDialog)gObj.GetComponent(typeof(DelegateDialog)); + var urlGetter = new WWW(string.Format("file://{0}GameData/kOS/GFX/resize-button.png", KSPUtil.ApplicationRootPath.Replace("\\", "/"))); + urlGetter.LoadImageIntoTexture(resizeImage); } - public void AttachTo( TermWindow termWindow, Volume attachVolume, string attachFileName = "" ) + public void AttachTo(TermWindow termWindow, Volume attachVolume, string attachFileName = "") { term = termWindow; - WindowRect = new Rect(0,0,470,280); // will be resized and moved in onGUI. + WindowRect = new Rect(0, 0, 470, 280); // will be resized and moved in onGUI. frozen = false; loadingVolume = attachVolume; loadingFileName = attachFileName; LoadContents(attachVolume, attachFileName); } - + public bool Contains(Vector2 posAbs) { return WindowRect.Contains(posAbs); @@ -78,12 +79,12 @@ public bool Contains(Vector2 posAbs) public override void GetFocus() { Freeze(false); - } + } public override void LoseFocus() { Freeze(true); - } + } public override void Open() { @@ -91,18 +92,18 @@ public override void Open() base.Open(); BringToFront(); } - + public override void Close() { isDirty = false; base.Close(); } - + public int GetUniqueId() { return UniqueId; } - + public void SetUniqueId(int newValue) { UniqueId = newValue; @@ -111,11 +112,11 @@ public void SetUniqueId(int newValue) public void Update() { // Only stay open as long as the attached terminal window stays open: - if (IsOpen && ( term == null || !(term.IsPowered) )) + if (IsOpen && (term == null || !(term.IsPowered))) IsOpen = false; UpdateLogic(); } - + public void OnGUI() { if (!IsOpen) return; @@ -123,15 +124,13 @@ public void OnGUI() CalcOuterCoords(); // force windowRect to lock to bottom edge of the parents CalcInnerCoords(); - WindowRect = GUI.Window( UniqueId, WindowRect, ProcessWindow, "" ); + WindowRect = GUI.Window(UniqueId, WindowRect, ProcessWindow, ""); // Some mouse global state data used by several of the checks: - // TODO: we aren't using this, do we need it? - Event e = Event.current; if (consumeEvent) { consumeEvent = false; - Event.current.Use(); + Event.current.Use(); } } @@ -143,35 +142,29 @@ protected void ExitEditor() Close(); } - public void SaveContents() { - var file = new ProgramFile(fileName) - { - StringContent = contents - }; - - if (! volume.SaveFile(file) ) + if (volume.Save(fileName, new FileContent(contents)) == null) { // For some reason the normal trap that prints exceptions on // the terminal doesn't work here in this part of the code, // thus the two messages: term.Print("[File Save failed. Check space on device?]"); - throw new Exception( "File Save Failed from Text Editor."); + throw new Exception("File Save Failed from Text Editor."); } isDirty = false; term.Print("[Saved changes to " + fileName + "]"); } - + protected void ReloadContents() { if (isDirty) InvokeReloadConfirmDialog(); else - DelegateLoadContents(this); + DelegateLoadContents(this); } - public void LoadContents( Volume vol, string fName ) + public void LoadContents(Volume vol, string fName) { if (isDirty) { @@ -187,88 +180,88 @@ public void LoadContents( Volume vol, string fName ) DelegateLoadContents(this); } } - + protected void InvokeDirtySaveExitDialog() { var choices = new List(); var actions = new List(); - choices.Add( "Yes" ); - actions.Add( DelegateSaveExit ); - choices.Add( "No" ); - actions.Add( DelegateNoSaveExit ); - choices.Add( "Cancel" ); - actions.Add( DelegateCancel ); - - dialog.Invoke( this, "\""+fileName+"\" has been edited. Save it before exiting?", choices, actions ); + choices.Add("Yes"); + actions.Add(DelegateSaveExit); + choices.Add("No"); + actions.Add(DelegateNoSaveExit); + choices.Add("Cancel"); + actions.Add(DelegateCancel); + + dialog.Invoke(this, "\"" + fileName + "\" has been edited. Save it before exiting?", choices, actions); } protected void InvokeDirtySaveLoadDialog() { var choices = new List(); var actions = new List(); - choices.Add( "Yes" ); - actions.Add( DelegateSaveThenLoad ); - choices.Add( "No" ); - actions.Add( DelegateLoadContents ); - choices.Add( "Cancel" ); - actions.Add( DelegateCancel ); - - dialog.Invoke( this, "\""+fileName+"\" has been edited. Save before loading \""+loadingFileName+"\"?", choices, actions ); + choices.Add("Yes"); + actions.Add(DelegateSaveThenLoad); + choices.Add("No"); + actions.Add(DelegateLoadContents); + choices.Add("Cancel"); + actions.Add(DelegateCancel); + + dialog.Invoke(this, "\"" + fileName + "\" has been edited. Save before loading \"" + loadingFileName + "\"?", choices, actions); } protected void InvokeReloadConfirmDialog() { var choices = new List(); var actions = new List(); - choices.Add( "Yes" ); - actions.Add( DelegateLoadContents ); - choices.Add( "No" ); - actions.Add( DelegateCancel ); - - dialog.Invoke( this, "\""+fileName+"\" has been edited. Throw away changes and reload?", choices, actions ); + choices.Add("Yes"); + actions.Add(DelegateLoadContents); + choices.Add("No"); + actions.Add(DelegateCancel); + + dialog.Invoke(this, "\"" + fileName + "\" has been edited. Throw away changes and reload?", choices, actions); } - - protected static void DelegateSaveExit( KOSTextEditPopup me ) + + protected static void DelegateSaveExit(KOSTextEditPopup me) { me.SaveContents(); me.Freeze(false); me.Close(); } - protected static void DelegateNoSaveExit( KOSTextEditPopup me ) + protected static void DelegateNoSaveExit(KOSTextEditPopup me) { me.Freeze(false); me.Close(); } - - protected static void DelegateSaveThenLoad( KOSTextEditPopup me ) + + protected static void DelegateSaveThenLoad(KOSTextEditPopup me) { me.SaveContents(); - DelegateLoadContents( me ); + DelegateLoadContents(me); } - protected static void DelegateLoadContents( KOSTextEditPopup me ) + protected static void DelegateLoadContents(KOSTextEditPopup me) { me.volume = me.loadingVolume; me.fileName = me.loadingFileName; - ProgramFile file = me.volume.GetByName( me.fileName ); - if ( file == null ) + VolumeFile file = me.volume.Open(me.fileName); + if (file == null) { me.term.Print("[New File]"); me.contents = ""; } else { - me.contents = file.StringContent; + me.contents = file.ReadAll().String; } me.isDirty = false; } - protected static void DelegateCancel( KOSTextEditPopup me ) + protected static void DelegateCancel(KOSTextEditPopup me) { // do nothing. } - + protected void CheckKeyboard() { if (Event.current.type == EventType.KeyDown) @@ -279,20 +272,24 @@ protected void CheckKeyboard() DoPageUp(); Event.current.Use(); break; + case KeyCode.PageDown: DoPageDown(); Event.current.Use(); break; + case KeyCode.E: if (Event.current.control) ExitEditor(); Event.current.Use(); break; + case KeyCode.S: if (Event.current.control) SaveContents(); Event.current.Use(); break; + case KeyCode.R: if (Event.current.control) ReloadContents(); @@ -301,14 +298,14 @@ protected void CheckKeyboard() } } } - + protected void DoPageUp() { var editor = GetWidgetController(); // Seems to be no way to move more than one line at // a time - so have to do this: - int pos = Math.Min( editor.pos, contents.Length - 1); + int pos = Math.Min(editor.pos, contents.Length - 1); int rows = ((int)innerCoords.height) / FONT_HEIGHT; while (rows > 0 && pos >= 0) { @@ -321,11 +318,11 @@ protected void DoPageUp() protected void DoPageDown() { - var editor = GetWidgetController(); - + var editor = GetWidgetController(); + // Seems to be no way to move more than one line at // a time - so have to do this: - int pos = Math.Min( editor.pos, contents.Length - 1); + int pos = Math.Min(editor.pos, contents.Length - 1); int rows = ((int)innerCoords.height) / FONT_HEIGHT; while (rows > 0 && pos < contents.Length) { @@ -345,7 +342,7 @@ protected void CheckResizeDrag() if (resizeButtonCoords.Contains(MouseButtonDownPosRelative)) { resizeMouseDown = true; - resizeOldSize = new Vector2(WindowRect.width,WindowRect.height); + resizeOldSize = new Vector2(WindowRect.width, WindowRect.height); Event.current.Use(); } } @@ -366,59 +363,57 @@ protected void CheckResizeDrag() { var mousePos = new Vector2(Event.current.mousePosition.x, Event.current.mousePosition.y); Vector2 dragDelta = mousePos - MouseButtonDownPosRelative; - WindowRect = new Rect( WindowRect.xMin, + WindowRect = new Rect(WindowRect.xMin, WindowRect.yMin, - Math.Max( resizeOldSize.x + dragDelta.x, 100 ), - Math.Max( resizeOldSize.y + dragDelta.y, 30 ) ); + Math.Max(resizeOldSize.x + dragDelta.x, 100), + Math.Max(resizeOldSize.y + dragDelta.y, 30)); CalcInnerCoords(); Event.current.Use(); } } } - - void ProcessWindow( int windowId ) - { + private void ProcessWindow(int windowId) + { if (!frozen) CheckKeyboard(); - DrawWindow( windowId ); + DrawWindow(windowId); CheckResizeDrag(); CalcOuterCoords(); } - - protected void DrawWindow( int windowId ) + + protected void DrawWindow(int windowId) { GUI.contentColor = Color.green; - - GUILayout.BeginArea( innerCoords ); - scrollPosition = GUILayout.BeginScrollView( scrollPosition ); + GUILayout.BeginArea(innerCoords); + scrollPosition = GUILayout.BeginScrollView(scrollPosition); int preLength = contents.Length; - contents = GUILayout.TextArea( contents ); + contents = GUILayout.TextArea(contents); int postLength = contents.Length; - GUILayout.EndScrollView(); + GUILayout.EndScrollView(); GUILayout.EndArea(); - - GUI.Label( labelCoords, BuildTitle() ); - if (GUI.Button( exitCoords, EXIT_BUTTON_TEXT )) + + GUI.Label(labelCoords, BuildTitle()); + if (GUI.Button(exitCoords, EXIT_BUTTON_TEXT)) { ExitEditor(); } - if (GUI.Button( saveCoords, SAVE_BUTTON_TEXT )) + if (GUI.Button(saveCoords, SAVE_BUTTON_TEXT)) { SaveContents(); } - if (GUI.Button( reloadCoords, RELOAD_BUTTON_TEXT )) + if (GUI.Button(reloadCoords, RELOAD_BUTTON_TEXT)) { ReloadContents(); } - KeepCursorScrolledInView(); + KeepCursorScrolledInView(); + + GUI.Box(resizeButtonCoords, resizeImage); - GUI.Box( resizeButtonCoords, resizeImage ); - if (preLength != postLength) { isDirty = true; @@ -430,17 +425,17 @@ protected void CalcOuterCoords() if (IsOpen && term != null) { Rect tRect = term.GetRect(); - + // Glue it to the bottom of the attached term window - move wherever it moves: float left = tRect.xMin; float top = tRect.yMin + tRect.height; - + // If it hasn't been given a size yet, then give it a starting size that matches // the attached terminal window size. Otherwise keep whatever size the user changed it to: if (WindowRect.width == 0) - WindowRect = new Rect( left, top, tRect.width, tRect.height ); + WindowRect = new Rect(left, top, tRect.width, tRect.height); else - WindowRect = new Rect( left, top, WindowRect.width, WindowRect.height ); + WindowRect = new Rect(left, top, WindowRect.width, WindowRect.height); } } @@ -448,38 +443,38 @@ protected void CalcInnerCoords() { if (!IsOpen) return; - innerCoords = new Rect( FRAME_THICKNESS, - FRAME_THICKNESS + 1.5f*FONT_HEIGHT, - WindowRect.width - 2*FRAME_THICKNESS, - WindowRect.height - 2*FRAME_THICKNESS -2*FONT_HEIGHT ); - - Vector2 labSize = GUI.skin.label.CalcSize( new GUIContent(BuildTitle()) ); - Vector2 exitSize = GUI.skin.box.CalcSize( new GUIContent(EXIT_BUTTON_TEXT) ); - exitSize = new Vector2(exitSize.x+4, exitSize.y+4); - Vector2 saveSize = GUI.skin.box.CalcSize( new GUIContent(SAVE_BUTTON_TEXT) ); - saveSize = new Vector2(saveSize.x+4, saveSize.y+4); - Vector2 reloadSize = GUI.skin.box.CalcSize( new GUIContent(RELOAD_BUTTON_TEXT) ); - reloadSize = new Vector2(reloadSize.x+4, reloadSize.y+4); - - labelCoords = new Rect( 5, 1, labSize.x, labSize.y); - + innerCoords = new Rect(FRAME_THICKNESS, + FRAME_THICKNESS + 1.5f * FONT_HEIGHT, + WindowRect.width - 2 * FRAME_THICKNESS, + WindowRect.height - 2 * FRAME_THICKNESS - 2 * FONT_HEIGHT); + + Vector2 labSize = GUI.skin.label.CalcSize(new GUIContent(BuildTitle())); + Vector2 exitSize = GUI.skin.box.CalcSize(new GUIContent(EXIT_BUTTON_TEXT)); + exitSize = new Vector2(exitSize.x + 4, exitSize.y + 4); + Vector2 saveSize = GUI.skin.box.CalcSize(new GUIContent(SAVE_BUTTON_TEXT)); + saveSize = new Vector2(saveSize.x + 4, saveSize.y + 4); + Vector2 reloadSize = GUI.skin.box.CalcSize(new GUIContent(RELOAD_BUTTON_TEXT)); + reloadSize = new Vector2(reloadSize.x + 4, reloadSize.y + 4); + + labelCoords = new Rect(5, 1, labSize.x, labSize.y); + float buttonXCounter = WindowRect.width; // Keep track of the x coord of leftmost button so far. buttonXCounter -= (exitSize.x + 5); - exitCoords = new Rect( buttonXCounter, 1, exitSize.x, exitSize.y ); - + exitCoords = new Rect(buttonXCounter, 1, exitSize.x, exitSize.y); + buttonXCounter -= (saveSize.x + 2); - saveCoords = new Rect( buttonXCounter, 1, saveSize.x, saveSize.y ); - + saveCoords = new Rect(buttonXCounter, 1, saveSize.x, saveSize.y); + buttonXCounter -= (reloadSize.x + 2); - reloadCoords = new Rect( buttonXCounter, 1, reloadSize.x, reloadSize.y ); + reloadCoords = new Rect(buttonXCounter, 1, reloadSize.x, reloadSize.y); - resizeButtonCoords = new Rect( WindowRect.width - resizeImage.width, + resizeButtonCoords = new Rect(WindowRect.width - resizeImage.width, WindowRect.height - resizeImage.height, resizeImage.width, - resizeImage.height ); + resizeImage.height); } - + protected void KeepCursorScrolledInView() { // It's utterly ridiculous that Unity's TextArea widget doesn't @@ -492,37 +487,36 @@ protected void KeepCursorScrolledInView() // to only be allowed to move as far as the cursor is still in view. // Fixing that would take a bit of work. // - + var editor = GetWidgetController(); Vector2 pos = editor.graphicalCursorPos; - float usableHeight = innerCoords.height - 2.5f*FONT_HEIGHT; + float usableHeight = innerCoords.height - 2.5f * FONT_HEIGHT; if (pos.y < scrollPosition.y) scrollPosition.y = pos.y; else if (pos.y > scrollPosition.y + usableHeight) scrollPosition.y = pos.y - usableHeight; - } // Return type needs full namespace path because kOS namespace has a TextEditor class too: protected TextEditor GetWidgetController() { // Whichever TextEdit widget has current focus (should be this one if processing input): - // There seems to be no way to grab the text edit controller of a Unity Widget by + // There seems to be no way to grab the text edit controller of a Unity Widget by // specific ID. return (TextEditor) GUIUtility.GetStateObject(typeof(TextEditor), GUIUtility.keyboardControl); } - + public Rect GetRect() { return WindowRect; } - + protected string BuildTitle() { - if (volume.Name.Length > 0) + if (volume.Name.Length > 0) return fileName + " on " + volume.Name; return fileName + " on local volume"; // Don't know which number because no link to VolumeManager from this class. } } -} +} \ No newline at end of file diff --git a/src/kOS/Screen/KOSToolBarWindow.cs b/src/kOS/Screen/KOSToolBarWindow.cs index c12ea71a5..7826cfeba 100644 --- a/src/kOS/Screen/KOSToolBarWindow.cs +++ b/src/kOS/Screen/KOSToolBarWindow.cs @@ -1,13 +1,14 @@ -using System; -using System.Collections.Generic; -using System.Linq; +using kOS.Module; +using kOS.Safe.Module; using kOS.Safe.Utilities; -using UnityEngine; -using kOS.Utilities; using kOS.Suffixed; -using kOS.Safe.Module; -using kOS.Module; using kOS.UserIO; +using kOS.Utilities; +using System; +using System.Collections.Generic; +using System.Linq; +using kOS.Safe.Encapsulation.Suffixes; +using UnityEngine; namespace kOS.Screen { @@ -16,7 +17,7 @@ namespace kOS.Screen /// Note that there should only be one of these at a time, unlike some of the /// other KOSManagedWindows. ///

- /// Frustratingly, The only two choices that KSP gives for the boolean + /// Frustratingly, The only two choices that KSP gives for the boolean /// value "once" in the KSPAddon attribute are these:
///
/// Set it to True to have your class instanced only exactly once in the entire game.
@@ -26,16 +27,16 @@ namespace kOS.Screen /// does not seem to be an option. Therefore this class has a lot of silly counters to /// track how many times its been instanced. ///
- [KSPAddon(KSPAddon.Startup.EveryScene,false)] + [KSPAddon(KSPAddon.Startup.EveryScene, false)] public class KOSToolBarWindow : MonoBehaviour { private ApplicationLauncherButton launcherButton; - private IButton BlizzyButton; + private IButton blizzyButton; - private const ApplicationLauncher.AppScenes APP_SCENES = - ApplicationLauncher.AppScenes.FLIGHT | - ApplicationLauncher.AppScenes.SPH | - ApplicationLauncher.AppScenes.VAB | + private const ApplicationLauncher.AppScenes APP_SCENES = + ApplicationLauncher.AppScenes.FLIGHT | + ApplicationLauncher.AppScenes.SPH | + ApplicationLauncher.AppScenes.VAB | ApplicationLauncher.AppScenes.MAPVIEW; private static Texture2D launcherButtonTexture; @@ -43,19 +44,21 @@ public class KOSToolBarWindow : MonoBehaviour private static Texture2D terminalOpenIconTexture; private static Texture2D terminalClosedTelnetIconTexture; private static Texture2D terminalOpenTelnetIconTexture; - + // ReSharper disable once RedundantDefaultFieldInitializer private bool clickedOn = false; - private float height = 1f; // will be automatically resized by GUILayout. - private float width = 1f; // will be automatically resized by GUILayout. - + + private Rect rectToFit = new Rect(0, 0, 1, 1); // will be changed in Open() + // ReSharper disable RedundantDefaultFieldInitializer - private int verticalSectionCount = 0; + private int verticalSectionCount = 0; + private int horizontalSectionCount = 0; + // ReSharper restore RedundantDefaultFieldInitializer - private Vector2 scrollPos = new Vector2(200,350); + private Vector2 scrollPos = new Vector2(200, 350); - private static Rect windowRect; + private static Rect windowRect; // does anybody know why this is ststic? private const int UNIQUE_ID = 8675309; // Jenny, I've got your number. private static GUISkin panelSkin; private static GUIStyle headingLabelStyle; @@ -66,7 +69,7 @@ public class KOSToolBarWindow : MonoBehaviour private static GUIStyle boxOffStyle; private static GUIStyle boxOnStyle; private static string versionString; - + ///Which CPU part description in the gui panel was the mouse hovering over during the current OnGUI call? private Part newHoverPart; @@ -75,22 +78,20 @@ public class KOSToolBarWindow : MonoBehaviour /// Use this to remember the part's previous highlight color before we messed with it. private Color originalPartHighlightColor = new Color(1.0f, 1.0f, 1.0f); // Should get overwritten with the real color later. - // This first value is a safety in case we don't do that - // properly. We don't want to "restore" the color to null. + + // This first value is a safety in case we don't do that + // properly. We don't want to "restore" the color to null. /// Our highlight color for kOS panel's part highlighting. private readonly Color ourPartHighlightColor = new Color(1.0f, 0.5f, 1.0f); // Bright purple. - - private bool alreadyAwake = false; - private bool isOpen = false; + + private bool alreadyAwake; + private bool isOpen; private DateTime prevConfigTimeStamp = DateTime.MinValue; - + private List backingConfigInts; - public KOSToolBarWindow() - { - - } + private bool uiGloballyHidden = false; /// /// Unity hates it when a MonoBehaviour has a constructor, @@ -98,21 +99,31 @@ public KOSToolBarWindow() /// public static void FirstTimeSetup() { - launcherButtonTexture = GameDatabase.Instance.GetTexture ("kOS/GFX/launcher-button",false); - terminalOpenIconTexture = GameDatabase.Instance.GetTexture ("kOS/GFX/terminal-icon-open", false); - terminalClosedIconTexture = GameDatabase.Instance.GetTexture ("kOS/GFX/terminal-icon-closed", false); - terminalOpenTelnetIconTexture = GameDatabase.Instance.GetTexture ("kOS/GFX/terminal-icon-open-telnet", false); - terminalClosedTelnetIconTexture = GameDatabase.Instance.GetTexture ("kOS/GFX/terminal-icon-closed-telnet", false); - - windowRect = new Rect(0,0,1f,1f); // this origin point will move when opened/closed. + launcherButtonTexture = GameDatabase.Instance.GetTexture("kOS/GFX/launcher-button", false); + terminalOpenIconTexture = GameDatabase.Instance.GetTexture("kOS/GFX/terminal-icon-open", false); + terminalClosedIconTexture = GameDatabase.Instance.GetTexture("kOS/GFX/terminal-icon-closed", false); + terminalOpenTelnetIconTexture = GameDatabase.Instance.GetTexture("kOS/GFX/terminal-icon-open-telnet", false); + terminalClosedTelnetIconTexture = GameDatabase.Instance.GetTexture("kOS/GFX/terminal-icon-closed-telnet", false); + + windowRect = new Rect(0, 0, 1f, 1f); // this origin point will move when opened/closed. panelSkin = BuildPanelSkin(); versionString = Utils.GetAssemblyFileVersion(); //UnityEngine.Debug.Log("[kOSToolBarWindow] FirstTimeSetup Finished, v=" + versionString); } - public void Awake () + public void Awake() { - + GameEvents.onGameSceneLoadRequested.Add(OnGameSceneLoadRequestedForAppLauncher); + + GameEvents.onHideUI.Add(OnHideUI); + GameEvents.onShowUI.Add(OnShowUI); + + RunWhenReady(); + } + + private void OnGameSceneLoadRequestedForAppLauncher(GameScenes sceneToLoad) + { + GoAway(); } public void Start() @@ -123,15 +134,6 @@ public void Start() FirstTimeSetup(); - //in 1.0 these Events are never fired (it seems), so we need to maka a workaround - GameEvents.onGUIApplicationLauncherReady.Add(RunWhenReady); - GameEvents.onGUIApplicationLauncherDestroyed.Add(GoAway); - - if (ApplicationLauncher.Ready && launcherButton == null) - { - RunWhenReady(); - } - SafeHouse.Logger.SuperVerbose("[kOSToolBarWindow] Start succesful"); } @@ -142,7 +144,7 @@ public void RunWhenReady() var useBlizzyOnly = false; if (ToolbarManager.ToolbarAvailable) - useBlizzyOnly = Config.Instance.UseBlizzyToolbarOnly; + useBlizzyOnly = SafeHouse.Config.UseBlizzyToolbarOnly; if (!useBlizzyOnly && launcherButton == null) { @@ -161,9 +163,8 @@ public void RunWhenReady() launcher.AddOnShowCallback(CallbackOnShow); launcher.AddOnHideCallback(CallbackOnHide); launcher.EnableMutuallyExclusive(launcherButton); - } - if (BlizzyButton == null) + if (blizzyButton == null) AddBlizzyButton(); SetupBackingConfigInts(); @@ -174,12 +175,12 @@ public void AddBlizzyButton() { if (!ToolbarManager.ToolbarAvailable) return; - BlizzyButton = ToolbarManager.Instance.add("kOS", "kOSButton"); - BlizzyButton.TexturePath = "kOS/GFX/launcher-button-blizzy"; - BlizzyButton.ToolTip = "kOS"; - BlizzyButton.OnClick += (e) => CallbackOnClickBlizzy(); + blizzyButton = ToolbarManager.Instance.add("kOS", "kOSButton"); + blizzyButton.TexturePath = "kOS/GFX/launcher-button-blizzy"; + blizzyButton.ToolTip = "kOS"; + blizzyButton.OnClick += e => CallbackOnClickBlizzy(); } - + /// /// In order to support the changes to solve issue #565 (see github for kOS) /// we have to store a temp value per integer field, that is NOT the actual @@ -188,11 +189,11 @@ public void AddBlizzyButton() /// public void SetupBackingConfigInts() { - if (Config.Instance.TimeStamp() <= prevConfigTimeStamp) - return; + if (SafeHouse.Config.TimeStamp <= prevConfigTimeStamp) + return; prevConfigTimeStamp = DateTime.Now; - - List keys = Config.Instance.GetConfigKeys(); + + IList keys = SafeHouse.Config.GetConfigKeys(); backingConfigInts = new List(); // Fills exactly the expected number of needed ints, in the same // order they will be encountered in when iterating over GetConfigKeys later @@ -201,7 +202,7 @@ public void SetupBackingConfigInts() if (key.Value is int) backingConfigInts.Add((int)(key.Value)); } - + public void GoAway() { if (isOpen) Close(); @@ -209,9 +210,6 @@ public void GoAway() try { - GameEvents.onGUIApplicationLauncherReady.Remove(RunWhenReady); - GameEvents.onGUIApplicationLauncherDestroyed.Remove(GoAway); - if (launcherButton != null && ApplicationLauncher.Instance != null) { ApplicationLauncher launcher = ApplicationLauncher.Instance; @@ -229,41 +227,48 @@ public void GoAway() SafeHouse.Logger.SuperVerbose("[kOSToolBarWindow] Failed unregistering AppLauncher handlers," + e.Message); } - if(BlizzyButton != null) - BlizzyButton.Destroy(); + if (blizzyButton != null) + blizzyButton.Destroy(); } public void OnDestroy() { + GameEvents.onGameSceneLoadRequested.Remove(OnGameSceneLoadRequestedForAppLauncher); + + GameEvents.onHideUI.Remove(OnHideUI); + GameEvents.onShowUI.Remove(OnShowUI); + GoAway(); SafeHouse.Logger.SuperVerbose("[kOSToolBarWindow] OnDestroy successful"); } public void CallbackOnClickBlizzy() { - if(!isOpen) + if (!isOpen) Open(); else - Close(); + Close(); } - + /// Callback for when the button is toggled on public void CallbackOnTrue() { + SafeHouse.Logger.SuperVerbose("KOSToolBarWindow: PROOF: CallbackOnTrue()"); clickedOn = true; Open(); } /// Callback for when the button is toggled off public void CallbackOnFalse() - { + { + SafeHouse.Logger.SuperVerbose("KOSToolBarWindow: PROOF: CallbackOnFalse()"); clickedOn = false; Close(); } /// Callback for when the mouse is hovering over the button public void CallbackOnHover() - { + { SafeHouse.Logger.SuperVerbose("KOSToolBarWindow: PROOF: CallbackOnHover()"); if (!clickedOn) Open(); @@ -271,56 +276,49 @@ public void CallbackOnHover() /// Callback for when the mouse is hover is off the button public void CallbackOnHoverOut() - { + { SafeHouse.Logger.SuperVerbose("KOSToolBarWindow: PROOF: CallbackOnHoverOut()"); if (!clickedOn) Close(); } - /// Callback for when the mouse is hovering over the button + /// Callback for when the application launcher shows itself public void CallbackOnShow() - { + { SafeHouse.Logger.SuperVerbose("KOSToolBarWindow: PROOF: CallbackOnShow()"); - if (!clickedOn && !isOpen) + if (clickedOn) Open(); } - /// Callback for when the mouse is hover is off the button + /// Callback for when the application launcher hides itself public void CallbackOnHide() - { + { SafeHouse.Logger.SuperVerbose("KOSToolBarWindow: PROOF: CallbackOnHide()"); - if (!clickedOn && isOpen) - { - Close(); - clickedOn = false; - } + Close(); } - + public void Open() { SafeHouse.Logger.SuperVerbose("KOSToolBarWindow: PROOF: Open()"); - + bool isTop = ApplicationLauncher.Instance.IsPositionedAtTop; - // Left edge is offset from the right - // edge of the screen by enough to hold the width of the window and maybe more offset - // if in the editor where there's a staging list we don't want to cover up: - float leftEdge = ( (UnityEngine.Screen.width - width) - (HighLogic.LoadedSceneIsEditor ? 64f : 0) ); - - // Top edge is either just under the button itself (which contains 40 pixel icons), or just above - // the screen bottom by enough room to hold the window height plus the 40 pixel icons): - float topEdge = isTop ? (40f) : (UnityEngine.Screen.height - (height+40) ); - - windowRect = new Rect(leftEdge, topEdge, 0, 0); // will resize upon first GUILayout-ing. - SafeHouse.Logger.SuperVerbose("KOSToolBarWindow: PROOF: Open(), windowRect = " + windowRect); - + float fitWidth = UnityEngine.Screen.width - (HighLogic.LoadedSceneIsEditor ? 64f : 0); + float fitHeight = UnityEngine.Screen.height - 40f - 40f; + rectToFit = new Rect(0, 40f, fitWidth, fitHeight); + + float leftEdge = UnityEngine.Screen.width; + float topEdge = isTop ? 0f : UnityEngine.Screen.height; + + windowRect = new Rect(leftEdge, topEdge, 0, 0); // will resize and move upon first GUILayout-ing. + isOpen = true; } public void Close() { SafeHouse.Logger.SuperVerbose("KOSToolBarWindow: PROOF: Close()"); - if (! isOpen) + if (!isOpen) return; isOpen = false; @@ -332,31 +330,39 @@ public void CallbackOnEnable() SafeHouse.Logger.SuperVerbose("KOSToolBarWindow: PROOF: CallbackOnEnable()"); // do nothing, but leaving the hook here as a way to document "this thing exists and might be used". } - + /// Callback for when the button is hidden or disabled by the application launcher public void CallbackOnDisable() - { + { SafeHouse.Logger.SuperVerbose("KOSToolBarWindow: PROOF: CallbackOnDisable()"); // do nothing, but leaving the hook here as a way to document "this thing exists and might be used". } - + + void OnHideUI() + { + uiGloballyHidden = true; + } + + void OnShowUI() + { + uiGloballyHidden = false; + } public void OnGUI() { horizontalSectionCount = 0; verticalSectionCount = 0; - if (!isOpen ) return; + if (!isOpen) return; + + if (uiGloballyHidden && kOS.Safe.Utilities.SafeHouse.Config.ObeyHideUI) return; GUI.skin = HighLogic.Skin; windowRect = GUILayout.Window(UNIQUE_ID, windowRect, DrawWindow, "kOS " + versionString); - - width = windowRect.width; - height = windowRect.height; - + windowRect = RectExtensions.ClampToRectAngle(windowRect, rectToFit); } - + public void DrawWindow(int windowID) { BeginHoverHousekeeping(); @@ -373,8 +379,8 @@ public void DrawWindow(int windowID) int whichInt = 0; // increments only when an integer field is encountered in the config keys, else stays put. SetupBackingConfigInts(); - - foreach (ConfigKey key in Config.Instance.GetConfigKeys()) + + foreach (ConfigKey key in SafeHouse.Config.GetConfigKeys()) { CountBeginHorizontal(); @@ -383,7 +389,7 @@ public void DrawWindow(int windowID) if (key.Value is bool) { - key.Value = GUILayout.Toggle((bool) key.Value, new GUIContent("", toolTipText)); + key.Value = GUILayout.Toggle((bool) key.Value, new GUIContent("", toolTipText), panelSkin.toggle); } else if (key.Value is int) { @@ -394,16 +400,15 @@ public void DrawWindow(int windowID) GUILayout.Label(key.Alias + " is a new type this dialog doesn't support. Contact kOS devs."); } GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); - GUILayout.Label(new GUIContent(labelText,toolTipText), panelSkin.label); + GUILayout.Label(new GUIContent(labelText, toolTipText), panelSkin.label); GUILayout.EndHorizontal(); CountEndHorizontal(); } CountEndVertical(); - + CountEndHorizontal(); - - + // This is where tooltip hover text will show up, rather than in a hover box wherever the pointer is like normal. // Unity doesn't do hovering tooltips and you have to specify a zone for them to appear like this: string whichMessage = (GUI.tooltip.Length > 0 ? GUI.tooltip : TelnetStatusMessage()); // when tooltip isn't showing, show telnet status instead. @@ -412,28 +417,28 @@ public void DrawWindow(int windowID) EndHoverHousekeeping(); GUI.SetNextControlName(""); // because if you don't then there is no such thing as the "non" control to move the focus to. - // This is an invisible dummy control to "focus on" to, basically, unfocus, because Unity didn't - // provide an unfocus method. + // This is an invisible dummy control to "focus on" to, basically, unfocus, because Unity didn't + // provide an unfocus method. } - + private int DrawConfigIntField(int keyVal, int whichInt) { int returnValue = keyVal; // no change, by default - return what was passed. - string fieldName = String.Format("CONFIG_intfield_{0}",whichInt); - + string fieldName = String.Format("CONFIG_intfield_{0}", whichInt); + bool hasFocus = GUI.GetNameOfFocusedControl().Equals(fieldName); bool userHitReturnThisPass = hasFocus && (Event.current.keyCode == KeyCode.Return || Event.current.keyCode == KeyCode.KeypadEnter); int backInt = backingConfigInts[whichInt]; string fieldValue = (backInt == 0) ? "" : backInt.ToString(); // this lets the user temporarily delete the whole value instead of having it become a zero. - + GUI.SetNextControlName(fieldName); fieldValue = GUILayout.TextField(fieldValue, 6, panelSkin.textField, GUILayout.MinWidth(60)); fieldValue = fieldValue.Trim(' '); int newInt = -99; // Nonzero value to act as a flag to detect if the following line got triggered: - if (fieldValue.Length == 0 ) + if (fieldValue.Length == 0) newInt = 0;// Empty or whitespace input should be a zero, instead of letting int.TryParse() call it an error. - if ( newInt == 0 || int.TryParse(fieldValue, out newInt)) + if (newInt == 0 || int.TryParse(fieldValue, out newInt)) { backingConfigInts[whichInt] = newInt; // Don't commit the temp value back to the CONFIGs unless RETURN is being pressed right now: @@ -444,76 +449,75 @@ private int DrawConfigIntField(int keyVal, int whichInt) } // (Upon committing the value back to config, config will range-check it and clamp it if its out of range). } - // else it reverts to what it was and wipes the typing if you don't assign it to anything. - + // else it reverts to what it was and wipes the typing if you don't assign it to anything. + // Lastly, check for losing the focus - when focus is lost (i.e. user clicks outside the textfield), then // revert the backing value to the config value, throwing away edits. if (!hasFocus) backingConfigInts[whichInt] = keyVal; - - + return returnValue; } private string TelnetStatusMessage() { - if (TelnetMainServer.Instance == null) // We can't control the order in which monobeavhiors are loaded, so TelnetMainServer might not be there yet. + if (TelnetMainServer.Instance == null) // We can't control the order in which monobeavhiors are loaded, so TelnetMainServer might not be there yet. return "TelnetMainServer object not found"; // hopefully the user never sees this. It should stop happening the the time the loading screen is over. bool isOn = TelnetMainServer.Instance.IsListening; if (!isOn) return "Telnet server disabled."; - + string addr = TelnetMainServer.Instance.BindAddr.ToString(); int numClients = TelnetMainServer.Instance.ClientCount; - + return String.Format("Telnet server listening on {0}. ({1} client{2} connected).", addr, (numClients == 0 ? "no" : numClients.ToString()), (numClients == 1 ? "" : "s")); } - + private void DrawActiveCPUsOnPanel() { - scrollPos = GUILayout.BeginScrollView(scrollPos, panelSkin.scrollView, GUILayout.MinWidth(260), GUILayout.Height(height-60)); - + scrollPos = GUILayout.BeginScrollView(scrollPos, panelSkin.scrollView, GUILayout.MinWidth(260), GUILayout.Height(windowRect.height - 60)); + CountBeginVertical(); Vessel prevVessel = null; bool atLeastOne = false; - + foreach (kOSProcessor kModule in kOSProcessor.AllInstances()) { - atLeastOne = true; + atLeastOne = true; Part thisPart = kModule.part; - Vessel thisVessel = (thisPart==null) ? null : thisPart.vessel; + Vessel thisVessel = (thisPart == null) ? null : thisPart.vessel; // For each new vessel in the list, start a new vessel section: if (thisVessel != null && thisVessel != prevVessel) { - GUILayout.Box(thisVessel.GetName(),vesselNameStyle); + GUILayout.Box(thisVessel.GetName(), vesselNameStyle); prevVessel = thisVessel; } DrawPartRow(thisPart); } - if (! atLeastOne) + if (!atLeastOne) GUILayout.Label("No Loaded CPUs Found.\n" + "-------------------------\n" + "There are either no kOS CPU's\n" + "in this universe, or there are\n " + - "but they are all \"on rails\".", panelSkin.label ); + "but they are all \"on rails\".", panelSkin.label); CountEndVertical(); GUILayout.EndScrollView(); } - + private void DrawPartRow(Part part) { CountBeginHorizontal(); - + DrawPart(part); - + kOSProcessor processorModule = part.Modules.OfType().FirstOrDefault(); if (processorModule == null) { - throw new ArgumentException("Part does not have a kOSProcessor module", "part"); + throw new ArgumentException(@"Part does not have a kOSProcessor module", "part"); } GUIStyle powerBoxStyle; @@ -521,26 +525,26 @@ private void DrawPartRow(Part part) string powerLabelTooltip; if (processorModule.ProcessorMode == ProcessorModes.STARVED) { - powerBoxStyle = boxDisabledStyle; - powerLabelText = "power\n"; - powerLabelTooltip = "Highlighted CPU has no ElectricCharge."; + powerBoxStyle = boxDisabledStyle; + powerLabelText = "power\n"; + powerLabelTooltip = "Highlighted CPU has no ElectricCharge."; } else if (processorModule.ProcessorMode == ProcessorModes.READY) { - powerBoxStyle = boxOnStyle; - powerLabelText = "power\non"; - powerLabelTooltip = "Highlighted CPU is turned on and running.\n"; + powerBoxStyle = boxOnStyle; + powerLabelText = "power\non"; + powerLabelTooltip = "Highlighted CPU is turned on and running.\n"; } else { - powerBoxStyle = boxOffStyle; - powerLabelText = "power\noff"; - powerLabelTooltip = "Highlighted CPU is turned off."; + powerBoxStyle = boxOffStyle; + powerLabelText = "power\noff"; + powerLabelTooltip = "Highlighted CPU is turned off."; } - GUILayout.Box( new GUIContent(powerLabelText, powerLabelTooltip), powerBoxStyle); + GUILayout.Box(new GUIContent(powerLabelText, powerLabelTooltip), powerBoxStyle); - if (GUILayout.Button((processorModule.WindowIsOpen() ? + if (GUILayout.Button((processorModule.WindowIsOpen() ? new GUIContent((processorModule.TelnetIsAttached() ? terminalOpenTelnetIconTexture : terminalOpenIconTexture), "Click to close terminal window.") : new GUIContent((processorModule.TelnetIsAttached() ? terminalClosedTelnetIconTexture : terminalClosedIconTexture), @@ -552,7 +556,7 @@ private void DrawPartRow(Part part) CheckHoverOnPreviousGUIElement(part); } - + private void DrawPart(Part part) { // Someday we may work on making this into something that @@ -571,39 +575,39 @@ private void DrawPart(Part part) // documentation with zero examples. // So for the meantime let's use our own text label and leave it at that. - + KOSNameTag partTag = part.Modules.OfType().FirstOrDefault(); string labelText = String.Format("{0}\n({1})", part.partInfo.title.Split(' ')[0], // just the first word of the name, i.e "CX-4181" - ((partTag==null) ? "" : partTag.nameTag) + ((partTag == null) ? "" : partTag.nameTag) ); GUILayout.Box(new GUIContent(labelText, "This is the currently highlighted part on the vessel"), partNameStyle); } - + public void BeginHoverHousekeeping() { // OnGUI() gets called many times in different modes for different reasons. // This logic only works right when used during the Repaint pass of OnGUI(). if (Event.current.type != EventType.Repaint) return; - + // Track whether or not the mouse is over the desired GUI element on *this* OnGUI // by clearing out what it was before first: newHoverPart = null; } - + /// /// Control the highlighting of parts in the vessel depending on whether or not /// the mouse was hovering in the right spot to cause a highlight. /// public void EndHoverHousekeeping() { - // OnGUI() gets called many times in different modes for different reasons. + // OnGUI() gets called many times in different modes for different reasons. // This logic only works right when used during the Repaint pass of OnGUI(). if (Event.current.type != EventType.Repaint) return; - + // If we were already highlighting a part, and are no longer hovering over // that part area in the panel, then de-highlight it: if (prevHoverPart != null && prevHoverPart != newHoverPart) @@ -611,7 +615,7 @@ public void EndHoverHousekeeping() prevHoverPart.SetHighlightColor(originalPartHighlightColor); prevHoverPart.SetHighlight(false, false); } - + // If we are now hovering over a part area in the panel, then start highlighting it, // remembering what it was before so it cab be set back again. if (newHoverPart != null && prevHoverPart != newHoverPart) @@ -629,85 +633,79 @@ public void EndHoverHousekeeping() /// The part that just had info drawn for it public void CheckHoverOnPreviousGUIElement(Part part) { - // OnGUI() gets called many times in different modes for different reasons. + // OnGUI() gets called many times in different modes for different reasons. // This logic only works right when used during the Repaint pass of OnGUI(). if (Event.current.type != EventType.Repaint) return; - + if (GUILayoutUtility.GetLastRect().Contains(Event.current.mousePosition)) newHoverPart = part; } - - + // Tracking the count to help detect when there's a mismatch: // To help detect if a begin matches with an end, put the same // string in both of them and see if they get the same count here. - private void CountBeginVertical(string debugHelp="") + private void CountBeginVertical(string debugHelp = "") { - if (! String.IsNullOrEmpty(debugHelp)) - SafeHouse.Logger.SuperVerbose("BeginVertical(\""+debugHelp+"\") Nest "+verticalSectionCount); + if (!String.IsNullOrEmpty(debugHelp)) + SafeHouse.Logger.SuperVerbose("BeginVertical(\"" + debugHelp + "\") Nest " + verticalSectionCount); GUILayout.BeginVertical(); ++verticalSectionCount; } - + // Tracking the count to help detect when there's a mismatch: // To help detect if a begin matches with an end, put the same // string in both of them and see if they get the same count here. - private void CountEndVertical(string debugHelp="") + private void CountEndVertical(string debugHelp = "") { GUILayout.EndVertical(); - --verticalSectionCount; - if (! String.IsNullOrEmpty(debugHelp)) - SafeHouse.Logger.SuperVerbose("EndVertical(\""+debugHelp+"\") Nest "+verticalSectionCount); + --verticalSectionCount; + if (!String.IsNullOrEmpty(debugHelp)) + SafeHouse.Logger.SuperVerbose("EndVertical(\"" + debugHelp + "\") Nest " + verticalSectionCount); } - + // Tracking the count to help detect when there's a mismatch: // To help detect if a begin matches with an end, put the same // string in both of them and see if they get the same count here. - private void CountBeginHorizontal(string debugHelp="") + private void CountBeginHorizontal(string debugHelp = "") { - if (! String.IsNullOrEmpty(debugHelp)) - SafeHouse.Logger.SuperVerbose("BeginHorizontal(\""+debugHelp+"\"): Nest "+horizontalSectionCount); + if (!String.IsNullOrEmpty(debugHelp)) + SafeHouse.Logger.SuperVerbose("BeginHorizontal(\"" + debugHelp + "\"): Nest " + horizontalSectionCount); GUILayout.BeginHorizontal(); ++horizontalSectionCount; } - + // Tracking the count to help detect when there's a mismatch: // To help detect if a begin matches with an end, put the same // string in both of them and see if they get the same count here. - private void CountEndHorizontal(string debugHelp="") + private void CountEndHorizontal(string debugHelp = "") { GUILayout.EndHorizontal(); - --horizontalSectionCount; - if (! String.IsNullOrEmpty(debugHelp)) - SafeHouse.Logger.SuperVerbose("EndHorizontal(\""+debugHelp+"\"): Nest "+horizontalSectionCount); + --horizontalSectionCount; + if (!String.IsNullOrEmpty(debugHelp)) + SafeHouse.Logger.SuperVerbose("EndHorizontal(\"" + debugHelp + "\"): Nest " + horizontalSectionCount); } - - + private static GUISkin BuildPanelSkin() { GUISkin theSkin = Utils.GetSkinCopy(HighLogic.Skin); // theSkin won't actually be used directly anymore because GetSkinCopy is missing a few key // fields. Instead we'll have to set all the GUIStyle's manually everywhere - ugly. - + // Now alter the parts of theSkin that we want to change: // theSkin.window = new GUIStyle(HighLogic.Skin.window); theSkin.box.fontSize = 11; - theSkin.box.padding = new RectOffset(5,3,3,5); - theSkin.box.margin = new RectOffset(1,1,1,1); + theSkin.box.padding = new RectOffset(5, 3, 3, 5); + theSkin.box.margin = new RectOffset(1, 1, 1, 1); theSkin.label.fontSize = 11; - theSkin.label.padding = new RectOffset(2,2,2,2); - theSkin.label.margin = new RectOffset(1,1,1,1); theSkin.textField.fontSize = 11; - theSkin.textField.padding = new RectOffset(0,0,0,0); - theSkin.textField.margin = new RectOffset(1,1,1,1); + theSkin.textField.padding = new RectOffset(0, 0, 0, 0); + theSkin.textField.margin = new RectOffset(1, 1, 1, 1); theSkin.textArea.fontSize = 11; - theSkin.textArea.padding = new RectOffset(0,0,0,0); - theSkin.textArea.margin = new RectOffset(1,1,1,1); - theSkin.toggle.fontSize = 11; - theSkin.toggle.padding = new RectOffset(0,0,0,0); - theSkin.toggle.margin = new RectOffset(1,1,1,1); + theSkin.textArea.padding = new RectOffset(0, 0, 0, 0); + theSkin.textArea.margin = new RectOffset(1, 1, 1, 1); + theSkin.toggle.fontSize = 10; theSkin.button.fontSize =11; theSkin.button.padding = new RectOffset(0,0,0,0); theSkin.button.margin = new RectOffset(1,1,1,1); @@ -716,41 +714,40 @@ private static GUISkin BuildPanelSkin() // headingLabelStyle = new GUIStyle(theSkin.label) { - fontSize = 13, + fontSize = 13, padding = new RectOffset(2, 2, 2, 2) }; vesselNameStyle = new GUIStyle(theSkin.box) { - fontSize = 12, - normal = {textColor = Color.white} + fontSize = 12, + normal = { textColor = Color.white } }; tooltipLabelStyle = new GUIStyle(theSkin.label) { fontSize = 11, padding = new RectOffset(0, 2, 0, 2), - normal = {textColor = Color.white} + normal = { textColor = Color.white } }; partNameStyle = new GUIStyle(theSkin.box) { - hover = {textColor = new Color(0.6f,1.0f,1.0f)} + hover = { textColor = new Color(0.6f, 1.0f, 1.0f) } }; boxOnStyle = new GUIStyle(theSkin.box) { - hover = {textColor = new Color(0.6f,1.0f,1.0f)}, - normal = {textColor = new Color(0.4f,1.0f,0.4f)} // brighter green, higher saturation. + hover = { textColor = new Color(0.6f, 1.0f, 1.0f) }, + normal = { textColor = new Color(0.4f, 1.0f, 0.4f) } // brighter green, higher saturation. }; boxOffStyle = new GUIStyle(theSkin.box) { - hover = {textColor = new Color(0.6f,1.0f,1.0f)}, - normal = {textColor = new Color(0.6f,0.7f,0.6f)} // dimmer green, more washed out and grey. + hover = { textColor = new Color(0.6f, 1.0f, 1.0f) }, + normal = { textColor = new Color(0.6f, 0.7f, 0.6f) } // dimmer green, more washed out and grey. }; boxDisabledStyle = new GUIStyle(theSkin.box) { - hover = {textColor = new Color(0.6f,1.0f,1.0f)}, - normal = {textColor = Color.white} + hover = { textColor = new Color(0.6f, 1.0f, 1.0f) }, + normal = { textColor = Color.white } }; return theSkin; } - } -} +} \ No newline at end of file diff --git a/src/kOS/Screen/RectExtensions.cs b/src/kOS/Screen/RectExtensions.cs new file mode 100644 index 000000000..48f267b9c --- /dev/null +++ b/src/kOS/Screen/RectExtensions.cs @@ -0,0 +1,117 @@ +// this file is based on RectExtensions.cs from InfernalRobotics + +using System; +using UnityEngine; + +namespace kOS.Screen +{ + public static class RectExtensions + { + public static Rect ScreenRect() + { + return new Rect(0, 0, UnityEngine.Screen.width, UnityEngine.Screen.height); + } + + public static Rect EnsureVisible(Rect pos, float min = 16.0f) + { + return EnsurePartiallyInside(pos, ScreenRect(), min); + } + + public static Rect EnsurePartiallyInside(Rect pos, Rect target, float min = 16.0f) + { + float xMin = target.x + min - pos.width; + float xMax = target.xMax - min; + float yMin = target.y + min - pos.height; + float yMax = target.yMax - min; + + pos.x = Mathf.Clamp(pos.x, xMin, xMax); + pos.y = Mathf.Clamp(pos.y, yMin, yMax); + + return pos; + } + + public static Rect EnsureCompletelyVisible(Rect pos) + { + return EnsureCompletelyInside(pos, ScreenRect()); + } + + public static Rect EnsureCompletelyInside(Rect pos, Rect target) + { + float xMin = target.x; + float xMax = target.xMax - pos.width; + float yMin = target.y; + float yMax = target.yMax - pos.height; + + pos.x = Mathf.Clamp(pos.x, xMin, xMax); + pos.y = Mathf.Clamp(pos.y, yMin, yMax); + + return pos; + } + + public static Rect ClampToScreenEdge(Rect pos) + { + return ClampToRectEdge(pos, ScreenRect()); + } + + public static Rect ClampToRectEdge(Rect pos, Rect target) + { + float topSeparation = Math.Abs(target.y - pos.y); + float bottomSeparation = Math.Abs(target.yMax - pos.yMax); + float leftSeparation = Math.Abs(target.x - pos.x); + float rightSeparation = Math.Abs(target.xMax - pos.xMax); + + if (topSeparation <= bottomSeparation && topSeparation <= leftSeparation && topSeparation <= rightSeparation) + { + pos.y = target.y; + } + else if (leftSeparation <= topSeparation && leftSeparation <= bottomSeparation && + leftSeparation <= rightSeparation) + { + pos.x = target.x; + } + else if (bottomSeparation <= topSeparation && bottomSeparation <= leftSeparation && + bottomSeparation <= rightSeparation) + { + pos.y = target.yMax - pos.height; + } + else if (rightSeparation <= topSeparation && rightSeparation <= bottomSeparation && + rightSeparation <= leftSeparation) + { + pos.x = target.xMax - pos.width; + } + + return pos; + } + + public static Rect ClampToScreenAngle(Rect pos) + { + return ClampToRectAngle(pos, ScreenRect()); + } + + public static Rect ClampToRectAngle(Rect pos, Rect target) + { + float topSeparation = Math.Abs(target.y - pos.y); + float bottomSeparation = Math.Abs(target.yMax - pos.yMax); + float leftSeparation = Math.Abs(target.x - pos.x); + float rightSeparation = Math.Abs(target.xMax - pos.xMax); + + if (topSeparation <= bottomSeparation) { + pos.y = target.y; + } + else + { + pos.y = target.yMax - pos.height; + } + if (leftSeparation <= rightSeparation) + { + pos.x = target.x; + } + else + { + pos.x = target.xMax - pos.width; + } + + return pos; + } + } +} diff --git a/src/kOS/Screen/TermWindow.cs b/src/kOS/Screen/TermWindow.cs index 0a7698b15..4a2ec26d4 100644 --- a/src/kOS/Screen/TermWindow.cs +++ b/src/kOS/Screen/TermWindow.cs @@ -13,23 +13,34 @@ namespace kOS.Screen // Blockotronix 550 Computor Monitor public class TermWindow : KOSManagedWindow , ITermWindow { - private const int CHARSIZE = 8; + /// + /// Pixel size of one square section of the font template image file holding one character: + /// + private const int CHAR_SOURCE_SIZE = 8; + private const string CONTROL_LOCKOUT = "kOSTerminal"; private const int FONTIMAGE_CHARS_PER_ROW = 16; private static readonly string root = KSPUtil.ApplicationRootPath.Replace("\\", "/"); - private static readonly Color color = new Color(1, 1, 1, 1); - private static readonly Color colorAlpha = new Color(0.9f, 0.9f, 0.9f, 0.6f); - private static readonly Color textColor = new Color(0.45f, 0.92f, 0.23f, 0.9f); - private static readonly Color textColorAlpha = new Color(0.45f, 0.92f, 0.23f, 0.5f); - private static readonly Color textColorOff = new Color(0.8f, 0.8f, 0.8f, 0.7f); - private static readonly Color textColorOffAlpha = new Color(0.8f, 0.8f, 0.8f, 0.3f); + private static readonly Color color = new Color(1, 1, 1, 1); // opaque window color when focused + private static readonly Color colorAlpha = new Color(1f, 1f, 1f, 0.8f); // slightly less opaque window color when not focused. + private static readonly Color bgColor = new Color(0.0f, 0.0f, 0.0f, 1.0f); // black background of terminal + private static readonly Color textColor = new Color(0.4f, 1.0f, 0.2f, 1.0f); // font color on terminal + private static readonly Color textColorOff = new Color(0.8f, 0.8f, 0.8f, 0.7f); // font color when power starved. + private static readonly Color textColorOffAlpha = new Color(0.8f, 0.8f, 0.8f, 0.8f); // font color when power starved and not focused. private Rect closeButtonRect = new Rect(0, 0, 0, 0); // will be resized later. private Rect resizeButtonCoords = new Rect(0,0,0,0); // will be resized later. + private GUIStyle tinyToggleStyle; private Vector2 resizeOldSize; private bool resizeMouseDown; + private int formerCharPixelHeight; + private int formerCharPixelWidth; private bool consumeEvent; + private bool fontGotResized; + private bool keyClickEnabled; + + private bool collapseFastBeepsToOneBeep = false; // This is a setting we might want to fiddle with depending on opinion. private KeyBinding rememberThrottleCutoffKey; private KeyBinding rememberThrottleFullKey; @@ -38,14 +49,34 @@ public class TermWindow : KOSManagedWindow , ITermWindow private CameraManager cameraManager; private float cursorBlinkTime; private Texture2D fontImage = new Texture2D(0, 0, TextureFormat.DXT1, false); + private Texture2D [] fontArray; private bool isLocked; + /// How long blinks should last for, for various blinking needs + private readonly TimeSpan blinkDuration = TimeSpan.FromMilliseconds(150); + /// How long to pad between consecutive blinks to ensure they are visibly detectable as distinct blinks. + private readonly TimeSpan blinkCoolDownDuration = TimeSpan.FromMilliseconds(50); + /// At what milliseconds-from-epoch timestamp will the current blink be over. + private DateTime blinkEndTime; + private Color currentTextColor; + + /// Telnet repaints happen less often than Update()s. Not every Update() has a telnet repaint happening. + /// This tells you whether there was one this update. + private bool telnetsGotRepainted; + private Texture2D terminalImage = new Texture2D(0, 0, TextureFormat.DXT1, false); + private Texture2D terminalFrameImage = new Texture2D(0, 0, TextureFormat.DXT1, false); + private Texture2D terminalFrameActiveImage = new Texture2D(0, 0, TextureFormat.DXT1, false); private Texture2D resizeButtonImage = new Texture2D(0, 0, TextureFormat.DXT1, false); private Texture2D networkZigZagImage = new Texture2D(0, 0, TextureFormat.DXT1, false); - + private Texture2D brightnessButtonImage = new Texture2D(0, 0, TextureFormat.DXT1, false); + private Texture2D fontWidthButtonImage = new Texture2D(0, 0, TextureFormat.DXT1, false); + private Texture2D fontHeightButtonImage = new Texture2D(0, 0, TextureFormat.DXT1, false); + private WWW beepURL; + private AudioSource beepSource; + private int guiTerminalBeepsPending; + private SharedObjects shared; private KOSTextEditPopup popupEditor; - private Color currentTextColor = new Color(1,1,1,1); // a dummy color at first just so it won't crash before TerminalGUI() where it's *really* set. // data stored per telnet client attached: private readonly List telnets; // support exists for more than one telnet client to be attached to the same terminal, thus this is a list. @@ -60,6 +91,10 @@ public class TermWindow : KOSManagedWindow , ITermWindow private DateTime lastBufferGet = DateTime.Now; private DateTime lastTelnetIncrementalRepaint = DateTime.Now; + private GUISkin customSkin; + + private bool uiGloballyHidden = false; + public TermWindow() { @@ -73,15 +108,76 @@ public TermWindow() public void Awake() { - LoadTexture("GameData/kOS/GFX/font_sml.png", ref fontImage); LoadTexture("GameData/kOS/GFX/monitor_minimal.png", ref terminalImage); + LoadTexture("GameData/kOS/GFX/monitor_minimal_frame.png", ref terminalFrameImage); + LoadTexture("GameData/kOS/GFX/monitor_minimal_frame_active.png", ref terminalFrameActiveImage); LoadTexture("GameData/kOS/GFX/resize-button.png", ref resizeButtonImage); LoadTexture("GameData/kOS/GFX/network-zigzag.png", ref networkZigZagImage); + LoadTexture("GameData/kOS/GFX/brightness-button.png", ref brightnessButtonImage); + LoadTexture("GameData/kOS/GFX/font-width-button.png", ref fontWidthButtonImage); + LoadTexture("GameData/kOS/GFX/font-height-button.png", ref fontHeightButtonImage); + LoadTexture("GameData/kOS/GFX/font_sml.png", ref fontImage); + + LoadFontArray(); + LoadAudio(); + + tinyToggleStyle = new GUIStyle(HighLogic.Skin.toggle) + { + fontSize = 10 + }; + var gObj = new GameObject( "texteditPopup", typeof(KOSTextEditPopup) ); DontDestroyOnLoad(gObj); popupEditor = (KOSTextEditPopup)gObj.GetComponent(typeof(KOSTextEditPopup)); popupEditor.SetUniqueId(UniqueId + 5); + + customSkin = BuildPanelSkin(); + + GameEvents.onHideUI.Add (OnHideUI); + GameEvents.onShowUI.Add (OnShowUI); + } + + public void OnDestroy() + { + GameEvents.onHideUI.Remove(OnHideUI); + GameEvents.onShowUI.Remove(OnShowUI); + } + + private void LoadFontArray() + { + // Make it hold all possible ASCII values even though many will be blank pictures: + fontArray = new Texture2D[128]; + + for (int i = 0 ; i < 128 ; ++i) + { + // TextureFormat cannot be DXT1 or DXT5 if you want to ever perform a + // SetPixel on the texture (which we do). So we start it off as a ARGB32 + // first, long enough to perform the SetPixel call, then compress it + // afterward into a DXT5: + Texture2D charImage = new Texture2D(CHAR_SOURCE_SIZE, CHAR_SOURCE_SIZE, TextureFormat.ARGB32, true); + + int tx = i % FONTIMAGE_CHARS_PER_ROW; + int ty = i / FONTIMAGE_CHARS_PER_ROW; + + // While Unity uses the convention of upside down textures common in + // 3D (2D images put orgin at upper-left, 3D uses lower-left), it doesn't seem + // to apply this rule to textures loaded from files like the fontImage. + // Thus the difference requiring the upside-down Y coord below. + charImage.SetPixels(fontImage.GetPixels(tx * CHAR_SOURCE_SIZE, fontImage.height - (ty+1) * CHAR_SOURCE_SIZE, CHAR_SOURCE_SIZE, CHAR_SOURCE_SIZE)); + charImage.Compress(false); + charImage.Apply(); + + fontArray[i] = charImage; + } + } + + private void LoadAudio() + { + beepURL = new WWW("file://"+ root + "GameData/kOS/GFX/terminal-beep.wav"); + AudioClip beepClip = beepURL.audioClip; + beepSource = gameObject.AddComponent(); + beepSource.clip = beepClip; } public void LoadTexture(String relativePath, ref Texture2D targetTexture) @@ -98,6 +194,16 @@ public void OpenPopupEditor( Volume v, string fName ) popupEditor.Open(); } + void OnHideUI() + { + uiGloballyHidden = true; + } + + void OnShowUI() + { + uiGloballyHidden = false; + } + public override void GetFocus() { Lock(); @@ -112,6 +218,7 @@ public override void Open() { base.Open(); BringToFront(); + guiTerminalBeepsPending = 0; // Closing and opening the window will wipe pending beeps from the beep queue. } public override void Close() @@ -186,7 +293,8 @@ void OnGUI() try { - if (PauseMenu.isOpen || FlightResultsDialog.isDisplaying) return; + if (FlightResultsDialog.isDisplaying) return; + if (uiGloballyHidden && kOS.Safe.Utilities.SafeHouse.Config.ObeyHideUI) return; } catch(NullReferenceException) { @@ -219,10 +327,20 @@ void Update() GetNewestBuffer(); TelnetOutputUpdate(); ProcessTelnetInput(); // want to do this even when the terminal isn't actually displaying. + if (telnetsGotRepainted) + { + // Move the beeps from the screenbuffer "queue" to my own local terminal "queue". + // This is only done in the Update() when telentRepaint got triggered + // because otherwise the GUI terminal could wipe shared.Screen.BeepsPending to zero during an update + // where the telnet terminal never saw the beeps pending and never knew to print the beeps out. + guiTerminalBeepsPending += shared.Screen.BeepsPending; + shared.Screen.BeepsPending = 0; // Presume all the beeping has been dealt with for both the telnets and the GUI terminal. + } if (!IsOpen ) return; UpdateLogic(); + UpdateGUIBeeps(); if (!isLocked) return; @@ -230,9 +348,63 @@ void Update() if (cursorBlinkTime > 1) cursorBlinkTime -= 1; } + void UpdateGUIBeeps() + { + // Eat just one beep off the pending queue. Wait for a future + // Update() to consume more, if there are any more: + if (guiTerminalBeepsPending > 0) + { + // Behavior depending on whether we'd like BEEP, BEEP, BEEP to + // emit 3 back to back beeps, or just one beep ingoring overlapping beeps. + // Many hardware terminals only emit one beep when given a string + // of lots of beeps. + if (collapseFastBeepsToOneBeep) + { + Beep(); + guiTerminalBeepsPending = 0; + } + else + { + if (Beep()) + --guiTerminalBeepsPending; + } + } + } + + /// + /// Attempts to make Unity start a playthrough of the beep audio clip. The playthrough will continue + /// on its own in the background while the rest of the code continues on. It will do nothing if the previous + /// beep is still being played. (We only gave ourselves one audio beep source per GUI terminal so we can't play beeps + /// simultaneously.)
+ /// Addendum: It will redirect into a visual beep if that is called for instead. + ///
+ /// true if it beeped. false if it coudn't beep yet (because the audio source is still busy emitting the previous beep). + bool Beep() + { + if (shared.Screen.VisualBeep) + { + DateTime nowTime = DateTime.Now; + if (nowTime < (blinkEndTime + (blinkCoolDownDuration))) // prev blink not done yet. + return false; + + // Turning this timer on tells GUI repainter elsewhere in this class to paint in reverse until it expires: + blinkEndTime = nowTime + blinkDuration; + } + else + { + if (!beepSource.clip.isReadyToPlay || beepSource.isPlaying) + return false; // prev beep sound still is happening. + + // This is nonblocking. Begins playing sound in background. Code will not wait for it to finish: + beepSource.Play(); + } + return true; + } + void TelnetOutputUpdate() { DateTime newTime = DateTime.Now; + telnetsGotRepainted = false; // Throttle it back so the faster Update() rates don't cause pointlessly repeated work: // Needs to be no faster than the fastest theoretical typist or script might change the view. @@ -243,6 +415,7 @@ void TelnetOutputUpdate() { RepaintTelnet(telnet, false); // try the incremental differ update. } + telnetsGotRepainted = true; } } @@ -448,6 +621,8 @@ void Type(char ch) if (shared != null && shared.Interpreter != null) { shared.Interpreter.Type(ch); + if (IsOpen && keyClickEnabled) + shared.SoundMaker.BeginSound("click"); } } @@ -455,7 +630,9 @@ void SpecialKey(char key) { if (shared != null && shared.Interpreter != null) { - shared.Interpreter.SpecialKey(key); + bool wasUsed = shared.Interpreter.SpecialKey(key); + if (IsOpen && keyClickEnabled && wasUsed) + shared.SoundMaker.BeginSound("click"); } } @@ -489,7 +666,6 @@ void TerminalGui(int windowId) "go to the following folder: \n\n\\GameData\\kOS\\GFX\\ \n\nand ensure that the png texture files are there."); GUI.Label(closeButtonRect, "Close"); - return; } @@ -498,7 +674,7 @@ void TerminalGui(int windowId) return; } IScreenBuffer screen = shared.Screen; - + GUI.color = isLocked ? color : colorAlpha; GUI.DrawTexture(new Rect(15, 20, WindowRect.width-30, WindowRect.height-55), terminalImage); @@ -506,6 +682,20 @@ void TerminalGui(int windowId) DrawTelnetStatus(); closeButtonRect = new Rect(WindowRect.width-75, WindowRect.height-30, 50, 25); + Rect reverseButtonRect = new Rect(WindowRect.width-180, WindowRect.height-42, 100, 18); + Rect visualBeepButtonRect = new Rect(WindowRect.width-180, WindowRect.height-22, 100, 18); + Rect keyClickButtonRect = new Rect(10, WindowRect.height - 22, 85, 18); + Rect rasterBarsButtonRect = new Rect(10, WindowRect.height - 42, 85, 18); + Rect brightnessRect = new Rect(3, WindowRect.height - 100, 8, 50); + Rect brightnessButtonRect = new Rect(1, WindowRect.height - 48, brightnessButtonImage.width, brightnessButtonImage.height); + Rect fontWidthButtonRect = new Rect(15, WindowRect.height-32, fontWidthButtonImage.width, fontWidthButtonImage.height); + Rect fontWidthLabelRect = new Rect(35, WindowRect.height-28, 20, 10); + Rect fontWidthLessButtonRect = new Rect(65, WindowRect.height-28, 10, 10); + Rect fontWidthMoreButtonRect = new Rect(90, WindowRect.height-28, 10, 10); + Rect fontHeightButtonRect = new Rect(140, WindowRect.height-32, fontHeightButtonImage.width, fontHeightButtonImage.height); + Rect fontHeightLabelRect = new Rect(160, WindowRect.height-28, 20, 10); + Rect fontHeightLessButtonRect = new Rect(185, WindowRect.height-28, 10, 10); + Rect fontHeightMoreButtonRect = new Rect(210, WindowRect.height-28, 10, 10); resizeButtonCoords = new Rect(WindowRect.width-resizeButtonImage.width, WindowRect.height-resizeButtonImage.height, @@ -526,18 +716,53 @@ void TerminalGui(int windowId) Close(); Event.current.Use(); } - - - if (IsPowered) - { - currentTextColor = isLocked ? textColor : textColorAlpha; - } - else + + screen.ReverseScreen = GUI.Toggle(reverseButtonRect, screen.ReverseScreen, "Reverse Screen", tinyToggleStyle); + screen.VisualBeep = GUI.Toggle(visualBeepButtonRect, screen.VisualBeep, "Visual Beep", tinyToggleStyle); + keyClickEnabled = GUI.Toggle(keyClickButtonRect, keyClickEnabled, "Keyclicker", tinyToggleStyle); + screen.Brightness = GUI.VerticalSlider(brightnessRect, screen.Brightness, 1f, 0f); + GUI.DrawTexture(brightnessButtonRect, brightnessButtonImage); + + int charWidth = screen.CharacterPixelWidth; + int charHeight = screen.CharacterPixelHeight; + + GUI.DrawTexture(fontWidthButtonRect, fontWidthButtonImage); + GUI.Label(fontWidthLabelRect,charWidth+"px", customSkin.label); + if (GUI.Button(fontWidthLessButtonRect, "-", customSkin.button)) + charWidth = Math.Max(4, charWidth - 2); + if (GUI.Button(fontWidthMoreButtonRect, "+", customSkin.button)) + charWidth = Math.Min(24, charWidth + 2); + + GUI.DrawTexture(fontHeightButtonRect, fontHeightButtonImage); + GUI.Label(fontHeightLabelRect,charHeight+"px", customSkin.label); + if (GUI.Button(fontHeightLessButtonRect, "-", customSkin.button)) + charHeight = Math.Max(4, charHeight - 2); + if (GUI.Button(fontHeightMoreButtonRect, "+", customSkin.button)) + charHeight = Math.Min(24, charHeight + 2); + + screen.CharacterPixelWidth = charWidth; + screen.CharacterPixelHeight = charHeight; + + fontGotResized = false; + if (formerCharPixelWidth != screen.CharacterPixelWidth || formerCharPixelHeight != screen.CharacterPixelHeight) { - currentTextColor = isLocked ? textColorOff : textColorOffAlpha; + formerCharPixelWidth = screen.CharacterPixelWidth; + formerCharPixelHeight = screen.CharacterPixelHeight; + screen.SetSize(HowManyRowsFit(), HowManyColumnsFit()); + fontGotResized = true; } - GUI.BeginGroup(new Rect(28, 38, screen.ColumnCount*CHARSIZE, screen.RowCount*CHARSIZE)); + currentTextColor = IsPowered ? textColor : textColorOff; + + // Paint the background color. + DateTime nowTime = DateTime.Now; + bool reversingScreen = (nowTime > blinkEndTime) ? screen.ReverseScreen : (!screen.ReverseScreen); + if (reversingScreen) + { // In reverse screen mode, draw a big rectangle in foreground color across the whole active screen area: + GUI.color = AdjustColor(textColor, screen.Brightness); + GUI.DrawTexture(new Rect(15, 20, WindowRect.width-30, WindowRect.height-55), Texture2D.whiteTexture, ScaleMode.ScaleAndCrop ); + } + GUI.BeginGroup(new Rect(28, 38, screen.ColumnCount * charWidth, screen.RowCount * charHeight)); List buffer = mostRecentScreen.Buffer; // just to keep the name shorter below: @@ -550,7 +775,9 @@ void TerminalGui(int windowId) for (int column = 0; column < lineBuffer.Length; column++) { char c = lineBuffer[column]; - if (c != 0 && c != 9 && c != 32) ShowCharacterByAscii(c, column, row, currentTextColor); + if (c != 0 && c != 9 && c != 32) + ShowCharacterByAscii(c, column, row, currentTextColor, reversingScreen, + charWidth, charHeight, screen.Brightness); } } @@ -561,15 +788,34 @@ void TerminalGui(int windowId) if (blinkOn) { - ShowCharacterByAscii((char)1, screen.CursorColumnShow, screen.CursorRowShow, currentTextColor); + ShowCharacterByAscii((char)1, screen.CursorColumnShow, screen.CursorRowShow, currentTextColor, reversingScreen, + charWidth, charHeight, screen.Brightness); } + GUI.EndGroup(); - GUI.Label(new Rect(WindowRect.width/2-40,WindowRect.height-20,100,10),screen.ColumnCount+"x"+screen.RowCount); + GUI.color = color; // screen size label was never supposed to be in green like the terminal is: + + // Draw the rounded corner frame atop the chars field, so it covers the sqaure corners of the character zone + // if they bleed over a bit. Also, change which variant is used depending on focus: + if (isLocked) + GUI.DrawTexture(new Rect(15, 20, WindowRect.width-30, WindowRect.height-55), terminalFrameActiveImage); + else + GUI.DrawTexture(new Rect(15, 20, WindowRect.width-30, WindowRect.height-55), terminalFrameImage); + + GUI.Label(new Rect(WindowRect.width/2-40, WindowRect.height-12,100,10), screen.ColumnCount+"x"+screen.RowCount, customSkin.label); - CheckResizeDrag(); // Has to occur before DragWindow or else DragWindow will consume the event and prevent drags from being seen by the resize icon. + if (!fontGotResized) + CheckResizeDrag(); // Has to occur before DragWindow or else DragWindow will consume the event and prevent drags from being seen by the resize icon. GUI.DragWindow(); } + + protected Color AdjustColor(Color baseColor, float brightness) + { + Color newColor = baseColor; + newColor.a = brightness; // represent dimness by making it fade into the backround. + return newColor; + } /// /// Draw a little status line at the bottom as a reminder that you are sharing the terminal with a telnet session: @@ -584,7 +830,7 @@ protected void DrawTelnetStatus() protected void CheckResizeDrag() { - if (Input.GetMouseButton(0)) // mouse button is down + if (Input.GetMouseButton(0) && !fontGotResized ) // mouse button is maybe dragging the frame { if (resizeMouseDown) // and it's in the midst of a drag. { @@ -612,19 +858,11 @@ protected void CheckResizeDrag() } } - void ShowCharacterByAscii(char ch, int x, int y, Color charTextColor) - { - int tx = ch % FONTIMAGE_CHARS_PER_ROW; - int ty = ch / FONTIMAGE_CHARS_PER_ROW; - - ShowCharacterByXY(x, y, tx, ty, charTextColor); - } - - void ShowCharacterByXY(int x, int y, int tx, int ty, Color charTextColor) + void ShowCharacterByAscii(char ch, int x, int y, Color charTextColor, bool reversingScreen, int charWidth, int charHeight, float brightness) { - GUI.BeginGroup(new Rect((x * CHARSIZE), (y * CHARSIZE), CHARSIZE, CHARSIZE)); - GUI.color = charTextColor; - GUI.DrawTexture(new Rect(tx * -CHARSIZE, ty * -CHARSIZE, fontImage.width, fontImage.height), fontImage); + GUI.BeginGroup(new Rect((x * charWidth), (y * charHeight), charWidth, charHeight)); + GUI.color = AdjustColor(reversingScreen ? bgColor : textColor, brightness); + GUI.DrawTexture(new Rect(0, 0, charWidth, charHeight), fontArray[ch], ScaleMode.StretchToFill, true); GUI.EndGroup(); } @@ -642,6 +880,13 @@ internal void AttachTo(SharedObjects sharedObj) { shared = sharedObj; shared.Window = this; + + shared.Screen.CharacterPixelWidth = 8; + shared.Screen.CharacterPixelHeight = 8; + shared.Screen.Brightness = 0.5f; + formerCharPixelWidth = shared.Screen.CharacterPixelWidth; + formerCharPixelHeight = shared.Screen.CharacterPixelHeight; + NotifyOfScreenResize(shared.Screen); shared.Screen.AddResizeNotifier(NotifyOfScreenResize); ChangeTitle(CalcualteTitle()); @@ -683,7 +928,7 @@ public void DetachAllTelnets() internal int NotifyOfScreenResize(IScreenBuffer sb) { - WindowRect = new Rect(WindowRect.xMin, WindowRect.yMin, sb.ColumnCount*CHARSIZE + 65, sb.RowCount*CHARSIZE + 100); + WindowRect = new Rect(WindowRect.xMin, WindowRect.yMin, sb.ColumnCount*sb.CharacterPixelWidth + 65, sb.RowCount*sb.CharacterPixelHeight + 100); foreach (TelnetSingletonServer telnet in telnets) { @@ -744,10 +989,24 @@ internal void RepaintTelnet(TelnetSingletonServer telnet, bool fullSync) return; } + // If the state of the screen reverse, or the visual bell flags, has changed since last time, + // spit out the characters to change the state: + if (telnet.ReverseScreen != shared.Screen.ReverseScreen) + { + telnet.Write(shared.Screen.ReverseScreen ? ((char)UnicodeCommand.REVERSESCREENMODE) : ((char)UnicodeCommand.NORMALSCREENMODE)); + telnet.ReverseScreen = shared.Screen.ReverseScreen; + } + if (telnet.VisualBeep != shared.Screen.VisualBeep) + { + telnet.Write(shared.Screen.VisualBeep ? ((char)UnicodeCommand.VISUALBEEPMODE) : ((char)UnicodeCommand.AUDIOBEEPMODE)); + telnet.VisualBeep = shared.Screen.VisualBeep; + } string updateText = mostRecentScreen.DiffFrom(prevTelnetScreens[telnet]); telnet.Write(updateText); prevTelnetScreens[telnet] = mostRecentScreen.DeepCopy(); + for (int i = 0 ; i < shared.Screen.BeepsPending ; ++i) + telnet.Write((char)UnicodeCommand.BEEP); // The terminal's UnicodeMapper will convert this to ascii 0x07 if the right terminal type. } /// @@ -817,13 +1076,28 @@ public int NumTelnets() private int HowManyRowsFit() { - return (int)(WindowRect.height - 100) / CHARSIZE; + return (int)(WindowRect.height - 100) / shared.Screen.CharacterPixelHeight; } private int HowManyColumnsFit() { - return (int)(WindowRect.width - 65) / CHARSIZE; + return (int)(WindowRect.width - 65) / shared.Screen.CharacterPixelWidth; } + + private static GUISkin BuildPanelSkin() + { + GUISkin theSkin = kOS.Utilities.Utils.GetSkinCopy(HighLogic.Skin); + + theSkin.label.fontSize = 10; + theSkin.label.normal.textColor = Color.white; + theSkin.label.padding = new RectOffset(0, 0, 0, 0); + theSkin.label.margin = new RectOffset(1, 1, 1, 1); + theSkin.button.fontSize = 10; + theSkin.button.padding = new RectOffset(0, 0, 0, 0); + theSkin.button.margin = new RectOffset(0, 0, 0, 0); + + return theSkin; + } } } diff --git a/src/kOS/Serialization/IHasSharedObjects.cs b/src/kOS/Serialization/IHasSharedObjects.cs new file mode 100644 index 000000000..a378df8d4 --- /dev/null +++ b/src/kOS/Serialization/IHasSharedObjects.cs @@ -0,0 +1,10 @@ +using kOS.Safe.Encapsulation; + +namespace kOS.Serialization +{ + public interface IHasSharedObjects + { + SharedObjects Shared { set; } + } +} + diff --git a/src/kOS/Serialization/SerializationMgr.cs b/src/kOS/Serialization/SerializationMgr.cs new file mode 100644 index 000000000..dff1bc4cb --- /dev/null +++ b/src/kOS/Serialization/SerializationMgr.cs @@ -0,0 +1,46 @@ +using System; +using kOS.Safe.Serialization; +using kOS.Safe.Encapsulation; +using System.Collections.Generic; +using kOS.Safe.Exceptions; +using kOS.Safe; + +namespace kOS.Serialization +{ + public class SerializationMgr : SafeSerializationMgr + { + private readonly SharedObjects sharedObjects; + + public SerializationMgr(SharedObjects sharedObjects) + { + this.sharedObjects = sharedObjects; + } + + public override SerializableStructure CreateInstance(string typeFullName, Dump data) + { + var deserializedType = Type.GetType(typeFullName) ?? + Type.GetType(typeFullName + ", " + typeof(SafeSerializationMgr).Assembly.FullName); + + if (deserializedType == null) + { + throw new KOSSerializationException("Unrecognized type: " + typeFullName); + } + + SerializableStructure instance = Activator.CreateInstance(deserializedType) as SerializableStructure; + + if (instance is IHasSharedObjects) + { + IHasSharedObjects withSharedObjects = instance as IHasSharedObjects; + withSharedObjects.Shared = sharedObjects; + } + + if (instance != null) + { + instance.LoadDump(data); + } + + return instance; + } + } +} + diff --git a/src/kOS/SharedObjects.cs b/src/kOS/SharedObjects.cs index 6873a8ae0..528035ce8 100644 --- a/src/kOS/SharedObjects.cs +++ b/src/kOS/SharedObjects.cs @@ -1,6 +1,5 @@ using kOS.Execution; using kOS.InterProcessor; -using kOS.Binding; using kOS.Factories; using kOS.Screen; @@ -9,7 +8,6 @@ namespace kOS public class SharedObjects : Safe.SharedObjects { public Vessel Vessel { get; set; } - public BindingManager BindingMgr { get; set; } public ProcessorManager ProcessorMgr { get; set; } public IFactory Factory { get; set; } public Part KSPPart { get; set; } diff --git a/src/kOS/Sound/SoundMaker.cs b/src/kOS/Sound/SoundMaker.cs new file mode 100644 index 000000000..955b4d590 --- /dev/null +++ b/src/kOS/Sound/SoundMaker.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; +using UnityEngine; +using kOS.Safe.Sound; + +namespace kOS.Sound +{ + /// + /// SoundMaker is the "unsafe" implementation of ISoundMaker, that has calls into the Unity API. + /// + [KSPAddon(KSPAddon.Startup.Instantly, true)] + public class SoundMaker : MonoBehaviour, ISoundMaker + { + private static SoundMaker myself; + public static ISoundMaker Instance {get{ return myself;}} + + private string kspDirectory = KSPUtil.ApplicationRootPath.Replace("\\", "/"); + private Dictionary sounds; + + // All kOS PartModules should actually share the single same instance of me: + void Awake() + { + myself = this; + sounds = new Dictionary(); + DontDestroyOnLoad(gameObject); + + LoadSound("beep", "file://"+ kspDirectory + "GameData/kOS/GFX/terminal-beep.wav"); + LoadSound("click", "file://"+ kspDirectory + "GameData/kOS/GFX/terminal-click.wav"); + LoadSound("error", "file://"+ kspDirectory + "GameData/kOS/GFX/error.wav"); + } + + + public void LoadSound(string name, string url) + { + WWW fileGetter = new WWW(url); + AudioClip clip = fileGetter.audioClip; + AudioSource source = gameObject.AddComponent(); + source.clip = clip; + + sounds[name] = source; + } + + public bool BeginSound(string name) + { + if (! sounds.ContainsKey(name)) + return false; + AudioSource source = sounds[name]; + source.volume = GameSettings.UI_VOLUME; + if (!source.clip.isReadyToPlay || source.isPlaying) + return false; // prev beep sound still is happening. + + // This is nonblocking. Begins playing sound in background. Code will not wait for it to finish: + source.Play(); + return true; + } + } +} diff --git a/src/kOS/Suffixed/ActiveResourceValue.cs b/src/kOS/Suffixed/ActiveResourceValue.cs index 75c19b526..d427aeaed 100644 --- a/src/kOS/Suffixed/ActiveResourceValue.cs +++ b/src/kOS/Suffixed/ActiveResourceValue.cs @@ -4,6 +4,7 @@ namespace kOS.Suffixed { + [kOS.Safe.Utilities.KOSNomenclature("ActiveResource")] public class ActiveResourceValue : Structure { private readonly Vessel.ActiveResource activeResource; @@ -18,9 +19,9 @@ public ActiveResourceValue(Vessel.ActiveResource activeResource, SharedObjects s private void InitializeActiveResourceSuffixes() { - AddSuffix("NAME", new Suffix(() => activeResource.info.name, "The name of the resource (eg LiguidFuel, ElectricCharge)")); - AddSuffix("AMOUNT", new Suffix(() => activeResource.amount, "The resources currently available")); - AddSuffix("CAPACITY", new Suffix(() => activeResource.maxAmount, "The total storage capacity currently available")); + AddSuffix("NAME", new Suffix(() => activeResource.info.name, "The name of the resource (eg LiguidFuel, ElectricCharge)")); + AddSuffix("AMOUNT", new Suffix(() => activeResource.amount, "The resources currently available")); + AddSuffix("CAPACITY", new Suffix(() => activeResource.maxAmount, "The total storage capacity currently available")); AddSuffix("PARTS", new Suffix>(() => PartValueFactory.ConstructGeneric(activeResource.parts, shared), "The containers for this resource")); } diff --git a/src/kOS/Suffixed/Addon.cs b/src/kOS/Suffixed/Addon.cs index 00ca7c2f8..fc4676dd4 100644 --- a/src/kOS/Suffixed/Addon.cs +++ b/src/kOS/Suffixed/Addon.cs @@ -1,35 +1,36 @@ -using kOS.Safe.Encapsulation; -using kOS.Safe.Encapsulation.Suffixes; -using System; - -namespace kOS.Suffixed -{ - /// - /// A generic addon description class for use in AddonList - /// Addons must inherit from this one to implement functions - /// - public abstract class Addon : Structure - { - protected readonly string addonName; - protected readonly SharedObjects shared; - - protected Addon(string name, SharedObjects shared) - { - addonName = name; - this.shared = shared; - InitializeSuffixes(); - } - - private void InitializeSuffixes() - { - AddSuffix("AVAILABLE", new Suffix(Available)); - } - - public abstract bool Available (); - - public override string ToString() - { - return string.Format("{0} Addon, name = " + addonName, base.ToString()); - } - } +using kOS.Safe.Encapsulation; +using kOS.Safe.Encapsulation.Suffixes; +using System; + +namespace kOS.Suffixed +{ + /// + /// A generic addon description class for use in AddonList + /// Addons must inherit from this one to implement functions + /// + [kOS.Safe.Utilities.KOSNomenclature("Addon")] + public abstract class Addon : Structure + { + protected readonly string addonName; + protected readonly SharedObjects shared; + + protected Addon(string name, SharedObjects shared) + { + addonName = name; + this.shared = shared; + InitializeSuffixes(); + } + + private void InitializeSuffixes() + { + AddSuffix("AVAILABLE", new Suffix(Available)); + } + + public abstract BooleanValue Available (); + + public override string ToString() + { + return string.Format("{0} Addon, name = " + addonName, base.ToString()); + } + } } \ No newline at end of file diff --git a/src/kOS/Suffixed/AddonList.cs b/src/kOS/Suffixed/AddonList.cs index 873e0bab2..424a473fc 100644 --- a/src/kOS/Suffixed/AddonList.cs +++ b/src/kOS/Suffixed/AddonList.cs @@ -1,31 +1,32 @@ -using kOS.Safe.Encapsulation; -using kOS.Safe.Encapsulation.Suffixes; - - -namespace kOS.Suffixed -{ - public class AddonList : Structure - { - private readonly SharedObjects shared; - - public AddonList(SharedObjects shared) - { - this.shared = shared; - - InitializeSuffixes(); - } - - private void InitializeSuffixes() - { - AddSuffix("KAC", new Suffix(() => new AddOns.KerbalAlarmClock.Addon(shared))); - AddSuffix("RT", new Suffix(() => new AddOns.RemoteTech.Addon(shared))); - AddSuffix("AGX", new Suffix(() => new AddOns.ActionGroupsExtended.Addon(shared))); - AddSuffix("IR", new Suffix(() => new AddOns.InfernalRobotics.Addon(shared))); - } - - public override string ToString() - { - return string.Format("{0} AddonList", base.ToString()); - } - } +using kOS.Safe.Encapsulation; +using kOS.Safe.Encapsulation.Suffixes; + + +namespace kOS.Suffixed +{ + [kOS.Safe.Utilities.KOSNomenclature("Addons")] + public class AddonList : Structure + { + private readonly SharedObjects shared; + + public AddonList(SharedObjects shared) + { + this.shared = shared; + + InitializeSuffixes(); + } + + private void InitializeSuffixes() + { + AddSuffix("KAC", new Suffix(() => new AddOns.KerbalAlarmClock.Addon(shared))); + AddSuffix("RT", new Suffix(() => new AddOns.RemoteTech.Addon(shared))); + AddSuffix("AGX", new Suffix(() => new AddOns.ActionGroupsExtended.Addon(shared))); + AddSuffix("IR", new Suffix(() => new AddOns.InfernalRobotics.Addon(shared))); + } + + public override string ToString() + { + return string.Format("{0} AddonList", base.ToString()); + } + } } \ No newline at end of file diff --git a/src/kOS/Suffixed/AggregateResourceValue.cs b/src/kOS/Suffixed/AggregateResourceValue.cs index 8c63b1b18..232af1a53 100644 --- a/src/kOS/Suffixed/AggregateResourceValue.cs +++ b/src/kOS/Suffixed/AggregateResourceValue.cs @@ -1,49 +1,61 @@ using System.Collections.Generic; +using System.Linq; using kOS.Safe.Encapsulation; using kOS.Safe.Encapsulation.Suffixes; using kOS.Suffixed.Part; namespace kOS.Suffixed { + [kOS.Safe.Utilities.KOSNomenclature("AggregateResource")] public class AggregateResourceValue : Structure { private readonly string name; private readonly SharedObjects shared; - private double amount; - private double capacity; - private readonly ListValue parts; private readonly float density; + private readonly List resources; public AggregateResourceValue(PartResourceDefinition definition, SharedObjects shared) { name = definition.name; density = definition.density; this.shared = shared; - amount = 0; - capacity = 0; - parts = new ListValue(); + resources = new List(); InitializeAggregateResourceSuffixes(); } private void InitializeAggregateResourceSuffixes() { - AddSuffix("NAME", new Suffix(() => name, "The name of the resource (eg LiguidFuel, ElectricCharge)")); - AddSuffix("DENSITY", new Suffix(() => density, "The density of the resource")); - AddSuffix("AMOUNT", new Suffix(() => amount, "The resources currently available")); - AddSuffix("CAPACITY", new Suffix(() => capacity, "The total storage capacity currently available")); - AddSuffix("PARTS", new Suffix>(() => parts, "The containers for this resource")); + AddSuffix("NAME", new Suffix(() => name, "The name of the resource (eg LiguidFuel, ElectricCharge)")); + AddSuffix("DENSITY", new Suffix(() => density, "The density of the resource")); + AddSuffix("AMOUNT", new Suffix(GetAmount, "The resources currently available")); + AddSuffix("CAPACITY", new Suffix(GetCapacity, "The total storage capacity currently available")); + AddSuffix("PARTS", new Suffix>(GetParts, "The containers for this resource")); + } + + private ListValue GetParts() + { + var parts = PartValueFactory.Construct(resources.Select(r => r.part), shared); + return ListValue.CreateList(parts); + } + + private ScalarValue GetCapacity() + { + return resources.Sum(r => r.maxAmount); + } + + private ScalarValue GetAmount() + { + return resources.Sum(r => r.amount); } public void AddResource(PartResource resource) { - amount += resource.amount; - capacity += resource.maxAmount; - parts.Add(new PartValue(resource.part, shared)); + resources.Add(resource); } public override string ToString() { - return string.Format("SHIPRESOURCE({0},{1},{2})", name, amount, capacity); + return string.Format("SHIPRESOURCE({0},{1},{2})", name, GetAmount(), GetCapacity()); } private static Dictionary ProspectResources(IEnumerable parts, SharedObjects shared) diff --git a/src/kOS/Suffixed/BodyAtmosphere.cs b/src/kOS/Suffixed/BodyAtmosphere.cs index 966628a82..64e4752f4 100644 --- a/src/kOS/Suffixed/BodyAtmosphere.cs +++ b/src/kOS/Suffixed/BodyAtmosphere.cs @@ -4,6 +4,7 @@ namespace kOS.Suffixed { + [kOS.Safe.Utilities.KOSNomenclature("Atmosphere")] public class BodyAtmosphere : Structure { private readonly CelestialBody celestialBody; @@ -12,13 +13,13 @@ public BodyAtmosphere(CelestialBody celestialBody) { this.celestialBody = celestialBody; - AddSuffix("BODY", new Suffix(()=> celestialBody.bodyName)); - AddSuffix("EXISTS", new Suffix(()=> celestialBody.atmosphere)); - AddSuffix("OXYGEN", new Suffix(()=> celestialBody.atmosphere && celestialBody.atmosphereContainsOxygen)); - AddSuffix("SEALEVELPRESSURE", new Suffix(()=> celestialBody.atmosphere ? celestialBody.atmospherePressureSeaLevel : 0)); - AddSuffix("HEIGHT", new Suffix(()=> celestialBody.atmosphere ? celestialBody.atmosphereDepth : 0)); + AddSuffix("BODY", new Suffix(()=> celestialBody.bodyName)); + AddSuffix("EXISTS", new Suffix(()=> celestialBody.atmosphere)); + AddSuffix("OXYGEN", new Suffix(()=> celestialBody.atmosphere && celestialBody.atmosphereContainsOxygen)); + AddSuffix("SEALEVELPRESSURE", new Suffix(()=> celestialBody.atmosphere ? celestialBody.atmospherePressureSeaLevel : 0)); + AddSuffix("HEIGHT", new Suffix(()=> celestialBody.atmosphere ? celestialBody.atmosphereDepth : 0)); - AddSuffix("SCALE", new Suffix(() => { throw new KOSAtmosphereDeprecationException("0.17.2","SCALE","",string.Empty); })); + AddSuffix("SCALE", new Suffix(() => { throw new KOSAtmosphereDeprecationException("0.17.2","SCALE","",string.Empty); })); } public override string ToString() diff --git a/src/kOS/Suffixed/BodyTarget.cs b/src/kOS/Suffixed/BodyTarget.cs index 56dfd7988..76f2ed577 100644 --- a/src/kOS/Suffixed/BodyTarget.cs +++ b/src/kOS/Suffixed/BodyTarget.cs @@ -2,36 +2,45 @@ using kOS.Utilities; using UnityEngine; using System; +using kOS.Serialization; +using System.Collections.Generic; +using kOS.Safe.Encapsulation; +using kOS.Safe.Exceptions; +using kOS.Safe; +using kOS.Safe.Serialization; namespace kOS.Suffixed { + [kOS.Safe.Utilities.KOSNomenclature("Body")] public class BodyTarget : Orbitable, IKOSTargetable { + private static string DumpName = "name"; + public CelestialBody Body { get; set; } - override public Orbit Orbit { get { return Body.orbit; } } + public override Orbit Orbit { get { return Body.orbit; } } - override public string GetName() + public override StringValue GetName() { return Body.name; } - override public Vector GetPosition() + public override Vector GetPosition() { return new Vector(Body.position - Shared.Vessel.findWorldCenterOfMass()); } - override public OrbitableVelocity GetVelocities() + public override OrbitableVelocity GetVelocities() { return new OrbitableVelocity(Body, Shared); } - override public Vector GetPositionAtUT(TimeSpan timeStamp) + public override Vector GetPositionAtUT(TimeSpan timeStamp) { return new Vector(Body.getPositionAtUT(timeStamp.ToUnixStyleTime()) - Shared.Vessel.findWorldCenterOfMass()); } - override public OrbitableVelocity GetVelocitiesAtUT(TimeSpan timeStamp) + public override OrbitableVelocity GetVelocitiesAtUT(TimeSpan timeStamp) { CelestialBody parent = Body.KOSExtensionGetParentBody(); if (parent == null) // only if Body is Sun and therefore has no parent, then do more complex work instead because KSP didn't provide a way itself @@ -41,7 +50,7 @@ override public OrbitableVelocity GetVelocitiesAtUT(TimeSpan timeStamp) if (soiBody.orbit != null) futureOrbitalVel = soiBody.orbit.GetFrameVelAtUT(timeStamp.ToUnixStyleTime()); else - futureOrbitalVel = (-1) * (new VesselTarget(Shared.Vessel, Shared).GetVelocitiesAtUT(timeStamp).Orbital.ToVector3D()); + futureOrbitalVel = -1 * new VesselTarget(Shared.Vessel, Shared).GetVelocitiesAtUT(timeStamp).Orbital.ToVector3D(); return new OrbitableVelocity(new Vector(futureOrbitalVel), new Vector(0.0, 0.0, 0.0)); } @@ -53,12 +62,12 @@ override public OrbitableVelocity GetVelocitiesAtUT(TimeSpan timeStamp) return new OrbitableVelocity(orbVel, surfVel); } - override public Orbit GetOrbitAtUT(double desiredUT) + public override Orbit GetOrbitAtUT(double desiredUT) { return Orbit; // Bodies cannot transition and are always on rails so this is constant. } - override public Vector GetUpVector() + public override Vector GetUpVector() { CelestialBody parent = Body.KOSExtensionGetParentBody(); return parent == null ? @@ -66,12 +75,17 @@ override public Vector GetUpVector() new Vector((Body.position - parent.position).normalized); } - override public Vector GetNorthVector() + public override Vector GetNorthVector() { CelestialBody parent = Body.KOSExtensionGetParentBody() ?? Body; return new Vector(Vector3d.Exclude(GetUpVector(), parent.transform.up)); } + public BodyTarget() + { + BodyInitializeSuffixes(); + } + public BodyTarget(string name, SharedObjects shareObj) : this(VesselUtils.GetBodyByName(name), shareObj) { @@ -87,21 +101,23 @@ public BodyTarget(CelestialBody body, SharedObjects shareObj) private void BodyInitializeSuffixes() { - AddSuffix("NAME", new Suffix(() => Body.name)); - AddSuffix("DESCRIPTION", new Suffix(() => Body.bodyDescription)); - AddSuffix("MASS", new Suffix(() => Body.Mass)); - AddSuffix("ALTITUDE", new Suffix(() => Body.orbit.altitude)); - AddSuffix("RADIUS", new Suffix(() => Body.Radius)); - AddSuffix("MU", new Suffix(() => Body.gravParameter)); - AddSuffix("ROTATIONPERIOD", new Suffix(() => Body.rotationPeriod)); + AddSuffix("NAME", new Suffix(() => Body.name)); + AddSuffix("DESCRIPTION", new Suffix(() => Body.bodyDescription)); + AddSuffix("MASS", new Suffix(() => Body.Mass)); + AddSuffix("ALTITUDE", new Suffix(() => Body.orbit.altitude)); + AddSuffix("RADIUS", new Suffix(() => Body.Radius)); + AddSuffix("MU", new Suffix(() => Body.gravParameter)); + AddSuffix("ROTATIONPERIOD", new Suffix(() => Body.rotationPeriod)); AddSuffix("ATM", new Suffix(() => new BodyAtmosphere(Body))); AddSuffix("ANGULARVEL", new Suffix(() => RawAngularVelFromRelative(Body.angularVelocity))); + AddSuffix("SOIRADIUS", new Suffix(() => Body.sphereOfInfluence)); + AddSuffix("ROTATIONANGLE", new Suffix(() => Body.rotationAngle)); AddSuffix("GEOPOSITIONOF", new OneArgsSuffix( GeoCoordinatesFromPosition, "Interpret the vector given as a 3D position, and return the geocoordinates directly underneath it on this body.")); AddSuffix("ALTITUDEOF", - new OneArgsSuffix( + new OneArgsSuffix( AltitudeFromPosition, "Interpret the vector given as a 3D position, and return its altitude above 'sea level' of this body.")); } @@ -124,7 +140,7 @@ public GeoCoordinates GeoCoordinatesFromPosition(Vector position) /// /// Vector to use as the 3D position in ship-raw coords /// The altitude above 'sea level'. - public double AltitudeFromPosition(Vector position) + public ScalarValue AltitudeFromPosition(Vector position) { Vector3d unityWorldPosition = Shared.Vessel.findWorldCenterOfMass() + position.ToVector3D(); return Body.GetAltitude(unityWorldPosition); @@ -137,7 +153,7 @@ public double AltitudeFromPosition(Vector position) /// weird exception for this one case. This transforms it back into raw universe /// axes again: /// - /// the value KSP is returning for angular velocity + /// the value KSP is returning for angular velocity /// altered velocity in the new reference frame private Vector RawAngularVelFromRelative(Vector3 angularVelFromKSP) { @@ -150,7 +166,7 @@ public double GetDistance() return Vector3d.Distance(Shared.Vessel.findWorldCenterOfMass(), Body.position) - Body.Radius; } - public override object GetSuffix(string suffixName) + public override ISuffixResult GetSuffix(string suffixName) { if (Target == null) throw new Exception("BODY structure appears to be empty!"); return base.GetSuffix(suffixName); @@ -198,5 +214,42 @@ public override int GetHashCode() { return Body.name.GetHashCode(); } + + public void SetSharedObjects(SharedObjects sharedObjects) + { + Shared = sharedObjects; + } + + public override Dump Dump() + { + var dump = new DumpWithHeader + { + Header = string.Format("BODY '{0}'", Body.bodyName) + }; + + dump.Add(DumpName, Body.bodyName); + + return dump; + } + + public override void LoadDump(Dump dump) + { + string name = dump[DumpName] as string; + + if (name == null) + { + throw new KOSSerializationException("Body's name is null or invalid"); + } + + CelestialBody body = VesselUtils.GetBodyByName(name); + + if (body == null) + { + throw new KOSSerializationException("Body with the given name does not exist"); + } + + Body = body; + + } } } \ No newline at end of file diff --git a/src/kOS/Suffixed/Career.cs b/src/kOS/Suffixed/Career.cs index 89efc7ec2..399ebd0d2 100644 --- a/src/kOS/Suffixed/Career.cs +++ b/src/kOS/Suffixed/Career.cs @@ -4,17 +4,18 @@ namespace kOS.Suffixed { + [kOS.Safe.Utilities.KOSNomenclature("Career")] public class Career : Structure { static Career() { - AddGlobalSuffix("CANTRACKOBJECTS", new StaticSuffix(CanTrackObjects, + AddGlobalSuffix("CANTRACKOBJECTS", new StaticSuffix(CanTrackObjects, "Can the Tracking Center track small space objects (asteroids)?")); - AddGlobalSuffix("PATCHLIMIT", new StaticSuffix(PatchLimit, + AddGlobalSuffix("PATCHLIMIT", new StaticSuffix(PatchLimit, "The Tracking Center's orbit patch prediction limit (an integer)")); - AddGlobalSuffix("CANMAKENODES", new StaticSuffix(CanMakeNodes, + AddGlobalSuffix("CANMAKENODES", new StaticSuffix(CanMakeNodes, "Can the Mission Control support maneuver nodes yet?")); - AddGlobalSuffix("CANDOACTIONS", new StaticSuffix(CanDoActions, + AddGlobalSuffix("CANDOACTIONS", new StaticSuffix(CanDoActions, "Can either the VAB or SPH allow custom action groups? " + "If either one allows it, then you are allowed to call " + "the :DOACTION suffix of a PartModule." )); @@ -42,7 +43,7 @@ public static bool CanTrackObjects(out string reason) /// only because you can't default out parameters like 'out string reason' to make them optional.) /// /// true if you can. false if you cannot. - public static bool CanTrackObjects() + public static BooleanValue CanTrackObjects() { string dummy; return CanTrackObjects(out dummy); @@ -65,7 +66,7 @@ public static int PatchLimit(out string reason) /// only because you can't default out parameters like 'out string reason' to make them optional.) /// /// max number of patches ahead (not including the current one). - public static int PatchLimit() + public static ScalarValue PatchLimit() { string dummy; return PatchLimit(out dummy); @@ -76,7 +77,7 @@ public static int PatchLimit() /// /// returns a string describing what would need upgrading to change the answer. /// true if it can. false if it cannot. - public static bool CanMakeNodes(out string reason) + public static BooleanValue CanMakeNodes(out string reason) { // This one is a weird check. It requires TWO building conditions, as far as I can tell: reason = "mission control building"; @@ -91,7 +92,7 @@ public static bool CanMakeNodes(out string reason) /// only because you can't default out parameters like 'out string reason' to make them optional.) /// /// true if you can. false if you cannot. - public static bool CanMakeNodes() + public static BooleanValue CanMakeNodes() { string dummy; return CanMakeNodes(out dummy); @@ -116,7 +117,7 @@ public static bool CanDoActions(out string reason) /// only because you can't default out parameters like 'out string reason' to make them optional.) /// /// true if you can. false if you cannot. - public static bool CanDoActions() + public static BooleanValue CanDoActions() { string dummy; return CanDoActions(out dummy); diff --git a/src/kOS/Suffixed/Config.cs b/src/kOS/Suffixed/Config.cs index 1f8857f22..a7114e7d4 100644 --- a/src/kOS/Suffixed/Config.cs +++ b/src/kOS/Suffixed/Config.cs @@ -1,32 +1,35 @@ using System; using System.Collections.Generic; using System.Linq; -using kOS.Safe.Utilities; -using KSP.IO; using kOS.Safe.Encapsulation; +using kOS.Safe.Encapsulation.Suffixes; using kOS.Screen; +using KSP.IO; namespace kOS.Suffixed { + [kOS.Safe.Utilities.KOSNomenclature("Config")] public class Config : Structure, IConfig { private static Config instance; private readonly Dictionary keys; private readonly Dictionary alias; private readonly Dictionary properties; - private DateTime lastChangeTime; public int InstructionsPerUpdate { get { return GetPropValue(PropId.InstructionsPerUpdate); } set { SetPropValue(PropId.InstructionsPerUpdate, value); } } public bool UseCompressedPersistence { get { return GetPropValue(PropId.UseCompressedPersistence); } set { SetPropValue(PropId.UseCompressedPersistence, value); } } public bool ShowStatistics { get { return GetPropValue(PropId.ShowStatistics); } set { SetPropValue(PropId.ShowStatistics, value); } } public bool EnableRTIntegration { get { return GetPropValue(PropId.EnableRTIntegration); } set { SetPropValue(PropId.EnableRTIntegration, value); } } public bool StartOnArchive { get { return GetPropValue(PropId.StartOnArchive); } set { SetPropValue(PropId.StartOnArchive, value); } } + public bool ObeyHideUI { get { return GetPropValue(PropId.ObeyHideUI); } set { SetPropValue(PropId.ObeyHideUI, value); } } public bool EnableSafeMode { get { return GetPropValue(PropId.EnableSafeMode); } set { SetPropValue(PropId.EnableSafeMode, value); } } + public bool AudibleExceptions { get { return GetPropValue(PropId.AudibleExceptions); } set { SetPropValue(PropId.AudibleExceptions, value); } } public bool VerboseExceptions { get { return GetPropValue(PropId.VerboseExceptions); } set { SetPropValue(PropId.VerboseExceptions, value); } } public bool EnableTelnet { get { return GetPropValue(PropId.EnableTelnet); } set { SetPropValue(PropId.EnableTelnet, value); } } public int TelnetPort { get { return GetPropValue(PropId.TelnetPort); } set { SetPropValue(PropId.TelnetPort, value); } } public bool TelnetLoopback { get { return GetPropValue(PropId.TelnetLoopback); } set { SetPropValue(PropId.TelnetLoopback, value); } } public bool UseBlizzyToolbarOnly { get { return GetPropValue(PropId.UseBlizzyToolbarOnly); } set { SetPropValue(PropId.UseBlizzyToolbarOnly, value); } } + public bool DebugEachOpcode { get { return GetPropValue(PropId.DebugEachOpcode); } set { SetPropValue(PropId.DebugEachOpcode, value); } } private Config() { @@ -35,7 +38,7 @@ private Config() properties = new Dictionary(); BuildValuesDictionary(); LoadConfig(); - lastChangeTime = DateTime.Now; + TimeStamp = DateTime.Now; } private void BuildValuesDictionary() @@ -45,11 +48,14 @@ private void BuildValuesDictionary() AddConfigKey(PropId.ShowStatistics, new ConfigKey("ShowStatistics", "STAT", "Show execution statistics", false, false, true, typeof(bool))); AddConfigKey(PropId.EnableRTIntegration, new ConfigKey("EnableRTIntegration", "RT", "Enable RT integration", true, false, true, typeof(bool))); AddConfigKey(PropId.StartOnArchive, new ConfigKey("StartOnArchive", "ARCH", "Start on Archive volume", false, false, true, typeof(bool))); + AddConfigKey(PropId.ObeyHideUI , new ConfigKey("ObeyHideUI", "OBEYHIDEUI", "Obey UI hide (F2 key)", true, false, true, typeof(bool))); AddConfigKey(PropId.EnableSafeMode, new ConfigKey("EnableSafeMode", "SAFE", "Enable safe mode", true, false, true, typeof(bool))); + AddConfigKey(PropId.AudibleExceptions, new ConfigKey("AudibleExceptions", "AUDIOERR", "Sound effect when KOS gives an error", true, false, true, typeof(bool))); AddConfigKey(PropId.VerboseExceptions, new ConfigKey("VerboseExceptions", "VERBOSE", "Enable verbose exception msgs", true, false, true, typeof(bool))); AddConfigKey(PropId.EnableTelnet, new ConfigKey("EnableTelnet", "TELNET", "Enable Telnet server", false, false, true, typeof(bool))); AddConfigKey(PropId.TelnetPort, new ConfigKey("TelnetPort", "TPORT", "Telnet port number (must restart telnet to take effect)", 5410, 1024, 65535, typeof(int))); AddConfigKey(PropId.TelnetLoopback, new ConfigKey("TelnetLoopback", "LOOPBACK", "Restricts telnet to 127.0.0.1 (must restart telnet to take effect)", true, false, true, typeof(bool))); + AddConfigKey(PropId.DebugEachOpcode , new ConfigKey("DebugEachOpcode", "DEBUGEACHOPCODE", "Unholy debug spam used by the kOS developers", false, false, true, typeof(bool))); if(ToolbarManager.ToolbarAvailable) AddConfigKey(PropId.UseBlizzyToolbarOnly, new ConfigKey("UseBlizzyToolbarOnly", "BLIZZY", "Use Blizzy toolbar only. Takes effect on new scene.", false, false, true, typeof(bool))); } @@ -65,12 +71,12 @@ private void LoadConfig() { try { - var config = PluginConfiguration.CreateForType(); + PluginConfiguration config = PluginConfiguration.CreateForType(); config.load(); - foreach (var key in keys.Values) + foreach (ConfigKey key in keys.Values) { - var value = config[key.StringKey]; + object value = config[key.StringKey]; if (value != null) { key.Value = value; @@ -100,16 +106,16 @@ private T GetPropValue(PropId id) private void SetPropValue(PropId id, object value) { if (! value.Equals(properties[id].Value)) - lastChangeTime = DateTime.Now; + TimeStamp = DateTime.Now; properties[id].Value = value; } public void SaveConfig() { - var config = PluginConfiguration.CreateForType(); + PluginConfiguration config = PluginConfiguration.CreateForType(); config.load(); - foreach (var key in keys.Values) + foreach (ConfigKey key in keys.Values) { SaveConfigKey(key, config); } @@ -119,7 +125,7 @@ public void SaveConfig() private void SaveConfigKey(ConfigKey key) { - var config = PluginConfiguration.CreateForType(); + PluginConfiguration config = PluginConfiguration.CreateForType(); config.load(); SaveConfigKey(key, config); config.save(); @@ -130,7 +136,7 @@ private void SaveConfigKey(ConfigKey key, PluginConfiguration config) config.SetValue(key.StringKey, keys[key.StringKey.ToUpper()].Value); } - public override object GetSuffix(String suffixName) + public override ISuffixResult GetSuffix(string suffixName) { ConfigKey key = null; @@ -143,10 +149,10 @@ public override object GetSuffix(String suffixName) key = alias[suffixName]; } - return key != null ? key.Value : base.GetSuffix(suffixName); + return key != null ? new SuffixResult(FromPrimitiveWithAssert(key.Value)) : base.GetSuffix(suffixName); } - public override bool SetSuffix(String suffixName, object value) + public override bool SetSuffix(string suffixName, object value) { ConfigKey key = null; @@ -175,12 +181,9 @@ public override bool SetSuffix(String suffixName, object value) /// config values happened. Used by KOSTollBarWindow to decide whether or not /// it needs to assume its cached values are stale and need re-loading. /// - public DateTime TimeStamp() - { - return lastChangeTime; - } + public DateTime TimeStamp { get; private set; } - public List GetConfigKeys() + public IList GetConfigKeys() { return keys.Values.ToList(); } @@ -197,70 +200,15 @@ private enum PropId ShowStatistics = 3, EnableRTIntegration = 4, StartOnArchive = 5, - EnableSafeMode = 6, - VerboseExceptions = 7, - EnableTelnet = 8, - TelnetPort = 9, - TelnetLoopback = 10, - UseBlizzyToolbarOnly = 11 - } - } - - public class ConfigKey - { - private object val; - public string StringKey {get;private set;} - public string Alias {get;set;} - public string Name {get;set;} - public Type ValType {get;set;} - public object Value {get{return val;} set{ val = SafeSetValue(value); } } - public object MinValue {get;set;} - public object MaxValue {get;set;} - - public ConfigKey(string stringKey, string alias, string name, object defaultValue, object min, object max, Type type) - { - StringKey = stringKey; - Alias = alias; - Name = name; - val = defaultValue; - MinValue = min; - MaxValue = max; - ValType = type; - } - - /// - /// Return the new value after it's been altered or the change was denied. - /// - /// attempted new value - /// new value to actually use, maybe constrained or even unchanged if the attempted value is disallowed - private object SafeSetValue(object newValue) - { - object returnValue = Value; - if (newValue==null || (! ValType.IsInstanceOfType(newValue))) - return returnValue; - - if (Value is int) - { - if ((int)newValue < (int)MinValue) - returnValue = MinValue; - else if ((int)newValue > (int)MaxValue) - returnValue = MaxValue; - else - returnValue = newValue; - - // TODO: If and when we end up making warning-level exceptions that don't break - // the execution but still get logged, then log such a warning here mentioning - // if the value attempted was denied and changed if it was. - } - else if (Value is bool) - { - returnValue = newValue; - } - else - { - throw new Exception( "kOS CONFIG has new type that wasn't supported yet: contact kOS developers" ); - } - return returnValue; + ObeyHideUI = 6, + EnableSafeMode = 7, + AudibleExceptions = 8, + VerboseExceptions = 9, + EnableTelnet = 10, + TelnetPort = 11, + TelnetLoopback = 12, + UseBlizzyToolbarOnly = 13, + DebugEachOpcode = 14 } } } diff --git a/src/kOS/Suffixed/CrewMember.cs b/src/kOS/Suffixed/CrewMember.cs new file mode 100644 index 000000000..c3b27b241 --- /dev/null +++ b/src/kOS/Suffixed/CrewMember.cs @@ -0,0 +1,52 @@ +using kOS.Safe.Encapsulation; +using kOS.Safe.Encapsulation.Suffixes; +using kOS.Suffixed.Part; + +namespace kOS.Suffixed +{ + [kOS.Safe.Utilities.KOSNomenclature("CrewMember")] + public class CrewMember : Structure + { + private readonly ProtoCrewMember crewMember; + private readonly SharedObjects shared; + + public string Name { + get { return crewMember.name; } + } + + public string Gender { + get { return crewMember.gender.ToString(); } + } + + public int Experience { + get { return crewMember.experienceLevel; } + } + + public string Trait { + get { return crewMember.experienceTrait.Title; } + } + + public CrewMember(ProtoCrewMember crewMember, SharedObjects shared) + { + this.crewMember = crewMember; + this.shared = shared; + InitializeSuffixes(); + } + + private void InitializeSuffixes() + { + AddSuffix("NAME", new Suffix(() => Name)); + AddSuffix("TOURIST", new Suffix(() => crewMember.type == ProtoCrewMember.KerbalType.Tourist)); + AddSuffix("GENDER", new Suffix(() => Gender)); + AddSuffix("TRAIT", new Suffix(() => Trait)); + AddSuffix("EXPERIENCE", new Suffix(() => Experience)); + AddSuffix("PART", new Suffix(() => PartValueFactory.Construct(crewMember.seat.part, shared))); + } + + public override string ToString() + { + return Name + " " + Gender[0] + ", " + Trait + " " + new string('*', Experience); + } + } +} + diff --git a/src/kOS/Suffixed/Direction.cs b/src/kOS/Suffixed/Direction.cs index 51f405ea3..cc0e77a70 100644 --- a/src/kOS/Suffixed/Direction.cs +++ b/src/kOS/Suffixed/Direction.cs @@ -5,6 +5,8 @@ namespace kOS.Suffixed { + [kOS.Safe.Utilities.KOSNomenclature("Direction")] + [kOS.Safe.Utilities.KOSNomenclature("Rotation", CSharpToKOS = false)] public class Direction : Structure { private Vector3d euler; @@ -121,13 +123,13 @@ public Quaternion Rotation private void DirectionInitializeSuffixes() { AddSuffix("PITCH", - new Suffix(() => euler.x, + new Suffix(() => euler.x, "The rotation around the universe's X axis. The word 'PITCH' is a misnomer.")); AddSuffix("YAW", - new Suffix(() => euler.y, + new Suffix(() => euler.y, "The rotation around the universe's Y axis. The word 'YAW' is a misnomer.")); AddSuffix("ROLL", - new Suffix(() => euler.z, + new Suffix(() => euler.z, "The rotation around the universe's Z axis. The word 'ROLL' is a misnomer.")); AddSuffix(new[] { "FOREVECTOR", "VECTOR" }, new Suffix(() => new Vector(vector), @@ -148,6 +150,16 @@ private void DirectionInitializeSuffixes() return new Direction(a.Rotation * b.Rotation); } + public static Vector operator *(Direction a, Vector b) + { + return new Vector(a.Rotation * (Vector3d)b); + } + + public static Vector operator *(Vector b, Direction a) + { + return new Vector(a.Rotation * (Vector3d)b); + } + public static Direction operator +(Direction a, Direction b) { return new Direction(a.Euler + b.Euler, true); diff --git a/src/kOS/Suffixed/ElementValue.cs b/src/kOS/Suffixed/ElementValue.cs index ad4fa5188..42a7bbcf6 100644 --- a/src/kOS/Suffixed/ElementValue.cs +++ b/src/kOS/Suffixed/ElementValue.cs @@ -6,6 +6,7 @@ namespace kOS.Suffixed { + [kOS.Safe.Utilities.KOSNomenclature("Element")] public class ElementValue : Structure { private readonly DockedVesselInfo dockedVesselInfo; @@ -30,13 +31,15 @@ public void AddPart(global::Part part) private void InitializeSuffixes() { - AddSuffix("NAME", new SetSuffix(() => dockedVesselInfo.name, SetName )); - AddSuffix("UID", new Suffix(() => dockedVesselInfo.rootPartUId.ToString())); + AddSuffix("NAME", new SetSuffix(() => dockedVesselInfo.name, SetName )); + AddSuffix("UID", new Suffix(() => dockedVesselInfo.rootPartUId.ToString())); + AddSuffix("VESSEL", new Suffix(() => new VesselTarget(parts[0].vessel, shared))); AddSuffix("PARTS", new Suffix(() => PartValueFactory.Construct(parts, shared))); + AddSuffix("DOCKINGPORTS", new Suffix(() => DockingPortValue.PartsToList(parts, shared))); AddSuffix("RESOURCES", new Suffix(GetResourceManifest)); } - private void SetName(string value) + private void SetName(StringValue value) { if (!string.IsNullOrEmpty(value)) { diff --git a/src/kOS/Suffixed/FlightControl.cs b/src/kOS/Suffixed/FlightControl.cs index dc804f650..0f6acabc1 100644 --- a/src/kOS/Suffixed/FlightControl.cs +++ b/src/kOS/Suffixed/FlightControl.cs @@ -9,9 +9,10 @@ namespace kOS.Suffixed { + [kOS.Safe.Utilities.KOSNomenclature("Control")] public class FlightControl : Structure , IDisposable { - private const float SETTING_EPILSON = 0.01f; + private const float SETTING_EPILSON = 0.00001f; // For rotation x = yaw, y = pitch, and z = roll private float yaw; private float yawTrim; @@ -119,27 +120,27 @@ public override string ToString() private void InitializePilotSuffixes() { - AddSuffix(new[] { "PILOTYAW" }, new Suffix(() => ReadPilot(ref FlightInputHandler.state.yaw))); - AddSuffix(new[] { "PILOTYAWTRIM" }, new Suffix(() => ReadPilot(ref FlightInputHandler.state.yawTrim))); - AddSuffix(new[] { "PILOTROLL" }, new Suffix(() => ReadPilot(ref FlightInputHandler.state.roll))); - AddSuffix(new[] { "PILOTROLLTRIM" }, new Suffix(() => ReadPilot(ref FlightInputHandler.state.rollTrim))); - AddSuffix(new[] { "PILOTPITCH" }, new Suffix(() => ReadPilot(ref FlightInputHandler.state.pitch))); - AddSuffix(new[] { "PILOTPITCHTRIM" }, new Suffix(() => ReadPilot(ref FlightInputHandler.state.pitchTrim))); - - AddSuffix(new[] { "PILOTFORE" }, new Suffix(() => Invert(ReadPilot(ref FlightInputHandler.state.Z)))); - AddSuffix(new[] { "PILOTSTARBOARD" }, new Suffix(() => Invert(ReadPilot(ref FlightInputHandler.state.X)))); + AddSuffix(new[] { "PILOTYAW" }, new Suffix(() => ReadPilot(ref FlightInputHandler.state.yaw))); + AddSuffix(new[] { "PILOTYAWTRIM" }, new Suffix(() => ReadPilot(ref FlightInputHandler.state.yawTrim))); + AddSuffix(new[] { "PILOTROLL" }, new Suffix(() => ReadPilot(ref FlightInputHandler.state.roll))); + AddSuffix(new[] { "PILOTROLLTRIM" }, new Suffix(() => ReadPilot(ref FlightInputHandler.state.rollTrim))); + AddSuffix(new[] { "PILOTPITCH" }, new Suffix(() => ReadPilot(ref FlightInputHandler.state.pitch))); + AddSuffix(new[] { "PILOTPITCHTRIM" }, new Suffix(() => ReadPilot(ref FlightInputHandler.state.pitchTrim))); + + AddSuffix(new[] { "PILOTFORE" }, new Suffix(() => Invert(ReadPilot(ref FlightInputHandler.state.Z)))); + AddSuffix(new[] { "PILOTSTARBOARD" }, new Suffix(() => Invert(ReadPilot(ref FlightInputHandler.state.X)))); - AddSuffix(new[] { "PILOTTOP" }, new Suffix(() => ReadPilot(ref FlightInputHandler.state.Y))); - AddSuffix(new[] { "PILOTWHEELTHROTTLE" }, new Suffix(() => ReadPilot(ref FlightInputHandler.state.wheelThrottle))); - AddSuffix(new[] { "PILOTWHEELTHROTTLETRIM" }, new Suffix(() => ReadPilot(ref FlightInputHandler.state.wheelThrottleTrim))); - AddSuffix(new[] { "PILOTWHEELSTEER" }, new Suffix(() => ReadPilot(ref FlightInputHandler.state.wheelSteer))); - AddSuffix(new[] { "PILOTWHEELSTEERTRIM" }, new Suffix(() => ReadPilot(ref FlightInputHandler.state.wheelSteerTrim))); - AddSuffix(new[] { "PILOTNEUTRAL" }, new Suffix(() => Vessel == FlightGlobals.ActiveVessel && FlightInputHandler.state.isNeutral)); + AddSuffix(new[] { "PILOTTOP" }, new Suffix(() => ReadPilot(ref FlightInputHandler.state.Y))); + AddSuffix(new[] { "PILOTWHEELTHROTTLE" }, new Suffix(() => ReadPilot(ref FlightInputHandler.state.wheelThrottle))); + AddSuffix(new[] { "PILOTWHEELTHROTTLETRIM" }, new Suffix(() => ReadPilot(ref FlightInputHandler.state.wheelThrottleTrim))); + AddSuffix(new[] { "PILOTWHEELSTEER" }, new Suffix(() => ReadPilot(ref FlightInputHandler.state.wheelSteer))); + AddSuffix(new[] { "PILOTWHEELSTEERTRIM" }, new Suffix(() => ReadPilot(ref FlightInputHandler.state.wheelSteerTrim))); + AddSuffix(new[] { "PILOTNEUTRAL" }, new Suffix(() => Vessel == FlightGlobals.ActiveVessel && FlightInputHandler.state.isNeutral)); AddSuffix(new[] { "PILOTROTATION" }, new Suffix(GetPilotRotation)); AddSuffix(new[] { "PILOTTRANSLATION" }, new Suffix(GetPilotTranslation)); - AddSuffix(new[] { "PILOTMAINTHROTTLE" }, new ClampSetSuffix(() => ReadPilot(ref FlightInputHandler.state.mainThrottle), value => + AddSuffix(new[] { "PILOTMAINTHROTTLE" }, new ClampSetSuffix(() => ReadPilot(ref FlightInputHandler.state.mainThrottle), value => { Vessel.ctrlState.mainThrottle = value; if (Vessel == FlightGlobals.ActiveVessel) @@ -157,33 +158,33 @@ private float ReadPilot(ref float flightInputValue) private void InitializeSuffixes() { //ROTATION - AddSuffix(new[] { "YAW" }, new ClampSetSuffix(() => yaw, value => yaw = value, -1, 1)); - AddSuffix(new[] { "YAWTRIM" }, new ClampSetSuffix(() => yawTrim, value => yawTrim = value, -1, 1)); - AddSuffix(new[] { "ROLL" }, new ClampSetSuffix(() => roll, value => roll = value, -1, 1)); - AddSuffix(new[] { "ROLLTRIM" }, new ClampSetSuffix(() => rollTrim, value => rollTrim = value, -1, 1)); - AddSuffix(new[] { "PITCH" }, new ClampSetSuffix(() => pitch, value => pitch = value, -1, 1)); - AddSuffix(new[] { "PITCHTRIM" }, new ClampSetSuffix(() => pitchTrim, value => pitchTrim = value, -1, 1)); + AddSuffix(new[] { "YAW" }, new ClampSetSuffix(() => yaw, value => yaw = value, -1, 1)); + AddSuffix(new[] { "YAWTRIM" }, new ClampSetSuffix(() => yawTrim, value => yawTrim = value, -1, 1)); + AddSuffix(new[] { "ROLL" }, new ClampSetSuffix(() => roll, value => roll = value, -1, 1)); + AddSuffix(new[] { "ROLLTRIM" }, new ClampSetSuffix(() => rollTrim, value => rollTrim = value, -1, 1)); + AddSuffix(new[] { "PITCH" }, new ClampSetSuffix(() => pitch, value => pitch = value, -1, 1)); + AddSuffix(new[] { "PITCHTRIM" }, new ClampSetSuffix(() => pitchTrim, value => pitchTrim = value, -1, 1)); AddSuffix(new[] { "ROTATION" }, new SetSuffix(() => new Vector(yaw, pitch, roll), SetRotation)); //TRANSLATION - AddSuffix(new[] { "FORE" }, new ClampSetSuffix(() => fore, value => fore = value, -1, 1)); - AddSuffix(new[] { "STARBOARD" }, new ClampSetSuffix(() => starboard, value => starboard = value, -1, 1)); - AddSuffix(new[] { "TOP" }, new ClampSetSuffix(() => top, value => top = value, -1, 1)); + AddSuffix(new[] { "FORE" }, new ClampSetSuffix(() => fore, value => fore = value, -1, 1)); + AddSuffix(new[] { "STARBOARD" }, new ClampSetSuffix(() => starboard, value => starboard = value, -1, 1)); + AddSuffix(new[] { "TOP" }, new ClampSetSuffix(() => top, value => top = value, -1, 1)); AddSuffix(new[] { "TRANSLATION" }, new SetSuffix(() => new Vector(starboard, top, fore) , SetTranslation)); //ROVER - AddSuffix(new[] { "WHEELSTEER" }, new ClampSetSuffix(() => wheelSteer, value => wheelSteer = value, -1, 1)); - AddSuffix(new[] { "WHEELSTEERTRIM" }, new ClampSetSuffix(() => wheelSteerTrim, value => wheelSteerTrim = value, -1, 1)); + AddSuffix(new[] { "WHEELSTEER" }, new ClampSetSuffix(() => wheelSteer, value => wheelSteer = value, -1, 1)); + AddSuffix(new[] { "WHEELSTEERTRIM" }, new ClampSetSuffix(() => wheelSteerTrim, value => wheelSteerTrim = value, -1, 1)); //THROTTLE - AddSuffix(new[] { "MAINTHROTTLE" }, new ClampSetSuffix(() => mainThrottle, value => mainThrottle = value, 0, 1)); - AddSuffix(new[] { "WHEELTHROTTLE" }, new ClampSetSuffix(() => wheelThrottle, value => wheelThrottle = value, -1, 1)); - AddSuffix(new[] { "WHEELTHROTTLETRIM" }, new ClampSetSuffix(() => wheelThrottleTrim, value => wheelThrottleTrim = value, -1, 1)); + AddSuffix(new[] { "MAINTHROTTLE" }, new ClampSetSuffix(() => mainThrottle, value => mainThrottle = value, 0, 1)); + AddSuffix(new[] { "WHEELTHROTTLE" }, new ClampSetSuffix(() => wheelThrottle, value => wheelThrottle = value, -1, 1)); + AddSuffix(new[] { "WHEELTHROTTLETRIM" }, new ClampSetSuffix(() => wheelThrottleTrim, value => wheelThrottleTrim = value, -1, 1)); //OTHER - AddSuffix(new[] { "BOUND" }, new SetSuffix(() => bound, value => bound = value)); - AddSuffix(new[] { "NEUTRAL" }, new Suffix(() => neutral.Value)); + AddSuffix(new[] { "BOUND" }, new SetSuffix(() => bound, value => bound = value)); + AddSuffix(new[] { "NEUTRAL" }, new Suffix(() => neutral.Value)); } diff --git a/src/kOS/Suffixed/GeoCoordinates.cs b/src/kOS/Suffixed/GeoCoordinates.cs index d2e5edfb8..b5981da4c 100644 --- a/src/kOS/Suffixed/GeoCoordinates.cs +++ b/src/kOS/Suffixed/GeoCoordinates.cs @@ -2,11 +2,21 @@ using kOS.Safe.Encapsulation; using kOS.Safe.Encapsulation.Suffixes; using kOS.Utilities; +using kOS.Serialization; +using kOS.Safe.Serialization; +using System; +using kOS.Safe; namespace kOS.Suffixed { - public class GeoCoordinates : Structure + [kOS.Safe.Utilities.KOSNomenclature("GeoCoordinates")] + [kOS.Safe.Utilities.KOSNomenclature("LatLng", CSharpToKOS = false)] + public class GeoCoordinates : SerializableStructure { + private static string DumpLat = "lat"; + private static string DumpLng = "lng"; + private static string DumpBody = "body"; + private double lat; private double lng; public double Latitude @@ -36,6 +46,11 @@ private set private const int TERRAIN_MASK_BIT = 15; + public GeoCoordinates() + { + GeoCoordsInitializeSuffixes(); + } + /// /// Build a GeoCoordinates from the current lat/long of the orbitable /// object passed in. The object being checked for should be in the same @@ -43,14 +58,13 @@ private set /// /// object to take current coords of /// to know the current CPU's running vessel - public GeoCoordinates(Orbitable orb, SharedObjects sharedObj) + public GeoCoordinates(Orbitable orb, SharedObjects sharedObj) : this() { Shared = sharedObj; Vector p = orb.GetPosition(); Latitude = orb.PositionToLatitude(p); Longitude = orb.PositionToLongitude(p); Body = orb.GetParentBody(); - GeoCoordsInitializeSuffixes(); } /// @@ -60,13 +74,12 @@ public GeoCoordinates(Orbitable orb, SharedObjects sharedObj) /// to know the current CPU's running vessel /// latitude /// longitude - public GeoCoordinates(CelestialBody body, SharedObjects sharedObj, double latitude, double longitude) + public GeoCoordinates(CelestialBody body, SharedObjects sharedObj, double latitude, double longitude) : this() { Latitude = latitude; Longitude = longitude; Shared = sharedObj; Body = body; - GeoCoordsInitializeSuffixes(); } /// @@ -86,13 +99,12 @@ public GeoCoordinates(SharedObjects sharedObj, float latitude, float longitude) /// to know the current CPU's running vessel /// latitude /// longitude - public GeoCoordinates(SharedObjects sharedObj, double latitude, double longitude) + public GeoCoordinates(SharedObjects sharedObj, double latitude, double longitude) : this() { Latitude = latitude; Longitude = longitude; Shared = sharedObj; Body = Shared.Vessel.GetOrbit().referenceBody; - GeoCoordsInitializeSuffixes(); } /// @@ -100,7 +112,7 @@ public GeoCoordinates(SharedObjects sharedObj, double latitude, double longitude /// given lat/long coords, relative to the current CPU vessel's heading. /// /// bearing - public double GetBearing() + public ScalarValue GetBearing() { return VesselUtils.AngleDelta(VesselUtils.GetHeading(Shared.Vessel), (float) GetHeadingFrom()); } @@ -109,7 +121,7 @@ public double GetBearing() /// Returns the ground's altitude above sea level at this geo position. /// /// - public double GetTerrainAltitude() + public ScalarValue GetTerrainAltitude() { double alt = 0.0; PQS bodyPQS = Body.pqsController; @@ -170,7 +182,7 @@ public double GetTerrainAltitude() /// LAT/LANG position on the SOI body's surface. /// /// compass heading in degrees - private double GetHeadingFrom() + private ScalarValue GetHeadingFrom() { var up = Shared.Vessel.upAxis; var north = VesselUtils.GetNorthVector(Shared.Vessel); @@ -190,7 +202,7 @@ private double GetHeadingFrom() /// the current CPU vessel is now. /// /// distance scalar - private double GetDistanceFrom() + private ScalarValue GetDistanceFrom() { return GetPosition().Magnitude(); } @@ -211,7 +223,7 @@ public Vector GetPosition() /// /// The (sea level) altitude to get a position for> /// position vector - public Vector GetAltitudePosition(double altitude) + public Vector GetAltitudePosition(ScalarValue altitude) { Vector3d latLongCoords = Body.GetWorldSurfacePosition(Latitude, Longitude, altitude); Vector3d hereCoords = Shared.Vessel.findWorldCenterOfMass(); @@ -220,17 +232,17 @@ public Vector GetAltitudePosition(double altitude) private void GeoCoordsInitializeSuffixes() { - AddSuffix("LAT", new Suffix(()=> Latitude)); - AddSuffix("LNG", new Suffix(()=> Longitude)); + AddSuffix("LAT", new Suffix(()=> Latitude)); + AddSuffix("LNG", new Suffix(()=> Longitude)); AddSuffix("BODY", new Suffix(()=> new BodyTarget(Body, Shared))); - AddSuffix("TERRAINHEIGHT", new Suffix(GetTerrainAltitude)); - AddSuffix("DISTANCE", new Suffix(GetDistanceFrom)); - AddSuffix("HEADING", new Suffix(GetHeadingFrom)); - AddSuffix("BEARING", new Suffix(GetBearing)); + AddSuffix("TERRAINHEIGHT", new Suffix(GetTerrainAltitude)); + AddSuffix("DISTANCE", new Suffix(GetDistanceFrom)); + AddSuffix("HEADING", new Suffix(GetHeadingFrom)); + AddSuffix("BEARING", new Suffix(GetBearing)); AddSuffix("POSITION", new Suffix(GetPosition, "Get the 3-D space position relative to the ship center, of this lat/long, " + "at a point on the terrain surface")); - AddSuffix("ALTITUDEPOSITION", new OneArgsSuffix(GetAltitudePosition, + AddSuffix("ALTITUDEPOSITION", new OneArgsSuffix(GetAltitudePosition, "Get the 3-D space position relative to the ship center, " + "of this lat/long, at this (sea level) altitude")); } @@ -239,5 +251,29 @@ public override string ToString() { return "LATLNG(" + Latitude + ", " + Longitude + ")"; } + + public void SetSharedObjects(SharedObjects sharedObjects) + { + Shared = sharedObjects; + } + + public override Dump Dump() + { + var dictionary = new DumpWithHeader + { + {DumpLat, lat}, + {DumpLng, lng}, + {DumpBody, new BodyTarget(Body, Shared)} + }; + + return dictionary; + } + + public override void LoadDump(Dump dump) + { + Body = (dump[DumpBody] as BodyTarget).Body; + lat = Convert.ToDouble(dump[DumpLat]); + lng = Convert.ToDouble(dump[DumpLng]); + } } } diff --git a/src/kOS/Suffixed/HsvColor.cs b/src/kOS/Suffixed/HsvColor.cs index bb7b585fa..1b5b50bd0 100644 --- a/src/kOS/Suffixed/HsvColor.cs +++ b/src/kOS/Suffixed/HsvColor.cs @@ -1,7 +1,9 @@ +using kOS.Safe.Encapsulation; using kOS.Safe.Encapsulation.Suffixes; namespace kOS.Suffixed { + [kOS.Safe.Utilities.KOSNomenclature("HSVA")] public class HsvColor : RgbaColor { private float hue; @@ -32,9 +34,9 @@ protected override void Recalculate() private void InitializeSuffixColor() { - AddSuffix(new[] { "H", "HUE" }, new ClampSetSuffix(() => hue, value => { hue = value; ReconcileHsvToRgb(); }, 0, 255)); - AddSuffix(new[] { "S", "SATURATION" }, new ClampSetSuffix(() => saturation, value => { saturation = value; ReconcileHsvToRgb(); }, 0, 255)); - AddSuffix(new[] { "V", "VALUE" }, new ClampSetSuffix(() => hsvValue, value => { hsvValue = value; ReconcileHsvToRgb(); }, 0, 255)); + AddSuffix(new[] { "H", "HUE" }, new ClampSetSuffix(() => hue, value => { hue = value; ReconcileHsvToRgb(); }, 0, 255)); + AddSuffix(new[] { "S", "SATURATION" }, new ClampSetSuffix(() => saturation, value => { saturation = value; ReconcileHsvToRgb(); }, 0, 255)); + AddSuffix(new[] { "V", "VALUE" }, new ClampSetSuffix(() => hsvValue, value => { hsvValue = value; ReconcileHsvToRgb(); }, 0, 255)); } // Converts an RGB color to an HSV color. diff --git a/src/kOS/Suffixed/KUniverseValue.cs b/src/kOS/Suffixed/KUniverseValue.cs new file mode 100644 index 000000000..7479f3aea --- /dev/null +++ b/src/kOS/Suffixed/KUniverseValue.cs @@ -0,0 +1,132 @@ +using kOS.Safe.Compilation.KS; +using kOS.Safe.Encapsulation; +using kOS.Safe.Encapsulation.Suffixes; +using kOS.Safe.Exceptions; +using kOS.Safe.Utilities; + +namespace kOS.Suffixed +{ + [kOS.Safe.Utilities.KOSNomenclature("Kuniverse")] + public class KUniverseValue : Structure + { + private readonly SharedObjects shared; + + public KUniverseValue(SharedObjects shared) + { + this.shared = shared; + InitializeSuffixes(); + } + + public void InitializeSuffixes() + { + AddSuffix("CANREVERT", new Suffix(CanRevert)); + AddSuffix("CANREVERTTOLAUNCH", new Suffix(CanRevertToLaunch)); + AddSuffix("CANREVERTTOEDITOR", new Suffix(CanRevvertToEditor)); + AddSuffix("REVERTTOLAUNCH", new NoArgsVoidSuffix(RevertToLaunch)); + AddSuffix("REVERTTOEDITOR", new NoArgsVoidSuffix(RevertToEditor)); + AddSuffix("REVERTTO", new OneArgsSuffix(RevertTo)); + AddSuffix("ORIGINEDITOR", new Suffix(OriginatingEditor)); + AddSuffix("DEFAULTLOADDISTANCE", new Suffix(() => new LoadDistanceValue(PhysicsGlobals.Instance.VesselRangesDefault))); + AddSuffix("ACTIVEVESSEL", new SetSuffix(() => new VesselTarget(FlightGlobals.ActiveVessel, shared), SetActiveVessel)); + AddSuffix("FORCESETACTIVEVESSEL", new OneArgsSuffix(ForceSetActiveVessel)); + AddSuffix("HOURSPERDAY", new Suffix(GetHoursPerDay)); + AddSuffix("DEBUGLOG", new OneArgsSuffix(DebugLog)); + } + + public void RevertToLaunch() + { + if (CanRevertToLaunch()) + { + FlightDriver.RevertToLaunch(); + } + else throw new KOSCommandInvalidHereException(LineCol.Unknown(), "REVERTTOLAUNCH", "When revert is disabled", "When revert is enabled"); + } + + public void RevertToEditor() + { + if (CanRevvertToEditor()) + { + EditorFacility fac = ShipConstruction.ShipType; + FlightDriver.RevertToPrelaunch(fac); + } + else throw new KOSCommandInvalidHereException(LineCol.Unknown(), "REVERTTOEDITOR", "When revert is disabled", "When revert is enabled"); + } + + public void RevertTo(StringValue editor) + { + if (CanRevvertToEditor()) + { + EditorFacility fac; + switch (editor.ToUpper()) + { + case "VAB": + fac = EditorFacility.VAB; + break; + case "SPH": + fac = EditorFacility.SPH; + break; + default: + fac = EditorFacility.None; + break; + } + FlightDriver.RevertToPrelaunch(fac); + } + else throw new KOSCommandInvalidHereException(LineCol.Unknown(), "REVERTTO", "When revert is disabled", "When revert is enabled"); + } + + public BooleanValue CanRevert() + { + return FlightDriver.CanRevert; + } + + public BooleanValue CanRevertToLaunch() + { + return FlightDriver.CanRevertToPostInit && HighLogic.CurrentGame.Parameters.Flight.CanRestart; + } + + public BooleanValue CanRevvertToEditor() + { + return FlightDriver.CanRevertToPrelaunch && + HighLogic.CurrentGame.Parameters.Flight.CanLeaveToEditor && + ShipConstruction.ShipConfig != null; + } + + public StringValue OriginatingEditor() + { + if (ShipConstruction.ShipConfig != null) + { + EditorFacility fac = ShipConstruction.ShipType; + return fac.ToString().ToUpper(); + } + return ""; + } + + public void SetActiveVessel(VesselTarget vesselTarget) + { + Vessel vessel = vesselTarget.Vessel; + if (!vessel.isActiveVessel) + { + FlightGlobals.SetActiveVessel(vessel); + } + } + + public void ForceSetActiveVessel(VesselTarget vesselTarget) + { + Vessel vessel = vesselTarget.Vessel; + if (!vessel.isActiveVessel) + { + FlightGlobals.ForceSetActiveVessel(vessel); + } + } + + public ScalarValue GetHoursPerDay() + { + return GameSettings.KERBIN_TIME ? TimeSpan.HOURS_IN_KERBIN_DAY : TimeSpan.HOURS_IN_EARTH_DAY; + } + + public void DebugLog(StringValue message) + { + SafeHouse.Logger.Log("(KUNIVERSE:DEBUGLOG) " + message); + } + } +} diff --git a/src/kOS/Suffixed/LoadDistanceValue.cs b/src/kOS/Suffixed/LoadDistanceValue.cs new file mode 100644 index 000000000..b03376dcf --- /dev/null +++ b/src/kOS/Suffixed/LoadDistanceValue.cs @@ -0,0 +1,101 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using kOS.Safe.Encapsulation; +using kOS.Safe.Encapsulation.Suffixes; +using kOS.Safe.Exceptions; + +namespace kOS.Suffixed +{ + [kOS.Safe.Utilities.KOSNomenclature("LoadDistances")] + public class LoadDistanceValue : Structure + { + private VesselRanges vesselRanges; + + public LoadDistanceValue(Vessel vessel) : + this(vessel.vesselRanges) + { + } + + public LoadDistanceValue(VesselRanges ranges) + { + vesselRanges = ranges; + InitializeSuffixes(); + } + + private void InitializeSuffixes() + { + AddSuffix("ESCAPING", new Suffix(() => new SituationLoadDistanceValue(vesselRanges.escaping))); + AddSuffix("FLYING", new Suffix(() => new SituationLoadDistanceValue(vesselRanges.flying))); + AddSuffix("LANDED", new Suffix(() => new SituationLoadDistanceValue(vesselRanges.landed))); + AddSuffix("ORBIT", new Suffix(() => new SituationLoadDistanceValue(vesselRanges.orbit))); + AddSuffix("PRELAUNCH", new Suffix(() => new SituationLoadDistanceValue(vesselRanges.prelaunch))); + AddSuffix("SPLASHED", new Suffix(() => new SituationLoadDistanceValue(vesselRanges.splashed))); + AddSuffix("SUBORBITAL", new Suffix(() => new SituationLoadDistanceValue(vesselRanges.subOrbital))); + } + + [kOS.Safe.Utilities.KOSNomenclature("LoadDistance")] + public class SituationLoadDistanceValue : Structure + { + private VesselRanges.Situation situationValue; + + public SituationLoadDistanceValue(VesselRanges.Situation situation) + { + situationValue = situation; + InitializeSuffixes(); + } + + public void InitializeSuffixes() + { + AddSuffix("LOAD", new SetSuffix(() => situationValue.load, value => SetLoad(value))); + AddSuffix("UNLOAD", new SetSuffix(() => situationValue.unload, value => SetUnload(value))); + AddSuffix("PACK", new SetSuffix(() => situationValue.pack, value => SetPack(value))); + AddSuffix("UNPACK", new SetSuffix(() => situationValue.unpack, value => SetUnpack(value))); + } + + public void SetLoad(float val) + { + if (situationValue.unload < val) + { + situationValue.unload = val + situationValue.unload - situationValue.load; + } + situationValue.load = val; + } + + public void SetUnload(float val) + { + if (situationValue.load > val) + { + situationValue.load = val + situationValue.load - situationValue.unload; + } + situationValue.unload = val; + } + + public void SetPack(float val) + { + if (situationValue.unpack > val) + { + situationValue.unpack = val + situationValue.unpack - situationValue.pack; + } + //if (situationValue.unload < val) + //{ + // SetUnload(val + situationValue.unload - situationValue.pack); + //} + situationValue.pack = val; + } + public void SetUnpack(float val) + { + if (situationValue.pack < val) + { + situationValue.pack = val + situationValue.pack - situationValue.unpack; + } + //if (situationValue.load < val) + //{ + // SetLoad(val + situationValue.load - situationValue.unpack); + //} + situationValue.unpack = val; + } + } + } +} diff --git a/src/kOS/Suffixed/Node.cs b/src/kOS/Suffixed/Node.cs index 50fad59ab..3853a1923 100644 --- a/src/kOS/Suffixed/Node.cs +++ b/src/kOS/Suffixed/Node.cs @@ -6,6 +6,7 @@ namespace kOS.Suffixed { + [kOS.Safe.Utilities.KOSNomenclature("Node")] public class Node : Structure { private static readonly Dictionary nodeLookup; @@ -53,7 +54,7 @@ private void InitializeSuffixes() { AddSuffix(new[] {"DELTAV", "BURNVECTOR"}, new Suffix(GetBurnVector)); - AddSuffix("ETA", new SetSuffix( + AddSuffix("ETA", new SetSuffix( () => { FromNodeRef(); @@ -66,7 +67,7 @@ private void InitializeSuffixes() } )); - AddSuffix("PROGRADE", new SetSuffix( + AddSuffix("PROGRADE", new SetSuffix( () => { FromNodeRef(); @@ -79,7 +80,7 @@ private void InitializeSuffixes() } )); - AddSuffix("RADIALOUT", new SetSuffix( + AddSuffix("RADIALOUT", new SetSuffix( () => { FromNodeRef(); @@ -91,7 +92,7 @@ private void InitializeSuffixes() } )); - AddSuffix("NORMAL", new SetSuffix( + AddSuffix("NORMAL", new SetSuffix( () => { FromNodeRef(); @@ -103,7 +104,7 @@ private void InitializeSuffixes() } )); - AddSuffix("ORBIT", new Suffix(() => + AddSuffix(new[] {"OBT", "ORBIT"}, new Suffix(() => { if (nodeRef == null) throw new Exception("Node must be added to flight plan first"); return new OrbitInfo(nodeRef.nextPatch, shared); @@ -125,6 +126,12 @@ public void AddToVessel(Vessel v) throw new KOSLowTechException("use maneuver nodes", careerReason); vesselRef = v; + + if (v.patchedConicSolver == null) + throw new KOSSituationallyInvalidException( + "A KSP limitation makes it impossible to access the manuever nodes of this vessel at this time. " + + "(perhaps it's not the active vessel?)"); + nodeRef = v.patchedConicSolver.AddManeuverNode(time); UpdateNodeDeltaV(); @@ -152,6 +159,11 @@ public void Remove() nodeLookup.Remove(nodeRef); + if (vesselRef.patchedConicSolver == null) + throw new KOSSituationallyInvalidException( + "A KSP limitation makes it impossible to access the manuever nodes of this vessel at this time. " + + "(perhaps it's not the active vessel?)"); + vesselRef.patchedConicSolver.RemoveManeuverNode(nodeRef); nodeRef = null; @@ -166,6 +178,8 @@ public override string ToString() private void ToNodeRef() { + if (nodeRef == null) return; + nodeRef.OnGizmoUpdated(new Vector3d(radialOut, normal, prograde), time); } diff --git a/src/kOS/Suffixed/OrbitInfo.cs b/src/kOS/Suffixed/OrbitInfo.cs index 90ab06fdb..5e03cffaf 100644 --- a/src/kOS/Suffixed/OrbitInfo.cs +++ b/src/kOS/Suffixed/OrbitInfo.cs @@ -1,50 +1,58 @@ using kOS.Safe.Encapsulation; using kOS.Safe.Encapsulation.Suffixes; +using System; +using kOS.Serialization; +using kOS.Safe.Serialization; +using kOS.Safe; namespace kOS.Suffixed { - public class OrbitInfo : Structure + [kOS.Safe.Utilities.KOSNomenclature("Orbit")] + public class OrbitInfo : Structure, IHasSharedObjects { - private readonly Orbit orbit; - private readonly SharedObjects shared; - private readonly string name; + private Orbit orbit; + public SharedObjects Shared { get; set; } + private string name; - public OrbitInfo(Orbitable orb, SharedObjects sharedObj) + public OrbitInfo() + { + InitializeSuffixes(); + } + + public OrbitInfo(Orbitable orb, SharedObjects sharedObj) : this() { orbit = orb.Orbit; - shared = sharedObj; + Shared = sharedObj; name = orb.GetName(); - InitializeSuffixes(); } - public OrbitInfo( Orbit orb, SharedObjects sharedObj ) + public OrbitInfo( Orbit orb, SharedObjects sharedObj) : this() { - shared = sharedObj; + Shared = sharedObj; orbit = orb; name = ""; - InitializeSuffixes(); } private void InitializeSuffixes() { - AddSuffix("NAME", new Suffix(() => name)); - AddSuffix("APOAPSIS", new Suffix(() => orbit.ApA)); - AddSuffix("PERIAPSIS", new Suffix(() => orbit.PeA)); - AddSuffix("BODY", new Suffix(() => new BodyTarget(orbit.referenceBody, shared))); - AddSuffix("PERIOD", new Suffix(() => orbit.period)); - AddSuffix("INCLINATION", new Suffix(() => orbit.inclination)); - AddSuffix("ECCENTRICITY", new Suffix(() => orbit.eccentricity)); - AddSuffix("SEMIMAJORAXIS", new Suffix(() => orbit.semiMajorAxis)); - AddSuffix("SEMIMINORAXIS", new Suffix(() => orbit.semiMinorAxis)); - AddSuffix(new[]{"LAN", "LONGITUDEOFASCENDINGNODE"}, new Suffix(() => orbit.LAN)); - AddSuffix("ARGUMENTOFPERIAPSIS", new Suffix(() => orbit.argumentOfPeriapsis)); - AddSuffix("TRUEANOMALY", new Suffix(() => orbit.trueAnomaly)); - AddSuffix("MEANANOMALYATEPOCH", new Suffix(() => orbit.meanAnomalyAtEpoch)); - AddSuffix("TRANSITION", new Suffix(() => orbit.patchEndTransition.ToString())); + AddSuffix("NAME", new Suffix(() => name)); + AddSuffix("APOAPSIS", new Suffix(() => orbit.ApA)); + AddSuffix("PERIAPSIS", new Suffix(() => orbit.PeA)); + AddSuffix("BODY", new Suffix(() => new BodyTarget(orbit.referenceBody, Shared))); + AddSuffix("PERIOD", new Suffix(() => orbit.period)); + AddSuffix("INCLINATION", new Suffix(() => orbit.inclination)); + AddSuffix("ECCENTRICITY", new Suffix(() => orbit.eccentricity)); + AddSuffix("SEMIMAJORAXIS", new Suffix(() => orbit.semiMajorAxis)); + AddSuffix("SEMIMINORAXIS", new Suffix(() => orbit.semiMinorAxis)); + AddSuffix(new[]{"LAN", "LONGITUDEOFASCENDINGNODE"}, new Suffix(() => orbit.LAN)); + AddSuffix("ARGUMENTOFPERIAPSIS", new Suffix(() => orbit.argumentOfPeriapsis)); + AddSuffix("TRUEANOMALY", new Suffix(() => Utilities.Utils.DegreeFix(orbit.trueAnomaly,0.0))); + AddSuffix("MEANANOMALYATEPOCH", new Suffix(() => Utilities.Utils.DegreeFix(orbit.meanAnomalyAtEpoch * 180.0 / Math.PI, 0.0))); + AddSuffix("TRANSITION", new Suffix(() => orbit.patchEndTransition.ToString())); AddSuffix("POSITION", new Suffix(() => GetPositionAtUT( new TimeSpan(Planetarium.GetUniversalTime() ) ))); AddSuffix("VELOCITY", new Suffix(() => GetVelocityAtUT( new TimeSpan(Planetarium.GetUniversalTime() ) ))); AddSuffix("NEXTPATCH", new Suffix(GetNextPatch)); - AddSuffix("HASNEXTPATCH", new Suffix(GetHasNextPatch)); + AddSuffix("HASNEXTPATCH", new Suffix(GetHasNextPatch)); //TODO: Determine if these vectors are different than POSITION and VELOCITY AddSuffix("VSTATEVECTOR", new Suffix(() => new Vector(orbit.vel))); @@ -62,7 +70,7 @@ private void InitializeSuffixes() /// public Vector GetPositionAtUT( TimeSpan timeStamp ) { - return new Vector( orbit.getPositionAtUT( timeStamp.ToUnixStyleTime() ) - shared.Vessel.findWorldCenterOfMass() ); + return new Vector( orbit.getPositionAtUT( timeStamp.ToUnixStyleTime() ) - Shared.Vessel.findWorldCenterOfMass() ); } /// @@ -83,7 +91,7 @@ public OrbitableVelocity GetVelocityAtUT( TimeSpan timeStamp ) if (parent != null) { Vector3d pos = GetPositionAtUT( timeStamp ); - surfVel = new Vector( orbVel - parent.getRFrmVel( pos + shared.Vessel.findWorldCenterOfMass()) ); + surfVel = new Vector( orbVel - parent.getRFrmVel( pos + Shared.Vessel.findWorldCenterOfMass()) ); } else surfVel = new Vector( orbVel.X, orbVel.Y, orbVel.Z ); @@ -96,14 +104,14 @@ public OrbitableVelocity GetVelocityAtUT( TimeSpan timeStamp ) /// an OrbitInfo, or a null if there isn't any. private OrbitInfo GetNextPatch() { - return ! GetHasNextPatch() ? null : new OrbitInfo(orbit.nextPatch,shared); + return ! GetHasNextPatch() ? null : new OrbitInfo(orbit.nextPatch,Shared); } /// /// Find out whether or not the orbit has a next patch. /// /// true if the :NEXTPATCH suffix will return a real suffix. - private bool GetHasNextPatch() + private BooleanValue GetHasNextPatch() { return orbit.nextPatch != null && (orbit.nextPatch.activePatch); } @@ -113,4 +121,4 @@ public override string ToString() return "ORBIT of " + name; } } -} \ No newline at end of file +} diff --git a/src/kOS/Suffixed/Orbitable.cs b/src/kOS/Suffixed/Orbitable.cs index f4d04d8d2..513a80ccd 100644 --- a/src/kOS/Suffixed/Orbitable.cs +++ b/src/kOS/Suffixed/Orbitable.cs @@ -1,8 +1,9 @@ using kOS.Safe.Encapsulation; using kOS.Safe.Encapsulation.Suffixes; -using kOS.Safe.Utilities; using kOS.Utilities; using UnityEngine; +using kOS.Safe.Serialization; +using kOS.Serialization; namespace kOS.Suffixed { @@ -11,23 +12,28 @@ namespace kOS.Suffixed /// in orbit around something. It could be a vessel or a planet /// or a moon. /// - abstract public class Orbitable : Structure + [kOS.Safe.Utilities.KOSNomenclature("Orbitable")] + public abstract class Orbitable : SerializableStructure, IHasSharedObjects { - protected Orbitable(SharedObjects shareObj) + protected Orbitable(SharedObjects shareObj) : this() { Shared = shareObj; + } + + protected Orbitable() + { InitializeSuffixes(); } /// /// The KSP Orbit object attached to this object. /// - abstract public Orbit Orbit{get;} + public abstract Orbit Orbit{get;} /// /// The shared context for the CPU running the code. /// - public SharedObjects Shared{get; private set;} + public SharedObjects Shared{get; set;} /// /// Subclasses must override this method to return the position of this object right now. @@ -39,7 +45,7 @@ protected Orbitable(SharedObjects shareObj) /// /// coordinate reference frame. /// - abstract public Vector GetPosition(); + public abstract Vector GetPosition(); /// /// Subclasses must override this method to return the velocity of this object right now. @@ -51,7 +57,7 @@ protected Orbitable(SharedObjects shareObj) /// /// coordinate reference frame. /// - abstract public OrbitableVelocity GetVelocities(); + public abstract OrbitableVelocity GetVelocities(); /// /// Subclasses must override this method to return the position of this object at some @@ -68,7 +74,7 @@ protected Orbitable(SharedObjects shareObj) /// /// coordinate reference frame. /// - abstract public Vector GetPositionAtUT( TimeSpan timeStamp ); + public abstract Vector GetPositionAtUT( TimeSpan timeStamp ); /// /// Subclasses must override this method to return the OrbitableVelocity of this object at some @@ -85,7 +91,7 @@ protected Orbitable(SharedObjects shareObj) /// /// coordinate reference frame. /// - abstract public OrbitableVelocity GetVelocitiesAtUT( TimeSpan timeStamp ); + public abstract OrbitableVelocity GetVelocitiesAtUT( TimeSpan timeStamp ); /// /// Return the Orbit that the object will be in at some point in the future. @@ -95,28 +101,28 @@ protected Orbitable(SharedObjects shareObj) /// /// the timestamp when to query for /// An OrbitInfo constructed from the orbit patch in question - abstract public Orbit GetOrbitAtUT(double desiredUT); + public abstract Orbit GetOrbitAtUT(double desiredUT); /// /// Subclasses must override this method to return a unit vector in /// the upward direction away from its SOI body. /// /// A vector pointing upward away from the SOI body. - abstract public Vector GetUpVector(); + public abstract Vector GetUpVector(); /// /// Subclasses must override this method to return a unit vector in /// the northward direction of its SOI body. /// /// A vector pointing northward away from the SOI body. - abstract public Vector GetNorthVector(); + public abstract Vector GetNorthVector(); /// /// Subclasses must override this method to return a string name of /// this orbital thing (its vessel name or body name) /// /// string name of the thing - abstract public string GetName(); + public abstract StringValue GetName(); /// /// Get the OrbitInfo object associated with this Orbitable. @@ -157,7 +163,7 @@ public Direction GetRetrograde() OrbitableVelocity vels = GetVelocities(); Vector3d normOrbVec = vels.Orbital.Normalized(); - var d = new Direction {Rotation = Quaternion.LookRotation(normOrbVec*(-1), up)}; + var d = new Direction {Rotation = Quaternion.LookRotation(normOrbVec*-1, up)}; return d; } @@ -177,7 +183,7 @@ public Direction GetSurfaceRetrograde() OrbitableVelocity vels = GetVelocities(); Vector3d normSrfVec = vels.Surface.Normalized(); - var d = new Direction {Rotation = Quaternion.LookRotation(normSrfVec*(-1), up)}; + var d = new Direction {Rotation = Quaternion.LookRotation(normSrfVec*-1, up)}; return d; } @@ -208,32 +214,38 @@ public double PositionToAltitude( Vector pos ) private void InitializeSuffixes() { - AddSuffix("NAME", new Suffix(GetName)); - AddSuffix("APOAPSIS", new Suffix(() => Orbit.ApA)); - AddSuffix("PERIAPSIS", new Suffix(() => Orbit.PeA)); + AddSuffix("NAME", new Suffix(GetName)); + AddSuffix("APOAPSIS", new Suffix(() => Orbit.ApA)); + AddSuffix("PERIAPSIS", new Suffix(() => Orbit.PeA)); AddSuffix("BODY", new Suffix(() => new BodyTarget(Orbit.referenceBody, Shared))); + AddSuffix(new [] {"HASBODY", "HASOBT", "HASORBIT"}, new NoArgsSuffix(HasBody)); AddSuffix("UP", new Suffix(() => new Direction(GetUpVector(), false))); AddSuffix("NORTH", new Suffix(() => new Direction(GetNorthVector(), false))); AddSuffix("PROGRADE", new Suffix(GetPrograde)); AddSuffix("RETROGRADE", new Suffix(GetRetrograde)); AddSuffix("SRFPROGRADE", new Suffix(GetSurfacePrograde)); AddSuffix("SRFRETROGRADE", new Suffix(GetSurfaceRetrograde)); - AddSuffix("OBT", new Suffix(GetOrbitInfo)); + AddSuffix(new[] {"OBT","ORBIT"}, new Suffix(GetOrbitInfo)); AddSuffix("POSITION", new Suffix(GetPosition)); AddSuffix("VELOCITY", new Suffix(GetVelocities)); - AddSuffix("DISTANCE", new Suffix(GetDistance)); + AddSuffix("DISTANCE", new Suffix(GetDistance)); AddSuffix("DIRECTION", new Suffix(() => new Direction(GetPosition(), false))); - AddSuffix("LATITUDE", new Suffix(()=> PositionToLatitude(GetPosition()))); - AddSuffix("LONGITUDE", new Suffix(() => PositionToLongitude(GetPosition()))); - AddSuffix("ALTITUDE", new Suffix(() => PositionToAltitude(GetPosition()))); + AddSuffix("LATITUDE", new Suffix(()=> PositionToLatitude(GetPosition()))); + AddSuffix("LONGITUDE", new Suffix(() => PositionToLongitude(GetPosition()))); + AddSuffix("ALTITUDE", new Suffix(() => PositionToAltitude(GetPosition()))); AddSuffix("GEOPOSITION", new Suffix(() => new GeoCoordinates(this, Shared))); AddSuffix("PATCHES", new Suffix(BuildPatchList)); } - private double GetDistance() + private ScalarValue GetDistance() { return GetPosition().Magnitude(); } + + private BooleanValue HasBody() + { + return (Orbit != null); + } private ListValue BuildPatchList() { @@ -243,7 +255,7 @@ private ListValue BuildPatchList() int highestAllowedIndex = Career.PatchLimit(); while (index <= highestAllowedIndex) { - if (orb == null || (!orb.activePatch)) + if (orb == null || !orb.activePatch) { break; } diff --git a/src/kOS/Suffixed/OrbitableVelocity.cs b/src/kOS/Suffixed/OrbitableVelocity.cs index aedc1e7e3..a5ac8828c 100644 --- a/src/kOS/Suffixed/OrbitableVelocity.cs +++ b/src/kOS/Suffixed/OrbitableVelocity.cs @@ -9,6 +9,7 @@ namespace kOS.Suffixed /// reference frames. (Note this may become moot after vector /// reference frame transformation is implemented.) /// + [kOS.Safe.Utilities.KOSNomenclature("OrbitableVelocity")] public class OrbitableVelocity : Structure { public Vector Orbital { get; private set; } @@ -24,7 +25,7 @@ public OrbitableVelocity(Vessel v) private void InitializeSuffixes() { - AddSuffix("ORBIT", new Suffix(() => Orbital)); + AddSuffix(new[] {"OBT", "ORBIT"}, new Suffix(() => Orbital)); AddSuffix("SURFACE", new Suffix(() => Surface)); } diff --git a/src/kOS/Suffixed/Part/DockingPortValue.cs b/src/kOS/Suffixed/Part/DockingPortValue.cs index 3eb580204..bf6834c11 100644 --- a/src/kOS/Suffixed/Part/DockingPortValue.cs +++ b/src/kOS/Suffixed/Part/DockingPortValue.cs @@ -1,16 +1,16 @@ -using System.Collections.Generic; -using kOS.Safe.Encapsulation; +using kOS.Safe.Encapsulation; using kOS.Safe.Encapsulation.Suffixes; -using kOS.Safe.Utilities; -using UnityEngine; +using System.Collections.Generic; namespace kOS.Suffixed.Part { - public class DockingPortValue: PartValue + [kOS.Safe.Utilities.KOSNomenclature("DockingPort")] + public class DockingPortValue : PartValue { private readonly ModuleDockingNode module; - public DockingPortValue(ModuleDockingNode module, SharedObjects sharedObj) : base(module.part, sharedObj) + public DockingPortValue(ModuleDockingNode module, SharedObjects sharedObj) + : base(module.part, sharedObj) { this.module = module; DockingInitializeSuffixes(); @@ -18,19 +18,24 @@ public DockingPortValue(ModuleDockingNode module, SharedObjects sharedObj) : bas private void DockingInitializeSuffixes() { - AddSuffix("AQUIRERANGE", new Suffix(() => module.acquireRange)); - AddSuffix("AQUIREFORCE", new Suffix(() => module.acquireForce)); - AddSuffix("AQUIRETORQUE", new Suffix(() => module.acquireTorque)); - AddSuffix("REENGAGEDISTANCE", new Suffix(() => module.minDistanceToReEngage)); - AddSuffix("DOCKEDSHIPNAME", new Suffix(() => module.vesselInfo != null ? module.vesselInfo.name : string.Empty)); - AddSuffix("STATE", new Suffix(() => module.state)); - AddSuffix("TARGETABLE", new Suffix(() => true)); - AddSuffix("UNDOCK", new NoArgsSuffix(() => module.Undock())); - AddSuffix("TARGET", new NoArgsSuffix(() => module.SetAsTarget())); + AddSuffix("AQUIRERANGE", new Suffix(() => { throw new Safe.Exceptions.KOSDeprecationException("0.18.0", "AQUIRERANGE", "ACQUIRERANGE", string.Empty); })); + AddSuffix("AQUIREFORCE", new Suffix(() => { throw new Safe.Exceptions.KOSDeprecationException("0.18.0", "AQUIREFORCE", "ACQUIREFORCE", string.Empty); })); + AddSuffix("AQUIRETORQUE", new Suffix(() => { throw new Safe.Exceptions.KOSDeprecationException("0.18.0", "AQUIRETORQUE", "ACQUIRETORQUE", string.Empty); })); + AddSuffix("ACQUIRERANGE", new Suffix(() => module.acquireRange)); + AddSuffix("ACQUIREFORCE", new Suffix(() => module.acquireForce)); + AddSuffix("ACQUIRETORQUE", new Suffix(() => module.acquireTorque)); + AddSuffix("REENGAGEDISTANCE", new Suffix(() => module.minDistanceToReEngage)); + AddSuffix("DOCKEDSHIPNAME", new Suffix(() => module.vesselInfo != null ? module.vesselInfo.name : string.Empty)); + AddSuffix("STATE", new Suffix(() => module.state)); + AddSuffix("TARGETABLE", new Suffix(() => true)); + AddSuffix("UNDOCK", new NoArgsVoidSuffix(() => DoUndock())); + AddSuffix("TARGET", new NoArgsVoidSuffix(() => module.SetAsTarget())); AddSuffix("PORTFACING", new NoArgsSuffix(GetPortFacing, "The direction facing outward from the docking port. This " + "can differ from :FACING in the case of sideways-facing " + "docking ports like the inline docking port.")); + AddSuffix("NODEPOSITION", new Suffix(GetNodePosition, "The position of the docking node itself rather than the part's center of mass")); + AddSuffix("NODETYPE", new Suffix(() => module.nodeType, "The type of the docking node")); } public override ITargetable Target @@ -45,7 +50,6 @@ public static ListValue PartsToList(IEnumerable parts, SharedObjec { foreach (PartModule module in part.Modules) { - SafeHouse.Logger.Log("Module Found: "+ module); var dockingNode = module as ModuleDockingNode; if (dockingNode != null) { @@ -55,15 +59,60 @@ public static ListValue PartsToList(IEnumerable parts, SharedObjec } return toReturn; } - + private Direction GetPortFacing() { // module.nodeTransform describes the transform representing the facing of // the docking node as opposed to the facing of the part itself. In the // case of a docking port facing out the side of the part (the in-line // docking node for example) they can differ. - // + return new Direction(module.nodeTransform.rotation); } + + public Vector GetNodePosition() + { + // like with GetPortFacing above, the position of the docking node itself difers + // from the position of the part's center of mass. This returns the possition + // of the node where the two docking ports will join together, which will help + // with docking operations + + return new Vector(module.nodeTransform.position - Shared.Vessel.findWorldCenterOfMass()); + } + + public void DoUndock() + { + // if the module is not currently docked, fail silently. + if (module.otherNode != null) + { + // check to see if either the undock or decouple events are available + // and execute accordingly. + var evnt1 = module.Events["Undock"]; + var evnt2 = module.Events["Decouple"]; + if (evnt1 != null && evnt1.guiActive && evnt1.active) + { + module.Undock(); + } + else if (evnt2 != null && evnt2.guiActive && evnt2.active) + { + module.Decouple(); + } + else + { + // If you can't do either event on this port, check to see if + // you can on the port it's docked too! + evnt1 = module.otherNode.Events["Undock"]; + evnt2 = module.otherNode.Events["Decouple"]; + if (evnt1 != null && evnt1.guiActive && evnt1.active) + { + module.otherNode.Undock(); + } + else if (evnt2 != null && evnt2.guiActive && evnt2.active) + { + module.otherNode.Decouple(); + } + } + } + } } -} +} \ No newline at end of file diff --git a/src/kOS/Suffixed/Part/EngineValue.cs b/src/kOS/Suffixed/Part/EngineValue.cs index 91901e122..19c3fb2fa 100644 --- a/src/kOS/Suffixed/Part/EngineValue.cs +++ b/src/kOS/Suffixed/Part/EngineValue.cs @@ -1,37 +1,117 @@ -using kOS.Safe.Encapsulation; -using System.Collections.Generic; +using kOS.Safe.Encapsulation; using kOS.Safe.Encapsulation.Part; using kOS.Safe.Encapsulation.Suffixes; +using kOS.Safe.Exceptions; +using kOS.Suffixed.PartModuleField; +using System.Collections.Generic; +using System.Linq; namespace kOS.Suffixed.Part { + [kOS.Safe.Utilities.KOSNomenclature("Engine")] public class EngineValue : PartValue { - private readonly IModuleEngine engine; + private IModuleEngine engine + { + get + { + if ((!MultiMode) || (MMengine.runningPrimary)) { return engine1; } + else { return engine2; } + } + } + + private readonly IModuleEngine engine1; + private readonly IModuleEngine engine2; + private readonly MultiModeEngine MMengine; + private readonly bool MultiMode = false; + private GimbalFields gimbal; + private bool HasGimbal = false; public EngineValue(global::Part part, IModuleEngine engine, SharedObjects sharedObj) : base(part, sharedObj) { - this.engine = engine; + engine1 = engine; + + findGimbal(); + + EngineInitializeSuffixes(); + } + + public EngineValue(global::Part part, MultiModeEngine engine, SharedObjects sharedObj) + : base(part, sharedObj) + { + MMengine = engine; + + var moduleEngines = part.Modules.GetModules(); + if (moduleEngines.Count == 2) + { + var modEngine1 = moduleEngines.Where(e => e.engineID == MMengine.primaryEngineID).FirstOrDefault(); + if (modEngine1 != null) + engine1 = new ModuleEngineAdapter(modEngine1); + else + throw new KOSException("Attempted to build a MultiModeEngine with no engine matching Primary ID"); + var modEngine2 = moduleEngines.Where(e => e.engineID == MMengine.secondaryEngineID).FirstOrDefault(); + if (modEngine2 != null) + engine2 = new ModuleEngineAdapter(modEngine2); + else + throw new KOSException("Attempted to build a MultiModeEngine with no engine matching Secondary ID"); + } + else + { + throw new KOSException(string.Format("Attempted to build a MultiModeEngine with {0} engine modules defined instead of 2", moduleEngines.Count)); + } + + MultiMode = true; + + findGimbal(); + EngineInitializeSuffixes(); } + private void findGimbal() + { + // if the part definition includes a ModuleGimbal, create GimbalFields and set HasGimbal to true + var gimbalModule = Part.Modules.GetModules().FirstOrDefault(); + if (gimbalModule != null) + { + HasGimbal = true; + gimbal = new GimbalFields(gimbalModule, Shared); + } + } + private void EngineInitializeSuffixes() { - AddSuffix("ACTIVATE", new NoArgsSuffix(() => engine.Activate())); - AddSuffix("SHUTDOWN", new NoArgsSuffix(() => engine.Shutdown())); - AddSuffix("THRUSTLIMIT", new ClampSetSuffix(() => engine.ThrustPercentage, value => engine.ThrustPercentage = value, 0, 100, 0.5f)); - AddSuffix("MAXTHRUST", new Suffix(() => engine.MaxThrust)); - AddSuffix("THRUST", new Suffix(() => engine.FinalThrust)); - AddSuffix("FUELFLOW", new Suffix(() => engine.FuelFlow)); - AddSuffix("ISP", new Suffix(() => engine.SpecificImpulse)); - AddSuffix(new[] {"VISP", "VACUUMISP"}, new Suffix(() => engine.VacuumSpecificImpluse)); - AddSuffix(new[] {"SLISP", "SEALEVELISP"}, new Suffix(() => engine.SeaLevelSpecificImpulse)); - AddSuffix("FLAMEOUT", new Suffix(() => engine.Flameout)); - AddSuffix("IGNITION", new Suffix(() => engine.Ignition)); - AddSuffix("ALLOWRESTART", new Suffix(() => engine.AllowRestart)); - AddSuffix("ALLOWSHUTDOWN", new Suffix(() => engine.AllowShutdown)); - AddSuffix("THROTTLELOCK", new Suffix(() => engine.ThrottleLock)); + AddSuffix("ACTIVATE", new NoArgsVoidSuffix(Activate)); + AddSuffix("SHUTDOWN", new NoArgsVoidSuffix(Shutdown)); + AddSuffix("THRUSTLIMIT", new ClampSetSuffix(() => engine.ThrustPercentage, + value => engine.ThrustPercentage = value, + 0f, 100f, 0f, + "thrust limit percentage for this engine")); + AddSuffix("MAXTHRUST", new Suffix(() => engine.MaxThrust)); + AddSuffix("THRUST", new Suffix(() => engine.FinalThrust)); + AddSuffix("FUELFLOW", new Suffix(() => engine.FuelFlow)); + AddSuffix("ISP", new Suffix(() => engine.SpecificImpulse)); + AddSuffix(new[] { "VISP", "VACUUMISP" }, new Suffix(() => engine.VacuumSpecificImpluse)); + AddSuffix(new[] { "SLISP", "SEALEVELISP" }, new Suffix(() => engine.SeaLevelSpecificImpulse)); + AddSuffix("FLAMEOUT", new Suffix(() => engine.Flameout)); + AddSuffix("IGNITION", new Suffix(() => engine.Ignition)); + AddSuffix("ALLOWRESTART", new Suffix(() => engine.AllowRestart)); + AddSuffix("ALLOWSHUTDOWN", new Suffix(() => engine.AllowShutdown)); + AddSuffix("THROTTLELOCK", new Suffix(() => engine.ThrottleLock)); + AddSuffix("ISPAT", new OneArgsSuffix(GetIspAtAtm)); + AddSuffix("MAXTHRUSTAT", new OneArgsSuffix(GetMaxThrustAtAtm)); + AddSuffix("AVAILABLETHRUST", new Suffix(() => engine.AvailableThrust)); + AddSuffix("AVAILABLETHRUSTAT", new OneArgsSuffix(GetAvailableThrustAtAtm)); + //MultiMode features + AddSuffix("MULTIMODE", new Suffix(() => MultiMode)); + AddSuffix("MODES", new Suffix(GetAllModes, "A List of all modes of this engine")); + AddSuffix("MODE", new Suffix(GetCurrentMode)); + AddSuffix("TOGGLEMODE", new NoArgsVoidSuffix(ToggleMode)); + AddSuffix("PRIMARYMODE", new SetSuffix(GetRunningPrimary, SetRunningPrimary)); + AddSuffix("AUTOSWITCH", new SetSuffix(GetAutoSwitch, SetAutoswitch)); + //gimbal interface + AddSuffix("HASGIMBAL", new Suffix(() => HasGimbal)); + AddSuffix("GIMBAL", new Suffix(GetGimbal)); } public static ListValue PartsToList(IEnumerable parts, SharedObjects sharedObj) @@ -39,21 +119,122 @@ public static ListValue PartsToList(IEnumerable parts, SharedObjec var toReturn = new ListValue(); foreach (var part in parts) { - foreach (PartModule module in part.Modules) + var multiModeEngines = part.Modules.GetModules(); + if (multiModeEngines.Count > 0) + toReturn.Add(new EngineValue(part, multiModeEngines.First(), sharedObj)); + else { - var engineModule = module as ModuleEngines; - var engineModuleFx = module as ModuleEnginesFX; - if (engineModuleFx != null) - { - toReturn.Add(new EngineValue(part, new ModuleEngineAdapter(engineModuleFx), sharedObj)); - } - else if (engineModule != null) - { - toReturn.Add(new EngineValue(part, new ModuleEngineAdapter(engineModule), sharedObj)); - } + var moduleEngines = part.Modules.GetModules(); + if (moduleEngines.Count > 0) + toReturn.Add(new EngineValue(part, new ModuleEngineAdapter(moduleEngines.First()), sharedObj)); } } return toReturn; } + + public void Activate() + { + ThrowIfNotCPUVessel(); + engine.Activate(); + } + + public void Shutdown() + { + ThrowIfNotCPUVessel(); + engine.Shutdown(); + } + + public ScalarValue GetIspAtAtm(ScalarValue atmPressure) + { + return engine.IspAtAtm(atmPressure); + } + + public ScalarValue GetMaxThrustAtAtm(ScalarValue atmPressure) + { + return engine.MaxThrustAtAtm(atmPressure); + } + + public ScalarValue GetAvailableThrustAtAtm(ScalarValue atmPressure) + { + return engine.AvailableThrustAtAtm(atmPressure); + } + + public ListValue GetAllModes() + { + var toReturn = new ListValue(); + if (MultiMode) + { + toReturn.Add(new StringValue(MMengine.primaryEngineID)); + toReturn.Add(new StringValue(MMengine.secondaryEngineID)); + } + else + { + toReturn.Add(new StringValue("Single mode")); + } + + return toReturn; + } + + public void ToggleMode() + { + ThrowIfNotCPUVessel(); + if (!MultiMode) + throw new KOSException("Attempted to call the TOGGLEMODE suffix on a non-multi mode engine."); + // Use Invoke to call ModeEvent, since the underlying method is private. + MMengine.Invoke("ModeEvent", 0); + } + + public BooleanValue GetRunningPrimary() + { + if (!MultiMode) + throw new KOSException("Attempted to get the PRIMARYMODE suffix on a non-multi mode engine."); + return MMengine.runningPrimary; + } + + public void SetRunningPrimary(BooleanValue prim) + { + ThrowIfNotCPUVessel(); + if (!MultiMode) + throw new KOSException("Attempted to set the PRIMARYMODE suffix on a non-multi mode engine."); + // If runningPrimary does not match prim, call ToggleMode + if (prim != MMengine.runningPrimary) + ToggleMode(); + } + + public BooleanValue GetAutoSwitch() + { + if (!MultiMode) + throw new KOSException("Attempted to get the AUTOSWITCH suffix on a non-multi mode engine."); + return MMengine.autoSwitch; + } + + public void SetAutoswitch(BooleanValue auto) + { + ThrowIfNotCPUVessel(); + if (!MultiMode) + throw new KOSException("Attempted to set the AUTOSWITCH suffix on a non-multi mode engine."); + // if autoSwitch doesn't equal auto, use invoke to call the autoswitch method because the method is private + if (MMengine.autoSwitch != auto) + { + if (auto) + MMengine.Invoke("EnableAutoSwitch", 0); + else + MMengine.Invoke("DisableAutoSwitch", 0); + } + } + + public StringValue GetCurrentMode() + { + if (!MultiMode) + throw new KOSException("Attempted to get the MODE suffix on a non-multi mode engine."); + return MMengine.mode; + } + + public GimbalFields GetGimbal() + { + if (gimbal != null) + return gimbal; + throw new KOSException("Attempted to get the GIMBAL suffix on an engine that does not have a gimbal."); + } } } \ No newline at end of file diff --git a/src/kOS/Suffixed/Part/GimbalValue.cs b/src/kOS/Suffixed/Part/GimbalValue.cs deleted file mode 100644 index 28bc8f1c2..000000000 --- a/src/kOS/Suffixed/Part/GimbalValue.cs +++ /dev/null @@ -1,28 +0,0 @@ -using kOS.Safe.Encapsulation.Suffixes; - -namespace kOS.Suffixed.Part -{ - public class GimbalValue : PartValue - { - private readonly ModuleGimbal gimbal; - - public GimbalValue(ModuleGimbal gimbal, SharedObjects sharedObj):base(gimbal.part, sharedObj) - { - this.gimbal = gimbal; - InitializeGimbalSuffixes(); - } - - private void InitializeGimbalSuffixes() - { - AddSuffix("LOCK", new SetSuffix(() => gimbal.gimbalLock, value => - { - gimbal.gimbalLock = value; - }, "Is the Gimbal free to travel?")); - AddSuffix("RANGE", new Suffix(() => gimbal.gimbalRange ,"The Gimbal's Possible Range of movement")); - AddSuffix("RESPONSESPEED", new Suffix(() => gimbal.gimbalResponseSpeed, "The Gimbal's Possible Rate of travel")); - AddSuffix("PITCHANGLE", new Suffix(() => gimbal.gimbalLock ? 0 : gimbal.gimbalAnglePitch, "Current Gimbal Pitch")); - AddSuffix("YAWANGLE", new Suffix(() => gimbal.gimbalLock ? 0 : gimbal.gimbalAngleYaw, "Current Gimbal Yaw" )); - AddSuffix("ROLLANGLE", new Suffix(() => gimbal.gimbalLock ? 0 : gimbal.gimbalAngleRoll, "Current Gimbal Roll")); - } - } -} diff --git a/src/kOS/Suffixed/Part/ModuleEngineAdapter.cs b/src/kOS/Suffixed/Part/ModuleEngineAdapter.cs index b3d1f5ddb..18597fd07 100644 --- a/src/kOS/Suffixed/Part/ModuleEngineAdapter.cs +++ b/src/kOS/Suffixed/Part/ModuleEngineAdapter.cs @@ -1,5 +1,6 @@ -using System; -using kOS.Safe.Encapsulation.Part; +using kOS.Safe.Encapsulation.Part; +using System; +using UnityEngine; namespace kOS.Suffixed.Part { @@ -34,9 +35,11 @@ public void Activate() case EngineType.Engine: engineModule.Activate(); break; + case EngineType.EngineFx: engineModuleFx.Activate(); break; + default: throw new ArgumentOutOfRangeException(); } @@ -49,9 +52,11 @@ public void Shutdown() case EngineType.Engine: engineModule.Shutdown(); break; + case EngineType.EngineFx: engineModuleFx.Shutdown(); break; + default: throw new ArgumentOutOfRangeException(); } @@ -98,10 +103,28 @@ public float MaxThrust switch (engineType) { case EngineType.Engine: - return engineModule.maxThrust; + return (float)GetEngineThrust(engineModule); + + case EngineType.EngineFx: + return (float)GetEngineThrust(engineModuleFx); + + default: + throw new ArgumentOutOfRangeException(); + } + } + } + + public float AvailableThrust + { + get + { + switch (engineType) + { + case EngineType.Engine: + return (float)GetEngineThrust(engineModule, useThrustLimit: true); case EngineType.EngineFx: - return engineModuleFx.maxThrust; + return (float)GetEngineThrust(engineModuleFx, useThrustLimit: true); default: throw new ArgumentOutOfRangeException(); @@ -127,6 +150,51 @@ public float FinalThrust } } + public static float GetEngineThrust(ModuleEngines engine, float throttle = 1.0f, bool useThrustLimit = false, double atmPressure = -1.0) + { + if (engine != null) + { + if (!engine.isOperational) return 0.0f; + if (useThrustLimit) { throttle = throttle * engine.thrustPercentage / 100.0f; } + if (atmPressure < 0) { atmPressure = engine.part.staticPressureAtm; } + float flowMod = 1.0f; + float velMod = 1.0f; + if (engine.atmChangeFlow) + { + flowMod = (float)(engine.part.atmDensity / 1.225f); + } + if (engine.useAtmCurve && engine.atmCurve != null) + { + flowMod = engine.atmCurve.Evaluate(flowMod); + } + if (engine.useVelCurve && engine.velCurve != null) + { + velMod = velMod * engine.velCurve.Evaluate((float)engine.vessel.mach); + } + // thrust is modified fuel flow rate times isp time g times the velocity modifier for jet engines (as of KSP 1.0) + return Mathf.Lerp(engine.minFuelFlow, engine.maxFuelFlow, throttle) * flowMod * GetEngineIsp(engine, atmPressure) * engine.g * velMod; + } + else return 0.0f; + } + + public static float GetEngineIsp(ModuleEngines engine) + { + if (engine != null) + { + return GetEngineIsp(engine, engine.part.staticPressureAtm); + } + else return 0.0f; + } + + public static float GetEngineIsp(ModuleEngines engine, double staticPressureAtm) + { + if (engine != null) + { + return engine.atmosphereCurve.Evaluate((float)staticPressureAtm); + } + else return 0.0f; + } + public float FuelFlow { get @@ -162,6 +230,7 @@ public float SpecificImpulse } } } + public float VacuumSpecificImpluse { get @@ -179,6 +248,7 @@ public float VacuumSpecificImpluse } } } + public float SeaLevelSpecificImpulse { get @@ -286,5 +356,50 @@ public bool ThrottleLock } } } + + public float IspAtAtm(double atmPressure) + { + switch (engineType) + { + case EngineType.Engine: + return ModuleEngineAdapter.GetEngineIsp(engineModule, atmPressure); + + case EngineType.EngineFx: + return ModuleEngineAdapter.GetEngineIsp(engineModuleFx, atmPressure); + + default: + throw new ArgumentOutOfRangeException(); + } + } + + public float MaxThrustAtAtm(double atmPressure) + { + switch (engineType) + { + case EngineType.Engine: + return ModuleEngineAdapter.GetEngineThrust(engineModule, atmPressure: atmPressure); + + case EngineType.EngineFx: + return ModuleEngineAdapter.GetEngineThrust(engineModuleFx, atmPressure: atmPressure); + + default: + throw new ArgumentOutOfRangeException(); + } + } + + public float AvailableThrustAtAtm(double atmPressure) + { + switch (engineType) + { + case EngineType.Engine: + return ModuleEngineAdapter.GetEngineThrust(engineModule, useThrustLimit: true, atmPressure: atmPressure); + + case EngineType.EngineFx: + return ModuleEngineAdapter.GetEngineThrust(engineModuleFx, useThrustLimit: true, atmPressure: atmPressure); + + default: + throw new ArgumentOutOfRangeException(); + } + } } } \ No newline at end of file diff --git a/src/kOS/Suffixed/Part/PartValue.cs b/src/kOS/Suffixed/Part/PartValue.cs index c721836af..82d7ef9a9 100644 --- a/src/kOS/Suffixed/Part/PartValue.cs +++ b/src/kOS/Suffixed/Part/PartValue.cs @@ -1,27 +1,28 @@ -using System; -using kOS.Module; +using kOS.Module; using kOS.Safe.Encapsulation; -using kOS.Safe.Exceptions; using kOS.Safe.Encapsulation.Suffixes; -using System.Linq; -using kOS.Safe.Utilities; +using kOS.Safe.Exceptions; using kOS.Suffixed.PartModuleField; using kOS.Utilities; +using System; +using System.Linq; +using kOS.Safe.Compilation.KS; using UnityEngine; namespace kOS.Suffixed.Part { + [kOS.Safe.Utilities.KOSNomenclature("Part")] public class PartValue : Structure, IKOSTargetable { - private readonly SharedObjects shared; + protected SharedObjects Shared { get; private set; } public global::Part Part { get; private set; } public PartValue(global::Part part, SharedObjects sharedObj) { Part = part; - shared = sharedObj; - + Shared = sharedObj; + // This cannot be called from inside InitializeSuffixes because the base constructor calls // InitializeSuffixes first before this constructor has set "Part" to a real value. PartInitializeSuffixes(); @@ -29,64 +30,77 @@ public PartValue(global::Part part, SharedObjects sharedObj) private void PartInitializeSuffixes() { - AddSuffix("CONTROLFROM", new NoArgsSuffix(ControlFrom)); - AddSuffix("NAME", new Suffix(() => Part.name)); - AddSuffix("FUELCROSSFEED", new Suffix(() => Part.fuelCrossFeed)); - AddSuffix("TITLE", new Suffix(() => Part.partInfo.title)); - AddSuffix("STAGE", new Suffix(() => Part.inverseStage)); - AddSuffix("UID", new Suffix(Part.flightID.ToString)); - AddSuffix("ROTATION", new Suffix(() => new Direction( Part.transform.rotation) )); - AddSuffix("POSITION", new Suffix(() => new Vector( Part.transform.position - shared.Vessel.findWorldCenterOfMass() ))); - AddSuffix("TAG", new SetSuffix(GetTagName, SetTagName)); + AddSuffix("CONTROLFROM", new NoArgsVoidSuffix(ControlFrom)); + AddSuffix("NAME", new Suffix(() => Part.name)); + AddSuffix("FUELCROSSFEED", new Suffix(() => Part.fuelCrossFeed)); + AddSuffix("TITLE", new Suffix(() => Part.partInfo.title)); + AddSuffix("STAGE", new Suffix(() => Part.inverseStage)); + AddSuffix("UID", new Suffix(() => Part.flightID.ToString())); + AddSuffix("ROTATION", new Suffix(() => new Direction(Part.transform.rotation))); + AddSuffix("POSITION", new Suffix(() => new Vector(Part.transform.position - Shared.Vessel.findWorldCenterOfMass()))); + AddSuffix("TAG", new SetSuffix(GetTagName, SetTagName)); AddSuffix("FACING", new Suffix(() => GetFacing(Part))); AddSuffix("RESOURCES", new Suffix(() => GatherResources(Part))); - AddSuffix("TARGETABLE", new Suffix(() => Part.Modules.OfType().Any())); - AddSuffix("SHIP", new Suffix(() => new VesselTarget(Part.vessel, shared))); - AddSuffix("GETMODULE", new OneArgsSuffix(GetModule)); - AddSuffix("GETMODULEBYINDEX", new OneArgsSuffix(GetModuleIndex)); + AddSuffix("TARGETABLE", new Suffix(() => Part.Modules.OfType().Any())); + AddSuffix("SHIP", new Suffix(() => new VesselTarget(Part.vessel, Shared))); + AddSuffix("HASMODULE", new OneArgsSuffix(HasModule)); + AddSuffix("GETMODULE", new OneArgsSuffix(GetModule)); + AddSuffix("GETMODULEBYINDEX", new OneArgsSuffix(GetModuleIndex)); AddSuffix(new[] { "MODULES", "ALLMODULES" }, new Suffix(GetAllModules, "A List of all the modules' names on this part")); - AddSuffix("PARENT", new Suffix(() => PartValueFactory.Construct(Part.parent,shared), "The parent part of this part")); - AddSuffix("HASPARENT", new Suffix(() => Part.parent != null, "Tells you if this part has a parent, is used to avoid null exception from PARENT")); - AddSuffix("CHILDREN", new Suffix>(() => PartValueFactory.ConstructGeneric(Part.children, shared), "A LIST() of the children parts of this part")); - AddSuffix("DRYMASS", new Suffix(Part.GetDryMass, "The Part's mass when empty")); - AddSuffix("MASS", new Suffix(Part.CalculateCurrentMass, "The Part's current mass")); - AddSuffix("WETMASS", new Suffix(Part.GetWetMass, "The Part's mass when full")); - AddSuffix("HASPHYSICS", new Suffix(Part.HasPhysics, "Is this a strange 'massless' part")); + AddSuffix("PARENT", new Suffix(() => PartValueFactory.Construct(Part.parent, Shared), "The parent part of this part")); + AddSuffix("HASPARENT", new Suffix(() => Part.parent != null, "Tells you if this part has a parent, is used to avoid null exception from PARENT")); + AddSuffix("CHILDREN", new Suffix>(() => PartValueFactory.ConstructGeneric(Part.children, Shared), "A LIST() of the children parts of this part")); + AddSuffix("DRYMASS", new Suffix(() => Part.GetDryMass(), "The Part's mass when empty")); + AddSuffix("MASS", new Suffix(() => Part.CalculateCurrentMass(), "The Part's current mass")); + AddSuffix("WETMASS", new Suffix(() => Part.GetWetMass(), "The Part's mass when full")); + AddSuffix("HASPHYSICS", new Suffix(() => Part.HasPhysics(), "Is this a strange 'massless' part")); } + public void ThrowIfNotCPUVessel() + { + if (Part.vessel.id != Shared.Vessel.id) + throw new KOSWrongCPUVesselException(); + } - - private PartModuleFields GetModule(string modName) + private PartModuleFields GetModule(StringValue modName) { foreach (PartModule mod in Part.Modules) { - SafeHouse.Logger.Log(string.Format("Does \"{0}\" == \"{1}\"?", mod.moduleName.ToUpper(), modName.ToUpper())); - if (String.Equals(mod.moduleName, modName, StringComparison.CurrentCultureIgnoreCase)) + if (string.Equals(mod.moduleName, modName, StringComparison.OrdinalIgnoreCase)) { - SafeHouse.Logger.Log("yes it does"); - return PartModuleFieldsFactory.Construct(mod,shared); + return PartModuleFieldsFactory.Construct(mod, Shared); } } - throw new KOSLookupFailException( "module", modName.ToUpper(), this ); + throw new KOSLookupFailException("module", modName.ToUpper(), this); } - private PartModuleFields GetModuleIndex(int moduleIndex) + private BooleanValue HasModule(StringValue modName) + { + foreach (PartModule mod in Part.Modules) + { + if (string.Equals(mod.moduleName, modName, StringComparison.OrdinalIgnoreCase)) return true; + } + return false; + } + + private PartModuleFields GetModuleIndex(ScalarValue moduleIndex) { if (moduleIndex < Part.Modules.Count) { - return PartModuleFieldsFactory.Construct(Part.Modules.GetModule(moduleIndex), shared); + return PartModuleFieldsFactory.Construct(Part.Modules.GetModule(moduleIndex), Shared); } - throw new KOSLookupFailException("module", String.Format("MODULEINDEX[{0}]", moduleIndex), this); + throw new KOSLookupFailException("module", string.Format("MODULEINDEX[{0}]", moduleIndex), this); } - - public string GetTagName() // public because I picture this being a useful API method later + + public StringValue GetTagName() // public because I picture this being a useful API method later { KOSNameTag tagModule = Part.Modules.OfType().FirstOrDefault(); return tagModule == null ? string.Empty : tagModule.nameTag; } - private void SetTagName(string value) + private void SetTagName(StringValue value) { + ThrowIfNotCPUVessel(); KOSNameTag tagModule = Part.Modules.OfType().FirstOrDefault(); if (tagModule != null) tagModule.nameTag = value; } @@ -117,8 +131,9 @@ private Direction GetFacing(global::Part part) private void ControlFrom() { - var dockingModule = Part.Modules.OfType().First(); - var commandModule = Part.Modules.OfType().First(); + ThrowIfNotCPUVessel(); + var dockingModule = Part.Modules.OfType().FirstOrDefault(); + var commandModule = Part.Modules.OfType().FirstOrDefault(); if (commandModule != null) { @@ -130,7 +145,7 @@ private void ControlFrom() } else { - Part.vessel.SetReferenceTransform(Part); + throw new KOSCommandInvalidHereException(LineCol.Unknown(), "CONTROLFROM", "a generic part value", "a docking port or command part"); } } @@ -149,7 +164,7 @@ private ListValue GetAllModules() var returnValue = new ListValue(); foreach (PartModule mod in Part.Modules) { - returnValue.Add(mod.moduleName); + returnValue.Add(new StringValue(mod.moduleName)); } return returnValue; } @@ -164,7 +179,7 @@ public override bool Equals(object obj) if (ReferenceEquals(null, obj)) return false; if (ReferenceEquals(this, obj)) return true; if (obj.GetType() != GetType()) return false; - return Equals((PartValue) obj); + return Equals((PartValue)obj); } public override int GetHashCode() diff --git a/src/kOS/Suffixed/Part/PartValueFactory.cs b/src/kOS/Suffixed/Part/PartValueFactory.cs index f1ee5e28d..10acf11f2 100644 --- a/src/kOS/Suffixed/Part/PartValueFactory.cs +++ b/src/kOS/Suffixed/Part/PartValueFactory.cs @@ -1,47 +1,43 @@ -using System.Collections.Generic; -using System.Linq; using kOS.Safe.Encapsulation; +using System.Collections.Generic; +using System.Linq; namespace kOS.Suffixed.Part { - public class PartValueFactory + public class PartValueFactory { public static ListValue Construct(IEnumerable parts, SharedObjects shared) { var partList = parts.Select(part => Construct(part, shared)).ToList(); return ListValue.CreateList(partList); - } + } public static ListValue ConstructGeneric(IEnumerable parts, SharedObjects shared) { var partList = parts.Select(part => Construct(part, shared)).ToList(); return ListValue.CreateList(partList); - } + } public static PartValue Construct(global::Part part, SharedObjects shared) { - foreach (PartModule module in part.Modules) - { - ModuleEngines mEng = module as ModuleEngines; - if (mEng != null) - return new EngineValue(part, new ModuleEngineAdapter(mEng), shared); - ModuleEnginesFX mEngFX = module as ModuleEnginesFX; - if (mEngFX != null) - return new EngineValue(part, new ModuleEngineAdapter(mEngFX), shared); - ModuleDockingNode mDock = module as ModuleDockingNode; - if (mDock != null) - return new DockingPortValue(mDock, shared); - ModuleEnviroSensor mSense = module as ModuleEnviroSensor; - if (mSense != null) - return new SensorValue(part, mSense, shared); - var gimbalModule = module as ModuleGimbal; - if (gimbalModule != null) - return new GimbalValue(gimbalModule,shared); - - } - + var multiModeEngines = part.Modules.GetModules(); + if (multiModeEngines.Count > 0) + return new EngineValue(part, multiModeEngines.First(), shared); + + var moduleEngines = part.Modules.GetModules(); + if (moduleEngines.Count > 0) + return new EngineValue(part, new ModuleEngineAdapter(moduleEngines.First()), shared); + + var moduleDockingNodes = part.Modules.GetModules(); + if (moduleDockingNodes.Count > 0) + return new DockingPortValue(moduleDockingNodes.First(), shared); + + var moduleEnviroSensors = part.Modules.GetModules(); + if (moduleEnviroSensors.Count > 0) + return new SensorValue(part, moduleEnviroSensors.First(), shared); + // Fallback if none of the above: then just a normal part: return new PartValue(part, shared); } } -} +} \ No newline at end of file diff --git a/src/kOS/Suffixed/Part/SensorValue.cs b/src/kOS/Suffixed/Part/SensorValue.cs index aa59b237a..f2902ad53 100644 --- a/src/kOS/Suffixed/Part/SensorValue.cs +++ b/src/kOS/Suffixed/Part/SensorValue.cs @@ -4,6 +4,7 @@ namespace kOS.Suffixed.Part { + [kOS.Safe.Utilities.KOSNomenclature("Sensor")] public class SensorValue : PartValue { private readonly ModuleEnviroSensor sensor; @@ -16,11 +17,11 @@ public SensorValue(global::Part part, ModuleEnviroSensor sensor, SharedObjects s private void SensorInitializeSuffixes() { - AddSuffix("ACTIVE", new SetSuffix(() => sensor.sensorActive, value => sensor.sensorActive = value)); - AddSuffix("TYPE", new Suffix(() => sensor.sensorType)); - AddSuffix("DISPLAY", new Suffix(() => sensor.readoutInfo)); - AddSuffix("POWERCONSUMPTION", new Suffix(() => sensor.powerConsumption)); - AddSuffix("TOGGLE", new NoArgsSuffix(() => sensor.Toggle())); + AddSuffix("ACTIVE", new SetSuffix(() => sensor.sensorActive, value => sensor.sensorActive = value)); + AddSuffix("TYPE", new Suffix(() => sensor.sensorType)); + AddSuffix("DISPLAY", new Suffix(() => sensor.readoutInfo)); + AddSuffix("POWERCONSUMPTION", new Suffix(() => sensor.powerConsumption)); + AddSuffix("TOGGLE", new NoArgsVoidSuffix(() => sensor.Toggle())); } public static ListValue PartsToList(IEnumerable parts, SharedObjects sharedObj) diff --git a/src/kOS/Suffixed/PartModuleField/GimbalFields.cs b/src/kOS/Suffixed/PartModuleField/GimbalFields.cs index 10a325cef..97764f84c 100644 --- a/src/kOS/Suffixed/PartModuleField/GimbalFields.cs +++ b/src/kOS/Suffixed/PartModuleField/GimbalFields.cs @@ -1,7 +1,9 @@ -using kOS.Safe.Encapsulation.Suffixes; +using kOS.Safe.Encapsulation; +using kOS.Safe.Encapsulation.Suffixes; namespace kOS.Suffixed.PartModuleField { + [kOS.Safe.Utilities.KOSNomenclature("Gimbal")] public class GimbalFields : PartModuleFields { private readonly ModuleGimbal gimbal; @@ -14,15 +16,19 @@ public GimbalFields(ModuleGimbal gimbal, SharedObjects sharedObj):base(gimbal, s private void InitializeGimbalSuffixes() { - AddSuffix("LOCK", new SetSuffix(() => gimbal.gimbalLock, value => + AddSuffix("LOCK", new SetSuffix(() => gimbal.gimbalLock, value => { gimbal.gimbalLock = value; }, "Is the Gimbal free to travel?")); - AddSuffix("RANGE", new Suffix(() => gimbal.gimbalRange ,"The Gimbal's Possible Range of movement")); - AddSuffix("RESPONSESPEED", new Suffix(() => gimbal.gimbalResponseSpeed, "The Gimbal's Possible Rate of travel")); - AddSuffix("PITCHANGLE", new Suffix(() => gimbal.gimbalLock ? 0 : gimbal.gimbalAnglePitch, "Current Gimbal Pitch")); - AddSuffix("YAWANGLE", new Suffix(() => gimbal.gimbalLock ? 0 : gimbal.gimbalAngleYaw, "Current Gimbal Yaw" )); - AddSuffix("ROLLANGLE", new Suffix(() => gimbal.gimbalLock ? 0 : gimbal.gimbalAngleRoll, "Current Gimbal Roll")); + AddSuffix("LIMIT", new ClampSetSuffix(() => gimbal.gimbalLimiter, + value => gimbal.gimbalLimiter = value, + 0f, 100f, 1f, + "Gimbal range limit percentage")); + AddSuffix("RANGE", new Suffix(() => gimbal.gimbalRange ,"The Gimbal's Possible Range of movement")); + AddSuffix("RESPONSESPEED", new Suffix(() => gimbal.gimbalResponseSpeed, "The Gimbal's Possible Rate of travel")); + AddSuffix("PITCHANGLE", new Suffix(() => gimbal.gimbalLock ? 0 : gimbal.gimbalAnglePitch, "Current Gimbal Pitch")); + AddSuffix("YAWANGLE", new Suffix(() => gimbal.gimbalLock ? 0 : gimbal.gimbalAngleYaw, "Current Gimbal Yaw" )); + AddSuffix("ROLLANGLE", new Suffix(() => gimbal.gimbalLock ? 0 : gimbal.gimbalAngleRoll, "Current Gimbal Roll")); } } } diff --git a/src/kOS/Suffixed/PartModuleField/PartModuleFields.cs b/src/kOS/Suffixed/PartModuleField/PartModuleFields.cs index c80212e07..30d4d19de 100644 --- a/src/kOS/Suffixed/PartModuleField/PartModuleFields.cs +++ b/src/kOS/Suffixed/PartModuleField/PartModuleFields.cs @@ -1,13 +1,15 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using kOS.Safe.Encapsulation; +using kOS.Safe.Encapsulation; using kOS.Safe.Encapsulation.Suffixes; using kOS.Safe.Exceptions; using kOS.Suffixed.Part; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; using UnityEngine; using Math = kOS.Safe.Utilities.Math; +using kOS.AddOns.RemoteTech; +using kOS.Safe.Utilities; namespace kOS.Suffixed.PartModuleField { @@ -17,11 +19,12 @@ namespace kOS.Suffixed.PartModuleField /// each KSPField of the PartModule becomes a suffix you can get to with /// GetSuffix(). /// + [kOS.Safe.Utilities.KOSNomenclature("PartModule")] public class PartModuleFields : Structure { - private readonly PartModule partModule; - private readonly SharedObjects shared; - + protected readonly PartModule partModule; + protected readonly SharedObjects shared; + /// /// Create a kOS-user variable wrapper around a KSP PartModule attached to a part. /// @@ -37,6 +40,12 @@ public PartModuleFields(PartModule partModule, SharedObjects shared) InitializeSuffixesAfterConstruction(); } + public void ThrowIfNotCPUVessel() + { + if (partModule.vessel.id != shared.Vessel.id) + throw new KOSWrongCPUVesselException(); + } + /// /// Get the string type of the module /// @@ -50,11 +59,11 @@ public override string ToString() { var returnValue = new StringBuilder(); returnValue.AppendLine(GetModuleName() + ", containing:"); - returnValue.AppendLine( AllThings().ToString()); + returnValue.AppendLine(AllThings().ToString()); return returnValue.ToString(); } - + /// /// Return true if the field in question is editable in the KSP rightclick menu /// as an in-game tweakable right now. @@ -65,7 +74,7 @@ private bool IsEditable(BaseField field) { return GetFieldControls(field).Count > 0; } - + /// /// Get the UI_Controls on a KSPField which are user editable. /// @@ -77,7 +86,7 @@ private List GetFieldControls(BaseField field) attribs.AddRange(field.FieldInfo.GetCustomAttributes(true)); return attribs.OfType().Where(obj => (obj).controlEnabled).ToList(); } - + /// /// Return true if the value given is allowed for the field given. This uses the hints from the GUI /// system to decide what is and isn't allowed. (For example if a GUI slider goes from 10 to 20 at @@ -95,30 +104,33 @@ private List GetFieldControls(BaseField field) /// alter the value to an acceptable replacement which is why it passes by ref /// An exception you can choose to throw if you want, or null if the value is legal. /// Is it legal? - private bool IsLegalValue(BaseField field, ref object newVal, out KOSException except) + private bool IsLegalValue(BaseField field, ref Structure newVal, out KOSException except) { except = null; bool isLegal = true; - + Type fType = field.FieldInfo.FieldType; object convertedVal = newVal; - + if (!IsEditable(field)) { except = new KOSInvalidFieldValueException("Field is read-only"); return false; } - if (! newVal.GetType().IsSubclassOf(fType)) + if (!newVal.GetType().IsSubclassOf(fType)) { - try { - convertedVal = Convert.ChangeType(newVal,fType); + try + { + convertedVal = Convert.ChangeType(newVal, fType); } - catch (InvalidCastException) { - except = new KOSCastException(newVal.GetType(),fType); + catch (InvalidCastException) + { + except = new KOSCastException(newVal.GetType(), fType); return false; } - catch (FormatException) { - except = new KOSCastException(newVal.GetType(),fType); + catch (FormatException) + { + except = new KOSCastException(newVal.GetType(), fType); return false; } } @@ -128,7 +140,7 @@ private bool IsLegalValue(BaseField field, ref object newVal, out KOSException e // it's technically possible to have more than one according to the structure of // the API, this loop is here to check all of "them": foreach (UI_Control control in controls) - { + { // Some of these are subclasses of each other, so don't change this to an if/else. // It's a series of if's on purpose so it checks all classes the control is derived from. if (control is UI_Toggle) @@ -163,41 +175,59 @@ private bool IsLegalValue(BaseField field, ref object newVal, out KOSException e val = Math.ClampToIndent(val, range.minValue, range.maxValue, range.stepIncrement); convertedVal = Convert.ToDouble(val); } - if (! isLegal) + if (!isLegal) break; } - newVal = convertedVal; + newVal = FromPrimitiveWithAssert(convertedVal); return isLegal; } - + /// /// Return a list of all the strings of all KSPfields registered to this PartModule /// which are currently showing on the part's RMB menu. /// /// List of all the strings field names. - private ListValue AllFields(string formatter) - { + protected virtual ListValue AllFields(string formatter) + { var returnValue = new ListValue(); - + IEnumerable visibleFields = partModule.Fields.Cast().Where(FieldIsVisible); foreach (BaseField field in visibleFields) { - returnValue.Add(String.Format(formatter, - (IsEditable(field)?"settable":"get-only"), + returnValue.Add(new StringValue(string.Format(formatter, + IsEditable(field) ? "settable" : "get-only", field.guiName.ToLower(), - Utilities.Utils.KOSType(field.FieldInfo.FieldType)) ); + Utilities.Utils.KOSType(field.FieldInfo.FieldType)))); } return returnValue; } - + + /// + /// Return a list of all the strings of all KSPfields registered to this PartModule + /// which are currently showing on the part's RMB menu, without formating. + /// + /// List of all the strings field names. + protected virtual ListValue AllFieldNames() + { + var returnValue = new ListValue(); + + IEnumerable visibleFields = partModule.Fields.Cast().Where(FieldIsVisible); + + foreach (BaseField field in visibleFields) + { + returnValue.Add(new StringValue(field.guiName.ToLower())); + } + return returnValue; + } + /// /// Determine if the Partmodule has this KSPField on it, which is publicly /// usable by a kOS script at the moment: /// /// The field to search for /// true if it is on the PartModule, false if it is not - public bool HasField(string fieldName) + public virtual BooleanValue HasField(StringValue fieldName) { return FieldIsVisible(GetField(fieldName)); } @@ -207,10 +237,10 @@ public bool HasField(string fieldName) /// /// The case-insensitive guiName of the field. /// a BaseField - a KSP type that can be used to get the value, or its GUI name or its reflection info. - private BaseField GetField(string cookedGuiName) + protected BaseField GetField(string cookedGuiName) { return partModule.Fields.Cast(). - FirstOrDefault(field => String.Equals(field.guiName, cookedGuiName, StringComparison.CurrentCultureIgnoreCase)); + FirstOrDefault(field => string.Equals(field.guiName, cookedGuiName, StringComparison.CurrentCultureIgnoreCase)); } /// @@ -219,28 +249,46 @@ private BaseField GetField(string cookedGuiName) /// /// private ListValue AllEvents(string formatter) - { + { var returnValue = new ListValue(); - IEnumerable visibleEvents = partModule.Events.Where( EventIsVisible ); - + IEnumerable visibleEvents = partModule.Events.Where(EventIsVisible); + foreach (BaseEvent kspEvent in visibleEvents) { - returnValue.Add(String.Format(formatter, + returnValue.Add(new StringValue(string.Format(formatter, "callable", kspEvent.guiName.ToLower(), - "KSPEvent") ); + "KSPEvent"))); } return returnValue; } - + + /// + /// Return a list of all the KSPEvents the module has in it which are currently + /// visible on the RMB menu, without formatting. + /// + /// List of Event Names + private ListValue AllEventNames() + { + var returnValue = new ListValue(); + + IEnumerable visibleEvents = partModule.Events.Where(EventIsVisible); + + foreach (BaseEvent kspEvent in visibleEvents) + { + returnValue.Add(new StringValue(kspEvent.guiName.ToLower())); + } + return returnValue; + } + /// /// Determine if the Partmodule has this KSPEvent on it, which is publicly /// usable by a kOS script: /// /// The event name to search for /// true if it is on the PartModule, false if it is not - public bool HasEvent(string eventName) + public BooleanValue HasEvent(StringValue eventName) { return EventIsVisible(GetEvent(eventName)); } @@ -251,9 +299,9 @@ public bool HasEvent(string eventName) /// The event's case-insensitive guiname. /// private BaseEvent GetEvent(string cookedGuiName) - { + { return partModule.Events. - FirstOrDefault(kspEvent => String.Equals(kspEvent.guiName, cookedGuiName, StringComparison.CurrentCultureIgnoreCase)); + FirstOrDefault(kspEvent => string.Equals(kspEvent.guiName, cookedGuiName, StringComparison.CurrentCultureIgnoreCase)); } /// @@ -261,15 +309,30 @@ private BaseEvent GetEvent(string cookedGuiName) /// /// private ListValue AllActions(string formatter) - { + { var returnValue = new ListValue(); - - foreach (BaseAction kspAction in partModule.Actions) + + foreach (BaseAction kspAction in partModule.Actions) { - returnValue.Add(String.Format(formatter, + returnValue.Add(new StringValue(string.Format(formatter, "callable", kspAction.guiName.ToLower(), - "KSPAction") ); + "KSPAction"))); + } + return returnValue; + } + + /// + /// Return a list of all the KSPActions the module has in it, without formatting. + /// + /// List of Action Names + private ListValue AllActionNames() + { + var returnValue = new ListValue(); + + foreach (BaseAction kspAction in partModule.Actions) + { + returnValue.Add(new StringValue(kspAction.guiName.ToLower())); } return returnValue; } @@ -280,9 +343,9 @@ private ListValue AllActions(string formatter) /// /// The action name to search for /// true if it is on the PartModule, false if it is not - public bool HasAction(string actionName) + public BooleanValue HasAction(StringValue actionName) { - return partModule.Actions.Any(kspAction => String.Equals(kspAction.guiName, actionName, StringComparison.CurrentCultureIgnoreCase)); + return partModule.Actions.Any(kspAction => string.Equals(kspAction.guiName, actionName, StringComparison.CurrentCultureIgnoreCase)); } /// @@ -292,7 +355,7 @@ public bool HasAction(string actionName) /// private BaseAction GetAction(string cookedGuiName) { - return partModule.Actions.FirstOrDefault(kspAction => String.Equals(kspAction.guiName, cookedGuiName, StringComparison.CurrentCultureIgnoreCase)); + return partModule.Actions.FirstOrDefault(kspAction => string.Equals(kspAction.guiName, cookedGuiName, StringComparison.CurrentCultureIgnoreCase)); } /// @@ -307,40 +370,43 @@ private ListValue AllThings() // We appear to have not implemented a concatenator or range add for // our ListValue type. Thus the for-loops below: - ListValue fields = AllFields(FORMATTER); - ListValue events = AllEvents(FORMATTER); + ListValue fields = AllFields(FORMATTER); + ListValue events = AllEvents(FORMATTER); ListValue actions = AllActions(FORMATTER); - foreach (object t in fields) + foreach (Structure field in fields) { - all.Add(t); + all.Add(field); } - foreach (object t in events) + foreach (Structure kspevent in events) { - all.Add(t); + all.Add(kspevent); } - foreach (object t in actions) + foreach (Structure action in actions) { - all.Add(t); + all.Add(action); } return all; } private void InitializeSuffixesAfterConstruction() { - AddSuffix("NAME", new Suffix(() => partModule.moduleName)); - AddSuffix("PART", new Suffix(() => PartValueFactory.Construct(partModule.part,shared))); - AddSuffix("ALLFIELDS", new Suffix(() => AllFields("({0}) {1}, is {2}"))); - AddSuffix("HASFIELD", new OneArgsSuffix(HasField)); - AddSuffix("ALLEVENTS", new Suffix(() => AllEvents("({0}) {1}, is {2}"))); - AddSuffix("HASEVENT", new OneArgsSuffix(HasEvent)); + AddSuffix("NAME", new Suffix(() => partModule.moduleName)); + AddSuffix("PART", new Suffix(() => PartValueFactory.Construct(partModule.part, shared))); + AddSuffix("ALLFIELDS", new Suffix(() => AllFields("({0}) {1}, is {2}"))); + AddSuffix("ALLFIELDNAMES", new Suffix(AllFieldNames)); + AddSuffix("HASFIELD", new OneArgsSuffix(HasField)); + AddSuffix("ALLEVENTS", new Suffix(() => AllEvents("({0}) {1}, is {2}"))); + AddSuffix("AllEVENTNAMES", new Suffix(AllEventNames)); + AddSuffix("HASEVENT", new OneArgsSuffix(HasEvent)); AddSuffix("ALLACTIONS", new Suffix(() => AllActions("({0}) {1}, is {2}"))); - AddSuffix("HASACTION", new OneArgsSuffix(HasAction)); - AddSuffix("GETFIELD", new OneArgsSuffix(GetKSPFieldValue)); - AddSuffix("SETFIELD", new TwoArgsSuffix(SetKSPFieldValue)); - AddSuffix("DOEVENT", new OneArgsSuffix(CallKSPEvent)); - AddSuffix("DOACTION", new TwoArgsSuffix(CallKSPAction)); + AddSuffix("ALLACTIONNAMES", new Suffix(AllActionNames)); + AddSuffix("HASACTION", new OneArgsSuffix(HasAction)); + AddSuffix("GETFIELD", new OneArgsSuffix(GetKSPFieldValue)); + AddSuffix("SETFIELD", new TwoArgsSuffix(SetKSPFieldValue)); + AddSuffix("DOEVENT", new OneArgsSuffix(CallKSPEvent)); + AddSuffix("DOACTION", new TwoArgsSuffix(CallKSPAction)); } - + private static bool FieldIsVisible(BaseField field) { return (field != null) && (HighLogic.LoadedSceneIsEditor ? field.guiActiveEditor : field.guiActive); @@ -354,40 +420,41 @@ private static bool EventIsVisible(BaseEvent evt) evt.active ); } - + /// /// Get a KSPField with the kOS suffix name given. /// /// /// - private object GetKSPFieldValue(string suffixName) + protected Structure GetKSPFieldValue(StringValue suffixName) { BaseField field = GetField(suffixName); - if (field==null) - throw new KOSLookupFailException( "FIELD", suffixName, this); - if (! FieldIsVisible(field)) - throw new KOSLookupFailException( "FIELD", suffixName, this, true); - object obj = field.GetValue(partModule); + if (field == null) + throw new KOSLookupFailException("FIELD", suffixName, this); + if (!FieldIsVisible(field)) + throw new KOSLookupFailException("FIELD", suffixName, this, true); + Structure obj = FromPrimitiveWithAssert(field.GetValue(partModule)); return obj; } - + /// /// Set a KSPField with the kOS suffix name given to the new value given. /// /// /// - private void SetKSPFieldValue(string suffixName, object newValue) + protected virtual void SetKSPFieldValue(StringValue suffixName, Structure newValue) { + ThrowIfNotCPUVessel(); BaseField field = GetField(suffixName); - if (field==null) - throw new KOSLookupFailException( "FIELD", suffixName, this); - if (! FieldIsVisible(field)) - throw new KOSLookupFailException( "FIELD", suffixName, this, true); + if (field == null) + throw new KOSLookupFailException("FIELD", suffixName, this); + if (!FieldIsVisible(field)) + throw new KOSLookupFailException("FIELD", suffixName, this, true); - KOSException except; + KOSException except; if (IsLegalValue(field, ref newValue, out except)) { - object convertedValue = Convert.ChangeType(newValue,field.FieldInfo.FieldType); + object convertedValue = Convert.ChangeType(newValue, field.FieldInfo.FieldType); field.SetValue(convertedValue, partModule); } else @@ -400,14 +467,23 @@ private void SetKSPFieldValue(string suffixName, object newValue) /// Trigger whatever code the PartModule has attached to this Event, given the kOS name for the suffix. /// /// - private void CallKSPEvent(string suffixName) + private void CallKSPEvent(StringValue suffixName) { + ThrowIfNotCPUVessel(); BaseEvent evt = GetEvent(suffixName); - if (evt==null) - throw new KOSLookupFailException( "EVENT", suffixName, this); - if (! EventIsVisible(evt)) - throw new KOSLookupFailException( "EVENT", suffixName, this, true); - evt.Invoke(); + if (evt == null) + throw new KOSLookupFailException("EVENT", suffixName, this); + if (!EventIsVisible(evt)) + throw new KOSLookupFailException("EVENT", suffixName, this, true); + + if (RemoteTechHook.IsAvailable()) + { + RemoteTechHook.Instance.InvokeOriginalEvent(evt); + } + else + { + evt.Invoke(); + } } /// @@ -419,15 +495,16 @@ private void CallKSPEvent(string suffixName) /// /// /// true = activate, false = de-activate - private void CallKSPAction(string suffixName, bool param) + private void CallKSPAction(StringValue suffixName, BooleanValue param) { + ThrowIfNotCPUVessel(); BaseAction act = GetAction(suffixName); - if (act==null) - throw new KOSLookupFailException( "ACTION", suffixName, this); + if (act == null) + throw new KOSLookupFailException("ACTION", suffixName, this); string careerReason; - if (! Career.CanDoActions(out careerReason)) + if (!Career.CanDoActions(out careerReason)) throw new KOSLowTechException("use :DOACTION", careerReason); - act.Invoke( new KSPActionParam( act.actionGroup, (param ? KSPActionType.Activate : KSPActionType.Deactivate) )); + act.Invoke(new KSPActionParam(act.actionGroup, (param ? KSPActionType.Activate : KSPActionType.Deactivate))); } } -} +} \ No newline at end of file diff --git a/src/kOS/Suffixed/PartModuleField/PartModuleFieldsFactory.cs b/src/kOS/Suffixed/PartModuleField/PartModuleFieldsFactory.cs index 0c817eb60..60713a52a 100644 --- a/src/kOS/Suffixed/PartModuleField/PartModuleFieldsFactory.cs +++ b/src/kOS/Suffixed/PartModuleField/PartModuleFieldsFactory.cs @@ -1,6 +1,8 @@ using System.Collections.Generic; using System.Linq; using kOS.Safe.Encapsulation; +using kOS.AddOns.RemoteTech; +using kOS.Module; namespace kOS.Suffixed.PartModuleField { @@ -20,9 +22,24 @@ public static PartModuleFields Construct(PartModule mod, SharedObjects shared) var moduleGimbal = mod as ModuleGimbal; if (moduleGimbal != null) return new GimbalFields(moduleGimbal, shared); - // This seems pointlessly do-nothing for a special factory now, - // but it's here so that it can possibly become more - // sophisticated later if need be: + + var processor = mod as kOSProcessor; + + if (processor != null) { + return new kOSProcessorFields(processor, shared); + } + + if (mod.moduleName.Equals(RemoteTechAntennaModuleFields.RTAntennaModule)) { + return new RemoteTechAntennaModuleFields(mod, shared); + } + + var scienceExperimentFields = ScienceExperimentFieldsFactory.Construct(mod, shared); + + if (scienceExperimentFields != null) + { + return scienceExperimentFields; + } + return new PartModuleFields(mod, shared); } } diff --git a/src/kOS/Suffixed/PartModuleField/ScienceExperimentFields.cs b/src/kOS/Suffixed/PartModuleField/ScienceExperimentFields.cs new file mode 100644 index 000000000..cb78e79c2 --- /dev/null +++ b/src/kOS/Suffixed/PartModuleField/ScienceExperimentFields.cs @@ -0,0 +1,75 @@ +using System; +using kOS.Safe.Encapsulation.Suffixes; +using kOS.Safe.Exceptions; +using System.Linq; +using System.Reflection; +using System.Collections.Generic; +using kOS.Safe.Encapsulation; + +namespace kOS.Suffixed.PartModuleField +{ + [kOS.Safe.Utilities.KOSNomenclature("ScienceExperimentModule")] + public abstract class ScienceExperimentFields : PartModuleFields + { + protected IScienceDataContainer container; + public ScienceExperimentFields(PartModule module, SharedObjects shared) : base(module, shared) + { + this.container = module as IScienceDataContainer; + + if (container == null) + { + throw new KOSException("This module is not a science data container"); + } + + InitializeSuffixes(); + } + + private void InitializeSuffixes() + { + AddSuffix("DEPLOY", new NoArgsVoidSuffix(DeployExperiment, "Deploy and run this experiment")); + AddSuffix("RESET", new NoArgsVoidSuffix(ResetExperiment, "Reset this experiment")); + AddSuffix("TRANSMIT", new NoArgsVoidSuffix(TransmitData, "Transmit experiment data back to Kerbin")); + AddSuffix("DUMP", new NoArgsVoidSuffix(DumpData, "Dump experiment data")); + AddSuffix("INOPERABLE", new Suffix(() => Inoperable(), "Is this experiment inoperable")); + AddSuffix("DEPLOYED", new Suffix(() => Deployed(), "Is this experiment deployed")); + AddSuffix("RERUNNABLE", new Suffix(() => Rerunnable(), "Is this experiment rerunnable")); + AddSuffix("HASDATA", new Suffix(() => HasData(), "Does this experiment have any data stored")); + AddSuffix("DATA", new Suffix(Data, "Does this experiment have any data stored")); + } + + public abstract bool Deployed(); + public abstract bool Inoperable(); + public abstract void DeployExperiment(); + public abstract void ResetExperiment(); + + public virtual bool Rerunnable() + { + return container.IsRerunnable(); + } + + public virtual bool HasData() + { + return container.GetData().Any(); + } + + public virtual ListValue Data() + { + return new ListValue(container.GetData().Select(s => new ScienceDataValue(s)).Cast()); + } + + public virtual void DumpData() + { + ThrowIfNotCPUVessel(); + + Array.ForEach(container.GetData(), (d) => container.DumpData(d)); + } + + public abstract void TransmitData(); + + public new string ToString() + { + return "SCIENCE EXPERIMENT"; + } + } +} + diff --git a/src/kOS/Suffixed/PartModuleField/ScienceExperimentFieldsFactory.cs b/src/kOS/Suffixed/PartModuleField/ScienceExperimentFieldsFactory.cs new file mode 100644 index 000000000..c7a9cae0f --- /dev/null +++ b/src/kOS/Suffixed/PartModuleField/ScienceExperimentFieldsFactory.cs @@ -0,0 +1,24 @@ +using System; +using kOS.Safe.Utilities; +using kOS.AddOns.OrbitalScience; + +namespace kOS.Suffixed.PartModuleField +{ + public class ScienceExperimentFieldsFactory + { + public static ScienceExperimentFields Construct(PartModule mod, SharedObjects shared) + { + var fields = DMOrbitalScienceFieldsFactory.Construct(mod, shared); + if (fields != null) + { + return fields; + } else if (mod is ModuleScienceExperiment) + { + return new StockScienceExperimentFields(mod as ModuleScienceExperiment, shared); + } + + return null; + } + } +} + diff --git a/src/kOS/Suffixed/PartModuleField/StockScienceExperimentFields.cs b/src/kOS/Suffixed/PartModuleField/StockScienceExperimentFields.cs new file mode 100644 index 000000000..6b1b90b57 --- /dev/null +++ b/src/kOS/Suffixed/PartModuleField/StockScienceExperimentFields.cs @@ -0,0 +1,98 @@ +using kOS.Safe.Encapsulation.Suffixes; +using kOS.Safe.Exceptions; +using System.Collections; +using System.Linq; +using System.Reflection; +using System.Collections.Generic; +using kOS.Safe.Encapsulation; +using System; + +namespace kOS.Suffixed.PartModuleField +{ + [kOS.Safe.Utilities.KOSNomenclature("ScienceExperimentModule", KOSToCSharp=false)] + public class StockScienceExperimentFields : ScienceExperimentFields + { + protected readonly ModuleScienceExperiment module; + + public StockScienceExperimentFields(ModuleScienceExperiment module, SharedObjects sharedObj) : base(module, sharedObj) + { + this.module = module; + } + + public override bool Deployed() + { + return module.Deployed; + } + + public override void DeployExperiment() + { + if (HasData()) + { + throw new KOSException("Experiment already contains data"); + } + + if (Inoperable()) + { + throw new KOSException("Experiment is inoperable"); + } + + Deploy(); + } + + protected virtual void Deploy() + { + ThrowIfNotCPUVessel(); + + var gatherDataMethod = module.GetType().GetMethod("gatherData", + BindingFlags.NonPublic | BindingFlags.Instance); + + object result = gatherDataMethod.Invoke(module, new object[] { false }); + + IEnumerator e = result as IEnumerator; + + module.StartCoroutine(e); + } + + public override bool Inoperable() + { + return module.Inoperable; + } + + public override void ResetExperiment() + { + ThrowIfNotCPUVessel(); + + if (Inoperable()) + { + throw new KOSException("Experiment is inoperable"); + } + + module.ResetExperiment(); + } + + public override void TransmitData() + { + ThrowIfNotCPUVessel(); + + IScienceDataContainer container = module as IScienceDataContainer; + + ScienceData[] data = container.GetData(); + + List tranList = module.vessel.FindPartModulesImplementing(); + if (tranList.Count() > 0 && data.Count() > 0) + { + tranList.OrderBy(ScienceUtil.GetTransmitterScore).First().TransmitData(new List(data)); + + if (!container.IsRerunnable()) + { + module.SetInoperable(); + } + + DumpData(); + } else + ScreenMessages.PostScreenMessage("No transmitters available on this vessel or no data to transmit.", 4f, ScreenMessageStyle.UPPER_LEFT); + + } + + } +} \ No newline at end of file diff --git a/src/kOS/Suffixed/PartModuleField/kOSProcessorFields.cs b/src/kOS/Suffixed/PartModuleField/kOSProcessorFields.cs new file mode 100644 index 000000000..56280ad54 --- /dev/null +++ b/src/kOS/Suffixed/PartModuleField/kOSProcessorFields.cs @@ -0,0 +1,56 @@ +using kOS.Safe.Encapsulation.Suffixes; +using kOS.Module; +using kOS.Safe.Encapsulation; +using kOS.Safe.Persistence; +using kOS.Safe.Module; + +namespace kOS.Suffixed.PartModuleField +{ + [kOS.Safe.Utilities.KOSNomenclature("KOSProcessor")] + public class kOSProcessorFields : PartModuleFields + { + private readonly kOSProcessor processor; + + public kOSProcessorFields(kOSProcessor processor, SharedObjects sharedObj):base(processor, sharedObj) + { + this.processor = processor; + InitializeSuffixes(); + } + + private void InitializeSuffixes() + { + AddSuffix("MODE", new NoArgsSuffix(() => processor.ProcessorMode.ToString(), "This processor's mode")); + AddSuffix("ACTIVATE", new NoArgsVoidSuffix(Activate, "Activate this processor")); + AddSuffix("DEACTIVATE", new NoArgsVoidSuffix(Deactivate, "Deactivate this processor")); + AddSuffix("VOLUME", new NoArgsSuffix(() => processor.HardDisk, "This processor's hard disk")); + AddSuffix("TAG", new NoArgsSuffix(() => processor.Tag, "This processor's tag")); + AddSuffix("BOOTFILENAME", new SetSuffix(GetBootFilename, SetBootFilename, "The name of the processor's boot file.")); + } + + private void Activate() + { + ThrowIfNotCPUVessel(); + + processor.SetMode(ProcessorModes.STARVED); + } + + private void Deactivate() + { + ThrowIfNotCPUVessel(); + + processor.SetMode(ProcessorModes.OFF); + } + + private StringValue GetBootFilename() + { + return processor.BootFilename; + } + + private void SetBootFilename(StringValue name) + { + ThrowIfNotCPUVessel(); + + processor.BootFilename = name; + } + } +} diff --git a/src/kOS/Suffixed/ResourceTransferValue.cs b/src/kOS/Suffixed/ResourceTransferValue.cs index 5781e02b7..3e16a90b8 100644 --- a/src/kOS/Suffixed/ResourceTransferValue.cs +++ b/src/kOS/Suffixed/ResourceTransferValue.cs @@ -10,6 +10,7 @@ namespace kOS.Suffixed { + [kOS.Safe.Utilities.KOSNomenclature("Transfer")] public class ResourceTransferValue : Structure { private const float RESOURCE_SHARE_PER_UPDATE = 0.005f; @@ -74,7 +75,7 @@ public void Update(double deltaTime) { return; } - WorkTransfer(fromParts, toParts); + WorkTransfer(fromParts, toParts, deltaTime); } public override string ToString() @@ -87,12 +88,12 @@ public override string ToString() private void InitializeSuffixes() { - AddSuffix("GOAL", new Suffix(() => amount ?? -1)); - AddSuffix("TRANSFERRED", new Suffix(() => transferredAmount)); - AddSuffix("STATUS", new Suffix(() => Status.ToString())); - AddSuffix("MESSAGE", new Suffix(() => StatusMessage)); - AddSuffix("RESOURCE", new Suffix(() => resourceInfo.name)); - AddSuffix("ACTIVE", new SetSuffix(() => Status == TransferManager.TransferStatus.Transferring, + AddSuffix("GOAL", new Suffix(() => amount ?? -1)); + AddSuffix("TRANSFERRED", new Suffix(() => transferredAmount)); + AddSuffix("STATUS", new Suffix(() => Status.ToString())); + AddSuffix("MESSAGE", new Suffix(() => StatusMessage)); + AddSuffix("RESOURCE", new Suffix(() => resourceInfo.name)); + AddSuffix("ACTIVE", new SetSuffix(() => Status == TransferManager.TransferStatus.Transferring, value => { Status = value ? TransferManager.TransferStatus.Transferring : TransferManager.TransferStatus.Inactive; })); @@ -126,11 +127,11 @@ private TransferPartType DetermineType(object toTest) throw new ArgumentOutOfRangeException("toTest", @"Type: " + toTest.GetType()); } - private void WorkTransfer(IList fromParts, IList toParts) + private void WorkTransfer(IList fromParts, IList toParts, double deltaTime) { var transferGoal = CalculateTransferGoal(toParts); - double pulledAmount = PullResources(fromParts, transferGoal); + double pulledAmount = PullResources(fromParts, transferGoal, deltaTime); PutResources(toParts, pulledAmount); @@ -179,7 +180,7 @@ private void PutResources(IList parts, double pulledAmount) /// All of the donor parts /// the aggregate amount we are seeking to remove from parts /// the amount we were successful at pulling - private double PullResources(IList parts, double transferGoal) + private double PullResources(IList parts, double transferGoal, double deltaTime) { double toReturn = 0.0; var availableResources = CalculateAvailableResource(parts); @@ -192,7 +193,7 @@ private double PullResources(IList parts, double transferGoal) // Throttle the transfer var thisPartsShare = transferGoal*thisPartsPercentage; - var thisPartsRate = resource.maxAmount*RESOURCE_SHARE_PER_UPDATE; + var thisPartsRate = resource.maxAmount*RESOURCE_SHARE_PER_UPDATE*deltaTime/0.02; // The amount you pull must be negative thisPartsShare = -Math.Min(thisPartsShare, thisPartsRate); diff --git a/src/kOS/Suffixed/RgbaColor.cs b/src/kOS/Suffixed/RgbaColor.cs index da4dc050e..c73aca90d 100644 --- a/src/kOS/Suffixed/RgbaColor.cs +++ b/src/kOS/Suffixed/RgbaColor.cs @@ -1,12 +1,12 @@ using kOS.Safe.Encapsulation; using kOS.Safe.Encapsulation.Suffixes; using kOS.Safe.Utilities; -using System; using UnityEngine; using Math = kOS.Safe.Utilities.Math; namespace kOS.Suffixed { + [kOS.Safe.Utilities.KOSNomenclature("RGBA")] public class RgbaColor : Structure { protected float Red { get; set; } @@ -43,11 +43,11 @@ public RgbaColor(RgbaColor copyFrom) private void InitializeSuffixColor() { - AddSuffix(new[] { "R", "RED" }, new ClampSetSuffix(() => Red, value => { Red = value; Recalculate(); }, 0, 255)); - AddSuffix(new[] { "G", "GREEN" }, new ClampSetSuffix(() => Green, value => { Green = value; Recalculate(); }, 0, 255)); - AddSuffix(new[] { "B", "BLUE" }, new ClampSetSuffix(() => Blue, value => { Blue = value; Recalculate(); }, 0, 255)); - AddSuffix(new[] { "A", "ALPHA" }, new ClampSetSuffix(() => Alpha, value => { Alpha = value; Recalculate(); }, 0, 1)); - AddSuffix(new[] { "HTML", "HEX" }, new NoArgsSuffix(ToHexNotation, "Returns a string representing the color in HTML, i.e. \"#ff0000\". Ignores transparency (alpha) information.")); + AddSuffix(new[] { "R", "RED" }, new ClampSetSuffix(() => Red, value => { Red = value; Recalculate(); }, 0, 255)); + AddSuffix(new[] { "G", "GREEN" }, new ClampSetSuffix(() => Green, value => { Green = value; Recalculate(); }, 0, 255)); + AddSuffix(new[] { "B", "BLUE" }, new ClampSetSuffix(() => Blue, value => { Blue = value; Recalculate(); }, 0, 255)); + AddSuffix(new[] { "A", "ALPHA" }, new ClampSetSuffix(() => Alpha, value => { Alpha = value; Recalculate(); }, 0, 1)); + AddSuffix(new[] { "HTML", "HEX" }, new NoArgsSuffix(ToHexNotation, "Returns a string representing the color in HTML, i.e. \"#ff0000\". Ignores transparency (alpha) information.")); } protected virtual void Recalculate() @@ -78,12 +78,12 @@ public override string ToString() /// got accepted as standard and remain special proprietary extensions. /// /// A color in hexadecimal notation - public string ToHexNotation() + public StringValue ToHexNotation() { - var redByte = (byte)(Mathf.Min(255, (int)(Red * 255f))); - var greenByte = (byte)(Mathf.Min(255, (int)(Green * 255f))); - var blueByte = (byte)(Mathf.Min(255, (int)(Blue * 255f))); - return String.Format("#{0:x2}{1:x2}{2:x2}", redByte, greenByte, blueByte); + var redByte = (byte)Mathf.Min(255, (int)(Red * 255f)); + var greenByte = (byte)Mathf.Min(255, (int)(Green * 255f)); + var blueByte = (byte)Mathf.Min(255, (int)(Blue * 255f)); + return string.Format("#{0:x2}{1:x2}{2:x2}", redByte, greenByte, blueByte); } } } \ No newline at end of file diff --git a/src/kOS/Suffixed/ScienceDataValue.cs b/src/kOS/Suffixed/ScienceDataValue.cs new file mode 100644 index 000000000..19e315705 --- /dev/null +++ b/src/kOS/Suffixed/ScienceDataValue.cs @@ -0,0 +1,49 @@ +using System; +using kOS.Safe.Encapsulation; +using kOS.Safe.Encapsulation.Suffixes; + +namespace kOS.Suffixed +{ + [kOS.Safe.Utilities.KOSNomenclature("ScienceData")] + public class ScienceDataValue : Structure + { + private ScienceData scienceData; + + public ScienceDataValue(ScienceData scienceData) + { + this.scienceData = scienceData; + + InitializeSuffixes(); + } + + private void InitializeSuffixes() + { + AddSuffix("DATAAMOUNT", new NoArgsSuffix(() => scienceData.dataAmount)); + AddSuffix("SCIENCEVALUE", new NoArgsSuffix(() => ScienceValue())); + AddSuffix("TRANSMITVALUE", new NoArgsSuffix(() => TransmitValue())); + AddSuffix("TITLE", new NoArgsSuffix(() => scienceData.title)); + } + + public float ScienceValue() + { + ScienceSubject subjectByID = ResearchAndDevelopment.GetSubjectByID(scienceData.subjectID); + + return ResearchAndDevelopment.GetScienceValue(scienceData.dataAmount, subjectByID, 1) * + HighLogic.CurrentGame.Parameters.Career.ScienceGainMultiplier; + } + + public float TransmitValue() + { + ScienceSubject subjectByID = ResearchAndDevelopment.GetSubjectByID(scienceData.subjectID); + + return ResearchAndDevelopment.GetScienceValue(scienceData.dataAmount, subjectByID, scienceData.transmitValue) * + HighLogic.CurrentGame.Parameters.Career.ScienceGainMultiplier; + } + + public new string ToString() + { + return "SCIENCE DATA"; + } + } +} + diff --git a/src/kOS/Suffixed/SingleResourceValue.cs b/src/kOS/Suffixed/SingleResourceValue.cs index 5dc592206..be6d504b8 100644 --- a/src/kOS/Suffixed/SingleResourceValue.cs +++ b/src/kOS/Suffixed/SingleResourceValue.cs @@ -1,9 +1,9 @@ using kOS.Safe.Encapsulation; using kOS.Safe.Encapsulation.Suffixes; -using kOS.Suffixed.Part; namespace kOS.Suffixed { + [kOS.Safe.Utilities.KOSNomenclature("Resource")] public class SingleResourceValue : Structure { private readonly PartResource partResource; @@ -16,12 +16,12 @@ public SingleResourceValue(PartResource partResource) private void InitializeSuffixes() { - AddSuffix("NAME", new Suffix(() => partResource.resourceName)); - AddSuffix("AMOUNT", new Suffix(() => partResource.amount)); - AddSuffix("DENSITY", new Suffix(() => partResource.info.density)); - AddSuffix("CAPACITY", new Suffix(() => partResource.maxAmount)); - AddSuffix("TOGGLEABLE", new Suffix(() => partResource.isTweakable)); - AddSuffix("ENABLED", new SetSuffix(() => partResource.flowState, value => + AddSuffix("NAME", new Suffix(() => partResource.resourceName)); + AddSuffix("AMOUNT", new Suffix(() => partResource.amount)); + AddSuffix("DENSITY", new Suffix(() => partResource.info.density)); + AddSuffix("CAPACITY", new Suffix(() => partResource.maxAmount)); + AddSuffix("TOGGLEABLE", new Suffix(() => partResource.isTweakable)); + AddSuffix("ENABLED", new SetSuffix(() => partResource.flowState, value => { if (partResource.isTweakable) { @@ -32,7 +32,7 @@ private void InitializeSuffixes() public override string ToString() { - return string.Format("RESOURCE({0},{1},{2}", partResource.resourceName, partResource.amount, partResource.maxAmount); + return string.Format("RESOURCE({0},{1},{2})", partResource.resourceName, partResource.amount, partResource.maxAmount); } } } \ No newline at end of file diff --git a/src/kOS/Suffixed/StageValues.cs b/src/kOS/Suffixed/StageValues.cs index 48f817833..4291fe336 100644 --- a/src/kOS/Suffixed/StageValues.cs +++ b/src/kOS/Suffixed/StageValues.cs @@ -1,10 +1,14 @@ -using System; -using System.Linq; -using kOS.Safe.Encapsulation; +using kOS.Safe.Encapsulation; using kOS.Safe.Encapsulation.Suffixes; +using kOS.Safe.Exceptions; +using kOS.Utilities; +using System; +using System.Collections.Generic; +using System.Linq; namespace kOS.Suffixed { + [kOS.Safe.Utilities.KOSNomenclature("Stage")] public class StageValues : Structure { private readonly SharedObjects shared; @@ -18,10 +22,10 @@ public StageValues(SharedObjects shared) private void InitializeSuffixes() { - AddSuffix("NUMBER", new Suffix(() => Staging.CurrentStage)); - AddSuffix("READY", new Suffix(() => shared.Vessel.isActiveVessel && Staging.separate_ready)); + AddSuffix("NUMBER", new Suffix(() => Staging.CurrentStage)); + AddSuffix("READY", new Suffix(() => shared.Vessel.isActiveVessel && Staging.separate_ready)); AddSuffix("RESOURCES", new Suffix>(GetResourceManifest)); - + AddSuffix("RESOURCESLEX", new Suffix(GetResourceDictionary)); } private ListValue GetResourceManifest() @@ -37,7 +41,20 @@ private ListValue GetResourceManifest() return toReturn; } - public override object GetSuffix(string suffixName) + private Lexicon GetResourceDictionary() + { + var resources = shared.Vessel.GetActiveResources(); + var toReturn = new Lexicon(); + + foreach (var resource in resources) + { + toReturn.Add(new StringValue(resource.info.name), new ActiveResourceValue(resource, shared)); + } + + return toReturn; + } + + public override ISuffixResult GetSuffix(string suffixName) { if (!IsResource(suffixName)) { @@ -45,7 +62,7 @@ public override object GetSuffix(string suffixName) } var resourceAmount = GetResourceOfCurrentStage(suffixName); - return resourceAmount.HasValue ? resourceAmount.Value : 0.0; + return new SuffixResult(ScalarValue.Create(resourceAmount.HasValue ? resourceAmount.Value : 0.0)); } private bool IsResource(string suffixName) @@ -56,9 +73,38 @@ private bool IsResource(string suffixName) private double? GetResourceOfCurrentStage(string resourceName) { - var resource = shared.Vessel.GetActiveResources(); - var match = resource.FirstOrDefault(r => string.Equals(r.info.name, resourceName, StringComparison.InvariantCultureIgnoreCase)); - return match == null ? null : (double?) Math.Round(match.amount, 2); + PartResourceDefinition resourceDef = PartResourceLibrary.Instance.resourceDefinitions.FirstOrDefault(pr => string.Equals(pr.name, resourceName, StringComparison.CurrentCultureIgnoreCase)); + + if (resourceDef == null) + { + throw new KOSInvalidArgumentException("STAGE", resourceName, "The resource definition could not be found"); + } + + var list = new List(); + if (resourceDef.resourceFlowMode == ResourceFlowMode.STACK_PRIORITY_SEARCH) + { + var engines = VesselUtils.GetListOfActivatedEngines(shared.Vessel); + foreach (var engine in engines) + { + engine.GetConnectedResources(resourceDef.id, resourceDef.resourceFlowMode, list); + } + } + else if (resourceDef.resourceFlowMode == ResourceFlowMode.NO_FLOW) { + var engines = VesselUtils.GetListOfActivatedEngines(shared.Vessel); + foreach (var engine in engines) + { + list.AddRange(engine.Resources.GetAll(resourceDef.id)); + } + } + else + { + shared.Vessel.rootPart.GetConnectedResources(resourceDef.id, resourceDef.resourceFlowMode, list); + } + if (list.Count == 0) + { + return 0; + } + return Math.Round(list.GroupBy(e => e.part.flightID).Select(e => e.FirstOrDefault()).Sum(e => e.amount), 2); } public override string ToString() diff --git a/src/kOS/Suffixed/Timespan.cs b/src/kOS/Suffixed/Timespan.cs index 2cb01a23e..e4bdaed88 100644 --- a/src/kOS/Suffixed/Timespan.cs +++ b/src/kOS/Suffixed/Timespan.cs @@ -1,16 +1,23 @@ using System; using kOS.Safe.Encapsulation; using kOS.Safe.Encapsulation.Suffixes; +using kOS.Safe.Serialization; +using System.Collections.Generic; +using kOS.Safe; namespace kOS.Suffixed { - public class TimeSpan : Structure + [kOS.Safe.Utilities.KOSNomenclature("Timespan")] + public class TimeSpan : SerializableStructure, IComparable { - readonly double span; - private readonly bool kerbinTimeSetting; + public const string DumpSpan = "span"; + + double span; private const int DAYS_IN_YEAR = 365; - private const int HOURS_IN_KERBIN_DAY = 6; - private const int HOURS_IN_EARTH_DAY = 24; + + public const int HOURS_IN_EARTH_DAY = 24; + public const int HOURS_IN_KERBIN_DAY = 6; + private const int MINUTE_IN_HOUR = 60; private const int SECONDS_IN_MINUTE = 60; @@ -21,54 +28,57 @@ public class TimeSpan : Structure private const int SECONDS_IN_EARTH_DAY = SECONDS_IN_EARTH_HOUR * HOURS_IN_EARTH_DAY; private const int SECONDS_IN_EARTH_YEAR = SECONDS_IN_EARTH_DAY * DAYS_IN_YEAR; - public TimeSpan(double unixStyleTime) + public TimeSpan() { - span = unixStyleTime; - kerbinTimeSetting = GameSettings.KERBIN_TIME; InitializeSuffixes(); } + public TimeSpan(double unixStyleTime) : this() + { + span = unixStyleTime; + } + private void InitializeSuffixes() { - AddSuffix("YEAR", new Suffix(CalculateYear)); - AddSuffix("DAY", new Suffix(CalculateDay)); - AddSuffix("HOUR", new Suffix(CalculateHour)); - AddSuffix("MINUTE", new Suffix(CalculateMinute)); - AddSuffix("SECOND", new Suffix(CalculateSecond)); - AddSuffix("SECONDS", new Suffix(() => span)); - AddSuffix("CLOCK", new Suffix(() => string.Format("{0:00}:{1:00}:{2:00}", CalculateHour(), CalculateMinute(), CalculateSecond()))); - AddSuffix("CALENDAR", new Suffix(() => "Year " + CalculateYear() + ", day " + CalculateDay())); + AddSuffix("YEAR", new Suffix(CalculateYear)); + AddSuffix("DAY", new Suffix(CalculateDay)); + AddSuffix("HOUR", new Suffix(CalculateHour)); + AddSuffix("MINUTE", new Suffix(CalculateMinute)); + AddSuffix("SECOND", new Suffix(CalculateSecond)); + AddSuffix("SECONDS", new Suffix(() => span)); + AddSuffix("CLOCK", new Suffix(() => string.Format("{0:00}:{1:00}:{2:00}", CalculateHour(), CalculateMinute(), CalculateSecond()))); + AddSuffix("CALENDAR", new Suffix(() => "Year " + CalculateYear() + ", day " + CalculateDay())); } - private int CalculateYear() + private ScalarValue CalculateYear() { - if (kerbinTimeSetting) + if (GameSettings.KERBIN_TIME) { return (int)Math.Floor(span / SECONDS_IN_KERBIN_YEAR) + 1; } return (int)Math.Floor(span / SECONDS_IN_EARTH_YEAR) + 1; } - private int SecondsPerDay { get { return kerbinTimeSetting ? SECONDS_IN_KERBIN_DAY : SECONDS_IN_EARTH_DAY; } } - private int SecondsPerHour { get { return kerbinTimeSetting ? SECONDS_IN_KERBIN_HOUR : SECONDS_IN_EARTH_HOUR; } } - private int SecongsPerYear { get { return kerbinTimeSetting ? SECONDS_IN_KERBIN_YEAR : SECONDS_IN_EARTH_YEAR; } } + private int SecondsPerDay { get { return GameSettings.KERBIN_TIME ? SECONDS_IN_KERBIN_DAY : SECONDS_IN_EARTH_DAY; } } + private int SecondsPerHour { get { return GameSettings.KERBIN_TIME ? SECONDS_IN_KERBIN_HOUR : SECONDS_IN_EARTH_HOUR; } } + private int SecongsPerYear { get { return GameSettings.KERBIN_TIME ? SECONDS_IN_KERBIN_YEAR : SECONDS_IN_EARTH_YEAR; } } - private int CalculateDay() + private ScalarValue CalculateDay() { - return (int)Math.Floor((span % SecongsPerYear) / SecondsPerDay) + 1; + return (int)Math.Floor(span % SecongsPerYear / SecondsPerDay) + 1; } - private int CalculateHour() + private ScalarValue CalculateHour() { - return (int)Math.Floor((span % SecondsPerDay) / SecondsPerHour); + return (int)Math.Floor(span % SecondsPerDay / SecondsPerHour); } - private int CalculateMinute() + private ScalarValue CalculateMinute() { - return (int)Math.Floor((span % SecondsPerHour) / SECONDS_IN_MINUTE); + return (int)Math.Floor(span % SecondsPerHour / SECONDS_IN_MINUTE); } - private double CalculateSecond() + private ScalarValue CalculateSecond() { return span%SECONDS_IN_MINUTE; } @@ -101,6 +111,23 @@ public double ToUnixStyleTime() public static bool operator >=(double a, TimeSpan b) { return a >= b.ToUnixStyleTime(); } public static bool operator <=(double a, TimeSpan b) { return a <= b.ToUnixStyleTime(); } + public static TimeSpan operator +(TimeSpan a, ScalarValue b) { return new TimeSpan(a.ToUnixStyleTime() + b); } + public static TimeSpan operator -(TimeSpan a, ScalarValue b) { return new TimeSpan(a.ToUnixStyleTime() - b); } + public static TimeSpan operator *(TimeSpan a, ScalarValue b) { return new TimeSpan(a.ToUnixStyleTime() * b); } + public static TimeSpan operator /(TimeSpan a, ScalarValue b) { return new TimeSpan(a.ToUnixStyleTime() / b); } + public static TimeSpan operator +(ScalarValue b, TimeSpan a) { return new TimeSpan(b + a.ToUnixStyleTime()); } + public static TimeSpan operator -(ScalarValue b, TimeSpan a) { return new TimeSpan(b - a.ToUnixStyleTime()); } + public static TimeSpan operator *(ScalarValue b, TimeSpan a) { return new TimeSpan(b * a.ToUnixStyleTime()); } + public static TimeSpan operator /(ScalarValue b, TimeSpan a) { return new TimeSpan(b / a.ToUnixStyleTime()); } + public static bool operator >(TimeSpan a, ScalarValue b) { return a.ToUnixStyleTime() > b; } + public static bool operator <(TimeSpan a, ScalarValue b) { return a.ToUnixStyleTime() < b; } + public static bool operator >=(TimeSpan a, ScalarValue b) { return a.ToUnixStyleTime() >= b; } + public static bool operator <=(TimeSpan a, ScalarValue b) { return a.ToUnixStyleTime() <= b; } + public static bool operator >(ScalarValue a, TimeSpan b) { return a > b.ToUnixStyleTime(); } + public static bool operator <(ScalarValue a, TimeSpan b) { return a < b.ToUnixStyleTime(); } + public static bool operator >=(ScalarValue a, TimeSpan b) { return a >= b.ToUnixStyleTime(); } + public static bool operator <=(ScalarValue a, TimeSpan b) { return a <= b.ToUnixStyleTime(); } + public override object TryOperation(string op, object other, bool reverseOrder) { other = ConvertToDoubleIfNeeded(other); @@ -149,5 +176,25 @@ public override string ToString() { return string.Format("TIME({0:0})", span); } + + public override Dump Dump() + { + var dump = new Dump + { + {DumpSpan, span} + }; + + return dump; + } + + public override void LoadDump(Dump dump) + { + span = Convert.ToDouble(dump[DumpSpan]); + } + + public int CompareTo(TimeSpan other) + { + return span.CompareTo(other.span); + } } } diff --git a/src/kOS/Suffixed/Vector.cs b/src/kOS/Suffixed/Vector.cs index 1a238c936..86e47040c 100644 --- a/src/kOS/Suffixed/Vector.cs +++ b/src/kOS/Suffixed/Vector.cs @@ -1,66 +1,96 @@ -using System; -using kOS.Safe.Encapsulation; +using kOS.Safe.Encapsulation; using kOS.Safe.Encapsulation.Suffixes; +using System; using UnityEngine; +using kOS.Safe.Serialization; +using System.Collections.Generic; +using kOS.Safe.Utilities; +using kOS.Safe; namespace kOS.Suffixed { - public class Vector : Structure + [kOS.Safe.Utilities.KOSNomenclature("Vector")] + public class Vector : SerializableStructure { + public const string DumpX = "x"; + public const string DumpY = "y"; + public const string DumpZ = "z"; + public double X { get; set; } + public double Y { get; set; } + public double Z { get; set; } - public Vector(Vector3d init) :this(init.x,init.y,init.z) { } - public Vector(Vector3 init) :this(init.x, init.y, init.z) { } - public Vector(float x, float y, float z) : this((double)x,(double)y,(double)z) { } + public Vector() + { + InitializeSuffixes(); + } - public Vector(double x, double y, double z) + public Vector(Vector3d init) + : this(init.x, init.y, init.z) + { + } + + public Vector(Vector3 init) + : this(init.x, init.y, init.z) + { + } + + public Vector(float x, float y, float z) + : this((double)x, (double)y, (double)z) + { + } + + public Vector(double x, double y, double z) : this() { X = x; Y = y; Z = z; - InitializeSuffixes(); } private void InitializeSuffixes() { - AddSuffix("X", new SetSuffix(() => X, value => X = value)); - AddSuffix("Y", new SetSuffix(() => Y, value => Y = value)); - AddSuffix("Z", new SetSuffix(() => Z, value => Z = value)); - AddSuffix("MAG", new SetSuffix(Magnitude, value => + AddSuffix("X", new SetSuffix(() => X, value => X = value)); + AddSuffix("Y", new SetSuffix(() => Y, value => Y = value)); + AddSuffix("Z", new SetSuffix(() => Z, value => Z = value)); + AddSuffix("MAG", new SetSuffix(Magnitude, value => { - double oldMag = new Vector3d(X, Y, Z).magnitude; + double oldMag = new Vector3d(X, Y, Z).magnitude; - if (oldMag == 0) return; // Avoid division by zero + if (oldMag == 0) return; // Avoid division by zero - X = X/oldMag*value; - Y = Y/oldMag*value; - Z = Z/oldMag*value; + X = X / oldMag * value; + Y = Y / oldMag * value; + Z = Z / oldMag * value; })); - AddSuffix("VEC", new Suffix(() => new Vector(X,Y,Z))); + AddSuffix("VEC", new Suffix(() => new Vector(X, Y, Z))); AddSuffix("NORMALIZED", new Suffix(Normalized)); - AddSuffix("SQRMAGNITUDE", new Suffix(() => new Vector3d(X,Y,Z).sqrMagnitude)); + AddSuffix("SQRMAGNITUDE", new Suffix(() => new Vector3d(X, Y, Z).sqrMagnitude)); AddSuffix("DIRECTION", new SetSuffix(ToDirection, value => { - Vector3d newVal = value.Rotation * Vector3d.forward; - X = newVal.x; - Y = newVal.y; - Z = newVal.z; + var newMagnitude = Vector3d.forward * new Vector3d(X, Y, Z).magnitude; + + var newVector = value.Rotation * newMagnitude; + + X = newVector.x; + Y = newVector.y; + Z = newVector.z; })); } - public override object TryOperation(string op, object other, bool reverseOrder) { other = ConvertToDoubleIfNeeded(other); + other = Structure.ToPrimitive(other); switch (op) { case "*": - if (other is Vector) return this*(Vector) other; - if (other is double) return this*(double) other; + if (other is Vector) return this * (Vector)other; + if (other is double) return this * (double)other; break; + case "/": if (!reverseOrder) { @@ -72,36 +102,38 @@ public override object TryOperation(string op, object other, bool reverseOrder) throw new NotImplementedException("Cannot divide by a vector."); } break; + case "+": - if (other is Vector) return this + (Vector) other; + if (other is Vector) return this + (Vector)other; break; + case "-": if (!reverseOrder) { - if (other is Vector) return this - (Vector) other; + if (other is Vector) return this - (Vector)other; } else { - if (other is Vector) return (Vector) other - this; + if (other is Vector) return (Vector)other - this; } break; - + default: throw new NotImplementedException(string.Format( - "Cannot perform operation: {0} {1} {2}", this, op, other ) ); + "Cannot perform operation: {0} {1} {2}", this, op, other)); } return null; } - - public double Magnitude() + + public ScalarValue Magnitude() { - return new Vector3d(X,Y,Z).magnitude; + return new Vector3d(X, Y, Z).magnitude; } - + public Vector Normalized() { - return new Vector( new Vector3d(X,Y,Z).normalized ); + return new Vector(new Vector3d(X, Y, Z).normalized); } public Direction ToDirection() @@ -111,7 +143,7 @@ public Direction ToDirection() public static Vector Zero { - get { return new Vector(Vector3d.zero);} + get { return new Vector(Vector3d.zero); } } public Vector3d ToVector3D() @@ -146,12 +178,37 @@ public static explicit operator Direction(Vector d) public static Vector operator *(Vector a, float b) { - return new Vector(a.X*b, a.Y*b, a.Z*b); + return new Vector(a.X * b, a.Y * b, a.Z * b); } public static Vector operator *(Vector a, double b) { - return new Vector(a.X*b, a.Y*b, a.Z*b); + return new Vector(a.X * b, a.Y * b, a.Z * b); + } + + public static Vector operator *(Vector a, ScalarValue b) + { + return a * b.GetDoubleValue(); + } + + public static Vector operator *(float b, Vector a) + { + return new Vector(a.X * b, a.Y * b, a.Z * b); + } + + public static Vector operator *(double b, Vector a) + { + return new Vector(a.X * b, a.Y * b, a.Z * b); + } + + public static Vector operator *(ScalarValue b, Vector a) + { + return a * b.GetDoubleValue(); + } + + public static Vector operator /(Vector a, ScalarValue b) + { + return new Vector(a.X / b, a.Y / b, a.Z / b); } public static Vector operator +(Vector a, Vector b) @@ -163,9 +220,28 @@ public static explicit operator Direction(Vector d) { return new Vector(a.ToVector3D() - b.ToVector3D()); } + public static Vector operator -(Vector a) { - return a*(-1); + return a * (-1d); + } + + public override Dump Dump() + { + DumpWithHeader dump = new DumpWithHeader(); + + dump.Add(DumpX, X); + dump.Add(DumpY, Y); + dump.Add(DumpZ, Z); + + return dump; + } + + public override void LoadDump(Dump dump) + { + X = Convert.ToDouble(dump[DumpX]); + Y = Convert.ToDouble(dump[DumpY]); + Z = Convert.ToDouble(dump[DumpZ]); } } -} +} \ No newline at end of file diff --git a/src/kOS/Suffixed/VectorRenderer.cs b/src/kOS/Suffixed/VectorRenderer.cs index 6a955485b..f63a51b30 100644 --- a/src/kOS/Suffixed/VectorRenderer.cs +++ b/src/kOS/Suffixed/VectorRenderer.cs @@ -1,32 +1,34 @@ -using System; +using kOS.Safe; +using kOS.Safe.Encapsulation; using kOS.Safe.Encapsulation.Suffixes; +using kOS.Safe.Execution; using kOS.Utilities; +using System; +using System.Collections.Generic; using UnityEngine; -using kOS.Safe; -using kOS.Safe.Encapsulation; -using kOS.Safe.Execution; namespace kOS.Suffixed { + [kOS.Safe.Utilities.KOSNomenclature("Vecdraw")] public class VectorRenderer : Structure, IUpdateObserver, IKOSScopeObserver { - public Vector3d Vector { get; set; } - public RgbaColor Color { get; set; } - public Vector3d Start { get; set; } - public double Scale { get; set; } - public double Width { get; set; } - - private LineRenderer line; - private LineRenderer hat; - private bool enable; + public Vector3d Vector { get; set; } + public RgbaColor Color { get; set; } + public Vector3d Start { get; set; } + public double Scale { get; set; } + public double Width { get; set; } + + private LineRenderer line; + private LineRenderer hat; + private bool enable; private readonly UpdateHandler updateHandler; private readonly SharedObjects shared; - private GameObject lineObj; - private GameObject hatObj; - private GameObject labelObj; - private GUIText label; - private string labelStr = ""; - private Vector3 labelLocation; + private GameObject lineObj; + private GameObject hatObj; + private GameObject labelObj; + private GUIText label; + private string labelStr = ""; + private Vector3 labelLocation; // These could probably be moved somewhere where they are updated // more globally just once per Update() rather than once per @@ -35,25 +37,26 @@ public class VectorRenderer : Structure, IUpdateObserver, IKOSScopeObserver // it might be worth the work to move these, and their associated // updater methods, to a new class with one global instance for the whole // mod. Until then it's not that much of an extra cost: - private Vector3 shipCenterCoords; - private Vector3 camPos; // camera coordinates. - private Vector3 camLookVec; // vector from camera to ship position. - private Vector3 prevCamLookVec; - private Quaternion camRot; - private Quaternion prevCamRot; - private bool isOnMap; // true = Map view, false = Flight view. - private bool prevIsOnMap; - private const int MAP_LAYER = 10; // found through trial-and-error - private const int FLIGHT_LAYER = 0; // found through trial-and-error - - public VectorRenderer( UpdateHandler updateHand, SharedObjects shared ) + private Vector3 shipCenterCoords; + + private Vector3 camPos; // camera coordinates. + private Vector3 camLookVec; // vector from camera to ship position. + private Vector3 prevCamLookVec; + private Quaternion camRot; + private Quaternion prevCamRot; + private bool isOnMap; // true = Map view, false = Flight view. + private bool prevIsOnMap; + private const int MAP_LAYER = 10; // found through trial-and-error + private const int FLIGHT_LAYER = 15; // Supposedly the layer for UI effects in flight camera. + + public VectorRenderer(UpdateHandler updateHand, SharedObjects shared) { - Vector = new Vector3d(0,0,0); - Color = new RgbaColor(1,1,1); - Start = new Vector3d(0,0,0); - Scale = 1.0; - Width = 0; - + Vector = new Vector3d(0, 0, 0); + Color = new RgbaColor(1, 1, 1); + Start = new Vector3d(0, 0, 0); + Scale = 1.0; + Width = 0; + updateHandler = updateHand; this.shared = shared; InitializeSuffixes(); @@ -62,6 +65,7 @@ public VectorRenderer( UpdateHandler updateHand, SharedObjects shared ) // Implementation of KOSSCopeObserver interface: // --------------------------------------------- public int LinkCount { get; set; } + public void ScopeLost() { // When no kos script variables can still access me, @@ -73,14 +77,28 @@ public void ScopeLost() SetShow(false); } - + /// Make all vector renderers invisible everywhere in the kOS module. + static public void ClearAll(UpdateHandler handler) + { + // Take a copy of the list because the items will be deleted from the update handler + // as SetShow() gets called, and .NET won't let you iterate over the collection + // directly while you do that: + List allOfMe = new List(); + foreach (VectorRenderer item in handler.GetAllUpdatersOfType(typeof(VectorRenderer))) + allOfMe.Add(item); + + // Now actually turn them all off: + foreach (VectorRenderer vecRend in allOfMe) + vecRend.SetShow(false); + } + /// /// Move the origin point of the vector drawings to move with the /// current ship, whichever ship that happens to be at the moment, /// and move to wherever that ship is within its local XYZ world (which /// isn't always at (0,0,0), as it turns out.): /// - public void KOSUpdate( double deltaTime ) + public void KOSUpdate(double deltaTime) { if (line == null || hat == null) return; if (!enable) return; @@ -92,8 +110,8 @@ public void KOSUpdate( double deltaTime ) SetLayer(isOnMap ? MAP_LAYER : FLIGHT_LAYER); var mapChange = isOnMap != prevIsOnMap; - var magnitudeChange = prevCamLookVec.magnitude != camLookVec.magnitude; - if ( mapChange || magnitudeChange ) + var magnitudeChange = prevCamLookVec.magnitude != camLookVec.magnitude; + if (mapChange || magnitudeChange) { RenderPointCoords(); LabelPlacement(); @@ -106,30 +124,30 @@ public void KOSUpdate( double deltaTime ) private void InitializeSuffixes() { - AddSuffix(new[]{"VEC", "VECTOR"}, new SetSuffix(() => new Vector(Vector), value => - { - Vector = value; - RenderPointCoords(); - })); - AddSuffix(new[]{"COLOR", "COLOUR"}, new SetSuffix(() => Color, value => - { - Color = value; - RenderColor(); - })); - AddSuffix("SHOW", new SetSuffix(() => enable, SetShow)); + AddSuffix(new[] { "VEC", "VECTOR" }, new SetSuffix(() => new Vector(Vector), value => + { + Vector = value; + RenderPointCoords(); + })); + AddSuffix(new[] { "COLOR", "COLOUR" }, new SetSuffix(() => Color, value => + { + Color = value; + RenderColor(); + })); + AddSuffix("SHOW", new SetSuffix(() => enable, SetShow)); AddSuffix("START", new SetSuffix(() => new Vector(Start), value => { Start = value; RenderPointCoords(); })); - AddSuffix("SCALE", new SetSuffix(() => Scale, value => + AddSuffix("SCALE", new SetSuffix(() => Scale, value => { Scale = value; RenderPointCoords(); })); - AddSuffix("LABEL", new SetSuffix(() => labelStr,SetLabel)); - AddSuffix("WIDTH", new SetSuffix(() => Width, value => + AddSuffix("LABEL", new SetSuffix(() => labelStr, SetLabel)); + AddSuffix("WIDTH", new SetSuffix(() => Width, value => { Width = value; RenderPointCoords(); @@ -144,22 +162,21 @@ private void GetShipCenterCoords() { if (isOnMap) shipCenterCoords = ScaledSpace.LocalToScaledSpace( - shared.Vessel.findWorldCenterOfMass() ); + shared.Vessel.findWorldCenterOfMass()); else shipCenterCoords = shared.Vessel.findWorldCenterOfMass(); } - + /// /// Update camera data, abstracting the different ways KSP does it /// depending on view mode: /// private void GetCamData() { - - prevIsOnMap = isOnMap; + prevIsOnMap = isOnMap; prevCamLookVec = camLookVec; - prevCamRot = camRot; - + prevCamRot = camRot; + isOnMap = MapView.MapIsEnabled; var cam = Utils.GetCurrentCamera(); @@ -173,7 +190,7 @@ private void GetCamData() camLookVec = camPos - shipCenterCoords; } - + /// /// Get the position in screen coordinates that the 3d world coordinates /// project onto, abstracting the two different ways KSP has to access @@ -182,10 +199,10 @@ private void GetCamData() /// (0,0) to (1,1) and the Z coord is how far from the screen it is /// (-Z means behind you). /// - private Vector3 GetViewportPosFor( Vector3 v ) + private Vector3 GetViewportPosFor(Vector3 v) { var cam = Utils.GetCurrentCamera(); - return cam.WorldToViewportPoint( v ); + return cam.WorldToViewportPoint(v); } /// @@ -194,57 +211,56 @@ private Vector3 GetViewportPosFor( Vector3 v ) /// private void PutAtShipRelativeCoords() { - line.transform.localPosition = shipCenterCoords; - hat.transform.localPosition = shipCenterCoords; + line.transform.localPosition = shipCenterCoords; + hat.transform.localPosition = shipCenterCoords; } - + public bool GetShow() { return enable; } - - public void SetShow( bool newShowVal ) + + public void SetShow(BooleanValue newShowVal) { if (newShowVal) { - if (line == null || hat == null ) + if (line == null || hat == null) { - lineObj = new GameObject("vecdrawLine"); - hatObj = new GameObject("vecdrawHat"); - labelObj = new GameObject("vecdrawLabel", typeof(GUIText) ); + lineObj = new GameObject("vecdrawLine"); + hatObj = new GameObject("vecdrawHat"); + labelObj = new GameObject("vecdrawLabel", typeof(GUIText)); - line = lineObj.AddComponent(); - hat = hatObj.AddComponent(); + line = lineObj.AddComponent(); + hat = hatObj.AddComponent(); label = labelObj.guiText; - line.useWorldSpace = false; - hat.useWorldSpace = false; + line.useWorldSpace = false; + hat.useWorldSpace = false; GetShipCenterCoords(); - line.material = new Material(Shader.Find("Particles/Additive")); - hat.material = new Material(Shader.Find("Particles/Additive")); + line.material = new Material(Shader.Find("Particles/Additive")); + hat.material = new Material(Shader.Find("Particles/Additive")); // This is how font loading would work if other fonts were available in KSP: // Font lblFont = (Font)Resources.Load( "Arial", typeof(Font) ); // SafeHouse.Logger.Log( "lblFont is " + (lblFont == null ? "null" : "not null") ); // _label.font = lblFont; - - label.fontSize = 12; + label.text = labelStr; label.anchor = TextAnchor.MiddleCenter; PutAtShipRelativeCoords(); RenderValues(); } - updateHandler.AddObserver( this ); - line.enabled = true; - hat.enabled = true; + updateHandler.AddObserver(this); + line.enabled = true; + hat.enabled = true; label.enabled = true; } else { - updateHandler.RemoveObserver( this ); + updateHandler.RemoveObserver(this); if (label != null) { label.enabled = false; @@ -252,35 +268,36 @@ public void SetShow( bool newShowVal ) } if (hat != null) { - hat.enabled = false; + hat.enabled = false; hat = null; } if (line != null) { - line.enabled = false; + line.enabled = false; line = null; } labelObj = null; - hatObj = null; - lineObj = null; + hatObj = null; + lineObj = null; } enable = newShowVal; } - public void SetLayer( int newVal ) + public void SetLayer(int newVal) { - if (lineObj != null) lineObj.layer = newVal; - if (hatObj != null) hatObj.layer = newVal; + if (lineObj != null) lineObj.layer = newVal; + if (hatObj != null) hatObj.layer = newVal; if (labelObj != null) labelObj.layer = newVal; } - - public void SetLabel( string newVal ) + + public void SetLabel(StringValue newVal) { labelStr = newVal; if (label != null) label.text = labelStr; + RenderPointCoords(); } - + public void RenderValues() { RenderPointCoords(); @@ -297,49 +314,42 @@ public void RenderValues() /// public void RenderPointCoords() { - if (line != null && hat != null) { double mapLengthMult = 1.0; // for scaling when on map view. - double mapWidthMult = 1.0; // for scaling when on map view. + double mapWidthMult = 1.0; // for scaling when on map view. float useWidth; if (isOnMap) { mapLengthMult = ScaledSpace.InverseScaleFactor; - mapWidthMult = Math.Max( camLookVec.magnitude, 100.0f ) / 100.0f; - } - - Vector3d point1 = mapLengthMult * Scale * Start; - Vector3d point2 = mapLengthMult * Scale * (Start+0.95*Vector); - Vector3d point3 = mapLengthMult * Scale * (Start+Vector); - - if (Width <= 0) // User didn't pick a valid width. Use dynamic calculation. - { - useWidth = (float) (0.2*mapWidthMult); - } - else // User did pick a width to override the dynamic calculations. - { - useWidth = (float)Width; + mapWidthMult = Math.Max(camLookVec.magnitude, 100.0f) / 100.0f; } + Vector3d point1 = mapLengthMult * Start; + Vector3d point2 = mapLengthMult * (Start + (Scale * 0.95 * Vector)); + Vector3d point3 = mapLengthMult * (Start + (Scale * Vector)); + + label.fontSize = (int)(12.0 * (Width / 0.2) * Scale); + + useWidth = (float)(Width * Scale * mapWidthMult); + // Position the arrow line: - line.SetVertexCount( 2 ); - line.SetWidth( useWidth , useWidth ); - line.SetPosition( 0, point1 ); - line.SetPosition( 1, point2 ); + line.SetVertexCount(2); + line.SetWidth(useWidth, useWidth); + line.SetPosition(0, point1); + line.SetPosition(1, point2); // Position the arrow hat: - hat.SetVertexCount( 2 ); - hat.SetWidth( useWidth * 3.5f, 0.0F ); - hat.SetPosition( 0, point2 ); - hat.SetPosition( 1, point3 ); + hat.SetVertexCount(2); + hat.SetWidth(useWidth * 3.5f, 0.0F); + hat.SetPosition(0, point2); + hat.SetPosition(1, point3); // Put the label at the midpoint of the arrow: labelLocation = (point1 + point3) / 2; PutAtShipRelativeCoords(); - } } @@ -349,33 +359,31 @@ public void RenderPointCoords() /// public void RenderColor() { - Color c1 = Color.Color; Color c2 = Color.Color; c1.a = c1.a * (float)0.25; - Color lCol = UnityEngine.Color.Lerp( c2, UnityEngine.Color.white, 0.7f ); // "whiten" the label color a lot. + Color lCol = UnityEngine.Color.Lerp(c2, UnityEngine.Color.white, 0.7f); // "whiten" the label color a lot. if (line != null && hat != null) { - line.SetColors( c1, c2 ); // The line has the fade effect - hat.SetColors( c2, c2 ); // The hat does not have the fade effect. + line.SetColors(c1, c2); // The line has the fade effect + hat.SetColors(c2, c2); // The hat does not have the fade effect. label.color = lCol; // The label does not have the fade effect. } } - + /// /// Place the 2D label at the correct projected spot on /// the screen from its location in 3D space: /// private void LabelPlacement() { - - Vector3 screenPos = GetViewportPosFor( shipCenterCoords + labelLocation ); - + Vector3 screenPos = GetViewportPosFor(shipCenterCoords + labelLocation); + // If the projected location is on-screen: - if ( screenPos.z > 0 + if (screenPos.z > 0 && screenPos.x >= 0 && screenPos.x <= 1 - && screenPos.y >= 0 && screenPos.y <= 1 ) + && screenPos.y >= 0 && screenPos.y <= 1) { label.enabled = true; label.transform.position = screenPos; @@ -393,7 +401,7 @@ public override string ToString() public void Dispose() { - updateHandler.RemoveObserver(this); + updateHandler.RemoveObserver(this); } } -} +} \ No newline at end of file diff --git a/src/kOS/Suffixed/VesselAlt.cs b/src/kOS/Suffixed/VesselAlt.cs new file mode 100644 index 000000000..81d166446 --- /dev/null +++ b/src/kOS/Suffixed/VesselAlt.cs @@ -0,0 +1,48 @@ +using kOS.Safe.Encapsulation; +using kOS.Safe.Encapsulation.Suffixes; +using System; +using UnityEngine; + +namespace kOS.Suffixed +{ + [kOS.Safe.Utilities.KOSNomenclature("VesselAltitude")] + public class VesselAlt : Structure + { + private readonly SharedObjects shared; + public VesselAlt(SharedObjects shared ) + { + this.shared = shared; + InitializeSuffixAlt(); + } + + private void InitializeSuffixAlt() + { + AddSuffix("APOAPSIS", new NoArgsSuffix(GetApoapsis)); + AddSuffix("PERIAPSIS", new NoArgsSuffix(GetPeriapsis)); + AddSuffix("RADAR", new NoArgsSuffix(GetRadar)); + } + + public ScalarValue GetApoapsis() + { + return shared.Vessel.orbit.ApA; + } + + public ScalarValue GetPeriapsis() + { + return shared.Vessel.orbit.PeA; + } + + public ScalarValue GetRadar() + { + return Convert.ToDouble( + shared.Vessel.heightFromTerrain > 0 ? + Mathf.Min(shared.Vessel.heightFromTerrain, (float)shared.Vessel.altitude) : + (float)shared.Vessel.altitude); + } + + public override string ToString() + { + return string.Format("ALT: Apoapsis={0} Periapsis={1} Radar={2}", GetApoapsis(), GetPeriapsis(), GetRadar()); + } + } +} \ No newline at end of file diff --git a/src/kOS/Suffixed/VesselEta.cs b/src/kOS/Suffixed/VesselEta.cs new file mode 100644 index 000000000..88862513e --- /dev/null +++ b/src/kOS/Suffixed/VesselEta.cs @@ -0,0 +1,42 @@ +using kOS.Safe.Encapsulation; +using kOS.Safe.Encapsulation.Suffixes; + +namespace kOS.Suffixed +{ + [kOS.Safe.Utilities.KOSNomenclature("VesselEta")] + public class VesselEta : Structure + { + private readonly SharedObjects shared; + public VesselEta(SharedObjects shared ) + { + this.shared = shared; + InitializeSuffixEta(); + } + + private void InitializeSuffixEta() + { + AddSuffix("APOAPSIS" , new NoArgsSuffix(GetApoapsis)); + AddSuffix("PERIAPSIS" , new NoArgsSuffix(GetPeriapsis)); + AddSuffix("TRANSITION" , new NoArgsSuffix(GetTransition)); + } + public ScalarValue GetApoapsis() + { + return shared.Vessel.orbit.timeToAp; + } + + public ScalarValue GetPeriapsis() + { + return shared.Vessel.orbit.timeToPe; + } + + public ScalarValue GetTransition() + { + return shared.Vessel.orbit.EndUT - Planetarium.GetUniversalTime(); + } + + public override string ToString() + { + return string.Format("ETA: Apoapsis={0} Periapsis={1} Transition={2}", GetApoapsis(), GetPeriapsis(), GetTransition()); + } + } +} \ No newline at end of file diff --git a/src/kOS/Suffixed/VesselSensors.cs b/src/kOS/Suffixed/VesselSensors.cs index fc57a03c2..073839b1e 100644 --- a/src/kOS/Suffixed/VesselSensors.cs +++ b/src/kOS/Suffixed/VesselSensors.cs @@ -1,34 +1,33 @@ using kOS.Safe.Encapsulation; using kOS.Safe.Encapsulation.Suffixes; +using kOS.Safe.Exceptions; namespace kOS.Suffixed { + [kOS.Safe.Utilities.KOSNomenclature("VesselSensors")] public class VesselSensors : Structure { - private Vector acceleration = new Vector(0, 0, 0); - private Vector geeForce = new Vector(0, 0, 0); - private double kerbolExposure; - private double temperature; - private double pressure; + private Vessel vessel; + public VesselSensors(Vessel target) { - FindSensors(target); + vessel = target; InitializeSuffixes(); } private void InitializeSuffixes() { - AddSuffix("ACC", new Suffix(() => acceleration)); - AddSuffix("PRES", new Suffix(() => pressure)); - AddSuffix("TEMP", new Suffix(() => temperature)); - AddSuffix("GRAV", new Suffix(() => geeForce)); - AddSuffix("LIGHT", new Suffix(() => kerbolExposure)); + AddSuffix("ACC", new Suffix(() => GetSensorVectorValue("ACC"))); + AddSuffix("PRES", new Suffix(() => GetSensorDoubleValue("PRES"))); + AddSuffix("TEMP", new Suffix(() => GetSensorDoubleValue("TEMP"))); + AddSuffix("GRAV", new Suffix(() => GetSensorVectorValue("GRAV"))); + AddSuffix("LIGHT", new Suffix(() => GetSunLightValue())); } - private void FindSensors(Vessel target) + private Vector GetSensorVectorValue (string sensorType) { - foreach (var part in target.Parts) + foreach (var part in vessel.Parts) { if (part.State != PartStates.ACTIVE && part.State != PartStates.IDLE) continue; @@ -36,29 +35,65 @@ private void FindSensors(Vessel target) { if (module is ModuleEnviroSensor) { - switch (module.Fields.GetValue("sensorType").ToString()) + var moduleSensorType = module.Fields.GetValue("sensorType").ToString(); + if (moduleSensorType != sensorType) continue; + switch (moduleSensorType) { case "ACC": - acceleration = new Vector(target.acceleration); - break; - case "PRES": - pressure = target.staticPressurekPa; - break; - case "TEMP": - temperature = part.temperature; - break; + return new Vector(vessel.acceleration); case "GRAV": - geeForce = new Vector(FlightGlobals.getGeeForceAtPosition(part.transform.position)); - break; + return new Vector(FlightGlobals.getGeeForceAtPosition(part.transform.position)); + } } - foreach (var c in part.FindModulesImplementing()) + } + } + throw new KOSException("Cannot find sensor for " + sensorType); + } + + private double GetSensorDoubleValue(string sensorType) + { + foreach (var part in vessel.Parts) + { + if (part.State != PartStates.ACTIVE && part.State != PartStates.IDLE) continue; + + foreach (PartModule module in part.Modules) + { + if (module is ModuleEnviroSensor) { - kerbolExposure += c.sunAOA; + var moduleSensorType = module.Fields.GetValue("sensorType").ToString(); + if (moduleSensorType != sensorType) continue; + switch (moduleSensorType) + { + + case "PRES": + return vessel.staticPressurekPa; + case "TEMP": + return part.temperature; + + + } } + + } + } + throw new KOSException("Cannot find sensor for " + sensorType); + } + private double GetSunLightValue() + { + double kerbolExposure = 0; + foreach (var part in vessel.Parts) + { + foreach (var c in part.FindModulesImplementing()) + { + kerbolExposure += c.sunAOA; + } } + return kerbolExposure; } + + public override string ToString() { diff --git a/src/kOS/Suffixed/VesselTarget.cs b/src/kOS/Suffixed/VesselTarget.cs index 31a36d698..1b5887f24 100644 --- a/src/kOS/Suffixed/VesselTarget.cs +++ b/src/kOS/Suffixed/VesselTarget.cs @@ -1,7 +1,5 @@ -using System; -using System.Linq; -using kOS.Binding; -using UnityEngine; +using kOS.Binding; +using kOS.Module; using kOS.Safe.Encapsulation; using kOS.Safe.Encapsulation.Suffixes; using kOS.Safe.Exceptions; @@ -9,30 +7,38 @@ using kOS.Suffixed.Part; using kOS.Suffixed.PartModuleField; using kOS.Utilities; -using kOS.Module; +using System; using System.Collections.Generic; +using System.Linq; +using UnityEngine; +using kOS.Serialization; +using kOS.Safe.Serialization; +using kOS.Safe; namespace kOS.Suffixed { + [kOS.Safe.Utilities.KOSNomenclature("Vessel")] public class VesselTarget : Orbitable, IKOSTargetable { - override public Orbit Orbit { get{return Vessel.orbit;} } + private static string DumpGuid = "guid"; - override public string GetName() + public override Orbit Orbit { get { return Vessel.orbit; } } + + public override StringValue GetName() { return Vessel.vesselName; } - override public Vector GetPosition() + public override Vector GetPosition() { - return new Vector( Vessel.findWorldCenterOfMass() - CurrentVessel.findWorldCenterOfMass() ); + return new Vector(Vessel.findWorldCenterOfMass() - CurrentVessel.findWorldCenterOfMass()); } - override public OrbitableVelocity GetVelocities() + public override OrbitableVelocity GetVelocities() { return new OrbitableVelocity(Vessel); } - + /// /// Calculates the position of this vessel at some future universal timestamp, /// taking into account all currently predicted SOI transition patches, and also @@ -43,15 +49,15 @@ override public OrbitableVelocity GetVelocities() /// The time to predict for. Although the intention is to /// predict for a future time, it could be used to predict for a past time. /// The position as a user-readable Vector in Shared.Vessel-origin raw rotation coordinates. - override public Vector GetPositionAtUT(TimeSpan timeStamp) + public override Vector GetPositionAtUT(TimeSpan timeStamp) { string blockingTech; - if (! Career.CanMakeNodes(out blockingTech)) + if (!Career.CanMakeNodes(out blockingTech)) throw new KOSLowTechException("use POSITIONAT on a vessel", blockingTech); double desiredUT = timeStamp.ToUnixStyleTime(); - Orbit patch = GetOrbitAtUT( desiredUT ); + Orbit patch = GetOrbitAtUT(desiredUT); Vector3d pos = patch.getPositionAtUT(desiredUT); // This is an ugly workaround to fix what is probably a bug in KSP's API: @@ -68,7 +74,7 @@ override public Vector GetPositionAtUT(TimeSpan timeStamp) pos = pos + offset; } - return new Vector( pos - Shared.Vessel.findWorldCenterOfMass() ); // Convert to ship-centered frame. + return new Vector(pos - Shared.Vessel.findWorldCenterOfMass()); // Convert to ship-centered frame. } /// @@ -81,18 +87,18 @@ override public Vector GetPositionAtUT(TimeSpan timeStamp) /// The time to predict for. Although the intention is to /// predict for a future time, it could be used to predict for a past time. /// The orbit/surface velocity pair as a user-readable Vector in raw rotation coordinates. - override public OrbitableVelocity GetVelocitiesAtUT(TimeSpan timeStamp) + public override OrbitableVelocity GetVelocitiesAtUT(TimeSpan timeStamp) { string blockingTech; - if (! Career.CanMakeNodes(out blockingTech)) + if (!Career.CanMakeNodes(out blockingTech)) throw new KOSLowTechException("use VELOCITYAT on a vessel", blockingTech); double desiredUT = timeStamp.ToUnixStyleTime(); - Orbit patch = GetOrbitAtUT( desiredUT ); - + Orbit patch = GetOrbitAtUT(desiredUT); + Vector3d orbVel = patch.getOrbitalVelocityAtUT(desiredUT); - + // This is an ugly workaround to fix what is probably a bug in KSP's API: // If looking at a future orbit patch around a child body of the current body, then // the various get{Thingy}AtUT() methods return numbers calculated incorrectly as @@ -107,55 +113,54 @@ override public OrbitableVelocity GetVelocitiesAtUT(TimeSpan timeStamp) // For some weird reason orbital velocities are returned by the KSP API // with Y and Z swapped, so swap them back: - orbVel = new Vector3d( orbVel.x, orbVel.z, orbVel.y ); - + orbVel = new Vector3d(orbVel.x, orbVel.z, orbVel.y); CelestialBody parent = patch.referenceBody; Vector surfVel; if (parent != null) { - Vector3d pos = GetPositionAtUT( timeStamp ); - surfVel = new Vector( orbVel - parent.getRFrmVel( pos + Shared.Vessel.findWorldCenterOfMass()) ); + Vector3d pos = GetPositionAtUT(timeStamp); + surfVel = new Vector(orbVel - parent.getRFrmVel(pos + Shared.Vessel.findWorldCenterOfMass())); } else - surfVel = new Vector( orbVel.x, orbVel.y, orbVel.z ); + surfVel = new Vector(orbVel.x, orbVel.y, orbVel.z); - return new OrbitableVelocity( new Vector(orbVel), surfVel ); + return new OrbitableVelocity(new Vector(orbVel), surfVel); } - - override public Vector GetUpVector() + + public override Vector GetUpVector() { - return new Vector( Vessel.upAxis ); + return new Vector(Vessel.upAxis); } - override public Vector GetNorthVector() + public override Vector GetNorthVector() { - return new Vector( VesselUtils.GetNorthVector(Vessel) ); + return new Vector(VesselUtils.GetNorthVector(Vessel)); } - + /// /// Calculate which orbit patch contains the timestamp given. /// /// The timestamp to look for /// the orbit patch the vessel is expected to be in at the given time. - override public Orbit GetOrbitAtUT(double desiredUT) - { + public override Orbit GetOrbitAtUT(double desiredUT) + { // After much trial and error this seems to be the only way to do this: // Find the lastmost maneuver node that occurs prior to timestamp: - List nodes = Vessel.patchedConicSolver.maneuverNodes; + List nodes = Vessel.patchedConicSolver == null ? new List() : Vessel.patchedConicSolver.maneuverNodes; Orbit orbitPatch = Vessel.orbit; - for (int nodeIndex = 0 ; nodeIndex < nodes.Count && nodes[nodeIndex].UT <= desiredUT ; ++nodeIndex) + for (int nodeIndex = 0; nodeIndex < nodes.Count && nodes[nodeIndex].UT <= desiredUT; ++nodeIndex) { orbitPatch = nodes[nodeIndex].nextPatch; // the orbit patch that starts with this node. } - + // Walk the orbit patch list from there looking for the lastmost orbit patch that // contains this timestamp, or if this timestamp is later than the end of the last // patch, then just return the last patch (this can happen because a patches' EndUT // is one period of time and we might be predicting for a point in time more than one // period into the future.) - while ( !( orbitPatch.StartUT < desiredUT && desiredUT < orbitPatch.EndUT ) ) + while (!(orbitPatch.StartUT < desiredUT && desiredUT < orbitPatch.EndUT)) { // Sadly the way to detect that you are at the end of the orbitPatch list is // messy and inconsistent. Sometimes KSP's API gives you a list that ends @@ -172,31 +177,40 @@ override public Orbit GetOrbitAtUT(double desiredUT) break; } } - + return orbitPatch; } static VesselTarget() { // TODO: These need to be refactored into the new suffix system at some point: - + ShortCuttableShipSuffixes = new[] { "HEADING", "PROGRADE", "RETROGRADE", "FACING", "MAXTHRUST", "AVAILABLETHRUST", "VELOCITY", "GEOPOSITION", "LATITUDE", "LONGITUDE", - "UP", "NORTH", "BODY", "ANGULARMOMENTUM", "ANGULARVEL", "MASS", "VERTICALSPEED", "SURFACESPEED", + "UP", "NORTH", "BODY", "ANGULARMOMENTUM", "ANGULARVEL", "MASS", "VERTICALSPEED", "SURFACESPEED", "GROUNDSPEED", "AIRSPEED", "VESSELNAME", "SHIPNAME", "ALTITUDE", "APOAPSIS", "PERIAPSIS", "SENSOR", "SRFPROGRADE", "SRFRETROGRADE" }; } - public VesselTarget(Vessel target, SharedObjects shared) :base(shared) + public VesselTarget() + { + InitializeSuffixes(); + } + + public VesselTarget(Vessel target, SharedObjects shared) + : base(shared) { Vessel = target; InitializeSuffixes(); } - public VesselTarget(SharedObjects shared) : this(shared.Vessel, shared) { } + public VesselTarget(SharedObjects shared) + : this(shared.Vessel, shared) + { + } private Vessel CurrentVessel { get { return Shared.Vessel; } } @@ -207,7 +221,7 @@ public ITargetable Target // TODO: We will need to replace with the same thing Orbitable:DISTANCE does // in order to implement the orbit solver later. - public double GetDistance() + public ScalarValue GetDistance() { return Vector3d.Distance(CurrentVessel.findWorldCenterOfMass(), Vessel.findWorldCenterOfMass()); } @@ -220,13 +234,13 @@ public override string ToString() { return "SHIP(\"" + Vessel.vesselName + "\")"; } - + public ListValue GetAllParts() { return PartValueFactory.Construct(Vessel.Parts, Shared); } - private ListValue GetPartsDubbed(string searchTerm) + private ListValue GetPartsDubbed(StringValue searchTerm) { // Get the list of all the parts where the part's API name OR its GUI title or its tag name matches. List kspParts = new List(); @@ -238,21 +252,23 @@ private ListValue GetPartsDubbed(string searchTerm) return PartValueFactory.Construct(kspParts.Distinct(), Shared); } - private ListValue GetPartsNamed(string partName) + private ListValue GetPartsNamed(StringValue partName) { return PartValueFactory.Construct(GetRawPartsNamed(partName), Shared); } + private IEnumerable GetRawPartsNamed(string partName) { // Get the list of all the parts where the part's KSP API title matches: return Vessel.parts.FindAll( - part => String.Equals(part.name, partName, StringComparison.CurrentCultureIgnoreCase)); + part => String.Equals(part.name, partName, StringComparison.CurrentCultureIgnoreCase)); } - private ListValue GetPartsTitled(string partTitle) + private ListValue GetPartsTitled(StringValue partTitle) { return PartValueFactory.Construct(GetRawPartsTitled(partTitle), Shared); } + private IEnumerable GetRawPartsTitled(string partTitle) { // Get the list of all the parts where the part's GUI title matches: @@ -260,17 +276,18 @@ private ListValue GetPartsTitled(string partTitle) part => String.Equals(part.partInfo.title, partTitle, StringComparison.CurrentCultureIgnoreCase)); } - private ListValue GetPartsTagged(string tagName) + private ListValue GetPartsTagged(StringValue tagName) { return PartValueFactory.Construct(GetRawPartsTagged(tagName), Shared); } + private IEnumerable GetRawPartsTagged(string tagName) { return Vessel.parts - .Where( p => p.Modules.OfType() + .Where(p => p.Modules.OfType() .Any(tag => String.Equals(tag.nameTag, tagName, StringComparison.CurrentCultureIgnoreCase))); } - + /// /// Get all the parts which have at least SOME non-default name: /// @@ -278,47 +295,47 @@ private ListValue GetPartsTagged(string tagName) private ListValue GetAllTaggedParts() { IEnumerable partsWithName = Vessel.parts - .Where( p => p.Modules.OfType() - .Any(tag => !(String.Equals(tag.nameTag, "", StringComparison.CurrentCultureIgnoreCase)))); + .Where(p => p.Modules.OfType() + .Any(tag => !String.Equals(tag.nameTag, "", StringComparison.CurrentCultureIgnoreCase))); - return PartValueFactory.Construct(partsWithName,Shared); + return PartValueFactory.Construct(partsWithName, Shared); } - private ListValue GetModulesNamed(string modName) + private ListValue GetModulesNamed(StringValue modName) { // This is slow - maybe there should be a faster lookup string hash, but // KSP's data model seems to have not implemented it: IEnumerable modules = Vessel.parts - .SelectMany( p => p.Modules.Cast() - .Where( pMod => String.Equals(pMod.moduleName, modName, StringComparison.CurrentCultureIgnoreCase))); + .SelectMany(p => p.Modules.Cast() + .Where(pMod => String.Equals(pMod.moduleName, modName, StringComparison.CurrentCultureIgnoreCase))); - return PartModuleFieldsFactory.Construct(modules,Shared); + return PartModuleFieldsFactory.Construct(modules, Shared); } - - private ListValue GetPartsInGroup(string groupName) + + private ListValue GetPartsInGroup(StringValue groupName) { var matchGroup = KSPActionGroup.None; string upperName = groupName.ToUpper(); - + // TODO: later refactor: put this in a Dictionary lookup instead, and then share it // by both this code and the code in ActionGroup.cs: - if (upperName == "SAS") { matchGroup = KSPActionGroup.SAS; } - if (upperName == "GEAR") { matchGroup = KSPActionGroup.Gear; } + if (upperName == "SAS") { matchGroup = KSPActionGroup.SAS; } + if (upperName == "GEAR") { matchGroup = KSPActionGroup.Gear; } if (upperName == "LIGHTS") { matchGroup = KSPActionGroup.Light; } if (upperName == "BRAKES") { matchGroup = KSPActionGroup.Brakes; } - if (upperName == "RCS") { matchGroup = KSPActionGroup.RCS; } - if (upperName == "ABORT") { matchGroup = KSPActionGroup.Abort; } - if (upperName == "AG1") { matchGroup = KSPActionGroup.Custom01; } - if (upperName == "AG2") { matchGroup = KSPActionGroup.Custom02; } - if (upperName == "AG3") { matchGroup = KSPActionGroup.Custom03; } - if (upperName == "AG4") { matchGroup = KSPActionGroup.Custom04; } - if (upperName == "AG5") { matchGroup = KSPActionGroup.Custom05; } - if (upperName == "AG6") { matchGroup = KSPActionGroup.Custom06; } - if (upperName == "AG7") { matchGroup = KSPActionGroup.Custom07; } - if (upperName == "AG8") { matchGroup = KSPActionGroup.Custom08; } - if (upperName == "AG9") { matchGroup = KSPActionGroup.Custom09; } - if (upperName == "AG10") { matchGroup = KSPActionGroup.Custom10; } - + if (upperName == "RCS") { matchGroup = KSPActionGroup.RCS; } + if (upperName == "ABORT") { matchGroup = KSPActionGroup.Abort; } + if (upperName == "AG1") { matchGroup = KSPActionGroup.Custom01; } + if (upperName == "AG2") { matchGroup = KSPActionGroup.Custom02; } + if (upperName == "AG3") { matchGroup = KSPActionGroup.Custom03; } + if (upperName == "AG4") { matchGroup = KSPActionGroup.Custom04; } + if (upperName == "AG5") { matchGroup = KSPActionGroup.Custom05; } + if (upperName == "AG6") { matchGroup = KSPActionGroup.Custom06; } + if (upperName == "AG7") { matchGroup = KSPActionGroup.Custom07; } + if (upperName == "AG8") { matchGroup = KSPActionGroup.Custom08; } + if (upperName == "AG9") { matchGroup = KSPActionGroup.Custom09; } + if (upperName == "AG10") { matchGroup = KSPActionGroup.Custom10; } + ListValue kScriptParts = new ListValue(); if (matchGroup == KSPActionGroup.None) return kScriptParts; @@ -328,46 +345,46 @@ private ListValue GetPartsInGroup(string groupName) bool hasPartAction = p.Actions.Any(a => a.actionGroup.Equals(matchGroup)); if (hasPartAction) { - kScriptParts.Add(PartValueFactory.Construct(p,Shared)); + kScriptParts.Add(PartValueFactory.Construct(p, Shared)); continue; } var modules = p.Modules.Cast(); - bool hasModuleAction = modules.Any(pm => pm.Actions.Any(a=>a.actionGroup.Equals(matchGroup))); + bool hasModuleAction = modules.Any(pm => pm.Actions.Any(a => a.actionGroup.Equals(matchGroup))); if (hasModuleAction) { - kScriptParts.Add(PartValueFactory.Construct(p,Shared)); + kScriptParts.Add(PartValueFactory.Construct(p, Shared)); } } return kScriptParts; } - - private ListValue GetModulesInGroup(string groupName) + + private ListValue GetModulesInGroup(StringValue groupName) { var matchGroup = KSPActionGroup.None; string upperName = groupName.ToUpper(); - + // TODO: later refactor: put this in a Dictionary lookup instead, and then share it // by both this code and the code in ActionGroup.cs: - if (upperName == "SAS") { matchGroup = KSPActionGroup.SAS; } - if (upperName == "GEAR") { matchGroup = KSPActionGroup.Gear; } + if (upperName == "SAS") { matchGroup = KSPActionGroup.SAS; } + if (upperName == "GEAR") { matchGroup = KSPActionGroup.Gear; } if (upperName == "LIGHTS") { matchGroup = KSPActionGroup.Light; } if (upperName == "BRAKES") { matchGroup = KSPActionGroup.Brakes; } - if (upperName == "RCS") { matchGroup = KSPActionGroup.RCS; } - if (upperName == "ABORT") { matchGroup = KSPActionGroup.Abort; } - if (upperName == "AG1") { matchGroup = KSPActionGroup.Custom01; } - if (upperName == "AG2") { matchGroup = KSPActionGroup.Custom02; } - if (upperName == "AG3") { matchGroup = KSPActionGroup.Custom03; } - if (upperName == "AG4") { matchGroup = KSPActionGroup.Custom04; } - if (upperName == "AG5") { matchGroup = KSPActionGroup.Custom05; } - if (upperName == "AG6") { matchGroup = KSPActionGroup.Custom06; } - if (upperName == "AG7") { matchGroup = KSPActionGroup.Custom07; } - if (upperName == "AG8") { matchGroup = KSPActionGroup.Custom08; } - if (upperName == "AG9") { matchGroup = KSPActionGroup.Custom09; } - if (upperName == "AG10") { matchGroup = KSPActionGroup.Custom10; } - + if (upperName == "RCS") { matchGroup = KSPActionGroup.RCS; } + if (upperName == "ABORT") { matchGroup = KSPActionGroup.Abort; } + if (upperName == "AG1") { matchGroup = KSPActionGroup.Custom01; } + if (upperName == "AG2") { matchGroup = KSPActionGroup.Custom02; } + if (upperName == "AG3") { matchGroup = KSPActionGroup.Custom03; } + if (upperName == "AG4") { matchGroup = KSPActionGroup.Custom04; } + if (upperName == "AG5") { matchGroup = KSPActionGroup.Custom05; } + if (upperName == "AG6") { matchGroup = KSPActionGroup.Custom06; } + if (upperName == "AG7") { matchGroup = KSPActionGroup.Custom07; } + if (upperName == "AG8") { matchGroup = KSPActionGroup.Custom08; } + if (upperName == "AG9") { matchGroup = KSPActionGroup.Custom09; } + if (upperName == "AG10") { matchGroup = KSPActionGroup.Custom10; } + ListValue kScriptParts = new ListValue(); - + // This is almost identical to the logic in GetPartsInGroup and it might be a nice idea // later to merge them somehow: // @@ -387,67 +404,100 @@ private ListValue GetModulesInGroup(string groupName) private void InitializeSuffixes() { - AddSuffix("PARTSNAMED", new OneArgsSuffix(GetPartsNamed)); - AddSuffix("PARTSTITLED", new OneArgsSuffix(GetPartsTitled)); - AddSuffix("PARTSDUBBED", new OneArgsSuffix(GetPartsDubbed)); - AddSuffix("MODULESNAMED", new OneArgsSuffix(GetModulesNamed)); - AddSuffix("PARTSINGROUP", new OneArgsSuffix(GetPartsInGroup)); - AddSuffix("MODULESINGROUP", new OneArgsSuffix(GetModulesInGroup)); - AddSuffix("PARTSTAGGED", new OneArgsSuffix(GetPartsTagged)); + AddSuffix("PARTSNAMED", new OneArgsSuffix(GetPartsNamed)); + AddSuffix("PARTSTITLED", new OneArgsSuffix(GetPartsTitled)); + AddSuffix("PARTSDUBBED", new OneArgsSuffix(GetPartsDubbed)); + AddSuffix("MODULESNAMED", new OneArgsSuffix(GetModulesNamed)); + AddSuffix("PARTSINGROUP", new OneArgsSuffix(GetPartsInGroup)); + AddSuffix("MODULESINGROUP", new OneArgsSuffix(GetModulesInGroup)); + AddSuffix("PARTSTAGGED", new OneArgsSuffix(GetPartsTagged)); AddSuffix("ALLTAGGEDPARTS", new NoArgsSuffix(GetAllTaggedParts)); AddSuffix("PARTS", new NoArgsSuffix(GetAllParts)); - - AddSuffix("CONTROL", new Suffix(() => FlightControlManager.GetControllerByVessel(Vessel))); - AddSuffix("BEARING", new Suffix(() => VesselUtils.GetTargetBearing(CurrentVessel, Vessel))); - AddSuffix("HEADING", new Suffix(() => VesselUtils.GetTargetHeading(CurrentVessel, Vessel))); - AddSuffix("AVAILABLETHRUST", new Suffix(() => VesselUtils.GetAvailableThrust(Vessel))); - AddSuffix("MAXTHRUST", new Suffix(() => VesselUtils.GetMaxThrust(Vessel))); + AddSuffix("DOCKINGPORTS", new NoArgsSuffix(() => Vessel.PartList("dockingports", Shared))); + AddSuffix("ELEMENTS", new NoArgsSuffix(() => Vessel.PartList("elements", Shared))); + + AddSuffix("CONTROL", new Suffix(GetFlightControl)); + AddSuffix("BEARING", new Suffix(() => VesselUtils.GetTargetBearing(CurrentVessel, Vessel))); + AddSuffix("HEADING", new Suffix(() => VesselUtils.GetTargetHeading(CurrentVessel, Vessel))); + AddSuffix("AVAILABLETHRUST", new Suffix(() => VesselUtils.GetAvailableThrust(Vessel))); + AddSuffix("AVAILABLETHRUSTAT", new OneArgsSuffix(GetAvailableThrustAt)); + AddSuffix("MAXTHRUST", new Suffix(() => VesselUtils.GetMaxThrust(Vessel))); + AddSuffix("MAXTHRUSTAT", new OneArgsSuffix(GetMaxThrustAt)); AddSuffix("FACING", new Suffix(() => VesselUtils.GetFacing(Vessel))); AddSuffix("ANGULARMOMENTUM", new Suffix(() => new Vector(Vessel.angularMomentum))); AddSuffix("ANGULARVEL", new Suffix(() => RawAngularVelFromRelative(Vessel.angularVelocity))); - AddSuffix("MASS", new Suffix(() => Vessel.GetTotalMass())); - AddSuffix("VERTICALSPEED", new Suffix(() => Vessel.verticalSpeed)); - AddSuffix("SURFACESPEED", new Suffix(() => Vessel.horizontalSrfSpeed)); - AddSuffix("AIRSPEED", new Suffix(() => (Vessel.orbit.GetVel() - FlightGlobals.currentMainBody.getRFrmVel(Vessel.findWorldCenterOfMass())).magnitude,"the velocity of the vessel relative to the air")); - AddSuffix(new[] {"SHIPNAME", "NAME"}, new SetSuffix(() => Vessel.vesselName, RenameVessel, "The KSP name for a craft, cannot be empty")); - AddSuffix("TYPE", new SetSuffix(() => Vessel.vesselType.ToString(), RetypeVessel, "The Ship's KSP type (e.g. rover, base, probe)")); + AddSuffix("MASS", new Suffix(() => Vessel.GetTotalMass())); + AddSuffix("VERTICALSPEED", new Suffix(() => Vessel.verticalSpeed)); + AddSuffix("GROUNDSPEED", new Suffix(GetHorizontalSrfSpeed)); + AddSuffix("SURFACESPEED", new Suffix(() => { throw new KOSDeprecationException("0.18.0","SURFACESPEED","GROUNDSPEED",""); })); + AddSuffix("AIRSPEED", new Suffix(() => (Vessel.orbit.GetVel() - FlightGlobals.currentMainBody.getRFrmVel(Vessel.findWorldCenterOfMass())).magnitude, "the velocity of the vessel relative to the air")); + AddSuffix(new[] { "SHIPNAME", "NAME" }, new SetSuffix(() => Vessel.vesselName, RenameVessel, "The KSP name for a craft, cannot be empty")); + AddSuffix("TYPE", new SetSuffix(() => Vessel.vesselType.ToString(), RetypeVessel, "The Ship's KSP type (e.g. rover, base, probe)")); AddSuffix("SENSORS", new Suffix(() => new VesselSensors(Vessel))); - AddSuffix("TERMVELOCITY", new Suffix(() => { throw new KOSAtmosphereDeprecationException("17.2", "TERMVELOCITY", "", string.Empty);})); - AddSuffix("LOADED", new Suffix(() => Vessel.loaded)); + AddSuffix("TERMVELOCITY", new Suffix(() => { throw new KOSAtmosphereDeprecationException("17.2", "TERMVELOCITY", "", string.Empty); })); + AddSuffix(new [] { "DYNAMICPRESSURE" , "Q"} , new Suffix(() => Vessel.dynamicPressurekPa * ConstantValue.KpaToAtm, "Dynamic Pressure in Atmospheres")); + AddSuffix("LOADED", new Suffix(() => Vessel.loaded)); + AddSuffix("UNPACKED", new Suffix(() => !Vessel.packed)); AddSuffix("ROOTPART", new Suffix(() => PartValueFactory.Construct(Vessel.rootPart, Shared))); - AddSuffix("DRYMASS", new Suffix(() => Vessel.GetDryMass(), "The Ship's mass when empty")); - AddSuffix("WETMASS", new Suffix(Vessel.GetWetMass, "The Ship's mass when full")); + AddSuffix("DRYMASS", new Suffix(() => Vessel.GetDryMass(), "The Ship's mass when empty")); + AddSuffix("WETMASS", new Suffix(() => Vessel.GetWetMass(), "The Ship's mass when full")); AddSuffix("RESOURCES", new Suffix>(() => AggregateResourceValue.FromVessel(Vessel, Shared), "The Aggregate resources from every part on the craft")); - AddSuffix("PACKDISTANCE", new SetSuffix( - () => - { - return System.Math.Min(Vessel.vesselRanges.landed.pack, Vessel.vesselRanges.prelaunch.pack); - }, - value => - { - Vessel.vesselRanges.landed.pack = value; - Vessel.vesselRanges.splashed.pack = value; - Vessel.vesselRanges.prelaunch.pack = value; - })); - AddSuffix("ISDEAD", new NoArgsSuffix(() => (Vessel.state == Vessel.State.DEAD) )); - AddSuffix("STATUS", new Suffix(() => Vessel.situation.ToString())); + AddSuffix("LOADDISTANCE", new Suffix(() => new LoadDistanceValue(Vessel))); + AddSuffix("ISDEAD", new NoArgsSuffix(() => (Vessel.state == Vessel.State.DEAD))); + AddSuffix("STATUS", new Suffix(() => Vessel.situation.ToString())); //// Although there is an implementation of lat/long/alt in Orbitible, //// it's better to use the methods for vessels that are faster if they're //// available: - AddSuffix("LATITUDE", new Suffix(() => VesselUtils.GetVesselLatitude(Vessel))); - AddSuffix("LONGITUDE", new Suffix(() => VesselUtils.GetVesselLongitude(Vessel))); - AddSuffix("ALTITUDE", new Suffix(() => Vessel.altitude)); + AddSuffix("LATITUDE", new Suffix(() => VesselUtils.GetVesselLatitude(Vessel))); + AddSuffix("LONGITUDE", new Suffix(() => VesselUtils.GetVesselLongitude(Vessel))); + AddSuffix("ALTITUDE", new Suffix(() => Vessel.altitude)); + AddSuffix("CREW", new NoArgsSuffix(GetCrew)); + AddSuffix("CREWCAPACITY", new NoArgsSuffix (GetCrewCapacity)); + } + + public ScalarValue GetCrewCapacity() { + return Vessel.GetCrewCapacity(); + } + + public ListValue GetCrew() { + var crew = new ListValue(); + + foreach (var crewMember in Vessel.GetVesselCrew()) { + crew.Add(new CrewMember(crewMember, Shared)); + } - } + return crew; + } + + public void ThrowIfNotCPUVessel() + { + if (this.Vessel.id != Shared.Vessel.id) + throw new KOSWrongCPUVesselException(); + } + + public FlightControl GetFlightControl() + { + ThrowIfNotCPUVessel(); + return FlightControlManager.GetControllerByVessel(Vessel); + } + + public ScalarValue GetAvailableThrustAt(ScalarValue atmPressure) + { + return VesselUtils.GetAvailableThrust(Vessel, atmPressure); + } + public ScalarValue GetMaxThrustAt(ScalarValue atmPressure) + { + return VesselUtils.GetMaxThrust(Vessel, atmPressure); + } - private void RetypeVessel(string value) + private void RetypeVessel(StringValue value) { - Vessel.vesselType = value.ToEnum(); + Vessel.vesselType = value.ToString().ToEnum(); } - private void RenameVessel(string value) + private void RenameVessel(StringValue value) { if (Vessel.IsValidVesselName(value)) { @@ -455,8 +505,43 @@ private void RenameVessel(string value) } } + private ScalarValue GetHorizontalSrfSpeed() + { + // NOTE: THIS Function replaces the functionality of the + // single KSP API CALL: + // Vessel.horizontalSrfSpeed; + // Which broke in KSP 1.0.3, badly, so we're just going to + // calculate it manually instead. + + // The logic, shamefully copied from the Kerbal Engineer mod, + // which had the same problem, is this: + // Run the Pythagorean Theorem slightly backward. + // If we know that: + // srfspd == sqrt( a^2 + b^2 + c^2). + // And we want to get what the speed would be if dimension C was excluded so it was projected + // into the plane of just the a and b components, we can do this: + // srfspd^2 == a^2 + b^2 + c^2. + // solve for (a^2+b^2): + // srfspd^2 - c^2 == a^2 + b^2. + // We know that, in just the two dimensions: + // speed_2D = sqrt(a^2+b^2). + // Therefore: + // speed_2D = sqrt(srfspd^2 - c^2) + // Since C in our case is the vertical speed we want to remove, we get the following formula: + + double squared2DSpeed = Vessel.srfSpeed*Vessel.srfSpeed - Vessel.verticalSpeed*Vessel.verticalSpeed; + + // Due to floating point roundoff errrors in the KSP API, the above expression can sometimes come + // out slightly negative when it should be nearly zero. (i.e. -0.0000012). The Sqrt() would + // return NaN for such a case, so it needs to be protected from ever going negative like so: + if (squared2DSpeed < 0) + squared2DSpeed = 0; + + return System.Math.Sqrt(squared2DSpeed); + } + /// - /// Annoyingly, KSP returns vessel.angularVelociy in a frame of reference + /// Annoyingly, KSP returns vessel.angularVelociy in a frame of reference /// relative to the ship facing instead of the universe facing. This would be /// wonderful if that was their philosophy everywhere, but it's not - its just a /// weird exception for this one case. This transforms it back into raw universe @@ -470,17 +555,17 @@ private Vector RawAngularVelFromRelative(Vector3 angularVelFromKSP) new Vector3d(angularVelFromKSP.x, -angularVelFromKSP.z, angularVelFromKSP.y)); } - public override object GetSuffix(string suffixName) + public override ISuffixResult GetSuffix(string suffixName) { // Most suffixes are handled by the newer AddSuffix system, except for the // resource levels, which have to use this older technique as a fallback because // the AddSuffix system doesn't support this type of late-binding string matching: - + // Is this a resource? double dblValue; if (VesselUtils.TryGetResource(Vessel, suffixName, out dblValue)) { - return dblValue; + return new SuffixResult(ScalarValue.Create(dblValue)); } return base.GetSuffix(suffixName); @@ -496,7 +581,7 @@ public override bool Equals(object obj) if (ReferenceEquals(null, obj)) return false; if (ReferenceEquals(this, obj)) return true; if (obj.GetType() != GetType()) return false; - return Equals((VesselTarget) obj); + return Equals((VesselTarget)obj); } public override int GetHashCode() @@ -513,5 +598,35 @@ public override int GetHashCode() { return !Equals(left, right); } + + public override Dump Dump() + { + DumpWithHeader dump = new DumpWithHeader(); + + dump.Header = "VESSEL '" + Vessel.vesselName + "'"; + + dump.Add(DumpGuid, Vessel.id.ToString()); + + return dump; + } + + public override void LoadDump(Dump dump) + { + string guid = dump[DumpGuid] as string; + + if (guid == null) + { + throw new KOSSerializationException("Vessel's guid is null or invalid"); + } + + Vessel vessel = FlightGlobals.Vessels.Find((v) => v.id.ToString().Equals(guid)); + + if (vessel == null) + { + throw new KOSSerializationException("Vessel with the given id does not exist"); + } + + Vessel = vessel; + } } } diff --git a/src/kOS/Suffixed/WaypointValue.cs b/src/kOS/Suffixed/WaypointValue.cs index 399060b84..1df98bdf1 100644 --- a/src/kOS/Suffixed/WaypointValue.cs +++ b/src/kOS/Suffixed/WaypointValue.cs @@ -7,6 +7,7 @@ namespace kOS.Suffixed { + [kOS.Safe.Utilities.KOSNomenclature("Waypoint")] public class WaypointValue : Structure { protected Waypoint WrappedWaypoint { get; set; } @@ -19,27 +20,21 @@ public WaypointValue(Waypoint wayPoint, SharedObjects shared) WrappedWaypoint = wayPoint; Shared = shared; InitializeSuffixes(); - - // greekMap is static, so whichever waypoint instance's constructor happens to - // get called first will make it, and from then on other waypoints don't need to - // keep re-initializing it: - if (greekMap == null) - InitializeGreekMap(); } private void InitializeSuffixes() { - AddSuffix("DUMP", new NoArgsSuffix(ToVerboseString)); // for debugging - AddSuffix("NAME", new NoArgsSuffix(CookedName, "Name of waypoint as it appears on the map and contract")); + AddSuffix("DUMP", new NoArgsSuffix(ToVerboseString)); // for debugging + AddSuffix("NAME", new NoArgsSuffix(CookedName, "Name of waypoint as it appears on the map and contract")); AddSuffix("BODY", new NoArgsSuffix(() => new BodyTarget(GetBody(), Shared), "Celestial body the waypoint is attached to")); AddSuffix("GEOPOSITION", new NoArgsSuffix(BuildGeoCoordinates, "the LATLNG of this waypoint")); AddSuffix("POSITION", new NoArgsSuffix(() => GetPosition() - new Vector(Shared.Vessel.findWorldCenterOfMass()))); - AddSuffix("ALTITUDE", new NoArgsSuffix(BuildSeaLevelAltitude, "Altitude of waypoint above sea level. Warning, this a point somewhere in the " + "midst of the contract altitude range, not the edge of the altitude range.")); - AddSuffix("AGL", new NoArgsSuffix(() => WrappedWaypoint.altitude, "Altitude of waypoint above ground. Warning, this a point somewhere" + "in the midst of the contract altitude range, not the edge of the altitude range.")); - AddSuffix("NEARSURFACE", new NoArgsSuffix(() => WrappedWaypoint.isOnSurface, "True if waypoint is a point near or on the body rather than high in orbit.")); - AddSuffix("GROUNDED", new NoArgsSuffix(() => WrappedWaypoint.landLocked, "True if waypoint is actually glued to the ground.")); - AddSuffix("INDEX", new NoArgsSuffix(() => WrappedWaypoint.index, "Number of this waypoint if this is a grouped waypoint (i.e. alpha/beta/gamma..")); - AddSuffix("CLUSTERED", new NoArgsSuffix(() => WrappedWaypoint.isClustered, "True if this is a member of a cluster of waypoints (i.e. alpha/beta/gamma..")); + AddSuffix("ALTITUDE", new NoArgsSuffix(BuildSeaLevelAltitude, "Altitude of waypoint above sea level. Warning, this a point somewhere in the " + "midst of the contract altitude range, not the edge of the altitude range.")); + AddSuffix("AGL", new NoArgsSuffix(() => WrappedWaypoint.altitude, "Altitude of waypoint above ground. Warning, this a point somewhere" + "in the midst of the contract altitude range, not the edge of the altitude range.")); + AddSuffix("NEARSURFACE", new NoArgsSuffix(() => WrappedWaypoint.isOnSurface, "True if waypoint is a point near or on the body rather than high in orbit.")); + AddSuffix("GROUNDED", new NoArgsSuffix(() => WrappedWaypoint.landLocked, "True if waypoint is actually glued to the ground.")); + AddSuffix("INDEX", new NoArgsSuffix(() => WrappedWaypoint.index, "Number of this waypoint if this is a grouped waypoint (i.e. alpha/beta/gamma..")); + AddSuffix("CLUSTERED", new NoArgsSuffix(() => WrappedWaypoint.isClustered, "True if this is a member of a cluster of waypoints (i.e. alpha/beta/gamma..")); } private static void InitializeGreekMap() @@ -64,7 +59,7 @@ public Vector GetPosition() return new Vector(GetBody().GetWorldSurfacePosition(WrappedWaypoint.latitude, WrappedWaypoint.longitude, BuildSeaLevelAltitude())); } - public double BuildSeaLevelAltitude() + public ScalarValue BuildSeaLevelAltitude() { GeoCoordinates gCoord = BuildGeoCoordinates(); return gCoord.GetTerrainAltitude() + WrappedWaypoint.altitude; @@ -72,25 +67,23 @@ public double BuildSeaLevelAltitude() public override string ToString() { - return String.Format("Waypoint \"{0}\"", CookedName() ); + return string.Format("Waypoint \"{0}\"", CookedName() ); } - public string CookedName() + public StringValue CookedName() { - return String.Format("{0}{1}", + return string.Format("{0}{1}", WrappedWaypoint.name, - ( - WrappedWaypoint.isClustered ? - (" " + FinePrint.Utilities.StringUtilities.IntegerToGreek(WrappedWaypoint.index)) : - "" - ) + WrappedWaypoint.isClustered ? + " " + FinePrint.Utilities.StringUtilities.IntegerToGreek(WrappedWaypoint.index) : + "" ); } - public string ToVerboseString() + public StringValue ToVerboseString() { // Remember to change this if you alter the suffix names: - return String.Format("A Waypoint consisting of\n" + + return string.Format("A Waypoint consisting of\n" + " name= {0}\n" + " body= {1}\n" + " geoposition= {2}\n" + @@ -128,10 +121,18 @@ public string ToVerboseString() /// /// string name to check. Case insensitively. /// integer position in alphabet. -1 if no match. - /// the name after the greek suffix has been stripped off, if there is one. + /// the name after the last term has been stripped off, if there are + /// space separated terms. Note that if the return value of this method is false, this + /// shouldn't be used and you should stick with the original full name. /// true if there was a greek letter suffix public static bool GreekToInteger(string greekLetterName, out int index, out string baseName ) { + // greekMap is static, and we only need to populate it once in + // the lifetime of the KSP process. We'll do so the first time + // this method (the only one that uses it) gets called: + if (greekMap == null) + InitializeGreekMap(); + // Get lastmost word (or whole string if there's no spaces): int lastSpace = greekLetterName.LastIndexOf(' '); string lastTerm; diff --git a/src/kOS/UserIO/TelnetMainServer.cs b/src/kOS/UserIO/TelnetMainServer.cs index d282ff8ff..1f9ccd35e 100644 --- a/src/kOS/UserIO/TelnetMainServer.cs +++ b/src/kOS/UserIO/TelnetMainServer.cs @@ -57,7 +57,6 @@ public TelnetMainServer() DontDestroyOnLoad(transform.gameObject); // Otherwise Unity will stop calling my Update() on the next scene change because my gameObject went away. - Console.WriteLine("kOS TelnetMainServer class exists."); // Console.Writeline used because this occurs before kSP's logger is set up. Instance = this; tempListenPermission = GetPermanentListenPermission(); @@ -82,7 +81,7 @@ private bool GetPermanentListenPermission() } catch (Exception ex) { - Debug.LogError(string.Format("{0} Exception Loading TelnetMainServer.xml (maybe the first time you ran and its not there yet): {1}", KSPLogger.LOGGER_PREFIX, ex.Message)); + Debug.LogError(string.Format("{0} Exception loading telnet config options: {1}", KSPLogger.LOGGER_PREFIX, ex.Message)); } return false; } @@ -102,7 +101,7 @@ private void SetPermanentListenPermission(bool newValue) } catch (Exception ex) { - Debug.LogError(string.Format("{0} Exception Loading TelnetMainServer.xml (maybe the first time you ran and its not there yet): {1}", KSPLogger.LOGGER_PREFIX, ex.Message)); + Debug.LogError(string.Format("{0} Exception loading telnet config options: {1}", KSPLogger.LOGGER_PREFIX, ex.Message)); } } @@ -125,7 +124,7 @@ private bool GetPermanentRealIPPermission() } catch (Exception ex) { - Debug.LogError(string.Format("{0} Exception Loading TelnetMainServer.xml (maybe the first time you ran and its not there yet): {1}", KSPLogger.LOGGER_PREFIX, ex.Message)); + Debug.LogError(string.Format("{0} Exception loading telnet config options: {1}", KSPLogger.LOGGER_PREFIX, ex.Message)); } return false; // In principle it should never reach here. } @@ -145,14 +144,14 @@ private void SetPermanentRealIPPermission(bool newValue) } catch (Exception ex) { - Debug.LogError(string.Format("{0} Exception Loading TelnetMainServer.xml (maybe the first time you ran and its not there yet): {1}", KSPLogger.LOGGER_PREFIX, ex.Message)); + Debug.LogError(string.Format("{0} Exception loading telnet config options: {1}", KSPLogger.LOGGER_PREFIX, ex.Message)); } } public void SetConfigEnable(bool newVal) { bool isLoopback = Equals(bindAddr, IPAddress.Loopback); - bool loopBackStatusChanged = (isLoopback != Config.Instance.TelnetLoopback); + bool loopBackStatusChanged = (isLoopback != SafeHouse.Config.TelnetLoopback); if (loopBackStatusChanged) StopListening(); // we'll be forcing a new restart of the telnet server on the new IP address. @@ -162,11 +161,11 @@ public void SetConfigEnable(bool newVal) if (newVal) { - if (tempListenPermission && ((tempRealIPPermission || Config.Instance.TelnetLoopback))) + if (tempListenPermission && ((tempRealIPPermission || SafeHouse.Config.TelnetLoopback))) StartListening(); else { - Config.Instance.EnableTelnet = false; // Turn it right back off, never having allowed the server to turn on. + SafeHouse.Config.EnableTelnet = false; // Turn it right back off, never having allowed the server to turn on. // Depending on which reason it was for the denial, activate the proper dialog window: if (!tempListenPermission) @@ -187,8 +186,8 @@ public void StartListening() // Build the server settings here, not in the constructor, because the settings might have been altered by the user post-init: - port = Config.Instance.TelnetPort; - bindAddr = Config.Instance.TelnetLoopback ? + port = SafeHouse.Config.TelnetPort; + bindAddr = SafeHouse.Config.TelnetLoopback ? IPAddress.Loopback : GetRealAddress(); @@ -232,7 +231,7 @@ void OnDestroy() public void Update() { - SetConfigEnable(Config.Instance.EnableTelnet); + SetConfigEnable(SafeHouse.Config.EnableTelnet); int howManySpawned = 0; @@ -347,7 +346,7 @@ void OptInOnGui(int id) if (yesClicked || yesNeverAgainClicked) { tempListenPermission = true; - Config.Instance.EnableTelnet = true; // should get noticed next Update() and turn on the server. + SafeHouse.Config.EnableTelnet = true; // should get noticed next Update() and turn on the server. } if (yesNeverAgainClicked) @@ -420,13 +419,13 @@ void RealIPOnGui(int id) if (noClicked) { - Config.Instance.TelnetLoopback = true; + SafeHouse.Config.TelnetLoopback = true; tempRealIPPermission = false; } if (yesClicked || yesNeverAgainClicked) { - Config.Instance.TelnetLoopback = false; + SafeHouse.Config.TelnetLoopback = false; tempRealIPPermission = true; StartListening(); } diff --git a/src/kOS/UserIO/TelnetSingletonServer.cs b/src/kOS/UserIO/TelnetSingletonServer.cs index b22fd0204..2df018c79 100644 --- a/src/kOS/UserIO/TelnetSingletonServer.cs +++ b/src/kOS/UserIO/TelnetSingletonServer.cs @@ -27,6 +27,11 @@ public class TelnetSingletonServer // actually part of the algorithm: // ReSharper disable RedundantDefaultFieldInitializer + // These exist just to track the state of whether or not the telnet client + // got told about a change to these statuses yet or not: + public bool ReverseScreen {get; set;} + public bool VisualBeep {get; set;} + private volatile TcpClient client; private readonly TelnetMainServer whoLaunchedMe; diff --git a/src/kOS/UserIO/TelnetWelcomeMenu.cs b/src/kOS/UserIO/TelnetWelcomeMenu.cs index 7e8d4dadf..6ec731467 100644 --- a/src/kOS/UserIO/TelnetWelcomeMenu.cs +++ b/src/kOS/UserIO/TelnetWelcomeMenu.cs @@ -152,7 +152,6 @@ private bool CPUListChanged() if (newList[i] != availableCPUs[i]) itChanged = true; - Console.WriteLine("in CPUListChanged(): itChanged = {0}, newList.Count={1}, availableCPUs.Count={2}", itChanged, newList.Count, availableCPUs.Count); availableCPUs = newList; lastMenuQueryTime = DateTime.Now; return itChanged; diff --git a/src/kOS/UserIO/TerminalVT100Mapper.cs b/src/kOS/UserIO/TerminalVT100Mapper.cs index 718b44b1f..5c942f065 100644 --- a/src/kOS/UserIO/TerminalVT100Mapper.cs +++ b/src/kOS/UserIO/TerminalVT100Mapper.cs @@ -1,6 +1,7 @@ using kOS.Safe.UserIO; using System.Collections.Generic; using System.Text; +using System; namespace kOS.UserIO { @@ -110,6 +111,26 @@ public override char[] OutputConvert(string str) sb.AppendFormat("{0}1K", csi); break; + case (char)UnicodeCommand.BEEP: + sb.Append(BELL_CHAR); + break; + + case (char)UnicodeCommand.REVERSESCREENMODE: + sb.AppendFormat("{0}?5h", csi); + break; + + case (char)UnicodeCommand.NORMALSCREENMODE: + sb.AppendFormat("{0}?5l", csi); + break; + + case (char)UnicodeCommand.VISUALBEEPMODE: + // sadly, have to consume and ignore - no vt100 code for this, so it's not supported. + break; + + case (char)UnicodeCommand.AUDIOBEEPMODE: + // sadly, have to consume and ignore - no vt100 code for this. so it's not supported. + break; + default: sb.Append(t); // default passhtrough break; @@ -134,7 +155,8 @@ public override string InputConvert(char[] inChars) switch (inChars[index]) { case ESCAPE_CHARACTER: - if (inChars[index + 1] == '[') // ESC followed by '[' is called the CSI (Control Sequence Initiator) and it's how most VT100 codes start. + if (index + 1 < inChars.Length && inChars[index + 1] == '[') + // ESC followed by '[' is called the CSI (Control Sequence Initiator) and it's how most VT100 codes start. { int numConsumed; char ch = ConvertVT100InputCSI(inChars, index + 2, out numConsumed); @@ -152,6 +174,10 @@ public override string InputConvert(char[] inChars) outChars.Add((char)UnicodeCommand.DELETELEFT); // Map to the same as backspace, because Vt100 sends it for the backspace key, annoyingly. break; + case BELL_CHAR: + outChars.Add((char)UnicodeCommand.BEEP); + break; + default: outChars.Add(inChars[index]); // dummy passthrough break; @@ -170,16 +196,20 @@ public override string InputConvert(char[] inChars) /// The UnicdeCommand equivalent. NOTE that if numConsumed is zero, this value shouldn't be used as nothing was actually done. protected char ConvertVT100InputCSI(char[] inChars, int offset, out int numConsumed) { - char returnChar = '\0'; // dummy until changed. - switch (inChars[offset]) + char returnChar = '\0'; // default until changed. + numConsumed = 0; // default if all the clauses below get skipped. + if (offset < inChars.Length) { - case 'A': returnChar = (char)UnicodeCommand.UPCURSORONE; numConsumed = 1; break; - case 'B': returnChar = (char)UnicodeCommand.DOWNCURSORONE; numConsumed = 1; break; - case 'C': returnChar = (char)UnicodeCommand.RIGHTCURSORONE; numConsumed = 1; break; - case 'D': returnChar = (char)UnicodeCommand.LEFTCURSORONE; numConsumed = 1; break; - case 'H': returnChar = (char)UnicodeCommand.HOMECURSOR; numConsumed = 1; break; - case 'F': returnChar = (char)UnicodeCommand.ENDCURSOR; numConsumed = 1; break; - default: numConsumed = 0; break; // Do nothing if it's not a recognized sequence. Leave the chars to be read normally. + switch (inChars[offset]) + { + case 'A': returnChar = (char)UnicodeCommand.UPCURSORONE; numConsumed = 1; break; + case 'B': returnChar = (char)UnicodeCommand.DOWNCURSORONE; numConsumed = 1; break; + case 'C': returnChar = (char)UnicodeCommand.RIGHTCURSORONE; numConsumed = 1; break; + case 'D': returnChar = (char)UnicodeCommand.LEFTCURSORONE; numConsumed = 1; break; + case 'H': returnChar = (char)UnicodeCommand.HOMECURSOR; numConsumed = 1; break; + case 'F': returnChar = (char)UnicodeCommand.ENDCURSOR; numConsumed = 1; break; + default: numConsumed = 0; break; // Do nothing if it's not a recognized sequence. Leave the chars to be read normally. + } } // The following are technically VT220 codes, not VT100, but I couldn't be bothered making a separate // mapper just for them. (i.e. the proper way would be to make a VT220Mapper that inherits from this VT100Mapper, diff --git a/src/kOS/Utilities/SteeringHelper.cs b/src/kOS/Utilities/SteeringHelper.cs deleted file mode 100644 index d79352b80..000000000 --- a/src/kOS/Utilities/SteeringHelper.cs +++ /dev/null @@ -1,234 +0,0 @@ -using System.Linq; -using kOS.Safe.Utilities; -using UnityEngine; -using kOS.Suffixed; -using Math = System.Math; - -namespace kOS.Utilities -{ - public static class SteeringHelper - { - public static Vector3d PrevErr; - public static Vector3d Integral; - - public static void KillRotation(FlightCtrlState c, Vessel vessel) - { - var act = vessel.transform.InverseTransformDirection(vessel.rigidbody.angularVelocity).normalized; - - c.pitch = act.x; - c.roll = act.y; - c.yaw = act.z; - - c.killRot = true; - } - - public static void SteerShipToward(Direction targetDir, FlightCtrlState c, Vessel vessel) - { - // I take no credit for this, this is a stripped down, rearranged version of MechJeb's attitude control system - if (vessel == null) - { - SafeHouse.Logger.LogError("SteerShipToward: Vessel is null!!"); - return; - } - - var centerOfMass = vessel.findWorldCenterOfMass(); - var momentOfInertia = vessel.findLocalMOI(centerOfMass); - var mass = vessel.GetTotalMass(); - var up = (centerOfMass - vessel.mainBody.position).normalized; - - var target = targetDir.Rotation; - var vesselRotation = vessel.ReferenceTransform.rotation; - - if (vessel.ActionGroups[KSPActionGroup.SAS]) - { - target = target * Quaternion.Euler(90, 0, 0); - if (vessel.Autopilot.SAS.lockedHeading != target) vessel.Autopilot.SAS.LockHeading(target, true); - return; - } - - // some validations - if (!Utils.IsValidNumber(c.mainThrottle) || - !Utils.IsValidVector(centerOfMass) || - !Utils.IsValidNumber(mass) || - !Utils.IsValidVector(up) || - !Utils.IsValidRotation(target) || - !Utils.IsValidRotation(vesselRotation)) - { - return; - } - - Quaternion delta = Quaternion.Inverse(Quaternion.Euler(90, 0, 0) * Quaternion.Inverse(vesselRotation) * target); - - Vector3d deltaEuler = ReduceAngles(delta.eulerAngles); - deltaEuler.y *= -1; - - Vector3d torque = GetTorque(vessel, c.mainThrottle); - Vector3d inertia = GetEffectiveInertia(vessel, torque); - - Vector3d err = deltaEuler * Math.PI / 180.0F; - err += new Vector3d(inertia.x, inertia.z, inertia.y); - //err.Scale(SwapYZ(Vector3d.Scale(MoI, Inverse(torque)))); - - PrevErr = err; - - Vector3d act = 120.0f * err; - - float precision = Mathf.Clamp((float)torque.x * 20f / momentOfInertia.magnitude, 0.5f, 10f); - float driveLimit = Mathf.Clamp01((float)(err.magnitude * 380.0f / precision)); - - act.x = Mathf.Clamp((float)act.x, -driveLimit, driveLimit); - act.y = Mathf.Clamp((float)act.y, -driveLimit, driveLimit); - act.z = Mathf.Clamp((float)act.z, -driveLimit, driveLimit); - - //act = averageVector3d(averagedAct, act, 2); - - c.roll = Mathf.Clamp((float)(c.roll + act.z), -driveLimit, driveLimit); - c.pitch = Mathf.Clamp((float)(c.pitch + act.x), -driveLimit, driveLimit); - c.yaw = Mathf.Clamp((float)(c.yaw + act.y), -driveLimit, driveLimit); - - /* - // This revised version from 0.6 gave people problems with gravity turns. I've reverted but may try to make it work - - var CoM = vessel.findWorldCenterOfMass(); - var MoI = vessel.findLocalMOI(CoM); - var mass = vessel.GetTotalMass(); - var up = (CoM - vessel.mainBody.position).normalized; - - var target = targetDir.Rotation; - var vesselR = vessel.transform.rotation; - - Quaternion delta; - delta = Quaternion.Inverse(Quaternion.Euler(90, 0, 0) * Quaternion.Inverse(vesselR) * target); - - Vector3d deltaEuler = ReduceAngles(delta.eulerAngles); - deltaEuler.y *= -1; - - Vector3d torque = GetTorque(vessel, c.mainThrottle); - Vector3d inertia = GetEffectiveInertia(vessel, torque); - - Vector3d err = deltaEuler * Math.PI / 180.0F; - err += SwapYZ(inertia * 8); - err.Scale(SwapYZ(Vector3d.Scale(MoI * 3, Inverse(torque)))); - - prev_err = err; - - Vector3d act = 400.0f * err; - - float precision = Mathf.Clamp((float)torque.x * 20f / MoI.magnitude, 0.5f, 10f); - float drive_limit = Mathf.Clamp01((float)(err.magnitude * 450.0f / precision)); - - act.x = Mathf.Clamp((float)act.x, -drive_limit, drive_limit); - act.y = Mathf.Clamp((float)act.y, -drive_limit, drive_limit); - act.z = Mathf.Clamp((float)act.z, -drive_limit, drive_limit); - - //act = averageVector3d(averagedAct, act, 2); - - c.roll = Mathf.Clamp((float)(c.roll + act.z), -drive_limit, drive_limit); - c.pitch = Mathf.Clamp((float)(c.pitch + act.x), -drive_limit, drive_limit); - c.yaw = Mathf.Clamp((float)(c.yaw + act.y), -drive_limit, drive_limit);*/ - } - - public static Vector3d SwapYZ(Vector3d input) - { - return new Vector3d(input.x, input.z, input.y); - } - - public static Vector3d Pow(Vector3d vector, float exponent) - { - return new Vector3d(Math.Pow(vector.x, exponent), Math.Pow(vector.y, exponent), Math.Pow(vector.z, exponent)); - } - - public static Vector3d GetEffectiveInertia(Vessel vessel, Vector3d torque) - { - var centerOfMass = vessel.findWorldCenterOfMass(); - var momentOfInertia = vessel.findLocalMOI(centerOfMass); - var angularVelocity = Quaternion.Inverse(vessel.transform.rotation) * vessel.rigidbody.angularVelocity; - var angularMomentum = new Vector3d(angularVelocity.x * momentOfInertia.x, angularVelocity.y * momentOfInertia.y, angularVelocity.z * momentOfInertia.z); - - var retVar = Vector3d.Scale - ( - Sign(angularMomentum) * 2.0f, - Vector3d.Scale(Pow(angularMomentum, 2), Inverse(Vector3d.Scale(torque, momentOfInertia))) - ); - - retVar.y *= 10; - - return retVar; - } - - public static Vector3d GetTorque(Vessel vessel, float thrust) - { - var centerOfMass = vessel.findWorldCenterOfMass(); - var rollaxis = vessel.transform.up; - rollaxis.Normalize (); - var pitchaxis = vessel.GetFwdVector (); - pitchaxis.Normalize (); - - float pitch = 0.0f; - float yaw = 0.0f; - float roll = 0.0f; - - foreach (Part part in vessel.parts) - { - var relCoM = part.Rigidbody.worldCenterOfMass - centerOfMass; - - foreach (PartModule module in part.Modules) - { - var wheel = module as ModuleReactionWheel; - if (wheel == null) continue; - - pitch += wheel.PitchTorque; - yaw += wheel.YawTorque; - roll += wheel.RollTorque; - } - if (vessel.ActionGroups [KSPActionGroup.RCS]) - { - foreach (PartModule module in part.Modules) { - var rcs = module as ModuleRCS; - if (rcs == null || !rcs.rcsEnabled) continue; - - bool enoughfuel = rcs.propellants.All(p => (int) (p.totalResourceAvailable) != 0); - if (!enoughfuel) continue; - foreach (Transform thrustdir in rcs.thrusterTransforms) - { - float rcsthrust = rcs.thrusterPower; - //just counting positive contributions in one direction. This is incorrect for asymmetric thruster placements. - roll += Mathf.Max(rcsthrust * Vector3.Dot(Vector3.Cross(relCoM, thrustdir.up), rollaxis), 0.0f); - pitch += Mathf.Max(rcsthrust * Vector3.Dot(Vector3.Cross(Vector3.Cross(relCoM, thrustdir.up), rollaxis), pitchaxis), 0.0f); - yaw += Mathf.Max(rcsthrust * Vector3.Dot(Vector3.Cross(Vector3.Cross(relCoM, thrustdir.up), rollaxis), Vector3.Cross(rollaxis,pitchaxis)),0.0f); - } - } - } - pitch += (float)GetThrustTorque(part, vessel) * thrust; - yaw += (float)GetThrustTorque (part, vessel) * thrust; - } - - return new Vector3d(pitch, roll, yaw); - } - - public static double GetThrustTorque(Part p, Vessel vessel) - { - //TODO: implement gimbalthrust Torque calculation - return 0; - } - - private static Vector3d ReduceAngles(Vector3d input) - { - return new Vector3d( - (input.x > 180f) ? (input.x - 360f) : input.x, - (input.y > 180f) ? (input.y - 360f) : input.y, - (input.z > 180f) ? (input.z - 360f) : input.z - ); - } - - public static Vector3d Inverse(Vector3d input) - { - return new Vector3d(1 / input.x, 1 / input.y, 1 / input.z); - } - - public static Vector3d Sign(Vector3d vector) - { - return new Vector3d(Math.Sign(vector.x), Math.Sign(vector.y), Math.Sign(vector.z)); - } - } -} diff --git a/src/kOS/Utilities/VesselUtils.cs b/src/kOS/Utilities/VesselUtils.cs index 214b3ced2..45f6e54a2 100644 --- a/src/kOS/Utilities/VesselUtils.cs +++ b/src/kOS/Utilities/VesselUtils.cs @@ -104,7 +104,7 @@ public static ListValue PartList(this IShipconstruct vessel, string partType, Sh return list; } - public static double GetMaxThrust(Vessel vessel) + public static double GetMaxThrust(Vessel vessel, double atmPressure = -1.0) { var thrust = 0.0; @@ -113,21 +113,9 @@ public static double GetMaxThrust(Vessel vessel) foreach (PartModule pm in p.Modules) { if (!pm.isEnabled) continue; - if (!(pm is ModuleEngines || pm is ModuleEnginesFX)) continue; - - var engine = pm as ModuleEngines; - var enginefx = pm as ModuleEnginesFX; - - if (enginefx != null) - { - if (!enginefx.isOperational) continue; - thrust += enginefx.maxThrust; - } - - if (engine != null) + if (pm is ModuleEngines) { - if (!engine.isOperational) continue; - thrust += engine.maxThrust; + thrust += ModuleEngineAdapter.GetEngineThrust((ModuleEngines)pm, atmPressure: atmPressure); } } } @@ -227,6 +215,11 @@ public static Vector3d GetNorthVector(Vessel vessel) public static object TryGetEncounter(Vessel vessel, SharedObjects sharedObj) { + // If not the active vessel, it will be on rails, and therefore won't + // be able to have "encounters" via its patchedConicSolver. + if (vessel.patchedConicSolver == null) + return "None"; + foreach (var patch in vessel.patchedConicSolver.flightPlan) { if (patch.patchStartTransition == Orbit.PatchTransitionType.ENCOUNTER) @@ -367,7 +360,7 @@ public static void UnsetTarget() FlightGlobals.fetch.SetVesselTarget(null); } - public static double GetAvailableThrust(Vessel vessel) + public static double GetAvailableThrust(Vessel vessel, double atmPressure = -1.0) { var thrust = 0.0; @@ -375,22 +368,9 @@ public static double GetAvailableThrust(Vessel vessel) { foreach (PartModule pm in p.Modules) { - if (!pm.isEnabled) continue; - if (!(pm is ModuleEngines || pm is ModuleEnginesFX)) continue; - - var engine = pm as ModuleEngines; - var enginefx = pm as ModuleEnginesFX; - - if (enginefx != null) - { - if (!enginefx.isOperational) continue; - thrust += enginefx.maxThrust * enginefx.thrustPercentage / 100; - } - - if (engine != null) + if (pm.isEnabled && pm is ModuleEngines) { - if (!engine.isOperational) continue; - thrust += engine.maxThrust * engine.thrustPercentage / 100; + thrust += ModuleEngineAdapter.GetEngineThrust((ModuleEngines)pm, useThrustLimit: true, atmPressure: atmPressure); } } } diff --git a/src/kOS/kOS.csproj b/src/kOS/kOS.csproj index 2ec5f634d..041cd8574 100644 --- a/src/kOS/kOS.csproj +++ b/src/kOS/kOS.csproj @@ -30,10 +30,10 @@ - ..\..\..\KSP_LIB\Assembly-CSharp.dll + ..\..\Resources\Assembly-CSharp.dll - ..\..\..\KSP_LIB\ICSharpCode.SharpZipLib.dll + ..\..\Resources\GameData\kOS\Plugins\ICSharpCode.SharpZipLib.dll @@ -42,10 +42,10 @@ - ..\..\..\KSP_LIB\UnityEngine.dll + ..\..\Resources\UnityEngine.dll - ..\..\..\KSP_LIB\KSPAPIExtensions.dll + ..\..\Resources\KSPAPIExtensions.dll @@ -71,6 +71,8 @@ + + @@ -86,6 +88,7 @@ + @@ -93,7 +96,10 @@ True Resources.resx + + + @@ -109,7 +115,6 @@ - @@ -128,7 +133,6 @@ - @@ -138,6 +142,8 @@ + + @@ -149,16 +155,13 @@ - - - @@ -173,6 +176,20 @@ + + + + + + + + + + + + + + @@ -189,7 +206,13 @@ - + + cp "$(TargetPath)" "$(SolutionDir)/../Resources/GameData/kOS/Plugins" + (test -h "$(SolutionDir)/../KSPdirlink" && cp "$(TargetPath)" "$(SolutionDir)/../KSPdirlink/GameData/kOS/Plugins") || true + + + xcopy "$(TargetPath)" "$(SolutionDir)\..\Resources\GameData\kOS\Plugins" /y + IF EXIST "$(SolutionDir)\..\KSPdirlink\" xcopy "$(TargetPath)" "$(SolutionDir)\..\KSPdirlink\GameData\kOS\Plugins" /y || exit /B 0 + + - + - \ No newline at end of file + diff --git a/src/packages/repositories.config b/src/packages/repositories.config index 4644e02bc..bb419be8c 100644 --- a/src/packages/repositories.config +++ b/src/packages/repositories.config @@ -1,5 +1,7 @@ - - - - + + + + + + \ No newline at end of file diff --git a/src/parts source/kOS Cherry Light/cherrytop meshes/cherrytop.fbx b/src/parts source/kOS Cherry Light/cherrytop meshes/cherrytop.fbx new file mode 100644 index 000000000..cb9539fc7 --- /dev/null +++ b/src/parts source/kOS Cherry Light/cherrytop meshes/cherrytop.fbx @@ -0,0 +1,824 @@ +; FBX 7.3.0 project file +; Copyright (C) 1997-2010 Autodesk Inc. and/or its licensors. +; All rights reserved. +; ---------------------------------------------------- + +FBXHeaderExtension: { + FBXHeaderVersion: 1003 + FBXVersion: 7300 + CreationTimeStamp: { + Version: 1000 + Year: 2016 + Month: 1 + Day: 24 + Hour: 12 + Minute: 2 + Second: 8 + Millisecond: 0 + } + Creator: "FBX SDK/FBX Plugins version 2013.3" + SceneInfo: "SceneInfo::GlobalInfo", "UserData" { + Type: "UserData" + Version: 100 + MetaData: { + Version: 100 + Title: "" + Subject: "" + Author: "" + Keywords: "" + Revision: "" + Comment: "" + } + Properties70: { + P: "DocumentUrl", "KString", "Url", "", "/var/folders/16/csq8fhn9279gfgk7gc955t500000gn/T/com.sketchup.SketchUp.2016.petergoddardObpDK6.fbx" + P: "SrcDocumentUrl", "KString", "Url", "", "/var/folders/16/csq8fhn9279gfgk7gc955t500000gn/T/com.sketchup.SketchUp.2016.petergoddardObpDK6.fbx" + P: "Original", "Compound", "", "" + P: "Original|ApplicationVendor", "KString", "", "", "" + P: "Original|ApplicationName", "KString", "", "", "" + P: "Original|ApplicationVersion", "KString", "", "", "" + P: "Original|DateTime_GMT", "DateTime", "", "", "" + P: "Original|FileName", "KString", "", "", "" + P: "LastSaved", "Compound", "", "" + P: "LastSaved|ApplicationVendor", "KString", "", "", "" + P: "LastSaved|ApplicationName", "KString", "", "", "" + P: "LastSaved|ApplicationVersion", "KString", "", "", "" + P: "LastSaved|DateTime_GMT", "DateTime", "", "", "" + } + } +} +GlobalSettings: { + Version: 1000 + Properties70: { + P: "UpAxis", "int", "Integer", "",1 + P: "UpAxisSign", "int", "Integer", "",1 + P: "FrontAxis", "int", "Integer", "",2 + P: "FrontAxisSign", "int", "Integer", "",1 + P: "CoordAxis", "int", "Integer", "",0 + P: "CoordAxisSign", "int", "Integer", "",1 + P: "OriginalUpAxis", "int", "Integer", "",-1 + P: "OriginalUpAxisSign", "int", "Integer", "",1 + P: "UnitScaleFactor", "double", "Number", "",1 + P: "OriginalUnitScaleFactor", "double", "Number", "",1 + P: "AmbientColor", "ColorRGB", "Color", "",0,0,0 + P: "DefaultCamera", "KString", "", "", "Producer Perspective" + P: "TimeMode", "enum", "", "",0 + P: "TimeSpanStart", "KTime", "Time", "",0 + P: "TimeSpanStop", "KTime", "Time", "",46186158000 + P: "CustomFrameRate", "double", "Number", "",-1 + } +} + +; Documents Description +;------------------------------------------------------------------ + +Documents: { + Count: 1 + Document: 140593608394128, "", "Scene" { + Properties70: { + P: "SourceObject", "object", "", "" + P: "ActiveAnimStackName", "KString", "", "", "" + } + RootNode: 0 + } +} + +; Document References +;------------------------------------------------------------------ + +References: { +} + +; Object definitions +;------------------------------------------------------------------ + +Definitions: { + Version: 100 + Count: 17 + ObjectType: "GlobalSettings" { + Count: 1 + } + ObjectType: "Model" { + Count: 6 + PropertyTemplate: "FbxNode" { + Properties70: { + P: "QuaternionInterpolate", "enum", "", "",0 + P: "RotationOffset", "Vector3D", "Vector", "",0,0,0 + P: "RotationPivot", "Vector3D", "Vector", "",0,0,0 + P: "ScalingOffset", "Vector3D", "Vector", "",0,0,0 + P: "ScalingPivot", "Vector3D", "Vector", "",0,0,0 + P: "TranslationActive", "bool", "", "",0 + P: "TranslationMin", "Vector3D", "Vector", "",0,0,0 + P: "TranslationMax", "Vector3D", "Vector", "",0,0,0 + P: "TranslationMinX", "bool", "", "",0 + P: "TranslationMinY", "bool", "", "",0 + P: "TranslationMinZ", "bool", "", "",0 + P: "TranslationMaxX", "bool", "", "",0 + P: "TranslationMaxY", "bool", "", "",0 + P: "TranslationMaxZ", "bool", "", "",0 + P: "RotationOrder", "enum", "", "",0 + P: "RotationSpaceForLimitOnly", "bool", "", "",0 + P: "RotationStiffnessX", "double", "Number", "",0 + P: "RotationStiffnessY", "double", "Number", "",0 + P: "RotationStiffnessZ", "double", "Number", "",0 + P: "AxisLen", "double", "Number", "",10 + P: "PreRotation", "Vector3D", "Vector", "",0,0,0 + P: "PostRotation", "Vector3D", "Vector", "",0,0,0 + P: "RotationActive", "bool", "", "",0 + P: "RotationMin", "Vector3D", "Vector", "",0,0,0 + P: "RotationMax", "Vector3D", "Vector", "",0,0,0 + P: "RotationMinX", "bool", "", "",0 + P: "RotationMinY", "bool", "", "",0 + P: "RotationMinZ", "bool", "", "",0 + P: "RotationMaxX", "bool", "", "",0 + P: "RotationMaxY", "bool", "", "",0 + P: "RotationMaxZ", "bool", "", "",0 + P: "InheritType", "enum", "", "",0 + P: "ScalingActive", "bool", "", "",0 + P: "ScalingMin", "Vector3D", "Vector", "",0,0,0 + P: "ScalingMax", "Vector3D", "Vector", "",1,1,1 + P: "ScalingMinX", "bool", "", "",0 + P: "ScalingMinY", "bool", "", "",0 + P: "ScalingMinZ", "bool", "", "",0 + P: "ScalingMaxX", "bool", "", "",0 + P: "ScalingMaxY", "bool", "", "",0 + P: "ScalingMaxZ", "bool", "", "",0 + P: "GeometricTranslation", "Vector3D", "Vector", "",0,0,0 + P: "GeometricRotation", "Vector3D", "Vector", "",0,0,0 + P: "GeometricScaling", "Vector3D", "Vector", "",1,1,1 + P: "MinDampRangeX", "double", "Number", "",0 + P: "MinDampRangeY", "double", "Number", "",0 + P: "MinDampRangeZ", "double", "Number", "",0 + P: "MaxDampRangeX", "double", "Number", "",0 + P: "MaxDampRangeY", "double", "Number", "",0 + P: "MaxDampRangeZ", "double", "Number", "",0 + P: "MinDampStrengthX", "double", "Number", "",0 + P: "MinDampStrengthY", "double", "Number", "",0 + P: "MinDampStrengthZ", "double", "Number", "",0 + P: "MaxDampStrengthX", "double", "Number", "",0 + P: "MaxDampStrengthY", "double", "Number", "",0 + P: "MaxDampStrengthZ", "double", "Number", "",0 + P: "PreferedAngleX", "double", "Number", "",0 + P: "PreferedAngleY", "double", "Number", "",0 + P: "PreferedAngleZ", "double", "Number", "",0 + P: "LookAtProperty", "object", "", "" + P: "UpVectorProperty", "object", "", "" + P: "Show", "bool", "", "",1 + P: "NegativePercentShapeSupport", "bool", "", "",1 + P: "DefaultAttributeIndex", "int", "Integer", "",-1 + P: "Freeze", "bool", "", "",0 + P: "LODBox", "bool", "", "",0 + P: "Lcl Translation", "Lcl Translation", "", "A",0,0,0 + P: "Lcl Rotation", "Lcl Rotation", "", "A",0,0,0 + P: "Lcl Scaling", "Lcl Scaling", "", "A",1,1,1 + P: "Visibility", "Visibility", "", "A",1 + P: "Visibility Inheritance", "Visibility Inheritance", "", "",1 + } + } + } + ObjectType: "Geometry" { + Count: 4 + PropertyTemplate: "FbxMesh" { + Properties70: { + P: "Color", "ColorRGB", "Color", "",0.8,0.8,0.8 + P: "BBoxMin", "Vector3D", "Vector", "",0,0,0 + P: "BBoxMax", "Vector3D", "Vector", "",0,0,0 + P: "Primary Visibility", "bool", "", "",1 + P: "Casts Shadows", "bool", "", "",1 + P: "Receive Shadows", "bool", "", "",1 + } + } + } + ObjectType: "Material" { + Count: 4 + PropertyTemplate: "FbxSurfacePhong" { + Properties70: { + P: "ShadingModel", "KString", "", "", "Phong" + P: "MultiLayer", "bool", "", "",0 + P: "EmissiveColor", "Color", "", "A",0,0,0 + P: "EmissiveFactor", "Number", "", "A",1 + P: "AmbientColor", "Color", "", "A",0.2,0.2,0.2 + P: "AmbientFactor", "Number", "", "A",1 + P: "DiffuseColor", "Color", "", "A",0.8,0.8,0.8 + P: "DiffuseFactor", "Number", "", "A",1 + P: "Bump", "Vector3D", "Vector", "",0,0,0 + P: "NormalMap", "Vector3D", "Vector", "",0,0,0 + P: "BumpFactor", "double", "Number", "",1 + P: "TransparentColor", "Color", "", "A",0,0,0 + P: "TransparencyFactor", "Number", "", "A",0 + P: "DisplacementColor", "ColorRGB", "Color", "",0,0,0 + P: "DisplacementFactor", "double", "Number", "",1 + P: "VectorDisplacementColor", "ColorRGB", "Color", "",0,0,0 + P: "VectorDisplacementFactor", "double", "Number", "",1 + P: "SpecularColor", "Color", "", "A",0.2,0.2,0.2 + P: "SpecularFactor", "Number", "", "A",1 + P: "ShininessExponent", "Number", "", "A",20 + P: "ReflectionColor", "Color", "", "A",0,0,0 + P: "ReflectionFactor", "Number", "", "A",1 + } + } + } + ObjectType: "Texture" { + Count: 1 + PropertyTemplate: "FbxFileTexture" { + Properties70: { + P: "TextureTypeUse", "enum", "", "",0 + P: "Texture alpha", "Number", "", "A",1 + P: "CurrentMappingType", "enum", "", "",0 + P: "WrapModeU", "enum", "", "",0 + P: "WrapModeV", "enum", "", "",0 + P: "UVSwap", "bool", "", "",0 + P: "PremultiplyAlpha", "bool", "", "",1 + P: "Translation", "Vector", "", "A",0,0,0 + P: "Rotation", "Vector", "", "A",0,0,0 + P: "Scaling", "Vector", "", "A",1,1,1 + P: "TextureRotationPivot", "Vector3D", "Vector", "",0,0,0 + P: "TextureScalingPivot", "Vector3D", "Vector", "",0,0,0 + P: "CurrentTextureBlendMode", "enum", "", "",1 + P: "UVSet", "KString", "", "", "default" + P: "UseMaterial", "bool", "", "",0 + P: "UseMipMap", "bool", "", "",0 + } + } + } + ObjectType: "Video" { + Count: 1 + PropertyTemplate: "FbxVideo" { + Properties70: { + P: "ImageSequence", "bool", "", "",0 + P: "ImageSequenceOffset", "int", "Integer", "",0 + P: "FrameRate", "double", "Number", "",0 + P: "LastFrame", "int", "Integer", "",0 + P: "Width", "int", "Integer", "",0 + P: "Height", "int", "Integer", "",0 + P: "Path", "KString", "XRefUrl", "", "" + P: "StartFrame", "int", "Integer", "",0 + P: "StopFrame", "int", "Integer", "",0 + P: "PlaySpeed", "double", "Number", "",0 + P: "Offset", "KTime", "Time", "",0 + P: "InterlaceMode", "enum", "", "",0 + P: "FreeRunning", "bool", "", "",0 + P: "Loop", "bool", "", "",0 + P: "AccessMode", "enum", "", "",0 + } + } + } +} + +; Object properties +;------------------------------------------------------------------ + +Objects: { + Geometry: 140593614758912, "Geometry::", "Mesh" { + Vertices: *1008 { + a: -0.00159129557805545,0.152388005302283,0.0155730154605699,-0.00632320810959149,0.145110395561536,0.0293534548542012,-0.00632320810959172,0.15293558442695,0.0300847556531268,-0.00159129557805525,0.148337389482496,0.0151944663116486,-0.00632320810959172,0.15293558442695,0.0300847556531268,-0.00632320810959149,0.145110395561536,0.0293534548542012,-0.00159129557805545,0.152388005302283,0.0155730154605699,-0.0138505939094924,0.142339313059757,0.0415120539573175,-0.0138505939094924,0.153405801281358,0.0425462694653325,-0.0138505939094924,0.153405801281358,0.0425462694653325,-0.0138505939094924,0.142339313059757,0.0415120539573175,-0.0236604740750876,0.153766611363948,0.0521083253245109,-0.0236604740750876,0.140212986670227,0.0508416751851554,-0.0236604740750876,0.140212986670227,0.0508416751851554,-0.0236604740750876,0.153766611363948,0.0521083253245109,-0.0236604740750873,0.127449023718279,0.0461102489017724,-0.0138505939094921,0.131917580950403,0.0376488605740236,-0.0236604740750873,0.127449023718279,0.0461102489017724,-0.0350843214846855,0.138876322022469,0.0567065202689658,-0.0350843214846857,0.124639971209656,0.0514292999676549,-0.0350843214846857,0.124639971209656,0.0514292999676549,-0.0350843214846855,0.138876322022469,0.0567065202689658,-0.0236604740750876,0.116344565489834,0.0382364853565232,-0.0350843214846854,0.11225455740663,0.0426472578644845,-0.0350843214846854,0.11225455740663,0.0426472578644845,-0.0236604740750876,0.116344565489834,0.0382364853565232,-0.0350843214846853,0.102564126096203,0.0309588756157758,-0.0236604740750873,0.107656362462175,0.0277569685230063,-0.0350843214846853,0.102564126096203,0.0309588756157758,-0.0473436198161224,0.110859531816025,0.0441516902269075,-0.0473436198161225,0.10082725910244,0.0320509864972911,-0.0473436198161225,0.10082725910244,0.0320509864972911,-0.0473436198161224,0.110859531816025,0.0441516902269075,-0.0473436198161224,0.0942687203763799,0.017766061004644,-0.0350843214846854,0.0962290641579847,0.0171606971558129,-0.0473436198161224,0.0942687203763799,0.017766061004644, +-0.0350843214846854,0.0962290641579847,0.0171606971558129,-0.0236604740750873,0.101976501313704,0.0153858601552059,-0.0236604740750873,0.101976501313704,0.0153858601552059,-0.0236604740750874,0.0996920551952722,0.00196623084416461,-0.0350843214846854,0.0936810955938806,0.00219304554407414,-0.0350843214846854,0.0936810955938806,0.00219304554407414,-0.0236604740750874,0.0996920551952722,0.00196623084416461,-0.0350843214846854,0.0950938602508172,-0.012924058497314,-0.0236604740750877,0.100958705334628,-0.0115873938495568,-0.0350843214846854,0.0950938602508172,-0.012924058497314,-0.0473436198161223,0.0930934708113813,-0.0133799699164958,-0.0473436198161229,0.0916308692135296,0.00227040781433468,-0.0473436198161229,0.0916308692135296,0.00227040781433468,-0.0473436198161223,0.0930934708113813,-0.0133799699164958,-0.0350843214846852,0.100371080552129,-0.0271604093101267,-0.0473436198161225,0.0985568512881056,-0.0281185248089626,-0.0473436198161225,0.0985568512881056,-0.0281185248089626,-0.0350843214846852,0.100371080552129,-0.0271604093101267,-0.0350843214846853,0.109153122655299,-0.0395458231131529,-0.0473436198161226,0.107648690292876,-0.0409408487037579,-0.0473436198161226,0.107648690292876,-0.0409408487037579,-0.0350843214846853,0.109153122655299,-0.0395458231131529,-0.0473436198161225,0.119749394022492,-0.0509731214173436,-0.0350843214846854,0.120841504904008,-0.0492362544235806,-0.0473436198161225,0.119749394022492,-0.0509731214173436,-0.0350843214846854,0.120841504904008,-0.0492362544235806,-0.0236604740750878,0.11356389516326,-0.0354558150299495,-0.0236604740750876,0.124043411996777,-0.0441440180576081,-0.0236604740750878,0.11356389516326,-0.0354558150299495,-0.0236604740750876,0.124043411996777,-0.0441440180576081,-0.013850593909492,0.12913691062383,-0.0360434398124489,-0.0138505939094922,0.120580420959489,-0.0289495517459595,-0.0138505939094922,0.120580420959489,-0.0289495517459595,-0.013850593909492,0.12913691062383,-0.0360434398124489,-0.0236604740750875,0.105690131618011,-0.0243513568015046,-0.013850593909492,0.11415151994576,-0.0198827995693796, +-0.013850593909492,0.11415151994576,-0.0198827995693796,-0.0236604740750875,0.105690131618011,-0.0243513568015046,-0.0138505939094922,0.110288326562466,-0.00946106746002606,-0.0138505939094922,0.110288326562466,-0.00946106746002606,-0.0236604740750877,0.100958705334628,-0.0115873938495568,-0.0138505939094922,0.109254111054451,0.00160542076157495,-0.0138505939094922,0.109254111054451,0.00160542076157495,-0.0138505939094923,0.111119353499463,0.0125625022113576,-0.0138505939094923,0.111119353499463,0.0125625022113576,-0.0138505939094923,0.115756940707334,0.0226634698959533,-0.0236604740750873,0.107656362462175,0.0277569685230063,-0.0138505939094923,0.115756940707334,0.0226634698959533,-0.0138505939094923,0.122850828773823,0.0312199595602942,-0.0138505939094923,0.122850828773823,0.0312199595602942,-0.00632320810959113,0.131329956167904,0.0220758451134537,-0.00632320810959144,0.126313819811112,0.0160254932486455,-0.00632320810959113,0.131329956167904,0.0220758451134537,-0.00632320810959144,0.126313819811112,0.0160254932486455,-0.00159129557805527,0.14120410915259,0.0114272983041907,-0.00159129557805525,0.138607565908652,0.00829540571982283,-0.00159129557805527,0.14120410915259,0.0114272983041907,-0.00159129557805525,0.138607565908652,0.00829540571982283,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,-0.00159129557805532,0.136910091178305,0.00459819494445524,2.2671665947323e-05,0.151800380519783,-0,-0.00159129557805527,0.136227365059213,0.000587624782499546,-0.00159129557805532,0.136605914208135,-0.0034629910372879,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,-0.00159129557805527,0.136227365059213,0.000587624782499546,-0.00159129557805532,0.136605914208135,-0.0034629910372879,-0.00159129557805532,0.136910091178305,0.00459819494445524,2.2671665947323e-05,0.151800380519783,-0,-0.0063232081095914,0.121715624866656,0.00113520390716734,-0.0063232081095912,0.123034550448082,0.00888303050232202,-0.0063232081095912,0.123034550448082,0.00888303050232202,-0.0063232081095914,0.121715624866656,0.00113520390716734, +-0.00632320810959158,0.122446925665582,-0.00668998495824788,-0.00632320810959158,0.122446925665582,-0.00668998495824788,-0.00159129557805541,0.138019941126152,-0.00727760974074707,-0.00632320810959149,0.125178615903944,-0.0140592624044813,-0.00159129557805541,0.138019941126152,-0.00727760974074707,-0.00632320810959149,0.125178615903944,-0.0140592624044813,-0.00159129557805527,0.140373082215593,-0.0105962713671934,-0.00632320810959108,0.12972453540633,-0.0204704243518788,-0.00159129557805527,0.140373082215593,-0.0105962713671934,-0.00632320810959108,0.12972453540633,-0.0204704243518788,-0.00159129557805543,0.143504974799961,-0.0131928146111317,-0.00632320810959144,0.135774887271138,-0.0254865607086716,-0.00159129557805543,0.143504974799961,-0.0131928146111317,-0.00632320810959144,0.135774887271138,-0.0254865607086716,-0.00159129557805514,0.147202185575328,-0.0148902893414782,-0.00632320810959144,0.142917350017462,-0.0287658300717016,-0.00159129557805514,0.147202185575328,-0.0148902893414782,-0.00632320810959144,0.142917350017462,-0.0287658300717016,-0.00159129557805536,0.151212755737284,-0.0155730154605699,-0.00632320810959126,0.150665176612616,-0.0300847556531268,-0.00159129557805536,0.151212755737284,-0.0155730154605699,-0.00632320810959126,0.150665176612616,-0.0300847556531268,-0.00632320810959124,0.158490365478032,-0.0293534548542008,-0.00159129557805516,0.155263371557071,-0.0151944663116485,-0.00159129557805516,0.155263371557071,-0.0151944663116485,-0.00632320810959124,0.158490365478032,-0.0293534548542008,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,-0.00159129557805536,0.159077990260531,-0.0137804393936309,-0.00159129557805536,0.159077990260531,-0.0137804393936309,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,-0.00159129557805525,0.162396651886977,-0.0114272983041905,-0.00159129557805525,0.162396651886977,-0.0114272983041905,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0, +-0.00159129557805538,0.164993195130915,-0.00829540571982265,-0.00159129557805538,0.164993195130915,-0.00829540571982265,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,-0.00159129557805532,0.166690669861262,-0.00459819494445506,-0.00159129557805532,0.166690669861262,-0.00459819494445506,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,-0.00159129557805545,0.167373395980353,-0.000587624782499185,-0.00159129557805545,0.167373395980353,-0.000587624782499185,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,-0.00159129557805529,0.166994846831432,0.0034629910372879,-0.00159129557805529,0.166994846831432,0.0034629910372879,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,-0.00159129557805505,0.165580819913415,0.00727760974074743,2.2671665947323e-05,0.151800380519783,-0,-0.00159129557805527,0.163227678823974,0.0105962713671934,2.2671665947323e-05,0.151800380519783,-0,-0.00159129557805527,0.160095786239606,0.0131928146111317,2.2671665947323e-05,0.151800380519783,-0,-0.0015912955780552,0.156398575464238,0.0148902893414786,2.2671665947323e-05,0.151800380519783,-0,-0.0015912955780552,0.156398575464238,0.0148902893414786,2.2671665947323e-05,0.151800380519783,-0,-0.00632320810959149,0.160683411022105,0.0287658300717016,-0.00632320810959149,0.160683411022105,0.0287658300717016,-0.00632320810959158,0.167825873768429,0.025486560708672,-0.00632320810959158,0.167825873768429,0.025486560708672,-0.00159129557805527,0.160095786239606,0.0131928146111317,-0.00632320810959113,0.173876225633237,0.0204704243518791,-0.00632320810959113,0.173876225633237,0.0204704243518791,-0.00159129557805527,0.163227678823974,0.0105962713671934,-0.00632320810959147,0.178422145135622,0.0140592624044813,-0.00632320810959147,0.178422145135622,0.0140592624044813,-0.00159129557805505,0.165580819913415,0.00727760974074743,-0.0063232081095914,0.181153835373984,0.00668998495824824,-0.0063232081095914,0.181153835373984,0.00668998495824824, +-0.00632320810959149,0.18188513617291,-0.00113520390716716,-0.00632320810959149,0.18188513617291,-0.00113520390716716,-0.00632320810959149,0.180566210591485,-0.00888303050232202,-0.00632320810959149,0.180566210591485,-0.00888303050232202,-0.0138505939094922,0.194346649985116,-0.00160542076157459,-0.0138505939094922,0.192481407540104,-0.0125625022113576,-0.0138505939094922,0.194346649985116,-0.00160542076157459,-0.0138505939094922,0.192481407540104,-0.0125625022113576,-0.0236604740750875,0.201624259725863,-0.0153858601552059,-0.0236604740750876,0.203908705844294,-0.00196623084416425,-0.0236604740750876,0.203908705844294,-0.00196623084416425,-0.0236604740750875,0.201624259725863,-0.0153858601552059,-0.0236604740750874,0.202642055704939,0.0115873938495571,-0.0138505939094926,0.193312434477101,0.00946106746002642,-0.0236604740750874,0.202642055704939,0.0115873938495571,-0.0350843214846853,0.209919665445686,-0.00219304554407414,-0.0350843214846855,0.208506900788749,0.0129240584973143,-0.0350843214846855,0.208506900788749,0.0129240584973143,-0.0350843214846853,0.209919665445686,-0.00219304554407414,-0.0236604740750874,0.197910629421556,0.0243513568015046,-0.0350843214846858,0.203229680487438,0.027160409310127,-0.0350843214846858,0.203229680487438,0.027160409310127,-0.0236604740750874,0.197910629421556,0.0243513568015046,-0.0350843214846856,0.194447638384268,0.0395458231131529,-0.0236604740750875,0.190036865876306,0.0354558150299495,-0.0350843214846856,0.194447638384268,0.0395458231131529,-0.0473436198161226,0.195952070746691,0.0409408487037579,-0.0473436198161228,0.205043909751461,0.0281185248089626,-0.0473436198161228,0.205043909751461,0.0281185248089626,-0.0473436198161226,0.195952070746691,0.0409408487037579,-0.0473436198161224,0.183851367017074,0.0509731214173436,-0.0350843214846853,0.182759256135559,0.0492362544235808,-0.0350843214846853,0.182759256135559,0.0492362544235808,-0.0473436198161224,0.183851367017074,0.0509731214173436,-0.0236604740750873,0.179557349042789,0.0441440180576081,-0.0236604740750873,0.179557349042789,0.0441440180576081, +-0.0236604740750875,0.190036865876306,0.0354558150299495,-0.0138505939094923,0.174463850415736,0.0360434398124487,-0.0138505939094918,0.183020340080078,0.0289495517459599,-0.0138505939094923,0.174463850415736,0.0360434398124487,-0.0138505939094923,0.164362882731141,0.0406810270203202,-0.0236604740750876,0.167186240674989,0.0498238792060799,-0.0236604740750876,0.167186240674989,0.0498238792060799,-0.0138505939094923,0.164362882731141,0.0406810270203202,-0.0138505939094918,0.183020340080078,0.0289495517459599,-0.0138505939094925,0.189449241093807,0.0198827995693796,-0.0138505939094925,0.189449241093807,0.0198827995693796,-0.0138505939094926,0.193312434477101,0.00946106746002642,-0.0350843214846853,0.153993426063857,0.0581192849259028,-0.0350843214846852,0.168961077675596,0.0555713163617988,-0.0350843214846853,0.153993426063857,0.0581192849259028,-0.0350843214846852,0.168961077675596,0.0555713163617988,-0.0473436198161224,0.154070788334118,0.0601695113062537,-0.0473436198161225,0.169566441524427,0.0575316601434032,-0.0473436198161224,0.154070788334118,0.0601695113062537,-0.0473436198161225,0.169566441524427,0.0575316601434032,-0.0473436198161225,0.138420410603288,0.058706909708402,-0.0473436198161225,0.138420410603288,0.058706909708402,-0.0473436198161225,0.123681855710821,0.0532435292316779,-0.0473436198161225,0.123681855710821,0.0532435292316779,-0.0473436198161227,0.210507290228185,0.0133799699164958,-0.0473436198161227,0.210507290228185,0.0133799699164958,-0.0473436198161226,0.211969891826038,-0.00227040781433432,-0.0473436198161226,0.211969891826038,-0.00227040781433432,-0.0350843214846858,0.207371696881582,-0.0171606971558127,-0.0473436198161227,0.209332040663187,-0.017766061004644,-0.0473436198161227,0.209332040663187,-0.017766061004644,-0.0350843214846858,0.207371696881582,-0.0171606971558127,-0.0350843214846852,0.201036634943364,-0.0309588756157758,-0.0236604740750874,0.195944398577392,-0.0277569685230061,-0.0350843214846852,0.201036634943364,-0.0309588756157758,-0.0236604740750874,0.195944398577392,-0.0277569685230061, +-0.0236604740750875,0.187256195549733,-0.038236485356523,-0.0350843214846855,0.191346203632937,-0.0426472578644845,-0.0350843214846855,0.191346203632937,-0.0426472578644845,-0.0236604740750875,0.187256195549733,-0.038236485356523,-0.0473436198161224,0.192741229223541,-0.0441516902269075,-0.0473436198161225,0.202773501937127,-0.0320509864972911,-0.0473436198161225,0.202773501937127,-0.0320509864972911,-0.0473436198161224,0.192741229223541,-0.0441516902269075,-0.0473436198161225,0.179918905328746,-0.0532435292316781,-0.0350843214846852,0.17896078982991,-0.0514292999676547,-0.0350843214846852,0.17896078982991,-0.0514292999676547,-0.0473436198161225,0.179918905328746,-0.0532435292316781,-0.0473436198161225,0.165180350436279,-0.058706909708402,-0.0350843214846854,0.164724439017098,-0.056706520268966,-0.0350843214846854,0.164724439017098,-0.056706520268966,-0.0473436198161225,0.165180350436279,-0.058706909708402,-0.0350843214846854,0.149607334975709,-0.0581192849259026,-0.0473436198161225,0.149529972705449,-0.0601695113062539,-0.0473436198161225,0.149529972705449,-0.0601695113062539,-0.0350843214846854,0.149607334975709,-0.0581192849259026,-0.0236604740750874,0.149834149675619,-0.0521083253245107,-0.0236604740750876,0.16338777436934,-0.0508416751851554,-0.0236604740750874,0.149834149675619,-0.0521083253245107,-0.0236604740750876,0.16338777436934,-0.0508416751851554,-0.0138505939094919,0.150194959758209,-0.0425462694653327,-0.0138505939094924,0.16126144797981,-0.0415120539573173,-0.0138505939094919,0.150194959758209,-0.0425462694653327,-0.0138505939094924,0.16126144797981,-0.0415120539573173,-0.0138505939094923,0.139237878308426,-0.0406810270203202,-0.0138505939094923,0.139237878308426,-0.0406810270203202,-0.0236604740750873,0.136414520364577,-0.0498238792060798,-0.0236604740750873,0.136414520364577,-0.0498238792060798,-0.0350843214846849,0.134639683363971,-0.0555713163617986,-0.0350843214846849,0.134639683363971,-0.0555713163617986,-0.0473436198161225,0.134034319515139,-0.0575316601434032,-0.0473436198161225,0.134034319515139,-0.0575316601434032, +-0.0138505939094922,0.171683180089163,-0.0376488605740236,-0.00632320810959117,0.165859642924265,-0.0266217646158389,-0.00632320810959117,0.165859642924265,-0.0266217646158389,-0.0138505939094922,0.171683180089163,-0.0376488605740236,-0.00632320810959149,0.172270804871662,-0.0220758451134537,-0.00632320810959149,0.172270804871662,-0.0220758451134537,-0.0138505939094924,0.180749932265743,-0.0312199595602942,-0.0138505939094924,0.180749932265743,-0.0312199595602942,-0.0236604740750876,0.176151737321288,-0.0461102489017724,-0.0236604740750876,0.176151737321288,-0.0461102489017724,-0.0138505939094923,0.187843820332232,-0.0226634698959529,-0.0138505939094923,0.187843820332232,-0.0226634698959529,-0.00632320810959144,0.177286941228455,-0.0160254932486455,-0.00632320810959144,0.177286941228455,-0.0160254932486455,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,-0.00159129557805523,0.144522770779036,0.0137804393936313,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,-0.00159129557805523,0.144522770779036,0.0137804393936313,2.2671665947323e-05,0.151800380519783,-0,-0.00632320810959144,0.137741118115302,0.0266217646158389,-0.00632320810959144,0.137741118115302,0.0266217646158389,-0.0138505939094921,0.131917580950403,0.0376488605740236,-0.00159129557805525,0.148337389482496,0.0151944663116486,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0 + } + PolygonVertexIndex: *1584 { + a: 0,1,-3,1,0,-4,4,5,-7,7,2,-2,2,7,-9,9,10,-5,7,11,-9,11,7,-13,13,10,-15,7,15,-13,15,7,-17,13,17,-11,15,18,-13,18,15,-20,20,17,-22,22,19,-16,19,22,-24,24,25,-21,22,26,-24,26,22,-28,24,28,-26,26,29,-24,29,26,-31,31,28,-33,26,33,-31,33,26,-35,31,35,-29,36,28,-36,26,37,-35,37,26,-28,36,38,-29,39,34,-38,34,39,-41,41,42,-37,39,43,-41,43,39,-45,41,45,-43,46,40,-44,40,46,-48,48,49,-42,45,41,-50,50,46,-44,46,50,-52,52,53,-50,54,51,-51,51,54,-56,56,57,-53,54,58,-56,58,54,-60,56,60,-58,61,57,-61,62,59,-55,59,62,-64,57,61,-65,65,64,-62,62,66,-64,66,62,-68,68,64,-70,70,67,-63,67,70,-72,72,73,-69,44,71,-71,71,44,-75,75,76,-73,39,74,-45,74,39,-78,76,75,-43,78,42,-76,37,77,-40,77,37,-80,42,78,-39,80,38,-79,37,81,-80,81,37,-28,82,38,-84,82,28,-39,82,25,-29,84,27,-23,27,84,-82,25,82,-86,83,85,-83,86,81,-85,81,86,-88,85,83,-89,89,88,-84,90,87,-87,87,90,-92,88,89,-93,93,92,-90,94,91,-91,95,96,-92,97,98,-97,99,98,-101,101,102,-104,104,102,-106,106,96,-99,96,106,-108,108,109,-105,77,107,-107,107,77,-80,80,78,-109,109,108,-79,106,74,-78,74,106,-111,78,75,-110,111,109,-76,98,110,-107,110,98,-100,109,111,-103,103,102,-112,112,110,-100,110,112,-114,103,111,-115,115,114,-112,116,113,-113,113,116,-118,114,115,-119,119,118,-116,120,117,-117,117,120,-122,118,119,-123,123,122,-120,124,121,-121,121,124,-126,122,123,-127,127,126,-124,128,125,-125,125,128,-130,126,127,-131,131,130,-128,128,132,-130,132,128,-134,134,130,-136,128,136,-134,134,137,-131,133,138,-140,140,141,-135,139,142,-144,144,145,-141,143,146,-148,148,149,-145,147,150,-152,152,153,-149,151,154,-156,156,157,-153,155,158,-160,160,161,-157,162,163,-160,164,165,-164,166,167,-166,168,169,-168,170,0,-170,171,6,-173,0,173,-170,173,0,-3,4,6,-175,171,174,-7,175,169,-174,169,175,-168,174,171,-177,177,176,-172,178,167,-176,167,178,-166,176,177,-180,180,179,-178,181,165,-179,165,181,-164,179,180,-183,183,182,-181,184,163,-182,163,184,-160,182,183,-186,160,185,-184,186,159,-185,159,186,-156,185,160,-188,156,187,-161,186,151,-156,151,186,-189,156,152,-188,189,187,-153,190,188,-187, +188,190,-192,187,189,-193,193,192,-190,190,194,-192,194,190,-196,196,192,-198,190,198,-196,198,190,-200,196,200,-193,198,201,-196,201,198,-203,203,200,-205,205,202,-199,202,205,-207,207,208,-204,205,209,-207,209,205,-211,207,211,-209,212,206,-210,206,212,-214,214,215,-208,211,207,-216,209,216,-213,216,209,-218,218,211,-220,210,217,-210,217,210,-221,221,222,-219,210,223,-221,223,210,-225,221,225,-223,226,220,-224,220,226,-228,228,229,-222,226,11,-228,11,226,-9,9,229,-15,226,2,-9,2,226,-174,9,4,-230,174,229,-5,223,173,-227,173,223,-176,229,174,-226,176,225,-175,224,175,-224,175,224,-179,225,176,-231,179,230,-177,231,178,-225,178,231,-182,230,179,-233,182,232,-180,199,181,-232,181,199,-185,232,182,-234,185,233,-183,190,184,-200,184,190,-187,233,185,-193,187,192,-186,233,192,-201,231,198,-200,198,231,-206,208,232,-201,224,205,-232,205,224,-211,222,230,-209,230,222,-226,232,208,-231,222,208,-212,211,218,-223,233,200,-233,200,203,-209,225,221,-230,228,14,-230,234,227,-12,227,234,-236,14,228,-237,237,236,-229,238,235,-235,235,238,-240,236,237,-241,241,240,-238,239,217,-236,217,239,-217,237,218,-242,220,235,-218,235,220,-228,228,221,-238,218,237,-222,219,241,-219,18,238,-235,238,18,-243,243,21,-241,19,242,-19,242,19,-245,245,20,-244,23,244,-20,244,23,-30,32,24,-246,24,32,-29,20,245,-25,21,243,-21,236,240,-22,234,12,-19,12,234,-12,21,13,-237,13,21,-18,14,236,-14,9,14,-11,215,219,-212,246,206,-214,206,246,-203,214,207,-248,203,247,-208,248,202,-247,202,248,-202,247,203,-250,204,249,-204,248,250,-202,250,248,-252,252,249,-254,204,253,-250,194,201,-251,201,194,-196,253,204,-198,196,197,-205,196,204,-201,254,194,-251,194,254,-256,253,197,-257,257,256,-198,254,258,-256,258,254,-260,260,256,-262,254,262,-260,262,254,-264,264,256,-266,250,263,-255,263,250,-252,252,253,-265,256,264,-254,260,265,-257,266,259,-263,259,266,-268,268,269,-261,270,267,-267,267,270,-272,272,273,-269,270,274,-272,274,270,-276,276,273,-278,272,277,-274,278,271,-275,271,278,-280,277,272,-281,281,280,-273,282,279,-279,279,282,-284,280,281,-285,285,284,-282,129, +283,-283,283,129,-133,135,131,-286,131,135,-131,284,285,-132,286,129,-283,129,286,-126,127,287,-132,66,125,-287,125,66,-122,123,69,-128,67,121,-67,121,67,-118,119,68,-124,71,117,-68,117,71,-114,115,72,-120,74,113,-72,113,74,-111,111,75,-116,72,115,-76,68,119,-73,69,123,-69,287,127,-70,286,63,-67,63,286,-289,69,65,-288,65,69,-65,289,287,-66,286,278,-289,278,286,-283,289,280,-288,274,288,-279,288,274,-291,291,277,-290,275,290,-275,290,275,-293,293,276,-292,277,291,-277,292,59,-291,59,292,-59,60,293,-62,291,61,-294,63,290,-60,290,63,-289,61,291,-66,289,65,-292,280,289,-278,284,287,-281,284,131,-288,132,294,-284,294,132,-296,296,135,-298,133,295,-133,295,133,-140,140,134,-297,135,296,-135,139,298,-296,298,139,-144,144,140,-300,296,299,-141,300,295,-299,295,300,-295,299,296,-302,297,301,-297,258,294,-301,294,258,-303,301,297,-262,303,261,-298,258,267,-303,267,258,-260,303,268,-262,271,302,-268,302,271,-280,281,272,-304,268,303,-273,283,302,-280,302,283,-295,297,285,-304,285,297,-136,281,303,-286,260,261,-269,300,255,-259,255,300,-305,305,301,-258,298,304,-301,304,298,-307,307,299,-306,143,306,-299,306,143,-148,148,144,-308,299,307,-145,147,188,-307,188,147,-152,152,148,-190,307,189,-149,191,306,-189,306,191,-305,189,307,-194,305,193,-308,194,304,-192,304,194,-256,193,305,-198,257,197,-306,193,197,-193,301,305,-300,261,257,-302,257,261,-257,269,268,-274,265,260,-270,160,183,-309,183,180,-310,180,177,-311,177,171,-312,312,3,-1,313,314,-4,315,90,-315,92,93,-317,93,104,-318,107,91,-97,91,107,-88,89,108,-94,79,87,-108,87,79,-82,83,80,-90,80,83,-39,108,89,-81,104,93,-109,318,92,-320,86,314,-91,314,86,-321,321,88,-319,84,320,-87,320,84,-17,322,85,-322,22,16,-85,16,22,-16,17,25,-323,17,20,-26,85,322,-26,322,10,-18,1,16,-8,16,1,-321,10,322,-6,321,5,-323,3,320,-2,320,3,-315,5,321,-324,318,323,-322,323,318,-325,6,323,-326,323,6,-6,5,4,-11,88,321,-86,92,318,-89,128,124,-327,327,126,-131,124,120,-329,329,122,-127,120,116,-331,331,118,-123,116,112,-333,333,114,-119,112,99,-335,335,103,-115,102,104,-110,38,36,-43,76,42,-46,44,50,-44, +50,44,-71,45,53,-77,45,49,-54,73,76,-54,73,72,-77,62,50,-71,50,62,-55,57,64,-54,73,53,-65,64,68,-74,53,52,-58,33,40,-48,40,33,-35,48,41,-36,36,35,-42 + } + GeometryVersion: 124 + LayerElementNormal: 0 { + Version: 101 + Name: "" + MappingInformationType: "ByVertice" + ReferenceInformationType: "Direct" + Normals: *1008 { + a: -0.978227201428166,-0.00782552786592357,-0.20738925598892,-0.909402416903602,0.0924222919608575,-0.405518635920212,-0.9094024169036,-0.0156828673903062,-0.415621572828348,-0.978227201428168,0.046117409729502,-0.20234803410425,0.9094024169036,0.0156828673903062,0.415621572828348,0.909402416903602,-0.0924222919608575,0.405518635920212,0.978227201428166,0.00782552786592357,0.20738925598892,-0.783622247195286,0.138047147680612,-0.605705504942672,-0.783622247195288,-0.0234248152123465,-0.620795821291409,0.783622247195288,0.0234248152123465,0.620795821291409,0.783622247195286,-0.138047147680612,0.605705504942672,-0.588320272074908,-0.0304906870593461,-0.808052953381371,-0.588320272074901,0.179687751694512,-0.788410787189448,0.588320272074901,-0.179687751694512,0.788410787189448,0.588320272074908,0.0304906870593461,0.808052953381371,-0.588320272074897,0.377620767118447,-0.715039728760993,-0.783622247195285,0.290111425592854,-0.549337359407764,0.588320272074897,-0.377620767118447,0.715039728760993,-0.319660973195766,0.210554037262502,-0.923841901846845,-0.319660973195765,0.442487461282975,-0.837867357535119,0.319660973195765,-0.442487461282975,0.837867357535119,0.319660973195766,-0.210554037262502,0.923841901846845,-0.588320272074896,0.549819551311085,-0.592939894476496,-0.319660973195766,0.644266096062121,-0.69479353744865,0.319660973195766,-0.644266096062121,0.69479353744865,0.588320272074896,-0.549819551311085,0.592939894476496,-0.319660973195771,0.802139061094697,-0.504370685985665,-0.5883202720749,0.684549041701638,-0.430432186262929,0.319660973195771,-0.802139061094697,0.504370685985665,-0.16506188588,0.670614654340582,-0.723208517105128,-0.165061885880004,0.834944151922643,-0.524997939995878,0.165061885880004,-0.834944151922643,0.524997939995878,0.16506188588,-0.670614654340582,0.723208517105128,-0.16506188588,0.94237358536163,-0.291009620876019,-0.319660973195768,0.905347574711147,-0.279575805784726,0.16506188588,-0.94237358536163,0.291009620876019,0.319660973195768,-0.905347574711147,0.279575805784726, +-0.588320272074902,0.772627646171004,-0.238591235878369,0.588320272074902,-0.772627646171004,0.238591235878369,-0.588320272074906,0.808052953381371,-0.0304906870593525,-0.319660973195763,0.946858147268641,-0.0357282964404237,0.319660973195763,-0.946858147268641,0.0357282964404237,0.588320272074906,-0.808052953381371,0.0304906870593525,-0.319660973195766,0.923841901846845,0.210554037262504,-0.588320272074905,0.788410787189444,0.179687751694518,0.319660973195766,-0.923841901846845,-0.210554037262504,-0.165061885879989,0.961624275216606,0.219165068256507,-0.165061885879992,0.985581816304203,-0.0371894770096083,0.165061885879992,-0.985581816304203,0.0371894770096083,0.165061885879989,-0.961624275216606,-0.219165068256507,-0.319660973195767,0.837867357535116,0.442487461282981,-0.165061885880001,0.872133628932245,0.460583876308334,0.165061885880001,-0.872133628932245,-0.460583876308334,0.319660973195767,-0.837867357535116,-0.442487461282981,-0.31966097319577,0.694793537448649,0.64426609606212,-0.165061885880016,0.723208517105129,0.670614654340578,0.165061885880016,-0.723208517105129,-0.670614654340578,0.31966097319577,-0.694793537448649,-0.64426609606212,-0.165061885880009,0.524997939995875,0.834944151922644,-0.319660973195773,0.504370685985664,0.802139061094697,0.165061885880009,-0.524997939995875,-0.834944151922644,0.319660973195773,-0.504370685985664,-0.802139061094697,-0.588320272074896,0.592939894476494,0.549819551311087,-0.5883202720749,0.43043218626293,0.684549041701637,0.588320272074896,-0.592939894476494,-0.549819551311087,0.5883202720749,-0.43043218626293,-0.684549041701637,-0.783622247195288,0.33068439569855,0.525912544195413,-0.783622247195286,0.455532780652119,0.422405089282738,0.783622247195286,-0.455532780652119,-0.422405089282738,0.783622247195288,-0.33068439569855,-0.525912544195413,-0.5883202720749,0.71503972876099,0.377620767118447,-0.783622247195287,0.549337359407761,0.290111425592853,0.783622247195287,-0.549337359407761,-0.290111425592853,0.5883202720749,-0.71503972876099,-0.377620767118447,-0.783622247195287,0.605705504942669,0.138047147680623, +0.783622247195287,-0.605705504942669,-0.138047147680623,0.588320272074906,-0.788410787189444,-0.179687751694518,-0.783622247195289,0.620795821291407,-0.0234248152123421,0.783622247195289,-0.620795821291407,0.0234248152123421,-0.783622247195286,0.593579928332744,-0.183300415659933,0.783622247195286,-0.593579928332744,0.183300415659933,-0.783622247195284,0.525912544195417,-0.330684395698554,0.5883202720749,-0.684549041701638,0.430432186262929,0.783622247195284,-0.525912544195417,0.330684395698554,-0.783622247195283,0.422405089282741,-0.455532780652123,0.783622247195283,-0.422405089282741,0.455532780652123,-0.909402416903605,0.282799370674205,-0.304978294434466,-0.909402416903603,0.352097406735037,-0.221392547978353,0.909402416903605,-0.282799370674205,0.304978294434466,0.909402416903603,-0.352097406735037,0.221392547978353,-0.97822720142817,0.14111286543463,-0.152179833075342,-0.978227201428169,0.175691600225386,-0.110471733924364,0.97822720142817,-0.14111286543463,0.152179833075342,0.978227201428169,-0.175691600225386,0.110471733924364,-1,3.40111612179979e-16,1.43253848275465e-15,-1,3.40692999551227e-16,1.4319570953834e-15,-0.978227201428169,0.198297242804875,-0.0612351686696155,-1,3.38367450066236e-16,1.43253848275465e-15,-0.978227201428169,0.207389255988906,-0.0078255278659171,-0.978227201428168,0.202348034104243,0.0461174097295397,-1,3.43599936407466e-16,1.43420997144699e-15,1,-3.43599936407466e-16,-1.43420997144699e-15,0.978227201428169,-0.207389255988906,0.0078255278659171,0.978227201428168,-0.202348034104243,-0.0461174097295397,0.978227201428169,-0.198297242804875,0.0612351686696155,1,-3.38367450066236e-16,-1.43253848275465e-15,-0.909402416903602,0.415621572828342,-0.0156828673902944,-0.909402416903604,0.397400586395346,-0.122719265246002,0.909402416903604,-0.397400586395346,0.122719265246002,0.909402416903602,-0.415621572828342,0.0156828673902944,-0.909402416903602,0.405518635920207,0.0924222919608763,0.909402416903602,-0.405518635920207,-0.0924222919608763,-0.978227201428168,0.183517128091319,0.0969175220645279, +-0.909402416903604,0.367780274125343,0.194229024849972,0.978227201428168,-0.183517128091319,-0.0969175220645279,0.909402416903604,-0.367780274125343,-0.194229024849972,-0.97822720142817,0.152179833075341,0.141112865434629,-0.909402416903606,0.304978294434464,0.282799370674203,0.97822720142817,-0.152179833075341,-0.141112865434629,0.909402416903606,-0.304978294434464,-0.282799370674203,-0.978227201428168,0.110471733924372,0.17569160022539,-0.909402416903605,0.221392547978347,0.352097406735037,0.978227201428168,-0.110471733924372,-0.17569160022539,0.909402416903605,-0.221392547978347,-0.352097406735037,-0.97822720142817,0.0612351686696237,0.198297242804871,-0.909402416903604,0.122719265246011,0.397400586395343,0.97822720142817,-0.0612351686696237,-0.198297242804871,0.909402416903604,-0.122719265246011,-0.397400586395343,-0.978227201428169,0.00782552786592991,0.207389255988907,-0.909402416903605,0.0156828673903087,0.415621572828336,0.978227201428169,-0.00782552786592991,-0.207389255988907,0.909402416903605,-0.0156828673903087,-0.415621572828336,-0.909402416903603,-0.0924222919608785,0.405518635920205,-0.978227201428171,-0.0461174097295262,0.202348034104234,0.978227201428171,0.0461174097295262,-0.202348034104234,0.909402416903603,0.0924222919608785,-0.405518635920205,-1,3.39457551387326e-16,1.4319570953834e-15,1,-3.39457551387326e-16,-1.4319570953834e-15,-1,3.37495369009364e-16,1.43021293326966e-15,-0.978227201428169,-0.096917522064549,0.183517128091302,0.978227201428169,0.096917522064549,-0.183517128091302,1,-3.37495369009364e-16,-1.43021293326966e-15,-1,3.38948837437484e-16,1.43602680698214e-15,-0.978227201428169,-0.141112865434633,0.152179833075343,0.978227201428169,0.141112865434633,-0.152179833075343,1,-3.38948837437484e-16,-1.43602680698214e-15,-1,3.40111612179979e-16,1.43777096909588e-15,-0.978227201428168,-0.175691600225389,0.110471733924369,0.978227201428168,0.175691600225389,-0.110471733924369,1,-3.40111612179979e-16,-1.43777096909588e-15,-1,3.44762711149962e-16,1.43835235646713e-15,-0.978227201428169,-0.198297242804879,0.0612351686696053, +0.978227201428169,0.198297242804879,-0.0612351686696053,1,-3.44762711149962e-16,-1.43835235646713e-15,-1,3.47669648006201e-16,1.43995117173806e-15,-0.978227201428168,-0.207389255988913,0.00782552786592494,0.978227201428168,0.207389255988913,-0.00782552786592494,1,-3.47669648006201e-16,-1.43995117173806e-15,-1,3.43018549036219e-16,1.43609948040354e-15,-0.978227201428168,-0.202348034104252,-0.0461174097294971,0.978227201428168,0.202348034104252,0.0461174097294971,1,-3.43018549036219e-16,-1.43609948040354e-15,-1,3.43018549036218e-16,1.44154998700899e-15,-0.97822720142817,-0.183517128091311,-0.0969175220645311,-1,3.38948837437484e-16,1.43515472592526e-15,-0.978227201428169,-0.152179833075332,-0.141112865434644,-1,3.43599936407466e-16,1.43835235646713e-15,-0.978227201428168,-0.110471733924366,-0.17569160022539,-1,3.45053404835586e-16,1.43544541961089e-15,-0.978227201428169,-0.0612351686695966,-0.198297242804884,-1,3.38076756380612e-16,1.4307943206409e-15,0.978227201428169,0.0612351686695966,0.198297242804885,1,-3.38076756380612e-16,-1.4307943206409e-15,-0.909402416903602,-0.122719265245992,-0.397400586395355,0.909402416903602,0.122719265245992,0.397400586395355,-0.909402416903602,-0.221392547978341,-0.352097406735049,0.909402416903602,0.221392547978341,0.352097406735049,0.978227201428168,0.110471733924366,0.17569160022539,-0.909402416903606,-0.304978294434464,-0.282799370674203,0.909402416903606,0.304978294434464,0.282799370674203,0.978227201428169,0.152179833075332,0.141112865434644,-0.909402416903599,-0.367780274125358,-0.19422902484997,0.909402416903599,0.367780274125358,0.19422902484997,0.97822720142817,0.183517128091311,0.0969175220645311,-0.909402416903599,-0.405518635920212,-0.0924222919608799,0.909402416903599,0.405518635920212,0.0924222919608799,-0.909402416903603,-0.41562157282834,0.0156828673902948,0.909402416903603,0.41562157282834,-0.0156828673902948,-0.909402416903604,-0.397400586395346,0.122719265246001,0.909402416903604,0.397400586395346,-0.122719265246001,-0.783622247195289,-0.620795821291408,0.0234248152123369, +-0.783622247195287,-0.593579928332741,0.183300415659937,0.783622247195289,0.620795821291408,-0.0234248152123369,0.783622247195287,0.593579928332741,-0.183300415659937,-0.588320272074902,-0.772627646171005,0.238591235878365,-0.588320272074906,-0.808052953381371,0.0304906870593554,0.588320272074906,0.808052953381371,-0.0304906870593554,0.588320272074902,0.772627646171005,-0.238591235878365,-0.588320272074908,-0.788410787189439,-0.17968775169453,-0.783622247195289,-0.605705504942662,-0.138047147680636,0.588320272074908,0.788410787189439,0.17968775169453,-0.319660973195769,-0.946858147268639,0.0357282964404246,-0.319660973195765,-0.923841901846842,-0.21055403726252,0.319660973195765,0.923841901846842,0.21055403726252,0.319660973195769,0.946858147268639,-0.0357282964404246,-0.588320272074896,-0.715039728760989,-0.377620767118456,-0.319660973195767,-0.837867357535113,-0.442487461282987,0.319660973195767,0.837867357535113,0.442487461282987,0.588320272074896,0.715039728760989,0.377620767118456,-0.319660973195771,-0.694793537448654,-0.644266096062115,-0.588320272074894,-0.592939894476501,-0.549819551311081,0.319660973195771,0.694793537448654,0.644266096062115,-0.165061885880014,-0.723208517105129,-0.670614654340578,-0.165061885880015,-0.872133628932243,-0.460583876308333,0.165061885880015,0.872133628932243,0.460583876308333,0.165061885880014,0.723208517105129,0.670614654340578,-0.165061885879996,-0.524997939995877,-0.834944151922645,-0.31966097319577,-0.504370685985667,-0.802139061094696,0.31966097319577,0.504370685985667,0.802139061094696,0.165061885879996,0.524997939995877,0.834944151922645,-0.588320272074904,-0.430432186262926,-0.684549041701636,0.588320272074904,0.430432186262926,0.684549041701636,0.588320272074894,0.592939894476501,0.549819551311081,-0.783622247195285,-0.33068439569854,-0.525912544195423,-0.783622247195286,-0.455532780652123,-0.422405089282734,0.783622247195285,0.33068439569854,0.525912544195423,-0.783622247195289,-0.183300415659926,-0.593579928332742,-0.588320272074911,-0.238591235878361,-0.772627646171, +0.588320272074911,0.238591235878361,0.772627646171,0.783622247195289,0.183300415659926,0.593579928332742,0.783622247195286,0.455532780652123,0.422405089282734,-0.783622247195284,-0.549337359407769,-0.290111425592845,0.783622247195284,0.549337359407769,0.290111425592845,0.783622247195289,0.605705504942662,0.138047147680636,-0.319660973195767,-0.0357282964404113,-0.94685814726864,-0.319660973195767,-0.279575805784721,-0.905347574711149,0.319660973195767,0.0357282964404113,0.94685814726864,0.319660973195767,0.279575805784721,0.905347574711149,-0.16506188587999,-0.0371894770095988,-0.985581816304204,-0.165061885879985,-0.291009620876019,-0.942373585361633,0.16506188587999,0.0371894770095988,0.985581816304204,0.165061885879985,0.291009620876019,0.942373585361633,-0.165061885879996,0.219165068256504,-0.961624275216605,0.165061885879996,-0.219165068256504,0.961624275216605,-0.165061885879997,0.460583876308328,-0.872133628932249,0.165061885879997,-0.460583876308328,0.872133628932249,-0.165061885880001,-0.9616242752166,-0.21916506825652,0.165061885880001,0.9616242752166,0.21916506825652,-0.165061885879998,-0.985581816304202,0.0371894770096061,0.165061885879998,0.985581816304202,-0.0371894770096061,-0.319660973195764,-0.905347574711148,0.279575805784728,-0.165061885879992,-0.942373585361628,0.29100962087603,0.165061885879992,0.942373585361628,-0.29100962087603,0.319660973195764,0.905347574711148,-0.279575805784728,-0.31966097319576,-0.802139061094706,0.504370685985658,-0.588320272074911,-0.684549041701634,0.43043218626292,0.31966097319576,0.802139061094706,-0.504370685985658,0.588320272074911,0.684549041701634,-0.43043218626292,-0.58832027207491,-0.549819551311075,0.592939894476491,-0.319660973195767,-0.644266096062121,0.69479353744865,0.319660973195767,0.644266096062121,-0.69479353744865,0.58832027207491,0.549819551311075,-0.592939894476491,-0.165061885879989,-0.670614654340588,0.723208517105126,-0.165061885879982,-0.834944151922651,0.524997939995872,0.165061885879982,0.834944151922651,-0.524997939995872,0.165061885879989,0.670614654340588,-0.723208517105126, +-0.165061885879998,-0.460583876308329,0.872133628932248,-0.319660973195775,-0.442487461282975,0.837867357535116,0.319660973195775,0.442487461282975,-0.837867357535116,0.165061885879998,0.460583876308329,-0.872133628932248,-0.165061885879999,-0.219165068256502,0.961624275216605,-0.319660973195774,-0.2105540372625,0.923841901846843,0.319660973195774,0.2105540372625,-0.923841901846843,0.165061885879999,0.219165068256502,-0.961624275216605,-0.319660973195772,0.035728296440418,0.946858147268638,-0.16506188588,0.0371894770096059,0.985581816304202,0.16506188588,-0.0371894770096059,-0.985581816304202,0.319660973195772,-0.035728296440418,-0.946858147268638,-0.588320272074903,0.0304906870593461,0.808052953381374,-0.588320272074903,-0.179687751694519,0.788410787189445,0.588320272074903,-0.0304906870593461,-0.808052953381374,0.588320272074903,0.179687751694519,-0.788410787189445,-0.783622247195286,0.0234248152123419,0.620795821291411,-0.78362224719528,-0.138047147680633,0.605705504942676,0.783622247195286,-0.0234248152123419,-0.620795821291411,0.78362224719528,0.138047147680633,-0.605705504942676,-0.783622247195287,0.183300415659938,0.593579928332742,0.783622247195287,-0.183300415659938,-0.593579928332742,-0.588320272074904,0.238591235878368,0.772627646171002,0.588320272074904,-0.238591235878368,-0.772627646171002,-0.319660973195773,0.279575805784725,0.905347574711145,0.319660973195773,-0.279575805784725,-0.905347574711145,-0.16506188588,0.291009620876022,0.942373585361629,0.16506188588,-0.291009620876022,-0.942373585361629,-0.783622247195281,-0.290111425592862,0.549337359407764,-0.909402416903603,-0.194229024849993,0.367780274125333,0.909402416903603,0.194229024849993,-0.367780274125333,0.783622247195281,0.290111425592862,-0.549337359407764,-0.909402416903601,-0.282799370674219,0.304978294434465,0.909402416903601,0.282799370674219,-0.304978294434465,-0.783622247195286,-0.422405089282742,0.455532780652117,0.783622247195286,0.422405089282742,-0.455532780652117,-0.588320272074905,-0.377620767118445,0.715039728760988,0.588320272074905,0.377620767118445,-0.715039728760988, +-0.783622247195289,-0.525912544195406,0.330684395698558,0.783622247195289,0.525912544195406,-0.330684395698558,-0.9094024169036,-0.352097406735035,0.221392547978367,0.9094024169036,0.352097406735035,-0.221392547978367,1,-3.43018549036218e-16,-1.44154998700899e-15,1,-3.38948837437484e-16,-1.43515472592526e-15,1,-3.43599936407466e-16,-1.43835235646713e-15,1,-3.45053404835586e-16,-1.43544541961089e-15,-1,3.3829477664483e-16,1.43021293326966e-15,-1,3.42146467979347e-16,1.42905015852716e-15,-0.978227201428169,0.0969175220645334,-0.183517128091313,-1,3.43018549036218e-16,1.43137570801215e-15,1,-3.40111612179979e-16,-1.43253848275465e-15,1,-3.40692999551227e-16,-1.4319570953834e-15,0.978227201428169,-0.0969175220645334,0.183517128091313,1,-3.43018549036218e-16,-1.43137570801215e-15,-0.909402416903602,0.194229024849974,-0.367780274125346,0.909402416903602,-0.194229024849974,0.367780274125346,0.783622247195285,-0.290111425592854,0.549337359407764,0.978227201428168,-0.046117409729502,0.20234803410425,1,-3.42146467979347e-16,-1.42905015852716e-15,1,-3.3829477664483e-16,-1.43021293326966e-15,-1,3.41129040079663e-16,1.43137570801215e-15,1,-3.41129040079663e-16,-1.43137570801215e-15,-1,3.40692999551227e-16,1.43021293326966e-15,1,-3.40692999551227e-16,-1.43021293326966e-15,-1,3.39530224808731e-16,1.4331198701259e-15,1,-3.39530224808731e-16,-1.4331198701259e-15,-1,3.48251035377449e-16,1.43166640169778e-15,1,-3.48251035377449e-16,-1.43166640169778e-15,-1,3.45925485892458e-16,1.43428264486839e-15,1,-3.45925485892458e-16,-1.43428264486839e-15 + } + } + LayerElementUV: 0 { + Version: 101 + Name: "" + MappingInformationType: "ByPolygonVertex" + ReferenceInformationType: "IndexToDirect" + UV: *1104 { + a: -2.22889623194163,4.94485515491462,-1.65532570962361,4.65821409340907,-1.62796211820158,4.96642249187613,-2.24306066914648,4.78531474814698,-1.31169613420979,4.54828603161074,-1.85004675285953,4.9659513258978,-1.87466767619684,4.65751171567376,-1.27687689050803,4.98448551156268,-1.45766789804671,4.53353072855837,-0.889963003741073,4.98443414474227,-1.4292987059451,4.97019714011507,-0.924708026273064,4.44962919667924,-1.44525477991645,4.48294825241775,-1.04644017978781,3.8775148106018,-0.912703262391721,4.39649263863384,-1.55445051571418,4.05920463025229,-1.08390899890427,3.73069212186255,-0.488017212233791,4.20359291564793,-0.993295458288041,4.25890868286803,-0.589083484320281,3.61444389540074,-1.25080975782689,2.88453078525124,-0.592011030540132,3.2649337546265,-1.08371486396208,3.39374866151616,-0.778381167859173,2.69697501375937,-1.26843623354287,2.50066166193389,-1.10170560183738,1.75841973463844,-0.810358053931659,2.28036567603564,-1.52965129887146,2.0326977330795,-0.756478826537806,1.16706793759619,-0.158670374706782,1.66907965324611,-0.640695288818692,1.75350218949911,-0.27853831339099,1.06195824087441,-0.873447352754612,0.509260656289733,-0.616888748616979,-0.228010250754166,-0.409070522775316,0.354893100662368,-1.07418434426864,-0.0537807450739496,-1.19968265309827,1.47385216967798,-1.95941762780769,1.43480155652716,-1.62403250532483,1.05285553984945,-1.57895595868322,1.81225680869685,-2.46687340140469,1.54265387630344,-1.75972572971534,1.26218221533127,-1.96389112486465,1.72767381725588,-2.32072956280456,1.05581928583351,-2.0923002773467,2.49936022250465,-2.74835698931326,2.11424754695656,-2.16242989720341,1.9959242519408,-2.61762813661115,2.60544598660188,-2.52562147471714,1.87510429896511,-1.75478157341256,1.99837860402144,-2.27388900921938,2.29475409137111,-1.98820191135258,1.56827381645454,-1.045639024034,4.15103601984352,-1.24747268086553,3.3969445912353,-0.804176291476906,3.60422096134773,-1.49745329633863,3.96304919638554,-0.618570676409607,5.04994580240541,-0.95845404861963, +4.34718695256748,-0.484114746414191,4.46750905708385,-1.09765307025877,4.95016984159444,-0.35533492387025,4.97487847515973,-0.92194049909082,5.51185969443965,-0.838721681199577,4.89863921171472,-0.435718129304659,5.56720397663318,-1.34127683622845,4.84975436654454,-2.01801605485789,5.19723992329904,-1.80389190776427,4.63915228766901,-1.53325529451148,5.35012205197071,-2.36477929387487,4.41774245284113,-2.14234361130184,5.10776064453118,-2.63239632489642,4.88207495630249,-1.92383522047472,4.72863474304139,-2.37717816704592,3.96128867075657,-2.33429830925958,4.68500412281015,-2.75237403305638,4.34397863821338,-2.02795216748382,4.37253907282631,-2.34322017071274,3.36906477346162,-2.51993652923386,4.07218216506558,-2.81612296149711,3.62122840988015,-2.13381301744724,3.86629141809554,-2.19163392047984,2.80366220122301,-2.60247008775086,3.4010032942402,-2.72278826409501,2.87506676915957,-2.16878438224418,3.34270170865737,-1.89659198856349,2.50354292776006,-2.49717322903895,2.9096277850668,-2.41714446038247,2.37607264437374,-2.07214391560527,3.01370683562161,-1.98825946489989,2.32011059641698,-1.87818009582411,3.03668946175474,-2.24332048375329,2.79553626740469,-1.5410556474457,2.61546173441691,-1.67758466916924,3.38523073639064,-1.57863949665124,2.66702979613766,-1.23429135805069,3.07769743365709,-1.95874374698541,3.04992201445835,-1.98286003082015,4.12761713707628,-1.85395747307113,3.45855075975768,-1.53996076732831,3.7633268001955,-2.20488923072113,3.91210793213952,-2.24790113597453,4.67066355102173,-2.03248037919708,4.0667263524964,-1.79935117333211,4.27017648494638,-2.36857769286949,4.56535001300834,-2.48768304529302,5.01047202570287,-2.15758872394683,4.48940057601292,-2.03455899018573,4.59195523111738,-2.44783267929821,5.03424234042376,-2.26420622604591,4.44537984175963,-2.1187848071206,4.51250944469802,-2.40119966215701,5.05091965038177,-2.37695466226219,4.43456756216669,-2.21908245443667,4.46158864040594,-2.48759111054218,4.4575298421717,-2.32812557931018,4.44254595009331,-2.35064173386826,5.05896361649403,-2.40959556766724, +3.98252386277456,-2.28372359474004,4.6112547182641,-2.44138044684132,4.58300423758795,-2.10502591739512,4.03709960055488,-2.42776055812635,3.31262575806233,-2.17284671645101,3.94451547943369,-2.47629947400164,3.88403732671662,-1.99861355285874,3.39815478186207,-2.22912087104751,4.07302449588468,-2.66239099160617,3.54715123236623,-2.22739993984036,3.49955763063257,-2.53670599350658,4.10667825441164,-2.28958836354591,4.64689559985362,-2.58166901012707,4.07607589267285,-2.27373466503919,4.04578361417724,-2.44898690984574,4.66257603704207,-2.43380750929313,4.76906997404341,-2.43196560428483,4.12786575571735,-2.28459604282649,4.71084874983961,-2.72022002236202,4.24034052391062,-2.40064397200227,4.87682613910774,-2.56937502559178,4.25821796443836,-2.27228666802239,4.78102334589199,-2.81734229540576,4.4432947488338,-2.35823198753783,4.96096550711088,-2.68169423833576,4.40732445505467,-2.25912867100951,4.83513901814291,-2.87314714414696,4.65040256570554,-2.31601009387183,5.00378217844692,-2.76905262482946,4.55002155063012,-2.25197560134424,4.85697156425419,-2.89275776504091,4.83363787827438,-2.28162308717413,4.99804618701356,-2.83315828124115,4.67100617123774,-2.25605270670399,4.8399325306915,-2.88255646300942,4.97645829949867,-2.27391280605285,4.78805388592849,-2.84748332837086,5.07469494743408,-2.8748469197929,4.76648654896698,-2.25974836884799,4.94759429269615,-2.7796535222291,4.84625786888993,-2.16325880607624,4.86939378395309,-2.76482997098292,5.00573838494556,-2.77736805920925,4.94780238684663,-2.17581562300948,4.81137517852988,-2.72196283598472,5.09808223883072,-2.74796782751268,5.0443789277376,-2.20199490274563,4.75734011139339,-2.6556589984355,5.17527145138702,-2.69270336452733,5.13135107250885,-2.23957930942005,4.71283427792336,-2.56967363076624,5.2339057276133,-2.61447831571456,5.20416675632401,-2.28543044353695,4.68243386059827,-2.46905689678925,5.27129635926241,-2.51794655146868,5.25832080537305,-2.33582934374834,4.66898979539721,-2.36007434364315,5.28534188361228,-2.4094074335959,5.28959680532676,-2.38689127903784, +4.67317913892605,-2.24994190236392,5.27461291324839,-2.43498022170874,4.69349452707607,-2.14634329996243,5.23862427683461,-2.29642625060153,5.29456067464838,-2.47703388500934,4.72668131068946,-2.05678500209208,5.17819940896878,-2.18720313520701,5.27117727315017,-2.5107341447143,4.7684943663624,-1.98790995971785,5.09580551534724,-2.08980713242066,5.21938034639342,-2.53451280785768,4.81455369054366,-1.94489964164528,4.99575532104397,-2.01143024265092,5.14145175820956,-2.54744055705391,4.8610673277229,-1.93104593233932,4.8842056787863,-1.9577835203924,5.04212614629453,-2.22547647670406,4.84487736501279,-1.67394128263705,5.17191738078863,-2.25104685717419,5.00299102133485,-1.62454310086877,4.86646525252767,-1.77054263776738,5.32311526774572,-2.22358516872501,4.8693546399289,-1.64683749755594,5.03949894010147,-2.28761966125261,5.01616525412165,-1.91133392574998,5.40794480188922,-2.23479617654793,4.85430374983299,-1.71988101993878,5.16486669123834,-2.33389949307624,4.98013023880097,-2.08502914234847,5.42445342740957,-2.25376019593798,4.80584525274021,-1.83706187253447,5.23937664301415,-2.38211749991785,4.90164804595595,-2.27517904975131,5.3809076808036,-2.273337144743,4.73970346247755,-1.98692463167413,5.26843291261033,-2.42254861120966,4.79792468668137,-2.46180830446977,5.29451272645808,-2.28655605966322,4.67772030359326,-2.15387395938188,5.26422044796245,-2.44595460596304,4.69340074078169,-2.32097158959223,5.24222298566723,-2.44684356251943,4.6134921301777,-2.28918671041814,4.64174261085383,-2.62554123986435,5.18764724788692,-2.28545905310624,4.83741927871761,-2.5403728947816,4.20552955734626,-2.23692013723097,4.26600771006331,-2.71460605837386,4.75189025491787,-2.17082275097528,3.41668320237549,-2.77140399145076,3.82276805968224,-2.59585206440898,3.3126041518207,-2.25085151963176,3.95023834306856,-2.54719352119047,3.81218691003919,-1.99318963933964,4.27982184953699,-2.52434398295481,4.35122641747356,-2.11350781568378,3.75388532445638,-2.0466179646026,2.72557522660391,-2.50181620401035,3.335096961265,-2.57194582386704, +2.83166099070115,-1.91588911190049,3.21677366624924,-1.69053709416644,3.73240237092782,-1.81576780340595,4.48276191917622,-2.10882607130355,4.06745144295913,-1.34922707134059,4.10906323743435,-1.63699768318943,4.9366358162398,-0.902314343723609,4.73924642215917,-1.22902064529844,5.23982004503893,-1.34408082659468,4.48783378395151,-0.208746171416185,4.52025754034199,-0.822284495260748,5.00291832485256,-0.68782856526534,4.42048157953102,-0.347945193055325,5.12324042936896,-0.642890652119008,5.53908904418414,-0.0762850768984617,5.00210782490419,-0.159503894789691,5.61532830762913,-0.562507446684621,4.94676354271067,-1.31778856071161,5.43279120221954,-0.641049342082162,5.08530564546506,-0.855173489175781,5.6433932810951,-1.12581010242858,4.93242351679339,-1.34194485208158,5.62582386308317,-1.5643805346546,4.93580567139316,-1.07432782106004,5.16149135962184,-1.78288892548172,5.31493157288294,-1.46212322710947,5.00598750369212,-1.09828806154708,5.63306541754739,-1.5951760536539,5.42285596183071,-0.935332294612625,5.12250791139725,-1.47861587915348,5.29986363509297,-0.887856331859623,4.87961859344933,-0.950839776140141,5.41183719027776,-1.42719011224338,4.86530897047641,-1.33645439480956,5.29975485065767,-1.84665831993718,4.84813815318422,-1.27349005033672,4.86672152934463,-1.89118083488689,5.15433895116442,-1.46949920272772,5.49385724815895,-1.86367746000996,4.93807924559101,-1.30974093298399,5.08647577915134,-1.97664361589637,5.22614144485602,-1.67256859028094,5.54902519134055,-1.92179091550383,4.91486912280303,-1.41968071687419,5.19191163863482,-2.1006096456696,5.16738653757487,-1.93403225509439,5.46626914557294,-2.01064813702936,4.78921989087443,-1.59734066748949,5.18676755187731,-2.24872504179326,4.98685736312906,-2.2261365557266,5.26857783977936,-2.11038123927247,4.597111985573,-1.82472148668125,5.09437018097639,-2.3942245566649,4.7202954024472,-2.50277253822791,5.00601537349182,-2.1934664845617,4.39889474971273,-2.06778148646211,4.95842177175816,-2.50105160702078,4.43254850823971,-1.93860505757275,4.2323806382509, +-2.11532141609385,4.93549802985484,-2.32472856935935,4.43827138522094,-1.6424186253095,4.68333439343629,-1.73169958771977,4.66299022826429,-1.68881972993344,5.38670568031787,-2.03804572949552,4.97545527824815,-1.31362386392297,5.00401571286104,-0.464309147812425,4.89789858084395,-1.01461627175572,5.42314542902244,-0.972526026312951,4.8888683845015,-0.511254716534029,5.49380719211677,-2.10206131703644e-14,4.91059740631861,-0.50600215446225,5.50503203469246,-0.489352270236512,4.90750903030939,-0.0172372285455016,5.52919874000346,-0.0186528372538131,5.13595913794231,-0.55211223489019,5.70588174567411,-0.507315590943606,5.10980774011539,-0.0650297356940315,5.75306035765887,-1.12277289479413,5.58899145234874,-0.508686021165608,5.13997085836523,-0.632919485865296,5.72467335165596,-1.01138821752192,5.06476153834877,-0.498495478860586,4.35754189766298,-2.10263122664281e-14,4.95828557452188,-0.489352456798956,4.95522690212541,-0.00946555295739218,4.33951652601362,-0.535225989357954,3.50165081582426,-0.0100338758116794,4.07920077175808,-0.499022710753649,4.09830840777293,-0.047514267803472,3.46149537895279,-0.610467942429473,2.4062800587474,-0.0543506220534413,2.95411601385456,-0.541552163256598,3.00004901616492,-0.125697486685512,2.33940115557327,-0.464938495449079,4.97189499302442,-0.996313489444281,4.4275028568388,-0.490766636123596,4.3746983197576,-0.973156612023798,4.96293474615021,-0.793597366882633,4.27385807666868,-0.995431023714121,3.51976664806043,-0.543616751409509,3.70775347151846,-1.23689375627126,4.06658170655621,-2.14412933971546,2.5432952001497,-1.85844224184875,1.8168149252331,-1.60670977635094,2.23646471763909,-2.37754967765554,2.11319041258284,-1.7283748481451,-0.0101041227135874,-1.79733334736392,-0.787687194234479,-1.38301966877687,-0.356810024791312,-2.15730393080435,-0.456180992920636,-2.54654609715617,1.7592464969741,-2.18970765921626,2.43110102839648,-2.75071149230548,2.22473809889872,-2.04356382061612,1.94426643792655,-2.50122950794384,1.93703938375925,-1.74149453323444,1.97608999691007,-2.07687965571729, +2.3580360135878,-2.12195620235891,1.5986347447404,-1.8978950622664,2.88742325710794,-1.73116443056091,2.1451813298125,-1.46994936523233,2.6131452586669,-2.18924261017214,2.36547731571075,-0.435583296967275,1.71300559168247,-1.03339174879829,1.21099387603254,-0.551366834686384,1.12657133977956,-0.9135238101141,1.81811528840424,-0.676517274141788,0.439050630128865,-1.34163109563509,0.0303767843925122,-0.877254265655787,-0.123990771234836,-1.13381286979346,0.613280135809055,-0.889992095826276,2.4281089902429,-0.333874775450249,2.97594494535007,-0.818645231194206,3.04282384852419,-0.402790554623101,2.38217598793254,-0.815527103995951,3.50809594694279,-0.290334990449654,4.08564590287661,-0.778046712004154,4.12580133974808,-0.326538269053973,3.48898831092795,-0.769335313287053,4.97005439871802,-0.289448409445488,4.35434402260621,-0.280305387383851,4.95202902706866,-0.778800866244429,4.35128535020975,-1.22687945867549,4.43747459739706,-1.7092694345757,5.02571102378968,-1.73509757525022,4.42851435052282,-1.20372258125502,4.97290648670846,-1.87167756385307,4.56042796505358,-2.37626824352512,5.08099590848939,-2.4110132660571,4.54619096042637,-1.84330837175146,4.99709437661026,-2.20144321485349,4.68359628853357,-2.73979383350324,5.10126158282064,-2.774613077205,4.66506210286872,-2.17682229151618,4.99203589875765,-2.72578839489266,4.65555299162875,-2.21558446976503,5.1071696891022,-2.78875273936549,5.08858631294181,-2.17106195481533,4.80096889112202,-2.67600861707014,4.55068174377684,-2.28183035978791,5.10645974634478,-2.83576688681387,4.95806321278444,-2.16886420390148,4.81839754707977,-2.61736088578222,4.343781432873,-2.36813856055932,4.97793750141052,-2.87024875918897,4.70089498557874,-2.18931983039356,4.72542008663868,-2.53472742699818,4.05757815411518,-2.45811154506318,4.73462740881368,-2.87141901460307,4.3370797478108,-2.22003464029931,4.53698993655903,-2.40897558916315,3.74811248771928,-2.52473090561731,4.41957834192562,-2.81039065820851,3.92232014652225,-2.24088758822486,4.29639492505141,-1.99041499686435,5.29670667534019, +-2.35425016242674,4.66962876148492,-1.85736217031991,4.87983821720161,-2.51720592936118,5.18018626763507,-1.83919760059389,4.81655146587154,-2.42995714788773,5.23679650751519,-2.36697370360721,4.70457791068675,-1.89062336750397,5.25110613048811,-1.75290182391405,5.39599046568453,-1.20259469997074,4.87074361750605,-1.24468494541351,5.405020662027,-1.70595625519243,4.80008185441171,-0.786364016638015,5.5077671434244,-0.280361862175763,4.91333251505055,-0.297011746401518,5.51085551943361,-0.769126788092523,4.88916580973956,-0.832291384196014,5.6953984791651,-0.298831986559639,5.12547587143331,-0.34362863050621,5.72154987699202,-0.7859144857558,5.07829725944853,-1.23713042793988,5.01679742454565,-1.85121730156838,5.46581801852916,-1.72698383686871,4.88111552523843,-1.34851510521207,5.54102733854561,-2.26021837837495,4.49908574052134,-2.69077110092187,5.02718614741373,-2.82285760978999,4.61001050069242,-2.16681911225105,4.79407346926384,-2.30503228079787,4.71494219743632,-2.78983777542851,5.1345966679107,-2.89261517886931,4.8427439852725,-2.25183078196454,4.86601626269838,-2.34566181457487,4.64096981285004,-2.70935440349547,5.16905497925544,-2.88222282199724,4.91242744194534,-2.25617853656485,4.77381000115726,-2.63592854153308,4.9137985432017,-2.34197108134981,4.29909967525491,-2.18167829132095,4.56376437725711,-2.86261677914252,4.53950613214877,-2.36023168911256,4.38176079777179,-2.0935304547959,3.70761453073558,-1.90006023744783,4.10010865940705,-2.59718334557664,3.90105562663007,-1.3029926386607,3.46570253076949,-1.96179136594745,3.08529956139423,-1.47008753252554,2.95648465450457,-1.77542122862843,3.65325830226138,-1.81664617257089,3.82502760239206,-1.22075438590042,4.29792839617742,-1.71557990048438,4.41417662263925,-1.31136792651664,3.76971183517196,-1.95620790020104,4.16273466803086,-2.3550225003297,4.76816810984681,-2.48875941772578,4.24919028181478,-1.84701216440332,4.58647829019633,-2.27665473861468,3.31649295457305,-2.37559991113266,4.03469389482605,-2.71994804973322,3.62402625730662,-1.99549566079849,3.65180167650533, +-2.43320989445663,4.14733618749371,-2.56211245220563,4.8164025648123,-2.87610915794846,4.51162652437447,-2.21118069455564,4.36284539243048,-2.38894336548321,4.58868660672863,-2.60436412226067,5.19262380525396,-2.83749332812565,4.98917367280397,-2.26826680858825,4.69400014474201,-2.42575833280846,4.57671890911988,-2.47398860892248,5.21610930839029,-2.75258070362274,5.08147042919237,-2.28154845296159,4.64641312141524,-2.45065406931533,4.78365282838732,-2.50982919893599,4.10485684233049,-2.23728636374273,4.25135457612174,-2.83608784317326,4.57647374640281,-2.36188190489788,3.85830995326938,-2.47196127397366,3.14173108793161,-2.10682088604448,3.38288428228168,-2.80908572235207,3.56295881526947,-2.54907953544303,4.90525542708686,-1.94750837053634,4.7689108260944,-1.93268481929016,4.92839134215002,-2.53937779057482,4.94541339312765,-1.99323057759957,4.6587063328268,-1.93782535437505,4.8089861848109,-2.51865458125749,4.9806567938471,-2.06499048556762,4.56272545385347,-1.97268165649043,4.69361797750288,-2.21984061700633,3.97913522300632,-2.26807089312034,4.61852562227672,-2.41228077296721,4.54883140998136,-1.94124852230607,4.11377410220423,-2.1412548523071,3.28381379586486,-2.08207972268643,3.96260978192169,-2.3546225578797,3.81611204813045,-1.75582107844915,3.49099287784934,-1.86679713463842,4.22842043895693,-2.23048972355902,4.75650560536233,-2.31997300156904,4.62366541705513,-1.69392871613665,4.48504797626704,-1.60732250455001,3.7792437319894,-1.90127996473328,4.3939425999362,-2.06157275476215,4.12927789793399,-1.38063426694058,4.15353614304234,-1.26122971005605,3.24253051415007,-1.52793094437272,3.91667678118628,-1.72140116172079,3.52418265251479,-1.02427805359199,3.72323568529178,-1.85429513426101,4.69512186095512,-1.42374241171412,4.1670214540627,-1.29165590284599,4.58419710078401,-1.94769440038493,4.40013413221259,-2.22261587748422,4.85572808581025,-1.73781038285358,4.43607361533587,-1.63503297941277,4.72792629797409,-2.27581737631754,4.70465402054817,-2.78178857530579,4.9026134658953,-2.75505098725269,4.74469299838705, +-2.16539395059119,4.92575181695869,-2.77165216069373,4.79430516980301,-2.7051215596881,4.64860873263743,-2.18203899448134,4.97550680030333,-2.73460186390027,4.6876963492945,-2.63270469119746,4.56412151824832,-2.21177767890383,5.01500749827934,-2.67234753282292,4.59067522908493,-2.54192939970797,4.49769736490354,-2.25209864990566,5.04219332736425,-2.58829389308936,4.51145059440195,-2.43821094245027,4.4555141965882,-2.29965697134306,5.05658034416049,-1.83481485493309,3.55228010821303,-2.59441385489603,3.51066831373777,-2.12787312283065,3.13696963199592,-2.25310383207023,3.88732918024431,-1.83025938021036,4.81050089545325,-1.94531956150656,4.05851463436584,-1.5373425236156,4.36169886316497,-2.27202586308141,4.55908825724562,-1.17375323363792,-0.543405345489913,-1.94803749566539,-0.642776313619184,-1.60268231629717,-0.989482215696929,-1.53372381707832,-0.211899144176031 + } + UVIndex: *1584 { + a: 0,1,2,1,0,3,2,1,0,4,5,6,5,4,7,7,4,5,8,9,10,9,8,11,11,8,9,12,13,14,13,12,15,14,13,12,16,17,18,17,16,19,19,16,17,20,21,22,21,20,23,23,20,21,24,25,26,25,24,27,26,25,24,28,29,30,29,28,31,31,28,29,32,33,34,33,32,35,34,33,32,35,32,33,36,37,38,37,36,39,38,37,36,40,41,42,41,40,43,43,40,41,44,45,46,45,44,47,46,45,44,48,49,50,49,48,51,51,48,49,50,49,48,52,53,54,53,52,55,55,52,53,56,57,58,57,56,59,59,56,57,60,61,62,61,60,63,62,61,60,63,60,61,64,65,66,65,64,67,66,65,64,67,64,65,68,69,70,69,68,71,71,68,69,72,73,74,73,72,75,75,72,73,76,77,78,77,76,79,79,76,77,80,81,82,81,80,83,82,81,80,83,80,81,84,85,86,85,84,87,86,85,84,87,84,85,88,89,90,89,88,91,91,88,89,39,36,37,27,24,25,92,93,94,93,92,95,94,93,92,95,92,93,96,97,98,97,96,99,98,97,96,99,96,97,100,101,102,101,100,103,102,101,100,103,100,101,104,105,106,107,108,109,110,111,112,113,114,115,115,114,113,112,111,110,116,117,118,117,116,119,119,116,117,120,121,122,121,120,123,123,120,121,122,121,120,124,125,126,125,124,127,126,125,124,127,124,125,128,129,130,129,128,131,130,129,128,131,128,129,132,133,134,133,132,135,134,133,132,135,132,133,136,137,138,137,136,139,138,137,136,139,136,137,140,141,142,141,140,143,142,141,140,143,140,141,144,145,146,145,144,147,146,145,144,147,144,145,148,149,150,149,148,151,150,149,148,151,148,149,152,153,154,153,152,155,155,152,153,156,157,158,158,157,156,159,160,161,161,160,159,162,163,164,164,163,162,165,166,167,167,166,165,168,169,170,170,169,168,171,172,173,173,172,171,174,175,176,176,175,174,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,191,190,189,192,193,194,193,192,195,195,192,193,194,193,192,196,197,198,197,196,199,198,197,196,199,196,197,200,201,202,201,200,203,202,201,200,203,200,201,204,205,206,205,204,207,206,205,204,207,204,205,208,209,210,209,208,211,210,209,208,211,208,209,212,213,214,213,212,215,214,213,212,215,212,213,216,217,218,217,216,219,218,217,216,219,216,217,220,221,222,221,220,223,222,221,220,223,220,221,224,225,226,225,224,227,227,224,225,228,229,230,229,228,231,230,229,228,232,233,234, +233,232,235,235,232,233,236,237,238,237,236,239,239,236,237,240,241,242,241,240,243,242,241,240,244,245,246,245,244,247,247,244,245,246,245,244,248,249,250,249,248,251,251,248,249,252,253,254,253,252,255,255,252,253,256,257,258,257,256,259,258,257,256,260,261,262,261,260,263,263,260,261,264,265,266,265,264,267,267,264,265,268,269,270,269,268,271,270,269,268,271,268,269,272,273,274,273,272,275,274,273,272,275,272,273,276,277,278,277,276,279,278,277,276,279,276,277,280,281,282,281,280,283,282,281,280,283,280,281,284,285,286,285,284,287,286,285,284,287,284,285,288,289,290,289,288,291,290,289,288,291,288,289,231,228,229,292,293,294,293,292,295,295,292,293,296,297,298,297,296,299,299,296,297,259,256,257,298,297,296,243,240,241,254,253,252,294,293,292,238,237,236,262,261,260,266,265,264,300,301,302,301,300,303,302,301,300,303,300,301,304,305,306,305,304,307,306,305,304,307,304,305,308,309,310,309,308,311,310,309,308,312,313,314,313,312,315,315,312,313,314,313,312,311,308,309,316,317,318,317,316,319,319,316,317,320,321,322,321,320,323,323,320,321,324,325,326,325,324,327,327,324,325,30,29,28,326,325,324,322,321,320,318,317,316,328,329,330,329,328,331,330,329,328,18,17,16,331,328,329,10,9,8,250,249,248,332,333,334,333,332,335,334,333,332,335,332,333,336,337,338,337,336,339,338,337,336,339,336,337,340,341,342,341,340,343,343,340,341,342,341,340,344,345,346,345,344,347,346,345,344,347,344,345,234,233,232,348,349,350,349,348,351,350,349,348,351,348,349,352,353,354,353,352,355,355,352,353,356,357,358,357,356,359,359,356,357,360,361,362,361,360,363,363,360,361,362,361,360,358,357,356,364,365,366,365,364,367,367,364,365,368,369,370,369,368,371,371,368,369,372,373,374,373,372,375,375,372,373,374,373,372,376,377,378,377,376,379,378,377,376,379,376,377,380,381,382,381,380,383,382,381,380,383,380,381,384,385,386,385,384,387,387,384,385,154,153,152,386,385,384,388,389,390,389,388,391,391,388,389,392,393,394,393,392,395,395,392,393,396,397,398,397,396,399,399,396,397,400,401,402,401,400,403,403,400,401,404,405,406,405,404,407,407,404, +405,406,405,404,402,401,400,398,397,396,394,393,392,408,409,410,409,408,411,410,409,408,70,69,68,411,408,409,412,413,414,413,412,415,414,413,412,416,417,418,417,416,419,419,416,417,420,421,422,421,420,423,423,420,421,422,421,420,424,425,426,425,424,427,427,424,425,426,425,424,428,429,430,429,428,431,430,429,428,431,428,429,418,417,416,415,412,413,390,389,388,432,433,434,433,432,435,435,432,433,436,437,438,437,436,439,439,436,437,438,437,436,440,441,442,441,440,443,443,440,441,442,441,440,444,445,446,445,444,447,446,445,444,447,444,445,448,449,450,449,448,451,450,449,448,451,448,449,452,453,454,453,452,455,454,453,452,456,457,458,457,456,459,459,456,457,458,457,456,460,461,462,461,460,463,463,460,461,434,433,432,462,461,460,455,452,453,464,465,466,465,464,467,467,464,465,468,469,470,469,468,471,471,468,469,472,473,474,473,472,475,475,472,473,474,473,472,476,477,478,477,476,479,479,476,477,478,477,476,480,481,482,481,480,483,482,481,480,483,480,481,484,485,486,485,484,487,486,485,484,487,484,485,226,225,224,470,469,468,466,465,464,354,353,352,370,369,368,366,365,364,179,178,177,182,181,180,185,184,183,188,187,186,488,489,490,491,492,493,494,495,496,106,105,104,109,108,107,497,498,499,498,497,500,500,497,498,501,502,503,502,501,504,504,501,502,90,89,88,503,502,501,499,498,497,496,495,494,505,506,507,506,505,508,508,505,506,509,510,511,510,509,512,512,509,510,513,514,515,514,513,516,516,513,514,22,21,20,515,514,513,15,12,13,517,518,519,518,517,520,519,518,517,520,517,518,521,522,523,522,521,524,523,522,521,524,521,522,493,492,491,490,489,488,3,0,1,6,5,4,511,510,509,507,506,505,525,526,527,527,526,525,528,529,530,530,529,528,531,532,533,533,532,531,534,535,536,536,535,534,537,538,539,539,538,537,118,117,116,42,41,40,47,44,45,540,541,542,541,540,543,542,541,540,54,53,52,543,540,541,78,77,76,544,545,546,545,544,547,547,544,545,546,545,544,74,73,72,58,57,56,548,549,550,549,548,551,550,549,548,551,548,549 + } + } + LayerElementMaterial: 0 { + Version: 101 + Name: "" + MappingInformationType: "ByPolygon" + ReferenceInformationType: "IndexToDirect" + Materials: *528 { + a: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + } + } + Layer: 0 { + Version: 100 + LayerElement: { + Type: "LayerElementNormal" + TypedIndex: 0 + } + LayerElement: { + Type: "LayerElementMaterial" + TypedIndex: 0 + } + LayerElement: { + Type: "LayerElementTexture" + TypedIndex: 0 + } + LayerElement: { + Type: "LayerElementUV" + TypedIndex: 0 + } + } + } + Geometry: 140593608540656, "Geometry::", "Mesh" { + Vertices: *1008 { + a: 0.0473889631480167,0.154070788334118,-0.0601695113062539,0.0351296648165796,0.168961077675596,-0.0555713163617986,0.0351296648165797,0.153993426063857,-0.0581192849259026,0.0473889631480169,0.169566441524427,-0.0575316601434032,0.0351296648165797,0.153993426063857,-0.0581192849259026,0.0351296648165796,0.168961077675596,-0.0555713163617986,0.0473889631480167,0.154070788334118,-0.0601695113062539,0.0237058174069819,0.167186240674989,-0.0498238792060798,0.0237058174069821,0.153766611363948,-0.0521083253245107,0.0237058174069821,0.153766611363948,-0.0521083253245107,0.0237058174069819,0.167186240674989,-0.0498238792060798,0.0138959372413864,0.164362882731141,-0.0406810270203202,0.0138959372413867,0.153405801281358,-0.0425462694653327,0.0138959372413867,0.153405801281358,-0.0425462694653327,0.0138959372413864,0.164362882731141,-0.0406810270203202,0.00636855144148618,0.15293558442695,-0.0300847556531268,0.00636855144148645,0.160683411022106,-0.0287658300717016,0.00636855144148645,0.160683411022106,-0.0287658300717016,0.00636855144148618,0.15293558442695,-0.0300847556531268,0.0138959372413865,0.174463850415736,-0.0360434398124489,0.00636855144148618,0.167825873768429,-0.0254865607086716,0.00636855144148618,0.167825873768429,-0.0254865607086716,0.0138959372413865,0.174463850415736,-0.0360434398124489,0.0138959372413866,0.183020340080077,-0.0289495517459595,0.00636855144148643,0.173876225633237,-0.0204704243518788,0.00636855144148643,0.173876225633237,-0.0204704243518788,0.0138959372413866,0.183020340080077,-0.0289495517459595,0.0138959372413869,0.189449241093807,-0.0198827995693796,0.00636855144148609,0.178422145135622,-0.0140592624044813,0.00636855144148609,0.178422145135622,-0.0140592624044813,0.0138959372413869,0.189449241093807,-0.0198827995693796,0.0138959372413868,0.193312434477101,-0.00946106746002606,0.00636855144148636,0.181153835373984,-0.00668998495824788,0.00636855144148636,0.181153835373984,-0.00668998495824788,0.0138959372413868,0.193312434477101,-0.00946106746002606,0.00636855144148614,0.18188513617291,0.00113520390716734, +0.0138959372413868,0.194346649985116,0.00160542076157495,0.0138959372413868,0.194346649985116,0.00160542076157495,0.00636855144148614,0.18188513617291,0.00113520390716734,0.0237058174069819,0.203908705844294,0.00196623084416461,0.0237058174069818,0.202642055704939,-0.0115873938495568,0.0237058174069819,0.203908705844294,0.00196623084416461,0.0237058174069817,0.201624259725863,0.0153858601552059,0.0138959372413866,0.192481407540104,0.0125625022113576,0.0138959372413866,0.192481407540104,0.0125625022113576,0.0237058174069817,0.201624259725863,0.0153858601552059,0.0138959372413867,0.187843820332232,0.0226634698959533,0.0237058174069819,0.195944398577392,0.0277569685230063,0.0237058174069819,0.195944398577392,0.0277569685230063,0.0138959372413867,0.187843820332232,0.0226634698959533,0.0351296648165797,0.207371696881582,0.0171606971558129,0.0351296648165797,0.201036634943364,0.0309588756157758,0.0351296648165797,0.207371696881582,0.0171606971558129,0.0351296648165797,0.201036634943364,0.0309588756157758,0.047388963148017,0.202773501937127,0.0320509864972911,0.0473889631480167,0.209332040663187,0.017766061004644,0.047388963148017,0.202773501937127,0.0320509864972911,0.0351296648165799,0.191346203632937,0.0426472578644845,0.0473889631480168,0.192741229223541,0.0441516902269075,0.0351296648165799,0.191346203632937,0.0426472578644845,0.0237058174069818,0.187256195549733,0.0382364853565232,0.0237058174069818,0.187256195549733,0.0382364853565232,0.0351296648165797,0.17896078982991,0.0514292999676549,0.0237058174069818,0.176151737321288,0.0461102489017724,0.0237058174069818,0.176151737321288,0.0461102489017724,0.0351296648165797,0.17896078982991,0.0514292999676549,0.0351296648165797,0.164724439017097,0.0567065202689658,0.0237058174069819,0.16338777436934,0.0508416751851554,0.0237058174069819,0.16338777436934,0.0508416751851554,0.0351296648165797,0.164724439017097,0.0567065202689658,0.023705817406982,0.149834149675619,0.0521083253245109,0.0351296648165794,0.149607334975709,0.0581192849259028,0.0351296648165794,0.149607334975709,0.0581192849259028, +0.023705817406982,0.149834149675619,0.0521083253245109,0.0473889631480169,0.165180350436279,0.058706909708402,0.0473889631480167,0.149529972705449,0.0601695113062537,0.0473889631480167,0.149529972705449,0.0601695113062537,0.0473889631480169,0.165180350436279,0.058706909708402,0.0473889631480168,0.179918905328746,0.0532435292316779,0.0473889631480168,0.179918905328746,0.0532435292316779,0.0473889631480168,0.192741229223541,0.0441516902269075,0.0351296648165797,0.134639683363971,0.0555713163617988,0.0473889631480167,0.134034319515139,0.0575316601434032,0.0473889631480167,0.134034319515139,0.0575316601434032,0.0351296648165797,0.134639683363971,0.0555713163617988,0.0237058174069817,0.136414520364577,0.0498238792060799,0.0237058174069817,0.136414520364577,0.0498238792060799,0.0138959372413866,0.139237878308426,0.0406810270203202,0.0138959372413865,0.150194959758208,0.0425462694653325,0.0138959372413866,0.139237878308426,0.0406810270203202,0.0138959372413865,0.150194959758208,0.0425462694653325,0.00636855144148634,0.150665176612616,0.0300847556531268,0.00636855144148627,0.142917350017461,0.0287658300717016,0.00636855144148634,0.150665176612616,0.0300847556531268,0.0138959372413866,0.161261447979809,0.0415120539573175,0.00636855144148623,0.158490365478031,0.0293534548542012,0.0138959372413866,0.161261447979809,0.0415120539573175,0.0138959372413869,0.171683180089163,0.0376488605740236,0.0138959372413869,0.171683180089163,0.0376488605740236,0.00636855144148645,0.165859642924265,0.0266217646158389,0.00636855144148623,0.158490365478031,0.0293534548542012,0.00636855144148645,0.165859642924265,0.0266217646158389,0.00163663890995019,0.155263371557071,0.0151944663116486,0.00163663890994996,0.159077990260531,0.0137804393936313,0.00163663890995019,0.155263371557071,0.0151944663116486,0.00163663890994996,0.159077990260531,0.0137804393936313,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,0.00163663890994996,0.162396651886977,0.0114272983041907,0.00163663890994996,0.162396651886977,0.0114272983041907, +2.2671665947323e-05,0.151800380519783,-0,0.00636855144148623,0.172270804871662,0.0220758451134537,0.00636855144148623,0.172270804871662,0.0220758451134537,0.0138959372413865,0.180749932265743,0.0312199595602942,0.0138959372413865,0.180749932265743,0.0312199595602942,0.00636855144148623,0.177286941228455,0.0160254932486455,0.00636855144148623,0.177286941228455,0.0160254932486455,0.00163663890995005,0.164993195130915,0.00829540571982283,0.00163663890995005,0.164993195130915,0.00829540571982283,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,0.00163663890994992,0.166690669861262,0.00459819494445524,2.2671665947323e-05,0.151800380519783,-0,0.00163663890995003,0.167373395980353,0.000587624782499546,0.00163663890995012,0.166994846831432,-0.0034629910372879,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,0.00163663890995003,0.167373395980353,0.000587624782499546,0.00163663890995012,0.166994846831432,-0.0034629910372879,0.00163663890994992,0.166690669861262,0.00459819494445524,2.2671665947323e-05,0.151800380519783,-0,0.00636855144148625,0.180566210591485,0.00888303050232202,0.00636855144148625,0.180566210591485,0.00888303050232202,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,0.00163663890995012,0.165580819913414,-0.00727760974074707,0.00163663890995012,0.165580819913414,-0.00727760974074707,0.00163663890995005,0.163227678823974,-0.0105962713671934,0.00163663890995005,0.163227678823974,-0.0105962713671934,0.00163663890994999,0.160095786239606,-0.0131928146111317,0.00163663890994999,0.160095786239606,-0.0131928146111317,0.00163663890995014,0.156398575464239,-0.0148902893414782,0.00163663890995014,0.156398575464239,-0.0148902893414782,0.00163663890995005,0.152388005302283,-0.0155730154605699,0.00163663890995005,0.152388005302283,-0.0155730154605699,0.00636855144148616,0.145110395561535,-0.0293534548542008,0.00163663890995005,0.148337389482496,-0.0151944663116485,0.00163663890995005,0.148337389482496,-0.0151944663116485,0.00636855144148616,0.145110395561535,-0.0293534548542008, +2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,0.00163663890995003,0.144522770779036,-0.0137804393936309,0.00163663890995003,0.144522770779036,-0.0137804393936309,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,0.00163663890995019,0.14120410915259,-0.0114272983041905,0.00163663890995019,0.14120410915259,-0.0114272983041905,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,0.00163663890995001,0.138607565908652,-0.00829540571982265,0.00163663890995001,0.138607565908652,-0.00829540571982265,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,0.00163663890994996,0.136910091178305,-0.00459819494445506,0.00163663890994996,0.136910091178305,-0.00459819494445506,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,0.00163663890994992,0.136227365059213,-0.000587624782499185,0.00163663890994992,0.136227365059213,-0.000587624782499185,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,0.00163663890995014,0.136605914208135,0.0034629910372879,0.00163663890995014,0.136605914208135,0.0034629910372879,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,0.00163663890995005,0.138019941126152,0.00727760974074743,0.00163663890995005,0.138019941126152,0.00727760974074743,2.2671665947323e-05,0.151800380519783,-0,0.00636855144148629,0.122446925665582,0.00668998495824824,0.00636855144148627,0.125178615903944,0.0140592624044813,0.00636855144148627,0.125178615903944,0.0140592624044813, +0.00636855144148629,0.122446925665582,0.00668998495824824,0.00163663890994996,0.140373082215593,0.0105962713671934,0.00636855144148618,0.12972453540633,0.0204704243518791,0.00636855144148618,0.12972453540633,0.0204704243518791,0.00163663890994996,0.140373082215593,0.0105962713671934,0.00163663890995019,0.143504974799961,0.0131928146111317,0.00636855144148623,0.135774887271138,0.025486560708672,0.00636855144148623,0.135774887271138,0.025486560708672,0.00163663890995019,0.143504974799961,0.0131928146111317,0.00163663890995005,0.147202185575328,0.0148902893414786,0.00636855144148627,0.142917350017461,0.0287658300717016,0.00163663890995005,0.147202185575328,0.0148902893414786,0.00163663890995003,0.151212755737284,0.0155730154605699,0.00163663890995003,0.151212755737284,0.0155730154605699,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,0.0138959372413867,0.12913691062383,0.0360434398124487,0.0138959372413867,0.12913691062383,0.0360434398124487,0.0138959372413867,0.120580420959489,0.0289495517459599,0.0138959372413867,0.120580420959489,0.0289495517459599,0.0138959372413867,0.11415151994576,0.0198827995693796,0.0138959372413867,0.11415151994576,0.0198827995693796,0.0138959372413867,0.110288326562466,0.00946106746002642,0.0138959372413867,0.110288326562466,0.00946106746002642,0.0138959372413867,0.109254111054451,-0.00160542076157459,0.00636855144148623,0.121715624866656,-0.00113520390716716,0.0138959372413867,0.109254111054451,-0.00160542076157459,0.00636855144148623,0.121715624866656,-0.00113520390716716,0.00636855144148627,0.123034550448082,-0.00888303050232202,0.0138959372413868,0.111119353499463,-0.0125625022113576,0.00636855144148627,0.123034550448082,-0.00888303050232202, +0.00636855144148636,0.126313819811112,-0.0160254932486455,0.00636855144148636,0.126313819811112,-0.0160254932486455,0.0138959372413867,0.115756940707334,-0.0226634698959529,0.0138959372413868,0.111119353499463,-0.0125625022113576,0.0138959372413867,0.115756940707334,-0.0226634698959529,0.0237058174069819,0.101976501313703,-0.0153858601552059,0.023705817406982,0.107656362462175,-0.0277569685230061,0.0237058174069819,0.101976501313703,-0.0153858601552059,0.023705817406982,0.107656362462175,-0.0277569685230061,0.0351296648165801,0.0962290641579851,-0.0171606971558127,0.0351296648165796,0.102564126096203,-0.0309588756157758,0.0351296648165801,0.0962290641579851,-0.0171606971558127,0.0351296648165796,0.102564126096203,-0.0309588756157758,0.0473889631480165,0.10082725910244,-0.0320509864972911,0.0473889631480169,0.0942687203763802,-0.017766061004644,0.0473889631480165,0.10082725910244,-0.0320509864972911,0.0473889631480168,0.110859531816025,-0.0441516902269075,0.0351296648165796,0.11225455740663,-0.0426472578644845,0.0351296648165796,0.11225455740663,-0.0426472578644845,0.0473889631480168,0.110859531816025,-0.0441516902269075,0.0473889631480169,0.123681855710821,-0.0532435292316781,0.0351296648165796,0.124639971209656,-0.0514292999676547,0.0473889631480169,0.123681855710821,-0.0532435292316781,0.0351296648165796,0.124639971209656,-0.0514292999676547,0.0473889631480167,0.138420410603287,-0.058706909708402,0.03512966481658,0.138876322022469,-0.056706520268966,0.0473889631480167,0.138420410603287,-0.058706909708402,0.03512966481658,0.138876322022469,-0.056706520268966,0.023705817406982,0.140212986670226,-0.0508416751851554,0.023705817406982,0.140212986670226,-0.0508416751851554,0.0237058174069818,0.127449023718279,-0.0461102489017724,0.0237058174069818,0.127449023718279,-0.0461102489017724,0.0237058174069817,0.116344565489833,-0.038236485356523,0.0237058174069817,0.116344565489833,-0.038236485356523,0.0138959372413867,0.122850828773823,-0.0312199595602942,0.0138959372413867,0.122850828773823,-0.0312199595602942,0.00636855144148641,0.131329956167905,-0.0220758451134537, +0.00636855144148641,0.131329956167905,-0.0220758451134537,0.00636855144148634,0.137741118115302,-0.0266217646158389,0.00636855144148634,0.137741118115302,-0.0266217646158389,0.0138959372413868,0.131917580950404,-0.0376488605740236,0.0138959372413868,0.131917580950404,-0.0376488605740236,0.0138959372413868,0.142339313059757,-0.0415120539573173,0.0138959372413868,0.142339313059757,-0.0415120539573173,0.0473889631480169,0.0942687203763802,-0.017766061004644,0.0473889631480167,0.0916308692135295,-0.00227040781433432,0.0351296648165798,0.0936810955938806,-0.00219304554407414,0.0351296648165798,0.0936810955938806,-0.00219304554407414,0.0473889631480167,0.0916308692135295,-0.00227040781433432,0.0237058174069819,0.0996920551952725,-0.00196623084416425,0.0237058174069819,0.0996920551952725,-0.00196623084416425,0.0351296648165797,0.0950938602508174,0.0129240584973143,0.0237058174069818,0.100958705334628,0.0115873938495571,0.0237058174069818,0.100958705334628,0.0115873938495571,0.0351296648165797,0.0950938602508174,0.0129240584973143,0.0237058174069819,0.105690131618011,0.0243513568015046,0.0237058174069819,0.105690131618011,0.0243513568015046,0.0237058174069819,0.11356389516326,0.0354558150299495,0.0237058174069819,0.11356389516326,0.0354558150299495,0.0237058174069817,0.124043411996777,0.0441440180576081,0.0237058174069817,0.124043411996777,0.0441440180576081,0.0351296648165796,0.120841504904007,0.0492362544235808,0.0351296648165796,0.120841504904007,0.0492362544235808,0.0473889631480168,0.119749394022492,0.0509731214173436,0.0473889631480168,0.119749394022492,0.0509731214173436,0.0351296648165797,0.109153122655299,0.0395458231131529,0.0473889631480166,0.107648690292876,0.0409408487037579,0.0473889631480166,0.107648690292876,0.0409408487037579,0.0351296648165797,0.109153122655299,0.0395458231131529,0.0351296648165797,0.100371080552129,0.027160409310127,0.0351296648165797,0.100371080552129,0.027160409310127,0.0473889631480168,0.0985568512881054,0.0281185248089626,0.0473889631480167,0.0930934708113814,0.0133799699164958,0.0473889631480168,0.0985568512881054,0.0281185248089626, +0.0473889631480167,0.0930934708113814,0.0133799699164958,0.0473889631480167,0.209332040663187,0.017766061004644,0.0351296648165799,0.209919665445686,0.00219304554407414,0.0473889631480168,0.211969891826037,0.00227040781433468,0.0351296648165799,0.209919665445686,0.00219304554407414,0.0473889631480168,0.211969891826037,0.00227040781433468,0.0473889631480168,0.210507290228185,-0.0133799699164958,0.0351296648165795,0.208506900788749,-0.012924058497314,0.0351296648165795,0.208506900788749,-0.012924058497314,0.0473889631480168,0.210507290228185,-0.0133799699164958,0.0237058174069818,0.202642055704939,-0.0115873938495568,0.0237058174069818,0.197910629421556,-0.0243513568015046,0.0237058174069818,0.197910629421556,-0.0243513568015046,0.0237058174069817,0.190036865876306,-0.0354558150299495,0.0237058174069817,0.190036865876306,-0.0354558150299495,0.0237058174069816,0.179557349042789,-0.0441440180576081,0.0237058174069816,0.179557349042789,-0.0441440180576081,0.0351296648165798,0.182759256135559,-0.0492362544235806,0.0351296648165798,0.182759256135559,-0.0492362544235806,0.0473889631480165,0.183851367017074,-0.0509731214173436,0.0473889631480169,0.169566441524427,-0.0575316601434032,0.0473889631480165,0.183851367017074,-0.0509731214173436,0.0351296648165799,0.194447638384268,-0.0395458231131529,0.0473889631480166,0.195952070746691,-0.0409408487037579,0.0351296648165799,0.194447638384268,-0.0395458231131529,0.0351296648165796,0.203229680487438,-0.0271604093101267,0.0351296648165796,0.203229680487438,-0.0271604093101267,0.0473889631480167,0.205043909751461,-0.0281185248089626,0.0473889631480167,0.205043909751461,-0.0281185248089626,0.0473889631480166,0.195952070746691,-0.0409408487037579 + } + PolygonVertexIndex: *1584 { + a: 0,1,-3,1,0,-4,4,5,-7,7,2,-2,2,7,-9,9,10,-5,11,8,-8,8,11,-13,13,14,-10,11,15,-13,15,11,-17,17,14,-19,19,16,-12,16,19,-21,21,22,-18,23,20,-20,20,23,-25,25,26,-22,27,24,-24,24,27,-29,29,30,-26,31,28,-28,28,31,-33,33,34,-30,31,35,-33,35,31,-37,37,34,-39,31,39,-37,39,31,-41,37,41,-35,42,36,-40,36,42,-44,44,45,-38,42,46,-44,46,42,-48,48,45,-50,50,47,-43,47,50,-52,45,48,-53,53,52,-49,50,54,-52,54,50,-56,53,56,-53,54,57,-52,57,54,-59,53,59,-57,57,47,-52,47,57,-61,61,59,-49,62,60,-58,60,62,-64,64,65,-62,66,63,-63,63,66,-68,68,69,-65,66,70,-68,70,66,-72,72,69,-74,74,71,-67,71,74,-76,76,77,-73,69,72,-78,62,74,-67,74,62,-79,69,77,-66,79,65,-78,57,78,-63,78,57,-59,65,79,-60,80,59,-80,80,56,-60,59,61,-66,65,64,-70,75,81,-72,81,75,-83,83,76,-85,72,84,-77,85,71,-82,71,85,-71,84,72,-87,73,86,-73,87,70,-86,70,87,-89,86,73,-90,90,89,-74,87,91,-89,91,87,-93,90,93,-90,91,94,-89,94,91,-96,90,96,-94,67,88,-95,88,67,-71,73,68,-91,68,73,-70,96,90,-69,94,63,-68,63,94,-98,68,64,-97,98,96,-65,95,97,-95,97,95,-100,96,98,-101,101,100,-99,102,99,-96,99,102,-104,100,101,-105,105,104,-102,106,103,-103,107,108,-104,105,109,-111,111,103,-109,103,111,-100,101,112,-106,113,99,-112,99,113,-98,98,114,-102,60,97,-114,97,60,-64,64,61,-99,114,98,-62,113,47,-61,47,113,-47,61,48,-115,49,114,-49,111,46,-114,46,111,-116,114,49,-113,116,112,-50,108,115,-112,115,108,-118,112,116,-110,118,109,-117,119,117,-109,120,121,-118,122,123,-122,124,123,-126,126,127,-129,129,127,-131,35,121,-124,121,35,-132,132,38,-130,36,131,-36,131,36,-44,44,37,-133,38,132,-38,43,115,-132,115,43,-47,49,44,-117,44,49,-46,132,116,-45,117,131,-116,131,117,-122,116,132,-119,129,118,-133,118,129,-134,109,118,-135,127,129,-39,123,32,-36,32,123,-125,38,33,-128,33,38,-35,128,127,-34,135,32,-125,32,135,-29,128,33,-137,29,136,-34,137,28,-136,28,137,-25,136,29,-139,25,138,-30,139,24,-138,24,139,-21,138,25,-141,21,140,-26,141,20,-140,20,141,-17,140,21,-143,17,142,-22,143,16,-142,16,143,-16,142,17,-145,18,144,-18,143,145,-16,145,143,-147,147,144,-149,143,149,-147,143,141,-151,151, +142,-145,141,139,-153,153,140,-143,139,137,-155,155,138,-141,137,135,-157,157,136,-139,135,124,-159,159,128,-137,147,160,-145,146,161,-163,163,164,-148,162,165,-167,167,168,-164,166,169,-171,171,172,-168,170,173,-175,175,176,-172,174,177,-179,179,180,-176,178,181,-183,183,184,-180,185,186,-183,183,187,-189,186,189,-183,189,186,-191,191,187,-193,193,190,-187,190,193,-195,195,196,-192,197,194,-194,194,197,-199,199,200,-196,201,198,-198,198,201,-93,202,203,-200,204,92,-202,92,204,-92,93,205,-203,204,95,-92,95,204,-103,93,100,-206,100,93,-97,104,205,-101,206,102,-205,104,105,-208,205,104,-209,209,204,-202,203,205,-211,203,202,-206,211,201,-198,200,203,-213,200,199,-204,213,197,-194,196,200,-215,196,195,-201,215,193,-187,187,196,-217,187,191,-197,202,89,-94,217,92,-88,92,217,-199,89,202,-219,199,218,-203,219,198,-218,198,219,-195,218,199,-221,195,220,-200,221,194,-220,194,221,-191,220,195,-223,191,222,-196,223,190,-222,190,223,-190,222,191,-225,192,224,-192,225,189,-224,189,225,-227,224,192,-228,228,227,-193,225,229,-227,229,225,-231,228,231,-228,174,226,-230,226,174,-179,179,175,-229,231,228,-176,229,170,-175,170,229,-233,175,171,-232,233,231,-172,230,232,-230,232,230,-235,231,233,-236,236,235,-234,237,234,-231,234,237,-239,235,236,-240,240,239,-237,241,238,-238,238,241,-243,239,240,-244,244,243,-241,241,245,-243,245,241,-247,244,247,-244,248,242,-246,242,248,-250,250,251,-245,252,249,-249,249,252,-254,251,250,-255,255,254,-251,256,253,-253,253,256,-258,254,255,-259,259,258,-256,0,257,-257,257,0,-3,258,259,-7,4,6,-260,2,260,-258,260,2,-9,259,261,-5,262,257,-261,257,262,-254,255,263,-260,264,253,-263,253,264,-250,250,265,-256,238,249,-265,249,238,-243,265,250,-241,244,240,-251,266,238,-265,238,266,-235,236,267,-241,268,234,-267,234,268,-233,233,269,-237,166,232,-269,232,166,-171,171,167,-234,269,233,-168,268,162,-167,162,268,-271,167,163,-270,271,269,-164,266,270,-269,270,266,-273,269,271,-268,273,267,-272,264,272,-267,272,264,-263,267,273,-266,263,265,-274,263,255,-266,262,274,-273,274,262,-261,273,275,-264,145,272,-275, +272,145,-271,271,148,-274,146,270,-146,270,146,-163,163,147,-272,148,271,-148,275,273,-149,274,15,-146,15,274,-13,148,18,-276,18,148,-145,13,275,-19,274,8,-13,8,274,-261,261,275,-10,261,263,-276,261,259,-264,13,9,-276,9,4,-262,13,18,-15,265,240,-268,267,236,-270,247,244,-252,276,243,-248,241,277,-247,277,241,-279,279,243,-281,241,281,-279,281,241,-238,239,243,-283,279,282,-244,281,283,-279,283,281,-285,285,282,-287,225,284,-282,284,225,-224,224,227,-286,282,285,-228,281,230,-226,230,281,-238,227,235,-283,235,227,-232,239,282,-236,221,284,-224,284,221,-288,288,222,-286,219,287,-222,287,219,-290,290,220,-289,217,289,-220,289,217,-292,292,218,-291,87,291,-218,291,87,-86,86,89,-293,218,292,-90,81,291,-86,291,81,-294,294,84,-293,82,293,-82,293,82,-296,296,83,-295,84,294,-84,295,297,-294,297,295,-299,299,296,-301,294,300,-297,289,293,-298,293,289,-292,300,294,-291,292,290,-295,301,289,-298,289,301,-288,288,302,-291,283,287,-302,287,283,-285,285,286,-289,302,288,-287,303,283,-302,283,303,-305,302,286,-306,306,305,-287,304,278,-284,278,304,-278,286,279,-307,279,286,-283,280,306,-280,301,298,-304,298,301,-298,300,302,-300,300,290,-303,305,299,-303,86,292,-85,220,290,-219,222,288,-221,224,285,-223,276,280,-244,182,226,-179,226,182,-190,192,183,-229,183,192,-188,179,228,-184,109,105,-113,112,101,-115,53,48,-60,307,52,-57,308,55,-51,55,308,-310,52,307,-311,311,310,-308,308,312,-310,312,308,-314,314,310,-316,39,313,-309,313,39,-41,316,41,-315,316,34,-42,27,40,-32,40,27,-318,34,316,-31,318,30,-317,23,317,-28,317,23,-320,30,318,-27,320,26,-319,19,319,-24,319,19,-322,26,320,-23,322,22,-321,11,321,-20,321,11,-8,22,322,-15,10,14,-323,10,9,-15,1,321,-8,321,1,-324,10,322,-6,324,5,-323,3,323,-2,323,3,-326,5,324,-327,327,326,-325,325,328,-324,328,325,-330,324,330,-328,319,323,-329,323,319,-322,322,320,-325,330,324,-321,328,317,-320,317,328,-332,320,318,-331,332,330,-319,328,333,-332,333,328,-330,332,334,-331,312,331,-334,331,312,-314,314,315,-333,334,332,-316,313,317,-332,317,313,-41,316,314,-319,332,318,-315,335,330,-335,335,327,-331, +326,6,-6,5,4,-11,14,17,-23,22,21,-27,26,25,-31,30,29,-35,310,314,-42,50,39,-309,39,50,-43,45,52,-42,310,41,-53,41,37,-46,311,315,-311 + } + GeometryVersion: 124 + LayerElementNormal: 0 { + Version: 101 + Name: "" + MappingInformationType: "ByVertice" + ReferenceInformationType: "Direct" + Normals: *1008 { + a: 0.165061885880005,-0.0371894770096069,0.985581816304201,0.319660973195773,-0.279575805784721,0.905347574711147,0.319660973195776,-0.0357282964404208,0.946858147268637,0.165061885880002,-0.291009620876021,0.942373585361629,-0.319660973195776,0.0357282964404208,-0.946858147268637,-0.319660973195773,0.279575805784721,-0.905347574711147,-0.165061885880005,0.0371894770096069,-0.985581816304201,0.588320272074902,-0.238591235878358,0.772627646171007,0.588320272074903,-0.0304906870593508,0.808052953381374,-0.588320272074903,0.0304906870593508,-0.808052953381374,-0.588320272074902,0.238591235878358,-0.772627646171007,0.783622247195295,-0.183300415659924,0.593579928332736,0.783622247195291,-0.0234248152123418,0.620795821291404,-0.783622247195291,0.0234248152123418,-0.620795821291404,-0.783622247195295,0.183300415659924,-0.593579928332736,0.909402416903608,-0.0156828673903083,0.415621572828329,0.909402416903608,-0.122719265245997,0.397400586395338,-0.909402416903608,0.122719265245997,-0.397400586395338,-0.909402416903608,0.0156828673903083,-0.415621572828329,0.783622247195298,-0.330684395698547,0.5259125441954,0.909402416903608,-0.221392547978352,0.352097406735024,-0.909402416903608,0.221392547978352,-0.352097406735024,-0.783622247195298,0.330684395698547,-0.5259125441954,0.783622247195297,-0.455532780652114,0.422405089282724,0.909402416903606,-0.304978294434471,0.282799370674197,-0.909402416903606,0.304978294434471,-0.282799370674197,-0.783622247195297,0.455532780652114,-0.422405089282724,0.783622247195295,-0.549337359407749,0.290111425592854,0.909402416903606,-0.367780274125332,0.194229024849982,-0.909402416903606,0.367780274125332,-0.194229024849982,-0.783622247195295,0.549337359407749,-0.290111425592854,0.783622247195294,-0.60570550494266,0.13804714768062,0.909402416903606,-0.405518635920199,0.0924222919608782,-0.909402416903606,0.405518635920199,-0.0924222919608782,-0.783622247195294,0.60570550494266,-0.13804714768062,0.909402416903607,-0.415621572828332,-0.0156828673902995,0.783622247195291,-0.620795821291405,-0.0234248152123439, +-0.783622247195291,0.620795821291405,0.0234248152123439,-0.909402416903607,0.415621572828332,0.0156828673902995,0.588320272074902,-0.808052953381375,-0.0304906870593533,0.588320272074905,-0.788410787189447,0.179687751694507,-0.588320272074902,0.808052953381375,0.0304906870593533,0.5883202720749,-0.772627646171008,-0.238591235878359,0.783622247195294,-0.593579928332736,-0.183300415659924,-0.783622247195294,0.593579928332736,0.183300415659924,-0.5883202720749,0.772627646171008,0.238591235878359,0.783622247195296,-0.525912544195403,-0.330684395698546,0.588320272074899,-0.68454904170164,-0.430432186262927,-0.588320272074899,0.68454904170164,0.430432186262927,-0.783622247195296,0.525912544195403,0.330684395698546,0.319660973195775,-0.905347574711147,-0.279575805784719,0.319660973195772,-0.8021390610947,-0.504370685985661,-0.319660973195775,0.905347574711147,0.279575805784719,-0.319660973195772,0.8021390610947,0.504370685985661,0.165061885880012,-0.834944151922644,-0.524997939995873,0.165061885880013,-0.942373585361628,-0.291009620876018,-0.165061885880012,0.834944151922644,0.524997939995873,0.319660973195768,-0.644266096062123,-0.694793537448647,0.165061885880004,-0.670614654340585,-0.723208517105125,-0.319660973195768,0.644266096062123,0.694793537448647,0.588320272074901,-0.549819551311081,-0.592939894476494,-0.588320272074901,0.549819551311081,0.592939894476494,0.31966097319577,-0.442487461282974,-0.837867357535118,0.588320272074904,-0.377620767118444,-0.715039728760989,-0.588320272074904,0.377620767118444,0.715039728760989,-0.31966097319577,0.442487461282974,0.837867357535118,0.31966097319577,-0.210554037262502,-0.923841901846844,0.588320272074904,-0.179687751694517,-0.788410787189445,-0.588320272074904,0.179687751694517,0.788410787189445,-0.31966097319577,0.210554037262502,0.923841901846844,0.588320272074908,0.0304906870593446,-0.808052953381371,0.319660973195768,0.0357282964404139,-0.946858147268639,-0.319660973195768,-0.0357282964404139,0.946858147268639,-0.588320272074908,-0.0304906870593446,0.808052953381371,0.165061885879998,-0.219165068256502,-0.961624275216605, +0.165061885879987,0.0371894770096023,-0.985581816304204,-0.165061885879987,-0.0371894770096023,0.985581816304204,-0.165061885879998,0.219165068256502,0.961624275216605,0.165061885880002,-0.460583876308327,-0.872133628932249,-0.165061885880002,0.460583876308327,0.872133628932249,-0.165061885880004,0.670614654340585,0.723208517105125,0.319660973195765,0.279575805784725,-0.905347574711148,0.165061885879982,0.291009620876022,-0.942373585361632,-0.165061885879982,-0.291009620876022,0.942373585361632,-0.319660973195765,-0.279575805784725,0.905347574711148,0.588320272074911,0.238591235878364,-0.772627646170998,-0.588320272074911,-0.238591235878364,0.772627646170998,0.783622247195297,0.183300415659929,-0.593579928332731,0.783622247195295,0.023424815212345,-0.6207958212914,-0.783622247195297,-0.183300415659929,0.593579928332731,-0.783622247195295,-0.023424815212345,0.6207958212914,0.909402416903607,0.0156828673903071,-0.415621572828332,0.909402416903607,0.122719265245996,-0.397400586395341,-0.909402416903607,-0.0156828673903071,0.415621572828332,0.783622247195294,-0.138047147680626,-0.605705504942658,0.909402416903607,-0.0924222919608787,-0.405518635920195,-0.783622247195294,0.138047147680626,0.605705504942658,0.783622247195294,-0.290111425592852,-0.549337359407751,-0.783622247195294,0.290111425592852,0.549337359407751,0.909402416903604,-0.194229024849983,-0.367780274125337,-0.909402416903607,0.0924222919608787,0.405518635920195,-0.909402416903604,0.194229024849983,0.367780274125337,0.978227201428167,-0.0461174097295258,-0.202348034104253,0.978227201428167,-0.0969175220645315,-0.183517128091324,-0.978227201428167,0.0461174097295258,0.202348034104253,-0.978227201428167,0.0969175220645315,0.183517128091324,1,-4.62202960142024e-16,6.74990738018729e-16,1,-4.59296023285785e-16,6.81967386473703e-16,0.978227201428167,-0.141112865434638,-0.15217983307535,-0.978227201428167,0.141112865434638,0.15217983307535,-1,4.59296023285785e-16,-6.81967386473703e-16,0.909402416903607,-0.282799370674193,-0.304978294434468,-0.909402416903607,0.282799370674193,0.304978294434468, +0.783622247195297,-0.422405089282722,-0.455532780652115,-0.783622247195297,0.422405089282722,0.455532780652115,0.909402416903608,-0.352097406735025,-0.22139254797835,-0.909402416903608,0.352097406735025,0.22139254797835,0.978227201428167,-0.175691600225391,-0.110471733924375,-0.978227201428167,0.175691600225391,0.110471733924375,1,-4.65109896998263e-16,6.79641836988712e-16,1,-4.63947122255767e-16,6.72665188533738e-16,0.978227201428168,-0.198297242804879,-0.0612351686696228,1,-4.66854059112006e-16,6.73391922747797e-16,0.978227201428168,-0.207389255988912,-0.0078255278659124,0.978227201428167,-0.202348034104249,0.0461174097295374,1,-4.64528509627015e-16,6.7876975593184e-16,-1,4.64528509627015e-16,-6.7876975593184e-16,-0.978227201428168,0.207389255988912,0.0078255278659124,-0.978227201428167,0.202348034104249,-0.0461174097295374,-0.978227201428168,0.198297242804879,0.0612351686696228,-1,4.66854059112006e-16,-6.73391922747797e-16,0.909402416903608,-0.397400586395337,-0.122719265246002,-0.909402416903608,0.397400586395337,0.122719265246002,-1,4.63947122255767e-16,-6.72665188533738e-16,-1,4.65109896998263e-16,-6.79641836988712e-16,0.978227201428167,-0.183517128091317,0.096917522064539,-0.978227201428167,0.183517128091317,-0.096917522064539,0.978227201428167,-0.152179833075363,0.141112865434628,-0.978227201428167,0.152179833075363,-0.141112865434628,0.978227201428168,-0.110471733924365,0.175691600225393,-0.978227201428168,0.110471733924365,-0.175691600225393,0.978227201428166,-0.0612351686696132,0.198297242804891,-0.978227201428166,0.0612351686696132,-0.198297242804891,0.978227201428168,-0.0078255278659391,0.207389255988911,-0.978227201428168,0.0078255278659391,-0.207389255988911,0.909402416903606,0.0924222919608851,0.405518635920197,0.978227201428168,0.0461174097295331,0.202348034104246,-0.978227201428168,-0.0461174097295331,-0.202348034104246,-0.909402416903606,-0.0924222919608851,-0.405518635920197,1,-4.62784347513272e-16,6.76153512761225e-16,1,-4.63656428570143e-16,6.73827963276233e-16,-1,4.63656428570143e-16,-6.73827963276233e-16, +1,-4.63365734884519e-16,6.78479062246216e-16,-1,4.63365734884519e-16,-6.78479062246216e-16,1,-4.65109896998263e-16,6.7731628750372e-16,-1,4.65109896998263e-16,-6.7731628750372e-16,1,-4.64528509627015e-16,6.76734900132472e-16,-1,4.64528509627015e-16,-6.76734900132472e-16,1,-4.64528509627015e-16,6.84583629644318e-16,-1,4.64528509627015e-16,-6.84583629644318e-16,-1,4.62784347513272e-16,-6.76153512761225e-16,1,-4.65981978055135e-16,6.72665188533738e-16,0.978227201428167,0.0969175220645579,0.183517128091308,-0.978227201428167,-0.0969175220645579,-0.183517128091308,-1,4.65981978055135e-16,-6.72665188533738e-16,1,-4.62784347513272e-16,6.7731628750372e-16,0.978227201428166,0.141112865434637,0.15217983307536,-0.978227201428166,-0.141112865434637,-0.15217983307536,-1,4.62784347513272e-16,-6.7731628750372e-16,1,-4.63947122255767e-16,6.74990738018729e-16,0.978227201428167,0.175691600225378,0.110471733924394,-0.978227201428167,-0.175691600225378,-0.110471733924394,-1,4.63947122255767e-16,-6.74990738018729e-16,1,-4.67435446483254e-16,6.73246575904986e-16,0.978227201428167,0.19829724280488,0.0612351686696285,-0.978227201428167,-0.19829724280488,-0.0612351686696285,-1,4.67435446483254e-16,-6.73246575904986e-16,1,-4.66272671740758e-16,6.75281431704353e-16,0.978227201428168,0.207389255988911,0.00782552786590903,-0.978227201428168,-0.207389255988911,-0.00782552786590903,-1,4.66272671740758e-16,-6.75281431704353e-16,1,-4.66272671740758e-16,6.7731628750372e-16,0.978227201428167,0.202348034104249,-0.0461174097295443,-0.978227201428167,-0.202348034104249,0.0461174097295443,-1,4.66272671740758e-16,-6.7731628750372e-16,1,-4.63947122255767e-16,6.82258080159327e-16,0.978227201428168,0.183517128091323,-0.0969175220645285,-0.978227201428168,-0.183517128091323,0.0969175220645285,-1,4.63947122255767e-16,-6.82258080159327e-16,0.909402416903605,0.405518635920198,-0.0924222919608817,0.909402416903604,0.367780274125338,-0.194229024849982,-0.909402416903604,-0.367780274125338,0.194229024849982,-0.909402416903605,-0.405518635920198,0.0924222919608817, +0.978227201428169,0.152179833075344,-0.141112865434637,0.909402416903605,0.30497829443447,-0.282799370674199,-0.909402416903605,-0.30497829443447,0.282799370674199,-0.978227201428169,-0.152179833075344,0.141112865434637,0.978227201428167,0.110471733924365,-0.175691600225396,0.909402416903606,0.221392547978351,-0.352097406735031,-0.909402416903606,-0.221392547978351,0.352097406735031,-0.978227201428167,-0.110471733924365,0.175691600225396,0.978227201428168,0.0612351686696213,-0.198297242804882,-0.909402416903607,-0.122719265245995,0.397400586395341,-0.978227201428168,-0.0612351686696213,0.198297242804882,0.978227201428167,0.00782552786591837,-0.207389255988915,-0.978227201428167,-0.00782552786591837,0.207389255988915,1,-4.6082216513531e-16,6.74409350647481e-16,-1,4.62202960142024e-16,-6.74990738018729e-16,-1,4.6082216513531e-16,-6.74409350647481e-16,1,-4.60749491713904e-16,6.74409350647481e-16,-1,4.60749491713904e-16,-6.74409350647481e-16,1,-4.61330879085152e-16,6.73246575904986e-16,-1,4.61330879085152e-16,-6.73246575904986e-16,1,-4.65691284369511e-16,6.76734900132472e-16,-1,4.65691284369511e-16,-6.76734900132472e-16,1,-4.62202960142024e-16,6.75862819075601e-16,-1,4.62202960142024e-16,-6.75862819075601e-16,0.783622247195293,0.330684395698553,-0.525912544195403,-0.783622247195293,-0.330684395698553,0.525912544195403,0.783622247195292,0.455532780652118,-0.422405089282729,-0.783622247195292,-0.455532780652118,0.422405089282729,0.783622247195292,0.54933735940775,-0.290111425592859,-0.783622247195292,-0.54933735940775,0.290111425592859,0.783622247195294,0.605705504942658,-0.138047147680625,-0.783622247195294,-0.605705504942658,0.138047147680625,0.783622247195294,0.6207958212914,0.0234248152123499,0.909402416903603,0.415621572828341,0.0156828673903053,-0.783622247195294,-0.6207958212914,-0.0234248152123499,-0.909402416903603,-0.415621572828341,-0.0156828673903053,0.909402416903602,0.397400586395349,0.122719265246005,0.783622247195296,0.593579928332733,0.183300415659927,-0.909402416903602,-0.397400586395349,-0.122719265246005, +0.909402416903606,0.352097406735026,0.221392547978359,-0.909402416903606,-0.352097406735026,-0.221392547978359,0.783622247195296,0.525912544195407,0.330684395698541,-0.783622247195296,-0.593579928332733,-0.183300415659927,-0.783622247195296,-0.525912544195407,-0.330684395698541,0.5883202720749,0.772627646171006,0.238591235878366,0.588320272074901,0.684549041701643,0.430432186262918,-0.5883202720749,-0.772627646171006,-0.238591235878366,-0.588320272074901,-0.684549041701643,-0.430432186262918,0.319660973195764,0.905347574711149,0.279575805784723,0.319660973195771,0.802139061094706,0.504370685985652,-0.319660973195764,-0.905347574711149,-0.279575805784723,-0.319660973195771,-0.802139061094706,-0.504370685985652,0.165061885880012,0.83494415192265,0.524997939995863,0.165061885880016,0.942373585361628,0.291009620876018,-0.165061885880012,-0.83494415192265,-0.524997939995863,0.165061885879995,0.670614654340583,0.723208517105129,0.319660973195769,0.644266096062124,0.694793537448647,-0.319660973195769,-0.644266096062124,-0.694793537448647,-0.165061885879995,-0.670614654340583,-0.723208517105129,0.165061885879994,0.460583876308329,0.872133628932249,0.319660973195768,0.442487461282974,0.837867357535119,-0.165061885879994,-0.460583876308329,-0.872133628932249,-0.319660973195768,-0.442487461282974,-0.837867357535119,0.165061885880002,0.219165068256504,0.961624275216604,0.319660973195773,0.210554037262499,0.923841901846844,-0.165061885880002,-0.219165068256504,-0.961624275216604,-0.319660973195773,-0.210554037262499,-0.923841901846844,0.588320272074907,0.179687751694512,0.788410787189444,-0.588320272074907,-0.179687751694512,-0.788410787189444,0.588320272074909,0.377620767118438,0.715039728760988,-0.588320272074909,-0.377620767118438,-0.715039728760988,0.588320272074909,0.549819551311083,0.592939894476485,-0.588320272074909,-0.549819551311083,-0.592939894476485,0.783622247195299,0.422405089282724,0.45553278065211,-0.783622247195299,-0.422405089282724,-0.45553278065211,0.909402416903607,0.282799370674195,0.304978294434467,-0.909402416903607,-0.282799370674195,-0.304978294434467, +0.909402416903605,0.194229024849988,0.367780274125331,-0.909402416903605,-0.194229024849988,-0.367780274125331,0.783622247195296,0.290111425592847,0.549337359407752,-0.783622247195296,-0.290111425592847,-0.549337359407752,0.783622247195292,0.138047147680627,0.605705504942661,-0.783622247195292,-0.138047147680627,-0.605705504942661,-0.165061885880016,-0.942373585361628,-0.291009620876018,0.165061885880007,0.9855818163042,0.0371894770096146,0.319660973195766,0.946858147268639,0.0357282964404277,-0.319660973195766,-0.946858147268639,-0.0357282964404277,-0.165061885880007,-0.9855818163042,-0.0371894770096146,0.588320272074904,0.808052953381373,0.0304906870593547,-0.588320272074904,-0.808052953381373,-0.0304906870593547,0.319660973195771,0.923841901846844,-0.210554037262501,0.588320272074908,0.788410787189442,-0.179687751694516,-0.588320272074908,-0.788410787189442,0.179687751694516,-0.319660973195771,-0.923841901846844,0.210554037262501,0.588320272074908,0.715039728760982,-0.377620767118451,-0.588320272074908,-0.715039728760982,0.377620767118451,0.588320272074908,0.59293989447649,-0.549819551311078,-0.588320272074908,-0.59293989447649,0.549819551311078,0.588320272074909,0.430432186262931,-0.684549041701629,-0.588320272074909,-0.430432186262931,0.684549041701629,0.319660973195768,0.504370685985667,-0.802139061094697,-0.319660973195768,-0.504370685985667,0.802139061094697,0.165061885879991,0.524997939995876,-0.834944151922646,-0.165061885879991,-0.524997939995876,0.834944151922646,0.319660973195773,0.694793537448648,-0.644266096062121,0.165061885880002,0.723208517105127,-0.670614654340584,-0.165061885880002,-0.723208517105127,0.670614654340584,-0.319660973195773,-0.694793537448648,0.644266096062121,0.319660973195772,0.837867357535114,-0.44248746128298,-0.319660973195772,-0.837867357535114,0.44248746128298,0.165061885879998,0.872133628932247,-0.460583876308331,0.165061885879997,0.961624275216605,-0.219165068256504,-0.165061885879998,-0.872133628932247,0.460583876308331,-0.165061885879997,-0.961624275216605,0.219165068256504, +-0.165061885880013,0.942373585361628,0.291009620876018,0.319660973195776,-0.946858147268636,-0.0357282964404201,0.16506188588001,-0.9855818163042,-0.0371894770096036,-0.319660973195776,0.946858147268636,0.0357282964404201,-0.16506188588001,0.9855818163042,0.0371894770096036,0.165061885880014,-0.961624275216603,0.219165068256502,0.319660973195775,-0.923841901846844,0.210554037262496,-0.319660973195775,0.923841901846844,-0.210554037262496,-0.165061885880014,0.961624275216603,-0.219165068256502,-0.588320272074905,0.788410787189447,-0.179687751694507,0.588320272074906,-0.715039728760986,0.377620767118448,-0.588320272074906,0.715039728760986,-0.377620767118448,0.588320272074907,-0.59293989447649,0.549819551311079,-0.588320272074907,0.59293989447649,-0.549819551311079,0.588320272074906,-0.430432186262923,0.684549041701637,-0.588320272074906,0.430432186262923,-0.684549041701637,0.319660973195769,-0.50437068598566,0.802139061094701,-0.319660973195769,0.50437068598566,-0.802139061094701,0.165061885879998,-0.524997939995872,0.834944151922648,-0.165061885880002,0.291009620876021,-0.942373585361629,-0.165061885879998,0.524997939995872,-0.834944151922648,0.319660973195768,-0.69479353744865,0.644266096062121,0.165061885879999,-0.723208517105129,0.670614654340582,-0.319660973195768,0.69479353744865,-0.644266096062121,0.319660973195771,-0.837867357535117,0.442487461282976,-0.319660973195771,0.837867357535117,-0.442487461282976,0.165061885880009,-0.872133628932247,0.460583876308327,-0.165061885880009,0.872133628932247,-0.460583876308327,-0.165061885879999,0.723208517105129,-0.670614654340582 + } + } + LayerElementUV: 0 { + Version: 101 + Name: "" + MappingInformationType: "ByPolygonVertex" + ReferenceInformationType: "IndexToDirect" + UV: *1104 { + a: 4.46426119763171,4.23960635191711,3.95825904316948,4.83404098029096,3.97490892739521,4.23651797590791,4.44702396908623,4.85820768560196,4.49859891589901,5.05993369441967,5.04890603984231,4.5346868462412,5.00196047112071,5.13059545751401,4.54068916134179,4.52565664989875,4.50161748549698,5.20694584170166,5.09237703279083,4.78670080005803,5.02939358851031,5.31891939688645,4.55304325240708,4.77239117708511,4.64512613921243,5.36605540583565,4.13492221408481,4.9144387083622,4.70809048368527,4.93302208452261,4.09039969913511,5.22063950634241,4.48164941032788,5.7042626751693,4.08747115304566,5.14848467260138,4.64140768007161,5.29688120616169,3.97450499715923,5.43654687186638,4.20019871137471,6.00254501389062,3.95097638615182,5.36838894535311,4.45308658478147,5.64543146118488,3.77215765598606,5.62090636012496,3.77356502210727,6.29100955472736,3.69694914017229,5.61396030002887,4.11025660971216,6.01150796103172,3.4588722354084,5.81159777228348,3.18111786652008,6.56950160060775,3.29687318297424,5.89803574640138,3.58253293556545,6.39529394180479,3.0130298655818,6.02121916327561,2.87334056915497,6.74768892268244,2.44007044859631,6.22181565916398,2.74765557105539,6.18816190063703,2.43834951738917,6.7952825244161,2.95967094972765,6.08622155476339,2.54883478245661,6.68356264778055,2.52598524422096,6.1445231403462,3.07998912607177,6.61215807984401,1.25892276910307,7.00085242910731,1.85950400957852,6.59476757180056,1.77947524092206,7.1283227124936,1.43447469614484,6.49068852124576,0.510767420229244,7.3215499004331,0.400688051153458,6.60497103509533,0.765828439082642,6.84612422944539,0.063563602775047,7.02619876243318,-0.704523653383229,7.08814041251166,-0.749600200024839,6.32873914366428,-0.369138530900367,6.70619439583395,-1.12887350560978,6.66714378268312,-2.39147031282071,5.6215675533636,-3.05658413431405,5.21289370762731,-2.59220730433476,5.05852615199993,-2.84876590847237,5.79579705904383,-3.33110494066048,6.01313223495711,-2.96894796523278,5.32158828633241,-2.85316442751366,5.90802253823531,-3.45097287934469, +5.4060108225854,-2.07655445377204,6.47960857030124,-1.35726120883224,6.72727651325739,-1.78520690586631,7.00155451169843,-1.61847627416082,6.25931258440298,-2.54940087215571,6.1622674426661,-1.89060214486895,6.54267041204136,-2.36303073483668,6.73022618353325,-2.05769703873378,6.03345253577645,-2.77059932360906,5.65945403215642,-2.1747075369386,6.1323548259418,-2.66953305152257,6.24860305240361,-2.26532107755482,5.60413826493634,-2.81236192350834,5.51467551569453,-2.32997194760815,4.92643908930193,-2.30681507018766,5.46187097861334,-2.83819006418286,4.91747884242769,-3.6694287773191,5.45531462155619,-3.18954187347752,4.83960424544438,-3.1803988514159,5.43728924990682,-3.67889433027647,4.83654557304792,-3.13734437086147,5.90814700493636,-3.66253648440776,5.33059704900255,-3.17354764946578,5.31148941298769,-3.62505609241597,5.94830244180786,-3.04432218050853,6.04931298051545,-3.60043950088455,5.50147702540831,-3.11323795968139,5.45554402309792,-3.52909263625248,6.11619188368958,-3.67789718099367,4.63180803989844,-3.17189502653145,4.0373734115246,-3.18854491075717,4.63489641590765,-3.66065995244819,4.0132067062136,-2.28138794417252,3.98821469399731,-2.83169506811581,4.51346154217579,-2.78474949939422,3.91755293090298,-2.32347818961529,4.52249173851827,-1.18380400574961,4.09348517533485,-1.77456355304347,4.51373021697851,-1.71158010876294,3.98151162015005,-1.2352297726597,4.52803983995141,-0.582883349510165,4.16369861070791,-0.0726794243825477,4.61531530818137,-0.645847693982995,4.59673193202096,-0.0281569094328393,4.30911451020116,-0.0833243867695979,4.95676635155803,-0.621675005419337,5.37443164584509,-0.656494249121092,4.93823216589315,-0.0587034634322969,5.26520596178208,-1.75065006296451,5.4821251185952,-1.24605938329247,4.96155717515935,-1.21769019119085,5.39822358671605,-1.7853950854965,4.94732017053217,-1.1509282497828,5.65574205217972,-1.54974284991144,6.26117549399569,-1.68347976730753,5.74219766596366,-1.04173251398508,6.0794856743452,0.00524351316338012,5.50908839027755,-0.425309209383514,6.03718879716996, +-0.557395718251639,5.62001315044864,0.0986427792872919,5.80407611902007,1.12424994296865,5.25315257718193,0.639444448338006,5.67280704765631,0.536667044897205,5.38095436501809,1.17745144180197,5.40422664244399,2.17581562300938,4.96209054979058,1.62966841003412,5.24879761009143,1.57426318680961,5.09851775810735,2.20199490274567,5.00482956170627,1.7483308070558,5.4227609016999,1.6560219779786,5.29186837805049,0.900998423137554,6.04119658577781,1.26469101205816,5.51311141937241,1.35417429006818,5.64595160767962,0.728130004635784,5.78456904846771,-0.0516573396985611,6.55244355943086,0.24230012048469,5.93774469148408,0.402592910513559,6.20240939348626,-0.278345577308011,6.17815114837793,-1.14349461571949,6.8372214576554,-0.876793381402844,6.1630751906192,-0.683323164054754,6.55556931929067,-1.38044627218357,6.3565162865137,-0.376777374422402,6.48324269843658,-0.475722546940407,7.20144363868958,-0.820070685540955,6.79077600117013,-0.0956182966062344,6.81855142036887,0.631998262947704,6.22604720501122,0.503095705198703,6.89511358232981,0.189098999455884,6.59033754189199,0.854027462848694,6.44155640994798,1.48223164534064,5.69983416233335,1.26681088856318,6.30377136085868,1.03368168269821,6.10032122840869,1.6029082022356,5.80514770034673,2.23957930942003,5.03567929550337,1.90948498807384,5.55675074519331,1.78645525431274,5.45419609008886,2.28543044353693,5.05372067679513,2.10180399028463,5.64258317545926,1.95638257135932,5.57545357252087,2.3358293437483,5.05942461216085,2.31158434385349,5.67577670037593,2.15371213602796,5.64875562213667,2.52384065571189,5.65563407624141,2.36437512447989,5.6706179683198,2.38689127903796,5.05420030191908,2.20420382452102,6.46875538826609,2.07833185159382,5.84002453277654,2.2359887036951,5.86827501345269,1.8996341742489,6.41417965048576,2.04866944542421,6.98640620677375,1.79375560374886,6.35451648540239,2.09720836129948,6.41499463811946,1.6195224401566,6.90087718297401,1.22297301967448,7.04330041384979,1.16379789005381,6.36450442779296,1.43634072524707,6.51100216158421,0.837539245816533,6.8361213318653, +1.76136745275596,5.80781835325299,1.71313717664195,6.4472087525234,1.43454508194168,6.31256987332548,1.90557733260282,5.87751256554835,2.40359110793637,5.80726926220792,2.69567175451752,6.37808896938869,2.38773740942965,6.40838124788431,2.5629896542362,5.79158882501949,2.85709796103502,5.66710956724802,2.85525605602671,6.30831378557408,2.70788649456838,5.72533079145183,3.14351047410391,6.1958390173808,3.0971667293469,5.51369879256438,3.26589778293642,6.13230696723374,2.96880942536702,5.60950158578012,3.5138650527504,5.94723018283834,3.27303843629781,5.34324865209353,3.59650068709574,5.89688970414976,3.1739351197695,5.46907514106149,3.78795359290694,5.65381159349888,3.38337911697251,5.15827231938563,3.83642164793013,5.61203294720244,3.31934462444491,5.30508293357837,3.96012678814159,5.32841661955819,3.4311695270915,4.95427028965104,3.98270472115852,5.28131030542688,3.40559914662136,5.1123839459731,4.03210290292679,4.97585817716592,3.43383226455401,4.88468132462773,4.00740278687202,4.59804026312215,4.03476637829406,4.90624866158923,3.41966782734915,4.72514091786008,3.1654742515959,4.89726768181079,2.54907953544303,4.87413176674763,3.15065070034971,4.73778716575516,3.1638351817685,4.9404286455556,3.1370975937154,5.09834911306385,2.5474405570539,4.9172902944922,3.12412597407014,5.13729886490045,3.0575953730645,5.28299530206604,2.53451280785774,4.95609723440013,3.03355832971073,5.31713670880995,2.93166115700791,5.44071153985611,2.51073414471428,4.98982555982509,2.89728276792651,5.46949521909633,2.76686463481156,5.56247308327771,2.47703388500925,5.017977120817,2.72361714345517,5.58496416659746,2.57353419281608,5.64090056441123,2.43498022170886,5.03983441683893,3.14093022677461,4.69162512687625,2.53937779057484,4.828052335193,3.08552500355008,4.54134527489215,3.06462750602455,4.49447406290821,2.51865458125749,4.78151287925243,2.97231867694736,4.3635815392588,2.94080710040037,4.31952475313844,2.48768304529308,4.73804154772393,2.81777736663927,4.21697009803399,2.77688055147588,4.18017930124392,2.44783267929827,4.70191219696966, +2.63145913255057,4.11304969830552,2.58331686987734,4.08816374720047,2.401199662157,4.67749475717631,2.42544466205181,4.06114266896122,2.37315788842623,4.0519981579504,2.35064173386817,4.66841582435112,2.21369235719424,4.06698205002879,2.29965697134313,4.67674859975451,2.01102004959681,4.13161884999597,2.16110300023592,4.07568245218222,1.85004669300108,3.52682781361649,1.85188859800938,2.88562359529042,1.99925815946773,3.46860658941268,1.5636341799322,2.99809836348371,1.55723743859335,3.71826680531002,1.38850638500383,3.09965863064065,1.68559474257321,3.62246401209428,1.14053911518983,3.28473541503607,1.31998972778794,4.00887277417733,0.996527476989996,3.45523172212111,1.41909304431626,3.88304628520936,0.805074571178797,3.69830983277198,1.15621614562434,4.36158960937345,0.703173614666716,3.90782898155663,1.22025063815194,4.21477899518071,0.579468474455271,4.19144530920089,1.07593003678663,4.73562632178249,0.524394842719614,4.40858630600666,1.10150041725676,4.57751266546044,0.474996660951337,4.71403843426762,1.06897677344044,4.93384175105772,0.495406251122418,5.22048281256329,0.468042659700387,4.91227441409622,1.08314121064529,5.09338215782539,2.16325880607623,4.90999340988167,1.56168764116954,5.04633801087415,1.54686408992336,4.88685749481851,2.16539395059119,4.85260580525615,1.5489993258766,4.82946745419275,1.57573691392968,4.67154698668452,2.18203899448129,4.79514412464058,1.59242582826888,4.61394249414027,1.65895642927453,4.46824605697469,2.2117776789038,4.74331242790815,1.68895349390735,4.4160012789233,1.79085066661016,4.29242644787712,2.25209864990563,4.70246510414208,1.83184976698837,4.25094700586275,1.96226790010331,4.15796914168136,-0.336141590530005,3.34489094756542,0.0580366667522183,3.90066895013335,-0.495899860273736,3.75227241657303,0.171002822638631,3.61260675086834,0.089730764688408,2.55554656071016,0.338953089911296,3.18970262924766,-0.163157108718334,2.91266011341588,0.517771820077059,2.93718521447582,0.69519465998538,1.8976758557496,0.771810541920351,2.57472511044809,0.358503072380475,2.17717744944523, +1.00988744668424,2.37708763819346,1.45399427836959,1.49064452561361,1.33823896191545,2.16211037981996,1.05257920932423,1.66485218441658,1.62208227930787,2.03892696294575,2.29182296067912,1.43279475798321,1.9825169070129,2.03991538176227,1.85683190891332,1.48038835971686,2.29010202947198,2.00626162323532,2.66455016580842,1.65738790926125,2.91946400748378,2.2892776306326,2.61601124993314,2.22879947791553,3.09369717107604,1.742916933061,2.65223530566561,3.54533652200439,2.52636333273842,2.91660566651485,2.83093298301055,2.97118140429517,2.49457845356433,3.51708604132825,2.98069204928686,3.11331327736131,2.93246177317284,3.75270367663172,2.78825189332597,3.68300946433636,3.25928414398712,3.24795215655923,3.36893590194802,2.1267377543418,3.4281110315687,2.8055337403986,3.15556819637543,2.65903600660737,3.75436967580595,2.33391683632628,3.83937394956851,1.30908247670059,3.94945331864428,2.02566134203836,3.58431293071511,1.78450814768832,4.2865777670227,1.60443361470052,4.40543581442528,1.08875389607206,4.45051236106688,1.84815516491945,4.07005069194242,1.47069991274975,4.82978566665182,1.50975052590061,4.14217193123143,2.65756767152551,4.80728575272476,3.0662415172618,4.34290892274548,3.22060907288919,4.59946752688308,2.48333816584528,4.6430350028499,4.43874579703844,4.04522655101887,3.93673408138853,4.52316706416568,3.83162438466674,4.16101008873798,4.52316833329144,4.54478221876423,5.17909780083677,3.98866489838819,4.63126184572959,4.47343535413216,4.56438294255547,4.05758067756106,5.22503080314711,4.4880974642154,5.45602217497841,3.96290535066911,4.87847221904459,4.45061707222361,4.83831678217314,3.99910862927343,5.47512981099327,4.45769519652093,5.33099081681677,3.95919971766037,4.73024713995787,4.44822964356355,4.71222176830849,3.96834273972199,5.32793214442031,5.03822613488218,5.17514567263525,4.50685114088698,4.63075353644961,5.01239799420767,4.57794899936841,4.53000801830746,5.16618542576103,4.4793709217432,4.44711202316357,5.07526270841369,4.92001281694895,4.56998446235943,4.97532858416904,4.97419643632717,4.33086379670175, +4.4444045413565,3.89985113632693,5.10320326864326,4.28025410570219,4.61149943522134,4.40906901259186,4.91683313132423,3.71229536483506,4.35686187293603,2.92390947272437,5.07615511787583,3.17157741568051,4.61807693826462,3.39187340157876,4.7848075699701,2.64963147428332,4.33101678220624,3.10678207116889,4.42996195472423,2.3885811309159,4.77431009332478,2.79924876843532,4.04985770439005,2.7714733492366,3.78407166232917,3.42286693227088,3.91297422007815,2.75380055495228,4.22697092582099,3.0585765953901,3.56204246242817,3.2073577273341,3.15461285611718,4.02708214029951,3.37003361289464,3.42314494177418,3.60316281875962,3.62659507422418,3.03393629922222,3.92176860228613,3.67515311499622,3.79940709072906,3.3114605260756,4.32749225713445,3.22197724806559,4.19465206882724,3.84802153349799,4.05603462803915,4.29490838578165,3.40838384768169,4.0009509255984,4.02308271562849,3.84065813556953,3.7584180136263,4.5215966233911,3.78267625873465,4.76495601488812,3.32729309737827,4.49825478057148,4.00143936441451,4.30478456322339,3.60894523574301,5.0019076713522,3.80799826851999,4.951205530029,4.03248616841555,4.55239092990036,4.63791961023151,4.44319519410264,4.21417598806607,5.0849424474251,4.55146399644759,4.10926999947272,4.53422790988024,4.53982272201963,4.00612750298786,4.67190923088775,4.42330314970915,4.01587073334882,4.23924018113773,3.40339821531337,4.62034818872927,3.88820370994402,4.20069371825489,3.99098111338481,4.49254640089309,3.35019671648004,4.4692741234672,4.67316497313243,4.51279675884624,4.13481435448269,4.9304620531333,4.11019343114538,4.62202244290924,4.70798421683419,4.94899623879818,4.51866646098905,4.58703646424276,5.08637135529469,5.03793988042667,4.54703565309067,5.02370287579946,5.0516263327627,4.50313493236362,4.44948550757377,0.514360258217849,4.38052700835492,-0.263222813303038,4.80945609101418,0.182854056903988,4.03517182898671,0.0834830887746911,3.89211652114567,-0.573666437489841,3.18496884945631,-0.293194776517677,3.33111268805646,-0.780029366987605,3.68795112599636,-0.108174835565239,1.91749299026654, +-1.47521041472016,1.26143627829999,-1.86032309026825,1.84736337040985,-1.97864638528401,1.39216513100209,-1.36912465062293,2.18999265921371,0.360846007976608,1.63598877736289,-0.106788931521202,2.16714312097806,-0.178193499457753,1.75630695370702,0.419147593559413,2.88852073909218,0.346036664884572,3.23352128386942,0.983670856132431,2.80849197043572,0.879591805577632,3.40907321091119,0.473506948270861,0.677158193725866,0.626427107619782,0.853874552246961,-0.0766902839841634,1.06328170551247,0.420536360649737,0.380971761462608,0.175473352434376,-0.182704353032513,1.38207080971872,-0.22558421081883,0.658355357665142,0.123641788743257,1.06960575973488,-0.600780076829294,1.04104532512197,-0.758439633203638,2.41525421447637,-0.980875315776658,1.72523602278635,-0.539931242376526,2.03612831298659,-1.2484923467982,2.18956852624769,-1.09193720005536,3.50840893186771,-1.45577236561775,2.88133101801244,-0.958884373510924,3.09154047372912,-1.6187281325522,3.39188852416257,-2.72533652271693,3.25914413162285,-2.1112496490884,2.81012353763934,-2.2226343263606,3.3343534516393,-2.60110305801723,2.67444163833212,-3.65032540898385,3.50122238896364,-3.11686601134747,2.93129978123183,-3.16166265529406,3.52737378679055,-3.60394851054363,2.88412116924708,-3.56962022903901,2.10099017391686,-3.00301465381845,1.56400895463692,-3.08339785925285,2.15633445611038,-3.48640141114777,1.48776969119193,-1.76902570089985,1.44687056278242,-2.4457649195293,1.7943561195369,-2.23164077243567,1.23626848390686,-1.96100415918289,1.94723824820858,-1.5396803604986,-0.291844543338313,-1.42462017920239,0.460141717749106,-1.86638666207345,0.208729079541444,-1.13170332260764,0.0113396854608165,-0.251180730660499,-1.62594283209781,-0.376411439900066,-0.875583283849433,-0.717721462725873,-1.25224415035597,0.0418775372370734,-1.2106323558807,-2.82216087960071,-1.47812331387152,-2.12888387473899,-1.83695154890929,-2.3703466072961,-1.29013649041351,-2.5721802641276,-2.04422791902174,-0.217552321414542,-3.59631628979155,0.553287579890039,-3.47304198473524,0.0341801440832179, +-3.17666649738555,0.319867241950004,-3.90314677230211,-2.7627531484983,-0.0249554105856957,-3.37629147234286,0.4577053739249,-3.23709245070373,-0.145277515102073,-2.8972090784937,0.557481334735846,2.17255331527282,3.45866840061712,2.34780556007937,2.84187597775229,2.33195186157264,3.44298796342867,2.03987121499148,2.87216825624791,-0.704114664544156,5.46984919265494,-1.47839892657163,5.37047822452568,-1.11842834313123,5.03897202321179,-1.04946984391235,5.81655509473268,3.57904367117803,3.03223098023958,4.34988357248261,3.15550528529592,3.81246400911804,3.46233576780647,4.09815110698485,2.73585549288991,2.74675311094717,5.33868209183278,3.40280982291371,5.72379476738088,2.81688273080386,5.84211806239663,3.27208097021162,5.23259632773556,3.78138339308066,5.51801152377434,3.60466703455954,6.22112891537827,3.39525988129404,5.72390227074438,4.07756982534391,5.96896527895974,4.24870225001188,5.11388641437681,4.29158210779822,5.8376018664304,3.94235610823613,5.42635146436067,4.66677797380868,5.45491189897355,4.46516377916012,4.92080397032172,4.68759946173313,5.61082216201175,4.24665538833299,5.29992987181152,4.95521649275468,5.14648965855042,4.54447542402923,4.84805997588416,4.90831058959162,5.47513788973943,4.41142259748481,5.26492843402274,5.07126635652607,4.96458038358928,5.08523984545089,4.30758160391279,4.47115297182236,4.75660219789632,4.58253764909457,4.23237228389634,4.9610063807512,4.89228409720354,4.50126963043368,3.49325118965536,3.9678102327973,4.06317379738717,4.01260687674388,3.46709979182844,4.45489273199344,4.11035240937193,4.56784580502815,2.58079406206015,4.00124022980761,3.11777528134011,4.081623435242,2.52544977986664,4.48462698713692,3.19401454478508,4.42809109783998,4.39857292267327,5.10483031646943,4.05108736591881,4.89070616937581,4.60917500154885,4.62006955612302,3.89820523724712,5.04072686887855,4.00294929018061,4.30604352941274,4.20033868426123,4.59896038600749,3.75153665197293,4.71402056730369,4.50352291306036,4.20360832016857,1.58323400650994,4.54349169237859,2.28599285634785,4.06915239017315, +2.16567075183148,4.68269071401772,1.68300996732087,4.61325031187588,1.80520745049824,4.4114166550444,1.05111602189,4.86323092734902,1.23910284534803,4.16995392248726,1.59793108038577,4.19482165689716,4.88077578069876,4.32005236613674,4.13041623245039,4.66136238896253,4.50707709895692,3.90176338899959,4.46546530448166,0.618320700875363,6.59477727530191,1.3254683725647,6.31430561432971,1.17932453396459,6.80114020479965,0.822486096024652,6.12928567337729 + } + UVIndex: *1584 { + a: 0,1,2,1,0,3,2,1,0,4,5,6,5,4,7,7,4,5,8,9,10,9,8,11,11,8,9,12,13,14,13,12,15,15,12,13,16,17,18,17,16,19,19,16,17,20,21,22,21,20,23,23,20,21,24,25,26,25,24,27,27,24,25,28,29,30,29,28,31,31,28,29,32,33,34,33,32,35,35,32,33,36,37,38,37,36,39,38,37,36,40,41,42,41,40,43,43,40,41,44,45,46,45,44,47,47,44,45,48,49,50,49,48,51,50,49,48,51,48,49,52,53,54,53,52,55,54,53,52,56,57,58,57,56,59,58,57,56,60,61,62,61,60,63,63,60,61,64,65,66,65,64,67,67,64,65,68,69,70,69,68,71,71,68,69,72,73,74,73,72,75,75,72,73,76,77,78,77,76,79,79,76,77,78,77,76,80,81,82,81,80,83,82,81,80,83,80,81,84,85,86,85,84,87,86,85,84,87,84,85,59,56,57,66,65,64,70,69,68,88,89,90,89,88,91,91,88,89,90,89,88,92,93,94,93,92,95,94,93,92,95,92,93,96,97,98,97,96,99,98,97,96,99,96,97,100,101,102,101,100,103,102,101,100,104,105,106,105,104,107,106,105,104,108,109,110,109,108,111,111,108,109,74,73,72,110,109,108,112,113,114,113,112,115,114,113,112,115,112,113,116,117,118,117,116,119,118,117,116,119,116,117,120,121,122,121,120,123,122,121,120,123,120,121,124,125,126,127,128,129,129,128,127,130,131,132,131,130,133,133,130,131,134,135,136,135,134,137,137,134,135,138,139,140,139,138,141,141,138,139,140,139,138,142,143,144,143,142,145,144,143,142,145,142,143,146,147,148,147,146,149,148,147,146,149,146,147,150,151,152,151,150,153,152,151,150,153,150,151,154,155,156,157,158,159,160,161,162,163,164,165,165,164,163,162,161,160,166,167,168,167,166,169,169,166,167,170,171,172,171,170,173,173,170,171,172,171,170,174,175,176,175,174,177,177,174,175,46,45,44,176,175,174,178,179,180,179,178,181,180,179,178,181,178,179,159,158,157,156,155,154,168,167,166,182,183,184,183,182,185,184,183,182,34,33,32,185,182,183,186,187,188,187,186,189,188,187,186,189,186,187,190,191,192,191,190,193,192,191,190,193,190,191,194,195,196,195,194,197,196,195,194,197,194,195,198,199,200,199,198,201,200,199,198,201,198,199,202,203,204,203,202,205,204,203,202,205,202,203,206,207,208,207,206,209,209,206,207,210,211,212,213,214,215,215,214,213,216,217,218,218,217,216,219,220,221,221,220,219, +222,223,224,224,223,222,225,226,227,227,226,225,212,211,210,228,229,230,230,229,228,231,232,233,233,232,231,234,235,236,236,235,234,237,238,239,239,238,237,240,241,242,242,241,240,243,244,245,245,244,243,246,247,248,248,247,246,249,250,251,250,249,252,252,249,250,253,254,255,254,253,256,256,253,254,257,258,259,258,257,260,260,257,258,261,262,263,262,261,264,264,261,262,265,266,267,266,265,268,268,265,266,269,270,271,270,269,272,271,270,269,107,104,105,272,269,270,273,274,275,126,125,124,275,274,273,276,277,278,278,277,276,267,266,265,279,280,281,281,280,279,263,262,261,282,283,284,284,283,282,259,258,257,285,286,287,287,286,285,255,254,253,103,100,101,288,289,290,289,288,291,290,289,288,291,288,289,292,293,294,293,292,295,294,293,292,295,292,293,296,297,298,297,296,299,298,297,296,299,296,297,300,301,302,301,300,303,302,301,300,303,300,301,304,305,306,305,304,307,306,305,304,307,304,305,308,309,310,309,308,311,310,309,308,312,313,314,313,312,315,315,312,313,314,313,312,316,317,318,317,316,319,318,317,316,319,316,317,320,321,322,321,320,323,322,321,320,323,320,321,324,325,326,325,324,327,326,325,324,327,324,325,328,329,330,329,328,331,330,329,328,331,328,329,332,333,334,333,332,335,334,333,332,336,337,338,337,336,339,339,336,337,340,341,342,341,340,343,342,341,340,343,340,341,344,345,346,345,344,347,346,345,344,347,344,345,348,349,350,349,348,351,350,349,348,351,348,349,352,353,354,353,352,355,354,353,352,356,357,358,357,356,359,359,356,357,360,361,362,361,360,363,363,360,361,364,365,366,365,364,367,366,365,364,367,364,365,368,369,370,369,368,371,371,368,369,372,373,374,373,372,375,375,372,373,376,377,378,377,376,379,379,376,377,378,377,376,380,381,382,381,380,383,382,381,380,383,380,381,384,385,386,385,384,387,386,385,384,387,384,385,388,389,390,389,388,391,390,389,388,391,388,389,362,361,360,392,393,394,393,392,395,394,393,392,396,397,398,397,396,399,399,396,397,400,401,402,401,400,403,403,400,401,402,401,400,398,397,396,404,405,406,405,404,407,406,405,404,208,207,206,407,404,405,408,409,410,409,408,411,411,408,409, +395,392,393,358,357,356,410,409,408,355,352,353,14,13,12,370,369,368,374,373,372,338,337,336,335,332,333,412,413,414,413,412,415,415,412,413,416,417,418,417,416,419,419,416,417,418,417,416,420,421,422,421,420,423,423,420,421,424,425,426,425,424,427,427,424,425,426,425,424,428,429,430,429,428,431,430,429,428,311,308,309,431,428,429,432,433,434,433,432,435,435,432,433,436,437,438,437,436,439,439,436,437,440,441,442,441,440,443,443,440,441,444,445,446,445,444,447,447,444,445,446,445,444,448,449,450,449,448,451,451,448,449,452,453,454,453,452,455,455,452,453,454,453,452,456,457,458,457,456,459,459,456,457,458,457,456,460,461,462,461,460,463,462,461,460,463,460,461,464,465,466,465,464,467,467,464,465,468,469,470,469,468,471,471,468,469,470,469,468,472,473,474,473,472,475,474,473,472,475,472,473,476,477,478,477,476,479,478,477,476,422,421,420,479,476,477,480,481,482,481,480,483,483,480,481,466,465,464,482,481,480,450,449,448,442,441,440,438,437,436,434,433,432,414,413,412,484,485,486,485,484,487,487,484,485,251,250,249,486,485,484,132,131,130,136,135,134,62,61,60,55,52,53,488,489,490,489,488,491,490,489,488,491,488,489,492,493,494,493,492,495,495,492,493,496,497,498,497,496,499,499,496,497,39,36,37,500,501,502,501,500,503,502,501,500,503,500,501,504,505,506,505,504,507,506,505,504,507,504,505,508,509,510,509,508,511,510,509,508,511,508,509,512,513,514,513,512,515,514,513,512,515,512,513,10,9,8,516,517,518,517,516,519,518,517,516,519,516,517,520,521,522,521,520,523,522,521,520,523,520,521,524,525,526,525,524,527,526,525,524,528,529,530,529,528,531,531,528,529,530,529,528,532,533,534,533,532,535,534,533,532,535,532,533,536,537,538,537,536,539,538,537,536,540,541,542,541,540,543,543,540,541,542,541,540,544,545,546,545,544,547,547,544,545,546,545,544,539,536,537,527,524,525,3,0,1,6,5,4,18,17,16,22,21,20,26,25,24,30,29,28,498,497,496,548,549,550,549,548,551,551,548,549,550,549,548,42,41,40,494,493,492 + } + } + LayerElementMaterial: 0 { + Version: 101 + Name: "" + MappingInformationType: "ByPolygon" + ReferenceInformationType: "IndexToDirect" + Materials: *528 { + a: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + } + } + Layer: 0 { + Version: 100 + LayerElement: { + Type: "LayerElementNormal" + TypedIndex: 0 + } + LayerElement: { + Type: "LayerElementMaterial" + TypedIndex: 0 + } + LayerElement: { + Type: "LayerElementTexture" + TypedIndex: 0 + } + LayerElement: { + Type: "LayerElementUV" + TypedIndex: 0 + } + } + } + Geometry: 140593614728304, "Geometry::", "Mesh" { + Vertices: *576 { + a: -0.00965925826289069,0.027596359291114,-0.00258819045102525,-0.00965925826289069,0.027596359291114,0.00258819045102516,-0.00999999999999997,0.027596359291114,-9.02389274415327e-17,-0.00866025403784437,0.027596359291114,-0.00500000000000004,-0.00999999999999997,0.027596359291114,-9.02389274415327e-17,-0.00965925826289069,0.027596359291114,0.00258819045102516,-0.00965925826289069,0.027596359291114,-0.00258819045102525,-0.00965925826289069,0.027596359291114,0.00258819045102516,-0.00999999999999997,0.147596359291114,-9.02389274415327e-17,-0.00999999999999997,0.027596359291114,-9.02389274415327e-17,-0.00965925826289069,0.147596359291114,0.00258819045102516,-0.00965925826289069,0.147596359291114,0.00258819045102516,-0.00965925826289069,0.027596359291114,0.00258819045102516,-0.00999999999999997,0.147596359291114,-9.02389274415327e-17,-0.00866025403784437,0.027596359291114,0.00499999999999995,-0.00866025403784437,0.147596359291114,0.00499999999999995,-0.00866025403784437,0.147596359291114,0.00499999999999995,-0.00866025403784437,0.027596359291114,0.00499999999999995,-0.00707106781186548,0.027596359291114,0.0070710678118654,-0.00707106781186548,0.147596359291114,0.0070710678118654,-0.00707106781186548,0.147596359291114,0.0070710678118654,-0.00707106781186548,0.027596359291114,0.0070710678118654,-0.00499999999999998,0.147596359291114,0.00866025403784434,-0.00499999999999998,0.027596359291114,0.00866025403784434,-0.00499999999999998,0.027596359291114,0.00866025403784434,-0.00499999999999998,0.147596359291114,0.00866025403784434,-0.00707106781186548,0.027596359291114,0.0070710678118654,-0.00499999999999998,0.027596359291114,-0.00866025403784443,-0.00499999999999998,0.027596359291114,0.00866025403784434,-0.00707106781186548,0.027596359291114,-0.00707106781186558,-0.00866025403784437,0.027596359291114,0.00499999999999995,-0.00866025403784437,0.027596359291114,-0.00500000000000004,-0.00965925826289069,0.027596359291114,-0.00258819045102525,-0.00866025403784437,0.147596359291114,-0.00500000000000004,-0.00866025403784437,0.027596359291114,-0.00500000000000004, +-0.00965925826289069,0.147596359291114,-0.00258819045102525,-0.00965925826289069,0.147596359291114,-0.00258819045102525,-0.00965925826289069,0.027596359291114,-0.00258819045102525,-0.00866025403784437,0.147596359291114,-0.00500000000000004,-0.00999999999999997,0.027596359291114,-9.02389274415327e-17,-0.00965925826289069,0.147596359291114,0.00258819045102516,-0.00965925826289069,0.147596359291114,-0.00258819045102525,-0.00999999999999997,0.147596359291114,-9.02389274415327e-17,-0.00866025403784437,0.147596359291114,0.00499999999999995,-0.00999999999999997,0.147596359291114,-9.02389274415327e-17,-0.00965925826289069,0.147596359291114,-0.00258819045102525,-0.00965925826289069,0.147596359291114,0.00258819045102516,-0.00866025403784437,0.147596359291114,0.00499999999999995,-0.00866025403784437,0.147596359291114,-0.00500000000000004,-0.00866025403784437,0.147596359291114,-0.00500000000000004,-0.00707106781186548,0.147596359291114,0.0070710678118654,-0.00707106781186548,0.147596359291114,0.0070710678118654,-0.00707106781186548,0.147596359291114,-0.00707106781186558,-0.00707106781186548,0.147596359291114,-0.00707106781186558,-0.00499999999999998,0.147596359291114,0.00866025403784434,-0.00499999999999998,0.147596359291114,0.00866025403784434,-0.00499999999999998,0.147596359291114,-0.00866025403784443,-0.00499999999999998,0.147596359291114,-0.00866025403784443,-0.00258819045102519,0.147596359291114,0.00965925826289065,-0.00258819045102519,0.147596359291114,0.00965925826289065,-0.00258819045102519,0.147596359291114,0.00965925826289065,-0.00258819045102519,0.027596359291114,0.00965925826289065,-0.00258819045102519,0.027596359291114,0.00965925826289065,-0.00258819045102519,0.147596359291114,0.00965925826289065,-0.00258819045102519,0.027596359291114,-0.00965925826289074,-0.00258819045102519,0.027596359291114,0.00965925826289065,-0.00499999999999998,0.027596359291114,0.00866025403784434,-0.00499999999999998,0.027596359291114,-0.00866025403784443,-0.00707106781186548,0.027596359291114,0.0070710678118654,-0.00258819045102519,0.027596359291114,-0.00965925826289074, +-0.00499999999999998,0.147596359291114,-0.00866025403784443,-0.00258819045102519,0.027596359291114,-0.00965925826289074,-0.00499999999999998,0.027596359291114,-0.00866025403784443,-0.00258819045102519,0.147596359291114,-0.00965925826289074,-0.00499999999999998,0.027596359291114,-0.00866025403784443,-0.00258819045102519,0.027596359291114,-0.00965925826289074,-0.00499999999999998,0.147596359291114,-0.00866025403784443,-0.00258819045102519,0.147596359291114,-0.00965925826289074,-0.00258819045102519,0.147596359291114,-0.00965925826289074,-0.00258819045102519,0.147596359291114,-0.00965925826289074,1.12798659301916e-17,0.147596359291114,0.00999999999999989,1.12798659301916e-17,0.147596359291114,0.00999999999999989,1.12798659301916e-17,0.147596359291114,0.00999999999999989,1.12798659301916e-17,0.027596359291114,0.00999999999999989,1.12798659301916e-17,0.027596359291114,0.00999999999999989,1.12798659301916e-17,0.147596359291114,0.00999999999999989,1.12798659301916e-17,0.027596359291114,-0.0100000000000001,1.12798659301916e-17,0.027596359291114,0.00999999999999989,-0.00258819045102519,0.027596359291114,0.00965925826289065,1.12798659301916e-17,0.027596359291114,-0.0100000000000001,1.12798659301916e-17,0.027596359291114,-0.0100000000000001,1.12798659301916e-17,0.147596359291114,-0.0100000000000001,1.12798659301916e-17,0.027596359291114,-0.0100000000000001,1.12798659301916e-17,0.147596359291114,-0.0100000000000001,1.12798659301916e-17,0.147596359291114,-0.0100000000000001,1.12798659301916e-17,0.147596359291114,-0.0100000000000001,0.00258819045102522,0.147596359291114,0.00965925826289065,0.00258819045102522,0.147596359291114,0.00965925826289065,0.00258819045102522,0.147596359291114,0.00965925826289065,0.00258819045102522,0.027596359291114,0.00965925826289065,0.00258819045102522,0.027596359291114,0.00965925826289065,0.00258819045102522,0.147596359291114,0.00965925826289065,0.00258819045102522,0.027596359291114,-0.00965925826289074,0.00258819045102522,0.027596359291114,0.00965925826289065,1.12798659301916e-17,0.027596359291114,0.00999999999999989, +0.00258819045102522,0.027596359291114,-0.00965925826289074,0.00258819045102522,0.027596359291114,-0.00965925826289074,0.00258819045102522,0.147596359291114,-0.00965925826289074,0.00258819045102522,0.027596359291114,-0.00965925826289074,0.00258819045102522,0.147596359291114,-0.00965925826289074,0.00258819045102522,0.147596359291114,-0.00965925826289074,0.00258819045102522,0.147596359291114,-0.00965925826289074,0.005,0.147596359291114,0.00866025403784434,0.005,0.147596359291114,0.00866025403784434,0.005,0.147596359291114,0.00866025403784434,0.005,0.027596359291114,0.00866025403784434,0.005,0.027596359291114,0.00866025403784434,0.005,0.147596359291114,0.00866025403784434,0.005,0.027596359291114,-0.00866025403784443,0.005,0.027596359291114,0.00866025403784434,0.00258819045102522,0.027596359291114,0.00965925826289065,0.005,0.027596359291114,-0.00866025403784443,0.005,0.027596359291114,-0.00866025403784443,0.005,0.147596359291114,-0.00866025403784443,0.005,0.027596359291114,-0.00866025403784443,0.005,0.147596359291114,-0.00866025403784443,0.005,0.147596359291114,-0.00866025403784443,0.005,0.147596359291114,-0.00866025403784443,0.00707106781186546,0.147596359291114,0.0070710678118654,0.00707106781186546,0.147596359291114,0.0070710678118654,0.00707106781186546,0.147596359291114,0.0070710678118654,0.00707106781186546,0.027596359291114,0.0070710678118654,0.00707106781186546,0.027596359291114,0.0070710678118654,0.00707106781186546,0.147596359291114,0.0070710678118654,0.00707106781186546,0.027596359291114,-0.00707106781186558,0.00707106781186546,0.027596359291114,0.0070710678118654,0.005,0.027596359291114,0.00866025403784434,0.00707106781186546,0.027596359291114,-0.00707106781186558,0.00707106781186546,0.027596359291114,-0.00707106781186558,0.00707106781186546,0.147596359291114,-0.00707106781186558,0.00707106781186546,0.027596359291114,-0.00707106781186558,0.00707106781186546,0.147596359291114,-0.00707106781186558,0.00707106781186546,0.147596359291114,-0.00707106781186558,0.00707106781186546,0.147596359291114,-0.00707106781186558, +0.00866025403784439,0.147596359291114,0.00499999999999995,0.00866025403784439,0.147596359291114,0.00499999999999995,0.00866025403784439,0.027596359291114,0.00499999999999995,0.00866025403784439,0.147596359291114,0.00499999999999995,0.00866025403784439,0.027596359291114,0.00499999999999995,0.00866025403784439,0.147596359291114,0.00499999999999995,0.00965925826289066,0.027596359291114,0.00258819045102516,0.00965925826289066,0.147596359291114,0.00258819045102516,0.00965925826289066,0.027596359291114,0.00258819045102516,0.00965925826289066,0.147596359291114,0.00258819045102516,0.00999999999999999,0.027596359291114,-9.02389274415327e-17,0.00999999999999999,0.147596359291114,-9.02389274415327e-17,0.00999999999999999,0.027596359291114,-9.02389274415327e-17,0.00999999999999999,0.147596359291114,-9.02389274415327e-17,0.00965925826289066,0.027596359291114,-0.00258819045102525,0.00965925826289066,0.147596359291114,-0.00258819045102525,0.00965925826289066,0.027596359291114,-0.00258819045102525,0.00965925826289066,0.147596359291114,-0.00258819045102525,0.00866025403784439,0.027596359291114,-0.00500000000000004,0.00866025403784439,0.147596359291114,-0.00500000000000004,0.00866025403784439,0.027596359291114,-0.00500000000000004,0.00866025403784439,0.147596359291114,-0.00500000000000004,0.00866025403784439,0.147596359291114,-0.00500000000000004,0.00866025403784439,0.147596359291114,-0.00500000000000004,0.00965925826289066,0.147596359291114,0.00258819045102516,0.00965925826289066,0.147596359291114,0.00258819045102516,0.00965925826289066,0.147596359291114,-0.00258819045102525,0.00965925826289066,0.147596359291114,-0.00258819045102525,0.00999999999999999,0.147596359291114,-9.02389274415327e-17,0.00999999999999999,0.147596359291114,-9.02389274415327e-17,0.00866025403784439,0.027596359291114,-0.00500000000000004,0.00707106781186546,0.027596359291114,0.0070710678118654,0.00866025403784439,0.027596359291114,-0.00500000000000004,0.00866025403784439,0.027596359291114,0.00499999999999995,0.00866025403784439,0.027596359291114,0.00499999999999995, +0.00965925826289066,0.027596359291114,-0.00258819045102525,0.00965925826289066,0.027596359291114,-0.00258819045102525,0.00965925826289066,0.027596359291114,0.00258819045102516,0.00965925826289066,0.027596359291114,0.00258819045102516,0.00999999999999999,0.027596359291114,-9.02389274415327e-17,0.00999999999999999,0.027596359291114,-9.02389274415327e-17,-0.00707106781186548,0.147596359291114,-0.00707106781186558,-0.00707106781186548,0.027596359291114,-0.00707106781186558,-0.00707106781186548,0.027596359291114,-0.00707106781186558,-0.00707106781186548,0.147596359291114,-0.00707106781186558,-0.00707106781186548,0.027596359291114,-0.00707106781186558,-0.00866025403784437,0.027596359291114,0.00499999999999995,-0.00866025403784437,0.027596359291114,-0.00500000000000004 + } + PolygonVertexIndex: *552 { + a: 0,1,-3,1,0,-4,4,5,-7,7,8,-10,8,7,-11,11,12,-14,14,10,-8,10,14,-16,16,17,-12,18,15,-15,15,18,-20,20,21,-17,18,22,-20,22,18,-24,24,21,-26,26,27,-29,26,29,-28,30,29,-27,30,3,-30,1,3,-31,31,6,-6,32,33,-35,33,32,-36,36,37,-39,9,35,-33,35,9,-9,13,39,-37,39,13,-13,37,36,-40,40,41,-43,41,40,-44,44,45,-47,47,46,-46,41,43,-49,49,47,-46,48,43,-51,51,47,-50,48,50,-53,53,51,-50,52,50,-55,55,51,-54,20,25,-22,52,54,-57,57,55,-54,56,54,-59,59,55,-58,23,60,-23,60,23,-62,62,24,-64,28,64,-66,28,27,-65,66,67,-69,69,67,-67,70,71,-73,71,70,-74,74,75,-77,77,76,-76,56,58,-79,79,59,-58,78,58,-81,81,59,-80,61,82,-61,82,61,-84,84,62,-86,65,86,-88,65,64,-87,88,69,-67,89,69,-89,73,90,-72,90,73,-92,75,92,-78,93,77,-93,78,80,-95,95,81,-80,94,80,-97,97,81,-96,83,98,-83,98,83,-100,100,84,-102,87,102,-104,87,86,-103,104,89,-89,105,89,-105,91,106,-91,106,91,-108,92,108,-94,109,93,-109,94,96,-111,111,97,-96,110,96,-113,113,97,-112,99,114,-99,114,99,-116,116,100,-118,103,118,-120,103,102,-119,120,105,-105,121,105,-121,107,122,-107,122,107,-124,108,124,-110,125,109,-125,110,112,-127,127,113,-112,126,112,-129,129,113,-128,115,130,-115,130,115,-132,132,116,-134,119,134,-136,119,118,-135,136,121,-121,137,121,-137,123,138,-123,138,123,-140,124,140,-126,141,125,-141,126,128,-143,143,129,-128,142,128,-145,145,129,-144,130,146,-148,146,130,-132,132,133,-149,149,148,-134,150,147,-147,147,150,-152,148,149,-153,153,152,-150,154,151,-151,151,154,-156,152,153,-157,157,156,-154,158,155,-155,155,158,-160,156,157,-161,161,160,-158,162,159,-159,159,162,-164,160,161,-165,165,164,-162,138,163,-163,163,138,-140,164,165,-141,141,140,-166,142,144,-167,167,145,-144,166,144,-169,169,145,-168,166,168,-171,171,169,-168,170,168,-173,173,169,-172,135,134,-175,175,137,-137,176,137,-176,135,174,-178,178,176,-176,177,174,-180,180,176,-179,177,179,-182,182,180,-179,181,179,-184,184,180,-183,117,133,-117,101,117,-101,85,101,-85,63,85,-63,72,185,-71,185,72,-187,187,74,-189,67,189,-69,68,189,-191,189,31,-191,34,185,-187,185,34,-34,38,191,-189,191,38,-38,187,188,-192, +190,31,-6,12,11,-18,17,16,-22,76,188,-75,25,63,-25 + } + GeometryVersion: 124 + LayerElementNormal: 0 { + Version: 101 + Name: "" + MappingInformationType: "ByVertice" + ReferenceInformationType: "Direct" + Normals: *576 { + a: 0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,-0,1,0,-0,1,0,-0,1,0,-0.965925826289069,0,0.258819045102518,-1,0,-2.26760126806314e-15,-1,0,-2.26760126806314e-15,-0.965925826289069,0,0.258819045102518,0.965925826289069,-0,-0.258819045102518,0.965925826289069,-0,-0.258819045102518,1,-0,2.26760126806314e-15,-0.866025403784437,0,0.500000000000002,-0.866025403784437,0,0.500000000000002,0.866025403784437,-0,-0.500000000000002,0.866025403784437,-0,-0.500000000000002,-0.707106781186549,0,0.707106781186546,-0.707106781186549,0,0.707106781186546,0.707106781186549,-0,-0.707106781186546,0.707106781186549,-0,-0.707106781186546,-0.500000000000004,0,0.866025403784436,-0.500000000000004,0,0.866025403784436,0.500000000000004,-0,-0.866025403784436,0.500000000000004,-0,-0.866025403784436,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,-0,1,0,-0.965925826289069,0,-0.25881904510252,-0.866025403784442,0,-0.499999999999993,-0.866025403784442,0,-0.499999999999993,-0.965925826289069,0,-0.25881904510252,0.965925826289069,-0,0.25881904510252,0.965925826289069,-0,0.25881904510252,0.866025403784442,-0,0.499999999999993,1,-0,2.26760126806314e-15,0,1,-0,0,1,-0,0,1,-0,0,1,-0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,0,1,-0,-0,-1,0,0,1,-0,-0,-1,0,0,1,-0,-0,-1,0,0,1,-0,-0,-1,0,0,1,-0,-0,-1,0,0,1,-0,-0,-1,0,-0.258819045102511,0,0.965925826289071,-0.258819045102511,0,0.965925826289071,0.258819045102511,-0,-0.965925826289071,0.258819045102511,-0,-0.965925826289071,0,-1,-0,0,-1,-0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0.499999999999992,0,-0.866025403784443,-0.258819045102527,0,-0.965925826289067,-0.499999999999992,0,-0.866025403784443,-0.258819045102527,0,-0.965925826289067,0.499999999999992,-0,0.866025403784443,0.258819045102527,-0,0.965925826289067,0.499999999999992,-0,0.866025403784443,0.258819045102527,-0,0.965925826289067,0,1,-0,-0,-1,0,0,1,-0,-0,-1,0,0,0,1,0,0,1,-0,-0,-1,-0,-0,-1,0,-1,-0,0,-1,-0,-0,1,0,-0,1,0,0,0,-1,0,0,-1,-0,-0,1,-0,-0,1,0,1,-0,-0,-1,0,0,1,-0,-0,-1,0,0.25881904510251,0,0.965925826289071,0.25881904510251,0,0.965925826289071,-0.25881904510251,-0,-0.965925826289071, +-0.25881904510251,-0,-0.965925826289071,0,-1,-0,0,-1,-0,-0,1,0,-0,1,0,0.258819045102527,0,-0.965925826289067,0.258819045102527,0,-0.965925826289067,-0.258819045102527,-0,0.965925826289067,-0.258819045102527,-0,0.965925826289067,0,1,-0,-0,-1,0,0,1,-0,-0,-1,0,0.500000000000008,0,0.866025403784434,0.500000000000008,0,0.866025403784434,-0.500000000000008,-0,-0.866025403784434,-0.500000000000008,-0,-0.866025403784434,0,-1,-0,0,-1,-0,-0,1,0,-0,1,0,0.499999999999996,0,-0.866025403784441,0.499999999999996,0,-0.866025403784441,-0.499999999999996,-0,0.866025403784441,-0.499999999999996,-0,0.866025403784441,0,1,-0,-0,-1,0,0,1,-0,-0,-1,0,0.707106781186548,0,0.707106781186548,0.707106781186548,0,0.707106781186548,-0.707106781186548,-0,-0.707106781186548,-0.707106781186548,-0,-0.707106781186548,0,-1,-0,0,-1,-0,-0,1,0,-0,1,0,0.707106781186545,0,-0.70710678118655,0.707106781186545,0,-0.70710678118655,-0.707106781186545,-0,0.70710678118655,-0.707106781186545,-0,0.70710678118655,0,1,-0,-0,-1,0,0,1,-0,-0,-1,0,0.866025403784438,0,0.500000000000001,0.866025403784438,0,0.500000000000001,-0.866025403784438,-0,-0.500000000000001,-0.866025403784438,-0,-0.500000000000001,0.965925826289069,0,0.258819045102518,0.965925826289069,0,0.258819045102518,-0.965925826289069,-0,-0.258819045102518,-0.965925826289069,-0,-0.258819045102518,1,0,-2.23960619067965e-15,1,0,-2.23960619067965e-15,-1,-0,2.23960619067965e-15,-1,-0,2.23960619067965e-15,0.965925826289068,0,-0.25881904510252,0.965925826289068,0,-0.25881904510252,-0.965925826289068,-0,0.25881904510252,-0.965925826289068,-0,0.25881904510252,0.866025403784443,0,-0.499999999999992,0.866025403784443,0,-0.499999999999992,-0.866025403784443,-0,0.499999999999992,-0.866025403784443,-0,0.499999999999992,0,1,-0,-0,-1,0,0,1,-0,-0,-1,0,0,1,-0,-0,-1,0,0,1,-0,-0,-1,0,0,-1,-0,-0,1,0,-0,1,0,0,-1,-0,-0,1,0,0,-1,-0,-0,1,0,0,-1,-0,-0,1,0,0,-1,-0,-0,1,0,-0.707106781186546,0,-0.707106781186549,-0.707106781186546,0,-0.707106781186549,0.707106781186546,-0,0.707106781186549,0.707106781186546,-0,0.707106781186549,-0,1,0,-0,1,0, +0.866025403784442,-0,0.499999999999993 + } + } + LayerElementUV: 0 { + Version: 101 + Name: "" + MappingInformationType: "ByPolygonVertex" + ReferenceInformationType: "IndexToDirect" + UV: *288 { + a: -1.48363628162332,2.47077565973539,-1.48363628162332,2.26698113603262,-1.47022125260326,2.36887839788401,-1.52296715662514,2.56572879158479,-2.05393340367112,0,-2.15670993297825,4.72440944881889,-2.15670993297825,0,-2.05393340367112,4.72440944881889,-1.42387791822959,0,-1.52665444753671,4.72440944881889,-1.52665444753671,0,-1.42387791822959,4.72440944881889,-0.693285480417275,0,-0.796062009724401,4.72440944881889,-0.796062009724401,0,-0.693285480417275,4.72440944881889,-0.0147212868170292,0,0.0880552424900996,4.72440944881889,-0.0147212868170292,4.72440944881889,0.0880552424900996,0,-1.5855335434747,2.09048990135387,-1.66707164630405,2.70983328126371,-1.66707164630405,2.02792351450431,-1.5855335434747,2.64726689441414,-1.52296715662514,2.17202800418322,-2.85046208608959,0,-2.95323861539672,4.72440944881889,-2.95323861539672,0,-2.85046208608959,4.72440944881889,-2.54051469662481,0,-2.64329122593194,4.72440944881889,-2.64329122593194,0,-2.54051469662481,4.72440944881889,1.48363628162332,2.26698113603262,1.48363628162332,2.47077565973539,1.47022125260326,2.36887839788401,1.52296715662514,2.17202800418322,1.52296715662514,2.56572879158479,1.5855335434747,2.09048990135387,1.5855335434747,2.64726689441414,1.66707164630405,2.02792351450431,1.66707164630405,2.70983328126371,1.76202477815345,1.98859263950248,0.764120642145804,0,0.866897171452931,4.72440944881889,0.764120642145804,4.72440944881889,0.866897171452931,0,-1.76202477815345,2.74916415626553,-1.76202477815345,1.98859263950248,-2.57718167446137,4.72440944881889,-2.6799582037685,0,-2.57718167446137,0,-2.6799582037685,4.72440944881889,1.76202477815345,2.74916415626553,1.86392204000484,1.97517761048243,1.48738698680255,0,1.59016351610968,4.72440944881889,1.48738698680255,4.72440944881889,1.59016351610968,0,-1.86392204000484,2.76257918528558,-1.86392204000484,1.97517761048243,-2.10578834101877,4.72440944881889,-2.2085648703259,0,-2.10578834101877,0,-2.2085648703259,4.72440944881889,1.86392204000484,2.76257918528558,1.96581930185623,1.98859263950248, +2.10578834101871,0,2.20856487032584,4.72440944881889,2.10578834101871,4.72440944881889,2.20856487032584,0,-1.96581930185623,2.74916415626553,-1.96581930185623,1.98859263950248,-1.48738698680247,4.72440944881889,-1.5901635161096,0,-1.48738698680247,0,-1.5901635161096,4.72440944881889,1.96581930185623,2.74916415626553,2.06077243370563,2.02792351450431,2.57718167446136,0,2.67995820376849,4.72440944881889,2.57718167446136,4.72440944881889,2.67995820376849,0,-2.06077243370563,2.70983328126371,-2.06077243370563,2.02792351450431,-0.7641206421458,4.72440944881889,-0.866897171452927,0,-0.7641206421458,0,-0.866897171452927,4.72440944881889,2.06077243370563,2.70983328126371,2.14231053653497,2.09048990135387,2.86944231047049,0,2.97221883977762,4.72440944881889,2.86944231047049,4.72440944881889,2.97221883977762,0,-2.14231053653497,2.64726689441414,-2.14231053653497,2.09048990135387,0.014721286816971,4.72440944881889,-0.0880552424901542,0,0.014721286816971,0,-0.0880552424901542,4.72440944881889,2.14231053653497,2.64726689441414,2.20487692338454,2.17202800418322,2.96265316968566,4.72440944881889,3.06542969899279,0,3.06542969899279,4.72440944881889,2.96265316968566,0,2.95323861539671,0,2.85046208608958,4.72440944881889,2.85046208608958,0,2.95323861539671,4.72440944881889,2.64329122593195,0,2.54051469662482,4.72440944881889,2.54051469662482,0,2.64329122593195,4.72440944881889,2.15670993297821,0,2.05393340367108,4.72440944881889,2.05393340367108,0,2.15670993297821,4.72440944881889,1.52665444753675,0,1.42387791822963,4.72440944881889,1.42387791822963,0,1.52665444753675,4.72440944881889,0.79606200972443,0,0.693285480417299,4.72440944881889,0.693285480417299,0,0.79606200972443,4.72440944881889,2.20487692338454,2.56572879158479,2.24420779838636,2.26698113603262,2.24420779838636,2.47077565973539,2.25762282740641,2.36887839788401,-2.20487692338454,2.56572879158479,-2.20487692338454,2.17202800418322,-2.24420779838636,2.47077565973539,-2.24420779838636,2.26698113603262,-2.25762282740641,2.36887839788401,-2.97221883977758,0,-2.86944231047045, +4.72440944881889,-2.97221883977758,4.72440944881889,-2.86944231047045,0,-2.96265316968567,0,-3.06542969899279,4.72440944881889,-3.06542969899279,0,-2.96265316968567,4.72440944881889 + } + UVIndex: *552 { + a: 0,1,2,1,0,3,2,1,0,4,5,6,5,4,7,7,4,5,8,9,10,9,8,11,11,8,9,12,13,14,13,12,15,15,12,13,16,17,18,17,16,19,19,16,17,20,21,22,20,23,21,24,23,20,24,3,23,1,3,24,3,0,1,25,26,27,26,25,28,28,25,26,29,30,31,30,29,32,32,29,30,6,5,4,31,30,29,33,34,35,34,33,36,35,34,33,36,33,34,34,36,37,37,36,34,37,36,38,38,36,37,37,38,39,39,38,37,39,38,40,40,38,39,18,17,16,39,40,41,41,40,39,41,40,42,42,40,41,43,44,45,44,43,46,46,43,44,22,47,48,22,21,47,22,21,20,47,21,22,49,50,51,50,49,52,51,50,49,52,49,50,41,42,53,53,42,41,53,42,54,54,42,53,55,56,57,56,55,58,58,55,56,48,59,60,48,47,59,48,47,22,59,47,48,61,62,63,62,61,64,63,62,61,64,61,62,53,54,65,65,54,53,65,54,66,66,54,65,67,68,69,68,67,70,70,67,68,60,71,72,60,59,71,60,59,48,71,59,60,73,74,75,74,73,76,75,74,73,76,73,74,65,66,77,77,66,65,77,66,78,78,66,77,79,80,81,80,79,82,82,79,80,72,83,84,72,71,83,72,71,60,83,71,72,85,86,87,86,85,88,87,86,85,88,85,86,77,78,89,89,78,77,89,78,90,90,78,89,91,92,93,92,91,94,94,91,92,84,95,96,84,83,95,84,83,72,95,83,84,97,98,99,98,97,100,99,98,97,100,97,98,89,90,101,101,90,89,101,90,102,102,90,101,103,104,105,104,103,106,106,103,104,105,104,103,107,108,109,108,107,110,109,108,107,110,107,108,111,112,113,112,111,114,113,112,111,114,111,112,115,116,117,116,115,118,117,116,115,118,115,116,119,120,121,120,119,122,121,120,119,122,119,120,123,124,125,124,123,126,125,124,123,126,123,124,101,102,127,127,102,101,127,102,128,128,102,127,127,128,129,129,128,127,129,128,130,130,128,129,96,95,131,96,95,84,131,95,96,96,131,132,132,131,96,132,131,133,133,131,132,132,133,134,134,133,132,134,133,135,135,133,134,93,92,91,81,80,79,69,68,67,57,56,55,136,137,138,137,136,139,139,136,137,21,23,20,20,23,24,23,3,24,140,141,142,141,140,143,143,140,141,27,26,25,142,141,140,24,3,1,10,9,8,14,13,12,138,137,136,45,44,43 + } + } + LayerElementMaterial: 0 { + Version: 101 + Name: "" + MappingInformationType: "ByPolygon" + ReferenceInformationType: "IndexToDirect" + Materials: *184 { + a: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + } + } + Layer: 0 { + Version: 100 + LayerElement: { + Type: "LayerElementNormal" + TypedIndex: 0 + } + LayerElement: { + Type: "LayerElementMaterial" + TypedIndex: 0 + } + LayerElement: { + Type: "LayerElementTexture" + TypedIndex: 0 + } + LayerElement: { + Type: "LayerElementUV" + TypedIndex: 0 + } + } + } + Geometry: 140593624419968, "Geometry::", "Mesh" { + Vertices: *2304 { + a: -0.0772740661031255,0.22,-0.0207055236082018,-0.0772740661031255,0.22,0.0207055236082015,-0.08,0.22,-1.24078525232107e-16,-0.0692820323027551,0.22,0.0399999999999999,-0.08,0.22,-1.24078525232107e-16,-0.0772740661031255,0.22,0.0207055236082015,-0.0772740661031255,0.22,-0.0207055236082018,-0.0772740661031255,0.22,0.0207055236082015,-0.08,0.21,-1.24078525232107e-16,-0.08,0.22,-1.24078525232107e-16,-0.0772740661031255,0.21,0.0207055236082015,-0.0772740661031255,0.21,0.0207055236082015,-0.0772740661031255,0.22,0.0207055236082015,-0.08,0.21,-1.24078525232107e-16,-0.0692820323027551,0.22,0.0399999999999999,-0.0692820323027551,0.21,0.0399999999999999,-0.0692820323027551,0.21,0.0399999999999999,-0.0692820323027551,0.22,0.0399999999999999,-0.0565685424949238,0.22,0.0565685424949236,-0.0565685424949238,0.21,0.0565685424949236,-0.0565685424949238,0.21,0.0565685424949236,-0.0565685424949238,0.22,0.0565685424949236,-0.04,0.21,0.0692820323027549,-0.04,0.22,0.0692820323027549,-0.04,0.21,0.0692820323027549,-0.0500000000000001,0.08,0.0866025403784437,-0.0565685424949238,0.21,0.0565685424949236,-0.04,0.21,0.0692820323027549,-0.0707106781186548,0.08,0.0707106781186546,-0.0707106781186548,0.08,0.0707106781186546,-0.0500000000000001,0.08,0.0866025403784437,-0.0565685424949238,0.21,0.0565685424949236,-0.0707106781186548,0.08,0.0707106781186546,-0.055,0.08,0.0952627944162883,-0.0500000000000001,0.08,0.0866025403784437,-0.0777817459305202,0.08,0.0777817459305202,-0.0866025403784439,0.08,0.0499999999999999,-0.0952627944162882,0.08,0.055,-0.0965925826289069,0.08,0.0258819045102519,-0.1,0.08,-1.24078525232107e-16,-0.106251840891797,0.08,0.0284700949612773,-0.106251840891797,0.08,0.0284700949612773,-0.1,0.08,-1.24078525232107e-16,-0.0952627944162882,0.08,0.055,-0.0952627944162883,0.08,-0.055,-0.106251840891798,0.08,-0.0284700949612772,-0.11,0.08,2.25597318603832e-17,-0.11,0.08,2.25597318603832e-17,-0.106251840891798,0.08,-0.0284700949612772,-0.106251840891798,0.08,-0.0284700949612772,-0.11,0.07,2.25597318603832e-17,-0.11,0.08,2.25597318603832e-17, +-0.106251840891798,0.07,-0.0284700949612772,-0.11,0.08,2.25597318603832e-17,-0.11,0.07,2.25597318603832e-17,-0.106251840891798,0.08,-0.0284700949612772,-0.106251840891797,0.07,0.0284700949612773,-0.106251840891797,0.08,0.0284700949612773,-0.106251840891797,0.08,0.0284700949612773,-0.106251840891797,0.07,0.0284700949612773,-0.0952627944162882,0.07,0.055,-0.0952627944162882,0.08,0.055,-0.0952627944162882,0.08,0.055,-0.0952627944162882,0.07,0.055,-0.0777817459305202,0.07,0.0777817459305202,-0.0777817459305202,0.08,0.0777817459305202,-0.0777817459305202,0.08,0.0777817459305202,-0.0777817459305202,0.07,0.0777817459305202,-0.055,0.08,0.0952627944162883,-0.055,0.07,0.0952627944162883,-0.055,0.07,0.0952627944162883,-0.055,0.08,0.0952627944162883,-0.0777817459305202,0.07,0.0777817459305202,-0.0707106781186548,0.07,0.0707106781186547,-0.055,0.07,0.0952627944162883,-0.0866025403784439,0.07,0.05,-0.0952627944162882,0.07,0.055,-0.0965925826289068,0.07,0.025881904510252,-0.1,0.07,-2.25597318603832e-17,-0.106251840891797,0.07,0.0284700949612773,-0.106251840891797,0.07,0.0284700949612773,-0.0952627944162882,0.07,0.055,-0.1,0.07,-2.25597318603832e-17,-0.0965925826289068,0.07,0.025881904510252,-0.1,0.07,-2.25597318603832e-17,-0.0965925826289068,0,0.025881904510252,-0.0965925826289068,0.07,0.025881904510252,-0.1,0,-2.25597318603832e-17,-0.0965925826289068,0.07,0.025881904510252,-0.0965925826289068,0,0.025881904510252,-0.1,0.07,-2.25597318603832e-17,-0.0866025403784439,0,0.05,-0.0866025403784439,0.07,0.05,-0.0866025403784439,0.07,0.05,-0.0866025403784439,0,0.05,-0.0707106781186548,0,0.0707106781186547,-0.0707106781186548,0.07,0.0707106781186547,-0.0707106781186548,0.07,0.0707106781186547,-0.0707106781186548,0,0.0707106781186547,-0.05,0.07,0.0866025403784438,-0.05,0,0.0866025403784438,-0.05,0,0.0866025403784438,-0.05,0.07,0.0866025403784438,-0.0707106781186548,0,0.0707106781186547,-0.0707106781186548,0,-0.0707106781186548,-0.05,0,0.0866025403784438,-0.0866025403784439,0,-0.05,-0.0866025403784439,0,0.05,-0.0965925826289068,0,-0.0258819045102521, +-0.0965925826289068,0,0.025881904510252,-0.1,0,-2.25597318603832e-17,-0.1,0,-2.25597318603832e-17,-0.0965925826289068,0,0.025881904510252,-0.0965925826289068,0,-0.0258819045102521,-0.1,0,-2.25597318603832e-17,-0.0965925826289068,0.07,-0.0258819045102521,-0.0965925826289068,0,-0.0258819045102521,-0.0965925826289068,0.07,-0.0258819045102521,-0.0965925826289068,0,-0.0258819045102521,-0.0866025403784439,0.07,-0.05,-0.0866025403784439,0,-0.05,-0.0866025403784439,0.07,-0.05,-0.0866025403784439,0,-0.05,-0.0707106781186548,0.07,-0.0707106781186548,-0.0707106781186548,0,-0.0707106781186548,-0.0707106781186548,0.07,-0.0707106781186548,-0.0707106781186548,0,-0.0707106781186548,-0.05,0,-0.0866025403784439,-0.05,0.07,-0.0866025403784439,-0.05,0,-0.0866025403784439,-0.05,0,-0.0866025403784439,-0.05,0,0.0866025403784438,-0.0707106781186548,0,-0.0707106781186548,-0.0707106781186548,0,0.0707106781186547,-0.05,0,-0.0866025403784439,-0.0258819045102521,0,0.0965925826289068,-0.0258819045102521,0,0.0965925826289068,-0.0258819045102521,0,-0.0965925826289068,-0.0258819045102521,0,-0.0965925826289068,-0.0258819045102521,0,-0.0965925826289068,-0.0258819045102521,0.07,-0.0965925826289068,-0.0258819045102521,0,-0.0965925826289068,-0.05,0.07,-0.0866025403784439,-0.0258819045102521,0.07,-0.0965925826289068,-0.05,0.07,-0.0866025403784439,-0.0284700949612774,0.07,-0.106251840891798,-0.0258819045102521,0.07,-0.0965925826289068,-0.055,0.07,-0.0952627944162882,-0.0707106781186548,0.07,-0.0707106781186548,-0.0777817459305203,0.07,-0.0777817459305202,-0.0866025403784439,0.07,-0.05,-0.0952627944162883,0.07,-0.055,-0.0965925826289068,0.07,-0.0258819045102521,-0.106251840891798,0.07,-0.0284700949612772,-0.11,0.07,2.25597318603832e-17,-0.11,0.07,2.25597318603832e-17,-0.106251840891798,0.07,-0.0284700949612772,-0.0952627944162883,0.07,-0.055,-0.0952627944162883,0.08,-0.055,-0.0952627944162883,0.07,-0.055,-0.106251840891798,0.07,-0.0284700949612772,-0.0952627944162883,0.08,-0.055,-0.0952627944162883,0.07,-0.055,-0.0777817459305203,0.08,-0.0777817459305202, +-0.0777817459305203,0.07,-0.0777817459305202,-0.0777817459305203,0.08,-0.0777817459305202,-0.0777817459305203,0.07,-0.0777817459305202,-0.055,0.07,-0.0952627944162882,-0.055,0.08,-0.0952627944162882,-0.055,0.07,-0.0952627944162882,-0.055,0.07,-0.0952627944162882,-0.0777817459305203,0.07,-0.0777817459305202,-0.0707106781186548,0.07,-0.0707106781186548,-0.0866025403784439,0.07,-0.05,-0.0965925826289068,0.07,-0.0258819045102521,-0.0965925826289068,0.07,-0.0258819045102521,-0.1,0.08,-1.24078525232107e-16,-0.1,0.07,-2.25597318603832e-17,-0.0965925826289068,0.08,-0.0258819045102522,-0.1,0.07,-2.25597318603832e-17,-0.1,0.08,-1.24078525232107e-16,-0.0965925826289068,0.07,-0.0258819045102521,-0.0965925826289069,0.08,0.0258819045102519,-0.0965925826289068,0.07,0.025881904510252,-0.0965925826289068,0.07,0.025881904510252,-0.0965925826289069,0.08,0.0258819045102519,-0.0866025403784439,0.08,0.0499999999999999,-0.0866025403784439,0.07,0.05,-0.0866025403784439,0.07,0.05,-0.0866025403784439,0.08,0.0499999999999999,-0.0707106781186548,0.08,0.0707106781186546,-0.0707106781186548,0.07,0.0707106781186547,-0.0707106781186548,0.07,0.0707106781186547,-0.0707106781186548,0.08,0.0707106781186546,-0.05,0.07,0.0866025403784438,-0.0500000000000001,0.08,0.0866025403784437,-0.05,0.07,0.0866025403784438,-0.05,0.07,0.0866025403784438,-0.055,0.07,0.0952627944162883,-0.0707106781186548,0.07,0.0707106781186547,-0.0777817459305202,0.07,0.0777817459305202,-0.05,0.07,0.0866025403784438,-0.0284700949612773,0.07,0.106251840891798,-0.0284700949612773,0.07,0.106251840891798,-0.0258819045102521,0.07,0.0965925826289068,-0.0258819045102521,0.07,0.0965925826289068,-0.0258819045102521,0.07,0.0965925826289068,-0.0258819045102521,0,0.0965925826289068,-0.0258819045102521,0,0.0965925826289068,-0.0258819045102521,0.07,0.0965925826289068,-0.0258819045102521,0.07,0.0965925826289068,-0.0258819045102522,0.08,0.0965925826289067,-0.0258819045102521,0.07,0.0965925826289068,-0.0500000000000001,0.08,0.0866025403784437,-0.0258819045102522,0.08,0.0965925826289067,-0.0258819045102522,0.08,0.0965925826289067, +-0.0207055236082017,0.21,0.0772740661031253,-0.0258819045102522,0.08,0.0965925826289067,-0.04,0.21,0.0692820323027549,-0.0284700949612773,0.08,0.106251840891798,-0.0258819045102522,0.08,0.0965925826289067,-0.0500000000000001,0.08,0.0866025403784437,-0.055,0.08,0.0952627944162883,-0.0707106781186548,0.08,0.0707106781186546,-0.0284700949612773,0.08,0.106251840891798,-0.0284700949612773,0.08,0.106251840891798,-0.0284700949612773,0.07,0.106251840891798,-0.0284700949612773,0.07,0.106251840891798,-0.0284700949612773,0.08,0.106251840891798,0,0.08,0.11,0,0.07,0.11,0,0.07,0.11,0,0.08,0.11,0,0.07,0.11,0,0.07,0.11,-2.25597318603832e-17,0.07,0.1,-2.25597318603832e-17,0.07,0.1,-2.25597318603832e-17,0.07,0.1,-2.25597318603832e-17,0,0.1,-2.25597318603832e-17,0,0.1,-2.25597318603832e-17,0.07,0.1,-2.25597318603832e-17,0,0.1,-2.25597318603832e-17,0,0.1,0,0,-0.1,0,0,-0.1,0,0,-0.1,0,0.07,-0.1,0,0,-0.1,0,0.07,-0.1,-2.25597318603832e-17,0.07,-0.11,0,0.07,-0.1,-0.0258819045102521,0.07,-0.0965925826289068,-0.0284700949612774,0.07,-0.106251840891798,-0.05,0.07,-0.0866025403784439,-2.25597318603832e-17,0.07,-0.11,-0.0284700949612774,0.08,-0.106251840891798,-2.25597318603832e-17,0.07,-0.11,-0.0284700949612774,0.07,-0.106251840891798,-2.25597318603832e-17,0.08,-0.11,-0.0284700949612774,0.07,-0.106251840891798,-2.25597318603832e-17,0.07,-0.11,-0.0284700949612774,0.08,-0.106251840891798,-2.25597318603832e-17,0.08,-0.11,-0.0284700949612774,0.08,-0.106251840891798,-0.0258819045102521,0.08,-0.096592582628907,-2.25597318603832e-17,0.08,-0.11,-0.05,0.08,-0.086602540378444,-0.055,0.08,-0.0952627944162882,-0.0707106781186548,0.08,-0.0707106781186549,-0.0777817459305203,0.08,-0.0777817459305202,-0.0866025403784439,0.08,-0.0500000000000002,-0.0965925826289068,0.08,-0.0258819045102522,-0.0952627944162883,0.08,-0.055,-0.0965925826289068,0.08,-0.0258819045102522,-0.0965925826289068,0.08,-0.0258819045102522,-0.08,0.21,-1.24078525232107e-16,-0.1,0.08,-1.24078525232107e-16,-0.0772740661031255,0.21,-0.0207055236082018,-0.1,0.08,-1.24078525232107e-16,-0.08,0.21,-1.24078525232107e-16, +-0.0965925826289068,0.08,-0.0258819045102522,-0.0772740661031255,0.21,0.0207055236082015,-0.0965925826289069,0.08,0.0258819045102519,-0.0965925826289069,0.08,0.0258819045102519,-0.0772740661031255,0.21,0.0207055236082015,-0.0692820323027551,0.21,0.0399999999999999,-0.0866025403784439,0.08,0.0499999999999999,-0.0866025403784439,0.08,0.0499999999999999,-0.0692820323027551,0.21,0.0399999999999999,-0.0777817459305202,0.08,0.0777817459305202,-0.0866025403784439,0.08,0.0499999999999999,-0.0965925826289069,0.08,0.0258819045102519,-0.0772740661031255,0.21,-0.0207055236082018,-0.0692820323027551,0.21,-0.0400000000000001,-0.0866025403784439,0.08,-0.0500000000000002,-0.0692820323027551,0.21,-0.0400000000000001,-0.0692820323027551,0.21,-0.0400000000000001,-0.0772740661031255,0.22,-0.0207055236082018,-0.0772740661031255,0.21,-0.0207055236082018,-0.0692820323027551,0.22,-0.0400000000000001,-0.0772740661031255,0.21,-0.0207055236082018,-0.0772740661031255,0.22,-0.0207055236082018,-0.0692820323027551,0.21,-0.0400000000000001,-0.08,0.22,-1.24078525232107e-16,-0.0692820323027551,0.22,-0.0400000000000001,-0.0565685424949238,0.21,-0.0565685424949239,-0.0565685424949238,0.22,-0.0565685424949239,-0.0565685424949238,0.21,-0.0565685424949239,-0.0565685424949238,0.22,-0.0565685424949239,-0.04,0.22,-0.0692820323027552,-0.04,0.21,-0.0692820323027552,-0.04,0.21,-0.0692820323027552,-0.04,0.22,-0.0692820323027552,-0.0707106781186548,0.08,-0.0707106781186549,-0.04,0.21,-0.0692820323027552,-0.0565685424949238,0.21,-0.0565685424949239,-0.05,0.08,-0.086602540378444,-0.05,0.08,-0.086602540378444,-0.0707106781186548,0.08,-0.0707106781186549,-0.04,0.21,-0.0692820323027552,-0.05,0.08,-0.086602540378444,-0.0707106781186548,0.08,-0.0707106781186549,-0.055,0.08,-0.0952627944162882,-0.0707106781186548,0.07,-0.0707106781186548,-0.05,0.08,-0.086602540378444,-0.0707106781186548,0.08,-0.0707106781186549,-0.05,0.07,-0.0866025403784439,-0.05,0.07,-0.0866025403784439,-0.0707106781186548,0.07,-0.0707106781186548,-0.05,0.08,-0.086602540378444,-0.055,0.08,-0.0952627944162882, +-0.0284700949612774,0.08,-0.106251840891798,-0.0258819045102521,0.08,-0.096592582628907,-0.0207055236082017,0.21,-0.0772740661031256,-0.0258819045102521,0.08,-0.096592582628907,-0.0258819045102521,0.08,-0.096592582628907,-0.0207055236082017,0.21,-0.0772740661031256,-0.0258819045102521,0.08,-0.096592582628907,-0.0258819045102521,0.07,-0.0965925826289068,-0.0258819045102521,0.07,-0.0965925826289068,-0.0258819045102521,0.08,-0.096592582628907,-1.12798659301916e-17,0.08,-0.1,0,0.07,-0.1,0,0.07,-0.1,-1.12798659301916e-17,0.08,-0.1,0,0.07,-0.1,0.0284700949612772,0.07,-0.106251840891798,0.0284700949612772,0.07,-0.106251840891798,0.0284700949612772,0.07,-0.106251840891798,0.0284700949612772,0.08,-0.106251840891798,0.0284700949612772,0.07,-0.106251840891798,0.0284700949612772,0.08,-0.106251840891798,-1.12798659301916e-17,0.08,-0.1,0.0284700949612772,0.08,-0.106251840891798,-2.25597318603832e-17,0.08,-0.11,-1.12798659301916e-17,0.08,-0.1,-2.25597318603832e-17,0.21,-0.0800000000000001,-1.12798659301916e-17,0.08,-0.1,-1.12798659301916e-17,0.08,-0.1,-2.25597318603832e-17,0.21,-0.0800000000000001,-2.25597318603832e-17,0.22,-0.0800000000000001,-0.0207055236082017,0.21,-0.0772740661031256,-2.25597318603832e-17,0.21,-0.0800000000000001,-0.0207055236082017,0.22,-0.0772740661031256,-2.25597318603832e-17,0.21,-0.0800000000000001,-0.0207055236082017,0.21,-0.0772740661031256,-2.25597318603832e-17,0.22,-0.0800000000000001,-0.0207055236082017,0.22,-0.0772740661031256,-3.38395977905748e-17,0.22,0.0799999999999999,-0.0207055236082017,0.22,-0.0772740661031256,-2.25597318603832e-17,0.22,-0.0800000000000001,-0.0207055236082017,0.22,0.0772740661031253,-0.04,0.22,-0.0692820323027552,-0.04,0.22,0.0692820323027549,-0.0565685424949238,0.22,-0.0565685424949239,-0.0565685424949238,0.22,0.0565685424949236,-0.0692820323027551,0.22,-0.0400000000000001,-0.0692820323027551,0.22,0.0399999999999999,-0.0692820323027551,0.22,-0.0400000000000001,-0.0565685424949238,0.22,0.0565685424949236,-0.0565685424949238,0.22,-0.0565685424949239,-0.04,0.22,0.0692820323027549, +-0.04,0.22,-0.0692820323027552,-0.0207055236082017,0.22,0.0772740661031253,-0.0207055236082017,0.22,-0.0772740661031256,-3.38395977905748e-17,0.22,0.0799999999999999,-2.25597318603832e-17,0.22,-0.0800000000000001,0.0207055236082016,0.22,0.0772740661031254,0.0207055236082016,0.22,0.0772740661031254,0.0207055236082016,0.22,-0.0772740661031256,0.0207055236082016,0.22,-0.0772740661031256,0.0207055236082016,0.22,-0.0772740661031256,0.0207055236082016,0.21,-0.0772740661031256,0.0207055236082016,0.21,-0.0772740661031256,0.0207055236082016,0.22,-0.0772740661031256,0.0207055236082016,0.21,-0.0772740661031256,0.0258819045102521,0.08,-0.0965925826289069,0.0258819045102521,0.08,-0.0965925826289069,0.0207055236082016,0.21,-0.0772740661031256,0.0258819045102521,0.08,-0.0965925826289069,0.0284700949612772,0.08,-0.106251840891798,0.0258819045102521,0.08,-0.0965925826289069,0.0258819045102521,0.08,-0.0965925826289069,0.0258819045102521,0.07,-0.0965925826289068,0.0258819045102521,0.07,-0.0965925826289068,0.0258819045102521,0.08,-0.0965925826289069,0.0258819045102521,0,-0.0965925826289068,0.0258819045102521,0.07,-0.0965925826289068,0.0258819045102521,0,-0.0965925826289068,0.025881904510252,0,0.0965925826289068,0.0258819045102521,0,-0.0965925826289068,0.025881904510252,0,0.0965925826289068,0.0258819045102521,0,-0.0965925826289068,0.0499999999999999,0,0.0866025403784439,0.0499999999999999,0,0.0866025403784439,0.05,0,-0.0866025403784439,0.05,0,-0.0866025403784439,0.05,0,-0.0866025403784439,0.05,0.07,-0.0866025403784439,0.05,0,-0.0866025403784439,0.0258819045102521,0.07,-0.0965925826289068,0.05,0.07,-0.0866025403784439,0.0258819045102521,0.07,-0.0965925826289068,0.05,0.07,-0.0866025403784439,0.0258819045102521,0.07,-0.0965925826289068,0.05,0.07,-0.0866025403784439,0.0549999999999999,0.07,-0.0952627944162883,0.0549999999999999,0.07,-0.0952627944162883,0.0549999999999999,0.07,-0.0952627944162883,0.0549999999999999,0.08,-0.0952627944162883,0.0549999999999999,0.07,-0.0952627944162883,0.0549999999999999,0.08,-0.0952627944162883,0.05,0.08,-0.086602540378444, +0.0549999999999999,0.08,-0.0952627944162883,0.05,0.08,-0.086602540378444,0.04,0.21,-0.0692820323027552,0.05,0.08,-0.086602540378444,0.05,0.08,-0.086602540378444,0.04,0.21,-0.0692820323027552,0.05,0.08,-0.086602540378444,0.05,0.07,-0.0866025403784439,0.05,0.07,-0.0866025403784439,0.05,0.08,-0.086602540378444,0.0707106781186547,0.08,-0.0707106781186549,0.0707106781186548,0.07,-0.0707106781186548,0.0707106781186548,0.07,-0.0707106781186548,0.0707106781186547,0.08,-0.0707106781186549,0.0707106781186548,0,-0.0707106781186548,0.0707106781186548,0.07,-0.0707106781186548,0.0707106781186548,0,-0.0707106781186548,0.0707106781186548,0,0.0707106781186548,0.0707106781186548,0,-0.0707106781186548,0.0707106781186548,0,0.0707106781186548,0.0707106781186548,0,-0.0707106781186548,0.0866025403784438,0,0.05,0.0866025403784438,0,0.05,0.0866025403784439,0,-0.05,0.0866025403784439,0,-0.05,0.0866025403784439,0.07,-0.05,0.0866025403784439,0,-0.05,0.0866025403784439,0,-0.05,0.0866025403784439,0.07,-0.05,0.0965925826289068,0.07,-0.0258819045102521,0.0965925826289068,0,-0.0258819045102521,0.0965925826289068,0,-0.0258819045102521,0.0965925826289068,0.07,-0.0258819045102521,0.1,0.07,-0,0.1,0,-0,0.1,0,-0,0.1,0.07,-0,0.0965925826289068,0.07,0.0258819045102522,0.0965925826289068,0,0.0258819045102522,0.0965925826289068,0,0.0258819045102522,0.0965925826289068,0.07,0.0258819045102522,0.0866025403784438,0.07,0.05,0.0866025403784438,0,0.05,0.0866025403784438,0,0.05,0.0866025403784438,0.07,0.05,0.0707106781186548,0.07,0.0707106781186548,0.0707106781186548,0,0.0707106781186548,0.0707106781186548,0,0.0707106781186548,0.0707106781186548,0.07,0.0707106781186548,0.0499999999999999,0,0.0866025403784439,0.0499999999999999,0.07,0.0866025403784439,0.0499999999999999,0,0.0866025403784439,0.0499999999999999,0.07,0.0866025403784439,0.055,0.07,0.0952627944162883,0.0499999999999999,0.07,0.0866025403784439,0.0707106781186548,0.07,0.0707106781186548,0.0284700949612773,0.07,0.106251840891797,0.025881904510252,0.07,0.0965925826289068,0.025881904510252,0.07,0.0965925826289068, +0.025881904510252,0.07,0.0965925826289068,0.025881904510252,0,0.0965925826289068,0.025881904510252,0,0.0965925826289068,0.025881904510252,0.07,0.0965925826289068,-4.51194637207664e-17,0.08,0.0999999999999999,0.025881904510252,0.07,0.0965925826289068,-2.25597318603832e-17,0.07,0.1,0.025881904510252,0.08,0.0965925826289067,-2.25597318603832e-17,0.07,0.1,0.025881904510252,0.07,0.0965925826289068,-4.51194637207664e-17,0.08,0.0999999999999999,0.025881904510252,0.08,0.0965925826289067,-3.38395977905748e-17,0.21,0.0799999999999999,0.025881904510252,0.08,0.0965925826289067,-4.51194637207664e-17,0.08,0.0999999999999999,0.0207055236082016,0.21,0.0772740661031254,-4.51194637207664e-17,0.08,0.0999999999999999,0.025881904510252,0.08,0.0965925826289067,-3.38395977905748e-17,0.21,0.0799999999999999,-4.51194637207664e-17,0.08,0.0999999999999999,0,0.08,0.11,0.025881904510252,0.08,0.0965925826289067,-0.0258819045102522,0.08,0.0965925826289067,0,0.08,0.11,-4.51194637207664e-17,0.08,0.0999999999999999,0.025881904510252,0.08,0.0965925826289067,0.0284700949612773,0.08,0.106251840891797,0.0284700949612773,0.08,0.106251840891797,0.0284700949612773,0.08,0.106251840891797,0.0284700949612773,0.07,0.106251840891797,0.0284700949612773,0.07,0.106251840891797,0.0284700949612773,0.08,0.106251840891797,0.0284700949612773,0.07,0.106251840891797,0.0499999999999999,0.07,0.0866025403784439,0.0499999999999999,0.07,0.0866025403784439,0.0499999999999999,0.08,0.0866025403784438,0.0499999999999999,0.07,0.0866025403784439,0.0499999999999999,0.08,0.0866025403784438,0.0499999999999999,0.08,0.0866025403784438,0.0399999999999999,0.21,0.069282032302755,0.0499999999999999,0.08,0.0866025403784438,0.0207055236082016,0.21,0.0772740661031254,0.0499999999999999,0.08,0.0866025403784438,0.0499999999999999,0.08,0.0866025403784438,0.055,0.08,0.0952627944162883,0.055,0.08,0.0952627944162883,0.055,0.08,0.0952627944162883,0.055,0.07,0.0952627944162883,0.055,0.07,0.0952627944162883,0.055,0.08,0.0952627944162883,0.055,0.07,0.0952627944162883,0.0707106781186548,0.07,0.0707106781186548, +0.0707106781186548,0.07,0.0707106781186548,0.0707106781186547,0.08,0.0707106781186547,0.0707106781186548,0.07,0.0707106781186548,0.0707106781186547,0.08,0.0707106781186547,0.0707106781186547,0.08,0.0707106781186547,0.0565685424949237,0.21,0.0565685424949237,0.0707106781186547,0.08,0.0707106781186547,0.0399999999999999,0.21,0.069282032302755,0.0707106781186547,0.08,0.0707106781186547,0.0707106781186547,0.08,0.0707106781186547,0.0777817459305202,0.08,0.0777817459305202,0.0777817459305202,0.08,0.0777817459305202,0.0777817459305202,0.08,0.0777817459305202,0.0777817459305202,0.07,0.0777817459305202,0.0777817459305202,0.07,0.0777817459305202,0.0777817459305202,0.08,0.0777817459305202,0.0777817459305202,0.07,0.0777817459305202,0.0777817459305202,0.07,0.0777817459305202,0.0866025403784438,0.07,0.05,0.0866025403784438,0.07,0.05,0.0866025403784438,0.07,0.05,0.0866025403784438,0.08,0.0499999999999999,0.0866025403784438,0.07,0.05,0.0866025403784438,0.08,0.0499999999999999,0.0866025403784438,0.08,0.0499999999999999,0.069282032302755,0.21,0.0399999999999999,0.0866025403784438,0.08,0.0499999999999999,0.0565685424949237,0.21,0.0565685424949237,0.0866025403784438,0.08,0.0499999999999999,0.0866025403784438,0.08,0.0499999999999999,0.0952627944162883,0.08,0.055,0.0952627944162883,0.08,0.055,0.0952627944162883,0.07,0.055,0.0952627944162883,0.08,0.055,0.0952627944162883,0.07,0.055,0.0952627944162883,0.08,0.055,0.106251840891798,0.07,0.0284700949612773,0.106251840891798,0.08,0.0284700949612773,0.106251840891798,0.07,0.0284700949612773,0.106251840891798,0.08,0.0284700949612773,0.11,0.07,-0,0.11,0.08,-0,0.11,0.07,-0,0.11,0.08,-0,0.106251840891798,0.07,-0.0284700949612774,0.106251840891798,0.08,-0.0284700949612774,0.106251840891798,0.07,-0.0284700949612774,0.106251840891798,0.08,-0.0284700949612774,0.0952627944162882,0.07,-0.0550000000000001,0.0952627944162882,0.08,-0.0550000000000001,0.0952627944162882,0.07,-0.0550000000000001,0.0952627944162882,0.08,-0.0550000000000001,0.0777817459305202,0.07,-0.0777817459305202,0.0777817459305202,0.08,-0.0777817459305202, +0.0777817459305202,0.07,-0.0777817459305202,0.0777817459305202,0.08,-0.0777817459305202,0.0707106781186548,0.07,-0.0707106781186548,0.0777817459305202,0.07,-0.0777817459305202,0.0707106781186548,0.07,-0.0707106781186548,0.0777817459305202,0.07,-0.0777817459305202,0.0866025403784439,0.07,-0.05,0.0866025403784439,0.07,-0.05,0.0952627944162882,0.07,-0.0550000000000001,0.0952627944162882,0.07,-0.0550000000000001,0.0965925826289068,0.07,-0.0258819045102521,0.0965925826289068,0.07,-0.0258819045102521,0.106251840891798,0.07,-0.0284700949612774,0.106251840891798,0.07,-0.0284700949612774,0.1,0.07,-0,0.1,0.07,-0,0.106251840891798,0.07,0.0284700949612773,0.0965925826289068,0.07,0.0258819045102522,0.0952627944162883,0.07,0.055,0.0952627944162883,0.07,0.055,0.0965925826289068,0.07,0.0258819045102522,0.0965925826289068,0.07,0.0258819045102522,0.0965925826289068,0.08,0.025881904510252,0.0965925826289068,0.07,0.0258819045102522,0.0965925826289068,0.08,0.025881904510252,0.0965925826289068,0.08,0.025881904510252,0.0772740661031254,0.21,0.0207055236082016,0.0965925826289068,0.08,0.025881904510252,0.069282032302755,0.21,0.0399999999999999,0.0965925826289068,0.08,0.025881904510252,0.0965925826289068,0.08,0.025881904510252,0.106251840891798,0.08,0.0284700949612773,0.106251840891798,0.08,0.0284700949612773,0.1,0.08,-1.12798659301916e-16,0.1,0.08,-1.12798659301916e-16,0.106251840891798,0.08,-0.0284700949612774,0.0965925826289068,0.08,-0.0258819045102522,0.0952627944162882,0.08,-0.0550000000000001,0.0866025403784439,0.08,-0.0500000000000001,0.0777817459305202,0.08,-0.0777817459305202,0.0707106781186547,0.08,-0.0707106781186549,0.0549999999999999,0.08,-0.0952627944162883,0.0707106781186547,0.08,-0.0707106781186549,0.0565685424949237,0.21,-0.0565685424949239,0.0707106781186547,0.08,-0.0707106781186549,0.0707106781186547,0.08,-0.0707106781186549,0.0565685424949237,0.21,-0.0565685424949239,0.0565685424949237,0.22,-0.0565685424949239,0.04,0.21,-0.0692820323027552,0.0565685424949237,0.21,-0.0565685424949239,0.04,0.22,-0.0692820323027552,0.0565685424949237,0.21,-0.0565685424949239, +0.04,0.21,-0.0692820323027552,0.0565685424949237,0.22,-0.0565685424949239,0.04,0.22,-0.0692820323027552,0.0565685424949237,0.22,0.0565685424949237,0.04,0.22,-0.0692820323027552,0.0565685424949237,0.22,-0.0565685424949239,0.0399999999999999,0.22,0.069282032302755,0.0399999999999999,0.22,0.069282032302755,0.04,0.22,-0.0692820323027552,0.0565685424949237,0.22,0.0565685424949237,0.0565685424949237,0.22,-0.0565685424949239,0.069282032302755,0.22,-0.0400000000000001,0.069282032302755,0.22,-0.0400000000000001,0.069282032302755,0.21,-0.0400000000000001,0.069282032302755,0.22,-0.0400000000000001,0.069282032302755,0.22,-0.0400000000000001,0.069282032302755,0.21,-0.0400000000000001,0.0772740661031255,0.21,-0.0207055236082018,0.0772740661031255,0.22,-0.0207055236082018,0.0772740661031255,0.22,-0.0207055236082018,0.0772740661031255,0.21,-0.0207055236082018,0.08,0.21,-1.12798659301916e-16,0.08,0.22,-1.12798659301916e-16,0.08,0.22,-1.12798659301916e-16,0.08,0.21,-1.12798659301916e-16,0.0772740661031254,0.21,0.0207055236082016,0.0772740661031254,0.22,0.0207055236082016,0.0772740661031254,0.22,0.0207055236082016,0.0772740661031254,0.21,0.0207055236082016,0.069282032302755,0.21,0.0399999999999999,0.069282032302755,0.22,0.0399999999999999,0.069282032302755,0.22,0.0399999999999999,0.069282032302755,0.21,0.0399999999999999,0.0565685424949237,0.21,0.0565685424949237,0.0565685424949237,0.22,0.0565685424949237,0.0565685424949237,0.22,0.0565685424949237,0.0565685424949237,0.21,0.0565685424949237,0.0399999999999999,0.22,0.069282032302755,0.0399999999999999,0.21,0.069282032302755,0.0399999999999999,0.21,0.069282032302755,0.0399999999999999,0.22,0.069282032302755,0.0207055236082016,0.22,0.0772740661031254,0.0207055236082016,0.21,0.0772740661031254,0.0207055236082016,0.21,0.0772740661031254,0.0207055236082016,0.22,0.0772740661031254,-3.38395977905748e-17,0.22,0.0799999999999999,-3.38395977905748e-17,0.21,0.0799999999999999,-3.38395977905748e-17,0.21,0.0799999999999999,-3.38395977905748e-17,0.22,0.0799999999999999,-0.0207055236082017,0.22,0.0772740661031253, +-0.0207055236082017,0.21,0.0772740661031253,-0.0207055236082017,0.21,0.0772740661031253,-0.0207055236082017,0.22,0.0772740661031253,-0.0207055236082017,0.21,0.0772740661031253,-0.04,0.22,0.0692820323027549,0.069282032302755,0.22,0.0399999999999999,0.069282032302755,0.22,0.0399999999999999,0.0772740661031255,0.22,-0.0207055236082018,0.0772740661031255,0.22,-0.0207055236082018,0.0772740661031254,0.22,0.0207055236082016,0.0772740661031254,0.22,0.0207055236082016,0.08,0.22,-1.12798659301916e-16,0.08,0.22,-1.12798659301916e-16,0.0772740661031254,0.21,0.0207055236082016,0.1,0.08,-1.12798659301916e-16,0.08,0.21,-1.12798659301916e-16,0.1,0.08,-1.12798659301916e-16,0.1,0.07,-0,0.1,0.08,-1.12798659301916e-16,0.1,0.07,-0,0.106251840891798,0.07,0.0284700949612773,0.11,0.07,-0,0.11,0.07,-0,0.1,0.08,-1.12798659301916e-16,0.0965925826289068,0.07,-0.0258819045102521,0.0965925826289068,0.08,-0.0258819045102522,0.0965925826289068,0.07,-0.0258819045102521,0.0965925826289068,0.08,-0.0258819045102522,0.0772740661031255,0.21,-0.0207055236082018,0.0965925826289068,0.08,-0.0258819045102522,0.08,0.21,-1.12798659301916e-16,0.0772740661031255,0.21,-0.0207055236082018,0.0965925826289068,0.08,-0.0258819045102522,0.069282032302755,0.21,-0.0400000000000001,0.0866025403784439,0.08,-0.0500000000000001,0.069282032302755,0.21,-0.0400000000000001,0.0866025403784439,0.08,-0.0500000000000001,0.0866025403784439,0.08,-0.0500000000000001,0.0777817459305202,0.08,-0.0777817459305202,0.0866025403784439,0.08,-0.0500000000000001,0.0866025403784439,0.07,-0.05,0.0866025403784439,0.07,-0.05,0.0866025403784439,0.08,-0.0500000000000001,0.0707106781186548,0.07,-0.0707106781186548,0.0965925826289068,0.08,-0.0258819045102522,0.0952627944162882,0.08,-0.0550000000000001,0.106251840891798,0.08,-0.0284700949612774,0.11,0.08,-0,0.11,0.08,-0,0.0965925826289068,0,0.0258819045102522,0.0965925826289068,0,0.0258819045102522,0.0965925826289068,0,-0.0258819045102521,0.0965925826289068,0,-0.0258819045102521,0.1,0,-0,0.1,0,-0,-0.0777817459305203,0.08,-0.0777817459305202,-0.0866025403784439,0.08,-0.0500000000000002, +-0.0565685424949238,0.21,-0.0565685424949239,-0.0866025403784439,0.08,-0.0500000000000002,-0.0866025403784439,0.08,-0.0500000000000002,-0.0866025403784439,0.07,-0.05,-0.0866025403784439,0.07,-0.05,-0.0866025403784439,0.08,-0.0500000000000002,-0.0965925826289068,0.08,-0.0258819045102522,-0.0707106781186548,0.08,-0.0707106781186549,-0.0866025403784439,0.07,0.05,-0.0866025403784439,0,-0.05,-0.0866025403784439,0,0.05 + } + PolygonVertexIndex: *2280 { + a: 0,1,-3,1,0,-4,4,5,-7,7,8,-10,8,7,-11,11,12,-14,14,10,-8,10,14,-16,16,17,-12,18,15,-15,15,18,-20,20,21,-17,18,22,-20,22,18,-24,20,24,-22,25,26,-28,26,25,-29,29,30,-32,32,33,-35,32,35,-34,36,35,-33,36,37,-36,38,37,-37,39,37,-39,37,39,-41,41,42,-44,44,40,-40,45,40,-45,40,45,-47,47,48,-42,49,50,-52,50,49,-53,53,54,-56,56,51,-51,51,56,-58,58,59,-54,60,57,-57,57,60,-62,62,63,-59,64,61,-61,61,64,-66,66,67,-63,64,68,-66,68,64,-70,70,67,-72,72,73,-75,72,75,-74,76,75,-73,76,77,-76,76,78,-78,78,76,-80,80,81,-83,59,58,-64,83,82,-82,84,85,-87,85,84,-88,88,89,-91,91,86,-86,86,91,-93,93,94,-89,95,92,-92,92,95,-97,97,98,-94,95,99,-97,99,95,-101,101,98,-103,103,104,-106,103,106,-105,107,106,-104,107,108,-107,109,108,-108,108,109,-111,111,112,-114,114,90,-90,115,87,-85,87,115,-117,90,114,-118,118,117,-115,119,116,-116,116,119,-121,117,118,-122,122,121,-119,123,120,-120,120,123,-125,121,122,-126,126,125,-123,123,127,-125,127,123,-129,126,129,-126,105,104,-131,131,132,-134,134,132,-132,105,130,-136,136,134,-132,135,130,-138,138,134,-137,128,139,-128,139,128,-141,129,141,-143,143,142,-142,144,145,-147,144,147,-146,148,147,-145,148,149,-148,150,149,-149,150,151,-150,152,151,-151,78,151,-153,79,151,-79,79,153,-152,153,79,-155,155,80,-157,54,53,-60,157,156,-81,52,158,-160,158,52,-50,55,160,-162,160,55,-55,162,161,-161,163,159,-159,159,163,-165,161,162,-166,166,165,-163,163,167,-165,167,163,-169,166,169,-166,170,171,-173,172,171,-174,171,157,-174,173,157,-175,174,157,-83,82,157,-81,175,176,-178,176,175,-179,179,180,-182,182,177,-177,177,182,-184,184,185,-180,186,183,-183,183,186,-188,188,189,-185,190,187,-187,187,190,-192,192,193,-189,190,194,-192,194,190,-196,192,196,-194,97,102,-99,74,73,-198,198,199,-201,201,199,-199,74,197,-203,203,201,-199,202,197,-205,205,201,-204,100,206,-100,206,100,-208,208,101,-210,102,209,-102,195,210,-195,210,195,-212,196,212,-214,214,213,-213,27,215,-26,215,27,-217,30,217,-219,34,219,-221,34,33,-220,221,222,-224,224,222,-222,69,225,-69,225,69,-227,227,70,-229,71,228,-71,226,229,-226,229,226, +-231,231,227,-233,202,204,-234,234,205,-204,233,204,-236,236,205,-235,207,237,-207,237,207,-239,239,208,-241,135,137,-242,242,138,-137,241,137,-244,244,138,-243,140,245,-140,245,140,-247,141,247,-144,248,143,-248,146,249,-251,146,145,-250,251,252,-254,254,252,-252,255,256,-258,256,255,-259,259,260,-262,262,261,-261,263,264,-266,263,266,-265,267,266,-264,267,268,-267,269,268,-268,269,270,-269,44,270,-270,44,271,-271,44,39,-272,42,41,-273,272,41,-49,273,42,-273,274,275,-277,275,274,-278,278,279,-281,281,276,-276,276,281,-283,283,284,-279,285,282,-282,282,285,-287,287,288,-284,26,286,-286,286,26,-29,29,31,-288,288,287,-32,223,289,-291,222,289,-224,66,71,-68,289,43,-291,290,43,-292,291,43,-43,180,179,-186,185,184,-190,189,188,-194,284,283,-289,279,278,-285,292,280,-280,274,293,-278,293,274,-295,292,295,-281,296,297,-299,297,296,-300,300,301,-303,9,298,-298,298,9,-9,13,303,-301,303,13,-13,301,300,-304,304,302,-302,305,299,-297,299,305,-307,302,304,-308,308,307,-305,305,309,-307,309,305,-311,311,307,-313,313,314,-316,314,313,-317,317,318,-320,320,321,-323,323,324,-326,324,323,-327,327,328,-330,142,125,-130,253,170,-173,252,170,-254,168,257,-168,257,168,-256,169,259,-331,261,330,-260,331,320,-323,332,320,-332,333,316,-335,316,333,-315,335,317,-337,326,337,-325,337,326,-339,339,327,-341,329,340,-328,338,341,-338,341,338,-343,343,339,-345,345,254,-252,250,249,-347,347,254,-346,258,348,-257,348,258,-350,260,350,-263,351,262,-351,265,352,-354,265,264,-353,354,332,-332,355,332,-355,356,334,-358,334,356,-334,358,335,-360,340,344,-340,336,359,-336,360,361,-363,361,360,-364,364,365,-367,367,366,-366,368,369,-371,371,369,-369,371,372,-370,373,372,-372,373,374,-373,375,374,-374,375,376,-375,3,376,-376,3,0,-377,377,6,-6,378,6,-378,379,378,-378,380,378,-380,381,380,-380,382,380,-382,308,312,-308,383,382,-382,384,382,-384,310,363,-310,363,310,-362,365,311,-368,319,336,-318,312,367,-312,385,384,-384,386,384,-386,368,370,-388,388,386,-386,387,370,-390,390,386,-389,362,391,-361,391,362,-393,393,364,-395,357,395,-357,395,357,-397,397,358, +-399,353,352,-400,400,355,-355,401,355,-401,342,402,-342,402,342,-404,404,343,-406,406,246,-408,246,406,-246,247,408,-249,409,243,-411,241,243,-410,411,244,-243,412,244,-412,409,410,-414,414,412,-412,413,410,-416,416,412,-415,407,417,-407,417,407,-419,408,419,-421,421,420,-420,422,346,-424,250,346,-423,424,347,-346,425,347,-425,423,346,-427,427,347,-426,349,428,-349,428,349,-430,350,430,-352,431,351,-431,353,432,-434,353,399,-433,434,401,-401,435,396,-437,396,435,-396,437,397,-439,403,439,-403,439,403,-441,441,404,-443,405,442,-405,440,443,-440,443,440,-445,445,441,-447,447,418,-449,418,447,-418,419,449,-422,450,415,-452,413,415,-451,452,416,-415,453,416,-453,450,451,-455,455,453,-453,454,451,-457,457,453,-456,447,458,-460,458,447,-449,460,461,-450,462,459,-459,459,462,-464,464,465,-461,466,463,-463,463,466,-468,468,469,-465,470,467,-467,467,470,-472,472,473,-469,474,471,-471,471,474,-476,476,477,-473,478,475,-475,475,478,-480,480,481,-477,478,482,-480,482,478,-484,480,484,-482,485,481,-485,486,487,-489,489,487,-487,489,490,-488,233,490,-490,233,235,-491,491,236,-235,238,492,-238,492,238,-494,494,239,-496,240,495,-240,496,497,-499,497,496,-500,500,501,-503,503,502,-502,504,505,-507,505,504,-508,508,509,-511,511,512,-514,220,512,-512,220,219,-513,514,224,-222,515,224,-515,228,232,-228,516,515,-515,517,515,-517,513,512,-519,519,515,-518,230,520,-230,520,230,-522,522,231,-524,524,491,-235,525,491,-525,493,483,-493,483,493,-483,484,494,-486,495,485,-495,499,526,-498,526,499,-528,501,528,-504,529,503,-529,507,530,-506,530,507,-532,509,532,-534,513,518,-535,535,519,-518,534,518,-537,537,519,-536,521,538,-521,538,521,-540,540,522,-542,542,525,-525,543,525,-543,527,544,-527,544,527,-546,528,546,-530,547,529,-547,531,548,-531,548,531,-550,532,550,-552,534,536,-553,553,537,-536,552,536,-555,555,537,-554,539,556,-539,556,539,-558,558,540,-560,486,488,-561,561,543,-543,560,488,-563,563,543,-562,477,476,-482,545,564,-545,564,545,-566,546,566,-548,567,547,-567,549,568,-549,568,549,-570,550,570,-572,552,554,-573,573,555,-554,572, +554,-575,575,555,-574,556,576,-578,576,556,-558,558,559,-579,579,578,-560,580,577,-577,577,580,-582,578,579,-583,583,582,-580,584,581,-581,581,584,-586,582,583,-587,587,586,-584,588,585,-585,585,588,-590,586,587,-591,591,590,-588,592,589,-589,589,592,-594,590,591,-595,595,594,-592,596,593,-593,593,596,-598,594,595,-599,599,598,-596,596,429,-598,429,596,-429,430,598,-432,600,426,-602,423,426,-601,602,427,-426,603,427,-603,600,601,-605,605,603,-603,604,601,-607,607,603,-606,604,606,-609,609,607,-606,608,606,-611,611,607,-610,608,610,-613,613,611,-610,614,612,-611,614,615,-613,616,615,-615,616,562,-616,560,562,-617,617,563,-562,618,563,-618,473,472,-478,565,619,-565,619,565,-621,566,621,-568,622,567,-622,569,623,-569,623,569,-625,570,625,-627,572,574,-628,628,575,-574,627,574,-630,630,575,-629,627,629,-632,632,630,-629,633,631,-630,633,634,-632,635,634,-634,635,636,-635,637,636,-636,637,638,-637,433,638,-638,433,432,-639,639,434,-401,640,434,-640,641,436,-643,436,641,-436,643,437,-645,442,446,-442,438,644,-438,645,646,-648,646,645,-649,649,650,-652,652,651,-651,653,654,-656,656,654,-654,656,389,-655,387,389,-657,657,390,-389,658,390,-658,392,648,-392,648,392,-647,650,393,-653,398,438,-398,394,652,-394,659,658,-658,660,658,-660,653,655,-662,662,660,-660,645,663,-665,663,645,-648,665,666,-652,667,664,-664,664,667,-669,669,670,-666,671,668,-668,668,671,-673,673,674,-670,675,672,-672,672,675,-677,677,678,-674,679,676,-676,676,679,-681,681,682,-678,683,680,-680,680,683,-685,685,686,-682,683,687,-685,687,683,-689,689,686,-691,571,551,-551,685,690,-687,688,691,-688,691,688,-693,693,689,-695,551,533,-533,690,694,-690,692,695,-692,695,692,-697,697,693,-699,533,510,-510,694,698,-694,696,699,-696,699,696,-701,701,697,-703,506,216,-505,216,506,-216,217,508,-704,498,211,-497,211,498,-211,212,500,-215,209,240,-209,502,214,-501,510,703,-509,703,218,-218,23,700,-23,700,23,-700,24,701,-705,702,704,-702,704,21,-25,698,702,-698,682,681,-687,626,571,-571,653,661,-706,706,662,-660,705,661,-708,708,662,-707,705,707,-710,710,708,-707,709,707, +-712,712,708,-711,678,677,-683,713,626,-626,624,714,-624,714,624,-716,625,716,-714,717,620,-719,620,717,-620,621,719,-623,469,468,-474,613,618,-721,720,618,-618,611,613,-721,614,610,-722,722,611,-721,723,622,-720,718,724,-718,724,718,-726,719,726,-724,465,464,-470,727,723,-727,714,728,-730,728,714,-716,730,716,-732,730,713,-717,674,673,-679,732,731,-717,733,729,-729,729,733,-735,731,732,-736,736,735,-733,641,734,-734,734,641,-643,735,736,-645,643,644,-737,737,640,-739,444,739,-444,739,444,-741,741,445,-743,743,449,-462,743,421,-450,446,742,-446,740,725,-740,725,740,-725,726,741,-728,461,460,-466,742,727,-742,744,737,-746,745,737,-739,746,744,-746,632,744,-747,630,632,-747,633,629,-748,748,630,-747,738,640,-640,599,431,-599,649,651,-667,666,665,-671,670,669,-675,541,559,-541,523,541,-523,232,523,-232,454,456,-750,750,457,-456,749,456,-752,752,457,-751,749,751,-754,754,752,-751,420,248,-409,344,405,-344,359,398,-359,366,394,-365,17,16,-22,12,11,-18,330,165,-170,322,321,-756,321,756,-756,315,294,-314,294,315,-294,295,757,-759,318,758,-758,759,323,-326,323,759,-761,761,762,-329,178,760,-760,760,178,-176,181,763,-762,763,181,-181,762,761,-764,758,280,-296,756,273,-273,755,756,-273,764,328,-763,764,329,-329,757,319,-319,213,193,-197,218,31,-31,199,765,-201,200,765,-82,765,83,-82,63,62,-68,132,766,-134,133,766,-768,766,113,-768,767,113,-113,89,88,-95,94,93,-99 + } + GeometryVersion: 124 + LayerElementNormal: 0 { + Version: 101 + Name: "" + MappingInformationType: "ByVertice" + ReferenceInformationType: "Direct" + Normals: *2304 { + a: 0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,-0,1,0,-0,1,0,-0,1,0,0.965925826289068,0,-0.258819045102521,1,0,1.67970464300974e-16,1,0,1.67970464300974e-16,0.965925826289068,0,-0.258819045102521,-0.965925826289068,-0,0.258819045102521,-0.965925826289068,-0,0.258819045102521,-1,-0,-1.67970464300974e-16,0.866025403784438,0,-0.500000000000001,0.866025403784438,0,-0.500000000000001,-0.866025403784438,-0,0.500000000000001,-0.866025403784438,-0,0.500000000000001,0.707106781186548,0,-0.707106781186547,0.707106781186548,0,-0.707106781186547,-0.707106781186548,-0,0.707106781186547,-0.707106781186548,-0,0.707106781186547,0.500000000000002,0,-0.866025403784437,0.500000000000002,0,-0.866025403784437,-0.500000000000002,-0,0.866025403784437,0.49418584882531,-0.152057184253941,-0.855954998546986,0.698884329741612,-0.152057184253942,-0.698884329741611,0.49418584882531,-0.152057184253941,-0.855954998546986,0.698884329741612,-0.152057184253942,-0.698884329741611,-0.698884329741612,0.152057184253942,0.698884329741611,-0.49418584882531,0.152057184253941,0.855954998546986,-0.698884329741612,0.152057184253942,0.698884329741611,0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,-0,-1,0,-0,-1,0,-0,-1,0,0,1,-0,0,1,-0,0,1,-0,-0,-1,0,-0,-1,0,-0.965925826289068,0,-0.25881904510252,-1,0,2.79950773834956e-16,-1,0,2.79950773834956e-16,-0.965925826289068,0,-0.25881904510252,1,-0,-2.79950773834956e-16,1,-0,-2.79950773834956e-16,0.965925826289068,-0,0.25881904510252,-0.965925826289068,0,0.258819045102521,-0.965925826289068,0,0.258819045102521,0.965925826289068,-0,-0.258819045102521,0.965925826289068,-0,-0.258819045102521,-0.866025403784438,0,0.5,-0.866025403784438,0,0.5,0.866025403784438,-0,-0.5,0.866025403784438,-0,-0.5,-0.707106781186548,0,0.707106781186548,-0.707106781186548,0,0.707106781186548,0.707106781186548,-0,-0.707106781186548,0.707106781186548,-0,-0.707106781186548,-0.5,0,0.866025403784439,-0.5,0,0.866025403784439,0.5,-0,-0.866025403784439,0.5,-0,-0.866025403784439,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0, +0,-1,-0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-1,0,-3.07945851218452e-16,-0.965925826289068,0,0.25881904510252,-0.965925826289068,0,0.25881904510252,-1,0,-3.07945851218452e-16,0.965925826289068,-0,-0.25881904510252,0.965925826289068,-0,-0.25881904510252,1,-0,3.07945851218452e-16,-0.866025403784439,0,0.5,-0.866025403784439,0,0.5,0.866025403784439,-0,-0.5,0.866025403784439,-0,-0.5,-0.707106781186548,0,0.707106781186547,-0.707106781186548,0,0.707106781186547,0.707106781186548,-0,-0.707106781186547,0.707106781186548,-0,-0.707106781186547,-0.500000000000001,0,0.866025403784438,-0.500000000000001,0,0.866025403784438,0.500000000000001,-0,-0.866025403784438,0.500000000000001,-0,-0.866025403784438,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,-0,1,0,-0,1,0,-0,1,0,1,-0,3.07945851218452e-16,-0.965925826289068,0,-0.258819045102521,-0.965925826289068,0,-0.258819045102521,0.965925826289068,-0,0.258819045102521,0.965925826289068,-0,0.258819045102521,-0.866025403784438,0,-0.5,-0.866025403784438,0,-0.5,0.866025403784438,-0,0.5,0.866025403784438,-0,0.5,-0.707106781186547,0,-0.707106781186548,-0.707106781186547,0,-0.707106781186548,0.707106781186547,-0,0.707106781186548,0.707106781186547,-0,0.707106781186548,-0.5,0,-0.866025403784439,-0.5,0,-0.866025403784439,0.5,-0,0.866025403784439,0,-1,-0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,0,-1,-0,-0,1,0,0,-1,-0,-0,1,0,-0.25881904510252,0,-0.965925826289068,-0.25881904510252,0,-0.965925826289068,0.25881904510252,-0,0.965925826289068,0.5,-0,0.866025403784439,0.25881904510252,-0,0.965925826289068,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,-0,1,0,-0,1,0,-0,1,0,-0.866025403784439,0,-0.5,-0.866025403784439,0,-0.5,0.965925826289068,-0,0.25881904510252,0.866025403784439,-0,0.5,0.866025403784439,-0,0.5,-0.707106781186548,0,-0.707106781186547,-0.707106781186548,0,-0.707106781186547,0.707106781186548,-0,0.707106781186547,0.707106781186548,-0,0.707106781186547,-0.500000000000001,0,-0.866025403784438,-0.500000000000001,0,-0.866025403784438,0.500000000000001,-0,0.866025403784438, +-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,0.965925826289068,5.28592816826665e-15,0.258819045102521,1,2.26662556261245e-15,3.35940928601947e-16,1,2.26662556261245e-15,3.35940928601947e-16,0.965925826289068,5.28592816826665e-15,0.258819045102521,-1,-2.26662556261245e-15,-3.35940928601947e-16,-1,-2.26662556261245e-15,-3.35940928601947e-16,-0.965925826289068,-5.28592816826665e-15,-0.258819045102521,0.965925826289068,-6.84424925549457e-16,-0.25881904510252,0.965925826289068,-6.84424925549457e-16,-0.25881904510252,-0.965925826289068,6.84424925549457e-16,0.25881904510252,-0.965925826289068,6.84424925549457e-16,0.25881904510252,0.866025403784439,-3.68131329715977e-15,-0.5,0.866025403784439,-3.68131329715977e-15,-0.5,-0.866025403784439,3.68131329715977e-15,0.5,-0.866025403784439,3.68131329715977e-15,0.5,0.707106781186548,-6.36682780642109e-15,-0.707106781186547,0.707106781186548,-6.36682780642109e-15,-0.707106781186547,-0.707106781186548,6.36682780642109e-15,0.707106781186547,-0.707106781186548,6.36682780642109e-15,0.707106781186547,0.5,-8.60593036246272e-15,-0.866025403784438,0.5,-8.60593036246272e-15,-0.866025403784438,-0.5,8.60593036246272e-15,0.866025403784438,0,-1,-0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,0,-1,-0,-0,1,0,0,-1,-0,-0,1,0,-0.258819045102521,0,0.965925826289068,-0.258819045102521,0,0.965925826289068,0.258819045102521,-0,-0.965925826289068,0.258819045102521,-0,-0.965925826289068,0.258819045102521,-1.02887796051795e-14,-0.965925826289068,0.258819045102521,-1.02887796051795e-14,-0.965925826289068,-0.258819045102521,1.02887796051795e-14,0.965925826289068,-0.5,8.60593036246272e-15,0.866025403784438,-0.258819045102521,1.02887796051795e-14,0.965925826289068,0.255809418992291,-0.152057184253941,-0.954693748733901,0.255809418992291,-0.152057184253941,-0.954693748733901,-0.255809418992291,0.152057184253941,0.954693748733901,-0.49418584882531,0.152057184253941,0.855954998546986,0,1,-0,0,1,-0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0.25881904510252,0,0.965925826289068,-0.25881904510252,0,0.965925826289068,0.25881904510252,-0,-0.965925826289068, +0.25881904510252,-0,-0.965925826289068,3.219433899102e-16,0,1,3.219433899102e-16,0,1,-3.219433899102e-16,-0,-1,-3.219433899102e-16,-0,-1,0,-1,-0,-0,1,0,0,-1,-0,-0,1,0,-4.19926160752434e-16,0,1,-4.19926160752434e-16,0,1,4.19926160752434e-16,-0,-1,4.19926160752434e-16,-0,-1,0,-1,-0,-0,1,0,0,-1,-0,-0,1,0,1.39975386917478e-16,0,-1,1.39975386917478e-16,0,-1,-1.39975386917478e-16,-0,1,-1.39975386917478e-16,-0,1,0,-1,-0,0,-1,-0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0.258819045102521,0,-0.965925826289068,-1.95965541684469e-16,0,-1,-0.258819045102521,0,-0.965925826289068,-1.95965541684469e-16,0,-1,0.258819045102521,-0,0.965925826289068,1.95965541684469e-16,-0,1,0.258819045102521,-0,0.965925826289068,1.95965541684469e-16,-0,1,0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,-0,-1,0,-0,-1,0,0.954693748733902,-0.152057184253941,0.25580941899229,0.988371697650617,-0.152057184253941,2.51906066232929e-16,0.988371697650617,-0.152057184253941,2.51906066232929e-16,0.954693748733902,-0.152057184253941,0.25580941899229,-0.988371697650617,0.152057184253941,-2.51906066232929e-16,-0.988371697650617,0.152057184253941,-2.51906066232929e-16,-0.954693748733902,0.152057184253941,-0.25580941899229,0.954693748733902,-0.152057184253941,-0.25580941899229,0.954693748733902,-0.152057184253941,-0.25580941899229,-0.954693748733902,0.152057184253941,0.25580941899229,-0.954693748733902,0.152057184253941,0.25580941899229,0.855954998546987,-0.152057184253941,-0.494185848825309,0.855954998546987,-0.152057184253941,-0.494185848825309,-0.855954998546987,0.152057184253941,0.494185848825309,-0.855954998546987,0.152057184253941,0.494185848825309,-0,-1,0,-0,-1,0,-0,-1,0,-0.954693748733902,0.152057184253941,-0.25580941899229,0.855954998546986,-0.152057184253941,0.494185848825309,0.855954998546986,-0.152057184253941,0.494185848825309,-0.855954998546986,0.152057184253941,-0.494185848825309,0.866025403784438,0,0.500000000000002,0.965925826289068,0,0.258819045102521,0.965925826289068,0,0.258819045102521,0.866025403784438,0,0.500000000000002,-0.965925826289068,-0,-0.258819045102521, +-0.965925826289068,-0,-0.258819045102521,-0.866025403784438,-0,-0.500000000000002,-1,-0,-1.67970464300974e-16,-0.866025403784438,-0,-0.500000000000002,0.707106781186547,0,0.707106781186548,0.707106781186547,0,0.707106781186548,-0.707106781186547,-0,-0.707106781186548,-0.707106781186547,-0,-0.707106781186548,0.500000000000001,0,0.866025403784438,0.500000000000001,0,0.866025403784438,-0.500000000000001,-0,-0.866025403784438,-0.500000000000001,-0,-0.866025403784438,0.698884329741611,-0.152057184253941,0.698884329741612,0.494185848825309,-0.152057184253941,0.855954998546987,0.698884329741611,-0.152057184253941,0.698884329741612,0.494185848825309,-0.152057184253941,0.855954998546987,-0.494185848825309,0.152057184253941,-0.855954998546987,-0.698884329741611,0.152057184253941,-0.698884329741612,-0.494185848825309,0.152057184253941,-0.855954998546987,-0,-1,0,-0,-1,0,-0,-1,0,0.707106781186547,9.60521683617532e-15,0.707106781186548,0.5,1.19982069463348e-14,0.866025403784439,0.707106781186547,9.60521683617532e-15,0.707106781186548,0.5,1.19982069463348e-14,0.866025403784439,-0.5,-1.19982069463348e-14,-0.866025403784439,-0.707106781186547,-9.60521683617532e-15,-0.707106781186548,-0.5,-1.19982069463348e-14,-0.866025403784439,0.500000000000001,-0,0.866025403784438,-0,-1,0,-0,-1,0,0.25580941899229,-0.152057184253941,0.954693748733901,0.25580941899229,-0.152057184253941,0.954693748733901,-0.25580941899229,0.152057184253941,-0.954693748733901,-0.25580941899229,0.152057184253941,-0.954693748733901,0.25881904510252,1.36237774637864e-14,0.965925826289069,0.25881904510252,1.36237774637864e-14,0.965925826289069,-0.25881904510252,-1.36237774637864e-14,-0.965925826289069,-0.25881904510252,-1.36237774637864e-14,-0.965925826289069,-1.67970464300974e-16,1.29544413390859e-14,1,-1.67970464300974e-16,1.29544413390859e-14,1,1.67970464300974e-16,-1.29544413390859e-14,-1,1.67970464300974e-16,-1.29544413390859e-14,-1,-0,1,0,0,-1,-0,-0,1,0,0.25881904510252,0,-0.965925826289068,0.25881904510252,0,-0.965925826289068,-0.25881904510252,-0,0.965925826289068, +-0.25881904510252,-0,0.965925826289068,0,1,-0,0,1,-0,-0,-1,0,-0,-1,0,-4.05848662264163e-16,-0.152057184253941,0.988371697650617,-4.05848662264163e-16,-0.152057184253941,0.988371697650617,4.05848662264163e-16,0.152057184253941,-0.988371697650617,4.05848662264163e-16,0.152057184253941,-0.988371697650617,-2.37958157759713e-16,0,1,0.258819045102521,0,0.965925826289068,-2.37958157759713e-16,0,1,0.258819045102521,0,0.965925826289068,2.37958157759713e-16,-0,-1,-0.258819045102521,-0,-0.965925826289068,2.37958157759713e-16,-0,-1,-0.258819045102521,-0,-0.965925826289068,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,0,-1,-0,-0,1,0,0,-1,-0,-0,1,0,-0.258819045102521,0,0.965925826289068,-0.258819045102521,0,0.965925826289068,0.258819045102521,-0,-0.965925826289068,0.258819045102521,-0,-0.965925826289068,-0.255809418992291,-0.152057184253941,0.954693748733901,-0.255809418992291,-0.152057184253941,0.954693748733901,0.255809418992291,0.152057184253941,-0.954693748733901,0.255809418992291,0.152057184253941,-0.954693748733901,0,1,-0,-0,-1,0,-0,-1,0,-0.258819045102521,1.01608174674873e-14,0.965925826289068,-0.258819045102521,1.01608174674873e-14,0.965925826289068,0.258819045102521,-1.01608174674873e-14,-0.965925826289068,0.258819045102521,-1.01608174674873e-14,-0.965925826289068,0.258819045102521,0,-0.965925826289068,0.258819045102521,0,-0.965925826289068,-0.258819045102521,-0,0.965925826289068,0,-1,-0,0,-1,-0,-0,1,0,-0,1,0,0,-1,-0,-0,1,0,0,-1,-0,-0,1,0,0.5,0,-0.866025403784439,0.5,0,-0.866025403784439,-0.5,-0,0.866025403784439,-0.258819045102521,-0,0.965925826289068,-0.5,-0,0.866025403784439,0,-1,-0,0,-1,-0,-0,1,0,-0,1,0,0,-1,-0,-0,1,0,0.499999999999999,0,-0.866025403784439,0.499999999999999,0,-0.866025403784439,-0.499999999999999,-0,0.866025403784439,-0.499999999999999,-0,0.866025403784439,0,1,-0,0,1,-0,-0,-1,0,-0.494185848825309,-0.152057184253941,0.855954998546987,-0.494185848825309,-0.152057184253941,0.855954998546987,0.494185848825309,0.152057184253941,-0.855954998546987, +0.494185848825309,0.152057184253941,-0.855954998546987,-0.5,6.76964270175402e-15,0.866025403784439,-0.5,6.76964270175402e-15,0.866025403784439,0.5,-6.76964270175402e-15,-0.866025403784439,0.5,-6.76964270175402e-15,-0.866025403784439,-0.707106781186548,4.81156404056102e-15,0.707106781186548,-0.707106781186548,4.81156404056102e-15,0.707106781186548,0.707106781186548,-4.81156404056102e-15,-0.707106781186548,0.707106781186548,-4.81156404056102e-15,-0.707106781186548,0.707106781186548,0,-0.707106781186548,0.707106781186548,0,-0.707106781186548,-0.707106781186548,-0,0.707106781186548,0,-1,-0,0,-1,-0,-0,1,0,-0,1,0,0,-1,-0,-0,1,0,0,-1,-0,-0,1,0,0.866025403784439,0,-0.5,0.866025403784439,0,-0.5,-0.866025403784439,-0,0.5,-0.866025403784439,-0,0.5,0.965925826289068,0,-0.258819045102521,0.965925826289068,0,-0.258819045102521,-0.965925826289068,-0,0.258819045102521,-0.965925826289068,-0,0.258819045102521,1,0,2.23960619067965e-16,1,0,2.23960619067965e-16,-1,-0,-2.23960619067965e-16,-1,-0,-2.23960619067965e-16,0.965925826289068,0,0.258819045102521,0.965925826289068,0,0.258819045102521,-0.965925826289068,-0,-0.258819045102521,-0.965925826289068,-0,-0.258819045102521,0.866025403784438,0,0.5,0.866025403784438,0,0.5,-0.866025403784438,-0,-0.5,-0.866025403784438,-0,-0.5,0.707106781186547,0,0.707106781186548,0.707106781186547,0,0.707106781186548,-0.707106781186547,-0,-0.707106781186548,-0.707106781186547,-0,-0.707106781186548,0.499999999999999,0,0.866025403784439,0.499999999999999,0,0.866025403784439,-0.499999999999999,-0,-0.866025403784439,-0.499999999999999,-0,-0.866025403784439,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,-0,1,0,0.25881904510252,0,0.965925826289069,0.25881904510252,0,0.965925826289069,-0.25881904510252,-0,-0.965925826289069,-0.25881904510252,-0,-0.965925826289069,4.89913854211173e-16,-1.12641904883204e-14,-1,-0.25881904510252,-1.15087445727774e-14,-0.965925826289069,4.89913854211173e-16,-1.12641904883204e-14,-1,-0.25881904510252,-1.15087445727774e-14,-0.965925826289069,-4.89913854211173e-16,1.12641904883204e-14,1,0.25881904510252,1.15087445727774e-14,0.965925826289069, +-4.89913854211173e-16,1.12641904883204e-14,1,0.25881904510252,1.15087445727774e-14,0.965925826289069,4.19843443721548e-16,-0.152057184253941,-0.988371697650617,-0.25580941899229,-0.152057184253941,-0.954693748733902,4.19843443721548e-16,-0.152057184253941,-0.988371697650617,-0.25580941899229,-0.152057184253941,-0.954693748733902,-4.19843443721548e-16,0.152057184253941,0.988371697650617,0.25580941899229,0.152057184253941,0.954693748733902,-4.19843443721548e-16,0.152057184253941,0.988371697650617,0,1,-0,0,1,-0,0,1,-0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,0,1,-0,-0,-1,0,0.258819045102521,0,0.965925826289068,0.258819045102521,0,0.965925826289068,-0.258819045102521,-0,-0.965925826289068,-0.258819045102521,-0,-0.965925826289068,-0,1,0,-0,1,0,-0.499999999999999,-1.08996956537765e-14,-0.866025403784439,-0.499999999999999,-1.08996956537765e-14,-0.866025403784439,0.499999999999999,1.08996956537765e-14,0.866025403784439,0.499999999999999,1.08996956537765e-14,0.866025403784439,-0.494185848825308,-0.152057184253941,-0.855954998546987,-0.494185848825308,-0.152057184253941,-0.855954998546987,0.494185848825308,0.152057184253941,0.855954998546987,0.25580941899229,0.152057184253941,0.954693748733902,0,1,-0,-0,-1,0,0,1,-0,-0,-1,0,0.5,0,0.866025403784439,0.5,0,0.866025403784439,-0.5,-0,-0.866025403784439,-0.5,-0,-0.866025403784439,-0,1,0,-0,1,0,-0.707106781186547,-9.08454934101695e-15,-0.707106781186548,-0.707106781186547,-9.08454934101695e-15,-0.707106781186548,0.707106781186547,9.08454934101695e-15,0.707106781186548,0.707106781186547,9.08454934101695e-15,0.707106781186548,-0.698884329741611,-0.152057184253941,-0.698884329741612,-0.698884329741611,-0.152057184253941,-0.698884329741612,0.698884329741611,0.152057184253941,0.698884329741612,0.494185848825308,0.152057184253941,0.855954998546987,0,1,-0,-0,-1,0,0,1,-0,-0,-1,0,0.707106781186548,0,0.707106781186548,0.707106781186548,0,0.707106781186548,-0.707106781186548,-0,-0.707106781186548,-0.707106781186548,-0,-0.707106781186548,0,-1,-0,-0,1,0,0,-1,-0,-0,1,0,-0.866025403784438,-7.131323406091e-15,-0.5, +-0.866025403784438,-7.131323406091e-15,-0.5,0.866025403784438,7.131323406091e-15,0.5,0.866025403784438,7.131323406091e-15,0.5,-0.855954998546986,-0.152057184253941,-0.494185848825309,-0.855954998546986,-0.152057184253941,-0.494185848825309,0.855954998546986,0.152057184253941,0.494185848825309,0.698884329741611,0.152057184253941,0.698884329741612,0,1,-0,-0,-1,0,0,1,-0,-0,-1,0,0.866025403784439,0,0.5,0.866025403784439,0,0.5,-0.866025403784439,-0,-0.5,-0.866025403784439,-0,-0.5,0.965925826289068,0,0.258819045102521,0.965925826289068,0,0.258819045102521,-0.965925826289068,-0,-0.258819045102521,-0.965925826289068,-0,-0.258819045102521,1,0,-1.95965541684469e-16,1,0,-1.95965541684469e-16,-1,-0,1.95965541684469e-16,-1,-0,1.95965541684469e-16,0.965925826289068,0,-0.258819045102521,0.965925826289068,0,-0.258819045102521,-0.965925826289068,-0,0.258819045102521,-0.965925826289068,-0,0.258819045102521,0.866025403784438,0,-0.500000000000001,0.866025403784438,0,-0.500000000000001,-0.866025403784438,-0,0.500000000000001,-0.866025403784438,-0,0.500000000000001,0.707106781186547,0,-0.707106781186548,0.707106781186547,0,-0.707106781186548,-0.707106781186547,-0,0.707106781186548,-0.707106781186547,-0,0.707106781186548,0,-1,-0,0,-1,-0,-0,1,0,-0,1,0,0,-1,-0,-0,1,0,0,-1,-0,-0,1,0,0,-1,-0,-0,1,0,0,-1,-0,-0,1,0,0,-1,-0,-0,1,0,0,-1,-0,0,-1,-0,0,-1,-0,-0,1,0,-0,1,0,-0.965925826289068,-5.09307932489816e-15,-0.258819045102521,-0.965925826289068,-5.09307932489816e-15,-0.258819045102521,0.965925826289068,5.09307932489816e-15,0.258819045102521,0.965925826289068,5.09307932489816e-15,0.258819045102521,-0.954693748733901,-0.152057184253941,-0.255809418992291,-0.954693748733901,-0.152057184253941,-0.255809418992291,0.954693748733901,0.152057184253941,0.255809418992291,0.855954998546986,0.152057184253941,0.494185848825309,0,1,-0,-0,-1,0,0,1,-0,-0,-1,0,0,1,-0,-0,-1,0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,-0,-1,0,-0,-1,0,-0.698884329741611,-0.152057184253941,0.698884329741612,-0.698884329741611,-0.152057184253941,0.698884329741612,0.698884329741611,0.152057184253941,-0.698884329741612, +0.698884329741611,0.152057184253941,-0.698884329741612,-0.707106781186548,0,0.707106781186547,-0.500000000000001,0,0.866025403784438,-0.707106781186548,0,0.707106781186547,-0.500000000000001,0,0.866025403784438,0.707106781186548,-0,-0.707106781186547,0.500000000000001,-0,-0.866025403784438,0.707106781186548,-0,-0.707106781186547,0.500000000000001,-0,-0.866025403784438,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,0,-1,-0,-0,1,0,-0.866025403784438,0,0.500000000000001,-0.866025403784438,0,0.500000000000001,0.866025403784438,-0,-0.500000000000001,0.866025403784438,-0,-0.500000000000001,-0.965925826289068,0,0.258819045102521,-0.965925826289068,0,0.258819045102521,0.965925826289068,-0,-0.258819045102521,0.965925826289068,-0,-0.258819045102521,-1,0,-3.07945851218452e-16,-1,0,-3.07945851218452e-16,1,-0,3.07945851218452e-16,1,-0,3.07945851218452e-16,-0.965925826289068,0,-0.258819045102522,-0.965925826289068,0,-0.258819045102522,0.965925826289068,-0,0.258819045102522,0.965925826289068,-0,0.258819045102522,-0.866025403784438,0,-0.500000000000002,-0.866025403784438,0,-0.500000000000002,0.866025403784438,-0,0.500000000000002,0.866025403784438,-0,0.500000000000002,-0.707106781186547,0,-0.707106781186548,-0.707106781186547,0,-0.707106781186548,0.707106781186547,-0,0.707106781186548,0.707106781186547,-0,0.707106781186548,-0.500000000000001,0,-0.866025403784438,-0.500000000000001,0,-0.866025403784438,0.500000000000001,-0,0.866025403784438,0.500000000000001,-0,0.866025403784438,-0.258819045102521,0,-0.965925826289068,-0.258819045102521,0,-0.965925826289068,0.258819045102521,-0,0.965925826289068,0.258819045102521,-0,0.965925826289068,3.219433899102e-16,0,-1,3.219433899102e-16,0,-1,-3.219433899102e-16,-0,1,-3.219433899102e-16,-0,1,0.258819045102522,0,-0.965925826289068,0.258819045102522,0,-0.965925826289068,-0.258819045102522,-0,0.965925826289068,-0.258819045102522,-0,0.965925826289068,-0.255809418992291,0.152057184253941,0.954693748733901,-0.500000000000002,-0,0.866025403784437,0,-1,-0,-0,1,0,0,-1,-0,-0,1,0,0,-1,-0,-0,1,0, +0,-1,-0,-0,1,0,0.954693748733901,0.152057184253941,0.255809418992291,-0.988371697650617,-0.152057184253941,-5.31801695380628e-16,-0.988371697650617,-0.152057184253941,-5.31801695380628e-16,0.988371697650617,0.152057184253941,5.31801695380628e-16,-1,-1.13036593973881e-15,-2.37958157759713e-16,-1,-1.13036593973881e-15,-2.37958157759713e-16,1,1.13036593973881e-15,2.37958157759713e-16,-0,1,0,0,-1,-0,-0,1,0,1,1.13036593973881e-15,2.37958157759713e-16,-0.965925826289068,2.39835689659947e-15,0.25881904510252,-0.965925826289068,2.39835689659947e-15,0.25881904510252,0.965925826289068,-2.39835689659947e-15,-0.25881904510252,0.965925826289068,-2.39835689659947e-15,-0.25881904510252,-0.954693748733902,-0.152057184253941,0.25580941899229,-0.954693748733902,-0.152057184253941,0.25580941899229,0.988371697650617,0.152057184253941,5.31801695380628e-16,0.954693748733902,0.152057184253941,-0.25580941899229,0.954693748733902,0.152057184253941,-0.25580941899229,-0.855954998546986,-0.152057184253941,0.494185848825309,-0.855954998546986,-0.152057184253941,0.494185848825309,0.855954998546986,0.152057184253941,-0.494185848825309,0.855954998546986,0.152057184253941,-0.494185848825309,-0,-1,0,-0,-1,0,-0.866025403784439,3.77584242285922e-15,0.5,-0.866025403784439,3.77584242285922e-15,0.5,0.866025403784439,-3.77584242285922e-15,-0.5,0.866025403784439,-3.77584242285922e-15,-0.5,-0.707106781186548,-0,0.707106781186548,-0,-1,0,-0,-1,0,-0,-1,0,0,1,-0,-0,-1,0,0,-1,-0,-0,1,0,0,-1,-0,-0,1,0,0,-1,-0,-0,1,0,-0,-1,0,-0,-1,0,-0.698884329741611,0.152057184253941,-0.698884329741612,-0.855954998546986,0.152057184253941,-0.494185848825309,0.866025403784438,7.80731547193642e-15,0.5,0.866025403784438,7.80731547193642e-15,0.5,-0.866025403784438,-7.80731547193642e-15,-0.5,-0.866025403784438,-7.80731547193642e-15,-0.5,-0.965925826289068,-5.28592816826665e-15,-0.258819045102521,-0.707106781186547,-9.60521683617532e-15,-0.707106781186548,-0,1,0,-0,1,0,-0,1,0 + } + } + LayerElementUV: 0 { + Version: 101 + Name: "" + MappingInformationType: "ByPolygonVertex" + ReferenceInformationType: "IndexToDirect" + UV: *258 { + a: 0.253523838921015,0.0679315079009241,0.253523838921015,-0.0679315079009239,0.26246719160105,3.70074341541719e-17,0.227303255586467,-0.131233595800525,3.1496062992126,4.88498130835069e-15,3.04228606705218,-0.815178094811083,3.04228606705218,0.815178094811094,-0.034258843102376,0.721784776902887,0.0342588431023754,0.688976377952756,0.0342588431023754,0.721784776902887,-0.034258843102376,0.688976377952756,-0.411106117228507,8.26771653543307,-0.411106117228507,8.66141732283464,0.41110611722851,8.26771653543307,0.411106117228509,8.66141732283464,-0.0428235538779698,0.210419002562367,0.0342588431023757,0.641861114482852,-0.0342588431023758,0.641861114482852,0.0428235538779696,0.210419002562367,0.513882646535639,2.5250280307484,-0.513882646535634,2.5250280307484,0.411106117228512,7.70233337379422,-2.78388496530137,-2.78388496530136,-2.16535433070866,-3.7505037171767,-1.96850393700788,-3.409548833797,-3.0622734618315,-3.06227346183151,-3.409548833797,-1.96850393700787,-3.7505037171767,-2.16535433070866,-3.80285758381523,-1.01897261851386,-3.93700787401575,4.88498130835069e-15,-4.18314334219675,-1.12086988036525,-3.7505037171767,2.16535433070866,-4.18314334219675,1.12086988036525,-4.33070866141732,-8.88178419700125e-16,-0.565270911189198,3.1496062992126,0.5652709111892,2.75590551181102,0.5652709111892,3.1496062992126,-0.565270911189198,2.75590551181102,3.0622734618315,-3.06227346183151,2.78388496530137,-2.78388496530137,2.16535433070866,-3.7505037171767,3.409548833797,-1.96850393700787,3.7505037171767,-2.16535433070866,3.80285758381523,-1.01897261851386,3.93700787401575,8.88178419700125e-16,4.18314334219675,-1.12086988036525,-0.513882646535635,2.75590551181102,0.513882646535636,0,0.513882646535636,2.75590551181102,-0.513882646535635,0,2.78388496530137,2.78388496530137,1.96850393700788,-3.409548833797,3.409548833797,1.96850393700787,3.80285758381523,1.01897261851386,1.96850393700787,3.409548833797,1.01897261851386,-3.80285758381523,1.01897261851386,3.80285758381523,1.12086988036525,4.18314334219675,2.16535433070866, +3.7505037171767,3.06227346183151,3.0622734618315,3.7505037171767,2.16535433070866,4.18314334219675,1.12086988036525,4.33070866141732,-8.88178419700125e-16,-0.513882646535632,3.14960629921261,0.513882646535641,3.14960629921261,1.12086988036525,-4.18314334219675,-1.12086988036525,-4.18314334219675,-1.01897261851386,-3.80285758381522,0,-4.33070866141732,8.88178419700125e-16,-3.93700787401575,0,3.93700787401575,8.88178419700125e-16,4.33070866141732,-1.12086988036525,4.18314334219675,-1.01897261851386,3.80285758381523,-8.88178419700125e-16,4.33070866141732,-1.96850393700787,3.40954883379701,-2.16535433070866,3.7505037171767,-2.78388496530137,2.78388496530137,-3.06227346183151,3.0622734618315,-3.409548833797,1.96850393700788,-3.80285758381523,1.01897261851387,-0.411106117228503,7.70233337379423,-4.44089209850063e-16,3.93700787401575,3.70074341541719e-17,-0.26246719160105,0.067931507900924,0.253523838921015,0,0.26246719160105,0.0679315079009242,-0.253523838921015,0.131233595800525,0.227303255586467,0.131233595800525,-0.227303255586467,0.185592331020091,0.185592331020091,0.185592331020091,-0.185592331020091,0.227303255586467,0.131233595800525,2.7276390670376,-1.57480314960629,2.7276390670376,1.5748031496063,2.2271079722411,-2.22710797224109,2.22710797224109,2.2271079722411,1.5748031496063,-2.7276390670376,1.5748031496063,2.7276390670376,0.815178094811092,-3.04228606705218,0.815178094811089,3.04228606705219,1.33226762955019e-15,-3.14960629921259,8.88178419700125e-16,3.1496062992126,-0.0679315079009239,-0.253523838921015,-0.815178094811086,-3.04228606705218,-0.0679315079009241,0.253523838921015,-0.815178094811088,3.04228606705219,-1.77635683940025e-15,-3.93700787401574,-3.93700787401575,0,3.93700787401575,4.44089209850063e-15,-0.185592331020091,-0.185592331020091,-0.131233595800525,0.227303255586467,-0.185592331020091,0.185592331020091,-0.131233595800525,-0.227303255586467,-1.5748031496063,-2.7276390670376,-1.5748031496063,2.7276390670376,-2.22710797224109,-2.22710797224109,-2.22710797224109,2.2271079722411,-0.227303255586467, +0.131233595800525,-2.7276390670376,1.5748031496063,-0.227303255586467,-0.131233595800525,-2.7276390670376,-1.5748031496063,-0.253523838921015,0.067931507900924,-3.04228606705218,0.815178094811093,-0.253523838921015,-0.0679315079009243,-3.04228606705218,-0.815178094811087,-0.26246719160105,0,-3.1496062992126,4.44089209850063e-15,-4.33070866141732,0,4.33070866141732,0 + } + UVIndex: *2280 { + a: 0,1,2,1,0,3,4,5,6,7,8,9,8,7,10,11,12,13,7,8,9,8,7,10,11,12,13,7,8,9,8,7,10,11,12,13,9,10,8,10,9,7,13,11,14,15,16,17,16,15,18,19,20,21,22,23,24,22,25,23,26,25,22,26,27,25,28,27,26,29,27,28,27,29,30,30,29,27,31,30,29,32,30,31,30,32,33,33,32,30,34,35,36,35,34,37,36,35,34,35,34,37,34,35,36,36,35,34,35,34,37,34,35,36,36,35,34,35,34,37,34,35,36,36,35,34,37,36,34,36,37,35,35,37,36,38,39,40,38,41,39,42,41,38,42,43,41,42,44,43,44,42,45,45,42,44,37,34,35,43,44,42,46,47,48,47,46,49,48,47,46,47,46,49,46,47,48,48,47,46,47,46,49,46,47,48,48,47,46,49,48,46,48,49,47,47,49,48,39,50,51,39,52,50,41,52,39,41,53,52,43,53,41,53,43,44,44,43,53,49,46,47,46,47,48,47,46,49,48,47,46,49,46,47,46,47,48,47,46,49,48,47,46,49,46,47,46,47,48,47,46,49,48,47,46,49,46,47,48,49,47,49,48,46,47,49,48,51,50,54,51,50,39,54,50,51,51,54,55,55,54,51,55,54,56,56,54,55,48,49,47,49,48,46,47,49,48,46,48,49,54,57,56,54,58,57,50,58,54,50,59,58,52,59,50,52,60,59,53,60,52,44,60,53,45,60,44,45,61,60,61,45,62,62,45,61,37,34,35,60,61,45,35,34,37,34,35,36,36,35,34,37,34,35,37,34,35,34,35,36,35,34,37,36,35,34,37,34,35,36,37,35,37,36,34,35,37,36,58,59,50,50,59,52,59,60,52,52,60,53,53,60,44,44,60,45,48,63,46,63,48,64,46,63,48,63,48,64,48,63,46,46,63,48,63,48,64,48,63,46,46,63,48,63,48,64,48,63,46,46,63,48,64,46,48,46,64,63,48,46,64,46,48,49,40,39,51,40,39,38,51,39,40,40,51,65,65,51,40,65,51,55,55,51,65,49,48,46,48,49,47,47,49,48,46,48,49,64,46,48,46,64,63,48,46,64,63,64,46,16,15,18,15,16,17,19,20,21,24,66,67,24,23,66,24,23,22,66,23,24,37,36,34,36,37,35,35,37,36,34,36,37,37,36,34,36,37,35,35,37,36,65,55,68,68,55,65,68,55,69,69,55,68,49,48,46,48,49,47,47,49,48,55,56,69,69,56,55,69,56,70,70,56,69,48,49,47,49,48,46,47,49,48,46,48,49,56,71,70,56,57,71,56,57,54,71,57,56,36,37,35,37,36,34,35,37,36,34,36,37,72,73,74,72,75,73,76,75,72,76,77,75,78,77,76,78,79,77,31,79,78,31,80,79,31,29,80,29,30,31,31,30,32,80,29,31,18,17,15,17,18,16,20,81,19,17,18,16,18,17,15,20,81,19,17,18,16,18,17,15,20,81,19,17,18,16,18,17,15,20,81,19,21,19,81,22,25,26,23,25,22,34,36,37,25, +27,26,26,27,28,28,27,29,64,48,63,64,48,63,64,48,63,21,19,81,21,19,81,21,19,81,15,16,17,16,15,18,81,21,20,8,7,10,7,8,9,11,12,13,7,8,9,8,7,10,11,12,13,14,13,12,14,13,12,14,13,12,8,7,10,7,8,9,11,12,13,14,13,12,10,9,7,9,10,8,13,11,14,15,16,17,16,15,18,19,20,21,75,77,76,46,64,63,64,46,48,48,46,64,46,48,49,54,58,50,57,58,54,36,37,35,37,36,34,35,37,36,34,36,37,72,75,76,73,75,72,16,15,18,15,16,17,19,20,21,46,64,63,64,46,48,48,46,64,63,64,46,46,64,63,64,46,48,48,46,64,70,71,56,70,71,72,72,71,70,36,37,35,37,36,34,35,37,36,34,36,37,74,82,57,74,73,82,74,73,72,82,73,74,16,15,18,15,16,17,19,20,21,63,64,46,81,21,20,9,10,8,10,9,7,13,11,14,12,14,11,83,84,85,86,84,83,86,87,84,88,87,86,88,89,87,90,89,88,90,91,89,3,91,90,3,0,91,92,6,5,93,6,92,94,93,92,95,93,94,96,95,94,97,95,96,12,14,11,98,97,96,99,97,98,10,9,7,9,10,8,13,11,14,81,21,20,12,14,11,100,99,98,101,99,100,83,85,102,103,101,100,102,85,104,105,101,103,10,9,7,9,10,8,13,11,14,15,16,17,16,15,18,19,20,21,57,82,56,57,82,74,56,82,57,46,64,63,64,46,48,48,46,64,49,48,46,48,49,47,47,49,48,67,70,73,69,70,67,67,70,69,73,70,67,67,73,24,24,73,67,24,73,75,75,73,24,48,49,47,49,48,46,47,49,48,46,48,49,73,72,75,70,72,73,73,72,70,75,72,73,75,72,76,76,72,75,36,37,35,37,36,34,35,37,36,34,36,37,57,54,58,57,56,54,54,56,57,16,15,18,15,16,17,19,20,21,46,64,63,64,46,48,48,46,64,63,64,46,46,64,63,64,46,48,48,46,64,49,48,46,48,49,47,47,49,48,22,75,77,24,75,22,22,75,24,77,75,22,22,77,26,26,77,22,26,77,79,79,77,26,47,46,49,46,47,48,49,46,47,46,47,48,47,46,49,49,46,47,46,47,48,47,46,49,49,46,47,46,47,48,47,46,49,49,46,47,46,47,48,47,46,49,49,46,47,46,47,48,47,46,49,49,46,47,48,49,47,49,48,46,47,49,48,46,48,49,23,24,22,66,24,23,66,67,24,68,67,66,68,69,67,67,69,68,49,48,46,48,49,47,47,49,48,46,48,49,64,46,48,46,64,63,48,46,64,63,64,46,16,15,18,15,16,17,19,20,21,106,68,55,67,68,106,67,66,68,67,66,24,68,66,67,34,36,37,106,68,67,55,68,106,55,68,65,65,68,55,37,36,34,36,37,35,35,37,36,66,67,68,24,67,66,49,48,46,48,49,47,47,49,48,46,48,49,64,46,48,46,64,63,48,46,64,63,64,46,16,15,18,15,16,17,19,20,21,55,65,51,51, +65,55,51,65,40,40,65,51,37,36,34,36,37,35,35,37,36,23,24,66,22,24,23,64,46,48,46,64,63,48,46,64,63,64,46,16,15,18,15,16,17,19,20,21,51,40,39,39,40,51,39,40,38,38,40,39,37,36,34,36,37,35,35,37,36,23,22,25,25,22,23,25,22,26,26,22,25,48,47,46,64,46,48,46,64,63,48,46,64,63,64,46,16,15,18,15,16,17,19,20,21,39,38,41,41,38,39,41,38,42,42,38,41,34,35,36,35,34,37,37,34,35,36,35,34,35,34,37,34,35,36,37,34,35,36,35,34,35,34,37,34,35,36,37,34,35,36,35,34,35,34,37,34,35,36,37,34,35,36,35,34,35,34,37,34,35,36,37,34,35,36,35,34,35,34,37,34,35,36,37,34,35,36,35,34,37,36,34,36,37,35,35,37,36,77,76,78,75,76,77,77,76,75,78,76,77,77,78,79,79,78,77,79,78,31,31,78,79,79,31,80,80,31,79,80,31,32,32,31,80,80,32,107,107,32,80,30,107,32,30,28,107,27,28,30,27,26,28,25,26,27,27,26,25,28,26,27,48,47,46,64,46,48,46,64,63,48,46,64,63,64,46,16,15,18,15,16,17,19,20,21,41,42,43,43,42,41,43,42,45,45,42,43,43,45,108,108,45,43,61,108,45,61,53,108,60,53,61,60,52,53,59,52,60,59,50,52,58,50,59,58,54,50,58,54,57,50,54,58,16,15,18,15,16,17,19,20,21,63,64,46,81,21,20,9,10,8,10,9,7,13,11,14,12,14,11,109,110,111,112,110,109,112,104,110,102,104,112,113,105,103,114,105,113,10,9,7,9,10,8,13,11,14,81,21,20,12,14,11,115,114,113,116,114,115,109,111,117,118,116,115,7,8,9,8,7,10,14,13,12,8,7,10,7,8,9,14,13,12,8,7,10,7,8,9,14,13,12,8,7,10,7,8,9,14,13,12,8,7,10,7,8,9,14,13,12,8,7,10,7,8,9,14,13,12,10,9,7,9,10,8,13,11,14,81,21,20,12,14,11,10,9,7,9,10,8,13,11,14,81,21,20,12,14,11,10,9,7,9,10,8,13,11,14,81,21,20,12,14,11,10,9,7,9,10,8,13,11,14,15,16,17,16,15,18,19,20,21,46,64,63,64,46,48,48,46,64,46,48,49,63,64,46,81,21,20,81,21,20,9,10,8,10,9,7,13,11,14,12,14,11,12,14,11,12,14,11,11,12,13,81,21,20,109,117,119,120,118,115,119,117,121,122,118,120,119,121,123,124,122,120,123,121,125,126,122,124,11,12,13,81,21,20,16,15,18,15,16,17,19,20,21,46,64,63,64,46,48,48,46,64,48,47,46,107,28,30,30,28,27,32,107,30,30,32,127,127,32,30,63,64,46,64,46,48,46,64,63,48,46,64,48,47,46,63,64,46,18,17,15,17,18,16,21,19,81,81,21,20,11,12,13,20,81,19,17,18,16,18,17,15,21,19,81,20,81,19,17,18,16,18, +17,15,21,19,81,20,81,19,52,50,59,46,64,63,64,46,48,48,46,64,48,47,46,46,48,49,63,64,46,46,64,63,64,46,48,48,46,64,48,47,46,63,64,46,53,52,60,60,52,59,61,53,60,108,53,61,45,108,61,61,45,128,128,45,61,59,50,58,34,36,37,11,12,13,11,12,13,11,12,13,34,36,37,34,36,37,34,36,37,26,79,28,28,79,26,28,79,80,80,79,28,28,80,107,107,80,28,46,48,49,63,64,46,81,21,20,12,14,11,14,13,12,14,13,12,34,36,37,76,77,78,77,79,78,16,15,18,15,16,17,81,21,20,19,20,21,63,48,64,48,63,46,46,63,48,63,48,64,48,63,46,46,63,48,64,48,63,64,48,63,19,20,21,79,80,31,78,79,31,64,48,63,63,64,46,81,21,20,63,64,46,81,21,20,39,41,38,38,41,42,41,43,42,37,34,35,50,52,39,39,52,41,52,53,41,41,53,43,49,46,47,49,46,47 + } + } + LayerElementMaterial: 0 { + Version: 101 + Name: "" + MappingInformationType: "ByPolygon" + ReferenceInformationType: "IndexToDirect" + Materials: *760 { + a: 0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,1,0,0,1,0,0,1,0,0,1,1,2,2,2,2,2,2,2,2,2,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,0,0,1,0,0,1,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,1,2,1,0,0,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,0,1,0,1,0,0,1,0,0,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,1,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,1,2,1,0,0,1,1,0,0,0,0,1,1,0,0,1,1,1,1,1,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,0,0,1,1,1,0,0,1,1,1,0,0,1,0,0,1,2,2,2,2,2,1,1,0,0,1,1,1,1,1,1,0,1,0,1,0,1,0,1,1,1,0,0,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,1,1,1,1,0,0,1,1,0,0,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,2,2,2,0,0,1,1,2,2,2,2,2,2,2,2,1,2,2,2,2,1,2,1,2,2,2,2,2,2,2,2,2,2 + } + } + Layer: 0 { + Version: 100 + LayerElement: { + Type: "LayerElementNormal" + TypedIndex: 0 + } + LayerElement: { + Type: "LayerElementMaterial" + TypedIndex: 0 + } + LayerElement: { + Type: "LayerElementTexture" + TypedIndex: 0 + } + LayerElement: { + Type: "LayerElementUV" + TypedIndex: 0 + } + } + } + Model: 140593525102080, "Model::Model", "Null" { + Version: 232 + Properties70: { + P: "ScalingMax", "Vector3D", "Vector", "",0,0,0 + } + Shading: Y + Culling: "CullingOff" + } + Model: 140593525190656, "Model::Group1", "Null" { + Version: 232 + Properties70: { + P: "ScalingMax", "Vector3D", "Vector", "",0,0,0 + } + Shading: Y + Culling: "CullingOff" + } + Model: 140593521132544, "Model::Mesh1", "Mesh" { + Version: 232 + Properties70: { + P: "ScalingMax", "Vector3D", "Vector", "",0,0,0 + P: "DefaultAttributeIndex", "int", "Integer", "",0 + } + Shading: T + Culling: "CullingOff" + } + Model: 140593542855168, "Model::Mesh2", "Mesh" { + Version: 232 + Properties70: { + P: "ScalingMax", "Vector3D", "Vector", "",0,0,0 + P: "DefaultAttributeIndex", "int", "Integer", "",0 + } + Shading: T + Culling: "CullingOff" + } + Model: 140593517671936, "Model::Mesh3", "Mesh" { + Version: 232 + Properties70: { + P: "ScalingMax", "Vector3D", "Vector", "",0,0,0 + P: "DefaultAttributeIndex", "int", "Integer", "",0 + } + Shading: T + Culling: "CullingOff" + } + Model: 140593600620544, "Model::Mesh4", "Mesh" { + Version: 232 + Properties70: { + P: "ScalingMax", "Vector3D", "Vector", "",0,0,0 + P: "DefaultAttributeIndex", "int", "Integer", "",0 + } + Shading: T + Culling: "CullingOff" + } + Material: 140593612588496, "Material::_10", "" { + Version: 102 + ShadingModel: "phong" + MultiLayer: 0 + Properties70: { + P: "AmbientColor", "Color", "", "A",0,0,0 + P: "DiffuseColor", "Color", "", "A",0.984313725490196,0.992156862745098,0.909803921568627 + P: "TransparentColor", "Color", "", "A",1,1,1 + P: "SpecularColor", "Color", "", "A",0.33,0.33,0.33 + P: "ReflectionFactor", "Number", "", "A",0 + P: "Emissive", "Vector3D", "Vector", "",0,0,0 + P: "Ambient", "Vector3D", "Vector", "",0,0,0 + P: "Diffuse", "Vector3D", "Vector", "",0.984313725490196,0.992156862745098,0.909803921568627 + P: "Specular", "Vector3D", "Vector", "",0.33,0.33,0.33 + P: "Shininess", "double", "Number", "",20 + P: "Opacity", "double", "Number", "",1 + P: "Reflectivity", "double", "Number", "",0 + } + } + Material: 140593593880064, "Material::Metal_Silver", "" { + Version: 102 + ShadingModel: "phong" + MultiLayer: 0 + Properties70: { + P: "AmbientColor", "Color", "", "A",0,0,0 + P: "DiffuseColor", "Color", "", "A",0.913725490196078,0.909803921568627,0.929411764705882 + P: "TransparentColor", "Color", "", "A",1,1,1 + P: "SpecularColor", "Color", "", "A",0.33,0.33,0.33 + P: "ReflectionFactor", "Number", "", "A",0 + P: "Emissive", "Vector3D", "Vector", "",0,0,0 + P: "Ambient", "Vector3D", "Vector", "",0,0,0 + P: "Diffuse", "Vector3D", "Vector", "",0.913725490196078,0.909803921568627,0.929411764705882 + P: "Specular", "Vector3D", "Vector", "",0.33,0.33,0.33 + P: "Shininess", "double", "Number", "",20 + P: "Opacity", "double", "Number", "",1 + P: "Reflectivity", "double", "Number", "",0 + } + } + Material: 140593594304416, "Material::_8", "" { + Version: 102 + ShadingModel: "phong" + MultiLayer: 0 + Properties70: { + P: "AmbientColor", "Color", "", "A",0,0,0 + P: "DiffuseColor", "Color", "", "A",1,0,0 + P: "TransparentColor", "Color", "", "A",1,1,1 + P: "SpecularColor", "Color", "", "A",0.33,0.33,0.33 + P: "ReflectionFactor", "Number", "", "A",0 + P: "Emissive", "Vector3D", "Vector", "",0,0,0 + P: "Ambient", "Vector3D", "Vector", "",0,0,0 + P: "Diffuse", "Vector3D", "Vector", "",1,0,0 + P: "Specular", "Vector3D", "Vector", "",0.33,0.33,0.33 + P: "Shininess", "double", "Number", "",20 + P: "Opacity", "double", "Number", "",1 + P: "Reflectivity", "double", "Number", "",0 + } + } + Material: 140593611933680, "Material::_9", "" { + Version: 102 + ShadingModel: "phong" + MultiLayer: 0 + Properties70: { + P: "AmbientColor", "Color", "", "A",0,0,0 + P: "DiffuseColor", "Color", "", "A",0.647058823529412,0.650980392156863,0.596078431372549 + P: "TransparentColor", "Color", "", "A",1,1,1 + P: "SpecularColor", "Color", "", "A",0.33,0.33,0.33 + P: "ReflectionFactor", "Number", "", "A",0 + P: "Emissive", "Vector3D", "Vector", "",0,0,0 + P: "Ambient", "Vector3D", "Vector", "",0,0,0 + P: "Diffuse", "Vector3D", "Vector", "",0.647058823529412,0.650980392156863,0.596078431372549 + P: "Specular", "Vector3D", "Vector", "",0.33,0.33,0.33 + P: "Shininess", "double", "Number", "",20 + P: "Opacity", "double", "Number", "",1 + P: "Reflectivity", "double", "Number", "",0 + } + } + Video: 140593624465312, "Video::Metal_Silver_texture", "Clip" { + Type: "Clip" + Properties70: { + P: "Path", "KString", "XRefUrl", "", "cherrytop/Metal_Silver.jpg" + } + UseMipMap: 0 + Filename: "cherrytop/Metal_Silver.jpg" + RelativeFilename: "../../../../../Metal_Silver.jpg" + } + Texture: 140593593900128, "Texture::Metal_Silver_texture", "" { + Type: "TextureVideoClip" + Version: 202 + TextureName: "Texture::Metal_Silver_texture" + Media: "Video::Metal_Silver_texture" + FileName: "cherrytop/Metal_Silver.jpg" + RelativeFilename: "../../../../../Metal_Silver.jpg" + ModelUVTranslation: 0,0 + ModelUVScaling: 1,1 + Texture_Alpha_Source: "None" + Cropping: 0,0,0,0 + } +} + +; Object connections +;------------------------------------------------------------------ + +Connections: { + + ;Model::Model, Model::RootNode + C: "OO",140593525102080,0 + + ;Model::Group1, Model::Model + C: "OO",140593525190656,140593525102080 + + ;Model::Mesh4, Model::Model + C: "OO",140593600620544,140593525102080 + + ;Model::Mesh1, Model::Group1 + C: "OO",140593521132544,140593525190656 + + ;Model::Mesh2, Model::Group1 + C: "OO",140593542855168,140593525190656 + + ;Model::Mesh3, Model::Group1 + C: "OO",140593517671936,140593525190656 + + ;Geometry::, Model::Mesh1 + C: "OO",140593614758912,140593521132544 + + ;Material::_10, Model::Mesh1 + C: "OO",140593612588496,140593521132544 + + ;Geometry::, Model::Mesh2 + C: "OO",140593608540656,140593542855168 + + ;Material::_10, Model::Mesh2 + C: "OO",140593612588496,140593542855168 + + ;Geometry::, Model::Mesh3 + C: "OO",140593614728304,140593517671936 + + ;Material::_10, Model::Mesh3 + C: "OO",140593612588496,140593517671936 + + ;Geometry::, Model::Mesh4 + C: "OO",140593624419968,140593600620544 + + ;Material::Metal_Silver, Model::Mesh4 + C: "OO",140593593880064,140593600620544 + + ;Material::_8, Model::Mesh4 + C: "OO",140593594304416,140593600620544 + + ;Material::_9, Model::Mesh4 + C: "OO",140593611933680,140593600620544 + + ;Texture::Metal_Silver_texture, Model::Mesh4 + C: "OO",140593593900128,140593600620544 + + ;Video::Metal_Silver_texture, Texture::Metal_Silver_texture + C: "OO",140593624465312,140593593900128 + + ;Texture::Metal_Silver_texture, Material::Metal_Silver + C: "OP",140593593900128,140593593880064, "DiffuseColor" +} +;Takes section +;---------------------------------------------------- + +Takes: { + Current: "" +} diff --git a/src/parts source/kOS Cherry Light/cherrytop meshes/colored dome.fbx b/src/parts source/kOS Cherry Light/cherrytop meshes/colored dome.fbx new file mode 100644 index 000000000..a8057a243 --- /dev/null +++ b/src/parts source/kOS Cherry Light/cherrytop meshes/colored dome.fbx @@ -0,0 +1,453 @@ +; FBX 7.3.0 project file +; Copyright (C) 1997-2010 Autodesk Inc. and/or its licensors. +; All rights reserved. +; ---------------------------------------------------- + +FBXHeaderExtension: { + FBXHeaderVersion: 1003 + FBXVersion: 7300 + CreationTimeStamp: { + Version: 1000 + Year: 2016 + Month: 1 + Day: 27 + Hour: 9 + Minute: 57 + Second: 32 + Millisecond: 0 + } + Creator: "FBX SDK/FBX Plugins version 2013.3" + SceneInfo: "SceneInfo::GlobalInfo", "UserData" { + Type: "UserData" + Version: 100 + MetaData: { + Version: 100 + Title: "" + Subject: "" + Author: "" + Keywords: "" + Revision: "" + Comment: "" + } + Properties70: { + P: "DocumentUrl", "KString", "Url", "", "/var/folders/16/csq8fhn9279gfgk7gc955t500000gn/T/com.sketchup.SketchUp.2016.petergoddard7fYZwZ.fbx" + P: "SrcDocumentUrl", "KString", "Url", "", "/var/folders/16/csq8fhn9279gfgk7gc955t500000gn/T/com.sketchup.SketchUp.2016.petergoddard7fYZwZ.fbx" + P: "Original", "Compound", "", "" + P: "Original|ApplicationVendor", "KString", "", "", "" + P: "Original|ApplicationName", "KString", "", "", "" + P: "Original|ApplicationVersion", "KString", "", "", "" + P: "Original|DateTime_GMT", "DateTime", "", "", "" + P: "Original|FileName", "KString", "", "", "" + P: "LastSaved", "Compound", "", "" + P: "LastSaved|ApplicationVendor", "KString", "", "", "" + P: "LastSaved|ApplicationName", "KString", "", "", "" + P: "LastSaved|ApplicationVersion", "KString", "", "", "" + P: "LastSaved|DateTime_GMT", "DateTime", "", "", "" + } + } +} +GlobalSettings: { + Version: 1000 + Properties70: { + P: "UpAxis", "int", "Integer", "",1 + P: "UpAxisSign", "int", "Integer", "",1 + P: "FrontAxis", "int", "Integer", "",2 + P: "FrontAxisSign", "int", "Integer", "",1 + P: "CoordAxis", "int", "Integer", "",0 + P: "CoordAxisSign", "int", "Integer", "",1 + P: "OriginalUpAxis", "int", "Integer", "",-1 + P: "OriginalUpAxisSign", "int", "Integer", "",1 + P: "UnitScaleFactor", "double", "Number", "",1 + P: "OriginalUnitScaleFactor", "double", "Number", "",1 + P: "AmbientColor", "ColorRGB", "Color", "",0,0,0 + P: "DefaultCamera", "KString", "", "", "Producer Perspective" + P: "TimeMode", "enum", "", "",0 + P: "TimeSpanStart", "KTime", "Time", "",0 + P: "TimeSpanStop", "KTime", "Time", "",46186158000 + P: "CustomFrameRate", "double", "Number", "",-1 + } +} + +; Documents Description +;------------------------------------------------------------------ + +Documents: { + Count: 1 + Document: 140593624845344, "", "Scene" { + Properties70: { + P: "SourceObject", "object", "", "" + P: "ActiveAnimStackName", "KString", "", "", "" + } + RootNode: 0 + } +} + +; Document References +;------------------------------------------------------------------ + +References: { +} + +; Object definitions +;------------------------------------------------------------------ + +Definitions: { + Version: 100 + Count: 8 + ObjectType: "GlobalSettings" { + Count: 1 + } + ObjectType: "Model" { + Count: 2 + PropertyTemplate: "FbxNode" { + Properties70: { + P: "QuaternionInterpolate", "enum", "", "",0 + P: "RotationOffset", "Vector3D", "Vector", "",0,0,0 + P: "RotationPivot", "Vector3D", "Vector", "",0,0,0 + P: "ScalingOffset", "Vector3D", "Vector", "",0,0,0 + P: "ScalingPivot", "Vector3D", "Vector", "",0,0,0 + P: "TranslationActive", "bool", "", "",0 + P: "TranslationMin", "Vector3D", "Vector", "",0,0,0 + P: "TranslationMax", "Vector3D", "Vector", "",0,0,0 + P: "TranslationMinX", "bool", "", "",0 + P: "TranslationMinY", "bool", "", "",0 + P: "TranslationMinZ", "bool", "", "",0 + P: "TranslationMaxX", "bool", "", "",0 + P: "TranslationMaxY", "bool", "", "",0 + P: "TranslationMaxZ", "bool", "", "",0 + P: "RotationOrder", "enum", "", "",0 + P: "RotationSpaceForLimitOnly", "bool", "", "",0 + P: "RotationStiffnessX", "double", "Number", "",0 + P: "RotationStiffnessY", "double", "Number", "",0 + P: "RotationStiffnessZ", "double", "Number", "",0 + P: "AxisLen", "double", "Number", "",10 + P: "PreRotation", "Vector3D", "Vector", "",0,0,0 + P: "PostRotation", "Vector3D", "Vector", "",0,0,0 + P: "RotationActive", "bool", "", "",0 + P: "RotationMin", "Vector3D", "Vector", "",0,0,0 + P: "RotationMax", "Vector3D", "Vector", "",0,0,0 + P: "RotationMinX", "bool", "", "",0 + P: "RotationMinY", "bool", "", "",0 + P: "RotationMinZ", "bool", "", "",0 + P: "RotationMaxX", "bool", "", "",0 + P: "RotationMaxY", "bool", "", "",0 + P: "RotationMaxZ", "bool", "", "",0 + P: "InheritType", "enum", "", "",0 + P: "ScalingActive", "bool", "", "",0 + P: "ScalingMin", "Vector3D", "Vector", "",0,0,0 + P: "ScalingMax", "Vector3D", "Vector", "",1,1,1 + P: "ScalingMinX", "bool", "", "",0 + P: "ScalingMinY", "bool", "", "",0 + P: "ScalingMinZ", "bool", "", "",0 + P: "ScalingMaxX", "bool", "", "",0 + P: "ScalingMaxY", "bool", "", "",0 + P: "ScalingMaxZ", "bool", "", "",0 + P: "GeometricTranslation", "Vector3D", "Vector", "",0,0,0 + P: "GeometricRotation", "Vector3D", "Vector", "",0,0,0 + P: "GeometricScaling", "Vector3D", "Vector", "",1,1,1 + P: "MinDampRangeX", "double", "Number", "",0 + P: "MinDampRangeY", "double", "Number", "",0 + P: "MinDampRangeZ", "double", "Number", "",0 + P: "MaxDampRangeX", "double", "Number", "",0 + P: "MaxDampRangeY", "double", "Number", "",0 + P: "MaxDampRangeZ", "double", "Number", "",0 + P: "MinDampStrengthX", "double", "Number", "",0 + P: "MinDampStrengthY", "double", "Number", "",0 + P: "MinDampStrengthZ", "double", "Number", "",0 + P: "MaxDampStrengthX", "double", "Number", "",0 + P: "MaxDampStrengthY", "double", "Number", "",0 + P: "MaxDampStrengthZ", "double", "Number", "",0 + P: "PreferedAngleX", "double", "Number", "",0 + P: "PreferedAngleY", "double", "Number", "",0 + P: "PreferedAngleZ", "double", "Number", "",0 + P: "LookAtProperty", "object", "", "" + P: "UpVectorProperty", "object", "", "" + P: "Show", "bool", "", "",1 + P: "NegativePercentShapeSupport", "bool", "", "",1 + P: "DefaultAttributeIndex", "int", "Integer", "",-1 + P: "Freeze", "bool", "", "",0 + P: "LODBox", "bool", "", "",0 + P: "Lcl Translation", "Lcl Translation", "", "A",0,0,0 + P: "Lcl Rotation", "Lcl Rotation", "", "A",0,0,0 + P: "Lcl Scaling", "Lcl Scaling", "", "A",1,1,1 + P: "Visibility", "Visibility", "", "A",1 + P: "Visibility Inheritance", "Visibility Inheritance", "", "",1 + } + } + } + ObjectType: "Texture" { + Count: 1 + PropertyTemplate: "FbxFileTexture" { + Properties70: { + P: "TextureTypeUse", "enum", "", "",0 + P: "Texture alpha", "Number", "", "A",1 + P: "CurrentMappingType", "enum", "", "",0 + P: "WrapModeU", "enum", "", "",0 + P: "WrapModeV", "enum", "", "",0 + P: "UVSwap", "bool", "", "",0 + P: "PremultiplyAlpha", "bool", "", "",1 + P: "Translation", "Vector", "", "A",0,0,0 + P: "Rotation", "Vector", "", "A",0,0,0 + P: "Scaling", "Vector", "", "A",1,1,1 + P: "TextureRotationPivot", "Vector3D", "Vector", "",0,0,0 + P: "TextureScalingPivot", "Vector3D", "Vector", "",0,0,0 + P: "CurrentTextureBlendMode", "enum", "", "",1 + P: "UVSet", "KString", "", "", "default" + P: "UseMaterial", "bool", "", "",0 + P: "UseMipMap", "bool", "", "",0 + } + } + } + ObjectType: "Geometry" { + Count: 1 + PropertyTemplate: "FbxMesh" { + Properties70: { + P: "Color", "ColorRGB", "Color", "",0.8,0.8,0.8 + P: "BBoxMin", "Vector3D", "Vector", "",0,0,0 + P: "BBoxMax", "Vector3D", "Vector", "",0,0,0 + P: "Primary Visibility", "bool", "", "",1 + P: "Casts Shadows", "bool", "", "",1 + P: "Receive Shadows", "bool", "", "",1 + } + } + } + ObjectType: "Material" { + Count: 2 + PropertyTemplate: "FbxSurfacePhong" { + Properties70: { + P: "ShadingModel", "KString", "", "", "Phong" + P: "MultiLayer", "bool", "", "",0 + P: "EmissiveColor", "Color", "", "A",0,0,0 + P: "EmissiveFactor", "Number", "", "A",1 + P: "AmbientColor", "Color", "", "A",0.2,0.2,0.2 + P: "AmbientFactor", "Number", "", "A",1 + P: "DiffuseColor", "Color", "", "A",0.8,0.8,0.8 + P: "DiffuseFactor", "Number", "", "A",1 + P: "Bump", "Vector3D", "Vector", "",0,0,0 + P: "NormalMap", "Vector3D", "Vector", "",0,0,0 + P: "BumpFactor", "double", "Number", "",1 + P: "TransparentColor", "Color", "", "A",0,0,0 + P: "TransparencyFactor", "Number", "", "A",0 + P: "DisplacementColor", "ColorRGB", "Color", "",0,0,0 + P: "DisplacementFactor", "double", "Number", "",1 + P: "VectorDisplacementColor", "ColorRGB", "Color", "",0,0,0 + P: "VectorDisplacementFactor", "double", "Number", "",1 + P: "SpecularColor", "Color", "", "A",0.2,0.2,0.2 + P: "SpecularFactor", "Number", "", "A",1 + P: "ShininessExponent", "Number", "", "A",20 + P: "ReflectionColor", "Color", "", "A",0,0,0 + P: "ReflectionFactor", "Number", "", "A",1 + } + } + } + ObjectType: "Video" { + Count: 1 + PropertyTemplate: "FbxVideo" { + Properties70: { + P: "ImageSequence", "bool", "", "",0 + P: "ImageSequenceOffset", "int", "Integer", "",0 + P: "FrameRate", "double", "Number", "",0 + P: "LastFrame", "int", "Integer", "",0 + P: "Width", "int", "Integer", "",0 + P: "Height", "int", "Integer", "",0 + P: "Path", "KString", "XRefUrl", "", "" + P: "StartFrame", "int", "Integer", "",0 + P: "StopFrame", "int", "Integer", "",0 + P: "PlaySpeed", "double", "Number", "",0 + P: "Offset", "KTime", "Time", "",0 + P: "InterlaceMode", "enum", "", "",0 + P: "FreeRunning", "bool", "", "",0 + P: "Loop", "bool", "", "",0 + P: "AccessMode", "enum", "", "",0 + } + } + } +} + +; Object properties +;------------------------------------------------------------------ + +Objects: { + Geometry: 140593626116512, "Geometry::", "Mesh" { + Vertices: *720 { + a: -0.0772740661031255,0.22,-0.0207055236082018,-0.0772740661031255,0.22,0.0207055236082015,-0.08,0.22,-1.24078525232107e-16,-0.0692820323027551,0.22,0.0399999999999999,-0.0692820323027551,0.22,-0.0400000000000001,-0.0565685424949238,0.22,0.0565685424949236,-0.0565685424949238,0.22,-0.0565685424949239,-0.04,0.22,0.0692820323027549,-0.04,0.22,-0.0692820323027552,-0.0207055236082017,0.22,0.0772740661031253,-0.0207055236082017,0.22,-0.0772740661031256,-3.38395977905748e-17,0.22,0.0799999999999999,-2.25597318603832e-17,0.22,-0.0800000000000001,0.0207055236082016,0.22,0.0772740661031254,0.0207055236082016,0.22,-0.0772740661031256,0.0399999999999999,0.22,0.069282032302755,0.04,0.22,-0.0692820323027552,0.0565685424949237,0.22,0.0565685424949237,0.0565685424949237,0.22,-0.0565685424949239,0.069282032302755,0.22,-0.0400000000000001,0.069282032302755,0.22,0.0399999999999999,0.0772740661031255,0.22,-0.0207055236082018,0.0772740661031254,0.22,0.0207055236082016,0.08,0.22,-1.12798659301916e-16,-0.08,0.22,-1.24078525232107e-16,-0.0772740661031255,0.22,0.0207055236082015,-0.0772740661031255,0.22,-0.0207055236082018,-0.0692820323027551,0.22,0.0399999999999999,-0.0692820323027551,0.22,-0.0400000000000001,-0.0565685424949238,0.22,0.0565685424949236,-0.0565685424949238,0.22,-0.0565685424949239,-0.04,0.22,0.0692820323027549,-0.04,0.22,-0.0692820323027552,-0.0207055236082017,0.22,0.0772740661031253,-0.0207055236082017,0.22,-0.0772740661031256,-3.38395977905748e-17,0.22,0.0799999999999999,-2.25597318603832e-17,0.22,-0.0800000000000001,0.0207055236082016,0.22,0.0772740661031254,0.0207055236082016,0.22,-0.0772740661031256,0.0399999999999999,0.22,0.069282032302755,0.04,0.22,-0.0692820323027552,0.0565685424949237,0.22,0.0565685424949237,0.0565685424949237,0.22,-0.0565685424949239,0.069282032302755,0.22,-0.0400000000000001,0.069282032302755,0.22,0.0399999999999999,0.0772740661031255,0.22,-0.0207055236082018,0.0772740661031254,0.22,0.0207055236082016,0.08,0.22,-1.12798659301916e-16,0.069282032302755,0.22,-0.0400000000000001,0.0772740661031255,0.21,-0.0207055236082018, +0.0772740661031255,0.22,-0.0207055236082018,0.069282032302755,0.21,-0.0400000000000001,0.0772740661031255,0.22,-0.0207055236082018,0.0772740661031255,0.21,-0.0207055236082018,0.069282032302755,0.22,-0.0400000000000001,0.069282032302755,0.21,-0.0400000000000001,0.08,0.21,-1.12798659301916e-16,0.08,0.22,-1.12798659301916e-16,0.08,0.22,-1.12798659301916e-16,0.08,0.21,-1.12798659301916e-16,0.0772740661031254,0.21,0.0207055236082016,0.0772740661031254,0.22,0.0207055236082016,0.0772740661031254,0.22,0.0207055236082016,0.0772740661031254,0.21,0.0207055236082016,0.069282032302755,0.21,0.0399999999999999,0.069282032302755,0.22,0.0399999999999999,0.069282032302755,0.22,0.0399999999999999,0.069282032302755,0.21,0.0399999999999999,0.0565685424949237,0.21,0.0565685424949237,0.0565685424949237,0.22,0.0565685424949237,0.0565685424949237,0.22,0.0565685424949237,0.0565685424949237,0.21,0.0565685424949237,0.0399999999999999,0.22,0.069282032302755,0.0399999999999999,0.21,0.069282032302755,0.0399999999999999,0.21,0.069282032302755,0.0399999999999999,0.22,0.069282032302755,0.0207055236082016,0.22,0.0772740661031254,0.0207055236082016,0.21,0.0772740661031254,0.0207055236082016,0.21,0.0772740661031254,0.0207055236082016,0.22,0.0772740661031254,-3.38395977905748e-17,0.22,0.0799999999999999,-3.38395977905748e-17,0.21,0.0799999999999999,-3.38395977905748e-17,0.21,0.0799999999999999,-3.38395977905748e-17,0.22,0.0799999999999999,-0.0207055236082017,0.22,0.0772740661031253,-0.0207055236082017,0.21,0.0772740661031253,-0.0207055236082017,0.21,0.0772740661031253,-0.0207055236082017,0.22,0.0772740661031253,-0.04,0.22,0.0692820323027549,-0.04,0.21,0.0692820323027549,-0.04,0.21,0.0692820323027549,-0.04,0.22,0.0692820323027549,-0.0565685424949238,0.22,0.0565685424949236,-0.0565685424949238,0.21,0.0565685424949236,-0.0565685424949238,0.21,0.0565685424949236,-0.0565685424949238,0.22,0.0565685424949236,-0.0692820323027551,0.21,0.0399999999999999,-0.0692820323027551,0.22,0.0399999999999999,-0.0692820323027551,0.21,0.0399999999999999,-0.0692820323027551,0.22,0.0399999999999999, +-0.0772740661031255,0.21,0.0207055236082015,-0.0772740661031255,0.22,0.0207055236082015,-0.0772740661031255,0.21,0.0207055236082015,-0.0772740661031255,0.22,0.0207055236082015,-0.08,0.21,-1.24078525232107e-16,-0.08,0.22,-1.24078525232107e-16,-0.08,0.21,-1.24078525232107e-16,-0.08,0.22,-1.24078525232107e-16,-0.0772740661031255,0.21,-0.0207055236082018,-0.0772740661031255,0.22,-0.0207055236082018,-0.0772740661031255,0.21,-0.0207055236082018,-0.0772740661031255,0.22,-0.0207055236082018,-0.0692820323027551,0.21,-0.0400000000000001,-0.0692820323027551,0.22,-0.0400000000000001,-0.0692820323027551,0.21,-0.0400000000000001,-0.0692820323027551,0.22,-0.0400000000000001,-0.0565685424949238,0.21,-0.0565685424949239,-0.0565685424949238,0.22,-0.0565685424949239,-0.0565685424949238,0.21,-0.0565685424949239,-0.0565685424949238,0.22,-0.0565685424949239,-0.04,0.22,-0.0692820323027552,-0.04,0.21,-0.0692820323027552,-0.04,0.21,-0.0692820323027552,-0.04,0.22,-0.0692820323027552,-0.0207055236082017,0.22,-0.0772740661031256,-0.0207055236082017,0.21,-0.0772740661031256,-0.0207055236082017,0.21,-0.0772740661031256,-0.0207055236082017,0.22,-0.0772740661031256,-2.25597318603832e-17,0.22,-0.0800000000000001,-2.25597318603832e-17,0.21,-0.0800000000000001,-2.25597318603832e-17,0.21,-0.0800000000000001,-2.25597318603832e-17,0.22,-0.0800000000000001,0.0207055236082016,0.22,-0.0772740661031256,0.0207055236082016,0.21,-0.0772740661031256,0.0207055236082016,0.21,-0.0772740661031256,0.0207055236082016,0.22,-0.0772740661031256,0.04,0.22,-0.0692820323027552,0.04,0.21,-0.0692820323027552,0.04,0.21,-0.0692820323027552,0.04,0.22,-0.0692820323027552,0.0565685424949237,0.22,-0.0565685424949239,0.0565685424949237,0.21,-0.0565685424949239,0.0565685424949237,0.21,-0.0565685424949239,0.0565685424949237,0.22,-0.0565685424949239,-2.25597318603832e-17,0.21,-0.0800000000000001,-0.0258819045102521,0.08,-0.096592582628907,-1.12798659301916e-17,0.08,-0.1,-0.0207055236082017,0.21,-0.0772740661031256,-1.12798659301916e-17,0.08,-0.1,-0.0258819045102521,0.08,-0.096592582628907, +-2.25597318603832e-17,0.21,-0.0800000000000001,-0.0207055236082017,0.21,-0.0772740661031256,-0.04,0.21,-0.0692820323027552,-0.0707106781186548,0.08,-0.0707106781186549,-0.05,0.08,-0.086602540378444,-0.0565685424949238,0.21,-0.0565685424949239,-0.05,0.08,-0.086602540378444,-0.0707106781186548,0.08,-0.0707106781186549,-0.04,0.21,-0.0692820323027552,-0.0565685424949238,0.21,-0.0565685424949239,0.0207055236082016,0.21,-0.0772740661031256,0.0258819045102521,0.08,-0.0965925826289069,0.0258819045102521,0.08,-0.0965925826289069,0.0207055236082016,0.21,-0.0772740661031256,0.04,0.21,-0.0692820323027552,0.05,0.08,-0.086602540378444,0.05,0.08,-0.086602540378444,0.04,0.21,-0.0692820323027552,0.069282032302755,0.21,0.0399999999999999,0.0965925826289068,0.08,0.025881904510252,0.0866025403784438,0.08,0.0499999999999999,0.0772740661031254,0.21,0.0207055236082016,0.0866025403784438,0.08,0.0499999999999999,0.0965925826289068,0.08,0.025881904510252,0.069282032302755,0.21,0.0399999999999999,0.0772740661031254,0.21,0.0207055236082016,0.0565685424949237,0.21,-0.0565685424949239,0.0707106781186547,0.08,-0.0707106781186549,0.0707106781186547,0.08,-0.0707106781186549,0.0565685424949237,0.21,-0.0565685424949239,0.0866025403784439,0.08,-0.0500000000000001,0.069282032302755,0.21,-0.0400000000000001,0.069282032302755,0.21,-0.0400000000000001,0.0866025403784439,0.08,-0.0500000000000001,0.1,0.08,-1.12798659301916e-16,0.08,0.21,-1.12798659301916e-16,0.1,0.08,-1.12798659301916e-16,0.08,0.21,-1.12798659301916e-16,0.0965925826289068,0.08,-0.0258819045102522,0.0772740661031255,0.21,-0.0207055236082018,0.0772740661031255,0.21,-0.0207055236082018,0.0965925826289068,0.08,-0.0258819045102522,0.0565685424949237,0.21,0.0565685424949237,0.0707106781186547,0.08,0.0707106781186547,0.0707106781186547,0.08,0.0707106781186547,0.0565685424949237,0.21,0.0565685424949237,0.0399999999999999,0.21,0.069282032302755,0.0499999999999999,0.08,0.0866025403784438,0.0499999999999999,0.08,0.0866025403784438,0.0399999999999999,0.21,0.069282032302755,0.0207055236082016,0.21,0.0772740661031254, +0.025881904510252,0.08,0.0965925826289067,0.025881904510252,0.08,0.0965925826289067,0.0207055236082016,0.21,0.0772740661031254,-3.38395977905748e-17,0.21,0.0799999999999999,-4.51194637207664e-17,0.08,0.0999999999999999,-4.51194637207664e-17,0.08,0.0999999999999999,-3.38395977905748e-17,0.21,0.0799999999999999,-0.0207055236082017,0.21,0.0772740661031253,-0.0258819045102522,0.08,0.0965925826289067,-0.0258819045102522,0.08,0.0965925826289067,-0.0207055236082017,0.21,0.0772740661031253,-0.04,0.21,0.0692820323027549,-0.0500000000000001,0.08,0.0866025403784437,-0.0500000000000001,0.08,0.0866025403784437,-0.04,0.21,0.0692820323027549,-0.0565685424949238,0.21,0.0565685424949236,-0.0707106781186548,0.08,0.0707106781186546,-0.0707106781186548,0.08,0.0707106781186546,-0.0565685424949238,0.21,0.0565685424949236,-0.0866025403784439,0.08,0.0499999999999999,-0.0692820323027551,0.21,0.0399999999999999,-0.0866025403784439,0.08,0.0499999999999999,-0.0692820323027551,0.21,0.0399999999999999,-0.0965925826289069,0.08,0.0258819045102519,-0.0772740661031255,0.21,0.0207055236082015,-0.0965925826289069,0.08,0.0258819045102519,-0.0772740661031255,0.21,0.0207055236082015,-0.1,0.08,-1.24078525232107e-16,-0.08,0.21,-1.24078525232107e-16,-0.1,0.08,-1.24078525232107e-16,-0.08,0.21,-1.24078525232107e-16,-0.0965925826289068,0.08,-0.0258819045102522,-0.0772740661031255,0.21,-0.0207055236082018,-0.0965925826289068,0.08,-0.0258819045102522,-0.0772740661031255,0.21,-0.0207055236082018,-0.0692820323027551,0.21,-0.0400000000000001,-0.0866025403784439,0.08,-0.0500000000000002,-0.0692820323027551,0.21,-0.0400000000000001,-0.0866025403784439,0.08,-0.0500000000000002 + } + PolygonVertexIndex: *708 { + a: 0,1,-3,1,0,-4,3,0,-5,3,4,-6,5,4,-7,5,6,-8,7,6,-9,7,8,-10,9,8,-11,9,10,-12,11,10,-13,11,12,-14,13,12,-15,13,14,-16,15,14,-17,15,16,-18,17,16,-19,17,18,-20,17,19,-21,20,19,-22,20,21,-23,22,21,-24,24,25,-27,27,26,-26,28,26,-28,29,28,-28,30,28,-30,31,30,-30,32,30,-32,33,32,-32,34,32,-34,35,34,-34,36,34,-36,37,36,-36,38,36,-38,39,38,-38,40,38,-40,41,40,-40,42,40,-42,43,42,-42,44,43,-42,45,43,-45,46,45,-45,47,45,-47,48,49,-51,49,48,-52,52,53,-55,55,54,-54,50,56,-58,56,50,-50,58,59,-53,53,52,-60,57,60,-62,60,57,-57,62,63,-59,59,58,-64,61,64,-66,64,61,-61,66,67,-63,63,62,-68,65,68,-70,68,65,-65,70,71,-67,67,66,-72,72,68,-74,68,72,-70,74,71,-76,70,75,-72,76,73,-78,73,76,-73,78,74,-80,75,79,-75,80,77,-82,77,80,-77,82,78,-84,79,83,-79,84,81,-86,81,84,-81,86,82,-88,83,87,-83,88,85,-90,85,88,-85,90,86,-92,87,91,-87,92,89,-94,89,92,-89,94,90,-96,91,95,-91,96,92,-94,92,96,-98,94,95,-99,99,98,-96,100,97,-97,97,100,-102,98,99,-103,103,102,-100,104,101,-101,101,104,-106,102,103,-107,107,106,-104,108,105,-105,105,108,-110,106,107,-111,111,110,-108,112,109,-109,109,112,-114,110,111,-115,115,114,-112,116,113,-113,113,116,-118,114,115,-119,119,118,-116,120,116,-122,116,120,-118,122,118,-124,119,123,-119,124,121,-126,121,124,-121,126,122,-128,123,127,-123,128,125,-130,125,128,-125,130,126,-132,127,131,-127,132,129,-134,129,132,-129,134,130,-136,131,135,-131,136,133,-138,133,136,-133,138,134,-140,135,139,-135,140,137,-142,137,140,-137,142,138,-144,139,143,-139,140,51,-49,51,140,-142,54,55,-144,142,143,-56,144,145,-147,145,144,-148,148,149,-151,151,150,-150,152,153,-155,153,152,-156,156,157,-159,159,158,-158,160,146,-162,146,160,-145,162,148,-164,150,163,-149,147,154,-146,154,147,-153,149,156,-152,158,151,-157,164,161,-166,161,164,-161,166,162,-168,163,167,-163,168,169,-171,169,168,-172,172,173,-175,175,174,-174,176,165,-178,165,176,-165,178,166,-180,167,179,-167,176,180,-182,180,176,-178,182,183,-180,178,179,-184,171,184,-170,184,171,-186,173,186,-176,187,175,-187,181,188,-190,188,181,-181,190,191,-183,183,182,-192,189, +184,-186,184,189,-189,187,186,-191,191,190,-187,192,170,-194,170,192,-169,194,172,-196,174,195,-173,196,193,-198,193,196,-193,198,194,-200,195,199,-195,200,197,-202,197,200,-197,202,198,-204,199,203,-199,204,201,-206,201,204,-201,206,202,-208,203,207,-203,208,205,-210,205,208,-205,210,206,-212,207,211,-207,212,209,-214,209,212,-209,214,210,-216,211,215,-211,216,213,-218,213,216,-213,218,214,-220,215,219,-215,220,216,-218,216,220,-222,218,219,-223,223,222,-220,224,221,-221,221,224,-226,222,223,-227,227,226,-224,228,225,-225,225,228,-230,226,227,-231,231,230,-228,232,229,-229,229,232,-234,230,231,-235,235,234,-232,232,236,-234,236,232,-238,235,238,-235,239,234,-239,237,155,-237,155,237,-154,238,159,-240,157,239,-160 + } + GeometryVersion: 124 + LayerElementNormal: 0 { + Version: 101 + Name: "" + MappingInformationType: "ByVertice" + ReferenceInformationType: "Direct" + Normals: *720 { + a: 0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0.866025403784438,0,0.500000000000001,-0.965925826289068,0,0.258819045102521,-0.965925826289068,0,0.258819045102521,-0.866025403784438,0,0.500000000000001,0.965925826289068,-0,-0.258819045102521,0.965925826289068,-0,-0.258819045102521,0.866025403784438,-0,-0.500000000000001,0.866025403784438,-0,-0.500000000000001,-1,0,-3.07945851218452e-16,-1,0,-3.07945851218452e-16,1,-0,3.07945851218452e-16,1,-0,3.07945851218452e-16,-0.965925826289068,0,-0.258819045102522,-0.965925826289068,0,-0.258819045102522,0.965925826289068,-0,0.258819045102522,0.965925826289068,-0,0.258819045102522,-0.866025403784438,0,-0.500000000000002,-0.866025403784438,0,-0.500000000000002,0.866025403784438,-0,0.500000000000002,0.866025403784438,-0,0.500000000000002,-0.707106781186547,0,-0.707106781186548,-0.707106781186547,0,-0.707106781186548,0.707106781186547,-0,0.707106781186548,0.707106781186547,-0,0.707106781186548,-0.500000000000001,0,-0.866025403784438,-0.500000000000001,0,-0.866025403784438,0.500000000000001,-0,0.866025403784438,0.500000000000001,-0,0.866025403784438,-0.258819045102521,0,-0.965925826289068,-0.258819045102521,0,-0.965925826289068,0.258819045102521,-0,0.965925826289068,0.258819045102521,-0,0.965925826289068,3.219433899102e-16,0,-1,3.219433899102e-16,0,-1,-3.219433899102e-16,-0,1,-3.219433899102e-16,-0,1,0.258819045102522,0,-0.965925826289068,0.258819045102522,0,-0.965925826289068,-0.258819045102522,-0,0.965925826289068,-0.258819045102522,-0,0.965925826289068,0.500000000000002,0,-0.866025403784437,0.500000000000002,0,-0.866025403784437,-0.500000000000002,-0,0.866025403784437,-0.500000000000002,-0,0.866025403784437,0.707106781186548,0,-0.707106781186547,0.707106781186548,0,-0.707106781186547, +-0.707106781186548,-0,0.707106781186547,-0.707106781186548,-0,0.707106781186547,0.866025403784438,0,-0.500000000000001,0.866025403784438,0,-0.500000000000001,-0.866025403784438,-0,0.500000000000001,-0.866025403784438,-0,0.500000000000001,0.965925826289068,0,-0.258819045102521,0.965925826289068,0,-0.258819045102521,-0.965925826289068,-0,0.258819045102521,-0.965925826289068,-0,0.258819045102521,1,0,1.67970464300974e-16,1,0,1.67970464300974e-16,-1,-0,-1.67970464300974e-16,-1,-0,-1.67970464300974e-16,0.965925826289068,0,0.258819045102521,0.965925826289068,0,0.258819045102521,-0.965925826289068,-0,-0.258819045102521,-0.965925826289068,-0,-0.258819045102521,0.866025403784438,0,0.500000000000002,0.866025403784438,0,0.500000000000002,-0.866025403784438,-0,-0.500000000000002,-0.866025403784438,-0,-0.500000000000002,0.707106781186547,0,0.707106781186548,0.707106781186547,0,0.707106781186548,-0.707106781186547,-0,-0.707106781186548,-0.707106781186547,-0,-0.707106781186548,0.500000000000001,0,0.866025403784438,0.500000000000001,0,0.866025403784438,-0.500000000000001,-0,-0.866025403784438,-0.500000000000001,-0,-0.866025403784438,0.258819045102521,0,0.965925826289068,0.258819045102521,0,0.965925826289068,-0.258819045102521,-0,-0.965925826289068,-0.258819045102521,-0,-0.965925826289068,-2.23960619067965e-16,0,1,-2.23960619067965e-16,0,1,2.23960619067965e-16,-0,-1,2.23960619067965e-16,-0,-1,-0.258819045102521,0,0.965925826289068,-0.258819045102521,0,0.965925826289068,0.258819045102521,-0,-0.965925826289068,0.258819045102521,-0,-0.965925826289068,-0.500000000000001,0,0.866025403784438,-0.500000000000001,0,0.866025403784438,0.500000000000001,-0,-0.866025403784438,0.500000000000001,-0,-0.866025403784438,-0.707106781186548,0,0.707106781186548,-0.707106781186548,0,0.707106781186548,0.707106781186548,-0,-0.707106781186548,0.707106781186548,-0,-0.707106781186548,-4.05848662264163e-16,-0.152057184253941,0.988371697650617,0.25580941899229,-0.152057184253941,0.954693748733901,-4.05848662264163e-16,-0.152057184253941,0.988371697650617,0.25580941899229,-0.152057184253941,0.954693748733901, +4.05848662264163e-16,0.152057184253941,-0.988371697650617,-0.25580941899229,0.152057184253941,-0.954693748733901,4.05848662264163e-16,0.152057184253941,-0.988371697650617,-0.25580941899229,0.152057184253941,-0.954693748733901,0.494185848825309,-0.152057184253941,0.855954998546987,0.698884329741611,-0.152057184253941,0.698884329741612,0.494185848825309,-0.152057184253941,0.855954998546987,0.698884329741611,-0.152057184253941,0.698884329741612,-0.494185848825309,0.152057184253941,-0.855954998546987,-0.698884329741611,0.152057184253941,-0.698884329741612,-0.494185848825309,0.152057184253941,-0.855954998546987,-0.698884329741611,0.152057184253941,-0.698884329741612,-0.255809418992291,-0.152057184253941,0.954693748733901,-0.255809418992291,-0.152057184253941,0.954693748733901,0.255809418992291,0.152057184253941,-0.954693748733901,0.255809418992291,0.152057184253941,-0.954693748733901,-0.494185848825309,-0.152057184253941,0.855954998546987,-0.494185848825309,-0.152057184253941,0.855954998546987,0.494185848825309,0.152057184253941,-0.855954998546987,0.494185848825309,0.152057184253941,-0.855954998546987,-0.855954998546986,-0.152057184253941,-0.494185848825309,-0.954693748733901,-0.152057184253941,-0.255809418992291,-0.855954998546986,-0.152057184253941,-0.494185848825309,-0.954693748733901,-0.152057184253941,-0.255809418992291,0.855954998546986,0.152057184253941,0.494185848825309,0.954693748733901,0.152057184253941,0.255809418992291,0.855954998546986,0.152057184253941,0.494185848825309,0.954693748733901,0.152057184253941,0.255809418992291,-0.698884329741611,-0.152057184253941,0.698884329741612,-0.698884329741611,-0.152057184253941,0.698884329741612,0.698884329741611,0.152057184253941,-0.698884329741612,0.698884329741611,0.152057184253941,-0.698884329741612,-0.855954998546986,-0.152057184253941,0.494185848825309,-0.855954998546986,-0.152057184253941,0.494185848825309,0.855954998546986,0.152057184253941,-0.494185848825309,0.855954998546986,0.152057184253941,-0.494185848825309,-0.988371697650617,-0.152057184253941,-5.31801695380628e-16, +-0.988371697650617,-0.152057184253941,-5.31801695380628e-16,0.988371697650617,0.152057184253941,5.31801695380628e-16,0.988371697650617,0.152057184253941,5.31801695380628e-16,-0.954693748733902,-0.152057184253941,0.25580941899229,-0.954693748733902,-0.152057184253941,0.25580941899229,0.954693748733902,0.152057184253941,-0.25580941899229,0.954693748733902,0.152057184253941,-0.25580941899229,-0.698884329741611,-0.152057184253941,-0.698884329741612,-0.698884329741611,-0.152057184253941,-0.698884329741612,0.698884329741611,0.152057184253941,0.698884329741612,0.698884329741611,0.152057184253941,0.698884329741612,-0.494185848825308,-0.152057184253941,-0.855954998546987,-0.494185848825308,-0.152057184253941,-0.855954998546987,0.494185848825308,0.152057184253941,0.855954998546987,0.494185848825308,0.152057184253941,0.855954998546987,-0.25580941899229,-0.152057184253941,-0.954693748733902,-0.25580941899229,-0.152057184253941,-0.954693748733902,0.25580941899229,0.152057184253941,0.954693748733902,0.25580941899229,0.152057184253941,0.954693748733902,4.19843443721548e-16,-0.152057184253941,-0.988371697650617,4.19843443721548e-16,-0.152057184253941,-0.988371697650617,-4.19843443721548e-16,0.152057184253941,0.988371697650617,-4.19843443721548e-16,0.152057184253941,0.988371697650617,0.255809418992291,-0.152057184253941,-0.954693748733901,0.255809418992291,-0.152057184253941,-0.954693748733901,-0.255809418992291,0.152057184253941,0.954693748733901,-0.255809418992291,0.152057184253941,0.954693748733901,0.49418584882531,-0.152057184253941,-0.855954998546986,0.49418584882531,-0.152057184253941,-0.855954998546986,-0.49418584882531,0.152057184253941,0.855954998546986,-0.49418584882531,0.152057184253941,0.855954998546986,0.698884329741612,-0.152057184253942,-0.698884329741611,0.698884329741612,-0.152057184253942,-0.698884329741611,-0.698884329741612,0.152057184253942,0.698884329741611,-0.698884329741612,0.152057184253942,0.698884329741611,0.855954998546987,-0.152057184253941,-0.494185848825309,0.855954998546987,-0.152057184253941,-0.494185848825309, +-0.855954998546987,0.152057184253941,0.494185848825309,-0.855954998546987,0.152057184253941,0.494185848825309,0.954693748733902,-0.152057184253941,-0.25580941899229,0.954693748733902,-0.152057184253941,-0.25580941899229,-0.954693748733902,0.152057184253941,0.25580941899229,-0.954693748733902,0.152057184253941,0.25580941899229,0.988371697650617,-0.152057184253941,2.51906066232929e-16,0.988371697650617,-0.152057184253941,2.51906066232929e-16,-0.988371697650617,0.152057184253941,-2.51906066232929e-16,-0.988371697650617,0.152057184253941,-2.51906066232929e-16,0.954693748733902,-0.152057184253941,0.25580941899229,0.954693748733902,-0.152057184253941,0.25580941899229,-0.954693748733902,0.152057184253941,-0.25580941899229,-0.954693748733902,0.152057184253941,-0.25580941899229,0.855954998546986,-0.152057184253941,0.494185848825309,0.855954998546986,-0.152057184253941,0.494185848825309,-0.855954998546986,0.152057184253941,-0.494185848825309,-0.855954998546986,0.152057184253941,-0.494185848825309 + } + } + LayerElementUV: 0 { + Version: 101 + Name: "" + MappingInformationType: "ByPolygonVertex" + ReferenceInformationType: "IndexToDirect" + UV: *128 { + a: 0.253523838921015,0.0679315079009241,0.253523838921015,-0.0679315079009239,0.26246719160105,3.70074341541719e-17,0.227303255586467,-0.131233595800525,0.227303255586467,0.131233595800525,0.185592331020091,-0.185592331020091,0.185592331020091,0.185592331020091,0.131233595800525,-0.227303255586467,0.131233595800525,0.227303255586467,0.0679315079009242,-0.253523838921015,0.067931507900924,0.253523838921015,3.70074341541719e-17,-0.26246719160105,0,0.26246719160105,-0.0679315079009239,-0.253523838921015,-0.0679315079009241,0.253523838921015,-0.131233595800525,-0.227303255586467,-0.131233595800525,0.227303255586467,-0.185592331020091,-0.185592331020091,-0.185592331020091,0.185592331020091,-0.227303255586467,0.131233595800525,-0.227303255586467,-0.131233595800525,-0.253523838921015,0.067931507900924,-0.253523838921015,-0.0679315079009243,-0.26246719160105,0,3.1496062992126,4.88498130835069e-15,3.04228606705218,-0.815178094811083,3.04228606705218,0.815178094811094,2.7276390670376,-1.57480314960629,2.7276390670376,1.5748031496063,2.2271079722411,-2.22710797224109,2.22710797224109,2.2271079722411,1.5748031496063,-2.7276390670376,1.5748031496063,2.7276390670376,0.815178094811092,-3.04228606705218,0.815178094811089,3.04228606705219,1.33226762955019e-15,-3.14960629921259,8.88178419700125e-16,3.1496062992126,-0.815178094811086,-3.04228606705218,-0.815178094811088,3.04228606705219,-1.5748031496063,-2.7276390670376,-1.5748031496063,2.7276390670376,-2.22710797224109,-2.22710797224109,-2.22710797224109,2.2271079722411,-2.7276390670376,1.5748031496063,-2.7276390670376,-1.5748031496063,-3.04228606705218,0.815178094811093,-3.04228606705218,-0.815178094811087,-3.1496062992126,4.44089209850063e-15,-0.034258843102375,0.721784776902887,0.0342588431023765,0.688976377952756,0.0342588431023765,0.721784776902887,-0.034258843102375,0.688976377952756,0.411106117228513,8.66141732283464,0.411106117228513,8.26771653543307,-0.411106117228505,8.66141732283464,-0.411106117228505,8.26771653543307,0.0342588431023756,0.641861114482852, +-0.0428235538779698,0.210419002562367,0.0428235538779696,0.210419002562367,-0.0342588431023758,0.641861114482852,0.513882646535634,2.5250280307484,-0.513882646535638,2.5250280307484,0.411106117228506,7.70233337379422,-0.411106117228511,7.70233337379422 + } + UVIndex: *708 { + a: 0,1,2,1,0,3,3,0,4,3,4,5,5,4,6,5,6,7,7,6,8,7,8,9,9,8,10,9,10,11,11,10,12,11,12,13,13,12,14,13,14,15,15,14,16,15,16,17,17,16,18,17,18,19,17,19,20,20,19,21,20,21,22,22,21,23,24,25,26,27,26,25,28,26,27,29,28,27,30,28,29,31,30,29,32,30,31,33,32,31,34,32,33,35,34,33,36,34,35,37,36,35,38,36,37,39,38,37,40,38,39,41,40,39,42,40,41,43,42,41,44,43,41,45,43,44,46,45,44,47,45,46,48,49,50,49,48,51,52,53,54,55,54,53,48,49,50,49,48,51,52,53,54,55,54,53,48,49,50,49,48,51,52,53,54,55,54,53,48,49,50,49,48,51,52,53,54,55,54,53,48,49,50,49,48,51,52,53,54,55,54,53,50,51,49,51,50,48,53,55,52,54,52,55,50,51,49,51,50,48,53,55,52,54,52,55,50,51,49,51,50,48,53,55,52,54,52,55,50,51,49,51,50,48,53,55,52,54,52,55,50,51,49,51,50,48,53,55,52,54,52,55,50,51,49,51,50,48,53,55,52,54,52,55,49,48,51,48,49,50,55,54,53,52,53,54,49,48,51,48,49,50,55,54,53,52,53,54,49,48,51,48,49,50,55,54,53,52,53,54,49,48,51,48,49,50,55,54,53,52,53,54,49,48,51,48,49,50,55,54,53,52,53,54,49,48,51,48,49,50,55,54,53,52,53,54,50,51,49,51,50,48,53,55,52,54,52,55,50,51,49,51,50,48,53,55,52,54,52,55,50,51,49,51,50,48,53,55,52,54,52,55,50,51,49,51,50,48,53,55,52,54,52,55,50,51,49,51,50,48,53,55,52,54,52,55,50,51,49,51,50,48,53,55,52,54,52,55,48,49,50,49,48,51,52,53,54,55,54,53,56,57,58,57,56,59,60,61,62,63,62,61,56,57,58,57,56,59,60,61,62,63,62,61,56,57,58,57,56,59,60,61,62,63,62,61,56,57,58,57,56,59,60,61,62,63,62,61,56,57,58,57,56,59,60,61,62,63,62,61,56,57,58,57,56,59,60,61,62,63,62,61,56,57,58,57,56,59,60,61,62,63,62,61,59,58,56,58,59,57,62,60,63,61,63,60,56,57,58,57,56,59,60,61,62,63,62,61,59,58,56,58,59,57,62,60,63,61,63,60,59,58,56,58,59,57,62,60,63,61,63,60,56,57,58,57,56,59,60,61,62,63,62,61,56,57,58,57,56,59,60,61,62,63,62,61,56,57,58,57,56,59,60,61,62,63,62,61,56,57,58,57,56,59,60,61,62,63,62,61,56,57,58,57,56,59,60,61,62,63,62,61,56,57,58,57,56,59,60,61,62,63,62,61,56,57,58,57,56,59,60,61,62,63,62,61,58,59,57,59,58,56,61,63,60,62,60,63,58,59,57,59,58,56,61,63,60,62,60,63,58,59,57,59,58,56,61,63,60,62,60,63,58,59,57,59,58,56,61,63,60,62,60,63,57, +56,59,56,57,58,63,62,61,60,61,62,57,56,59,56,57,58,63,62,61,60,61,62 + } + } + LayerElementMaterial: 0 { + Version: 101 + Name: "" + MappingInformationType: "ByPolygon" + ReferenceInformationType: "IndexToDirect" + Materials: *236 { + a: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1 + } + } + Layer: 0 { + Version: 100 + LayerElement: { + Type: "LayerElementNormal" + TypedIndex: 0 + } + LayerElement: { + Type: "LayerElementMaterial" + TypedIndex: 0 + } + LayerElement: { + Type: "LayerElementTexture" + TypedIndex: 0 + } + LayerElement: { + Type: "LayerElementUV" + TypedIndex: 0 + } + } + } + Model: 140593540063744, "Model::Model", "Null" { + Version: 232 + Properties70: { + P: "ScalingMax", "Vector3D", "Vector", "",0,0,0 + } + Shading: Y + Culling: "CullingOff" + } + Model: 140593542953472, "Model::Mesh1", "Mesh" { + Version: 232 + Properties70: { + P: "ScalingMax", "Vector3D", "Vector", "",0,0,0 + P: "DefaultAttributeIndex", "int", "Integer", "",0 + } + Shading: T + Culling: "CullingOff" + } + Material: 140593628137824, "Material::Metal_Silver", "" { + Version: 102 + ShadingModel: "phong" + MultiLayer: 0 + Properties70: { + P: "AmbientColor", "Color", "", "A",0,0,0 + P: "DiffuseColor", "Color", "", "A",0.913725490196078,0.909803921568627,0.929411764705882 + P: "TransparentColor", "Color", "", "A",1,1,1 + P: "SpecularColor", "Color", "", "A",0.33,0.33,0.33 + P: "ReflectionFactor", "Number", "", "A",0 + P: "Emissive", "Vector3D", "Vector", "",0,0,0 + P: "Ambient", "Vector3D", "Vector", "",0,0,0 + P: "Diffuse", "Vector3D", "Vector", "",0.913725490196078,0.909803921568627,0.929411764705882 + P: "Specular", "Vector3D", "Vector", "",0.33,0.33,0.33 + P: "Shininess", "double", "Number", "",20 + P: "Opacity", "double", "Number", "",1 + P: "Reflectivity", "double", "Number", "",0 + } + } + Material: 140593628149632, "Material::_12", "" { + Version: 102 + ShadingModel: "phong" + MultiLayer: 0 + Properties70: { + P: "AmbientColor", "Color", "", "A",0,0,0 + P: "DiffuseColor", "Color", "", "A",0.956862745098039,0,0 + P: "TransparentColor", "Color", "", "A",1,1,1 + P: "TransparencyFactor", "Number", "", "A",0.531673955362897 + P: "SpecularColor", "Color", "", "A",0.33,0.33,0.33 + P: "ReflectionFactor", "Number", "", "A",0 + P: "Emissive", "Vector3D", "Vector", "",0,0,0 + P: "Ambient", "Vector3D", "Vector", "",0,0,0 + P: "Diffuse", "Vector3D", "Vector", "",0.956862745098039,0,0 + P: "Specular", "Vector3D", "Vector", "",0.33,0.33,0.33 + P: "Shininess", "double", "Number", "",20 + P: "Opacity", "double", "Number", "",0.468326044637103 + P: "Reflectivity", "double", "Number", "",0 + } + } + Video: 140593624680720, "Video::Metal_Silver_texture", "Clip" { + Type: "Clip" + Properties70: { + P: "Path", "KString", "XRefUrl", "", "colored dome/Metal_Silver.jpg" + } + UseMipMap: 0 + Filename: "colored dome/Metal_Silver.jpg" + RelativeFilename: "../../../../../Metal_Silver.jpg" + } + Texture: 140593628143712, "Texture::Metal_Silver_texture", "" { + Type: "TextureVideoClip" + Version: 202 + TextureName: "Texture::Metal_Silver_texture" + Media: "Video::Metal_Silver_texture" + FileName: "colored dome/Metal_Silver.jpg" + RelativeFilename: "../../../../../Metal_Silver.jpg" + ModelUVTranslation: 0,0 + ModelUVScaling: 1,1 + Texture_Alpha_Source: "None" + Cropping: 0,0,0,0 + } +} + +; Object connections +;------------------------------------------------------------------ + +Connections: { + + ;Model::Model, Model::RootNode + C: "OO",140593540063744,0 + + ;Model::Mesh1, Model::Model + C: "OO",140593542953472,140593540063744 + + ;Geometry::, Model::Mesh1 + C: "OO",140593626116512,140593542953472 + + ;Material::Metal_Silver, Model::Mesh1 + C: "OO",140593628137824,140593542953472 + + ;Material::_12, Model::Mesh1 + C: "OO",140593628149632,140593542953472 + + ;Texture::Metal_Silver_texture, Model::Mesh1 + C: "OO",140593628143712,140593542953472 + + ;Video::Metal_Silver_texture, Texture::Metal_Silver_texture + C: "OO",140593624680720,140593628143712 + + ;Texture::Metal_Silver_texture, Material::Metal_Silver + C: "OP",140593628143712,140593628137824, "DiffuseColor" +} +;Takes section +;---------------------------------------------------- + +Takes: { + Current: "" +} diff --git a/src/parts source/kOS Cherry Light/cherrytop meshes/light_base.fbx b/src/parts source/kOS Cherry Light/cherrytop meshes/light_base.fbx new file mode 100644 index 000000000..9e3326e30 --- /dev/null +++ b/src/parts source/kOS Cherry Light/cherrytop meshes/light_base.fbx @@ -0,0 +1,365 @@ +; FBX 7.3.0 project file +; Copyright (C) 1997-2010 Autodesk Inc. and/or its licensors. +; All rights reserved. +; ---------------------------------------------------- + +FBXHeaderExtension: { + FBXHeaderVersion: 1003 + FBXVersion: 7300 + CreationTimeStamp: { + Version: 1000 + Year: 2016 + Month: 1 + Day: 27 + Hour: 9 + Minute: 58 + Second: 54 + Millisecond: 0 + } + Creator: "FBX SDK/FBX Plugins version 2013.3" + SceneInfo: "SceneInfo::GlobalInfo", "UserData" { + Type: "UserData" + Version: 100 + MetaData: { + Version: 100 + Title: "" + Subject: "" + Author: "" + Keywords: "" + Revision: "" + Comment: "" + } + Properties70: { + P: "DocumentUrl", "KString", "Url", "", "/var/folders/16/csq8fhn9279gfgk7gc955t500000gn/T/com.sketchup.SketchUp.2016.petergoddardrOV7I6.fbx" + P: "SrcDocumentUrl", "KString", "Url", "", "/var/folders/16/csq8fhn9279gfgk7gc955t500000gn/T/com.sketchup.SketchUp.2016.petergoddardrOV7I6.fbx" + P: "Original", "Compound", "", "" + P: "Original|ApplicationVendor", "KString", "", "", "" + P: "Original|ApplicationName", "KString", "", "", "" + P: "Original|ApplicationVersion", "KString", "", "", "" + P: "Original|DateTime_GMT", "DateTime", "", "", "" + P: "Original|FileName", "KString", "", "", "" + P: "LastSaved", "Compound", "", "" + P: "LastSaved|ApplicationVendor", "KString", "", "", "" + P: "LastSaved|ApplicationName", "KString", "", "", "" + P: "LastSaved|ApplicationVersion", "KString", "", "", "" + P: "LastSaved|DateTime_GMT", "DateTime", "", "", "" + } + } +} +GlobalSettings: { + Version: 1000 + Properties70: { + P: "UpAxis", "int", "Integer", "",1 + P: "UpAxisSign", "int", "Integer", "",1 + P: "FrontAxis", "int", "Integer", "",2 + P: "FrontAxisSign", "int", "Integer", "",1 + P: "CoordAxis", "int", "Integer", "",0 + P: "CoordAxisSign", "int", "Integer", "",1 + P: "OriginalUpAxis", "int", "Integer", "",-1 + P: "OriginalUpAxisSign", "int", "Integer", "",1 + P: "UnitScaleFactor", "double", "Number", "",1 + P: "OriginalUnitScaleFactor", "double", "Number", "",1 + P: "AmbientColor", "ColorRGB", "Color", "",0,0,0 + P: "DefaultCamera", "KString", "", "", "Producer Perspective" + P: "TimeMode", "enum", "", "",0 + P: "TimeSpanStart", "KTime", "Time", "",0 + P: "TimeSpanStop", "KTime", "Time", "",46186158000 + P: "CustomFrameRate", "double", "Number", "",-1 + } +} + +; Documents Description +;------------------------------------------------------------------ + +Documents: { + Count: 1 + Document: 140593611507744, "", "Scene" { + Properties70: { + P: "SourceObject", "object", "", "" + P: "ActiveAnimStackName", "KString", "", "", "" + } + RootNode: 0 + } +} + +; Document References +;------------------------------------------------------------------ + +References: { +} + +; Object definitions +;------------------------------------------------------------------ + +Definitions: { + Version: 100 + Count: 5 + ObjectType: "GlobalSettings" { + Count: 1 + } + ObjectType: "Model" { + Count: 2 + PropertyTemplate: "FbxNode" { + Properties70: { + P: "QuaternionInterpolate", "enum", "", "",0 + P: "RotationOffset", "Vector3D", "Vector", "",0,0,0 + P: "RotationPivot", "Vector3D", "Vector", "",0,0,0 + P: "ScalingOffset", "Vector3D", "Vector", "",0,0,0 + P: "ScalingPivot", "Vector3D", "Vector", "",0,0,0 + P: "TranslationActive", "bool", "", "",0 + P: "TranslationMin", "Vector3D", "Vector", "",0,0,0 + P: "TranslationMax", "Vector3D", "Vector", "",0,0,0 + P: "TranslationMinX", "bool", "", "",0 + P: "TranslationMinY", "bool", "", "",0 + P: "TranslationMinZ", "bool", "", "",0 + P: "TranslationMaxX", "bool", "", "",0 + P: "TranslationMaxY", "bool", "", "",0 + P: "TranslationMaxZ", "bool", "", "",0 + P: "RotationOrder", "enum", "", "",0 + P: "RotationSpaceForLimitOnly", "bool", "", "",0 + P: "RotationStiffnessX", "double", "Number", "",0 + P: "RotationStiffnessY", "double", "Number", "",0 + P: "RotationStiffnessZ", "double", "Number", "",0 + P: "AxisLen", "double", "Number", "",10 + P: "PreRotation", "Vector3D", "Vector", "",0,0,0 + P: "PostRotation", "Vector3D", "Vector", "",0,0,0 + P: "RotationActive", "bool", "", "",0 + P: "RotationMin", "Vector3D", "Vector", "",0,0,0 + P: "RotationMax", "Vector3D", "Vector", "",0,0,0 + P: "RotationMinX", "bool", "", "",0 + P: "RotationMinY", "bool", "", "",0 + P: "RotationMinZ", "bool", "", "",0 + P: "RotationMaxX", "bool", "", "",0 + P: "RotationMaxY", "bool", "", "",0 + P: "RotationMaxZ", "bool", "", "",0 + P: "InheritType", "enum", "", "",0 + P: "ScalingActive", "bool", "", "",0 + P: "ScalingMin", "Vector3D", "Vector", "",0,0,0 + P: "ScalingMax", "Vector3D", "Vector", "",1,1,1 + P: "ScalingMinX", "bool", "", "",0 + P: "ScalingMinY", "bool", "", "",0 + P: "ScalingMinZ", "bool", "", "",0 + P: "ScalingMaxX", "bool", "", "",0 + P: "ScalingMaxY", "bool", "", "",0 + P: "ScalingMaxZ", "bool", "", "",0 + P: "GeometricTranslation", "Vector3D", "Vector", "",0,0,0 + P: "GeometricRotation", "Vector3D", "Vector", "",0,0,0 + P: "GeometricScaling", "Vector3D", "Vector", "",1,1,1 + P: "MinDampRangeX", "double", "Number", "",0 + P: "MinDampRangeY", "double", "Number", "",0 + P: "MinDampRangeZ", "double", "Number", "",0 + P: "MaxDampRangeX", "double", "Number", "",0 + P: "MaxDampRangeY", "double", "Number", "",0 + P: "MaxDampRangeZ", "double", "Number", "",0 + P: "MinDampStrengthX", "double", "Number", "",0 + P: "MinDampStrengthY", "double", "Number", "",0 + P: "MinDampStrengthZ", "double", "Number", "",0 + P: "MaxDampStrengthX", "double", "Number", "",0 + P: "MaxDampStrengthY", "double", "Number", "",0 + P: "MaxDampStrengthZ", "double", "Number", "",0 + P: "PreferedAngleX", "double", "Number", "",0 + P: "PreferedAngleY", "double", "Number", "",0 + P: "PreferedAngleZ", "double", "Number", "",0 + P: "LookAtProperty", "object", "", "" + P: "UpVectorProperty", "object", "", "" + P: "Show", "bool", "", "",1 + P: "NegativePercentShapeSupport", "bool", "", "",1 + P: "DefaultAttributeIndex", "int", "Integer", "",-1 + P: "Freeze", "bool", "", "",0 + P: "LODBox", "bool", "", "",0 + P: "Lcl Translation", "Lcl Translation", "", "A",0,0,0 + P: "Lcl Rotation", "Lcl Rotation", "", "A",0,0,0 + P: "Lcl Scaling", "Lcl Scaling", "", "A",1,1,1 + P: "Visibility", "Visibility", "", "A",1 + P: "Visibility Inheritance", "Visibility Inheritance", "", "",1 + } + } + } + ObjectType: "Geometry" { + Count: 1 + PropertyTemplate: "FbxMesh" { + Properties70: { + P: "Color", "ColorRGB", "Color", "",0.8,0.8,0.8 + P: "BBoxMin", "Vector3D", "Vector", "",0,0,0 + P: "BBoxMax", "Vector3D", "Vector", "",0,0,0 + P: "Primary Visibility", "bool", "", "",1 + P: "Casts Shadows", "bool", "", "",1 + P: "Receive Shadows", "bool", "", "",1 + } + } + } + ObjectType: "Material" { + Count: 1 + PropertyTemplate: "FbxSurfacePhong" { + Properties70: { + P: "ShadingModel", "KString", "", "", "Phong" + P: "MultiLayer", "bool", "", "",0 + P: "EmissiveColor", "Color", "", "A",0,0,0 + P: "EmissiveFactor", "Number", "", "A",1 + P: "AmbientColor", "Color", "", "A",0.2,0.2,0.2 + P: "AmbientFactor", "Number", "", "A",1 + P: "DiffuseColor", "Color", "", "A",0.8,0.8,0.8 + P: "DiffuseFactor", "Number", "", "A",1 + P: "Bump", "Vector3D", "Vector", "",0,0,0 + P: "NormalMap", "Vector3D", "Vector", "",0,0,0 + P: "BumpFactor", "double", "Number", "",1 + P: "TransparentColor", "Color", "", "A",0,0,0 + P: "TransparencyFactor", "Number", "", "A",0 + P: "DisplacementColor", "ColorRGB", "Color", "",0,0,0 + P: "DisplacementFactor", "double", "Number", "",1 + P: "VectorDisplacementColor", "ColorRGB", "Color", "",0,0,0 + P: "VectorDisplacementFactor", "double", "Number", "",1 + P: "SpecularColor", "Color", "", "A",0.2,0.2,0.2 + P: "SpecularFactor", "Number", "", "A",1 + P: "ShininessExponent", "Number", "", "A",20 + P: "ReflectionColor", "Color", "", "A",0,0,0 + P: "ReflectionFactor", "Number", "", "A",1 + } + } + } +} + +; Object properties +;------------------------------------------------------------------ + +Objects: { + Geometry: 140593628365424, "Geometry::", "Mesh" { + Vertices: *1584 { + a: -0.0965925826289068,0,-0.0258819045102521,-0.0965925826289068,0,0.025881904510252,-0.1,0,-2.25597318603832e-17,-0.0866025403784439,0,0.05,-0.0866025403784439,0,-0.05,-0.0707106781186548,0,0.0707106781186547,-0.0707106781186548,0,-0.0707106781186548,-0.05,0,0.0866025403784438,-0.05,0,-0.0866025403784439,-0.0258819045102521,0,0.0965925826289068,-0.0258819045102521,0,-0.0965925826289068,-2.25597318603832e-17,0,0.1,0,0,-0.1,0.025881904510252,0,0.0965925826289068,0.0258819045102521,0,-0.0965925826289068,0.0499999999999999,0,0.0866025403784439,0.05,0,-0.0866025403784439,0.0707106781186548,0,0.0707106781186548,0.0707106781186548,0,-0.0707106781186548,0.0866025403784438,0,0.05,0.0866025403784439,0,-0.05,0.0965925826289068,0,0.0258819045102522,0.0965925826289068,0,-0.0258819045102521,0.1,0,-0,-0.1,0,-2.25597318603832e-17,-0.0965925826289068,0,0.025881904510252,-0.0965925826289068,0,-0.0258819045102521,-0.0866025403784439,0,0.05,-0.0866025403784439,0,-0.05,-0.0707106781186548,0,0.0707106781186547,-0.0707106781186548,0,-0.0707106781186548,-0.05,0,0.0866025403784438,-0.05,0,-0.0866025403784439,-0.0258819045102521,0,0.0965925826289068,-0.0258819045102521,0,-0.0965925826289068,-2.25597318603832e-17,0,0.1,0,0,-0.1,0.025881904510252,0,0.0965925826289068,0.0258819045102521,0,-0.0965925826289068,0.0499999999999999,0,0.0866025403784439,0.05,0,-0.0866025403784439,0.0707106781186548,0,0.0707106781186548,0.0707106781186548,0,-0.0707106781186548,0.0866025403784438,0,0.05,0.0866025403784439,0,-0.05,0.0965925826289068,0,0.0258819045102522,0.0965925826289068,0,-0.0258819045102521,0.1,0,-0,-0.0707106781186548,0.07,-0.0707106781186548,-0.05,0,-0.0866025403784439,-0.0707106781186548,0,-0.0707106781186548,-0.05,0.07,-0.0866025403784439,-0.0707106781186548,0,-0.0707106781186548,-0.05,0,-0.0866025403784439,-0.0707106781186548,0.07,-0.0707106781186548,-0.05,0.07,-0.0866025403784439,-0.0258819045102521,0,-0.0965925826289068,-0.0258819045102521,0.07,-0.0965925826289068,-0.0258819045102521,0,-0.0965925826289068,-0.0258819045102521,0.07,-0.0965925826289068, +0,0,-0.1,0,0.07,-0.1,0,0,-0.1,0,0.07,-0.1,0.0258819045102521,0,-0.0965925826289068,0.0258819045102521,0.07,-0.0965925826289068,0.0258819045102521,0,-0.0965925826289068,0.0258819045102521,0.07,-0.0965925826289068,0.05,0,-0.0866025403784439,0.05,0.07,-0.0866025403784439,0.05,0,-0.0866025403784439,0.05,0.07,-0.0866025403784439,0.0707106781186548,0,-0.0707106781186548,0.0707106781186548,0.07,-0.0707106781186548,0.0707106781186548,0,-0.0707106781186548,0.0707106781186548,0.07,-0.0707106781186548,0.0866025403784439,0.07,-0.05,0.0866025403784439,0,-0.05,0.0866025403784439,0,-0.05,0.0866025403784439,0.07,-0.05,0.0965925826289068,0.07,-0.0258819045102521,0.0965925826289068,0,-0.0258819045102521,0.0965925826289068,0,-0.0258819045102521,0.0965925826289068,0.07,-0.0258819045102521,0.1,0.07,-0,0.1,0,-0,0.1,0,-0,0.1,0.07,-0,0.0965925826289068,0.07,0.0258819045102522,0.0965925826289068,0,0.0258819045102522,0.0965925826289068,0,0.0258819045102522,0.0965925826289068,0.07,0.0258819045102522,0.0866025403784438,0.07,0.05,0.0866025403784438,0,0.05,0.0866025403784438,0,0.05,0.0866025403784438,0.07,0.05,0.0707106781186548,0.07,0.0707106781186548,0.0707106781186548,0,0.0707106781186548,0.0707106781186548,0,0.0707106781186548,0.0707106781186548,0.07,0.0707106781186548,0.0499999999999999,0,0.0866025403784439,0.0499999999999999,0.07,0.0866025403784439,0.0499999999999999,0,0.0866025403784439,0.0499999999999999,0.07,0.0866025403784439,0.025881904510252,0,0.0965925826289068,0.025881904510252,0.07,0.0965925826289068,0.025881904510252,0,0.0965925826289068,0.025881904510252,0.07,0.0965925826289068,-2.25597318603832e-17,0,0.1,-2.25597318603832e-17,0.07,0.1,-2.25597318603832e-17,0,0.1,-2.25597318603832e-17,0.07,0.1,-0.0258819045102521,0,0.0965925826289068,-0.0258819045102521,0.07,0.0965925826289068,-0.0258819045102521,0,0.0965925826289068,-0.0258819045102521,0.07,0.0965925826289068,-0.05,0,0.0866025403784438,-0.05,0.07,0.0866025403784438,-0.05,0,0.0866025403784438,-0.05,0.07,0.0866025403784438,-0.0707106781186548,0,0.0707106781186547,-0.0707106781186548,0.07,0.0707106781186547, +-0.0707106781186548,0,0.0707106781186547,-0.0707106781186548,0.07,0.0707106781186547,-0.0866025403784439,0.07,0.05,-0.0866025403784439,0,0.05,-0.0866025403784439,0.07,0.05,-0.0866025403784439,0,0.05,-0.0965925826289068,0.07,0.025881904510252,-0.0965925826289068,0,0.025881904510252,-0.0965925826289068,0.07,0.025881904510252,-0.0965925826289068,0,0.025881904510252,-0.1,0.07,-2.25597318603832e-17,-0.1,0,-2.25597318603832e-17,-0.1,0.07,-2.25597318603832e-17,-0.1,0,-2.25597318603832e-17,-0.0965925826289068,0.07,-0.0258819045102521,-0.0965925826289068,0,-0.0258819045102521,-0.0965925826289068,0.07,-0.0258819045102521,-0.0965925826289068,0,-0.0258819045102521,-0.0866025403784439,0.07,-0.05,-0.0866025403784439,0,-0.05,-0.0866025403784439,0.07,-0.05,-0.0866025403784439,0,-0.05,-0.106251840891798,0.07,-0.0284700949612772,-0.106251840891797,0.07,0.0284700949612773,-0.11,0.07,2.25597318603832e-17,-0.0952627944162883,0.07,-0.055,-0.1,0.07,-2.25597318603832e-17,-0.0965925826289068,0.07,-0.0258819045102521,-0.0866025403784439,0.07,-0.05,-0.0777817459305203,0.07,-0.0777817459305202,-0.0707106781186548,0.07,-0.0707106781186548,-0.055,0.07,-0.0952627944162882,-0.05,0.07,-0.0866025403784439,-0.0284700949612774,0.07,-0.106251840891798,-0.0258819045102521,0.07,-0.0965925826289068,-2.25597318603832e-17,0.07,-0.11,0,0.07,-0.1,0.0284700949612772,0.07,-0.106251840891798,0.0258819045102521,0.07,-0.0965925826289068,0.05,0.07,-0.0866025403784439,0.0549999999999999,0.07,-0.0952627944162883,0.0707106781186548,0.07,-0.0707106781186548,0.0777817459305202,0.07,-0.0777817459305202,0.0866025403784439,0.07,-0.05,0.0952627944162882,0.07,-0.0550000000000001,0.0965925826289068,0.07,-0.0258819045102521,0.106251840891798,0.07,-0.0284700949612774,0.1,0.07,-0,-0.0952627944162882,0.07,0.055,-0.0965925826289068,0.07,0.025881904510252,-0.0866025403784439,0.07,0.05,-0.0777817459305202,0.07,0.0777817459305202,-0.0707106781186548,0.07,0.0707106781186547,-0.055,0.07,0.0952627944162883,-0.05,0.07,0.0866025403784438,-0.0284700949612773,0.07,0.106251840891798,-0.0258819045102521,0.07,0.0965925826289068, +0,0.07,0.11,-2.25597318603832e-17,0.07,0.1,0.025881904510252,0.07,0.0965925826289068,0.0284700949612773,0.07,0.106251840891797,0.0499999999999999,0.07,0.0866025403784439,0.055,0.07,0.0952627944162883,0.0707106781186548,0.07,0.0707106781186548,0.0777817459305202,0.07,0.0777817459305202,0.0866025403784438,0.07,0.05,0.0952627944162883,0.07,0.055,0.0965925826289068,0.07,0.0258819045102522,0.106251840891798,0.07,0.0284700949612773,0.11,0.07,-0,-0.11,0.07,2.25597318603832e-17,-0.106251840891797,0.07,0.0284700949612773,-0.106251840891798,0.07,-0.0284700949612772,-0.0952627944162883,0.07,-0.055,-0.1,0.07,-2.25597318603832e-17,-0.0965925826289068,0.07,-0.0258819045102521,-0.0866025403784439,0.07,-0.05,-0.0777817459305203,0.07,-0.0777817459305202,-0.0707106781186548,0.07,-0.0707106781186548,-0.055,0.07,-0.0952627944162882,-0.05,0.07,-0.0866025403784439,-0.0284700949612774,0.07,-0.106251840891798,-0.0258819045102521,0.07,-0.0965925826289068,-2.25597318603832e-17,0.07,-0.11,0,0.07,-0.1,0.0284700949612772,0.07,-0.106251840891798,0.0258819045102521,0.07,-0.0965925826289068,0.05,0.07,-0.0866025403784439,0.0549999999999999,0.07,-0.0952627944162883,0.0707106781186548,0.07,-0.0707106781186548,0.0777817459305202,0.07,-0.0777817459305202,0.0866025403784439,0.07,-0.05,0.0952627944162882,0.07,-0.0550000000000001,0.0965925826289068,0.07,-0.0258819045102521,0.106251840891798,0.07,-0.0284700949612774,0.1,0.07,-0,-0.0952627944162882,0.07,0.055,-0.0965925826289068,0.07,0.025881904510252,-0.0866025403784439,0.07,0.05,-0.0777817459305202,0.07,0.0777817459305202,-0.0707106781186548,0.07,0.0707106781186547,-0.055,0.07,0.0952627944162883,-0.05,0.07,0.0866025403784438,-0.0284700949612773,0.07,0.106251840891798,-0.0258819045102521,0.07,0.0965925826289068,0,0.07,0.11,-2.25597318603832e-17,0.07,0.1,0.025881904510252,0.07,0.0965925826289068,0.0284700949612773,0.07,0.106251840891797,0.0499999999999999,0.07,0.0866025403784439,0.055,0.07,0.0952627944162883,0.0707106781186548,0.07,0.0707106781186548,0.0777817459305202,0.07,0.0777817459305202,0.0866025403784438,0.07,0.05, +0.0952627944162883,0.07,0.055,0.0965925826289068,0.07,0.0258819045102522,0.106251840891798,0.07,0.0284700949612773,0.11,0.07,-0,-0.0952627944162882,0.08,0.055,-0.1,0.08,-1.24078525232107e-16,-0.106251840891797,0.08,0.0284700949612773,-0.0965925826289069,0.08,0.0258819045102519,-0.0866025403784439,0.08,0.0499999999999999,-0.0777817459305202,0.08,0.0777817459305202,-0.0707106781186548,0.08,0.0707106781186546,-0.055,0.08,0.0952627944162883,-0.0500000000000001,0.08,0.0866025403784437,-0.0284700949612773,0.08,0.106251840891798,-0.0258819045102522,0.08,0.0965925826289067,0,0.08,0.11,-4.51194637207664e-17,0.08,0.0999999999999999,0.025881904510252,0.08,0.0965925826289067,0.0284700949612773,0.08,0.106251840891797,0.0499999999999999,0.08,0.0866025403784438,0.055,0.08,0.0952627944162883,0.0707106781186547,0.08,0.0707106781186547,0.0777817459305202,0.08,0.0777817459305202,0.0866025403784438,0.08,0.0499999999999999,0.0952627944162883,0.08,0.055,0.0965925826289068,0.08,0.025881904510252,0.106251840891798,0.08,0.0284700949612773,0.1,0.08,-1.12798659301916e-16,-0.106251840891798,0.08,-0.0284700949612772,-0.11,0.08,2.25597318603832e-17,-0.0952627944162883,0.08,-0.055,-0.0965925826289068,0.08,-0.0258819045102522,-0.0866025403784439,0.08,-0.0500000000000002,-0.0777817459305203,0.08,-0.0777817459305202,-0.0707106781186548,0.08,-0.0707106781186549,-0.055,0.08,-0.0952627944162882,-0.05,0.08,-0.086602540378444,-0.0284700949612774,0.08,-0.106251840891798,-0.0258819045102521,0.08,-0.096592582628907,-2.25597318603832e-17,0.08,-0.11,-1.12798659301916e-17,0.08,-0.1,0.0284700949612772,0.08,-0.106251840891798,0.0258819045102521,0.08,-0.0965925826289069,0.05,0.08,-0.086602540378444,0.0549999999999999,0.08,-0.0952627944162883,0.0707106781186547,0.08,-0.0707106781186549,0.0777817459305202,0.08,-0.0777817459305202,0.0866025403784439,0.08,-0.0500000000000001,0.0952627944162882,0.08,-0.0550000000000001,0.0965925826289068,0.08,-0.0258819045102522,0.106251840891798,0.08,-0.0284700949612774,0.11,0.08,-0,-0.106251840891797,0.08,0.0284700949612773,-0.1,0.08,-1.24078525232107e-16, +-0.0952627944162882,0.08,0.055,-0.0965925826289069,0.08,0.0258819045102519,-0.0866025403784439,0.08,0.0499999999999999,-0.0777817459305202,0.08,0.0777817459305202,-0.0707106781186548,0.08,0.0707106781186546,-0.055,0.08,0.0952627944162883,-0.0500000000000001,0.08,0.0866025403784437,-0.0284700949612773,0.08,0.106251840891798,-0.0258819045102522,0.08,0.0965925826289067,0,0.08,0.11,-4.51194637207664e-17,0.08,0.0999999999999999,0.025881904510252,0.08,0.0965925826289067,0.0284700949612773,0.08,0.106251840891797,0.0499999999999999,0.08,0.0866025403784438,0.055,0.08,0.0952627944162883,0.0707106781186547,0.08,0.0707106781186547,0.0777817459305202,0.08,0.0777817459305202,0.0866025403784438,0.08,0.0499999999999999,0.0952627944162883,0.08,0.055,0.0965925826289068,0.08,0.025881904510252,0.106251840891798,0.08,0.0284700949612773,0.1,0.08,-1.12798659301916e-16,-0.11,0.08,2.25597318603832e-17,-0.106251840891798,0.08,-0.0284700949612772,-0.0952627944162883,0.08,-0.055,-0.0965925826289068,0.08,-0.0258819045102522,-0.0866025403784439,0.08,-0.0500000000000002,-0.0777817459305203,0.08,-0.0777817459305202,-0.0707106781186548,0.08,-0.0707106781186549,-0.055,0.08,-0.0952627944162882,-0.05,0.08,-0.086602540378444,-0.0284700949612774,0.08,-0.106251840891798,-0.0258819045102521,0.08,-0.096592582628907,-2.25597318603832e-17,0.08,-0.11,-1.12798659301916e-17,0.08,-0.1,0.0284700949612772,0.08,-0.106251840891798,0.0258819045102521,0.08,-0.0965925826289069,0.05,0.08,-0.086602540378444,0.0549999999999999,0.08,-0.0952627944162883,0.0707106781186547,0.08,-0.0707106781186549,0.0777817459305202,0.08,-0.0777817459305202,0.0866025403784439,0.08,-0.0500000000000001,0.0952627944162882,0.08,-0.0550000000000001,0.0965925826289068,0.08,-0.0258819045102522,0.106251840891798,0.08,-0.0284700949612774,0.11,0.08,-0,0.106251840891798,0.07,-0.0284700949612774,0.11,0.08,-0,0.11,0.07,-0,0.106251840891798,0.08,-0.0284700949612774,0.11,0.07,-0,0.11,0.08,-0,0.106251840891798,0.07,-0.0284700949612774,0.106251840891798,0.08,-0.0284700949612774,0.106251840891798,0.08,0.0284700949612773, +0.106251840891798,0.07,0.0284700949612773,0.106251840891798,0.07,0.0284700949612773,0.106251840891798,0.08,0.0284700949612773,0.0952627944162883,0.08,0.055,0.0952627944162883,0.07,0.055,0.0952627944162883,0.07,0.055,0.0952627944162883,0.08,0.055,0.0777817459305202,0.08,0.0777817459305202,0.0777817459305202,0.07,0.0777817459305202,0.0777817459305202,0.07,0.0777817459305202,0.0777817459305202,0.08,0.0777817459305202,0.055,0.07,0.0952627944162883,0.055,0.08,0.0952627944162883,0.055,0.07,0.0952627944162883,0.055,0.08,0.0952627944162883,0.0284700949612773,0.07,0.106251840891797,0.0284700949612773,0.08,0.106251840891797,0.0284700949612773,0.07,0.106251840891797,0.0284700949612773,0.08,0.106251840891797,0,0.07,0.11,0,0.08,0.11,0,0.07,0.11,0,0.08,0.11,-0.0284700949612773,0.07,0.106251840891798,-0.0284700949612773,0.08,0.106251840891798,-0.0284700949612773,0.07,0.106251840891798,-0.0284700949612773,0.08,0.106251840891798,-0.055,0.07,0.0952627944162883,-0.055,0.08,0.0952627944162883,-0.055,0.07,0.0952627944162883,-0.055,0.08,0.0952627944162883,-0.0777817459305202,0.07,0.0777817459305202,-0.0777817459305202,0.08,0.0777817459305202,-0.0777817459305202,0.07,0.0777817459305202,-0.0777817459305202,0.08,0.0777817459305202,-0.0952627944162882,0.08,0.055,-0.0952627944162882,0.07,0.055,-0.0952627944162882,0.08,0.055,-0.0952627944162882,0.07,0.055,-0.106251840891797,0.08,0.0284700949612773,-0.106251840891797,0.07,0.0284700949612773,-0.106251840891797,0.08,0.0284700949612773,-0.106251840891797,0.07,0.0284700949612773,-0.11,0.08,2.25597318603832e-17,-0.11,0.07,2.25597318603832e-17,-0.11,0.08,2.25597318603832e-17,-0.11,0.07,2.25597318603832e-17,-0.106251840891798,0.08,-0.0284700949612772,-0.106251840891798,0.07,-0.0284700949612772,-0.106251840891798,0.08,-0.0284700949612772,-0.106251840891798,0.07,-0.0284700949612772,-0.0952627944162883,0.08,-0.055,-0.0952627944162883,0.07,-0.055,-0.0952627944162883,0.08,-0.055,-0.0952627944162883,0.07,-0.055,-0.0777817459305203,0.08,-0.0777817459305202,-0.0777817459305203,0.07,-0.0777817459305202,-0.0777817459305203,0.08,-0.0777817459305202, +-0.0777817459305203,0.07,-0.0777817459305202,-0.055,0.07,-0.0952627944162882,-0.055,0.08,-0.0952627944162882,-0.055,0.07,-0.0952627944162882,-0.055,0.08,-0.0952627944162882,-0.0284700949612774,0.07,-0.106251840891798,-0.0284700949612774,0.08,-0.106251840891798,-0.0284700949612774,0.07,-0.106251840891798,-0.0284700949612774,0.08,-0.106251840891798,-2.25597318603832e-17,0.07,-0.11,-2.25597318603832e-17,0.08,-0.11,-2.25597318603832e-17,0.07,-0.11,-2.25597318603832e-17,0.08,-0.11,0.0284700949612772,0.07,-0.106251840891798,0.0284700949612772,0.08,-0.106251840891798,0.0284700949612772,0.07,-0.106251840891798,0.0284700949612772,0.08,-0.106251840891798,0.0549999999999999,0.07,-0.0952627944162883,0.0549999999999999,0.08,-0.0952627944162883,0.0549999999999999,0.07,-0.0952627944162883,0.0549999999999999,0.08,-0.0952627944162883,0.0777817459305202,0.07,-0.0777817459305202,0.0777817459305202,0.08,-0.0777817459305202,0.0777817459305202,0.07,-0.0777817459305202,0.0777817459305202,0.08,-0.0777817459305202,0.0952627944162882,0.08,-0.0550000000000001,0.0952627944162882,0.07,-0.0550000000000001,0.0952627944162882,0.07,-0.0550000000000001,0.0952627944162882,0.08,-0.0550000000000001,-0.05,0.08,-0.086602540378444,-0.0707106781186548,0.07,-0.0707106781186548,-0.05,0.07,-0.0866025403784439,-0.0707106781186548,0.08,-0.0707106781186549,-0.05,0.07,-0.0866025403784439,-0.0707106781186548,0.07,-0.0707106781186548,-0.05,0.08,-0.086602540378444,-0.0707106781186548,0.08,-0.0707106781186549,-0.0866025403784439,0.08,-0.0500000000000002,-0.0866025403784439,0.07,-0.05,-0.0866025403784439,0.07,-0.05,-0.0866025403784439,0.08,-0.0500000000000002,-0.0965925826289068,0.08,-0.0258819045102522,-0.0965925826289068,0.07,-0.0258819045102521,-0.0965925826289068,0.07,-0.0258819045102521,-0.0965925826289068,0.08,-0.0258819045102522,-0.1,0.08,-1.24078525232107e-16,-0.1,0.07,-2.25597318603832e-17,-0.1,0.07,-2.25597318603832e-17,-0.1,0.08,-1.24078525232107e-16,-0.0965925826289069,0.08,0.0258819045102519,-0.0965925826289068,0.07,0.025881904510252,-0.0965925826289068,0.07,0.025881904510252, +-0.0965925826289069,0.08,0.0258819045102519,-0.0866025403784439,0.08,0.0499999999999999,-0.0866025403784439,0.07,0.05,-0.0866025403784439,0.07,0.05,-0.0866025403784439,0.08,0.0499999999999999,-0.0707106781186548,0.08,0.0707106781186546,-0.0707106781186548,0.07,0.0707106781186547,-0.0707106781186548,0.07,0.0707106781186547,-0.0707106781186548,0.08,0.0707106781186546,-0.05,0.07,0.0866025403784438,-0.0500000000000001,0.08,0.0866025403784437,-0.05,0.07,0.0866025403784438,-0.0500000000000001,0.08,0.0866025403784437,-0.0258819045102521,0.07,0.0965925826289068,-0.0258819045102522,0.08,0.0965925826289067,-0.0258819045102521,0.07,0.0965925826289068,-0.0258819045102522,0.08,0.0965925826289067,-2.25597318603832e-17,0.07,0.1,-4.51194637207664e-17,0.08,0.0999999999999999,-2.25597318603832e-17,0.07,0.1,-4.51194637207664e-17,0.08,0.0999999999999999,0.025881904510252,0.07,0.0965925826289068,0.025881904510252,0.08,0.0965925826289067,0.025881904510252,0.07,0.0965925826289068,0.025881904510252,0.08,0.0965925826289067,0.0499999999999999,0.07,0.0866025403784439,0.0499999999999999,0.08,0.0866025403784438,0.0499999999999999,0.07,0.0866025403784439,0.0499999999999999,0.08,0.0866025403784438,0.0707106781186548,0.07,0.0707106781186548,0.0707106781186547,0.08,0.0707106781186547,0.0707106781186548,0.07,0.0707106781186548,0.0707106781186547,0.08,0.0707106781186547,0.0866025403784438,0.07,0.05,0.0866025403784438,0.08,0.0499999999999999,0.0866025403784438,0.07,0.05,0.0866025403784438,0.08,0.0499999999999999,0.0965925826289068,0.07,0.0258819045102522,0.0965925826289068,0.08,0.025881904510252,0.0965925826289068,0.07,0.0258819045102522,0.0965925826289068,0.08,0.025881904510252,0.1,0.07,-0,0.1,0.08,-1.12798659301916e-16,0.1,0.07,-0,0.1,0.08,-1.12798659301916e-16,0.0965925826289068,0.07,-0.0258819045102521,0.0965925826289068,0.08,-0.0258819045102522,0.0965925826289068,0.07,-0.0258819045102521,0.0965925826289068,0.08,-0.0258819045102522,0.0866025403784439,0.07,-0.05,0.0866025403784439,0.08,-0.0500000000000001,0.0866025403784439,0.07,-0.05,0.0866025403784439,0.08,-0.0500000000000001, +0.0707106781186548,0.07,-0.0707106781186548,0.0707106781186547,0.08,-0.0707106781186549,0.0707106781186548,0.07,-0.0707106781186548,0.0707106781186547,0.08,-0.0707106781186549,0.05,0.07,-0.0866025403784439,0.05,0.08,-0.086602540378444,0.05,0.07,-0.0866025403784439,0.05,0.08,-0.086602540378444,0.0258819045102521,0.07,-0.0965925826289068,0.0258819045102521,0.08,-0.0965925826289069,0.0258819045102521,0.07,-0.0965925826289068,0.0258819045102521,0.08,-0.0965925826289069,0,0.07,-0.1,-1.12798659301916e-17,0.08,-0.1,0,0.07,-0.1,-1.12798659301916e-17,0.08,-0.1,-0.0258819045102521,0.07,-0.0965925826289068,-0.0258819045102521,0.08,-0.096592582628907,-0.0258819045102521,0.07,-0.0965925826289068,-0.0258819045102521,0.08,-0.096592582628907 + } + PolygonVertexIndex: *1572 { + a: 0,1,-3,1,0,-4,3,0,-5,3,4,-6,5,4,-7,5,6,-8,7,6,-9,7,8,-10,9,8,-11,9,10,-12,11,10,-13,11,12,-14,13,12,-15,13,14,-16,15,14,-17,15,16,-18,17,16,-19,17,18,-20,19,18,-21,19,20,-22,21,20,-23,21,22,-24,24,25,-27,27,26,-26,28,26,-28,29,28,-28,30,28,-30,31,30,-30,32,30,-32,33,32,-32,34,32,-34,35,34,-34,36,34,-36,37,36,-36,38,36,-38,39,38,-38,40,38,-40,41,40,-40,42,40,-42,43,42,-42,44,42,-44,45,44,-44,46,44,-46,47,46,-46,48,49,-51,49,48,-52,52,53,-55,55,54,-54,51,56,-50,56,51,-58,53,58,-56,59,55,-59,57,60,-57,60,57,-62,58,62,-60,63,59,-63,61,64,-61,64,61,-66,62,66,-64,67,63,-67,65,68,-65,68,65,-70,66,70,-68,71,67,-71,69,72,-69,72,69,-74,70,74,-72,75,71,-75,72,76,-78,76,72,-74,78,79,-75,75,74,-80,77,80,-82,80,77,-77,82,83,-79,79,78,-84,81,84,-86,84,81,-81,86,87,-83,83,82,-88,85,88,-90,88,85,-85,90,91,-87,87,86,-92,89,92,-94,92,89,-89,94,95,-91,91,90,-96,93,96,-98,96,93,-93,98,99,-95,95,94,-100,96,100,-98,100,96,-102,98,102,-100,103,99,-103,101,104,-101,104,101,-106,102,106,-104,107,103,-107,105,108,-105,108,105,-110,106,110,-108,111,107,-111,109,112,-109,112,109,-114,110,114,-112,115,111,-115,113,116,-113,116,113,-118,114,118,-116,119,115,-119,117,120,-117,120,117,-122,118,122,-120,123,119,-123,124,120,-122,120,124,-126,123,122,-127,127,126,-123,128,125,-125,125,128,-130,126,127,-131,131,130,-128,132,129,-129,129,132,-134,130,131,-135,135,134,-132,136,133,-133,133,136,-138,134,135,-139,139,138,-136,140,137,-137,137,140,-142,138,139,-143,143,142,-140,48,141,-141,141,48,-51,142,143,-55,52,54,-144,144,145,-147,145,144,-148,145,147,-149,148,147,-150,149,147,-151,150,147,-152,150,151,-153,152,151,-154,152,153,-155,154,153,-156,154,155,-157,156,155,-158,156,157,-159,158,157,-160,158,159,-161,160,159,-162,161,159,-163,161,162,-164,163,162,-165,163,164,-166,165,164,-167,165,166,-168,167,166,-169,167,168,-170,148,170,-146,170,148,-172,170,171,-173,170,172,-174,173,172,-175,173,174,-176,175,174,-177,175,176,-178,177,176,-179,177,178,-180,179,178,-181,179,180,-182,179,181,-183,182,181,-184,182,183,-185,184,183,-186,184, +185,-187,186,185,-188,186,187,-189,188,187,-190,188,189,-191,190,189,-170,190,169,-169,190,168,-192,192,193,-195,195,194,-194,196,195,-194,197,195,-197,198,195,-198,199,195,-199,200,199,-199,201,199,-201,202,201,-201,203,201,-203,204,203,-203,205,203,-205,206,205,-205,207,205,-207,208,207,-207,209,207,-209,210,207,-210,211,210,-210,212,210,-212,213,212,-212,214,212,-214,215,214,-214,216,214,-216,217,216,-216,193,218,-197,219,196,-219,220,219,-219,221,220,-219,222,220,-222,223,222,-222,224,222,-224,225,224,-224,226,224,-226,227,226,-226,228,226,-228,229,228,-228,230,229,-228,231,229,-231,232,231,-231,233,231,-233,234,233,-233,235,233,-235,236,235,-235,237,235,-237,238,237,-237,217,237,-239,216,217,-239,239,216,-239,240,241,-243,241,240,-244,243,240,-245,244,240,-246,244,245,-247,246,245,-248,246,247,-249,248,247,-250,248,249,-251,250,249,-252,250,251,-253,252,251,-254,253,251,-255,253,254,-256,255,254,-257,255,256,-258,257,256,-259,257,258,-260,259,258,-261,259,260,-262,261,260,-263,261,262,-264,242,264,-266,264,242,-267,266,242,-242,266,241,-268,266,267,-269,266,268,-270,269,268,-271,269,270,-272,271,270,-273,271,272,-274,273,272,-275,273,274,-276,275,274,-277,275,276,-278,277,276,-279,277,278,-280,277,279,-281,280,279,-282,280,281,-283,282,281,-284,282,283,-285,284,283,-286,284,285,-287,286,285,-264,286,263,-263,286,262,-288,288,289,-291,291,290,-290,292,290,-292,293,290,-293,294,293,-293,295,293,-295,296,295,-295,297,295,-297,298,297,-297,299,297,-299,300,299,-299,301,299,-301,302,299,-302,303,302,-302,304,302,-304,305,304,-304,306,304,-306,307,306,-306,308,306,-308,309,308,-308,310,308,-310,311,310,-310,312,313,-289,314,288,-314,289,288,-315,315,289,-315,316,315,-315,317,316,-315,318,316,-318,319,318,-318,320,318,-320,321,320,-320,322,320,-322,323,322,-322,324,322,-324,325,324,-324,326,324,-326,327,326,-326,328,327,-326,329,327,-329,330,329,-329,331,329,-331,332,331,-331,333,331,-333,334,333,-333,311,333,-335,310,311,-335,335,310,-335,336,337,-339,337,336,-340,340,341,-343,343,342,-342,338,344,-346,344,338,-338, +346,347,-341,341,340,-348,345,348,-350,348,345,-345,350,351,-347,347,346,-352,349,352,-354,352,349,-349,354,355,-351,351,350,-356,352,356,-354,356,352,-358,354,358,-356,359,355,-359,357,360,-357,360,357,-362,358,362,-360,363,359,-363,361,364,-361,364,361,-366,362,366,-364,367,363,-367,365,368,-365,368,365,-370,366,370,-368,371,367,-371,369,372,-369,372,369,-374,370,374,-372,375,371,-375,373,376,-373,376,373,-378,374,378,-376,379,375,-379,380,376,-378,376,380,-382,379,378,-383,383,382,-379,384,381,-381,381,384,-386,382,383,-387,387,386,-384,388,385,-385,385,388,-390,386,387,-391,391,390,-388,392,389,-389,389,392,-394,390,391,-395,395,394,-392,396,393,-393,393,396,-398,394,395,-399,399,398,-396,400,397,-397,397,400,-402,398,399,-403,403,402,-400,400,404,-402,404,400,-406,403,406,-403,407,402,-407,405,408,-405,408,405,-410,406,410,-408,411,407,-411,409,412,-409,412,409,-414,410,414,-412,415,411,-415,413,416,-413,416,413,-418,414,418,-416,419,415,-419,417,420,-417,420,417,-422,418,422,-420,423,419,-423,421,424,-421,424,421,-426,422,426,-424,427,423,-427,424,428,-430,428,424,-426,430,431,-427,427,426,-432,429,339,-337,339,429,-429,342,343,-431,431,430,-344,432,433,-435,433,432,-436,436,437,-439,439,438,-438,433,440,-442,440,433,-436,442,443,-438,439,437,-444,441,444,-446,444,441,-441,446,447,-443,443,442,-448,445,448,-450,448,445,-445,450,451,-447,447,446,-452,449,452,-454,452,449,-449,454,455,-451,451,450,-456,453,456,-458,456,453,-453,458,459,-455,455,454,-460,457,460,-462,460,457,-457,462,463,-459,459,458,-464,460,464,-462,464,460,-466,462,466,-464,467,463,-467,465,468,-465,468,465,-470,466,470,-468,471,467,-471,469,472,-469,472,469,-474,470,474,-472,475,471,-475,473,476,-473,476,473,-478,474,478,-476,479,475,-479,477,480,-477,480,477,-482,478,482,-480,483,479,-483,481,484,-481,484,481,-486,482,486,-484,487,483,-487,485,488,-485,488,485,-490,486,490,-488,491,487,-491,489,492,-489,492,489,-494,490,494,-492,495,491,-495,493,496,-493,496,493,-498,494,498,-496,499,495,-499,497,500,-497,500,497,-502,498,502,-500,503,499, +-503,501,504,-501,504,501,-506,502,506,-504,507,503,-507,505,508,-505,508,505,-510,506,510,-508,511,507,-511,509,512,-509,512,509,-514,510,514,-512,515,511,-515,513,516,-513,516,513,-518,514,518,-516,519,515,-519,517,520,-517,520,517,-522,518,522,-520,523,519,-523,521,524,-521,524,521,-526,522,526,-524,527,523,-527,525,434,-525,434,525,-433,526,436,-528,438,527,-437 + } + GeometryVersion: 124 + LayerElementNormal: 0 { + Version: 101 + Name: "" + MappingInformationType: "ByVertice" + ReferenceInformationType: "Direct" + Normals: *1584 { + a: 0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0.707106781186547,0,-0.707106781186548,-0.5,0,-0.866025403784439,-0.707106781186547,0,-0.707106781186548,-0.5,0,-0.866025403784439,0.707106781186547,-0,0.707106781186548,0.5,-0,0.866025403784439,0.707106781186547,-0,0.707106781186548,0.5,-0,0.866025403784439,-0.25881904510252,0,-0.965925826289068,-0.25881904510252,0,-0.965925826289068,0.25881904510252,-0,0.965925826289068,0.25881904510252,-0,0.965925826289068,1.53972925609226e-16,0,-1,1.53972925609226e-16,0,-1,-1.53972925609226e-16,-0,1,-1.53972925609226e-16,-0,1,0.258819045102521,0,-0.965925826289068,0.258819045102521,0,-0.965925826289068,-0.258819045102521,-0,0.965925826289068,-0.258819045102521,-0,0.965925826289068,0.5,0,-0.866025403784439,0.5,0,-0.866025403784439,-0.5,-0,0.866025403784439,-0.5,-0,0.866025403784439,0.707106781186548,0,-0.707106781186548,0.707106781186548,0,-0.707106781186548,-0.707106781186548,-0,0.707106781186548,-0.707106781186548,-0,0.707106781186548,0.866025403784439,0,-0.5,0.866025403784439,0,-0.5,-0.866025403784439,-0,0.5,-0.866025403784439,-0,0.5,0.965925826289068,0,-0.258819045102521,0.965925826289068,0,-0.258819045102521,-0.965925826289068,-0,0.258819045102521,-0.965925826289068,-0,0.258819045102521,1,0,2.37958157759713e-16,1,0,2.37958157759713e-16,-1,-0,-2.37958157759713e-16,-1,-0,-2.37958157759713e-16,0.965925826289068,0,0.258819045102521,0.965925826289068,0,0.258819045102521,-0.965925826289068,-0,-0.258819045102521,-0.965925826289068,-0,-0.258819045102521,0.866025403784438,0,0.5,0.866025403784438,0,0.5,-0.866025403784438,-0,-0.5,-0.866025403784438,-0,-0.5,0.707106781186547,0,0.707106781186548,0.707106781186547,0,0.707106781186548,-0.707106781186547,-0,-0.707106781186548, +-0.707106781186547,-0,-0.707106781186548,0.499999999999999,0,0.866025403784439,0.499999999999999,0,0.866025403784439,-0.499999999999999,-0,-0.866025403784439,-0.499999999999999,-0,-0.866025403784439,0.25881904510252,0,0.965925826289069,0.25881904510252,0,0.965925826289069,-0.25881904510252,-0,-0.965925826289069,-0.25881904510252,-0,-0.965925826289069,-4.19926160752434e-16,0,1,-4.19926160752434e-16,0,1,4.19926160752434e-16,-0,-1,4.19926160752434e-16,-0,-1,-0.258819045102521,0,0.965925826289068,-0.258819045102521,0,0.965925826289068,0.258819045102521,-0,-0.965925826289068,0.258819045102521,-0,-0.965925826289068,-0.500000000000001,0,0.866025403784438,-0.500000000000001,0,0.866025403784438,0.500000000000001,-0,-0.866025403784438,0.500000000000001,-0,-0.866025403784438,-0.707106781186548,0,0.707106781186547,-0.707106781186548,0,0.707106781186547,0.707106781186548,-0,-0.707106781186547,0.707106781186548,-0,-0.707106781186547,-0.866025403784439,0,0.5,-0.866025403784439,0,0.5,0.866025403784439,-0,-0.5,0.866025403784439,-0,-0.5,-0.965925826289068,0,0.25881904510252,-0.965925826289068,0,0.25881904510252,0.965925826289068,-0,-0.25881904510252,0.965925826289068,-0,-0.25881904510252,-1,0,-3.07945851218452e-16,-1,0,-3.07945851218452e-16,1,-0,3.07945851218452e-16,1,-0,3.07945851218452e-16,-0.965925826289068,0,-0.258819045102521,-0.965925826289068,0,-0.258819045102521,0.965925826289068,-0,0.258819045102521,0.965925826289068,-0,0.258819045102521,-0.866025403784438,0,-0.5,-0.866025403784438,0,-0.5,0.866025403784438,-0,0.5,0.866025403784438,-0,0.5,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0, +-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,0.965925826289068,0,-0.258819045102521,1,0,-1.95965541684469e-16,1,0,-1.95965541684469e-16,0.965925826289068,0,-0.258819045102521,-1,-0,1.95965541684469e-16,-1,-0,1.95965541684469e-16,-0.965925826289068,-0,0.258819045102521,-0.965925826289068,-0,0.258819045102521,0.965925826289068,0,0.258819045102521,0.965925826289068,0,0.258819045102521,-0.965925826289068,-0,-0.258819045102521,-0.965925826289068,-0,-0.258819045102521,0.866025403784439,0,0.5,0.866025403784439,0,0.5,-0.866025403784439,-0,-0.5,-0.866025403784439,-0,-0.5,0.707106781186548,0,0.707106781186547,0.707106781186548,0,0.707106781186547,-0.707106781186548,-0,-0.707106781186547,-0.707106781186548,-0,-0.707106781186547,0.5,0,0.866025403784439,0.5,0,0.866025403784439,-0.5,-0,-0.866025403784439,-0.5,-0,-0.866025403784439,0.258819045102521,0,0.965925826289068,0.258819045102521,0,0.965925826289068,-0.258819045102521,-0,-0.965925826289068,-0.258819045102521,-0,-0.965925826289068,3.219433899102e-16,0,1,3.219433899102e-16,0,1,-3.219433899102e-16,-0,-1,-3.219433899102e-16,-0,-1,-0.25881904510252,0,0.965925826289068,-0.25881904510252,0,0.965925826289068, +0.25881904510252,-0,-0.965925826289068,0.25881904510252,-0,-0.965925826289068,-0.5,0,0.866025403784439,-0.5,0,0.866025403784439,0.5,-0,-0.866025403784439,0.5,-0,-0.866025403784439,-0.707106781186548,0,0.707106781186548,-0.707106781186548,0,0.707106781186548,0.707106781186548,-0,-0.707106781186548,0.707106781186548,-0,-0.707106781186548,-0.866025403784438,0,0.5,-0.866025403784438,0,0.5,0.866025403784438,-0,-0.5,0.866025403784438,-0,-0.5,-0.965925826289068,0,0.258819045102521,-0.965925826289068,0,0.258819045102521,0.965925826289068,-0,-0.258819045102521,0.965925826289068,-0,-0.258819045102521,-1,0,2.65953235143208e-16,-1,0,2.65953235143208e-16,1,-0,-2.65953235143208e-16,1,-0,-2.65953235143208e-16,-0.965925826289068,0,-0.25881904510252,-0.965925826289068,0,-0.25881904510252,0.965925826289068,-0,0.25881904510252,0.965925826289068,-0,0.25881904510252,-0.866025403784439,0,-0.5,-0.866025403784439,0,-0.5,0.866025403784439,-0,0.5,0.866025403784439,-0,0.5,-0.707106781186548,0,-0.707106781186547,-0.707106781186548,0,-0.707106781186547,0.707106781186548,-0,0.707106781186547,0.707106781186548,-0,0.707106781186547,-0.500000000000001,0,-0.866025403784438,-0.500000000000001,0,-0.866025403784438,0.500000000000001,-0,0.866025403784438,0.500000000000001,-0,0.866025403784438,-0.258819045102521,0,-0.965925826289068,-0.258819045102521,0,-0.965925826289068,0.258819045102521,-0,0.965925826289068,0.258819045102521,-0,0.965925826289068,-1.95965541684469e-16,0,-1,-1.95965541684469e-16,0,-1,1.95965541684469e-16,-0,1,1.95965541684469e-16,-0,1,0.25881904510252,0,-0.965925826289068,0.25881904510252,0,-0.965925826289068,-0.25881904510252,-0,0.965925826289068,-0.25881904510252,-0,0.965925826289068,0.499999999999999,0,-0.866025403784439,0.499999999999999,0,-0.866025403784439,-0.499999999999999,-0,0.866025403784439,-0.499999999999999,-0,0.866025403784439,0.707106781186547,0,-0.707106781186548,0.707106781186547,0,-0.707106781186548,-0.707106781186547,-0,0.707106781186548,-0.707106781186547,-0,0.707106781186548,0.866025403784438,0,-0.500000000000001, +0.866025403784438,0,-0.500000000000001,-0.866025403784438,-0,0.500000000000001,-0.866025403784438,-0,0.500000000000001,0.5,1.19982069463348e-14,0.866025403784439,0.707106781186547,9.60521683617532e-15,0.707106781186548,0.5,1.19982069463348e-14,0.866025403784439,0.707106781186547,9.60521683617532e-15,0.707106781186548,-0.5,-1.19982069463348e-14,-0.866025403784439,-0.707106781186547,-9.60521683617532e-15,-0.707106781186548,-0.5,-1.19982069463348e-14,-0.866025403784439,-0.707106781186547,-9.60521683617532e-15,-0.707106781186548,0.866025403784438,7.80731547193642e-15,0.5,0.866025403784438,7.80731547193642e-15,0.5,-0.866025403784438,-7.80731547193642e-15,-0.5,-0.866025403784438,-7.80731547193642e-15,-0.5,0.965925826289068,5.28592816826665e-15,0.258819045102521,0.965925826289068,5.28592816826665e-15,0.258819045102521,-0.965925826289068,-5.28592816826665e-15,-0.258819045102521,-0.965925826289068,-5.28592816826665e-15,-0.258819045102521,1,2.26662556261245e-15,3.35940928601947e-16,1,2.26662556261245e-15,3.35940928601947e-16,-1,-2.26662556261245e-15,-3.35940928601947e-16,-1,-2.26662556261245e-15,-3.35940928601947e-16,0.965925826289068,-6.84424925549458e-16,-0.25881904510252,0.965925826289068,-6.84424925549458e-16,-0.25881904510252,-0.965925826289068,6.84424925549458e-16,0.25881904510252,-0.965925826289068,6.84424925549458e-16,0.25881904510252,0.866025403784439,-3.68131329715977e-15,-0.5,0.866025403784439,-3.68131329715977e-15,-0.5,-0.866025403784439,3.68131329715977e-15,0.5,-0.866025403784439,3.68131329715977e-15,0.5,0.707106781186548,-6.36682780642109e-15,-0.707106781186547,0.707106781186548,-6.36682780642109e-15,-0.707106781186547,-0.707106781186548,6.36682780642109e-15,0.707106781186547,-0.707106781186548,6.36682780642109e-15,0.707106781186547,0.5,-8.60593036246272e-15,-0.866025403784438,0.5,-8.60593036246272e-15,-0.866025403784438,-0.5,8.60593036246272e-15,0.866025403784438,-0.5,8.60593036246272e-15,0.866025403784438,0.258819045102521,-1.02887796051795e-14,-0.965925826289068,0.258819045102521,-1.02887796051795e-14,-0.965925826289068, +-0.258819045102521,1.02887796051795e-14,0.965925826289068,-0.258819045102521,1.02887796051795e-14,0.965925826289068,4.89913854211173e-16,-1.12641904883204e-14,-1,4.89913854211173e-16,-1.12641904883204e-14,-1,-4.89913854211173e-16,1.12641904883204e-14,1,-4.89913854211173e-16,1.12641904883204e-14,1,-0.25881904510252,-1.15087445727774e-14,-0.965925826289069,-0.25881904510252,-1.15087445727774e-14,-0.965925826289069,0.25881904510252,1.15087445727774e-14,0.965925826289069,0.25881904510252,1.15087445727774e-14,0.965925826289069,-0.499999999999999,-1.08996956537765e-14,-0.866025403784439,-0.499999999999999,-1.08996956537765e-14,-0.866025403784439,0.499999999999999,1.08996956537765e-14,0.866025403784439,0.499999999999999,1.08996956537765e-14,0.866025403784439,-0.707106781186547,-9.08454934101695e-15,-0.707106781186548,-0.707106781186547,-9.08454934101695e-15,-0.707106781186548,0.707106781186547,9.08454934101695e-15,0.707106781186548,0.707106781186547,9.08454934101695e-15,0.707106781186548,-0.866025403784438,-7.131323406091e-15,-0.5,-0.866025403784438,-7.131323406091e-15,-0.5,0.866025403784438,7.131323406091e-15,0.5,0.866025403784438,7.131323406091e-15,0.5,-0.965925826289068,-5.09307932489816e-15,-0.258819045102521,-0.965925826289068,-5.09307932489816e-15,-0.258819045102521,0.965925826289068,5.09307932489816e-15,0.258819045102521,0.965925826289068,5.09307932489816e-15,0.258819045102521,-1,-1.13036593973881e-15,-2.37958157759713e-16,-1,-1.13036593973881e-15,-2.37958157759713e-16,1,1.13036593973881e-15,2.37958157759713e-16,1,1.13036593973881e-15,2.37958157759713e-16,-0.965925826289068,2.39835689659947e-15,0.25881904510252,-0.965925826289068,2.39835689659947e-15,0.25881904510252,0.965925826289068,-2.39835689659947e-15,-0.25881904510252,0.965925826289068,-2.39835689659947e-15,-0.25881904510252,-0.866025403784439,3.77584242285922e-15,0.5,-0.866025403784439,3.77584242285922e-15,0.5,0.866025403784439,-3.77584242285922e-15,-0.5,0.866025403784439,-3.77584242285922e-15,-0.5,-0.707106781186548,4.81156404056102e-15,0.707106781186548,-0.707106781186548,4.81156404056102e-15,0.707106781186548, +0.707106781186548,-4.81156404056102e-15,-0.707106781186548,0.707106781186548,-4.81156404056102e-15,-0.707106781186548,-0.5,6.76964270175402e-15,0.866025403784439,-0.5,6.76964270175402e-15,0.866025403784439,0.5,-6.76964270175402e-15,-0.866025403784439,0.5,-6.76964270175402e-15,-0.866025403784439,-0.258819045102521,1.01608174674873e-14,0.965925826289068,-0.258819045102521,1.01608174674873e-14,0.965925826289068,0.258819045102521,-1.01608174674873e-14,-0.965925826289068,0.258819045102521,-1.01608174674873e-14,-0.965925826289068,-1.67970464300974e-16,1.29544413390859e-14,1,-1.67970464300974e-16,1.29544413390859e-14,1,1.67970464300974e-16,-1.29544413390859e-14,-1,1.67970464300974e-16,-1.29544413390859e-14,-1,0.25881904510252,1.36237774637864e-14,0.965925826289069,0.25881904510252,1.36237774637864e-14,0.965925826289069,-0.25881904510252,-1.36237774637864e-14,-0.965925826289069,-0.25881904510252,-1.36237774637864e-14,-0.965925826289069 + } + } + LayerElementUV: 0 { + Version: 101 + Name: "" + MappingInformationType: "ByPolygonVertex" + ReferenceInformationType: "IndexToDirect" + UV: *130 { + a: 3.80285758381523,1.01897261851386,3.80285758381523,-1.01897261851386,3.93700787401575,8.88178419700125e-16,3.409548833797,-1.96850393700787,3.409548833797,1.96850393700787,2.78388496530137,-2.78388496530137,2.78388496530137,2.78388496530137,1.96850393700788,-3.409548833797,1.96850393700787,3.409548833797,1.01897261851386,-3.80285758381523,1.01897261851386,3.80285758381523,8.88178419700125e-16,-3.93700787401575,0,3.93700787401575,-1.01897261851386,-3.80285758381523,-1.01897261851386,3.80285758381523,-1.96850393700787,-3.409548833797,-1.96850393700787,3.409548833797,-2.78388496530137,-2.78388496530137,-2.78388496530137,2.78388496530137,-3.409548833797,-1.96850393700788,-3.409548833797,1.96850393700787,-3.80285758381523,-1.01897261851386,-3.80285758381523,1.01897261851386,-3.93700787401575,0,0.513882646535636,2.75590551181102,-0.513882646535637,0,0.513882646535636,0,-0.513882646535637,2.75590551181102,4.18314334219675,1.12086988036525,4.18314334219675,-1.12086988036525,4.33070866141732,-8.88178419700125e-16,3.7505037171767,2.16535433070866,3.06227346183151,3.0622734618315,2.16535433070866,3.7505037171767,1.12086988036525,4.18314334219675,8.88178419700125e-16,4.33070866141732,-1.12086988036525,4.18314334219675,-2.16535433070866,3.7505037171767,-3.0622734618315,3.06227346183151,-3.7505037171767,2.16535433070866,-4.18314334219675,1.12086988036525,3.7505037171767,-2.16535433070866,3.0622734618315,-3.06227346183151,2.16535433070866,-3.7505037171767,1.12086988036525,-4.18314334219675,0,-4.33070866141732,-1.12086988036525,-4.18314334219675,-2.16535433070866,-3.7505037171767,-3.0622734618315,-3.0622734618315,-3.7505037171767,-2.16535433070866,-4.18314334219675,-1.12086988036525,-4.33070866141732,0,-3.93700787401575,4.88498130835069e-15,-1.77635683940025e-15,-3.93700787401574,3.93700787401575,4.44089209850063e-15,-4.33070866141732,-8.88178419700125e-16,-8.88178419700125e-16,4.33070866141732,-4.44089209850063e-16,3.93700787401575,4.33070866141732,0,0.565270911189203,2.75590551181102,-0.5652709111892,3.1496062992126, +-0.5652709111892,2.75590551181102,0.565270911189203,3.1496062992126,0.513882646535639,3.14960629921264,-0.513882646535635,3.14960629921264 + } + UVIndex: *1572 { + a: 0,1,2,1,0,3,3,0,4,3,4,5,5,4,6,5,6,7,7,6,8,7,8,9,9,8,10,9,10,11,11,10,12,11,12,13,13,12,14,13,14,15,15,14,16,15,16,17,17,16,18,17,18,19,19,18,20,19,20,21,21,20,22,21,22,23,2,1,0,3,0,1,4,0,3,5,4,3,6,4,5,7,6,5,8,6,7,9,8,7,10,8,9,11,10,9,12,10,11,13,12,11,14,12,13,15,14,13,16,14,15,17,16,15,18,16,17,19,18,17,20,18,19,21,20,19,22,20,21,23,22,21,24,25,26,25,24,27,26,25,24,27,24,25,24,25,26,25,24,27,26,25,24,27,24,25,24,25,26,25,24,27,26,25,24,27,24,25,24,25,26,25,24,27,26,25,24,27,24,25,24,25,26,25,24,27,26,25,24,27,24,25,24,25,26,25,24,27,26,25,24,27,24,25,26,27,25,27,26,24,25,27,26,24,26,27,26,27,25,27,26,24,25,27,26,24,26,27,26,27,25,27,26,24,25,27,26,24,26,27,26,27,25,27,26,24,25,27,26,24,26,27,26,27,25,27,26,24,25,27,26,24,26,27,26,27,25,27,26,24,25,27,26,24,26,27,24,25,26,25,24,27,26,25,24,27,24,25,24,25,26,25,24,27,26,25,24,27,24,25,24,25,26,25,24,27,26,25,24,27,24,25,24,25,26,25,24,27,26,25,24,27,24,25,24,25,26,25,24,27,26,25,24,27,24,25,24,25,26,25,24,27,26,25,24,27,24,25,27,26,24,26,27,25,24,26,27,25,27,26,27,26,24,26,27,25,24,26,27,25,27,26,27,26,24,26,27,25,24,26,27,25,27,26,27,26,24,26,27,25,24,26,27,25,27,26,27,26,24,26,27,25,24,26,27,25,27,26,27,26,24,26,27,25,24,26,27,25,27,26,28,29,30,29,28,31,29,31,2,2,31,0,0,31,4,4,31,32,4,32,6,6,32,33,6,33,8,8,33,34,8,34,10,10,34,35,10,35,12,12,35,36,12,36,14,14,36,16,16,36,37,16,37,18,18,37,38,18,38,20,20,38,39,20,39,22,22,39,40,22,40,23,2,41,29,41,2,1,41,1,3,41,3,42,42,3,5,42,5,43,43,5,7,43,7,44,44,7,9,44,9,45,45,9,11,45,11,13,45,13,46,46,13,15,46,15,47,47,15,17,47,17,48,48,17,19,48,19,49,49,19,21,49,21,50,50,21,23,50,23,40,50,40,51,30,29,28,31,28,29,2,31,29,0,31,2,4,31,0,32,31,4,6,32,4,33,32,6,8,33,6,34,33,8,10,34,8,35,34,10,12,35,10,36,35,12,14,36,12,16,36,14,37,36,16,18,37,16,38,37,18,20,38,18,39,38,20,22,39,20,40,39,22,23,40,22,29,41,2,1,2,41,3,1,41,42,3,41,5,3,42,43,5,42,7,5,43,44,7,43,9,7,44,45,9,44,11,9,45,13,11,45,46,13,45,15,13,46,47,15,46,17,15,47,48,17,47,19,17,48,49,19,48,21,19,49,50,21,49,23,21,50,40,23,50,51,40,50,49,52,50,52,49, +21,21,49,19,19,49,48,19,48,17,17,48,47,17,47,15,15,47,46,15,46,13,13,46,45,13,45,53,53,45,9,9,45,44,9,44,7,7,44,43,7,43,5,5,43,42,5,42,3,3,42,41,3,41,1,1,41,29,1,29,54,50,40,55,40,50,39,39,50,52,39,52,22,39,22,20,39,20,38,38,20,18,38,18,37,37,18,16,37,16,36,36,16,14,36,14,56,56,14,57,56,57,34,34,57,10,34,10,8,34,8,33,33,8,6,33,6,32,32,6,4,32,4,31,31,4,0,31,0,28,28,0,54,28,54,29,28,29,58,50,52,49,21,49,52,19,49,21,48,49,19,17,48,19,47,48,17,15,47,17,46,47,15,13,46,15,45,46,13,53,45,13,9,45,53,44,45,9,7,44,9,43,44,7,5,43,7,42,43,5,3,42,5,41,42,3,1,41,3,29,41,1,54,29,1,55,40,50,39,50,40,52,50,39,22,52,39,20,22,39,38,20,39,18,20,38,37,18,38,16,18,37,36,16,37,14,16,36,56,14,36,57,14,56,34,57,56,10,57,34,8,10,34,33,8,34,6,8,33,32,6,33,4,6,32,31,4,32,0,4,31,28,0,31,54,0,28,29,54,28,58,29,28,59,60,61,60,59,62,61,60,59,62,59,60,59,60,61,60,59,62,61,60,59,62,59,60,59,60,61,60,59,62,61,60,59,62,59,60,59,60,61,60,59,62,61,60,59,62,59,60,62,61,59,61,62,60,59,61,62,60,62,61,62,61,59,61,62,60,59,61,62,60,62,61,62,61,59,61,62,60,59,61,62,60,62,61,62,61,59,61,62,60,59,61,62,60,62,61,62,61,59,61,62,60,59,61,62,60,62,61,62,61,59,61,62,60,59,61,62,60,62,61,60,59,62,59,60,61,62,59,60,61,60,59,60,59,62,59,60,61,62,59,60,61,60,59,60,59,62,59,60,61,62,59,60,61,60,59,60,59,62,59,60,61,62,59,60,61,60,59,60,59,62,59,60,61,62,59,60,61,60,59,60,59,62,59,60,61,62,59,60,61,60,59,62,61,59,61,62,60,59,61,62,60,62,61,62,61,59,61,62,60,59,61,62,60,62,61,62,61,59,61,62,60,59,61,62,60,62,61,62,61,59,61,62,60,59,61,62,60,62,61,62,61,59,61,62,60,59,61,62,60,62,61,62,61,59,61,62,60,59,61,62,60,62,61,59,60,61,60,59,62,61,60,59,62,59,60,59,60,61,60,59,62,61,60,59,62,59,60,63,27,24,27,63,64,24,27,63,64,63,27,24,64,27,64,24,63,27,64,24,63,24,64,24,64,27,64,24,63,27,64,24,63,24,64,24,64,27,64,24,63,27,64,24,63,24,64,24,64,27,64,24,63,27,64,24,63,24,64,24,64,27,64,24,63,27,64,24,63,24,64,24,64,27,64,24,63,27,64,24,63,24,64,63,27,24,27,63,64,24,27,63,64,63,27,63,27,24,27,63,64,24,27,63,64,63,27,63,27,24,27,63,64,24,27,63,64,63,27,63,27,24,27,63,64,24,27,63,64, +63,27,63,27,24,27,63,64,24,27,63,64,63,27,63,27,24,27,63,64,24,27,63,64,63,27,63,27,24,27,63,64,24,27,63,64,63,27,63,27,24,27,63,64,24,27,63,64,63,27,63,27,24,27,63,64,24,27,63,64,63,27,63,27,24,27,63,64,24,27,63,64,63,27,63,27,24,27,63,64,24,27,63,64,63,27,63,27,24,27,63,64,24,27,63,64,63,27,63,27,24,27,63,64,24,27,63,64,63,27,63,27,24,27,63,64,24,27,63,64,63,27,63,27,24,27,63,64,24,27,63,64,63,27,63,27,24,27,63,64,24,27,63,64,63,27,63,27,24,27,63,64,24,27,63,64,63,27 + } + } + LayerElementMaterial: 0 { + Version: 101 + Name: "" + MappingInformationType: "ByPolygon" + ReferenceInformationType: "IndexToDirect" + Materials: *524 { + a: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + } + } + Layer: 0 { + Version: 100 + LayerElement: { + Type: "LayerElementNormal" + TypedIndex: 0 + } + LayerElement: { + Type: "LayerElementMaterial" + TypedIndex: 0 + } + LayerElement: { + Type: "LayerElementTexture" + TypedIndex: 0 + } + LayerElement: { + Type: "LayerElementUV" + TypedIndex: 0 + } + } + } + Model: 140593527729664, "Model::Model", "Null" { + Version: 232 + Properties70: { + P: "ScalingMax", "Vector3D", "Vector", "",0,0,0 + } + Shading: Y + Culling: "CullingOff" + } + Model: 140593526827008, "Model::Mesh1", "Mesh" { + Version: 232 + Properties70: { + P: "ScalingMax", "Vector3D", "Vector", "",0,0,0 + P: "DefaultAttributeIndex", "int", "Integer", "",0 + } + Shading: T + Culling: "CullingOff" + } + Material: 140593625783440, "Material::_9", "" { + Version: 102 + ShadingModel: "phong" + MultiLayer: 0 + Properties70: { + P: "AmbientColor", "Color", "", "A",0,0,0 + P: "DiffuseColor", "Color", "", "A",0.647058823529412,0.650980392156863,0.596078431372549 + P: "TransparentColor", "Color", "", "A",1,1,1 + P: "SpecularColor", "Color", "", "A",0.33,0.33,0.33 + P: "ReflectionFactor", "Number", "", "A",0 + P: "Emissive", "Vector3D", "Vector", "",0,0,0 + P: "Ambient", "Vector3D", "Vector", "",0,0,0 + P: "Diffuse", "Vector3D", "Vector", "",0.647058823529412,0.650980392156863,0.596078431372549 + P: "Specular", "Vector3D", "Vector", "",0.33,0.33,0.33 + P: "Shininess", "double", "Number", "",20 + P: "Opacity", "double", "Number", "",1 + P: "Reflectivity", "double", "Number", "",0 + } + } +} + +; Object connections +;------------------------------------------------------------------ + +Connections: { + + ;Model::Model, Model::RootNode + C: "OO",140593527729664,0 + + ;Model::Mesh1, Model::Model + C: "OO",140593526827008,140593527729664 + + ;Geometry::, Model::Mesh1 + C: "OO",140593628365424,140593526827008 + + ;Material::_9, Model::Mesh1 + C: "OO",140593625783440,140593526827008 +} +;Takes section +;---------------------------------------------------- + +Takes: { + Current: "" +} diff --git a/src/parts source/kOS Cherry Light/cherrytop meshes/materials/Metal_Silver.jpg b/src/parts source/kOS Cherry Light/cherrytop meshes/materials/Metal_Silver.jpg new file mode 100644 index 000000000..855e52db0 Binary files /dev/null and b/src/parts source/kOS Cherry Light/cherrytop meshes/materials/Metal_Silver.jpg differ diff --git a/src/parts source/kOS Cherry Light/cherrytop meshes/materials/dirty aluminum.jpeg b/src/parts source/kOS Cherry Light/cherrytop meshes/materials/dirty aluminum.jpeg new file mode 100644 index 000000000..55058977b Binary files /dev/null and b/src/parts source/kOS Cherry Light/cherrytop meshes/materials/dirty aluminum.jpeg differ diff --git a/src/parts source/kOS Cherry Light/cherrytop meshes/materials/red plastic.jpg b/src/parts source/kOS Cherry Light/cherrytop meshes/materials/red plastic.jpg new file mode 100644 index 000000000..cbcf363df Binary files /dev/null and b/src/parts source/kOS Cherry Light/cherrytop meshes/materials/red plastic.jpg differ diff --git a/src/parts source/kOS Cherry Light/cherrytop meshes/reflector.fbx b/src/parts source/kOS Cherry Light/cherrytop meshes/reflector.fbx new file mode 100644 index 000000000..2bb8fa903 --- /dev/null +++ b/src/parts source/kOS Cherry Light/cherrytop meshes/reflector.fbx @@ -0,0 +1,432 @@ +; FBX 7.3.0 project file +; Copyright (C) 1997-2010 Autodesk Inc. and/or its licensors. +; All rights reserved. +; ---------------------------------------------------- + +FBXHeaderExtension: { + FBXHeaderVersion: 1003 + FBXVersion: 7300 + CreationTimeStamp: { + Version: 1000 + Year: 2016 + Month: 1 + Day: 27 + Hour: 10 + Minute: 0 + Second: 3 + Millisecond: 0 + } + Creator: "FBX SDK/FBX Plugins version 2013.3" + SceneInfo: "SceneInfo::GlobalInfo", "UserData" { + Type: "UserData" + Version: 100 + MetaData: { + Version: 100 + Title: "" + Subject: "" + Author: "" + Keywords: "" + Revision: "" + Comment: "" + } + Properties70: { + P: "DocumentUrl", "KString", "Url", "", "/var/folders/16/csq8fhn9279gfgk7gc955t500000gn/T/com.sketchup.SketchUp.2016.petergoddardjnN9cW.fbx" + P: "SrcDocumentUrl", "KString", "Url", "", "/var/folders/16/csq8fhn9279gfgk7gc955t500000gn/T/com.sketchup.SketchUp.2016.petergoddardjnN9cW.fbx" + P: "Original", "Compound", "", "" + P: "Original|ApplicationVendor", "KString", "", "", "" + P: "Original|ApplicationName", "KString", "", "", "" + P: "Original|ApplicationVersion", "KString", "", "", "" + P: "Original|DateTime_GMT", "DateTime", "", "", "" + P: "Original|FileName", "KString", "", "", "" + P: "LastSaved", "Compound", "", "" + P: "LastSaved|ApplicationVendor", "KString", "", "", "" + P: "LastSaved|ApplicationName", "KString", "", "", "" + P: "LastSaved|ApplicationVersion", "KString", "", "", "" + P: "LastSaved|DateTime_GMT", "DateTime", "", "", "" + } + } +} +GlobalSettings: { + Version: 1000 + Properties70: { + P: "UpAxis", "int", "Integer", "",1 + P: "UpAxisSign", "int", "Integer", "",1 + P: "FrontAxis", "int", "Integer", "",2 + P: "FrontAxisSign", "int", "Integer", "",1 + P: "CoordAxis", "int", "Integer", "",0 + P: "CoordAxisSign", "int", "Integer", "",1 + P: "OriginalUpAxis", "int", "Integer", "",-1 + P: "OriginalUpAxisSign", "int", "Integer", "",1 + P: "UnitScaleFactor", "double", "Number", "",1 + P: "OriginalUnitScaleFactor", "double", "Number", "",1 + P: "AmbientColor", "ColorRGB", "Color", "",0,0,0 + P: "DefaultCamera", "KString", "", "", "Producer Perspective" + P: "TimeMode", "enum", "", "",0 + P: "TimeSpanStart", "KTime", "Time", "",0 + P: "TimeSpanStop", "KTime", "Time", "",46186158000 + P: "CustomFrameRate", "double", "Number", "",-1 + } +} + +; Documents Description +;------------------------------------------------------------------ + +Documents: { + Count: 1 + Document: 140593624681264, "", "Scene" { + Properties70: { + P: "SourceObject", "object", "", "" + P: "ActiveAnimStackName", "KString", "", "", "" + } + RootNode: 0 + } +} + +; Document References +;------------------------------------------------------------------ + +References: { +} + +; Object definitions +;------------------------------------------------------------------ + +Definitions: { + Version: 100 + Count: 6 + ObjectType: "GlobalSettings" { + Count: 1 + } + ObjectType: "Model" { + Count: 3 + PropertyTemplate: "FbxNode" { + Properties70: { + P: "QuaternionInterpolate", "enum", "", "",0 + P: "RotationOffset", "Vector3D", "Vector", "",0,0,0 + P: "RotationPivot", "Vector3D", "Vector", "",0,0,0 + P: "ScalingOffset", "Vector3D", "Vector", "",0,0,0 + P: "ScalingPivot", "Vector3D", "Vector", "",0,0,0 + P: "TranslationActive", "bool", "", "",0 + P: "TranslationMin", "Vector3D", "Vector", "",0,0,0 + P: "TranslationMax", "Vector3D", "Vector", "",0,0,0 + P: "TranslationMinX", "bool", "", "",0 + P: "TranslationMinY", "bool", "", "",0 + P: "TranslationMinZ", "bool", "", "",0 + P: "TranslationMaxX", "bool", "", "",0 + P: "TranslationMaxY", "bool", "", "",0 + P: "TranslationMaxZ", "bool", "", "",0 + P: "RotationOrder", "enum", "", "",0 + P: "RotationSpaceForLimitOnly", "bool", "", "",0 + P: "RotationStiffnessX", "double", "Number", "",0 + P: "RotationStiffnessY", "double", "Number", "",0 + P: "RotationStiffnessZ", "double", "Number", "",0 + P: "AxisLen", "double", "Number", "",10 + P: "PreRotation", "Vector3D", "Vector", "",0,0,0 + P: "PostRotation", "Vector3D", "Vector", "",0,0,0 + P: "RotationActive", "bool", "", "",0 + P: "RotationMin", "Vector3D", "Vector", "",0,0,0 + P: "RotationMax", "Vector3D", "Vector", "",0,0,0 + P: "RotationMinX", "bool", "", "",0 + P: "RotationMinY", "bool", "", "",0 + P: "RotationMinZ", "bool", "", "",0 + P: "RotationMaxX", "bool", "", "",0 + P: "RotationMaxY", "bool", "", "",0 + P: "RotationMaxZ", "bool", "", "",0 + P: "InheritType", "enum", "", "",0 + P: "ScalingActive", "bool", "", "",0 + P: "ScalingMin", "Vector3D", "Vector", "",0,0,0 + P: "ScalingMax", "Vector3D", "Vector", "",1,1,1 + P: "ScalingMinX", "bool", "", "",0 + P: "ScalingMinY", "bool", "", "",0 + P: "ScalingMinZ", "bool", "", "",0 + P: "ScalingMaxX", "bool", "", "",0 + P: "ScalingMaxY", "bool", "", "",0 + P: "ScalingMaxZ", "bool", "", "",0 + P: "GeometricTranslation", "Vector3D", "Vector", "",0,0,0 + P: "GeometricRotation", "Vector3D", "Vector", "",0,0,0 + P: "GeometricScaling", "Vector3D", "Vector", "",1,1,1 + P: "MinDampRangeX", "double", "Number", "",0 + P: "MinDampRangeY", "double", "Number", "",0 + P: "MinDampRangeZ", "double", "Number", "",0 + P: "MaxDampRangeX", "double", "Number", "",0 + P: "MaxDampRangeY", "double", "Number", "",0 + P: "MaxDampRangeZ", "double", "Number", "",0 + P: "MinDampStrengthX", "double", "Number", "",0 + P: "MinDampStrengthY", "double", "Number", "",0 + P: "MinDampStrengthZ", "double", "Number", "",0 + P: "MaxDampStrengthX", "double", "Number", "",0 + P: "MaxDampStrengthY", "double", "Number", "",0 + P: "MaxDampStrengthZ", "double", "Number", "",0 + P: "PreferedAngleX", "double", "Number", "",0 + P: "PreferedAngleY", "double", "Number", "",0 + P: "PreferedAngleZ", "double", "Number", "",0 + P: "LookAtProperty", "object", "", "" + P: "UpVectorProperty", "object", "", "" + P: "Show", "bool", "", "",1 + P: "NegativePercentShapeSupport", "bool", "", "",1 + P: "DefaultAttributeIndex", "int", "Integer", "",-1 + P: "Freeze", "bool", "", "",0 + P: "LODBox", "bool", "", "",0 + P: "Lcl Translation", "Lcl Translation", "", "A",0,0,0 + P: "Lcl Rotation", "Lcl Rotation", "", "A",0,0,0 + P: "Lcl Scaling", "Lcl Scaling", "", "A",1,1,1 + P: "Visibility", "Visibility", "", "A",1 + P: "Visibility Inheritance", "Visibility Inheritance", "", "",1 + } + } + } + ObjectType: "Geometry" { + Count: 1 + PropertyTemplate: "FbxMesh" { + Properties70: { + P: "Color", "ColorRGB", "Color", "",0.8,0.8,0.8 + P: "BBoxMin", "Vector3D", "Vector", "",0,0,0 + P: "BBoxMax", "Vector3D", "Vector", "",0,0,0 + P: "Primary Visibility", "bool", "", "",1 + P: "Casts Shadows", "bool", "", "",1 + P: "Receive Shadows", "bool", "", "",1 + } + } + } + ObjectType: "Material" { + Count: 1 + PropertyTemplate: "FbxSurfacePhong" { + Properties70: { + P: "ShadingModel", "KString", "", "", "Phong" + P: "MultiLayer", "bool", "", "",0 + P: "EmissiveColor", "Color", "", "A",0,0,0 + P: "EmissiveFactor", "Number", "", "A",1 + P: "AmbientColor", "Color", "", "A",0.2,0.2,0.2 + P: "AmbientFactor", "Number", "", "A",1 + P: "DiffuseColor", "Color", "", "A",0.8,0.8,0.8 + P: "DiffuseFactor", "Number", "", "A",1 + P: "Bump", "Vector3D", "Vector", "",0,0,0 + P: "NormalMap", "Vector3D", "Vector", "",0,0,0 + P: "BumpFactor", "double", "Number", "",1 + P: "TransparentColor", "Color", "", "A",0,0,0 + P: "TransparencyFactor", "Number", "", "A",0 + P: "DisplacementColor", "ColorRGB", "Color", "",0,0,0 + P: "DisplacementFactor", "double", "Number", "",1 + P: "VectorDisplacementColor", "ColorRGB", "Color", "",0,0,0 + P: "VectorDisplacementFactor", "double", "Number", "",1 + P: "SpecularColor", "Color", "", "A",0.2,0.2,0.2 + P: "SpecularFactor", "Number", "", "A",1 + P: "ShininessExponent", "Number", "", "A",20 + P: "ReflectionColor", "Color", "", "A",0,0,0 + P: "ReflectionFactor", "Number", "", "A",1 + } + } + } +} + +; Object properties +;------------------------------------------------------------------ + +Objects: { + Geometry: 140593628753696, "Geometry::", "Mesh" { + Vertices: *2586 { + a: -0.00159129557805545,0.152388005302283,0.0155730154605699,-0.00632320810959149,0.145110395561536,0.0293534548542012,-0.00632320810959172,0.15293558442695,0.0300847556531268,-0.00159129557805525,0.148337389482496,0.0151944663116486,-0.00632320810959172,0.15293558442695,0.0300847556531268,-0.00632320810959149,0.145110395561536,0.0293534548542012,-0.00159129557805545,0.152388005302283,0.0155730154605699,-0.00159129557805525,0.148337389482496,0.0151944663116486,-0.0138505939094924,0.142339313059757,0.0415120539573175,-0.0138505939094924,0.153405801281358,0.0425462694653325,-0.0138505939094924,0.153405801281358,0.0425462694653325,-0.0138505939094924,0.142339313059757,0.0415120539573175,-0.0236604740750876,0.153766611363948,0.0521083253245109,-0.0236604740750876,0.140212986670227,0.0508416751851554,-0.0236604740750876,0.140212986670227,0.0508416751851554,-0.0236604740750876,0.153766611363948,0.0521083253245109,-0.0350843214846853,0.153993426063857,0.0581192849259028,-0.0350843214846855,0.138876322022469,0.0567065202689658,-0.0350843214846855,0.138876322022469,0.0567065202689658,-0.0350843214846853,0.153993426063857,0.0581192849259028,-0.0473436198161224,0.154070788334118,0.0601695113062537,-0.0473436198161225,0.138420410603288,0.058706909708402,-0.0473436198161225,0.138420410603288,0.058706909708402,-0.0473436198161224,0.154070788334118,0.0601695113062537,2.2671665947323e-05,0.151800380519783,-0,-0.0015912955780552,0.156398575464238,0.0148902893414786,-0.0015912955780552,0.156398575464238,0.0148902893414786,2.2671665947323e-05,0.151800380519783,-0,-0.00632320810959149,0.160683411022105,0.0287658300717016,-0.00632320810959149,0.160683411022105,0.0287658300717016,-0.0138505939094923,0.164362882731141,0.0406810270203202,-0.0138505939094923,0.164362882731141,0.0406810270203202,-0.0236604740750876,0.167186240674989,0.0498238792060799,-0.0236604740750876,0.167186240674989,0.0498238792060799,-0.0350843214846852,0.168961077675596,0.0555713163617988,-0.0350843214846852,0.168961077675596,0.0555713163617988,-0.0473436198161225,0.169566441524427,0.0575316601434032, +-0.0473436198161225,0.169566441524427,0.0575316601434032,2.2671665947323e-05,0.151800380519783,-0,-0.00159129557805527,0.160095786239606,0.0131928146111317,-0.00159129557805527,0.160095786239606,0.0131928146111317,2.2671665947323e-05,0.151800380519783,-0,-0.00632320810959158,0.167825873768429,0.025486560708672,-0.00632320810959158,0.167825873768429,0.025486560708672,-0.0138505939094923,0.174463850415736,0.0360434398124487,-0.0138505939094923,0.174463850415736,0.0360434398124487,-0.0236604740750873,0.179557349042789,0.0441440180576081,-0.0236604740750873,0.179557349042789,0.0441440180576081,-0.0350843214846853,0.182759256135559,0.0492362544235808,-0.0350843214846853,0.182759256135559,0.0492362544235808,-0.0473436198161224,0.183851367017074,0.0509731214173436,-0.0473436198161224,0.183851367017074,0.0509731214173436,-0.00159129557805532,0.166690669861262,-0.00459819494445506,2.2671665947323e-05,0.151800380519783,-0,-0.00159129557805545,0.167373395980353,-0.000587624782499185,-0.00159129557805545,0.167373395980353,-0.000587624782499185,2.2671665947323e-05,0.151800380519783,-0,-0.00159129557805532,0.166690669861262,-0.00459819494445506,2.2671665947323e-05,0.151800380519783,-0,-0.00159129557805527,0.163227678823974,0.0105962713671934,-0.00159129557805527,0.163227678823974,0.0105962713671934,2.2671665947323e-05,0.151800380519783,-0,-0.00632320810959113,0.173876225633237,0.0204704243518791,-0.00632320810959113,0.173876225633237,0.0204704243518791,-0.0138505939094918,0.183020340080078,0.0289495517459599,-0.0138505939094918,0.183020340080078,0.0289495517459599,-0.0236604740750875,0.190036865876306,0.0354558150299495,-0.0236604740750875,0.190036865876306,0.0354558150299495,-0.0350843214846856,0.194447638384268,0.0395458231131529,-0.0350843214846856,0.194447638384268,0.0395458231131529,-0.0473436198161226,0.195952070746691,0.0409408487037579,-0.0473436198161226,0.195952070746691,0.0409408487037579,2.2671665947323e-05,0.151800380519783,-0,-0.00159129557805505,0.165580819913415,0.00727760974074743,-0.00159129557805505,0.165580819913415,0.00727760974074743, +2.2671665947323e-05,0.151800380519783,-0,-0.00632320810959147,0.178422145135622,0.0140592624044813,-0.00632320810959147,0.178422145135622,0.0140592624044813,-0.0138505939094925,0.189449241093807,0.0198827995693796,-0.0138505939094925,0.189449241093807,0.0198827995693796,-0.0236604740750874,0.197910629421556,0.0243513568015046,-0.0236604740750874,0.197910629421556,0.0243513568015046,-0.0350843214846858,0.203229680487438,0.027160409310127,-0.0350843214846858,0.203229680487438,0.027160409310127,-0.0473436198161228,0.205043909751461,0.0281185248089626,-0.0473436198161228,0.205043909751461,0.0281185248089626,2.2671665947323e-05,0.151800380519783,-0,-0.00159129557805529,0.166994846831432,0.0034629910372879,-0.00159129557805529,0.166994846831432,0.0034629910372879,2.2671665947323e-05,0.151800380519783,-0,-0.0063232081095914,0.181153835373984,0.00668998495824824,-0.0063232081095914,0.181153835373984,0.00668998495824824,-0.0138505939094926,0.193312434477101,0.00946106746002642,-0.0138505939094926,0.193312434477101,0.00946106746002642,-0.0236604740750874,0.202642055704939,0.0115873938495571,-0.0236604740750874,0.202642055704939,0.0115873938495571,-0.0350843214846855,0.208506900788749,0.0129240584973143,-0.0350843214846855,0.208506900788749,0.0129240584973143,-0.0473436198161227,0.210507290228185,0.0133799699164958,-0.0473436198161227,0.210507290228185,0.0133799699164958,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,-0.00632320810959149,0.18188513617291,-0.00113520390716716,-0.00632320810959149,0.18188513617291,-0.00113520390716716,-0.0138505939094922,0.194346649985116,-0.00160542076157459,-0.0236604740750876,0.203908705844294,-0.00196623084416425,-0.0236604740750876,0.203908705844294,-0.00196623084416425,-0.0138505939094922,0.194346649985116,-0.00160542076157459,-0.0350843214846853,0.209919665445686,-0.00219304554407414,-0.0350843214846853,0.209919665445686,-0.00219304554407414,-0.0473436198161226,0.211969891826038,-0.00227040781433432,-0.0473436198161226,0.211969891826038,-0.00227040781433432, +-0.00632320810959149,0.180566210591485,-0.00888303050232202,-0.00632320810959149,0.180566210591485,-0.00888303050232202,-0.0138505939094922,0.192481407540104,-0.0125625022113576,-0.0138505939094922,0.192481407540104,-0.0125625022113576,-0.0236604740750875,0.201624259725863,-0.0153858601552059,-0.0236604740750875,0.201624259725863,-0.0153858601552059,-0.0350843214846858,0.207371696881582,-0.0171606971558127,-0.0350843214846858,0.207371696881582,-0.0171606971558127,-0.0473436198161227,0.209332040663187,-0.017766061004644,-0.0473436198161227,0.209332040663187,-0.017766061004644,-0.00159129557805538,0.164993195130915,-0.00829540571982265,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,-0.00159129557805538,0.164993195130915,-0.00829540571982265,-0.00632320810959144,0.177286941228455,-0.0160254932486455,-0.00632320810959144,0.177286941228455,-0.0160254932486455,-0.0138505939094923,0.187843820332232,-0.0226634698959529,-0.0138505939094923,0.187843820332232,-0.0226634698959529,-0.0236604740750874,0.195944398577392,-0.0277569685230061,-0.0236604740750874,0.195944398577392,-0.0277569685230061,-0.0350843214846852,0.201036634943364,-0.0309588756157758,-0.0350843214846852,0.201036634943364,-0.0309588756157758,-0.0473436198161225,0.202773501937127,-0.0320509864972911,-0.0473436198161225,0.202773501937127,-0.0320509864972911,-0.00159129557805525,0.162396651886977,-0.0114272983041905,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,-0.00159129557805525,0.162396651886977,-0.0114272983041905,-0.00632320810959149,0.172270804871662,-0.0220758451134537,-0.00632320810959149,0.172270804871662,-0.0220758451134537,-0.0138505939094924,0.180749932265743,-0.0312199595602942,-0.0138505939094924,0.180749932265743,-0.0312199595602942,-0.0236604740750875,0.187256195549733,-0.038236485356523,-0.0236604740750875,0.187256195549733,-0.038236485356523,-0.0350843214846855,0.191346203632937,-0.0426472578644845,-0.0350843214846855,0.191346203632937,-0.0426472578644845,-0.0473436198161224,0.192741229223541,-0.0441516902269075, +-0.0473436198161224,0.192741229223541,-0.0441516902269075,-0.00159129557805536,0.159077990260531,-0.0137804393936309,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,-0.00159129557805536,0.159077990260531,-0.0137804393936309,-0.00632320810959117,0.165859642924265,-0.0266217646158389,-0.00632320810959117,0.165859642924265,-0.0266217646158389,-0.0138505939094922,0.171683180089163,-0.0376488605740236,-0.0138505939094922,0.171683180089163,-0.0376488605740236,-0.0236604740750876,0.176151737321288,-0.0461102489017724,-0.0236604740750876,0.176151737321288,-0.0461102489017724,-0.0350843214846852,0.17896078982991,-0.0514292999676547,-0.0350843214846852,0.17896078982991,-0.0514292999676547,-0.0473436198161225,0.179918905328746,-0.0532435292316781,-0.0473436198161225,0.179918905328746,-0.0532435292316781,-0.00159129557805516,0.155263371557071,-0.0151944663116485,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,-0.00159129557805516,0.155263371557071,-0.0151944663116485,-0.00632320810959124,0.158490365478032,-0.0293534548542008,-0.00632320810959124,0.158490365478032,-0.0293534548542008,-0.0138505939094924,0.16126144797981,-0.0415120539573173,-0.0138505939094924,0.16126144797981,-0.0415120539573173,-0.0236604740750876,0.16338777436934,-0.0508416751851554,-0.0236604740750876,0.16338777436934,-0.0508416751851554,-0.0350843214846854,0.164724439017098,-0.056706520268966,-0.0350843214846854,0.164724439017098,-0.056706520268966,-0.0473436198161225,0.165180350436279,-0.058706909708402,-0.0473436198161225,0.165180350436279,-0.058706909708402,0.0473889631480167,0.154070788334118,-0.0601695113062539,0.0351296648165796,0.168961077675596,-0.0555713163617986,0.0351296648165797,0.153993426063857,-0.0581192849259026,0.0473889631480169,0.169566441524427,-0.0575316601434032,0.0351296648165797,0.153993426063857,-0.0581192849259026,0.0351296648165796,0.168961077675596,-0.0555713163617986,0.0473889631480167,0.154070788334118,-0.0601695113062539,0.0473889631480169,0.169566441524427,-0.0575316601434032, +0.0351296648165799,0.191346203632937,0.0426472578644845,0.0473889631480168,0.179918905328746,0.0532435292316779,0.0351296648165797,0.17896078982991,0.0514292999676549,0.0473889631480168,0.192741229223541,0.0441516902269075,0.0351296648165797,0.17896078982991,0.0514292999676549,0.0473889631480168,0.179918905328746,0.0532435292316779,0.0351296648165799,0.191346203632937,0.0426472578644845,0.0473889631480168,0.192741229223541,0.0441516902269075,2.2671665947323e-05,0.151800380519783,-0,0.00163663890995005,0.147202185575328,0.0148902893414786,0.00163663890995019,0.143504974799961,0.0131928146111317,0.00163663890995019,0.143504974799961,0.0131928146111317,0.00163663890995005,0.147202185575328,0.0148902893414786,2.2671665947323e-05,0.151800380519783,-0,0.0138959372413867,0.12913691062383,0.0360434398124487,0.00636855144148627,0.142917350017461,0.0287658300717016,0.0138959372413866,0.139237878308426,0.0406810270203202,0.00636855144148623,0.135774887271138,0.025486560708672,0.0138959372413866,0.139237878308426,0.0406810270203202,0.00636855144148627,0.142917350017461,0.0287658300717016,0.0138959372413867,0.12913691062383,0.0360434398124487,0.00636855144148623,0.135774887271138,0.025486560708672,0.00163663890994992,0.136227365059213,-0.000587624782499185,2.2671665947323e-05,0.151800380519783,-0,0.00163663890995014,0.136605914208135,0.0034629910372879,0.00163663890995014,0.136605914208135,0.0034629910372879,2.2671665947323e-05,0.151800380519783,-0,0.00163663890994992,0.136227365059213,-0.000587624782499185,0.0138959372413864,0.164362882731141,-0.0406810270203202,0.0237058174069816,0.179557349042789,-0.0441440180576081,0.0138959372413865,0.174463850415736,-0.0360434398124489,0.0237058174069819,0.167186240674989,-0.0498238792060798,0.0138959372413865,0.174463850415736,-0.0360434398124489,0.0237058174069816,0.179557349042789,-0.0441440180576081,0.0138959372413864,0.164362882731141,-0.0406810270203202,0.0237058174069819,0.167186240674989,-0.0498238792060798,0.00636855144148623,0.121715624866656,-0.00113520390716716,0.00636855144148629,0.122446925665582,0.00668998495824824, +0.00636855144148629,0.122446925665582,0.00668998495824824,0.00636855144148623,0.121715624866656,-0.00113520390716716,0.0138959372413867,0.109254111054451,-0.00160542076157459,0.0138959372413867,0.110288326562466,0.00946106746002642,0.0138959372413867,0.110288326562466,0.00946106746002642,0.0138959372413867,0.109254111054451,-0.00160542076157459,2.2671665947323e-05,0.151800380519783,-0,0.00163663890995005,0.138019941126152,0.00727760974074743,0.00163663890995005,0.138019941126152,0.00727760974074743,2.2671665947323e-05,0.151800380519783,-0,0.00636855144148627,0.125178615903944,0.0140592624044813,0.00636855144148627,0.125178615903944,0.0140592624044813,0.0138959372413867,0.11415151994576,0.0198827995693796,0.0138959372413867,0.11415151994576,0.0198827995693796,0.0237058174069818,0.100958705334628,0.0115873938495571,0.0237058174069819,0.105690131618011,0.0243513568015046,0.0237058174069819,0.105690131618011,0.0243513568015046,0.0237058174069818,0.100958705334628,0.0115873938495571,0.0351296648165797,0.0950938602508174,0.0129240584973143,0.0351296648165797,0.100371080552129,0.027160409310127,0.0351296648165797,0.0950938602508174,0.0129240584973143,0.0351296648165797,0.100371080552129,0.027160409310127,0.0473889631480168,0.0985568512881054,0.0281185248089626,0.0473889631480167,0.0930934708113814,0.0133799699164958,0.0473889631480168,0.0985568512881054,0.0281185248089626,0.0473889631480167,0.0930934708113814,0.0133799699164958,0.00163663890994996,0.140373082215593,0.0105962713671934,0.00636855144148618,0.12972453540633,0.0204704243518791,0.00636855144148618,0.12972453540633,0.0204704243518791,0.00163663890994996,0.140373082215593,0.0105962713671934,0.0138959372413867,0.120580420959489,0.0289495517459599,0.0138959372413867,0.120580420959489,0.0289495517459599,0.0237058174069819,0.11356389516326,0.0354558150299495,0.0237058174069819,0.11356389516326,0.0354558150299495,0.0351296648165797,0.109153122655299,0.0395458231131529,0.0351296648165797,0.109153122655299,0.0395458231131529,0.0473889631480166,0.107648690292876,0.0409408487037579, +0.0473889631480166,0.107648690292876,0.0409408487037579,0.0237058174069817,0.124043411996777,0.0441440180576081,0.0351296648165797,0.134639683363971,0.0555713163617988,0.0351296648165796,0.120841504904007,0.0492362544235808,0.0237058174069817,0.136414520364577,0.0498238792060799,0.0351296648165796,0.120841504904007,0.0492362544235808,0.0351296648165797,0.134639683363971,0.0555713163617988,0.0237058174069817,0.124043411996777,0.0441440180576081,0.0237058174069817,0.136414520364577,0.0498238792060799,0.0473889631480167,0.134034319515139,0.0575316601434032,0.0473889631480168,0.119749394022492,0.0509731214173436,0.0473889631480168,0.119749394022492,0.0509731214173436,0.0473889631480167,0.134034319515139,0.0575316601434032,0.00163663890995005,0.152388005302283,-0.0155730154605699,0.00636855144148645,0.160683411022106,-0.0287658300717016,0.00163663890995014,0.156398575464239,-0.0148902893414782,0.00636855144148618,0.15293558442695,-0.0300847556531268,0.00163663890995014,0.156398575464239,-0.0148902893414782,0.00636855144148645,0.160683411022106,-0.0287658300717016,0.00163663890995005,0.152388005302283,-0.0155730154605699,0.00636855144148618,0.15293558442695,-0.0300847556531268,0.00636855144148616,0.145110395561535,-0.0293534548542008,0.00163663890995005,0.148337389482496,-0.0151944663116485,0.00163663890995005,0.148337389482496,-0.0151944663116485,0.00636855144148616,0.145110395561535,-0.0293534548542008,0.0237058174069821,0.153766611363948,-0.0521083253245107,0.0138959372413868,0.142339313059757,-0.0415120539573173,0.023705817406982,0.140212986670226,-0.0508416751851554,0.0138959372413867,0.153405801281358,-0.0425462694653327,0.023705817406982,0.140212986670226,-0.0508416751851554,0.0138959372413868,0.142339313059757,-0.0415120539573173,0.0237058174069821,0.153766611363948,-0.0521083253245107,0.0138959372413867,0.153405801281358,-0.0425462694653327,0.03512966481658,0.138876322022469,-0.056706520268966,0.0473889631480167,0.138420410603287,-0.058706909708402,0.0473889631480167,0.138420410603287,-0.058706909708402,0.03512966481658,0.138876322022469,-0.056706520268966, +0.0351296648165801,0.0962290641579851,-0.0171606971558127,0.0473889631480165,0.10082725910244,-0.0320509864972911,0.0351296648165796,0.102564126096203,-0.0309588756157758,0.0473889631480169,0.0942687203763802,-0.017766061004644,0.0351296648165796,0.102564126096203,-0.0309588756157758,0.0473889631480165,0.10082725910244,-0.0320509864972911,0.0351296648165801,0.0962290641579851,-0.0171606971558127,0.0473889631480169,0.0942687203763802,-0.017766061004644,0.0237058174069817,0.190036865876306,-0.0354558150299495,0.0138959372413866,0.183020340080077,-0.0289495517459595,0.0138959372413866,0.183020340080077,-0.0289495517459595,0.0237058174069817,0.190036865876306,-0.0354558150299495,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,0.00636855144148618,0.167825873768429,-0.0254865607086716,0.00636855144148618,0.167825873768429,-0.0254865607086716,0.047388963148017,0.202773501937127,0.0320509864972911,0.0351296648165797,0.201036634943364,0.0309588756157758,0.0351296648165797,0.201036634943364,0.0309588756157758,0.047388963148017,0.202773501937127,0.0320509864972911,0.0473889631480165,0.183851367017074,-0.0509731214173436,0.0351296648165799,0.194447638384268,-0.0395458231131529,0.0351296648165798,0.182759256135559,-0.0492362544235806,0.0473889631480166,0.195952070746691,-0.0409408487037579,0.0351296648165798,0.182759256135559,-0.0492362544235806,0.0351296648165799,0.194447638384268,-0.0395458231131529,0.0473889631480165,0.183851367017074,-0.0509731214173436,0.0473889631480166,0.195952070746691,-0.0409408487037579,0.00163663890994999,0.160095786239606,-0.0131928146111317,0.00163663890994999,0.160095786239606,-0.0131928146111317,0.00163663890994996,0.159077990260531,0.0137804393936313,0.00636855144148623,0.172270804871662,0.0220758451134537,0.00636855144148645,0.165859642924265,0.0266217646158389, +0.00163663890994996,0.162396651886977,0.0114272983041907,0.00636855144148645,0.165859642924265,0.0266217646158389,0.00636855144148623,0.172270804871662,0.0220758451134537,0.00163663890994996,0.159077990260531,0.0137804393936313,0.00163663890994996,0.162396651886977,0.0114272983041907,0.0237058174069819,0.195944398577392,0.0277569685230063,0.0237058174069818,0.187256195549733,0.0382364853565232,0.0237058174069818,0.187256195549733,0.0382364853565232,0.0237058174069819,0.195944398577392,0.0277569685230063,0.00636855144148636,0.126313819811112,-0.0160254932486455,0.00163663890995019,0.14120410915259,-0.0114272983041905,0.00163663890995001,0.138607565908652,-0.00829540571982265,0.00636855144148641,0.131329956167905,-0.0220758451134537,0.00163663890995001,0.138607565908652,-0.00829540571982265,0.00163663890995019,0.14120410915259,-0.0114272983041905,0.00636855144148636,0.126313819811112,-0.0160254932486455,0.00636855144148641,0.131329956167905,-0.0220758451134537,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,0.00636855144148627,0.123034550448082,-0.00888303050232202,0.00163663890994996,0.136910091178305,-0.00459819494445506,0.00163663890994996,0.136910091178305,-0.00459819494445506,0.00636855144148627,0.123034550448082,-0.00888303050232202,0.0138959372413868,0.111119353499463,-0.0125625022113576,0.0138959372413867,0.115756940707334,-0.0226634698959529,0.0138959372413868,0.111119353499463,-0.0125625022113576,0.0138959372413867,0.115756940707334,-0.0226634698959529,0.0237058174069819,0.101976501313703,-0.0153858601552059,0.023705817406982,0.107656362462175,-0.0277569685230061,0.0237058174069819,0.101976501313703,-0.0153858601552059,0.023705817406982,0.107656362462175,-0.0277569685230061,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,0.00163663890995012,0.166994846831432,-0.0034629910372879,0.00163663890995003,0.167373395980353,0.000587624782499546,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,0.00163663890995003,0.167373395980353,0.000587624782499546, +0.00163663890995012,0.166994846831432,-0.0034629910372879,0.0138959372413865,0.180749932265743,0.0312199595602942,0.0138959372413869,0.171683180089163,0.0376488605740236,0.0138959372413869,0.171683180089163,0.0376488605740236,0.0138959372413865,0.180749932265743,0.0312199595602942,0.0237058174069818,0.176151737321288,0.0461102489017724,0.0237058174069818,0.176151737321288,0.0461102489017724,0.00163663890995005,0.163227678823974,-0.0105962713671934,0.00163663890995012,0.165580819913414,-0.00727760974074707,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,0.00163663890995012,0.165580819913414,-0.00727760974074707,0.00163663890995005,0.163227678823974,-0.0105962713671934,0.00636855144148609,0.178422145135622,-0.0140592624044813,0.00636855144148643,0.173876225633237,-0.0204704243518788,0.00636855144148609,0.178422145135622,-0.0140592624044813,0.00636855144148643,0.173876225633237,-0.0204704243518788,0.0138959372413869,0.189449241093807,-0.0198827995693796,0.0138959372413869,0.189449241093807,-0.0198827995693796,0.0237058174069818,0.197910629421556,-0.0243513568015046,0.0237058174069818,0.197910629421556,-0.0243513568015046,0.0351296648165796,0.203229680487438,-0.0271604093101267,0.0351296648165796,0.203229680487438,-0.0271604093101267,0.0473889631480167,0.205043909751461,-0.0281185248089626,0.0473889631480167,0.205043909751461,-0.0281185248089626,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,0.00636855144148636,0.181153835373984,-0.00668998495824788,0.00636855144148636,0.181153835373984,-0.00668998495824788,0.0138959372413868,0.193312434477101,-0.00946106746002606,0.0138959372413868,0.193312434477101,-0.00946106746002606,0.0237058174069818,0.202642055704939,-0.0115873938495568,0.0237058174069818,0.202642055704939,-0.0115873938495568,0.0351296648165795,0.208506900788749,-0.012924058497314,0.0351296648165795,0.208506900788749,-0.012924058497314,0.0473889631480168,0.210507290228185,-0.0133799699164958,0.0473889631480168,0.210507290228185,-0.0133799699164958, +2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,0.00636855144148614,0.18188513617291,0.00113520390716734,0.00636855144148614,0.18188513617291,0.00113520390716734,0.0138959372413868,0.194346649985116,0.00160542076157495,0.0138959372413868,0.194346649985116,0.00160542076157495,0.0237058174069819,0.203908705844294,0.00196623084416461,0.0237058174069819,0.203908705844294,0.00196623084416461,0.0351296648165799,0.209919665445686,0.00219304554407414,0.0351296648165799,0.209919665445686,0.00219304554407414,0.0473889631480168,0.211969891826037,0.00227040781433468,0.0473889631480168,0.211969891826037,0.00227040781433468,2.2671665947323e-05,0.151800380519783,-0,0.00163663890994992,0.166690669861262,0.00459819494445524,0.00163663890994992,0.166690669861262,0.00459819494445524,2.2671665947323e-05,0.151800380519783,-0,0.00636855144148625,0.180566210591485,0.00888303050232202,0.00636855144148625,0.180566210591485,0.00888303050232202,0.0138959372413866,0.192481407540104,0.0125625022113576,0.0138959372413866,0.192481407540104,0.0125625022113576,0.0237058174069817,0.201624259725863,0.0153858601552059,0.0237058174069817,0.201624259725863,0.0153858601552059,0.0351296648165797,0.207371696881582,0.0171606971558129,0.0351296648165797,0.207371696881582,0.0171606971558129,0.0473889631480167,0.209332040663187,0.017766061004644,0.0473889631480167,0.209332040663187,0.017766061004644,2.2671665947323e-05,0.151800380519783,-0,0.00163663890995005,0.164993195130915,0.00829540571982283,0.00163663890995005,0.164993195130915,0.00829540571982283,2.2671665947323e-05,0.151800380519783,-0,0.00636855144148623,0.177286941228455,0.0160254932486455,0.00636855144148623,0.177286941228455,0.0160254932486455,0.0138959372413867,0.187843820332232,0.0226634698959533,0.0138959372413867,0.187843820332232,0.0226634698959533,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,0.0138959372413867,0.122850828773823,-0.0312199595602942,0.0138959372413867,0.122850828773823,-0.0312199595602942,0.0237058174069817,0.116344565489833,-0.038236485356523, +0.0237058174069817,0.116344565489833,-0.038236485356523,0.0351296648165796,0.11225455740663,-0.0426472578644845,0.0351296648165796,0.11225455740663,-0.0426472578644845,0.0473889631480168,0.110859531816025,-0.0441516902269075,0.0473889631480168,0.110859531816025,-0.0441516902269075,0.00163663890995003,0.144522770779036,-0.0137804393936309,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,0.00163663890995003,0.144522770779036,-0.0137804393936309,0.00636855144148634,0.137741118115302,-0.0266217646158389,0.00636855144148634,0.137741118115302,-0.0266217646158389,0.0138959372413868,0.131917580950404,-0.0376488605740236,0.0138959372413868,0.131917580950404,-0.0376488605740236,0.0237058174069818,0.127449023718279,-0.0461102489017724,0.0237058174069818,0.127449023718279,-0.0461102489017724,0.0351296648165796,0.124639971209656,-0.0514292999676547,0.0351296648165796,0.124639971209656,-0.0514292999676547,0.0473889631480169,0.123681855710821,-0.0532435292316781,0.0473889631480169,0.123681855710821,-0.0532435292316781,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,0.00163663890995003,0.151212755737284,0.0155730154605699,0.00636855144148623,0.158490365478031,0.0293534548542012,0.00636855144148634,0.150665176612616,0.0300847556531268,0.00163663890995019,0.155263371557071,0.0151944663116486,0.00636855144148634,0.150665176612616,0.0300847556531268,0.00636855144148623,0.158490365478031,0.0293534548542012,0.00163663890995003,0.151212755737284,0.0155730154605699,0.00163663890995019,0.155263371557071,0.0151944663116486,0.0138959372413866,0.161261447979809,0.0415120539573175,0.0138959372413865,0.150194959758208,0.0425462694653325,0.0138959372413865,0.150194959758208,0.0425462694653325,0.0138959372413866,0.161261447979809,0.0415120539573175,0.0237058174069819,0.16338777436934,0.0508416751851554,0.023705817406982,0.149834149675619,0.0521083253245109,0.023705817406982,0.149834149675619,0.0521083253245109,0.0237058174069819,0.16338777436934,0.0508416751851554,0.0351296648165797,0.164724439017097,0.0567065202689658, +0.0351296648165794,0.149607334975709,0.0581192849259028,0.0351296648165794,0.149607334975709,0.0581192849259028,0.0351296648165797,0.164724439017097,0.0567065202689658,0.0473889631480169,0.165180350436279,0.058706909708402,0.0473889631480167,0.149529972705449,0.0601695113062537,0.0473889631480167,0.149529972705449,0.0601695113062537,0.0473889631480169,0.165180350436279,0.058706909708402,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,0.0237058174069819,0.0996920551952725,-0.00196623084416425,0.0237058174069819,0.0996920551952725,-0.00196623084416425,0.0351296648165798,0.0936810955938806,-0.00219304554407414,0.0351296648165798,0.0936810955938806,-0.00219304554407414,0.0473889631480167,0.0916308692135295,-0.00227040781433432,0.0473889631480167,0.0916308692135295,-0.00227040781433432,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,-0.00159129557805536,0.151212755737284,-0.0155730154605699,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,-0.00159129557805536,0.151212755737284,-0.0155730154605699,-0.00632320810959126,0.150665176612616,-0.0300847556531268,-0.00632320810959126,0.150665176612616,-0.0300847556531268,-0.0138505939094919,0.150194959758209,-0.0425462694653327,-0.0138505939094919,0.150194959758209,-0.0425462694653327,-0.0236604740750874,0.149834149675619,-0.0521083253245107,-0.0236604740750874,0.149834149675619,-0.0521083253245107,-0.0350843214846854,0.149607334975709,-0.0581192849259026,-0.0350843214846854,0.149607334975709,-0.0581192849259026,-0.0473436198161225,0.149529972705449,-0.0601695113062539,-0.0473436198161225,0.149529972705449,-0.0601695113062539,-0.00159129557805514,0.147202185575328,-0.0148902893414782,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0, +-0.00159129557805514,0.147202185575328,-0.0148902893414782,-0.00632320810959144,0.142917350017462,-0.0287658300717016,-0.00632320810959144,0.142917350017462,-0.0287658300717016,-0.0138505939094923,0.139237878308426,-0.0406810270203202,-0.0138505939094923,0.139237878308426,-0.0406810270203202,-0.0236604740750873,0.136414520364577,-0.0498238792060798,-0.0236604740750873,0.136414520364577,-0.0498238792060798,-0.0350843214846849,0.134639683363971,-0.0555713163617986,-0.0350843214846849,0.134639683363971,-0.0555713163617986,-0.0473436198161225,0.134034319515139,-0.0575316601434032,-0.0473436198161225,0.134034319515139,-0.0575316601434032,-0.00159129557805543,0.143504974799961,-0.0131928146111317,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,-0.00159129557805543,0.143504974799961,-0.0131928146111317,-0.00632320810959144,0.135774887271138,-0.0254865607086716,-0.00632320810959144,0.135774887271138,-0.0254865607086716,-0.013850593909492,0.12913691062383,-0.0360434398124489,-0.013850593909492,0.12913691062383,-0.0360434398124489,-0.0236604740750876,0.124043411996777,-0.0441440180576081,-0.0236604740750876,0.124043411996777,-0.0441440180576081,-0.0350843214846854,0.120841504904008,-0.0492362544235806,-0.0350843214846854,0.120841504904008,-0.0492362544235806,-0.0473436198161225,0.119749394022492,-0.0509731214173436,-0.0473436198161225,0.119749394022492,-0.0509731214173436,-0.00159129557805527,0.140373082215593,-0.0105962713671934,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,-0.00159129557805527,0.140373082215593,-0.0105962713671934,-0.00632320810959108,0.12972453540633,-0.0204704243518788,-0.00632320810959108,0.12972453540633,-0.0204704243518788,-0.0138505939094922,0.120580420959489,-0.0289495517459595,-0.0138505939094922,0.120580420959489,-0.0289495517459595,-0.0236604740750878,0.11356389516326,-0.0354558150299495,-0.0236604740750878,0.11356389516326,-0.0354558150299495,-0.0350843214846853,0.109153122655299,-0.0395458231131529,-0.0350843214846853,0.109153122655299,-0.0395458231131529, +-0.0473436198161226,0.107648690292876,-0.0409408487037579,-0.0473436198161226,0.107648690292876,-0.0409408487037579,-0.00159129557805541,0.138019941126152,-0.00727760974074707,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,-0.00159129557805541,0.138019941126152,-0.00727760974074707,-0.00632320810959149,0.125178615903944,-0.0140592624044813,-0.00632320810959149,0.125178615903944,-0.0140592624044813,-0.013850593909492,0.11415151994576,-0.0198827995693796,-0.013850593909492,0.11415151994576,-0.0198827995693796,-0.0236604740750875,0.105690131618011,-0.0243513568015046,-0.0236604740750875,0.105690131618011,-0.0243513568015046,-0.0350843214846852,0.100371080552129,-0.0271604093101267,-0.0350843214846852,0.100371080552129,-0.0271604093101267,-0.0473436198161225,0.0985568512881056,-0.0281185248089626,-0.0473436198161225,0.0985568512881056,-0.0281185248089626,-0.00159129557805532,0.136605914208135,-0.0034629910372879,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,-0.00159129557805532,0.136605914208135,-0.0034629910372879,-0.00632320810959158,0.122446925665582,-0.00668998495824788,-0.00632320810959158,0.122446925665582,-0.00668998495824788,-0.0138505939094922,0.110288326562466,-0.00946106746002606,-0.0138505939094922,0.110288326562466,-0.00946106746002606,-0.0236604740750877,0.100958705334628,-0.0115873938495568,-0.0236604740750877,0.100958705334628,-0.0115873938495568,-0.0350843214846854,0.0950938602508172,-0.012924058497314,-0.0350843214846854,0.0950938602508172,-0.012924058497314,-0.0473436198161223,0.0930934708113813,-0.0133799699164958,-0.0473436198161223,0.0930934708113813,-0.0133799699164958,-0.00159129557805527,0.136227365059213,0.000587624782499546,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,-0.00159129557805527,0.136227365059213,0.000587624782499546,-0.0063232081095914,0.121715624866656,0.00113520390716734,-0.0063232081095914,0.121715624866656,0.00113520390716734,-0.0138505939094922,0.109254111054451,0.00160542076157495, +-0.0138505939094922,0.109254111054451,0.00160542076157495,-0.0236604740750874,0.0996920551952722,0.00196623084416461,-0.0236604740750874,0.0996920551952722,0.00196623084416461,-0.0350843214846854,0.0936810955938806,0.00219304554407414,-0.0350843214846854,0.0936810955938806,0.00219304554407414,-0.0473436198161229,0.0916308692135296,0.00227040781433468,-0.0473436198161229,0.0916308692135296,0.00227040781433468,2.2671665947323e-05,0.151800380519783,-0,-0.00159129557805532,0.136910091178305,0.00459819494445524,-0.00159129557805532,0.136910091178305,0.00459819494445524,2.2671665947323e-05,0.151800380519783,-0,-0.0063232081095912,0.123034550448082,0.00888303050232202,-0.0063232081095912,0.123034550448082,0.00888303050232202,-0.0138505939094923,0.111119353499463,0.0125625022113576,-0.0138505939094923,0.111119353499463,0.0125625022113576,-0.0236604740750873,0.101976501313704,0.0153858601552059,-0.0236604740750873,0.101976501313704,0.0153858601552059,-0.0350843214846854,0.0962290641579847,0.0171606971558129,-0.0350843214846854,0.0962290641579847,0.0171606971558129,-0.0473436198161224,0.0942687203763799,0.017766061004644,-0.0473436198161224,0.0942687203763799,0.017766061004644,2.2671665947323e-05,0.151800380519783,-0,-0.00159129557805525,0.138607565908652,0.00829540571982283,-0.00159129557805525,0.138607565908652,0.00829540571982283,2.2671665947323e-05,0.151800380519783,-0,-0.00632320810959144,0.126313819811112,0.0160254932486455,-0.00632320810959144,0.126313819811112,0.0160254932486455,-0.0138505939094923,0.115756940707334,0.0226634698959533,-0.0138505939094923,0.115756940707334,0.0226634698959533,-0.0236604740750873,0.107656362462175,0.0277569685230063,-0.0236604740750873,0.107656362462175,0.0277569685230063,-0.0350843214846853,0.102564126096203,0.0309588756157758,-0.0350843214846853,0.102564126096203,0.0309588756157758,-0.0473436198161225,0.10082725910244,0.0320509864972911,-0.0473436198161225,0.10082725910244,0.0320509864972911,2.2671665947323e-05,0.151800380519783,-0,-0.00159129557805527,0.14120410915259,0.0114272983041907, +-0.00159129557805527,0.14120410915259,0.0114272983041907,2.2671665947323e-05,0.151800380519783,-0,-0.00632320810959113,0.131329956167904,0.0220758451134537,-0.00632320810959113,0.131329956167904,0.0220758451134537,-0.0138505939094923,0.122850828773823,0.0312199595602942,-0.0138505939094923,0.122850828773823,0.0312199595602942,-0.0236604740750876,0.116344565489834,0.0382364853565232,-0.0236604740750876,0.116344565489834,0.0382364853565232,-0.0350843214846854,0.11225455740663,0.0426472578644845,-0.0350843214846854,0.11225455740663,0.0426472578644845,-0.0473436198161224,0.110859531816025,0.0441516902269075,-0.0473436198161224,0.110859531816025,0.0441516902269075,2.2671665947323e-05,0.151800380519783,-0,-0.00159129557805523,0.144522770779036,0.0137804393936313,-0.00159129557805523,0.144522770779036,0.0137804393936313,2.2671665947323e-05,0.151800380519783,-0,-0.00632320810959144,0.137741118115302,0.0266217646158389,-0.00632320810959144,0.137741118115302,0.0266217646158389,-0.0138505939094921,0.131917580950403,0.0376488605740236,-0.0138505939094921,0.131917580950403,0.0376488605740236,-0.0236604740750873,0.127449023718279,0.0461102489017724,-0.0236604740750873,0.127449023718279,0.0461102489017724,-0.0350843214846857,0.124639971209656,0.0514292999676549,-0.0350843214846857,0.124639971209656,0.0514292999676549,-0.0473436198161225,0.123681855710821,0.0532435292316779,-0.0473436198161225,0.123681855710821,0.0532435292316779,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,2.2671665947323e-05,0.151800380519783,-0,-0.00965925826289069,0.027596359291114,-0.00258819045102525,-0.00965925826289069,0.027596359291114,0.00258819045102516,-0.00999999999999997,0.027596359291114,-9.02389274415327e-17,-0.00866025403784437,0.027596359291114,-0.00500000000000004,-0.00866025403784437,0.027596359291114,0.00499999999999995,-0.00707106781186548,0.027596359291114,-0.00707106781186558,-0.00707106781186548,0.027596359291114,0.0070710678118654,-0.00499999999999998,0.027596359291114,-0.00866025403784443, +-0.00499999999999998,0.027596359291114,0.00866025403784434,-0.00258819045102519,0.027596359291114,-0.00965925826289074,-0.00258819045102519,0.027596359291114,0.00965925826289065,1.12798659301916e-17,0.027596359291114,-0.0100000000000001,1.12798659301916e-17,0.027596359291114,0.00999999999999989,0.00258819045102522,0.027596359291114,-0.00965925826289074,0.00258819045102522,0.027596359291114,0.00965925826289065,0.005,0.027596359291114,-0.00866025403784443,0.005,0.027596359291114,0.00866025403784434,0.00707106781186546,0.027596359291114,-0.00707106781186558,0.00707106781186546,0.027596359291114,0.0070710678118654,0.00866025403784439,0.027596359291114,-0.00500000000000004,0.00866025403784439,0.027596359291114,0.00499999999999995,0.00965925826289066,0.027596359291114,-0.00258819045102525,0.00965925826289066,0.027596359291114,0.00258819045102516,0.00999999999999999,0.027596359291114,-9.02389274415327e-17,-0.00999999999999997,0.027596359291114,-9.02389274415327e-17,-0.00965925826289069,0.027596359291114,0.00258819045102516,-0.00965925826289069,0.027596359291114,-0.00258819045102525,-0.00866025403784437,0.027596359291114,-0.00500000000000004,-0.00866025403784437,0.027596359291114,0.00499999999999995,-0.00707106781186548,0.027596359291114,-0.00707106781186558,-0.00707106781186548,0.027596359291114,0.0070710678118654,-0.00499999999999998,0.027596359291114,-0.00866025403784443,-0.00499999999999998,0.027596359291114,0.00866025403784434,-0.00258819045102519,0.027596359291114,-0.00965925826289074,-0.00258819045102519,0.027596359291114,0.00965925826289065,1.12798659301916e-17,0.027596359291114,-0.0100000000000001,1.12798659301916e-17,0.027596359291114,0.00999999999999989,0.00258819045102522,0.027596359291114,-0.00965925826289074,0.00258819045102522,0.027596359291114,0.00965925826289065,0.005,0.027596359291114,-0.00866025403784443,0.005,0.027596359291114,0.00866025403784434,0.00707106781186546,0.027596359291114,-0.00707106781186558,0.00707106781186546,0.027596359291114,0.0070710678118654,0.00866025403784439,0.027596359291114,-0.00500000000000004, +0.00866025403784439,0.027596359291114,0.00499999999999995,0.00965925826289066,0.027596359291114,-0.00258819045102525,0.00965925826289066,0.027596359291114,0.00258819045102516,0.00999999999999999,0.027596359291114,-9.02389274415327e-17,-0.00999999999999997,0.147596359291114,-9.02389274415327e-17,-0.00965925826289069,0.027596359291114,0.00258819045102516,-0.00965925826289069,0.147596359291114,0.00258819045102516,-0.00999999999999997,0.027596359291114,-9.02389274415327e-17,-0.00965925826289069,0.147596359291114,0.00258819045102516,-0.00965925826289069,0.027596359291114,0.00258819045102516,-0.00999999999999997,0.147596359291114,-9.02389274415327e-17,-0.00999999999999997,0.027596359291114,-9.02389274415327e-17,0.005,0.147596359291114,0.00866025403784434,0.00258819045102522,0.027596359291114,0.00965925826289065,0.005,0.027596359291114,0.00866025403784434,0.00258819045102522,0.147596359291114,0.00965925826289065,0.005,0.027596359291114,0.00866025403784434,0.00258819045102522,0.027596359291114,0.00965925826289065,0.005,0.147596359291114,0.00866025403784434,0.00258819045102522,0.147596359291114,0.00965925826289065,0.00965925826289066,0.027596359291114,-0.00258819045102525,0.00999999999999999,0.147596359291114,-9.02389274415327e-17,0.00999999999999999,0.027596359291114,-9.02389274415327e-17,0.00965925826289066,0.147596359291114,-0.00258819045102525,0.00999999999999999,0.027596359291114,-9.02389274415327e-17,0.00999999999999999,0.147596359291114,-9.02389274415327e-17,0.00965925826289066,0.027596359291114,-0.00258819045102525,0.00965925826289066,0.147596359291114,-0.00258819045102525,1.12798659301916e-17,0.147596359291114,-0.0100000000000001,0.00258819045102522,0.027596359291114,-0.00965925826289074,1.12798659301916e-17,0.027596359291114,-0.0100000000000001,0.00258819045102522,0.147596359291114,-0.00965925826289074,1.12798659301916e-17,0.027596359291114,-0.0100000000000001,0.00258819045102522,0.027596359291114,-0.00965925826289074,1.12798659301916e-17,0.147596359291114,-0.0100000000000001,0.00258819045102522,0.147596359291114,-0.00965925826289074, +-0.00258819045102519,0.147596359291114,-0.00965925826289074,-0.00258819045102519,0.027596359291114,-0.00965925826289074,-0.00258819045102519,0.027596359291114,-0.00965925826289074,-0.00258819045102519,0.147596359291114,-0.00965925826289074,0.00707106781186546,0.147596359291114,0.0070710678118654,0.00707106781186546,0.027596359291114,0.0070710678118654,0.00707106781186546,0.027596359291114,0.0070710678118654,0.00707106781186546,0.147596359291114,0.0070710678118654,-0.00499999999999998,0.147596359291114,0.00866025403784434,-0.00707106781186548,0.027596359291114,0.0070710678118654,-0.00499999999999998,0.027596359291114,0.00866025403784434,-0.00707106781186548,0.147596359291114,0.0070710678118654,-0.00499999999999998,0.027596359291114,0.00866025403784434,-0.00707106781186548,0.027596359291114,0.0070710678118654,-0.00499999999999998,0.147596359291114,0.00866025403784434,-0.00707106781186548,0.147596359291114,0.0070710678118654,-0.00499999999999998,0.147596359291114,-0.00866025403784443,-0.00499999999999998,0.027596359291114,-0.00866025403784443,-0.00499999999999998,0.027596359291114,-0.00866025403784443,-0.00499999999999998,0.147596359291114,-0.00866025403784443,0.00866025403784439,0.027596359291114,0.00499999999999995,0.00866025403784439,0.147596359291114,0.00499999999999995,0.00866025403784439,0.027596359291114,0.00499999999999995,0.00866025403784439,0.147596359291114,0.00499999999999995,-0.00965925826289069,0.147596359291114,-0.00258819045102525,-0.00965925826289069,0.027596359291114,-0.00258819045102525,-0.00965925826289069,0.147596359291114,-0.00258819045102525,-0.00965925826289069,0.027596359291114,-0.00258819045102525,-0.00707106781186548,0.147596359291114,-0.00707106781186558,-0.00866025403784437,0.027596359291114,-0.00500000000000004,-0.00866025403784437,0.147596359291114,-0.00500000000000004,-0.00707106781186548,0.027596359291114,-0.00707106781186558,-0.00866025403784437,0.147596359291114,-0.00500000000000004,-0.00866025403784437,0.027596359291114,-0.00500000000000004,-0.00707106781186548,0.147596359291114,-0.00707106781186558, +-0.00707106781186548,0.027596359291114,-0.00707106781186558,0.00965925826289066,0.027596359291114,0.00258819045102516,0.00965925826289066,0.147596359291114,0.00258819045102516,0.00965925826289066,0.027596359291114,0.00258819045102516,0.00965925826289066,0.147596359291114,0.00258819045102516,0.00866025403784439,0.027596359291114,-0.00500000000000004,0.00866025403784439,0.147596359291114,-0.00500000000000004,0.00866025403784439,0.027596359291114,-0.00500000000000004,0.00866025403784439,0.147596359291114,-0.00500000000000004,-0.00258819045102519,0.147596359291114,0.00965925826289065,-0.00258819045102519,0.027596359291114,0.00965925826289065,-0.00258819045102519,0.027596359291114,0.00965925826289065,-0.00258819045102519,0.147596359291114,0.00965925826289065,-0.00866025403784437,0.147596359291114,0.00499999999999995,-0.00866025403784437,0.027596359291114,0.00499999999999995,-0.00866025403784437,0.147596359291114,0.00499999999999995,-0.00866025403784437,0.027596359291114,0.00499999999999995,0.00707106781186546,0.027596359291114,-0.00707106781186558,0.00707106781186546,0.147596359291114,-0.00707106781186558,0.00707106781186546,0.027596359291114,-0.00707106781186558,0.00707106781186546,0.147596359291114,-0.00707106781186558,-0.00965925826289069,0.147596359291114,0.00258819045102516,-0.00965925826289069,0.147596359291114,-0.00258819045102525,-0.00999999999999997,0.147596359291114,-9.02389274415327e-17,-0.00866025403784437,0.147596359291114,0.00499999999999995,-0.00866025403784437,0.147596359291114,-0.00500000000000004,-0.00707106781186548,0.147596359291114,0.0070710678118654,-0.00707106781186548,0.147596359291114,-0.00707106781186558,-0.00499999999999998,0.147596359291114,0.00866025403784434,-0.00499999999999998,0.147596359291114,-0.00866025403784443,-0.00258819045102519,0.147596359291114,0.00965925826289065,-0.00258819045102519,0.147596359291114,-0.00965925826289074,1.12798659301916e-17,0.147596359291114,0.00999999999999989,1.12798659301916e-17,0.147596359291114,-0.0100000000000001,0.00258819045102522,0.147596359291114,0.00965925826289065, +0.00258819045102522,0.147596359291114,-0.00965925826289074,0.005,0.147596359291114,0.00866025403784434,0.005,0.147596359291114,-0.00866025403784443,0.00707106781186546,0.147596359291114,0.0070710678118654,0.00707106781186546,0.147596359291114,-0.00707106781186558,0.00866025403784439,0.147596359291114,0.00499999999999995,0.00866025403784439,0.147596359291114,-0.00500000000000004,0.00965925826289066,0.147596359291114,0.00258819045102516,0.00965925826289066,0.147596359291114,-0.00258819045102525,0.00999999999999999,0.147596359291114,-9.02389274415327e-17,-0.00999999999999997,0.147596359291114,-9.02389274415327e-17,-0.00965925826289069,0.147596359291114,-0.00258819045102525,-0.00965925826289069,0.147596359291114,0.00258819045102516,-0.00866025403784437,0.147596359291114,0.00499999999999995,-0.00866025403784437,0.147596359291114,-0.00500000000000004,-0.00707106781186548,0.147596359291114,0.0070710678118654,-0.00707106781186548,0.147596359291114,-0.00707106781186558,-0.00499999999999998,0.147596359291114,0.00866025403784434,-0.00499999999999998,0.147596359291114,-0.00866025403784443,-0.00258819045102519,0.147596359291114,0.00965925826289065,-0.00258819045102519,0.147596359291114,-0.00965925826289074,1.12798659301916e-17,0.147596359291114,0.00999999999999989,1.12798659301916e-17,0.147596359291114,-0.0100000000000001,0.00258819045102522,0.147596359291114,0.00965925826289065,0.00258819045102522,0.147596359291114,-0.00965925826289074,0.005,0.147596359291114,0.00866025403784434,0.005,0.147596359291114,-0.00866025403784443,0.00707106781186546,0.147596359291114,0.0070710678118654,0.00707106781186546,0.147596359291114,-0.00707106781186558,0.00866025403784439,0.147596359291114,0.00499999999999995,0.00866025403784439,0.147596359291114,-0.00500000000000004,0.00965925826289066,0.147596359291114,0.00258819045102516,0.00965925826289066,0.147596359291114,-0.00258819045102525,0.00999999999999999,0.147596359291114,-9.02389274415327e-17,0.005,0.147596359291114,-0.00866025403784443,0.005,0.027596359291114,-0.00866025403784443,0.005,0.027596359291114,-0.00866025403784443, +0.005,0.147596359291114,-0.00866025403784443,1.12798659301916e-17,0.027596359291114,0.00999999999999989,1.12798659301916e-17,0.147596359291114,0.00999999999999989,1.12798659301916e-17,0.027596359291114,0.00999999999999989,1.12798659301916e-17,0.147596359291114,0.00999999999999989 + } + PolygonVertexIndex: *3720 { + a: 0,1,-3,1,0,-4,4,5,-7,7,6,-6,2,8,-10,8,2,-2,10,11,-5,5,4,-12,12,8,-14,8,12,-10,14,11,-16,10,15,-12,16,13,-18,13,16,-13,18,14,-20,15,19,-15,20,17,-22,17,20,-17,22,18,-24,19,23,-19,24,0,-26,26,6,-28,28,0,-3,0,28,-26,4,6,-30,26,29,-7,30,2,-10,2,30,-29,10,4,-32,29,31,-5,12,30,-10,30,12,-33,10,31,-16,33,15,-32,16,32,-13,32,16,-35,15,33,-20,35,19,-34,20,34,-17,34,20,-37,19,35,-24,37,23,-36,38,25,-40,40,26,-42,42,25,-29,25,42,-40,29,26,-44,40,43,-27,44,28,-31,28,44,-43,31,29,-46,43,45,-30,46,30,-33,30,46,-45,33,31,-48,45,47,-32,34,46,-33,46,34,-49,33,47,-36,49,35,-48,36,48,-35,48,36,-51,35,49,-38,51,37,-50,52,53,-55,55,56,-58,58,39,-60,60,40,-62,62,39,-43,39,62,-60,43,40,-64,60,63,-41,64,42,-45,42,64,-63,45,43,-66,63,65,-44,66,44,-47,44,66,-65,47,45,-68,65,67,-46,48,66,-47,66,48,-69,47,67,-50,69,49,-68,50,68,-49,68,50,-71,49,69,-52,71,51,-70,72,59,-74,74,60,-76,76,59,-63,59,76,-74,63,60,-78,74,77,-61,78,62,-65,62,78,-77,65,63,-80,77,79,-64,80,64,-67,64,80,-79,67,65,-82,79,81,-66,80,68,-83,68,80,-67,83,69,-82,67,81,-70,82,70,-85,70,82,-69,85,71,-84,69,83,-72,86,73,-88,88,74,-90,90,73,-77,73,90,-88,77,74,-92,88,91,-75,92,76,-79,76,92,-91,79,77,-94,91,93,-78,94,78,-81,78,94,-93,81,79,-96,93,95,-80,96,80,-83,80,96,-95,83,81,-98,95,97,-82,98,82,-85,82,98,-97,85,83,-100,97,99,-84,54,100,-88,88,101,-56,102,87,-91,87,102,-55,91,88,-104,55,103,-89,104,94,-106,94,104,-93,106,95,-108,93,107,-96,108,94,-97,94,108,-106,97,95,-110,106,109,-96,110,96,-99,96,110,-109,99,97,-112,109,111,-98,102,52,-55,52,102,-113,55,57,-104,113,103,-58,104,112,-103,112,104,-115,103,113,-108,115,107,-114,116,104,-106,104,116,-115,106,107,-118,115,117,-108,116,108,-119,108,116,-106,119,109,-118,106,117,-110,118,110,-121,110,118,-109,121,111,-120,109,119,-112,122,123,-53,57,124,-126,112,122,-53,122,112,-127,57,125,-114,127,113,-126,114,126,-113,126,114,-129,113,127,-116,129,115,-128,116,128,-115,128,116,-131,115,129,-118,131,117,-130,132,116,-119,116,132,-131,119,117,-134,131,133,-118,134,118,-121,118,134,-133,121,119,-136,133,135,-120,136, +137,-123,125,138,-140,126,136,-123,136,126,-141,125,139,-128,141,127,-140,128,140,-127,140,128,-143,127,141,-130,143,129,-142,130,142,-129,142,130,-145,129,143,-132,145,131,-144,144,132,-147,132,144,-131,147,133,-146,131,145,-134,148,132,-135,132,148,-147,135,133,-150,147,149,-134,150,151,-137,139,152,-154,140,150,-137,150,140,-155,139,153,-142,155,141,-154,142,154,-141,154,142,-157,141,155,-144,157,143,-156,144,156,-143,156,144,-159,143,157,-146,159,145,-158,144,160,-159,160,144,-147,159,161,-146,147,145,-162,146,162,-161,162,146,-149,161,163,-148,149,147,-164,164,165,-151,153,166,-168,154,164,-151,164,154,-169,153,167,-156,169,155,-168,156,168,-155,168,156,-171,155,169,-158,171,157,-170,158,170,-157,170,158,-173,157,171,-160,173,159,-172,158,174,-173,174,158,-161,173,175,-160,161,159,-176,160,176,-175,176,160,-163,175,177,-162,163,161,-178,178,179,-181,179,178,-182,182,183,-185,185,184,-184,104,90,-93,90,104,-103,93,91,-108,103,107,-92,186,187,-189,187,186,-190,190,191,-193,193,192,-192,194,195,-197,197,198,-200,200,201,-203,201,200,-204,204,205,-207,207,206,-206,208,209,-211,211,212,-214,203,195,-202,195,203,-197,205,198,-208,197,207,-199,214,215,-217,215,214,-218,218,219,-221,221,220,-220,222,210,-224,210,222,-209,224,211,-226,213,225,-212,226,223,-228,223,226,-223,228,224,-230,225,229,-225,230,231,-211,211,232,-234,223,231,-235,231,223,-211,235,232,-225,211,224,-233,227,234,-237,234,227,-224,237,235,-229,224,228,-236,238,236,-240,236,238,-228,240,237,-242,228,241,-238,239,242,-239,242,239,-244,241,244,-241,245,240,-245,246,242,-244,242,246,-248,245,244,-249,249,248,-245,234,250,-252,250,234,-232,252,253,-236,232,235,-254,236,251,-255,251,236,-235,255,252,-238,235,237,-253,239,254,-257,254,239,-237,257,255,-241,237,240,-256,256,243,-240,243,256,-259,240,245,-258,259,257,-246,260,243,-259,243,260,-247,259,245,-262,248,261,-246,262,263,-265,263,262,-266,266,267,-269,269,268,-268,264,270,-272,270,264,-264,272,273,-267,267,266,-274,274,275,-277,275,274,-278,278,279,-281,281,280,-280,282,274,-284,274,282,-278,284,280, +-286,281,285,-281,286,287,-289,287,286,-290,290,291,-293,293,292,-292,262,202,-266,202,262,-201,269,204,-269,206,268,-205,178,294,-296,294,178,-181,296,297,-185,182,184,-298,277,214,-276,214,277,-290,279,220,-282,293,281,-221,286,214,-290,214,286,-218,293,220,-293,221,292,-221,298,299,-301,299,298,-302,302,303,-305,305,304,-304,216,306,-308,306,216,-216,308,309,-219,219,218,-310,310,196,-251,253,197,-312,251,196,-204,196,251,-251,207,197,-253,253,252,-198,254,203,-201,203,254,-252,206,207,-256,252,255,-208,256,200,-263,200,256,-255,268,206,-258,255,257,-207,256,264,-259,264,256,-263,259,266,-258,268,257,-267,258,271,-261,271,258,-265,261,272,-260,266,259,-273,312,250,-232,232,253,-314,274,276,-315,315,278,-281,274,316,-284,284,317,-281,275,216,-319,216,275,-215,319,218,-280,220,279,-219,320,186,-322,186,320,-190,322,192,-324,193,323,-193,324,325,-327,325,324,-328,328,329,-331,331,330,-330,180,288,-295,288,180,-287,297,290,-183,292,182,-291,276,318,-333,318,276,-276,333,319,-279,279,278,-320,334,335,-337,335,334,-338,338,339,-341,341,340,-340,342,186,-344,186,342,-322,344,192,-346,322,345,-193,326,306,-216,306,326,-326,219,309,-329,329,328,-310,346,347,-349,347,346,-350,350,351,-353,353,352,-352,354,337,-335,340,341,-356,356,348,-358,348,356,-347,358,350,-360,352,359,-351,360,346,-357,346,360,-362,359,352,-363,363,362,-353,364,361,-361,361,364,-366,362,363,-367,367,366,-364,298,365,-365,365,298,-301,366,367,-305,302,304,-368,179,215,-218,215,179,-327,221,219,-184,328,183,-220,347,368,-349,350,369,-352,370,371,-373,373,374,-376,336,376,-378,376,336,-336,378,379,-339,339,338,-380,377,343,-381,343,377,-377,381,344,-379,379,378,-345,343,188,-381,188,343,-187,381,190,-345,192,344,-191,382,383,-385,385,386,-388,382,388,-384,388,382,-390,386,390,-388,391,387,-391,389,392,-389,392,389,-308,390,393,-392,308,391,-394,307,394,-393,394,307,-307,393,395,-309,309,308,-396,325,394,-307,394,325,-397,309,395,-330,397,329,-396,325,398,-397,398,325,-328,397,399,-330,331,329,-400,383,370,-401,401,375,-387,383,402,-371,402,383,-389,375, +403,-387,390,386,-404,388,404,-403,404,388,-393,403,405,-391,393,390,-406,392,406,-405,406,392,-395,405,407,-394,395,393,-408,394,408,-407,408,394,-397,407,409,-396,397,395,-410,396,410,-409,410,396,-399,409,411,-398,399,397,-412,357,412,-209,213,413,-359,371,402,-415,402,371,-371,415,403,-375,375,374,-404,414,404,-417,404,414,-403,417,405,-416,403,415,-406,404,418,-417,418,404,-407,417,419,-406,407,405,-420,408,418,-407,418,408,-421,407,419,-410,421,409,-420,410,420,-409,420,410,-423,409,421,-412,423,411,-422,424,371,-426,426,374,-428,425,414,-429,414,425,-372,429,415,-427,374,426,-416,428,416,-431,416,428,-415,431,417,-430,415,429,-418,416,432,-431,432,416,-419,431,433,-418,419,417,-434,418,434,-433,434,418,-421,433,435,-420,421,419,-436,420,436,-435,436,420,-423,435,437,-422,423,421,-438,438,425,-440,440,426,-442,439,428,-443,428,439,-426,443,429,-441,426,440,-430,442,430,-445,430,442,-429,445,431,-444,429,443,-432,444,432,-343,432,444,-431,345,433,-446,431,445,-434,434,342,-433,342,434,-322,433,345,-436,322,435,-346,434,320,-322,320,434,-437,322,323,-436,437,435,-324,446,439,-338,341,440,-448,337,442,-336,442,337,-440,339,443,-342,440,341,-444,335,444,-377,444,335,-443,379,445,-340,443,339,-446,376,342,-344,342,376,-445,344,345,-380,445,379,-346,361,349,-347,349,361,-449,352,353,-364,449,363,-354,365,448,-362,448,365,-451,363,449,-368,451,367,-450,365,452,-451,452,365,-301,451,453,-368,302,367,-454,300,454,-453,454,300,-300,453,455,-303,303,302,-456,456,457,-348,351,458,-460,349,456,-348,456,349,-461,351,459,-354,461,353,-460,448,460,-350,460,448,-463,353,461,-450,463,449,-462,450,462,-449,462,450,-465,449,463,-452,465,451,-464,466,450,-453,450,466,-465,453,451,-468,465,467,-452,468,452,-455,452,468,-467,455,453,-470,467,469,-454,283,470,-457,459,471,-285,460,283,-457,283,460,-283,459,284,-462,285,461,-285,462,282,-461,282,462,-288,461,285,-464,291,463,-286,464,287,-463,287,464,-289,463,291,-466,290,465,-292,294,464,-467,464,294,-289,467,465,-298,290,297,-466,295,466,-469,466,295,-295,469,467,-297,297,296,-468, +472,473,-475,473,472,-476,476,477,-479,479,478,-478,474,480,-482,480,474,-474,482,483,-477,477,476,-484,481,484,-486,484,481,-481,486,487,-483,483,482,-488,485,488,-490,488,485,-485,490,491,-487,487,486,-492,489,492,-494,492,489,-489,494,495,-491,491,490,-496,318,307,-390,307,318,-217,391,308,-320,218,319,-309,496,472,-196,198,478,-498,201,472,-475,472,201,-196,476,478,-206,198,205,-479,202,474,-482,474,202,-202,482,476,-205,205,204,-477,202,485,-266,485,202,-482,269,486,-205,482,204,-487,265,489,-264,489,265,-486,267,490,-270,486,269,-491,263,493,-271,493,263,-490,273,494,-268,490,267,-495,238,226,-228,226,238,-499,228,229,-242,499,241,-230,242,498,-239,498,242,-501,241,499,-245,501,244,-500,247,500,-243,500,247,-503,244,501,-250,503,249,-502,222,357,-209,357,222,-357,213,358,-226,359,225,-359,226,356,-223,356,226,-361,225,359,-230,362,229,-360,498,360,-227,360,498,-365,229,362,-500,366,499,-363,498,298,-365,298,498,-501,366,304,-500,501,499,-305,502,298,-501,298,502,-302,501,304,-504,305,503,-305,332,382,-458,458,387,-334,348,504,-358,358,505,-351,506,334,-476,479,340,-508,475,336,-474,336,475,-335,477,338,-480,340,479,-339,473,377,-481,377,473,-337,483,378,-478,338,477,-379,480,380,-485,380,480,-378,487,381,-484,378,483,-382,380,488,-485,488,380,-189,487,491,-382,190,381,-492,188,492,-489,492,188,-188,491,495,-191,191,190,-496,508,475,-473,478,479,-510,332,389,-383,389,332,-319,387,391,-334,319,333,-392,181,326,-180,326,181,-325,183,328,-186,330,185,-329,180,217,-287,217,180,-180,292,221,-183,183,182,-222,276,332,-511,511,333,-279,287,277,-283,277,287,-290,285,281,-292,293,291,-282,512,513,-165,167,514,-516,168,512,-165,512,168,-517,167,515,-170,517,169,-516,170,516,-169,516,170,-519,169,517,-172,519,171,-518,518,172,-521,172,518,-171,521,173,-520,171,519,-174,520,174,-523,174,520,-173,523,175,-522,173,521,-176,522,176,-525,176,522,-175,525,177,-524,175,523,-178,512,526,-528,528,529,-516,512,530,-527,530,512,-517,529,531,-516,517,515,-532,516,532,-531,532,516,-519,531,533,-518,519,517,-534,532,520,-535,520,532, +-519,535,521,-534,519,533,-522,534,522,-537,522,534,-521,537,523,-536,521,535,-524,536,524,-539,524,536,-523,539,525,-538,523,537,-526,526,540,-542,542,543,-530,526,544,-541,544,526,-531,543,545,-530,531,529,-546,530,546,-545,546,530,-533,545,547,-532,533,531,-548,532,548,-547,548,532,-535,547,549,-534,535,533,-550,548,536,-551,536,548,-535,551,537,-550,535,549,-538,550,538,-553,538,550,-537,553,539,-552,537,551,-540,540,554,-556,556,557,-544,540,558,-555,558,540,-545,557,559,-544,545,543,-560,544,560,-559,560,544,-547,559,561,-546,547,545,-562,546,562,-561,562,546,-549,561,563,-548,549,547,-564,562,550,-565,550,562,-549,565,551,-564,549,563,-552,564,552,-567,552,564,-551,567,553,-566,551,565,-554,554,568,-570,570,571,-558,554,572,-569,572,554,-559,571,573,-558,559,557,-574,558,574,-573,574,558,-561,573,575,-560,561,559,-576,560,576,-575,576,560,-563,575,577,-562,563,561,-578,578,562,-565,562,578,-577,565,563,-580,577,579,-564,580,564,-567,564,580,-579,567,565,-582,579,581,-566,568,582,-584,584,585,-572,568,586,-583,586,568,-573,585,587,-572,573,571,-588,572,588,-587,588,572,-575,587,589,-574,575,573,-590,574,590,-589,590,574,-577,589,591,-576,577,575,-592,590,578,-593,578,590,-577,593,579,-592,577,591,-580,594,578,-581,578,594,-593,581,579,-596,593,595,-580,582,596,-598,598,599,-586,596,586,-601,586,596,-583,601,587,-600,585,599,-588,600,588,-603,588,600,-587,603,589,-602,587,601,-590,604,588,-591,588,604,-603,591,589,-606,603,605,-590,604,592,-607,592,604,-591,607,593,-606,591,605,-594,606,594,-609,594,606,-593,609,595,-608,593,607,-596,610,596,-612,612,599,-614,611,600,-615,600,611,-597,615,601,-613,599,612,-602,614,602,-617,602,614,-601,617,603,-616,601,615,-604,618,602,-605,602,618,-617,605,603,-620,617,619,-604,620,604,-607,604,620,-619,607,605,-622,619,621,-606,622,606,-609,606,622,-621,609,607,-624,621,623,-608,624,611,-626,626,612,-628,625,614,-629,614,625,-612,629,615,-627,612,626,-616,628,616,-631,616,628,-615,631,617,-630,615,629,-618,630,618,-633,618,630,-617,633,619,-632,617,631,-620,634,618,-621,618, +634,-633,621,619,-636,633,635,-620,634,622,-637,622,634,-621,637,623,-636,621,635,-624,638,625,-640,640,626,-642,639,628,-643,628,639,-626,643,629,-641,626,640,-630,642,630,-645,630,642,-629,645,631,-644,629,643,-632,644,632,-647,632,644,-631,647,633,-646,631,645,-634,646,634,-649,634,646,-633,649,635,-648,633,647,-636,650,634,-637,634,650,-649,637,635,-652,649,651,-636,652,639,-654,654,640,-656,653,642,-657,642,653,-640,657,643,-655,640,654,-644,656,644,-659,644,656,-643,659,645,-658,643,657,-646,658,646,-661,646,658,-645,661,647,-660,645,659,-648,662,646,-649,646,662,-661,649,647,-664,661,663,-648,664,648,-651,648,664,-663,651,649,-666,663,665,-650,666,653,-4,7,654,-668,3,656,-2,656,3,-654,5,657,-8,654,7,-658,1,658,-9,658,1,-657,11,659,-6,657,5,-660,8,660,-14,660,8,-659,14,661,-12,659,11,-662,17,660,-663,660,17,-14,663,661,-19,14,18,-662,21,662,-665,662,21,-18,665,663,-23,18,22,-664,668,3,-1,6,7,-670,670,671,-673,671,670,-674,671,673,-675,674,673,-676,674,675,-677,676,675,-678,676,677,-679,678,677,-680,678,679,-681,680,679,-682,680,681,-683,682,681,-684,682,683,-685,684,683,-686,684,685,-687,686,685,-688,686,687,-689,688,687,-690,688,689,-691,690,689,-692,690,691,-693,692,691,-694,694,695,-697,697,696,-696,698,697,-696,699,697,-699,700,699,-699,701,699,-701,702,701,-701,703,701,-703,704,703,-703,705,703,-705,706,705,-705,707,705,-707,708,707,-707,709,707,-709,710,709,-709,711,709,-711,712,711,-711,713,711,-713,714,713,-713,715,713,-715,716,715,-715,717,715,-717,718,719,-721,719,718,-722,722,723,-725,725,724,-724,726,727,-729,727,726,-730,730,731,-733,733,732,-732,734,735,-737,735,734,-738,738,739,-741,741,740,-740,742,743,-745,743,742,-746,746,747,-749,749,748,-748,750,744,-752,744,750,-743,752,746,-754,748,753,-747,754,728,-756,728,754,-727,756,730,-758,732,757,-731,758,759,-761,759,758,-762,762,763,-765,765,764,-764,766,751,-768,751,766,-751,768,752,-770,753,769,-753,770,754,-756,754,770,-772,756,757,-773,773,772,-758,774,721,-719,721,774,-776,724,725,-777,777,776,-726,778,779,-781,779,778,-782,782,783,-785,785, +784,-784,786,771,-771,771,786,-788,772,773,-789,789,788,-774,790,737,-735,737,790,-792,740,741,-793,793,792,-742,780,775,-775,775,780,-780,776,777,-783,783,782,-778,794,760,-796,760,794,-759,796,762,-798,764,797,-763,798,759,-762,759,798,-800,765,763,-801,801,800,-764,802,791,-791,791,802,-804,792,793,-805,805,804,-794,720,799,-799,799,720,-720,800,801,-723,723,722,-802,806,807,-809,807,806,-810,807,809,-811,810,809,-812,810,811,-813,812,811,-814,812,813,-815,814,813,-816,814,815,-817,816,815,-818,816,817,-819,818,817,-820,818,819,-821,820,819,-822,820,821,-823,822,821,-824,822,823,-825,824,823,-826,824,825,-827,826,825,-828,826,827,-829,828,827,-830,830,831,-833,833,832,-832,834,833,-832,835,833,-835,836,835,-835,837,835,-837,838,837,-837,839,837,-839,840,839,-839,841,839,-841,842,841,-841,843,841,-843,844,843,-843,845,843,-845,846,845,-845,847,845,-847,848,847,-847,849,847,-849,850,849,-849,851,849,-851,852,851,-851,853,851,-853,736,787,-787,787,736,-736,788,789,-739,739,738,-790,854,802,-856,802,854,-804,856,804,-858,805,857,-805,729,858,-728,858,729,-860,731,860,-734,861,733,-861,745,855,-744,855,745,-855,747,856,-750,857,749,-857,859,795,-859,795,859,-795,860,796,-862,797,861,-797,778,767,-782,767,778,-767,785,768,-785,769,784,-769 + } + GeometryVersion: 124 + LayerElementNormal: 0 { + Version: 101 + Name: "" + MappingInformationType: "ByVertice" + ReferenceInformationType: "Direct" + Normals: *2586 { + a: -0.978227201428166,-0.00782552786592357,-0.20738925598892,-0.909402416903602,0.0924222919608575,-0.405518635920212,-0.9094024169036,-0.0156828673903062,-0.415621572828348,-0.978227201428168,0.046117409729502,-0.20234803410425,0.9094024169036,0.0156828673903062,0.415621572828348,0.909402416903602,-0.0924222919608575,0.405518635920212,0.978227201428166,0.00782552786592357,0.20738925598892,0.978227201428168,-0.046117409729502,0.20234803410425,-0.783622247195286,0.138047147680612,-0.605705504942672,-0.783622247195288,-0.0234248152123465,-0.620795821291409,0.783622247195288,0.0234248152123465,0.620795821291409,0.783622247195286,-0.138047147680612,0.605705504942672,-0.588320272074908,-0.0304906870593461,-0.808052953381371,-0.588320272074901,0.179687751694512,-0.788410787189448,0.588320272074901,-0.179687751694512,0.788410787189448,0.588320272074908,0.0304906870593461,0.808052953381371,-0.319660973195767,-0.0357282964404113,-0.94685814726864,-0.319660973195766,0.210554037262502,-0.923841901846845,0.319660973195766,-0.210554037262502,0.923841901846845,0.319660973195767,0.0357282964404113,0.94685814726864,-0.16506188587999,-0.0371894770095988,-0.985581816304204,-0.165061885879996,0.219165068256504,-0.961624275216605,0.165061885879996,-0.219165068256504,0.961624275216605,0.16506188587999,0.0371894770095988,0.985581816304204,-1,3.379314095378e-16,1.42963154589841e-15,-0.978227201428169,-0.0612351686695966,-0.198297242804884,0.978227201428169,0.0612351686695966,0.198297242804884,1,-3.379314095378e-16,-1.42963154589841e-15,-0.909402416903602,-0.122719265245992,-0.397400586395355,0.909402416903602,0.122719265245992,0.397400586395355,-0.783622247195289,-0.183300415659926,-0.593579928332742,0.783622247195289,0.183300415659926,0.593579928332742,-0.588320272074911,-0.238591235878361,-0.772627646171,0.588320272074911,0.238591235878361,0.772627646171,-0.319660973195767,-0.279575805784721,-0.905347574711149,0.319660973195767,0.279575805784721,0.905347574711149,-0.165061885879985,-0.291009620876019,-0.942373585361633, +0.165061885879985,0.291009620876019,0.942373585361633,-1,3.45634792206834e-16,1.43660819435338e-15,-0.978227201428168,-0.110471733924366,-0.17569160022539,0.978227201428168,0.110471733924366,0.17569160022539,1,-3.45634792206834e-16,-1.43660819435338e-15,-0.909402416903602,-0.221392547978341,-0.352097406735049,0.909402416903602,0.221392547978341,0.352097406735049,-0.783622247195285,-0.33068439569854,-0.525912544195423,0.783622247195285,0.33068439569854,0.525912544195423,-0.588320272074904,-0.430432186262926,-0.684549041701636,0.588320272074904,0.430432186262926,0.684549041701636,-0.31966097319577,-0.504370685985667,-0.802139061094696,0.31966097319577,0.504370685985667,0.802139061094696,-0.165061885879996,-0.524997939995877,-0.834944151922645,0.165061885879996,0.524997939995877,0.834944151922645,-0.978227201428169,-0.198297242804879,0.0612351686696053,-1,3.41855774293723e-16,1.44009651858087e-15,-0.978227201428167,-0.207389255988913,0.00782552786592495,0.978227201428167,0.207389255988913,-0.00782552786592495,1,-3.41855774293723e-16,-1.44009651858087e-15,0.978227201428169,0.198297242804879,-0.0612351686696053,-1,3.43599936407466e-16,1.43486403223964e-15,-0.978227201428169,-0.152179833075332,-0.141112865434644,0.978227201428169,0.152179833075332,0.141112865434644,1,-3.43599936407466e-16,-1.43486403223964e-15,-0.909402416903606,-0.304978294434464,-0.282799370674203,0.909402416903606,0.304978294434464,0.282799370674203,-0.783622247195286,-0.455532780652123,-0.422405089282734,0.783622247195286,0.455532780652123,0.422405089282734,-0.588320272074894,-0.592939894476501,-0.549819551311081,0.588320272074894,0.592939894476501,0.549819551311081,-0.319660973195771,-0.694793537448654,-0.644266096062115,0.319660973195771,0.694793537448654,0.644266096062115,-0.165061885880014,-0.723208517105129,-0.670614654340578,0.165061885880014,0.723208517105129,0.670614654340578,-1,3.38948837437484e-16,1.43515472592526e-15,-0.97822720142817,-0.183517128091311,-0.0969175220645311,0.97822720142817,0.183517128091311,0.0969175220645311,1,-3.38948837437484e-16,-1.43515472592526e-15, +-0.909402416903599,-0.367780274125358,-0.19422902484997,0.909402416903599,0.367780274125358,0.19422902484997,-0.783622247195284,-0.549337359407769,-0.290111425592845,0.783622247195284,0.549337359407769,0.290111425592845,-0.588320272074896,-0.715039728760989,-0.377620767118456,0.588320272074896,0.715039728760989,0.377620767118456,-0.319660973195767,-0.837867357535113,-0.442487461282987,0.319660973195767,0.837867357535113,0.442487461282987,-0.165061885880015,-0.872133628932243,-0.460583876308333,0.165061885880015,0.872133628932243,0.460583876308333,-1,3.36041900581244e-16,1.44154998700899e-15,-0.978227201428168,-0.202348034104252,-0.0461174097294971,0.978227201428168,0.202348034104252,0.0461174097294971,1,-3.36041900581244e-16,-1.44154998700899e-15,-0.909402416903599,-0.405518635920212,-0.0924222919608799,0.909402416903599,0.405518635920212,0.0924222919608799,-0.783622247195289,-0.605705504942662,-0.138047147680636,0.783622247195289,0.605705504942662,0.138047147680636,-0.588320272074908,-0.788410787189439,-0.17968775169453,0.588320272074908,0.788410787189439,0.17968775169453,-0.319660973195765,-0.923841901846842,-0.21055403726252,0.319660973195765,0.923841901846842,0.21055403726252,-0.165061885880001,-0.961624275216601,-0.21916506825652,0.165061885880001,0.961624275216601,0.21916506825652,-1,3.3720467532374e-16,1.43857037673134e-15,1,-3.3720467532374e-16,-1.43857037673134e-15,-0.909402416903603,-0.41562157282834,0.0156828673902948,0.909402416903603,0.41562157282834,-0.0156828673902948,-0.783622247195289,-0.620795821291408,0.0234248152123369,-0.588320272074906,-0.808052953381371,0.0304906870593554,0.588320272074906,0.808052953381371,-0.0304906870593554,0.783622247195289,0.620795821291408,-0.0234248152123369,-0.319660973195769,-0.946858147268639,0.0357282964404246,0.319660973195769,0.946858147268639,-0.0357282964404246,-0.165061885879997,-0.985581816304202,0.0371894770096061,0.165061885879997,0.985581816304202,-0.0371894770096061,-0.909402416903604,-0.397400586395346,0.122719265246001,0.909402416903604,0.397400586395346,-0.122719265246001, +-0.783622247195287,-0.593579928332741,0.183300415659937,0.783622247195287,0.593579928332741,-0.183300415659937,-0.588320272074902,-0.772627646171005,0.238591235878365,0.588320272074902,0.772627646171005,-0.238591235878365,-0.319660973195764,-0.905347574711148,0.279575805784728,0.319660973195764,0.905347574711148,-0.279575805784728,-0.165061885879992,-0.942373585361628,0.29100962087603,0.165061885879992,0.942373585361628,-0.29100962087603,-0.978227201428168,-0.175691600225389,0.110471733924369,-1,3.43599936407466e-16,1.43835235646713e-15,1,-3.43599936407466e-16,-1.43835235646713e-15,0.978227201428168,0.175691600225389,-0.110471733924369,-0.9094024169036,-0.352097406735035,0.221392547978367,0.9094024169036,0.352097406735035,-0.221392547978367,-0.783622247195289,-0.525912544195406,0.330684395698558,0.783622247195289,0.525912544195406,-0.330684395698558,-0.588320272074911,-0.684549041701634,0.43043218626292,0.588320272074911,0.684549041701634,-0.43043218626292,-0.31966097319576,-0.802139061094706,0.504370685985658,0.31966097319576,0.802139061094706,-0.504370685985658,-0.165061885879982,-0.834944151922651,0.524997939995872,0.165061885879982,0.834944151922651,-0.524997939995872,-0.978227201428169,-0.141112865434633,0.152179833075343,-1,3.40111612179979e-16,1.43428264486839e-15,1,-3.40111612179979e-16,-1.43428264486839e-15,0.978227201428169,0.141112865434633,-0.152179833075343,-0.909402416903601,-0.282799370674219,0.304978294434465,0.909402416903601,0.282799370674219,-0.304978294434465,-0.783622247195286,-0.422405089282742,0.455532780652117,0.783622247195286,0.422405089282742,-0.455532780652117,-0.58832027207491,-0.549819551311075,0.592939894476491,0.58832027207491,0.549819551311075,-0.592939894476491,-0.319660973195767,-0.644266096062121,0.69479353744865,0.319660973195767,0.644266096062121,-0.69479353744865,-0.165061885879989,-0.670614654340588,0.723208517105126,0.165061885879989,0.670614654340588,-0.723208517105126,-0.978227201428169,-0.096917522064549,0.183517128091302,-1,3.38948837437484e-16,1.43370125749714e-15,1,-3.38948837437484e-16,-1.43370125749714e-15, +0.978227201428169,0.096917522064549,-0.183517128091302,-0.909402416903603,-0.194229024849993,0.367780274125333,0.909402416903603,0.194229024849993,-0.367780274125333,-0.783622247195281,-0.290111425592862,0.549337359407764,0.783622247195281,0.290111425592862,-0.549337359407764,-0.588320272074905,-0.377620767118445,0.715039728760988,0.588320272074905,0.377620767118445,-0.715039728760988,-0.319660973195775,-0.442487461282975,0.837867357535116,0.319660973195775,0.442487461282975,-0.837867357535116,-0.165061885879998,-0.460583876308329,0.872133628932248,0.165061885879998,0.460583876308329,-0.872133628932248,-0.978227201428171,-0.0461174097295262,0.202348034104234,-1,3.37495369009364e-16,1.43021293326966e-15,1,-3.37495369009364e-16,-1.43021293326966e-15,0.978227201428171,0.0461174097295262,-0.202348034104234,-0.909402416903603,-0.0924222919608785,0.405518635920205,0.909402416903603,0.0924222919608785,-0.405518635920205,-0.78362224719528,-0.138047147680633,0.605705504942676,0.78362224719528,0.138047147680633,-0.605705504942676,-0.588320272074903,-0.179687751694519,0.788410787189445,0.588320272074903,0.179687751694519,-0.788410787189445,-0.319660973195774,-0.2105540372625,0.923841901846843,0.319660973195774,0.2105540372625,-0.923841901846843,-0.165061885879999,-0.219165068256502,0.961624275216605,0.165061885879999,0.219165068256502,-0.961624275216605,0.165061885880005,-0.0371894770096069,0.985581816304201,0.319660973195773,-0.279575805784721,0.905347574711147,0.319660973195776,-0.0357282964404208,0.946858147268636,0.165061885880002,-0.291009620876021,0.942373585361629,-0.319660973195776,0.0357282964404208,-0.946858147268636,-0.319660973195773,0.279575805784721,-0.905347574711147,-0.165061885880005,0.0371894770096069,-0.985581816304201,-0.165061885880002,0.291009620876021,-0.942373585361629,0.319660973195768,-0.644266096062123,-0.694793537448647,0.165061885880002,-0.460583876308327,-0.872133628932249,0.31966097319577,-0.442487461282974,-0.837867357535118,0.165061885880004,-0.670614654340585,-0.723208517105125,-0.31966097319577,0.442487461282974,0.837867357535118, +-0.165061885880002,0.460583876308327,0.872133628932249,-0.319660973195768,0.644266096062123,0.694793537448647,-0.165061885880004,0.670614654340585,0.723208517105125,1,-4.63656428570143e-16,6.73246575904986e-16,0.978227201428168,0.0612351686696213,-0.198297242804882,0.978227201428167,0.110471733924365,-0.175691600225396,-0.978227201428167,-0.110471733924365,0.175691600225396,-0.978227201428168,-0.0612351686696213,0.198297242804882,-1,4.63656428570143e-16,-6.73246575904986e-16,0.783622247195293,0.330684395698553,-0.525912544195403,0.909402416903607,0.122719265245996,-0.397400586395341,0.783622247195297,0.183300415659929,-0.593579928332731,0.909402416903606,0.221392547978351,-0.352097406735031,-0.783622247195297,-0.183300415659929,0.593579928332731,-0.909402416903607,-0.122719265245996,0.397400586395341,-0.783622247195293,-0.330684395698553,0.525912544195403,-0.909402416903606,-0.221392547978351,0.352097406735031,0.978227201428168,0.207389255988911,0.00782552786590903,1,-4.66272671740758e-16,6.7731628750372e-16,0.978227201428167,0.202348034104249,-0.0461174097295443,-0.978227201428167,-0.202348034104249,0.0461174097295443,-1,4.66272671740758e-16,-6.7731628750372e-16,-0.978227201428168,-0.207389255988911,-0.00782552786590903,0.783622247195294,-0.183300415659924,0.593579928332736,0.588320272074906,-0.430432186262923,0.684549041701637,0.783622247195298,-0.330684395698547,0.5259125441954,0.588320272074902,-0.238591235878358,0.772627646171007,-0.783622247195298,0.330684395698547,-0.5259125441954,-0.588320272074906,0.430432186262923,-0.684549041701637,-0.783622247195294,0.183300415659924,-0.593579928332736,-0.588320272074902,0.238591235878358,-0.772627646171007,0.909402416903603,0.415621572828341,0.0156828673903053,0.909402416903605,0.405518635920198,-0.0924222919608817,-0.909402416903605,-0.405518635920198,0.0924222919608817,-0.909402416903603,-0.415621572828341,-0.0156828673903053,0.783622247195294,0.6207958212914,0.0234248152123499,0.783622247195295,0.605705504942658,-0.138047147680625,-0.783622247195295,-0.605705504942658,0.138047147680625, +-0.783622247195294,-0.6207958212914,-0.0234248152123499,1,-4.65109896998263e-16,6.82548773844951e-16,0.978227201428168,0.183517128091323,-0.0969175220645285,-0.978227201428168,-0.183517128091323,0.0969175220645285,-1,4.65109896998263e-16,-6.82548773844951e-16,0.909402416903604,0.367780274125338,-0.194229024849982,-0.909402416903604,-0.367780274125338,0.194229024849982,0.783622247195292,0.54933735940775,-0.290111425592859,-0.783622247195292,-0.54933735940775,0.290111425592859,0.588320272074908,0.788410787189442,-0.179687751694516,0.588320272074908,0.715039728760982,-0.377620767118451,-0.588320272074908,-0.715039728760982,0.377620767118451,-0.588320272074908,-0.788410787189442,0.179687751694516,0.319660973195771,0.923841901846844,-0.210554037262501,0.319660973195772,0.837867357535114,-0.44248746128298,-0.319660973195771,-0.923841901846844,0.210554037262501,-0.319660973195772,-0.837867357535114,0.44248746128298,0.165061885879998,0.872133628932247,-0.460583876308331,0.165061885879997,0.961624275216605,-0.219165068256504,-0.165061885879998,-0.872133628932247,0.460583876308331,-0.165061885879997,-0.961624275216605,0.219165068256504,0.978227201428169,0.152179833075344,-0.141112865434637,0.909402416903605,0.30497829443447,-0.282799370674199,-0.909402416903605,-0.30497829443447,0.282799370674199,-0.978227201428169,-0.152179833075344,0.141112865434637,0.783622247195292,0.455532780652118,-0.422405089282729,-0.783622247195292,-0.455532780652118,0.422405089282729,0.588320272074908,0.59293989447649,-0.549819551311078,-0.588320272074908,-0.59293989447649,0.549819551311078,0.319660973195773,0.694793537448648,-0.644266096062121,-0.319660973195773,-0.694793537448648,0.644266096062121,0.165061885880002,0.723208517105127,-0.670614654340584,-0.165061885880002,-0.723208517105127,0.670614654340584,0.588320272074909,0.430432186262931,-0.684549041701629,0.319660973195765,0.279575805784725,-0.905347574711148,0.319660973195768,0.504370685985667,-0.802139061094697,0.588320272074911,0.238591235878365,-0.772627646170998,-0.319660973195768,-0.504370685985667,0.802139061094697, +-0.319660973195765,-0.279575805784725,0.905347574711148,-0.588320272074909,-0.430432186262931,0.684549041701629,-0.588320272074911,-0.238591235878365,0.772627646170998,0.165061885879982,0.291009620876022,-0.942373585361632,0.165061885879991,0.524997939995876,-0.834944151922646,-0.165061885879991,-0.524997939995876,0.834944151922646,-0.165061885879982,-0.291009620876022,0.942373585361632,0.978227201428168,-0.0078255278659391,0.207389255988911,0.909402416903608,-0.122719265245997,0.397400586395338,0.978227201428166,-0.0612351686696132,0.198297242804891,0.909402416903608,-0.0156828673903083,0.415621572828329,-0.978227201428166,0.0612351686696132,-0.198297242804891,-0.909402416903608,0.122719265245997,-0.397400586395338,-0.978227201428168,0.0078255278659391,-0.207389255988911,-0.909402416903608,0.0156828673903083,-0.415621572828329,0.909402416903606,0.0924222919608851,0.405518635920197,0.978227201428168,0.0461174097295331,0.202348034104246,-0.978227201428168,-0.0461174097295331,-0.202348034104246,-0.909402416903606,-0.0924222919608851,-0.405518635920197,0.588320272074903,-0.0304906870593508,0.808052953381374,0.783622247195292,0.138047147680627,0.605705504942661,0.588320272074907,0.179687751694512,0.788410787189444,0.783622247195291,-0.0234248152123418,0.620795821291404,-0.588320272074907,-0.179687751694512,-0.788410787189444,-0.783622247195292,-0.138047147680627,-0.605705504942661,-0.588320272074903,0.0304906870593508,-0.808052953381374,-0.783622247195291,0.0234248152123418,-0.620795821291404,0.319660973195773,0.210554037262499,0.923841901846844,0.165061885880002,0.219165068256504,0.961624275216604,-0.165061885880002,-0.219165068256504,-0.961624275216604,-0.319660973195773,-0.210554037262499,-0.923841901846844,0.319660973195764,0.905347574711149,0.279575805784723,0.165061885880012,0.83494415192265,0.524997939995863,0.319660973195771,0.802139061094706,0.504370685985652,0.165061885880016,0.942373585361628,0.291009620876018,-0.319660973195771,-0.802139061094706,-0.504370685985652,-0.165061885880012,-0.83494415192265,-0.524997939995863, +-0.319660973195764,-0.905347574711149,-0.279575805784723,-0.165061885880016,-0.942373585361628,-0.291009620876018,0.588320272074907,-0.59293989447649,0.549819551311079,0.783622247195297,-0.455532780652114,0.422405089282724,-0.783622247195297,0.455532780652114,-0.422405089282724,-0.588320272074907,0.59293989447649,-0.549819551311079,1,-4.65691284369511e-16,6.76734900132472e-16,-1,4.65691284369511e-16,-6.76734900132472e-16,1,-4.63365734884519e-16,6.76153512761224e-16,-1,4.63365734884519e-16,-6.76153512761224e-16,1,-4.65981978055135e-16,6.73827963276233e-16,-1,4.65981978055135e-16,-6.73827963276233e-16,1,-4.62784347513272e-16,6.76153512761225e-16,-1,4.62784347513272e-16,-6.76153512761225e-16,0.909402416903608,-0.221392547978352,0.352097406735024,-0.909402416903608,0.221392547978352,-0.352097406735024,0.165061885880012,-0.834944151922644,-0.524997939995873,0.319660973195772,-0.8021390610947,-0.504370685985661,-0.319660973195772,0.8021390610947,0.504370685985661,-0.165061885880012,0.834944151922644,0.524997939995873,0.165061885879998,-0.524997939995872,0.834944151922648,0.319660973195768,-0.69479353744865,0.644266096062121,0.319660973195769,-0.50437068598566,0.802139061094701,0.165061885879999,-0.723208517105129,0.670614654340582,-0.319660973195769,0.50437068598566,-0.802139061094701,-0.319660973195768,0.69479353744865,-0.644266096062121,-0.165061885879998,0.524997939995872,-0.834944151922648,-0.165061885879999,0.723208517105129,-0.670614654340582,0.978227201428168,-0.110471733924365,0.175691600225393,-0.978227201428168,0.110471733924365,-0.175691600225393,0.978227201428167,-0.0969175220645315,-0.183517128091324,0.909402416903608,-0.282799370674193,-0.304978294434468,0.909402416903604,-0.194229024849983,-0.367780274125337,0.978227201428167,-0.141112865434638,-0.15217983307535,-0.909402416903604,0.194229024849983,0.367780274125337,-0.909402416903608,0.282799370674193,0.304978294434468,-0.978227201428167,0.0969175220645315,0.183517128091324,-0.978227201428167,0.141112865434638,0.15217983307535,0.588320272074899,-0.68454904170164,-0.430432186262927, +0.588320272074901,-0.549819551311081,-0.592939894476494,-0.588320272074901,0.549819551311081,0.592939894476494,-0.588320272074899,0.68454904170164,0.430432186262927,0.909402416903606,0.352097406735026,0.221392547978359,0.978227201428166,0.141112865434637,0.15217983307536,0.978227201428167,0.175691600225378,0.110471733924394,0.909402416903607,0.282799370674195,0.304978294434467,-0.978227201428167,-0.175691600225378,-0.110471733924394,-0.978227201428166,-0.141112865434637,-0.15217983307536,-0.909402416903606,-0.352097406735026,-0.221392547978359,-0.909402416903607,-0.282799370674195,-0.304978294434467,1,-4.6045879802828e-16,6.81967386473703e-16,-1,4.6045879802828e-16,-6.81967386473703e-16,0.909402416903602,0.397400586395349,0.122719265246005,0.978227201428167,0.19829724280488,0.0612351686696285,-0.978227201428167,-0.19829724280488,-0.0612351686696285,-0.909402416903602,-0.397400586395349,-0.122719265246005,0.783622247195296,0.593579928332733,0.183300415659927,0.783622247195296,0.525912544195407,0.330684395698541,-0.783622247195296,-0.593579928332733,-0.183300415659927,-0.783622247195296,-0.525912544195407,-0.330684395698541,0.5883202720749,0.772627646171006,0.238591235878366,0.588320272074901,0.684549041701643,0.430432186262918,-0.5883202720749,-0.772627646171006,-0.238591235878366,-0.588320272074901,-0.684549041701643,-0.430432186262918,1,-4.6859822122575e-16,6.74990738018729e-16,-1,4.6859822122575e-16,-6.74990738018729e-16,0.978227201428167,-0.202348034104249,0.0461174097295374,0.978227201428168,-0.207389255988912,-0.0078255278659124,1,-4.66854059112006e-16,6.7876975593184e-16,-1,4.66854059112006e-16,-6.7876975593184e-16,-0.978227201428168,0.207389255988912,0.0078255278659124,-0.978227201428167,0.202348034104249,-0.0461174097295374,0.783622247195297,-0.422405089282722,-0.455532780652115,0.783622247195294,-0.290111425592852,-0.549337359407751,-0.783622247195294,0.290111425592852,0.549337359407751,-0.783622247195297,0.422405089282722,0.455532780652115,0.588320272074904,-0.377620767118444,-0.715039728760989,-0.588320272074904,0.377620767118444,0.715039728760989, +0.978227201428167,-0.152179833075363,0.141112865434628,0.978227201428167,-0.183517128091317,0.096917522064539,1,-4.64528509627015e-16,6.76734900132472e-16,-1,4.64528509627015e-16,-6.76734900132472e-16,-0.978227201428167,0.183517128091317,-0.096917522064539,-0.978227201428167,0.152179833075363,-0.141112865434628,0.909402416903606,-0.367780274125332,0.194229024849982,0.909402416903605,-0.304978294434471,0.282799370674197,-0.909402416903606,0.367780274125332,-0.194229024849982,-0.909402416903605,0.304978294434471,-0.282799370674197,0.783622247195295,-0.549337359407749,0.290111425592854,-0.783622247195295,0.549337359407749,-0.290111425592854,0.588320272074906,-0.715039728760985,0.377620767118447,-0.588320272074906,0.715039728760985,-0.377620767118447,0.319660973195771,-0.837867357535117,0.442487461282976,-0.319660973195771,0.837867357535117,-0.442487461282976,0.165061885880009,-0.872133628932247,0.460583876308327,-0.165061885880009,0.872133628932247,-0.460583876308327,1,-4.69179608596998e-16,6.84583629644318e-16,-1,4.69179608596998e-16,-6.84583629644318e-16,0.909402416903606,-0.405518635920199,0.0924222919608782,-0.909402416903606,0.405518635920199,-0.0924222919608782,0.783622247195294,-0.60570550494266,0.13804714768062,-0.783622247195294,0.60570550494266,-0.13804714768062,0.588320272074905,-0.788410787189447,0.179687751694507,-0.588320272074905,0.788410787189447,-0.179687751694507,0.319660973195775,-0.923841901846844,0.210554037262496,-0.319660973195775,0.923841901846844,-0.210554037262496,0.165061885880014,-0.961624275216603,0.219165068256502,-0.165061885880014,0.961624275216603,-0.219165068256502,1,-4.6859822122575e-16,6.75572125389977e-16,-1,4.6859822122575e-16,-6.75572125389977e-16,0.909402416903607,-0.415621572828332,-0.0156828673902995,-0.909402416903607,0.415621572828332,0.0156828673902995,0.783622247195291,-0.620795821291405,-0.0234248152123439,-0.783622247195291,0.620795821291405,0.0234248152123439,0.588320272074902,-0.808052953381375,-0.0304906870593533,-0.588320272074902,0.808052953381375,0.0304906870593533, +0.319660973195776,-0.946858147268636,-0.0357282964404201,-0.319660973195776,0.946858147268636,0.0357282964404201,0.16506188588001,-0.9855818163042,-0.0371894770096037,-0.16506188588001,0.9855818163042,0.0371894770096037,1,-4.66854059112006e-16,6.73391922747797e-16,0.978227201428168,-0.198297242804879,-0.0612351686696228,-0.978227201428168,0.198297242804879,0.0612351686696228,-1,4.66854059112006e-16,-6.73391922747797e-16,0.909402416903608,-0.397400586395337,-0.122719265246002,-0.909402416903608,0.397400586395337,0.122719265246002,0.783622247195294,-0.593579928332736,-0.183300415659924,-0.783622247195294,0.593579928332736,0.183300415659924,0.5883202720749,-0.772627646171008,-0.238591235878359,-0.5883202720749,0.772627646171008,0.238591235878359,0.319660973195775,-0.905347574711146,-0.279575805784719,-0.319660973195775,0.905347574711146,0.279575805784719,0.165061885880013,-0.942373585361628,-0.291009620876017,-0.165061885880013,0.942373585361628,0.291009620876017,1,-4.63947122255767e-16,6.72665188533738e-16,0.978227201428167,-0.175691600225391,-0.110471733924375,-0.978227201428167,0.175691600225391,0.110471733924375,-1,4.63947122255767e-16,-6.72665188533738e-16,0.909402416903608,-0.352097406735025,-0.22139254797835,-0.909402416903608,0.352097406735025,0.22139254797835,0.783622247195296,-0.525912544195403,-0.330684395698546,-0.783622247195296,0.525912544195403,0.330684395698546,1,-4.65109896998263e-16,6.79641836988712e-16,-1,4.65109896998263e-16,-6.79641836988712e-16,0.783622247195299,0.422405089282724,0.45553278065211,-0.783622247195299,-0.422405089282724,-0.45553278065211,0.588320272074909,0.549819551311083,0.592939894476485,-0.588320272074909,-0.549819551311083,-0.592939894476485,0.319660973195769,0.644266096062124,0.694793537448647,-0.319660973195769,-0.644266096062124,-0.694793537448647,0.165061885879995,0.670614654340583,0.723208517105129,-0.165061885879995,-0.670614654340583,-0.723208517105129,0.978227201428167,0.0969175220645579,0.183517128091308,1,-4.65109896998263e-16,6.7731628750372e-16,-1,4.65109896998263e-16,-6.7731628750372e-16, +-0.978227201428167,-0.0969175220645579,-0.183517128091308,0.909402416903605,0.194229024849988,0.367780274125331,-0.909402416903605,-0.194229024849988,-0.367780274125331,0.783622247195296,0.290111425592847,0.549337359407752,-0.783622247195296,-0.290111425592847,-0.549337359407752,0.588320272074909,0.377620767118439,0.715039728760988,-0.588320272074909,-0.377620767118439,-0.715039728760988,0.319660973195768,0.442487461282974,0.837867357535119,-0.319660973195768,-0.442487461282974,-0.837867357535119,0.165061885879994,0.460583876308329,0.872133628932249,-0.165061885879994,-0.460583876308329,-0.872133628932249,1,-4.65981978055135e-16,6.7731628750372e-16,-1,4.65981978055135e-16,-6.7731628750372e-16,0.978227201428167,0.00782552786591837,-0.207389255988915,0.909402416903607,-0.0924222919608787,-0.405518635920195,0.909402416903607,0.0156828673903071,-0.415621572828332,0.978227201428167,-0.0461174097295258,-0.202348034104253,-0.909402416903607,-0.0156828673903071,0.415621572828332,-0.909402416903607,0.0924222919608787,0.405518635920195,-0.978227201428167,-0.00782552786591837,0.207389255988915,-0.978227201428167,0.0461174097295258,0.202348034104253,0.783622247195294,-0.138047147680626,-0.605705504942658,0.783622247195295,0.023424815212345,-0.6207958212914,-0.783622247195295,-0.023424815212345,0.6207958212914,-0.783622247195294,0.138047147680626,0.605705504942658,0.588320272074904,-0.179687751694517,-0.788410787189445,0.588320272074908,0.0304906870593446,-0.808052953381371,-0.588320272074908,-0.0304906870593446,0.808052953381371,-0.588320272074904,0.179687751694517,0.788410787189445,0.31966097319577,-0.210554037262502,-0.923841901846844,0.319660973195768,0.0357282964404139,-0.946858147268639,-0.319660973195768,-0.0357282964404139,0.946858147268639,-0.31966097319577,0.210554037262502,0.923841901846844,0.165061885879998,-0.219165068256502,-0.961624275216605,0.165061885879987,0.0371894770096023,-0.985581816304204,-0.165061885879987,-0.0371894770096023,0.985581816304204,-0.165061885879998,0.219165068256502,0.961624275216605,1,-4.63075041198895e-16,6.74409350647481e-16, +-1,4.63075041198895e-16,-6.74409350647481e-16,0.588320272074904,0.808052953381373,0.0304906870593547,-0.588320272074904,-0.808052953381373,-0.0304906870593547,0.319660973195766,0.946858147268639,0.0357282964404277,-0.319660973195766,-0.946858147268639,-0.0357282964404277,0.165061885880007,0.9855818163042,0.0371894770096146,-0.165061885880007,-0.9855818163042,-0.0371894770096146,1,-4.67435446483254e-16,6.73246575904986e-16,-1,4.67435446483254e-16,-6.73246575904986e-16,1,-4.66854059112006e-16,6.74990738018729e-16,-1,4.66854059112006e-16,-6.74990738018729e-16,1,-4.63147714620301e-16,6.74409350647481e-16,-1,4.63147714620301e-16,-6.74409350647481e-16,1,-4.65691284369511e-16,6.78479062246216e-16,-1,4.65691284369511e-16,-6.78479062246216e-16,-0.978227201428169,0.00782552786592991,0.207389255988907,-1,3.3938487796592e-16,1.42846877115591e-15,1,-3.3938487796592e-16,-1.42846877115591e-15,0.978227201428169,-0.00782552786592991,-0.207389255988907,-0.909402416903605,0.0156828673903087,0.415621572828336,0.909402416903605,-0.0156828673903087,-0.415621572828336,-0.783622247195286,0.0234248152123419,0.620795821291411,0.783622247195286,-0.0234248152123419,-0.620795821291411,-0.588320272074903,0.0304906870593461,0.808052953381374,0.588320272074903,-0.0304906870593461,-0.808052953381374,-0.319660973195772,0.035728296440418,0.946858147268638,0.319660973195772,-0.035728296440418,-0.946858147268638,-0.16506188588,0.0371894770096059,0.985581816304202,0.16506188588,-0.0371894770096059,-0.985581816304202,-0.97822720142817,0.0612351686696237,0.198297242804871,-1,3.40983693236851e-16,1.42788738378467e-15,1,-3.40983693236851e-16,-1.42788738378467e-15,0.97822720142817,-0.0612351686696237,-0.198297242804871,-0.909402416903604,0.12271926524601,0.397400586395343,0.909402416903604,-0.12271926524601,-0.397400586395343,-0.783622247195287,0.183300415659938,0.593579928332742,0.783622247195287,-0.183300415659938,-0.593579928332742,-0.588320272074904,0.238591235878368,0.772627646171002,0.588320272074904,-0.238591235878368,-0.772627646171002,-0.319660973195773,0.279575805784725,0.905347574711145, +0.319660973195773,-0.279575805784725,-0.905347574711145,-0.16506188588,0.291009620876022,0.942373585361629,0.16506188588,-0.291009620876022,-0.942373585361629,-0.978227201428168,0.110471733924372,0.17569160022539,-1,3.40692999551227e-16,1.43253848275465e-15,1,-3.40692999551227e-16,-1.43253848275465e-15,0.978227201428168,-0.110471733924372,-0.17569160022539,-0.909402416903604,0.221392547978347,0.352097406735037,0.909402416903604,-0.221392547978347,-0.352097406735037,-0.783622247195287,0.33068439569855,0.525912544195413,0.783622247195287,-0.33068439569855,-0.525912544195413,-0.5883202720749,0.43043218626293,0.684549041701637,0.5883202720749,-0.43043218626293,-0.684549041701637,-0.319660973195773,0.504370685985664,0.802139061094696,0.319660973195773,-0.504370685985664,-0.802139061094696,-0.165061885880009,0.524997939995875,0.834944151922644,0.165061885880009,-0.524997939995875,-0.834944151922644,-0.97822720142817,0.152179833075341,0.141112865434629,-1,3.39530224808731e-16,1.43544541961089e-15,1,-3.39530224808731e-16,-1.43544541961089e-15,0.97822720142817,-0.152179833075341,-0.141112865434629,-0.909402416903606,0.304978294434464,0.282799370674203,0.909402416903606,-0.304978294434464,-0.282799370674203,-0.783622247195286,0.455532780652119,0.422405089282738,0.783622247195286,-0.455532780652119,-0.422405089282738,-0.588320272074896,0.592939894476494,0.549819551311087,0.588320272074896,-0.592939894476494,-0.549819551311087,-0.31966097319577,0.694793537448649,0.64426609606212,0.31966097319577,-0.694793537448649,-0.64426609606212,-0.165061885880016,0.723208517105129,0.670614654340578,0.165061885880016,-0.723208517105129,-0.670614654340578,-0.978227201428168,0.183517128091319,0.0969175220645279,-1,3.45925485892458e-16,1.43399195118277e-15,1,-3.45925485892458e-16,-1.43399195118277e-15,0.978227201428168,-0.183517128091319,-0.0969175220645279,-0.909402416903604,0.367780274125343,0.194229024849972,0.909402416903604,-0.367780274125343,-0.194229024849972,-0.783622247195287,0.549337359407761,0.290111425592853,0.783622247195287,-0.549337359407761,-0.290111425592853, +-0.5883202720749,0.71503972876099,0.377620767118447,0.5883202720749,-0.71503972876099,-0.377620767118447,-0.319660973195767,0.837867357535116,0.442487461282981,0.319660973195767,-0.837867357535116,-0.442487461282981,-0.165061885880001,0.872133628932245,0.460583876308334,0.165061885880001,-0.872133628932245,-0.460583876308334,-0.978227201428168,0.202348034104243,0.0461174097295397,-1,3.41274386922475e-16,1.43660819435338e-15,1,-3.41274386922475e-16,-1.43660819435338e-15,0.978227201428168,-0.202348034104243,-0.0461174097295397,-0.909402416903602,0.405518635920207,0.0924222919608763,0.909402416903602,-0.405518635920207,-0.0924222919608763,-0.783622247195287,0.605705504942669,0.138047147680623,0.783622247195287,-0.605705504942669,-0.138047147680623,-0.588320272074906,0.788410787189444,0.179687751694518,0.588320272074906,-0.788410787189444,-0.179687751694518,-0.319660973195766,0.923841901846845,0.210554037262504,0.319660973195766,-0.923841901846845,-0.210554037262504,-0.165061885879989,0.961624275216606,0.219165068256507,0.165061885879989,-0.961624275216606,-0.219165068256507,-0.978227201428169,0.207389255988906,-0.0078255278659171,-1,3.38948837437484e-16,1.43653552093198e-15,1,-3.38948837437484e-16,-1.43653552093198e-15,0.978227201428169,-0.207389255988906,0.0078255278659171,-0.909402416903602,0.415621572828342,-0.0156828673902944,0.909402416903602,-0.415621572828342,0.0156828673902944,-0.783622247195289,0.620795821291407,-0.0234248152123422,0.783622247195289,-0.620795821291407,0.0234248152123422,-0.588320272074906,0.808052953381371,-0.0304906870593525,0.588320272074906,-0.808052953381371,0.0304906870593525,-0.319660973195763,0.946858147268641,-0.0357282964404237,0.319660973195763,-0.946858147268641,0.0357282964404237,-0.165061885879992,0.985581816304203,-0.0371894770096083,0.165061885879992,-0.985581816304203,0.0371894770096083,-1,3.38367450066236e-16,1.43486403223964e-15,-0.978227201428169,0.198297242804875,-0.0612351686696155,0.978227201428169,-0.198297242804875,0.0612351686696155,1,-3.38367450066236e-16,-1.43486403223964e-15, +-0.909402416903604,0.397400586395346,-0.122719265246002,0.909402416903604,-0.397400586395346,0.122719265246002,-0.783622247195286,0.593579928332744,-0.183300415659933,0.783622247195286,-0.593579928332744,0.183300415659933,-0.588320272074902,0.772627646171004,-0.238591235878369,0.588320272074902,-0.772627646171004,0.238591235878369,-0.319660973195768,0.905347574711147,-0.279575805784726,0.319660973195768,-0.905347574711147,0.279575805784726,-0.16506188588,0.94237358536163,-0.291009620876019,0.16506188588,-0.94237358536163,0.291009620876019,-1,3.40692999551227e-16,1.43428264486839e-15,-0.978227201428169,0.175691600225386,-0.110471733924364,0.978227201428169,-0.175691600225386,0.110471733924364,1,-3.40692999551227e-16,-1.43428264486839e-15,-0.909402416903603,0.352097406735037,-0.221392547978353,0.909402416903603,-0.352097406735037,0.221392547978353,-0.783622247195284,0.525912544195417,-0.330684395698554,0.783622247195284,-0.525912544195417,0.330684395698554,-0.5883202720749,0.684549041701638,-0.430432186262929,0.5883202720749,-0.684549041701638,0.430432186262929,-0.319660973195772,0.802139061094697,-0.504370685985665,0.319660973195772,-0.802139061094697,0.504370685985665,-0.165061885880004,0.834944151922643,-0.524997939995878,0.165061885880004,-0.834944151922643,0.524997939995878,-1,3.44762711149962e-16,1.43021293326966e-15,-0.97822720142817,0.14111286543463,-0.152179833075343,0.97822720142817,-0.14111286543463,0.152179833075343,1,-3.44762711149962e-16,-1.43021293326966e-15,-0.909402416903605,0.282799370674205,-0.304978294434466,0.909402416903605,-0.282799370674205,0.304978294434466,-0.783622247195283,0.422405089282741,-0.455532780652123,0.783622247195283,-0.422405089282741,0.455532780652123,-0.588320272074896,0.549819551311085,-0.592939894476496,0.588320272074896,-0.549819551311085,0.592939894476496,-0.319660973195766,0.644266096062121,-0.69479353744865,0.319660973195766,-0.644266096062121,0.69479353744865,-0.16506188588,0.670614654340582,-0.723208517105129,0.16506188588,-0.670614654340582,0.723208517105129,-1,3.43599936407466e-16,1.4331198701259e-15, +-0.978227201428169,0.0969175220645334,-0.183517128091313,0.978227201428169,-0.0969175220645334,0.183517128091313,1,-3.43599936407466e-16,-1.4331198701259e-15,-0.909402416903602,0.194229024849974,-0.367780274125346,0.909402416903602,-0.194229024849974,0.367780274125346,-0.783622247195285,0.290111425592854,-0.549337359407764,0.783622247195285,-0.290111425592854,0.549337359407764,-0.588320272074898,0.377620767118447,-0.715039728760993,0.588320272074898,-0.377620767118447,0.715039728760993,-0.319660973195765,0.442487461282975,-0.837867357535119,0.319660973195765,-0.442487461282975,0.837867357535119,-0.165061885879997,0.460583876308328,-0.872133628932249,0.165061885879997,-0.460583876308328,0.872133628932249,-1,3.42727855350594e-16,1.42846877115591e-15,1,-3.42727855350594e-16,-1.42846877115591e-15,-1,3.38149429802018e-16,1.42905015852716e-15,1,-3.38149429802018e-16,-1.42905015852716e-15,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-1,0,-2.25360372937139e-15,-0.965925826289069,0,0.258819045102518,-0.965925826289069,0,0.258819045102518,-1,0,-2.25360372937139e-15,0.965925826289069,-0,-0.258819045102518,0.965925826289069,-0,-0.258819045102518,1,-0,2.25360372937139e-15,1,-0,2.25360372937139e-15,0.500000000000008,0,0.866025403784434,0.25881904510251,0,0.965925826289071,0.500000000000008,0,0.866025403784434,0.25881904510251,0,0.965925826289071,-0.500000000000008,-0,-0.866025403784434,-0.25881904510251,-0,-0.965925826289071,-0.500000000000008,-0,-0.866025403784434,-0.25881904510251,-0,-0.965925826289071,0.965925826289068,0,-0.25881904510252,1,0,-2.2256086519879e-15,1,0,-2.2256086519879e-15,0.965925826289068,0,-0.25881904510252,-1,-0,2.2256086519879e-15,-1,-0,2.2256086519879e-15,-0.965925826289068,-0,0.25881904510252,-0.965925826289068,-0,0.25881904510252, +0,0,-1,0.258819045102527,0,-0.965925826289067,0,0,-1,0.258819045102527,0,-0.965925826289067,-0,-0,1,-0.258819045102527,-0,0.965925826289067,-0,-0,1,-0.258819045102527,-0,0.965925826289067,-0.258819045102527,0,-0.965925826289067,-0.258819045102527,0,-0.965925826289067,0.258819045102527,-0,0.965925826289067,0.258819045102527,-0,0.965925826289067,0.707106781186547,0,0.707106781186547,0.707106781186547,0,0.707106781186547,-0.707106781186547,-0,-0.707106781186547,-0.707106781186547,-0,-0.707106781186547,-0.500000000000004,0,0.866025403784436,-0.707106781186549,0,0.707106781186546,-0.500000000000004,0,0.866025403784436,-0.707106781186549,0,0.707106781186546,0.500000000000004,-0,-0.866025403784436,0.707106781186549,-0,-0.707106781186546,0.500000000000004,-0,-0.866025403784436,0.707106781186549,-0,-0.707106781186546,-0.499999999999992,0,-0.866025403784443,-0.499999999999992,0,-0.866025403784443,0.499999999999992,-0,0.866025403784443,0.499999999999992,-0,0.866025403784443,0.866025403784438,0,0.500000000000001,0.866025403784438,0,0.500000000000001,-0.866025403784438,-0,-0.500000000000001,-0.866025403784438,-0,-0.500000000000001,-0.965925826289069,0,-0.25881904510252,-0.965925826289069,0,-0.25881904510252,0.965925826289069,-0,0.25881904510252,0.965925826289069,-0,0.25881904510252,-0.707106781186546,0,-0.707106781186549,-0.866025403784442,0,-0.499999999999993,-0.866025403784442,0,-0.499999999999993,-0.707106781186546,0,-0.707106781186549,0.866025403784442,-0,0.499999999999993,0.866025403784442,-0,0.499999999999993,0.707106781186546,-0,0.707106781186549,0.707106781186546,-0,0.707106781186549,0.965925826289069,0,0.258819045102518,0.965925826289069,0,0.258819045102518,-0.965925826289069,-0,-0.258819045102518,-0.965925826289069,-0,-0.258819045102518,0.866025403784443,0,-0.499999999999992,0.866025403784443,0,-0.499999999999992,-0.866025403784443,-0,0.499999999999992,-0.866025403784443,-0,0.499999999999992,-0.258819045102511,0,0.965925826289071,-0.258819045102511,0,0.965925826289071,0.258819045102511,-0,-0.965925826289071,0.258819045102511,-0,-0.965925826289071, +-0.866025403784437,0,0.500000000000002,-0.866025403784437,0,0.500000000000002,0.866025403784437,-0,-0.500000000000002,0.866025403784437,-0,-0.500000000000002,0.707106781186545,0,-0.70710678118655,0.707106781186545,0,-0.70710678118655,-0.707106781186545,-0,0.70710678118655,-0.707106781186545,-0,0.70710678118655,0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,0.499999999999996,0,-0.866025403784441,0.499999999999996,0,-0.866025403784441,-0.499999999999996,-0,0.866025403784441,-0.499999999999996,-0,0.866025403784441,0,0,1,0,0,1,-0,-0,-1,-0,-0,-1 + } + } + LayerElementUV: 0 { + Version: 101 + Name: "" + MappingInformationType: "ByPolygonVertex" + ReferenceInformationType: "IndexToDirect" + UV: *2496 { + a: -2.22889623194163,4.94485515491462,-1.65532570962361,4.65821409340907,-1.62796211820158,4.96642249187613,-2.24306066914648,4.78531474814698,-1.85004675285953,4.9659513258978,-1.31169613420979,4.54828603161074,-1.27687689050803,4.98448551156268,-1.87466767619684,4.65751171567376,-0.889963003741073,4.98443414474227,-1.45766789804671,4.53353072855837,-0.924708026273064,4.44962919667924,-1.4292987059451,4.97019714011507,-0.464938495449079,4.97189499302442,-0.996313489444281,4.4275028568388,-0.490766636123596,4.3746983197576,-0.973156612023798,4.96293474615021,-2.10263122664281e-14,4.95828557452188,-0.498495478860586,4.35754189766298,-0.00946555295739218,4.33951652601362,-0.489352456798956,4.95522690212541,-2.54744055705391,4.8610673277229,-1.93104593233932,4.8842056787863,-1.9577835203924,5.04212614629453,-1.67394128263705,5.17191738078863,-2.22547647670406,4.84487736501279,-1.62454310086877,4.86646525252767,-2.25104685717419,5.00299102133485,-1.33645439480956,5.29975485065767,-1.84665831993718,4.84813815318422,-1.27349005033672,4.86672152934463,-1.89118083488689,5.15433895116442,-0.887856331859623,4.87961859344933,-1.47861587915348,5.29986363509297,-1.42719011224338,4.86530897047641,-0.950839776140141,5.41183719027776,-0.464309147812425,4.89789858084395,-1.01461627175572,5.42314542902244,-0.972526026312951,4.8888683845015,-0.511254716534029,5.49380719211677,-2.10206131703644e-14,4.91059740631861,-0.50600215446225,5.50503203469246,-0.489352270236512,4.90750903030939,-0.0172372285455016,5.52919874000346,-2.53451280785768,4.81455369054366,-1.94489964164528,4.99575532104397,-2.01143024265092,5.14145175820956,-1.77054263776738,5.32311526774572,-2.22358516872501,4.8693546399289,-1.64683749755594,5.03949894010147,-2.28761966125261,5.01616525412165,-1.46949920272772,5.49385724815895,-1.86367746000996,4.93807924559101,-1.30974093298399,5.08647577915134,-1.97664361589637,5.22614144485602,-1.09828806154708,5.63306541754739,-1.46212322710947,5.00598750369212,-0.935332294612625,5.12250791139725,-1.5951760536539, +5.42285596183071,-0.508686021165608,5.13997085836523,-1.12277289479413,5.58899145234874,-1.01138821752192,5.06476153834877,-0.632919485865297,5.72467335165596,-0.0186528372538131,5.13595913794231,-0.55211223489019,5.70588174567411,-0.507315590943606,5.10980774011539,-0.0650297356940315,5.75306035765887,-2.51794655146868,5.25832080537305,-2.33582934374834,4.66898979539721,-2.36007434364314,5.28534188361228,-2.5107341447143,4.7684943663624,-1.98790995971785,5.09580551534724,-2.08980713242066,5.21938034639342,-1.91133392574998,5.40794480188922,-2.23479617654793,4.85430374983299,-1.71988101993878,5.16486669123834,-2.33389949307624,4.98013023880097,-1.67256859028094,5.54902519134055,-1.92179091550383,4.91486912280303,-1.41968071687419,5.19191163863482,-2.1006096456696,5.16738653757487,-1.34194485208158,5.62582386308317,-1.5643805346546,4.93580567139316,-1.07432782106004,5.16149135962184,-1.78288892548172,5.31493157288294,-0.641049342082162,5.08530564546506,-1.31778856071161,5.43279120221954,-1.12581010242858,4.93242351679339,-0.855173489175781,5.6433932810951,-0.0762850768984617,5.00210782490419,-0.642890652119008,5.53908904418414,-0.562507446684621,4.94676354271067,-0.159503894789691,5.61532830762913,-2.47703388500934,4.72668131068946,-2.05678500209208,5.17819940896878,-2.18720313520701,5.27117727315017,-2.08502914234847,5.42445342740957,-2.25376019593798,4.80584525274021,-1.83706187253447,5.23937664301415,-2.38211749991785,4.90164804595595,-1.93403225509439,5.46626914557294,-2.01064813702936,4.78921989087443,-1.59734066748949,5.18676755187731,-2.24872504179326,4.98685736312906,-1.68881972993344,5.38670568031787,-1.73169958771977,4.66299022826429,-1.31362386392297,5.00401571286104,-2.03804572949552,4.97545527824815,-1.63699768318943,4.9366358162398,-0.902314343723609,4.73924642215917,-1.22902064529844,5.23982004503893,-1.34408082659468,4.48783378395151,-0.822284495260748,5.00291832485256,-0.208746171416185,4.52025754034199,-0.347945193055325,5.12324042936896,-0.68782856526534,4.42048157953102,-2.43498022170874,4.69349452707607, +-2.14634329996243,5.23862427683461,-2.29642625060153,5.29456067464838,-2.27517904975131,5.3809076808036,-2.273337144743,4.73970346247755,-1.98692463167413,5.26843291261033,-2.42254861120966,4.79792468668137,-2.2261365557266,5.26857783977936,-2.11038123927247,4.597111985573,-1.82472148668125,5.09437018097639,-2.3942245566649,4.7202954024472,-2.11532141609385,4.93549802985484,-1.93860505757275,4.2323806382509,-1.6424186253095,4.68333439343629,-2.32472856935935,4.43827138522094,-1.81576780340595,4.48276191917622,-1.69053709416644,3.73240237092782,-1.34922707134059,4.10906323743435,-2.10882607130355,4.06745144295913,-0.793597366882632,4.27385807666868,-0.995431023714121,3.51976664806043,-0.543616751409509,3.70775347151846,-1.23689375627126,4.06658170655621,-2.4094074335959,5.28959680532676,-2.38689127903784,4.67317913892605,-2.24994190236392,5.27461291324839,-2.46180830446977,5.29451272645808,-2.28655605966322,4.67772030359326,-2.15387395938188,5.26422044796245,-2.44595460596304,4.69340074078169,-2.54719352119047,3.81218691003919,-1.99318963933964,4.27982184953699,-2.52434398295481,4.35122641747356,-2.11350781568378,3.75388532445638,-2.50181620401035,3.335096961265,-2.0466179646026,2.72557522660391,-1.91588911190049,3.21677366624924,-2.57194582386704,2.83166099070115,-2.14412933971546,2.5432952001497,-1.85844224184875,1.81681492523311,-1.60670977635094,2.23646471763909,-2.37754967765554,2.11319041258284,-2.32097158959223,5.24222298566723,-2.44684356251943,4.6134921301777,-2.28918671041814,4.64174261085383,-2.62554123986435,5.18764724788692,-2.28545905310624,4.83741927871761,-2.5403728947816,4.20552955734626,-2.23692013723097,4.26600771006331,-2.71460605837386,4.75189025491787,-2.77140399145076,3.82276805968224,-2.17082275097528,3.41668320237549,-2.25085151963176,3.95023834306856,-2.59585206440898,3.3126041518207,-2.54654609715617,1.7592464969741,-2.18970765921626,2.43110102839648,-2.75071149230548,2.22473809889872,-2.04356382061612,1.94426643792655,-1.79733334736392,-0.787687194234479,-1.72837484814511,-0.0101041227135874, +-2.15730393080435,-0.456180992920636,-1.38301966877687,-0.356810024791312,-2.61447831571456,5.20416675632401,-2.28543044353695,4.68243386059827,-2.46905689678925,5.27129635926241,-2.47398860892248,5.21610930839029,-2.42575833280846,4.57671890911988,-2.28154845296159,4.64641312141524,-2.75258070362274,5.08147042919237,-2.45065406931533,4.78365282838732,-2.50982919893599,4.10485684233049,-2.23728636374273,4.25135457612174,-2.83608784317326,4.57647374640281,-2.36188190489788,3.85830995326938,-2.47196127397366,3.14173108793161,-2.10682088604448,3.38288428228168,-2.80908572235207,3.56295881526947,-2.50122950794384,1.93703938375925,-1.74149453323444,1.97608999691007,-2.07687965571729,2.3580360135878,-2.12195620235891,1.5986347447404,-1.34163109563509,0.0303767843925122,-0.676517274141788,0.439050630128865,-1.13381286979346,0.613280135809055,-0.877254265655787,-0.123990771234836,-2.69270336452733,5.13135107250885,-2.23957930942005,4.71283427792336,-2.56967363076624,5.2339057276133,-2.60436412226067,5.19262380525396,-2.38894336548321,4.58868660672863,-2.26826680858825,4.69400014474201,-2.83749332812565,4.98917367280397,-2.56211245220563,4.8164025648123,-2.43320989445663,4.14733618749371,-2.21118069455564,4.36284539243048,-2.87610915794846,4.51162652437447,-2.37559991113266,4.03469389482605,-2.27665473861468,3.31649295457305,-1.99549566079849,3.65180167650533,-2.71994804973322,3.62402625730662,-1.73116443056091,2.1451813298125,-1.8978950622664,2.88742325710794,-2.18924261017214,2.36547731571075,-1.46994936523233,2.6131452586669,-1.03339174879829,1.21099387603254,-0.435583296967275,1.71300559168247,-0.9135238101141,1.81811528840424,-0.551366834686384,1.12657133977956,-2.74796782751268,5.0443789277376,-2.20199490274563,4.75734011139339,-2.6556589984355,5.17527145138702,-2.70935440349547,5.16905497925544,-2.34566181457487,4.64096981285004,-2.25617853656485,4.77381000115726,-2.88222282199724,4.91242744194534,-2.63592854153308,4.9137985432017,-2.34197108134981,4.29909967525491,-2.18167829132095,4.56376437725711,-2.86261677914252, +4.53950613214877,-2.36023168911256,4.38176079777179,-2.0935304547959,3.70761453073558,-1.90006023744783,4.10010865940705,-2.59718334557664,3.90105562663007,-1.3029926386607,3.46570253076949,-1.96179136594745,3.08529956139423,-1.47008753252554,2.95648465450457,-1.77542122862843,3.65325830226138,-0.333874775450249,2.97594494535007,-0.889992095826276,2.4281089902429,-0.402790554623101,2.38217598793254,-0.818645231194206,3.04282384852419,-2.77736805920925,4.94780238684663,-2.17581562300948,4.81137517852988,-2.72196283598472,5.09808223883072,-2.78983777542851,5.1345966679107,-2.30503228079787,4.71494219743632,-2.25183078196454,4.86601626269838,-2.89261517886931,4.8427439852725,-2.69077110092187,5.02718614741373,-2.26021837837495,4.49908574052134,-2.16681911225105,4.79407346926384,-2.82285760978999,4.61001050069242,-2.3550225003297,4.76816810984681,-1.95620790020104,4.16273466803086,-1.84701216440332,4.58647829019633,-2.48875941772578,4.24919028181478,-1.22075438590042,4.29792839617742,-1.81664617257089,3.82502760239206,-1.31136792651664,3.76971183517196,-1.71557990048438,4.41417662263924,-0.290334990449654,4.08564590287661,-0.815527103995951,3.50809594694279,-0.326538269053973,3.48898831092795,-0.778046712004154,4.12580133974808,4.46426119763171,4.23960635191711,3.95825904316948,4.83404098029096,3.97490892739521,4.23651797590791,4.44702396908623,4.85820768560196,-2.50277253822791,5.00601537349182,-2.1934664845617,4.39889474971273,-2.06778148646211,4.95842177175816,-2.50105160702078,4.43254850823971,-3.04432218050853,6.04931298051545,-3.60043950088455,5.50147702540831,-3.11323795968139,5.45554402309792,-3.52909263625248,6.11619188368958,2.18203899448129,4.79514412464058,1.59242582826888,4.61394249414027,1.65895642927453,4.46824605697469,-0.336141590530005,3.34489094756542,0.0580366667522183,3.90066895013335,-0.495899860273736,3.75227241657303,0.171002822638631,3.61260675086834,2.37315788842623,4.0519981579504,2.35064173386817,4.66841582435112,2.21369235719424,4.06698205002879,0.703173614666716,3.90782898155663,1.15621614562434, +4.36158960937345,0.579468474455271,4.19144530920089,1.22025063815194,4.21477899518071,4.54447542402923,4.84805997588416,4.90831058959162,5.47513788973943,4.41142259748481,5.26492843402274,5.07126635652607,4.96458038358928,2.34780556007937,2.84187597775229,2.17255331527282,3.45866840061712,2.03987121499148,2.87216825624791,2.33195186157264,3.44298796342867,2.29182296067912,1.43279475798321,1.9825169070129,2.03991538176227,1.85683190891332,1.48038835971686,2.29010202947198,2.00626162323532,2.29965697134313,4.67674859975451,2.01102004959681,4.13161884999597,2.16110300023592,4.07568245218221,1.85188859800938,2.88562359529042,1.85004669300108,3.52682781361649,1.5636341799322,2.99809836348371,1.99925815946773,3.46860658941268,1.45399427836959,1.49064452561361,1.33823896191545,2.16211037981996,1.05257920932423,1.66485218441658,1.62208227930787,2.03892696294575,0.853874552246961,-0.0766902839841634,0.677158193725866,0.626427107619782,0.380971761462608,0.175473352434376,1.06328170551247,0.420536360649737,-0.376411439900066,-0.875583283849433,-0.251180730660499,-1.62594283209781,0.0418775372370734,-1.2106323558807,-0.717721462725873,-1.25224415035597,-2.82216087960071,-1.47812331387152,-2.12888387473899,-1.83695154890929,-2.3703466072961,-1.29013649041351,-2.5721802641276,-2.04422791902174,1.38850638500383,3.09965863064065,1.55723743859335,3.71826680531002,1.14053911518983,3.28473541503607,1.68559474257321,3.62246401209428,0.69519465998538,1.8976758557496,0.771810541920351,2.57472511044809,0.358503072380475,2.17717744944523,1.00988744668424,2.37708763819346,-0.22558421081883,0.658355357665142,-0.182704353032513,1.38207080971872,-0.600780076829294,1.04104532512197,0.123641788743257,1.06960575973488,-1.42462017920239,0.460141717749106,-1.5396803604986,-0.291844543338313,-1.13170332260764,0.0113396854608165,-1.86638666207345,0.208729079541444,-3.37629147234286,0.4577053739249,-2.7627531484983,-0.0249554105856957,-2.8972090784937,0.557481334735846,-3.23709245070373,-0.145277515102073,-2.1112496490884,2.81012353763934,-2.72533652271693, +3.25914413162285,-2.60110305801723,2.67444163833212,-2.2226343263606,3.3343534516393,-3.11686601134747,2.93129978123183,-3.65032540898385,3.50122238896364,-3.60394851054363,2.88412116924708,-3.16166265529406,3.52737378679055,3.4311695270915,4.95427028965104,3.98270472115852,5.28131030542688,3.40559914662136,5.1123839459731,4.03210290292679,4.97585817716592,4.00740278687202,4.59804026312215,3.43383226455401,4.88468132462773,3.41966782734915,4.72514091786008,4.03476637829406,4.90624866158923,5.08637135529469,5.03793988042667,4.51866646098905,4.58703646424276,5.0516263327627,4.50313493236362,4.54703565309067,5.02370287579946,-1.45577236561775,2.88133101801244,-1.09193720005536,3.50840893186771,-1.6187281325522,3.39188852416257,-0.958884373510924,3.09154047372912,4.45769519652093,5.33099081681677,3.95919971766037,4.73024713995787,4.44822964356355,4.71222176830849,3.96834273972199,5.32793214442031,4.13492221408481,4.9144387083622,4.64512613921243,5.36605540583565,4.09039969913511,5.22063950634241,4.70809048368527,4.93302208452261,5.09237703279083,4.78670080005803,4.50161748549698,5.20694584170166,4.55304325240708,4.77239117708511,5.02939358851031,5.31891939688645,4.14217193123143,2.65756767152551,4.80728575272476,3.0662415172618,4.34290892274548,3.22060907288919,4.59946752688308,2.48333816584528,4.46516377916012,4.92080397032172,4.68759946173313,5.61082216201175,4.24665538833299,5.29992987181152,4.95521649275468,5.14648965855042,2.2117776789038,4.74331242790815,1.68895349390735,4.4160012789233,1.79085066661016,4.29242644787712,0.996527476989996,3.45523172212111,1.31998972778794,4.00887277417733,0.805074571178797,3.69830983277198,1.41909304431626,3.88304628520936,0.089730764688408,2.55554656071016,0.338953089911296,3.18970262924766,-0.163157108718334,2.91266011341588,0.517771820077059,2.93718521447582,-0.980875315776658,1.72523602278635,-0.758439633203638,2.41525421447637,-1.2484923467982,2.18956852624769,-0.539931242376526,2.03612831298659,-1.76902570089985,1.44687056278242,-2.4457649195293,1.7943561195369,-2.23164077243567, +1.23626848390686,-1.96100415918289,1.94723824820858,-3.00301465381845,1.56400895463692,-3.56962022903901,2.10099017391686,-3.48640141114777,1.48776969119193,-3.08339785925285,2.15633445611038,2.25209864990563,4.70246510414208,1.83184976698837,4.25094700586275,1.96226790010331,4.15796914168136,3.1638351817685,4.9404286455556,3.1370975937154,5.09834911306385,2.5474405570539,4.9172902944922,3.1654742515959,4.89726768181079,2.54907953544303,4.87413176674763,3.15065070034971,4.73778716575516,4.08747115304566,5.14848467260138,4.48164941032788,5.7042626751693,3.97450499715923,5.43654687186638,4.64140768007161,5.29688120616169,-3.33110494066048,6.01313223495711,-2.96894796523278,5.32158828633241,-2.85316442751366,5.90802253823531,-3.45097287934469,5.4060108225854,4.56784580502815,2.58079406206015,4.00124022980761,3.11777528134011,4.081623435242,2.52544977986664,4.48462698713692,3.19401454478508,5.03822613488218,5.17514567263525,4.50685114088698,4.63075353644961,5.01239799420767,4.57794899936841,4.53000801830746,5.16618542576103,3.38337911697251,5.15827231938563,3.83642164793013,5.61203294720244,3.31934462444491,5.30508293357837,3.96012678814159,5.32841661955819,1.26469101205816,5.51311141937241,0.900998423137554,6.04119658577781,0.728130004635784,5.78456904846771,1.35417429006818,5.64595160767962,-1.35726120883224,6.72727651325739,-2.07655445377204,6.47960857030124,-1.61847627416082,6.25931258440298,-1.78520690586631,7.00155451169843,5.10483031646943,4.05108736591881,4.42809109783998,4.39857292267327,4.62006955612302,3.89820523724712,4.89070616937581,4.60917500154885,3.37003361289464,3.42314494177418,3.15461285611718,4.02708214029951,3.03393629922222,3.92176860228613,3.60316281875961,3.62659507422418,2.20199490274567,5.00482956170627,1.7483308070558,5.4227609016999,1.6560219779786,5.29186837805049,2.98069204928686,3.11331327736131,2.93246177317284,3.75270367663172,2.78825189332597,3.68300946433636,3.25928414398712,3.24795215655923,3.36893590194802,2.1267377543418,3.4281110315687,2.8055337403986,3.15556819637543,2.65903600660737, +3.75436967580595,2.33391683632628,3.83937394956851,1.30908247670059,3.94945331864428,2.02566134203836,3.58431293071511,1.78450814768832,4.2865777670227,1.60443361470052,4.40543581442528,1.08875389607206,4.45051236106688,1.84815516491945,4.07005069194242,1.47069991274975,4.82978566665182,1.50975052590061,5.08523984545089,4.30758160391279,4.47115297182236,4.75660219789632,4.58253764909457,4.23237228389634,4.9610063807512,4.89228409720354,2.94080710040037,4.31952475313844,2.48768304529308,4.73804154772393,2.81777736663927,4.21697009803399,2.52384065571189,5.65563407624141,2.36437512447989,5.6706179683198,2.38689127903796,5.05420030191908,0.24230012048469,5.93774469148408,-0.0516573396985611,6.55244355943086,-0.278345577308011,6.17815114837793,0.402592910513559,6.20240939348626,-0.876793381402844,6.1630751906192,-1.14349461571949,6.8372214576554,-1.38044627218357,6.3565162865137,-0.683323164054754,6.55556931929067,-1.89060214486895,6.54267041204136,-2.54940087215571,6.1622674426661,-2.05769703873378,6.03345253577645,-2.36303073483668,6.73022618353325,2.89728276792651,5.46949521909633,2.76686463481156,5.56247308327771,2.47703388500925,5.017977120817,3.0971667293469,5.51369879256438,3.26589778293642,6.13230696723374,2.96880942536702,5.60950158578012,3.5138650527504,5.94723018283834,3.69694914017229,5.61396030002887,3.77356502210727,6.29100955472736,3.4588722354084,5.81159777228348,4.11025660971216,6.01150796103172,4.24870225001188,5.11388641437681,4.29158210779822,5.8376018664304,3.94235610823613,5.42635146436067,4.66677797380868,5.45491189897355,5.04072686887855,4.00294929018061,4.30604352941274,4.20033868426123,4.59896038600749,3.75153665197293,4.71402056730369,4.50352291306036,4.20360832016857,1.58323400650994,4.54349169237859,2.28599285634785,4.06915239017315,2.16567075183148,4.68269071401772,1.68300996732087,2.72361714345517,5.58496416659746,2.57353419281608,5.64090056441123,2.43498022170886,5.03983441683893,2.85709796103502,5.66710956724802,2.85525605602671,6.30831378557408,2.70788649456838,5.72533079145183,3.14351047410391, +6.1958390173808,3.29687318297424,5.89803574640138,3.18111786652008,6.56950160060775,3.0130298655818,6.02121916327561,3.58253293556545,6.39529394180479,3.78138339308066,5.51801152377434,3.60466703455954,6.22112891537827,3.39525988129404,5.72390227074438,4.07756982534391,5.96896527895974,4.32005236613674,4.13041623245038,4.19482165689716,4.88077578069876,3.90176338899959,4.46546530448166,4.66136238896253,4.50707709895692,4.4114166550444,1.05111602189,4.61325031187588,1.80520745049824,4.16995392248726,1.59793108038577,4.86323092734902,1.23910284534803,2.58331686987734,4.08816374720047,2.401199662157,4.67749475717631,2.42544466205181,4.06114266896122,2.40359110793637,5.80726926220792,2.69567175451752,6.37808896938869,2.38773740942965,6.40838124788431,2.5629896542362,5.79158882501949,2.44007044859631,6.22181565916398,2.87334056915497,6.74768892268244,2.43834951738917,6.7952825244161,2.74765557105539,6.18816190063703,2.95967094972765,6.08622155476339,2.54883478245661,6.68356264778055,2.52598524422096,6.1445231403462,3.07998912607177,6.61215807984401,3.40280982291371,5.72379476738088,2.74675311094717,5.33868209183278,3.27208097021162,5.23259632773556,2.81688273080386,5.84211806239663,4.34988357248261,3.15550528529592,3.57904367117803,3.03223098023958,4.09815110698485,2.73585549288991,3.81246400911804,3.46233576780647,2.3358293437483,5.05942461216085,2.31158434385349,5.67577670037593,2.15371213602796,5.64875562213667,2.07833185159382,5.84002453277654,2.20420382452102,6.46875538826609,1.8996341742489,6.41417965048576,2.2359887036951,5.86827501345269,1.79375560374886,6.35451648540239,2.04866944542421,6.98640620677375,1.6195224401566,6.90087718297401,2.09720836129948,6.41499463811946,1.85950400957852,6.59476757180056,1.25892276910307,7.00085242910731,1.43447469614484,6.49068852124576,1.77947524092206,7.1283227124936,1.3254683725647,6.31430561432971,0.618320700875363,6.59477727530191,0.822486096024652,6.12928567337729,1.17932453396459,6.80114020479965,-0.704114664544156,5.46984919265494,-1.47839892657163,5.37047822452568,-1.11842834313123, +5.03897202321179,-1.04946984391235,5.81655509473268,2.28543044353693,5.05372067679513,2.10180399028463,5.64258317545926,1.95638257135932,5.57545357252087,1.76136745275596,5.80781835325299,1.71313717664195,6.4472087525234,1.43454508194168,6.31256987332548,1.90557733260282,5.87751256554835,1.16379789005381,6.36450442779296,1.22297301967448,7.04330041384979,0.837539245816533,6.8361213318653,1.43634072524707,6.51100216158421,0.400688051153458,6.60497103509533,0.510767420229244,7.3215499004331,0.063563602775047,7.02619876243318,0.765828439082642,6.84612422944539,-0.704523653383229,7.08814041251166,-0.749600200024839,6.32873914366428,-0.369138530900367,6.70619439583395,-1.12887350560978,6.66714378268312,-2.39147031282071,5.6215675533636,-3.05658413431405,5.21289370762731,-2.59220730433476,5.05852615199993,-2.84876590847237,5.79579705904383,2.23957930942003,5.03567929550337,1.90948498807384,5.55675074519331,1.78645525431274,5.45419609008886,1.48223164534064,5.69983416233335,1.26681088856318,6.30377136085868,1.03368168269821,6.10032122840869,1.6029082022356,5.80514770034673,0.631998262947704,6.22604720501122,0.503095705198703,6.89511358232981,0.189098999455884,6.59033754189199,0.854027462848694,6.44155640994798,-0.376777374422402,6.48324269843658,-0.475722546940407,7.20144363868958,-0.820070685540955,6.79077600117013,-0.0956182966062344,6.81855142036887,3.91297422007815,2.75380055495228,3.78407166232917,3.42286693227088,3.56204246242817,3.20735772733411,4.22697092582099,3.0585765953901,4.42996195472423,2.3885811309159,4.33101678220624,3.10678207116889,4.04985770439005,2.7714733492366,4.77431009332478,2.79924876843532,4.35686187293603,2.92390947272437,5.07615511787583,3.17157741568051,4.61807693826462,3.39187340157876,4.7848075699701,2.64963147428332,4.04522655101887,3.93673408138853,4.6430350028499,4.43874579703844,4.16101008873798,4.52316833329144,4.52316706416568,3.83162438466674,3.06462750602455,4.49447406290821,2.51865458125749,4.78151287925243,2.97231867694736,4.3635815392588,3.67515311499622,3.79940709072906,3.3114605260756, +4.32749225713445,3.22197724806559,4.19465206882724,3.84802153349799,4.05603462803915,4.29490838578165,3.40838384768169,4.0009509255984,4.02308271562849,3.84065813556953,3.7584180136263,4.5215966233911,3.78267625873465,4.76495601488812,3.32729309737827,4.49825478057148,4.00143936441451,4.30478456322339,3.60894523574301,5.0019076713522,3.80799826851999,5.10320326864326,4.28025410570219,4.4444045413565,3.89985113632693,4.91683313132423,3.71229536483506,4.61149943522134,4.40906901259186,4.54478221876423,5.17909780083677,3.98866489838819,4.63126184572959,4.47343535413216,4.56438294255547,4.05758067756106,5.22503080314711,3.14093022677461,4.69162512687625,2.53937779057484,4.828052335193,3.08552500355008,4.54134527489215,3.88820370994402,4.20069371825489,3.40339821531337,4.62034818872927,3.35019671648004,4.4692741234672,3.99098111338481,4.49254640089309,4.53982272201963,4.00612750298786,4.10926999947272,4.53422790988024,4.01587073334882,4.23924018113773,4.67190923088775,4.42330314970915,4.951205530029,4.03248616841555,4.55239092990036,4.63791961023151,4.44319519410264,4.21417598806607,5.0849424474251,4.55146399644759,5.07526270841369,4.92001281694895,4.4793709217432,4.44711202316357,4.97419643632717,4.33086379670175,4.56998446235943,4.97532858416904,4.4880974642154,5.45602217497841,3.96290535066911,4.87847221904459,4.45061707222361,4.83831678217314,3.99910862927343,5.47512981099327,1.06897677344044,4.93384175105772,0.495406251122418,5.22048281256329,0.468042659700387,4.91227441409622,1.08314121064529,5.09338215782539,-0.083324386769598,4.95676635155803,-0.621675005419338,5.37443164584509,-0.656494249121092,4.93823216589315,-0.058703463432297,5.26520596178208,-1.24605938329247,4.96155717515935,-1.75065006296451,5.4821251185952,-1.7853950854965,4.94732017053217,-1.21769019119085,5.39822358671605,-2.32997194760815,4.92643908930193,-2.81236192350834,5.51467551569453,-2.83819006418286,4.91747884242769,-2.30681507018766,5.46187097861334,-3.18954187347752,4.83960424544438,-3.6694287773191,5.45531462155619,-3.67889433027647,4.83654557304792, +-3.1803988514159,5.43728924990682,3.95097638615183,5.36838894535311,4.20019871137471,6.00254501389062,3.77215765598606,5.62090636012496,4.45308658478147,5.64543146118488,2.16539395059119,4.85260580525615,1.5489993258766,4.82946745419275,1.57573691392968,4.67154698668452,0.524394842719614,4.40858630600666,1.07593003678663,4.73562632178249,0.474996660951337,4.71403843426762,1.10150041725676,4.57751266546044,-0.582883349510165,4.16369861070791,-0.0726794243825477,4.61531530818137,-0.645847693982995,4.59673193202096,-0.0281569094328393,4.30911451020116,-1.18380400574961,4.09348517533485,-1.77456355304347,4.51373021697851,-1.71158010876294,3.98151162015005,-1.2352297726597,4.52803983995141,-2.28138794417252,3.98821469399731,-2.83169506811581,4.51346154217579,-2.78474949939422,3.91755293090298,-2.32347818961529,4.52249173851827,-3.17189502653145,4.0373734115246,-3.67789718099367,4.63180803989844,-3.66065995244819,4.0132067062136,-3.18854491075717,4.63489641590765,1.63598877736289,-0.106788931521202,2.18999265921371,0.360846007976608,1.75630695370702,0.419147593559413,2.16714312097806,-0.178193499457753,1.26143627829999,-1.86032309026825,1.91749299026654,-1.47521041472016,1.39216513100209,-1.36912465062293,1.84736337040985,-1.97864638528401,-0.217552321414542,-3.59631628979155,0.553287579890039,-3.47304198473524,0.0341801440832179,-3.17666649738555,0.319867241950004,-3.90314677230211,2.52636333273842,2.91660566651485,2.65223530566561,3.54533652200439,2.49457845356433,3.51708604132825,2.83093298301055,2.97118140429517,2.66455016580842,1.65738790926125,2.91946400748378,2.2892776306326,2.61601124993314,2.22879947791553,3.09369717107604,1.742916933061,2.88852073909218,0.346036664884572,3.23352128386942,0.983670856132431,2.80849197043572,0.879591805577632,3.40907321091119,0.473506948270861,3.18496884945631,-0.293194776517677,3.89211652114567,-0.573666437489841,3.68795112599636,-0.108174835565239,3.33111268805646,-0.780029366987605,4.38052700835492,-0.263222813303038,4.44948550757377,0.514360258217849,4.03517182898671,0.0834830887746911, +4.80945609101418,0.182854056903988,3.03355832971073,5.31713670880995,2.93166115700791,5.44071153985611,2.51073414471428,4.98982555982509,2.77688055147588,4.18017930124392,2.44783267929827,4.70191219696966,2.63145913255057,4.11304969830552,2.17581562300938,4.96209054979058,1.62966841003412,5.24879761009143,1.57426318680961,5.09851775810735,1.12424994296865,5.25315257718193,0.639444448338006,5.67280704765631,0.536667044897204,5.38095436501809,1.17745144180197,5.40422664244399,0.00524351316338012,5.50908839027755,-0.425309209383514,6.03718879716996,-0.557395718251639,5.62001315044864,0.0986427792872919,5.80407611902007,-1.1509282497828,5.65574205217972,-1.54974284991144,6.26117549399569,-1.68347976730753,5.74219766596366,-1.04173251398508,6.0794856743452,-2.1747075369386,6.1323548259418,-2.77059932360906,5.65945403215642,-2.26532107755482,5.60413826493634,-2.66953305152257,6.24860305240361,-3.13734437086147,5.90814700493636,-3.66253648440776,5.33059704900255,-3.17354764946578,5.3114894129877,-3.62505609241597,5.94830244180786,2.16325880607623,4.90999340988167,1.56168764116954,5.04633801087415,1.54686408992336,4.88685749481851,3.27303843629781,5.34324865209353,3.59650068709574,5.89688970414976,3.1739351197695,5.46907514106149,3.78795359290694,5.65381159349888,4.50126963043368,3.49325118965536,3.9678102327973,4.06317379738717,4.01260687674388,3.46709979182844,4.45489273199344,4.11035240937193,5.04890603984231,4.5346868462412,4.49859891589901,5.05993369441967,4.54068916134179,4.52565664989875,5.00196047112071,5.13059545751401,3.12412597407014,5.13729886490045,3.0575953730645,5.28299530206604,2.53451280785774,4.95609723440013,4.67316497313243,4.51279675884624,4.13481435448269,4.9304620531333,4.11019343114538,4.62202244290924,4.70798421683419,4.94899623879818,-2.7796535222291,4.84625786888993,-2.16325880607624,4.86939378395309,-2.76482997098292,5.00573838494556,-2.84748332837086,5.07469494743408,-2.27391280605285,4.78805388592849,-2.25974836884799,4.94759429269615,-2.8748469197929,4.76648654896698,-2.73979383350324,5.10126158282064, +-2.20144321485349,4.68359628853357,-2.17682229151618,4.99203589875765,-2.774613077205,4.66506210286872,-1.87167756385307,4.56042796505358,-2.37626824352512,5.08099590848939,-2.4110132660571,4.54619096042637,-1.84330837175146,4.99709437661026,-1.22687945867549,4.43747459739706,-1.7092694345757,5.02571102378968,-1.73509757525022,4.42851435052282,-1.20372258125502,4.97290648670846,-0.289448409445489,4.35434402260621,-0.769335313287053,4.97005439871802,-0.778800866244429,4.35128535020975,-0.280305387383852,4.95202902706866,-2.78178857530579,4.9026134658953,-2.75505098725269,4.74469299838705,-2.16539395059119,4.92575181695869,-2.28162308717413,4.99804618701356,-2.83315828124115,4.67100617123774,-2.25605270670399,4.8399325306915,-2.88255646300942,4.97645829949867,-2.21558446976503,5.1071696891022,-2.72578839489266,4.65555299162875,-2.17106195481533,4.80096889112202,-2.78875273936549,5.08858631294181,-1.83919760059389,4.81655146587154,-2.42995714788773,5.23679650751519,-2.36697370360721,4.70457791068675,-1.89062336750397,5.25110613048811,-1.20259469997074,4.87074361750605,-1.75290182391405,5.39599046568453,-1.70595625519243,4.80008185441171,-1.24468494541351,5.405020662027,-0.280361862175763,4.91333251505055,-0.786364016638015,5.5077671434244,-0.769126788092523,4.88916580973956,-0.297011746401518,5.51085551943361,-2.77165216069373,4.79430516980301,-2.7051215596881,4.64860873263743,-2.18203899448134,4.97550680030333,-2.31601009387183,5.00378217844692,-2.76905262482946,4.55002155063012,-2.25197560134424,4.85697156425419,-2.89275776504091,4.83363787827438,-2.28183035978791,5.10645974634478,-2.67600861707014,4.55068174377684,-2.16886420390148,4.81839754707977,-2.83576688681387,4.95806321278444,-1.99041499686435,5.29670667534019,-2.35425016242674,4.66962876148492,-1.85736217031991,4.87983821720161,-2.51720592936118,5.18018626763507,-1.23713042793988,5.01679742454565,-1.85121730156838,5.46581801852916,-1.72698383686871,4.88111552523843,-1.34851510521207,5.54102733854561,-0.298831986559639,5.12547587143331,-0.832291384196014,5.6953984791651, +-0.7859144857558,5.07829725944853,-0.34362863050621,5.72154987699202,-2.73460186390027,4.6876963492945,-2.63270469119746,4.56412151824832,-2.21177767890383,5.01500749827934,-2.35823198753783,4.96096550711088,-2.68169423833576,4.40732445505467,-2.25912867100951,4.83513901814291,-2.87314714414696,4.65040256570554,-2.36813856055932,4.97793750141052,-2.61736088578222,4.343781432873,-2.18931983039356,4.72542008663868,-2.87024875918897,4.70089498557874,-2.14234361130184,5.10776064453118,-2.36477929387487,4.41774245284113,-1.92383522047472,4.72863474304139,-2.63239632489642,4.88207495630249,-1.34127683622845,4.84975436654454,-2.01801605485789,5.19723992329904,-1.80389190776427,4.63915228766901,-1.53325529451148,5.35012205197071,-0.35533492387025,4.97487847515973,-0.92194049909082,5.51185969443965,-0.838721681199577,4.89863921171472,-0.435718129304659,5.56720397663318,-2.67234753282292,4.59067522908493,-2.54192939970797,4.49769736490354,-2.25209864990566,5.04219332736425,-2.40064397200227,4.87682613910774,-2.56937502559178,4.25821796443836,-2.27228666802239,4.78102334589199,-2.81734229540576,4.4432947488338,-2.45811154506318,4.73462740881368,-2.53472742699818,4.05757815411518,-2.22003464029931,4.53698993655903,-2.87141901460307,4.3370797478108,-2.33429830925958,4.68500412281015,-2.37717816704592,3.96128867075657,-2.02795216748382,4.37253907282631,-2.75237403305638,4.34397863821338,-1.94531956150656,4.05851463436584,-1.83025938021036,4.81050089545325,-2.27202586308141,4.55908825724562,-1.5373425236156,4.36169886316497,-0.95845404861963,4.34718695256748,-0.618570676409607,5.04994580240541,-1.09765307025877,4.95016984159444,-0.484114746414191,4.46750905708385,-2.58829389308936,4.51145059440195,-2.43821094245027,4.4555141965882,-2.29965697134306,5.05658034416049,-2.43380750929313,4.76906997404341,-2.43196560428483,4.12786575571735,-2.28459604282649,4.71084874983961,-2.72022002236202,4.24034052391062,-2.52473090561731,4.41957834192562,-2.40897558916315,3.74811248771928,-2.24088758822486,4.29639492505141,-2.81039065820851,3.92232014652225, +-2.51993652923386,4.07218216506558,-2.34322017071274,3.36906477346162,-2.13381301744724,3.86629141809554,-2.81612296149711,3.62122840988015,-1.83481485493309,3.55228010821303,-2.59441385489603,3.51066831373777,-2.12787312283065,3.13696963199592,-2.25310383207023,3.88732918024431,-1.24747268086553,3.3969445912353,-1.045639024034,4.15103601984352,-1.49745329633863,3.96304919638554,-0.804176291476906,3.60422096134773,-2.48759111054218,4.4575298421717,-2.32812557931018,4.44254595009331,-2.35064173386826,5.05896361649403,-2.28958836354591,4.64689559985362,-2.58166901012707,4.07607589267285,-2.27373466503919,4.04578361417724,-2.44898690984574,4.66257603704207,-2.22912087104751,4.07302449588468,-2.66239099160617,3.54715123236623,-2.22739993984036,3.49955763063257,-2.53670599350658,4.10667825441164,-2.19163392047984,2.80366220122301,-2.60247008775086,3.4010032942402,-2.72278826409501,2.87506676915957,-2.16878438224418,3.34270170865737,-2.0923002773467,2.49936022250465,-2.74835698931326,2.11424754695656,-2.16242989720341,1.9959242519408,-2.61762813661115,2.60544598660188,-1.75478157341256,1.99837860402144,-2.52562147471714,1.87510429896511,-1.98820191135258,1.56827381645454,-2.27388900921938,2.29475409137111,-2.40119966215701,5.05091965038177,-2.37695466226219,4.43456756216669,-2.21908245443667,4.46158864040594,-2.28372359474004,4.6112547182641,-2.40959556766724,3.98252386277456,-2.10502591739512,4.03709960055488,-2.44138044684132,4.58300423758795,-2.17284671645101,3.94451547943369,-2.42776055812635,3.31262575806233,-1.99861355285874,3.39815478186207,-2.47629947400164,3.88403732671662,-1.89659198856349,2.50354292776006,-2.49717322903895,2.9096277850668,-2.41714446038247,2.37607264437374,-2.07214391560527,3.01370683562161,-1.75972572971534,1.26218221533127,-2.46687340140469,1.54265387630344,-2.32072956280456,1.05581928583351,-1.96389112486465,1.72767381725588,-1.17375323363792,-0.543405345489913,-1.94803749566539,-0.642776313619184,-1.60268231629717,-0.989482215696929,-1.53372381707832,-0.211899144176031,-2.44783267929821,5.03424234042376, +-2.26420622604591,4.44537984175963,-2.1187848071206,4.51250944469802,-2.26807089312034,4.61852562227672,-2.21984061700633,3.97913522300632,-1.94124852230607,4.11377410220423,-2.41228077296721,4.54883140998136,-2.08207972268643,3.96260978192169,-2.1412548523071,3.28381379586486,-1.75582107844915,3.49099287784934,-2.3546225578797,3.81611204813045,-1.87818009582411,3.03668946175474,-1.98825946489989,2.32011059641698,-1.5410556474457,2.61546173441691,-2.24332048375329,2.79553626740469,-1.19968265309827,1.47385216967798,-1.95941762780769,1.43480155652716,-1.62403250532483,1.05285553984945,-1.57895595868322,1.81225680869685,-0.873447352754612,0.509260656289733,-0.616888748616979,-0.228010250754166,-0.409070522775316,0.354893100662368,-1.07418434426864,-0.0537807450739496,-2.48768304529302,5.01047202570287,-2.15758872394683,4.48940057601292,-2.03455899018573,4.59195523111738,-2.24790113597453,4.67066355102173,-2.03248037919708,4.0667263524964,-1.79935117333211,4.27017648494638,-2.36857769286949,4.56535001300834,-1.98286003082015,4.12761713707628,-1.85395747307113,3.45855075975768,-1.53996076732831,3.7633268001955,-2.20488923072113,3.91210793213952,-1.67758466916924,3.38523073639064,-1.57863949665124,2.66702979613766,-1.23429135805069,3.07769743365709,-1.95874374698541,3.04992201445835,-1.26843623354287,2.50066166193389,-1.10170560183738,1.75841973463844,-0.810358053931659,2.28036567603564,-1.52965129887146,2.0326977330795,-0.158670374706782,1.66907965324611,-0.756478826537806,1.16706793759619,-0.27853831339099,1.06195824087441,-0.640695288818692,1.75350218949911,-2.51865458125749,4.9806567938471,-2.06499048556762,4.56272545385347,-1.97268165649043,4.69361797750288,-2.23048972355902,4.75650560536233,-1.86679713463842,4.22842043895693,-1.69392871613665,4.48504797626704,-2.31997300156904,4.62366541705513,-1.90127996473328,4.3939425999362,-1.60732250455001,3.7792437319894,-1.38063426694058,4.15353614304234,-2.06157275476215,4.12927789793399,-1.52793094437272,3.91667678118628,-1.26122971005605,3.24253051415007,-1.02427805359199, +3.72323568529178,-1.72140116172079,3.52418265251479,-0.592011030540132,3.2649337546265,-1.25080975782689,2.88453078525124,-0.778381167859173,2.69697501375937,-1.08371486396208,3.39374866151616,-0.0543506220534413,2.95411601385456,-0.610467942429473,2.4062800587474,-0.125697486685512,2.33940115557327,-0.541552163256598,3.00004901616492,-2.53937779057482,4.94541339312765,-1.99323057759957,4.6587063328268,-1.93782535437505,4.8089861848109,-2.22261587748422,4.85572808581025,-1.73781038285358,4.43607361533587,-1.63503297941277,4.72792629797409,-2.27581737631754,4.70465402054817,-1.85429513426101,4.69512186095512,-1.42374241171412,4.1670214540627,-1.29165590284599,4.58419710078401,-1.94769440038493,4.40013413221259,-1.44525477991645,4.48294825241775,-1.04644017978781,3.8775148106018,-0.912703262391721,4.39649263863384,-1.55445051571418,4.05920463025229,-0.488017212233791,4.20359291564793,-1.08390899890427,3.73069212186255,-0.589083484320281,3.61444389540074,-0.993295458288041,4.25890868286803,-0.0100338758116793,4.07920077175808,-0.535225989357954,3.50165081582426,-0.047514267803472,3.46149537895279,-0.499022710753649,4.09830840777293,-2.54907953544303,4.90525542708686,-1.94750837053634,4.7689108260944,-1.93268481929016,4.92839134215002,-1.48363628162332,2.47077565973539,-1.48363628162332,2.26698113603262,-1.47022125260326,2.36887839788401,-1.52296715662514,2.56572879158479,-1.52296715662514,2.17202800418322,-1.5855335434747,2.64726689441414,-1.5855335434747,2.09048990135387,-1.66707164630405,2.70983328126371,-1.66707164630405,2.02792351450431,-1.76202477815345,2.74916415626553,-1.76202477815345,1.98859263950248,-1.86392204000484,2.76257918528558,-1.86392204000484,1.97517761048243,-1.96581930185623,2.74916415626553,-1.96581930185623,1.98859263950248,-2.06077243370563,2.70983328126371,-2.06077243370563,2.02792351450431,-2.14231053653497,2.64726689441414,-2.14231053653497,2.09048990135387,-2.20487692338454,2.56572879158479,-2.20487692338454,2.17202800418322,-2.24420779838636,2.47077565973539,-2.24420779838636,2.26698113603262, +-2.25762282740641,2.36887839788401,-2.15670993297825,4.72440944881889,-2.05393340367112,0,-2.05393340367112,4.72440944881889,-2.15670993297825,0,2.67995820376849,4.72440944881889,2.57718167446136,0,2.67995820376849,0,2.57718167446136,4.72440944881889,2.15670993297821,0,2.05393340367108,4.72440944881889,2.05393340367108,0,2.15670993297821,4.72440944881889,-1.48738698680247,4.72440944881889,-1.5901635161096,0,-1.48738698680247,0,-1.5901635161096,4.72440944881889,-2.10578834101877,4.72440944881889,-2.2085648703259,0,-2.10578834101877,0,-2.2085648703259,4.72440944881889,2.97221883977762,4.72440944881889,2.86944231047049,0,2.97221883977762,0,2.86944231047049,4.72440944881889,0.0880552424900996,4.72440944881889,-0.0147212868170292,0,0.0880552424900996,0,-0.0147212868170292,4.72440944881889,-2.57718167446137,4.72440944881889,-2.6799582037685,0,-2.57718167446137,0,-2.6799582037685,4.72440944881889,3.06542969899279,0,2.96265316968566,4.72440944881889,2.96265316968566,0,3.06542969899279,4.72440944881889,-2.64329122593194,4.72440944881889,-2.54051469662481,0,-2.54051469662481,4.72440944881889,-2.64329122593194,0,-3.06542969899279,4.72440944881889,-2.96265316968567,0,-2.96265316968567,4.72440944881889,-3.06542969899279,0,2.95323861539671,0,2.85046208608958,4.72440944881889,2.85046208608958,0,2.95323861539671,4.72440944881889,1.52665444753675,0,1.42387791822963,4.72440944881889,1.42387791822963,0,1.52665444753675,4.72440944881889,-2.95323861539672,4.72440944881889,-2.85046208608959,0,-2.85046208608959,4.72440944881889,-2.95323861539672,0,0.866897171452931,4.72440944881889,0.764120642145804,0,0.866897171452931,0,0.764120642145804,4.72440944881889,-0.796062009724401,4.72440944881889,-0.693285480417275,0,-0.693285480417275,4.72440944881889,-0.796062009724401,0,0.79606200972443,0,0.693285480417299,4.72440944881889,0.693285480417299,0,0.79606200972443,4.72440944881889,-1.52665444753671,4.72440944881889,-1.42387791822959,0,-1.42387791822959,4.72440944881889,-1.52665444753671,0,1.48363628162332,2.26698113603262,1.48363628162332,2.47077565973539, +1.47022125260326,2.36887839788401,1.52296715662514,2.17202800418322,1.52296715662514,2.56572879158479,1.5855335434747,2.09048990135387,1.5855335434747,2.64726689441414,1.66707164630405,2.02792351450431,1.66707164630405,2.70983328126371,1.76202477815345,1.98859263950248,1.76202477815345,2.74916415626553,1.86392204000484,1.97517761048243,1.86392204000484,2.76257918528558,1.96581930185623,1.98859263950248,1.96581930185623,2.74916415626553,2.06077243370563,2.02792351450431,2.06077243370563,2.70983328126371,2.14231053653497,2.09048990135387,2.14231053653497,2.64726689441414,2.20487692338454,2.17202800418322,2.20487692338454,2.56572879158479,2.24420779838636,2.26698113603262,2.24420779838636,2.47077565973539,2.25762282740641,2.36887839788401,2.64329122593195,0,2.54051469662483,4.72440944881889,2.54051469662483,0,2.64329122593195,4.72440944881889,0.014721286816971,4.72440944881889,-0.0880552424901542,0,0.014721286816971,0,-0.0880552424901542,4.72440944881889,2.20856487032584,4.72440944881889,2.10578834101871,0,2.20856487032584,0,2.10578834101871,4.72440944881889,-0.7641206421458,4.72440944881889,-0.866897171452927,0,-0.7641206421458,0,-0.866897171452927,4.72440944881889,1.59016351610968,4.72440944881889,1.48738698680255,0,1.59016351610968,0,1.48738698680255,4.72440944881889,-2.86944231047045,4.72440944881889,-2.97221883977758,0,-2.86944231047045,0,-2.97221883977758,4.72440944881889 + } + UVIndex: *3720 { + a: 0,1,2,1,0,3,2,1,0,3,0,1,4,5,6,5,4,7,6,5,4,7,4,5,8,9,10,9,8,11,10,9,8,11,8,9,12,13,14,13,12,15,14,13,12,15,12,13,16,17,18,17,16,19,18,17,16,19,16,17,20,21,22,22,21,20,23,24,25,24,23,26,25,24,23,26,23,24,27,28,29,28,27,30,29,28,27,30,27,28,31,32,33,32,31,34,33,32,31,34,31,32,35,36,37,36,35,38,37,36,35,38,35,36,39,40,41,40,39,42,41,40,39,42,39,40,43,44,45,45,44,43,46,47,48,47,46,49,48,47,46,49,46,47,50,51,52,51,50,53,52,51,50,53,50,51,54,55,56,55,54,57,56,55,54,57,54,55,58,59,60,59,58,61,60,59,58,61,58,59,62,63,64,63,62,65,64,63,62,65,62,63,66,67,68,68,67,66,69,70,71,71,70,69,72,73,74,73,72,75,74,73,72,75,72,73,76,77,78,77,76,79,78,77,76,79,76,77,80,81,82,81,80,83,82,81,80,83,80,81,84,85,86,85,84,87,86,85,84,87,84,85,88,89,90,89,88,91,90,89,88,91,88,89,92,93,94,94,93,92,95,96,97,96,95,98,97,96,95,98,95,96,99,100,101,100,99,102,101,100,99,102,99,100,103,104,105,104,103,106,105,104,103,106,103,104,107,108,109,108,107,110,109,108,107,110,107,108,111,112,113,112,111,114,113,112,111,114,111,112,115,116,117,117,116,115,118,119,120,119,118,121,120,119,118,121,118,119,122,123,124,123,122,125,124,123,122,125,122,123,126,127,128,127,126,129,128,127,126,129,126,127,130,131,132,131,130,133,132,131,130,133,130,131,134,135,136,135,134,137,136,135,134,137,134,135,138,139,140,140,139,138,141,142,143,142,141,144,143,142,141,144,141,142,145,146,147,146,145,148,147,146,145,148,145,146,149,150,151,150,149,152,151,150,149,152,149,150,153,154,155,154,153,156,155,154,153,156,153,154,157,158,159,158,157,160,159,158,157,160,157,158,161,162,163,162,161,164,163,162,161,164,161,162,165,166,167,166,165,168,167,166,165,168,165,166,169,170,171,170,169,172,171,170,169,172,169,170,173,174,175,174,173,176,175,174,173,176,173,174,177,178,179,179,178,177,180,181,182,181,180,183,182,181,180,183,180,181,184,185,186,185,184,187,186,185,184,187,184,185,188,189,190,189,188,191,190,189,188,191,188,189,192,193,194,193,192,195,194,193,192,195,192,193,196,197,198,197,196,199,198,197,196,199,196,197,200,201,202,202,201,200,203,204,205,204, +203,206,205,204,203,206,203,204,207,208,209,208,207,210,209,208,207,210,207,208,211,212,213,212,211,214,213,212,211,214,211,212,215,216,217,216,215,218,217,216,215,218,215,216,219,220,221,220,219,222,221,220,219,222,219,220,223,224,225,225,224,223,226,227,228,227,226,229,228,227,226,229,226,227,230,231,232,231,230,233,232,231,230,233,230,231,234,235,236,235,234,237,236,235,234,237,234,235,238,239,240,239,238,241,240,239,238,241,238,239,242,243,244,243,242,245,244,243,242,245,242,243,246,247,248,248,247,246,249,250,251,250,249,252,251,250,249,252,249,250,253,254,255,254,253,256,255,254,253,256,253,254,257,258,259,258,257,260,259,258,257,260,257,258,261,262,263,262,261,264,263,262,261,264,261,262,265,266,267,266,265,268,267,266,265,268,265,266,269,270,271,270,269,272,271,270,269,272,269,270,273,274,275,274,273,276,275,274,273,276,273,274,277,278,279,278,277,280,279,278,277,280,277,278,281,282,283,283,282,281,284,285,286,285,284,287,286,285,284,287,284,285,288,289,290,290,289,288,291,292,293,292,291,294,293,292,291,294,291,292,295,296,297,296,295,298,297,296,295,298,295,296,299,300,301,300,299,302,301,300,299,302,299,300,303,304,305,304,303,306,305,304,303,306,303,304,307,308,309,309,308,307,310,311,312,311,310,313,312,311,310,313,310,311,314,315,316,315,314,317,316,315,314,317,314,315,318,319,320,319,318,321,320,319,318,321,318,319,322,323,324,323,322,325,324,323,322,325,322,323,326,327,328,327,326,329,328,327,326,329,326,327,330,331,332,331,330,333,332,331,330,333,330,331,334,335,336,335,334,337,336,335,334,337,334,335,338,339,340,339,338,341,340,339,338,341,338,339,342,343,344,343,342,345,344,343,342,345,342,343,346,347,348,347,346,349,348,347,346,349,346,347,350,351,352,351,350,353,352,351,350,353,350,351,354,355,356,355,354,357,356,355,354,357,354,355,358,359,360,359,358,361,360,359,358,361,358,359,362,363,364,363,362,365,364,363,362,365,362,363,366,367,368,367,366,369,368,367,366,369,366,367,370,371,372,371,370,373,372,371,370,373,370,371,374,375,376,375,374,377,376,375,374,377,374,375,378,379,380,379,378,381,380, +379,378,381,378,379,382,383,384,383,382,385,384,383,382,385,382,383,386,387,388,387,386,389,388,387,386,389,386,387,390,391,392,391,390,393,392,391,390,393,390,391,394,395,396,396,395,394,397,398,399,398,397,400,399,398,397,400,397,398,401,402,403,402,401,404,403,402,401,404,401,402,405,406,407,406,405,408,407,406,405,408,405,406,409,410,411,410,409,412,411,410,409,412,409,410,413,414,415,414,413,416,415,414,413,416,413,414,417,418,419,419,418,417,420,421,422,422,421,420,423,424,425,425,424,423,426,427,428,427,426,429,428,427,426,429,426,427,430,431,432,431,430,433,432,431,430,433,430,431,434,435,436,435,434,437,436,435,434,437,434,435,438,439,440,439,438,441,440,439,438,441,438,439,442,443,444,443,442,445,444,443,442,445,442,443,446,447,448,447,446,449,448,447,446,449,446,447,450,451,452,451,450,453,452,451,450,453,450,451,454,455,456,455,454,457,456,455,454,457,454,455,458,459,460,459,458,461,460,459,458,461,458,459,462,463,464,464,463,462,465,466,467,466,465,468,467,466,465,468,465,466,469,470,471,470,469,472,471,470,469,472,469,470,473,474,475,474,473,476,475,474,473,476,473,474,477,478,479,478,477,480,479,478,477,480,477,478,481,482,483,482,481,484,483,482,481,484,481,482,485,486,487,487,486,485,488,489,490,490,489,488,491,492,493,492,491,494,493,492,491,494,491,492,495,496,497,496,495,498,497,496,495,498,495,496,499,500,501,500,499,502,501,500,499,502,499,500,503,504,505,505,504,503,506,507,508,507,506,509,508,507,506,509,506,507,510,511,512,511,510,513,512,511,510,513,510,511,514,515,516,515,514,517,516,515,514,517,514,515,518,519,520,519,518,521,520,519,518,521,518,519,522,523,524,523,522,525,524,523,522,525,522,523,526,527,528,528,527,526,529,530,531,530,529,532,531,530,529,532,529,530,533,534,535,534,533,536,535,534,533,536,533,534,537,538,539,538,537,540,539,538,537,540,537,538,541,542,543,542,541,544,543,542,541,544,541,542,545,546,547,546,545,548,547,546,545,548,545,546,549,550,551,551,550,549,552,553,554,553,552,555,554,553,552,555,552,553,556,557,558,557,556,559,558,557,556,559,556,557,560,561,562,561, +560,563,562,561,560,563,560,561,564,565,566,565,564,567,566,565,564,567,564,565,568,569,570,569,568,571,570,569,568,571,568,569,572,573,574,574,573,572,575,576,577,576,575,578,577,576,575,578,575,576,579,580,581,580,579,582,581,580,579,582,579,580,583,584,585,584,583,586,585,584,583,586,583,584,587,588,589,588,587,590,589,588,587,590,587,588,591,592,593,592,591,594,593,592,591,594,591,592,595,596,597,597,596,595,598,599,600,599,598,601,600,599,598,601,598,599,602,603,604,603,602,605,604,603,602,605,602,603,606,607,608,607,606,609,608,607,606,609,606,607,610,611,612,611,610,613,612,611,610,613,610,611,614,615,616,615,614,617,616,615,614,617,614,615,618,619,620,620,619,618,621,622,623,622,621,624,623,622,621,624,621,622,625,626,627,626,625,628,627,626,625,628,625,626,629,630,631,630,629,632,631,630,629,632,629,630,633,634,635,634,633,636,635,634,633,636,633,634,637,638,639,638,637,640,639,638,637,640,637,638,641,642,643,642,641,644,643,642,641,644,641,642,645,646,647,646,645,648,647,646,645,648,645,646,649,650,651,651,650,649,652,653,654,653,652,655,654,653,652,655,652,653,656,657,658,657,656,659,658,657,656,659,656,657,660,661,662,661,660,663,662,661,660,663,660,661,664,665,666,665,664,667,666,665,664,667,664,665,668,669,670,669,668,671,670,669,668,671,668,669,672,673,674,674,673,672,675,676,677,676,675,678,677,676,675,678,675,676,679,680,681,680,679,682,681,680,679,682,679,680,683,684,685,684,683,686,685,684,683,686,683,684,687,688,689,688,687,690,689,688,687,690,687,688,691,692,693,692,691,694,693,692,691,694,691,692,695,696,697,696,695,698,697,696,695,698,695,696,699,700,701,700,699,702,701,700,699,702,699,700,703,704,705,704,703,706,705,704,703,706,703,704,707,708,709,708,707,710,709,708,707,710,707,708,711,712,713,712,711,714,713,712,711,714,711,712,715,716,717,716,715,718,717,716,715,718,715,716,719,720,721,721,720,719,722,723,724,723,722,725,724,723,722,725,722,723,726,727,728,727,726,729,728,727,726,729,726,727,730,731,732,731,730,733,732,731,730,733,730,731,734,735,736,735,734,737,736,735,734,737,734,735,738, +739,740,739,738,741,740,739,738,741,738,739,742,743,744,743,742,745,744,743,742,745,742,743,746,747,748,747,746,749,748,747,746,749,746,747,750,751,752,751,750,753,752,751,750,753,750,751,754,755,756,755,754,757,756,755,754,757,754,755,758,759,760,759,758,761,760,759,758,761,758,759,762,763,764,763,762,765,764,763,762,765,762,763,766,767,768,767,766,769,768,767,766,769,766,767,770,771,772,771,770,773,772,771,770,773,770,771,774,775,776,776,775,774,777,778,779,779,778,777,780,781,782,782,781,780,783,784,785,784,783,786,785,784,783,786,783,784,787,788,789,788,787,790,789,788,787,790,787,788,791,792,793,792,791,794,793,792,791,794,791,792,795,796,797,796,795,798,797,796,795,798,795,796,799,800,801,800,799,802,801,800,799,802,799,800,803,804,805,805,804,803,806,807,808,807,806,809,808,807,806,809,806,807,810,811,812,811,810,813,812,811,810,813,810,811,814,815,816,815,814,817,816,815,814,817,814,815,818,819,820,820,819,818,821,822,823,822,821,824,823,822,821,824,821,822,825,826,827,827,826,825,828,829,830,829,828,831,830,829,828,831,828,829,832,833,834,833,832,835,834,833,832,835,832,833,836,837,838,837,836,839,838,837,836,839,836,837,840,841,842,841,840,843,842,841,840,843,840,841,844,845,846,845,844,847,846,845,844,847,844,845,848,849,850,850,849,848,851,852,853,852,851,854,853,852,851,854,851,852,855,856,857,856,855,858,857,856,855,858,855,856,859,860,861,860,859,862,861,860,859,862,859,860,863,864,865,864,863,866,865,864,863,866,863,864,867,868,869,868,867,870,869,868,867,870,867,868,871,872,873,873,872,871,874,875,876,875,874,877,876,875,874,877,874,875,878,879,880,879,878,881,880,879,878,881,878,879,882,883,884,883,882,885,884,883,882,885,882,883,886,887,888,887,886,889,888,887,886,889,886,887,890,891,892,891,890,893,892,891,890,893,890,891,894,895,896,896,895,894,897,898,899,898,897,900,899,898,897,900,897,898,901,902,903,902,901,904,903,902,901,904,901,902,905,906,907,906,905,908,907,906,905,908,905,906,909,910,911,910,909,912,911,910,909,912,909,910,913,914,915,914,913,916,915,914,913,916,913,914,917,918,919,919, +918,917,920,921,922,921,920,923,922,921,920,923,920,921,924,925,926,925,924,927,926,925,924,927,924,925,928,929,930,929,928,931,930,929,928,931,928,929,932,933,934,933,932,935,934,933,932,935,932,933,936,937,938,937,936,939,938,937,936,939,936,937,940,941,942,942,941,940,943,944,945,944,943,946,945,944,943,946,943,944,947,948,949,948,947,950,949,948,947,950,947,948,951,952,953,952,951,954,953,952,951,954,951,952,955,956,957,956,955,958,957,956,955,958,955,956,959,960,961,960,959,962,961,960,959,962,959,960,963,964,965,965,964,963,966,967,968,967,966,969,968,967,966,969,966,967,970,971,972,971,970,973,972,971,970,973,970,971,974,975,976,975,974,977,976,975,974,977,974,975,978,979,980,979,978,981,980,979,978,981,978,979,982,983,984,983,982,985,984,983,982,985,982,983,986,987,988,988,987,986,989,990,991,990,989,992,991,990,989,992,989,990,993,994,995,994,993,996,995,994,993,996,993,994,997,998,999,998,997,1000,999,998,997,1000,997,998,1001,1002,1003,1002,1001,1004,1003,1002,1001,1004,1001,1002,1005,1006,1007,1006,1005,1008,1007,1006,1005,1008,1005,1006,1009,1010,1011,1011,1010,1009,1012,1013,1014,1013,1012,1015,1014,1013,1012,1015,1012,1013,1016,1017,1018,1017,1016,1019,1018,1017,1016,1019,1016,1017,1020,1021,1022,1021,1020,1023,1022,1021,1020,1023,1020,1021,1024,1025,1026,1025,1024,1027,1026,1025,1024,1027,1024,1025,1028,1029,1030,1029,1028,1031,1030,1029,1028,1031,1028,1029,1032,1033,1034,1034,1033,1032,1035,1036,1037,1036,1035,1038,1037,1036,1035,1038,1035,1036,1039,1040,1041,1040,1039,1042,1041,1040,1039,1042,1039,1040,1043,1044,1045,1044,1043,1046,1045,1044,1043,1046,1043,1044,1047,1048,1049,1048,1047,1050,1049,1048,1047,1050,1047,1048,1051,1052,1053,1052,1051,1054,1053,1052,1051,1054,1051,1052,1055,1056,1057,1057,1056,1055,1058,1059,1060,1059,1058,1061,1060,1059,1058,1061,1058,1059,1062,1063,1064,1063,1062,1065,1064,1063,1062,1065,1062,1063,1066,1067,1068,1067,1066,1069,1068,1067,1066,1069,1066,1067,1070,1071,1072,1071,1070,1073,1072,1071,1070,1073,1070,1071,1074,1075,1076,1075,1074,1077,1076,1075,1074,1077,1074, +1075,1078,1079,1080,1080,1079,1078,1081,1082,1083,1082,1081,1084,1083,1082,1081,1084,1081,1082,1085,1086,1087,1086,1085,1088,1087,1086,1085,1088,1085,1086,1089,1090,1091,1090,1089,1092,1091,1090,1089,1092,1089,1090,1093,1094,1095,1094,1093,1096,1095,1094,1093,1096,1093,1094,1097,1098,1099,1098,1097,1100,1099,1098,1097,1100,1097,1098,1101,1102,1103,1103,1102,1101,1104,1105,1106,1105,1104,1107,1105,1107,1108,1108,1107,1109,1108,1109,1110,1110,1109,1111,1110,1111,1112,1112,1111,1113,1112,1113,1114,1114,1113,1115,1114,1115,1116,1116,1115,1117,1116,1117,1118,1118,1117,1119,1118,1119,1120,1120,1119,1121,1120,1121,1122,1122,1121,1123,1122,1123,1124,1124,1123,1125,1124,1125,1126,1126,1125,1127,1106,1105,1104,1107,1104,1105,1108,1107,1105,1109,1107,1108,1110,1109,1108,1111,1109,1110,1112,1111,1110,1113,1111,1112,1114,1113,1112,1115,1113,1114,1116,1115,1114,1117,1115,1116,1118,1117,1116,1119,1117,1118,1120,1119,1118,1121,1119,1120,1122,1121,1120,1123,1121,1122,1124,1123,1122,1125,1123,1124,1126,1125,1124,1127,1125,1126,1128,1129,1130,1129,1128,1131,1130,1129,1128,1131,1128,1129,1132,1133,1134,1133,1132,1135,1134,1133,1132,1135,1132,1133,1136,1137,1138,1137,1136,1139,1138,1137,1136,1139,1136,1137,1140,1141,1142,1141,1140,1143,1142,1141,1140,1143,1140,1141,1144,1145,1146,1145,1144,1147,1146,1145,1144,1147,1144,1145,1148,1149,1150,1149,1148,1151,1150,1149,1148,1151,1148,1149,1152,1153,1154,1153,1152,1155,1154,1153,1152,1155,1152,1153,1156,1157,1158,1157,1156,1159,1158,1157,1156,1159,1156,1157,1160,1161,1162,1161,1160,1163,1162,1161,1160,1163,1160,1161,1164,1165,1166,1165,1164,1167,1166,1165,1164,1167,1164,1165,1168,1169,1170,1169,1168,1171,1170,1169,1168,1171,1168,1169,1172,1173,1174,1173,1172,1175,1174,1173,1172,1175,1172,1173,1176,1177,1178,1177,1176,1179,1178,1177,1176,1179,1176,1177,1180,1181,1182,1181,1180,1183,1182,1181,1180,1183,1180,1181,1184,1185,1186,1185,1184,1187,1186,1185,1184,1187,1184,1185,1188,1189,1190,1189,1188,1191,1190,1189,1188,1191,1188,1189,1192,1193,1194,1193,1192,1195,1194,1193,1192,1195,1192,1193,1196, +1197,1198,1197,1196,1199,1198,1197,1196,1199,1196,1197,1200,1201,1202,1201,1200,1203,1201,1203,1204,1204,1203,1205,1204,1205,1206,1206,1205,1207,1206,1207,1208,1208,1207,1209,1208,1209,1210,1210,1209,1211,1210,1211,1212,1212,1211,1213,1212,1213,1214,1214,1213,1215,1214,1215,1216,1216,1215,1217,1216,1217,1218,1218,1217,1219,1218,1219,1220,1220,1219,1221,1220,1221,1222,1222,1221,1223,1202,1201,1200,1203,1200,1201,1204,1203,1201,1205,1203,1204,1206,1205,1204,1207,1205,1206,1208,1207,1206,1209,1207,1208,1210,1209,1208,1211,1209,1210,1212,1211,1210,1213,1211,1212,1214,1213,1212,1215,1213,1214,1216,1215,1214,1217,1215,1216,1218,1217,1216,1219,1217,1218,1220,1219,1218,1221,1219,1220,1222,1221,1220,1223,1221,1222,1224,1225,1226,1225,1224,1227,1226,1225,1224,1227,1224,1225,1228,1229,1230,1229,1228,1231,1230,1229,1228,1231,1228,1229,1232,1233,1234,1233,1232,1235,1234,1233,1232,1235,1232,1233,1236,1237,1238,1237,1236,1239,1238,1237,1236,1239,1236,1237,1240,1241,1242,1241,1240,1243,1242,1241,1240,1243,1240,1241,1244,1245,1246,1245,1244,1247,1246,1245,1244,1247,1244,1245 + } + } + LayerElementMaterial: 0 { + Version: 101 + Name: "" + MappingInformationType: "ByPolygon" + ReferenceInformationType: "IndexToDirect" + Materials: *1240 { + a: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + } + } + Layer: 0 { + Version: 100 + LayerElement: { + Type: "LayerElementNormal" + TypedIndex: 0 + } + LayerElement: { + Type: "LayerElementMaterial" + TypedIndex: 0 + } + LayerElement: { + Type: "LayerElementTexture" + TypedIndex: 0 + } + LayerElement: { + Type: "LayerElementUV" + TypedIndex: 0 + } + } + } + Model: 140593523188736, "Model::Model", "Null" { + Version: 232 + Properties70: { + P: "ScalingMax", "Vector3D", "Vector", "",0,0,0 + } + Shading: Y + Culling: "CullingOff" + } + Model: 140593540972032, "Model::Group1", "Null" { + Version: 232 + Properties70: { + P: "ScalingMax", "Vector3D", "Vector", "",0,0,0 + } + Shading: Y + Culling: "CullingOff" + } + Model: 140593527199744, "Model::Mesh1", "Mesh" { + Version: 232 + Properties70: { + P: "ScalingMax", "Vector3D", "Vector", "",0,0,0 + P: "DefaultAttributeIndex", "int", "Integer", "",0 + } + Shading: T + Culling: "CullingOff" + } + Material: 140593628412208, "Material::_10", "" { + Version: 102 + ShadingModel: "phong" + MultiLayer: 0 + Properties70: { + P: "AmbientColor", "Color", "", "A",0,0,0 + P: "DiffuseColor", "Color", "", "A",0.984313725490196,0.992156862745098,0.909803921568627 + P: "TransparentColor", "Color", "", "A",1,1,1 + P: "SpecularColor", "Color", "", "A",0.33,0.33,0.33 + P: "ReflectionFactor", "Number", "", "A",0 + P: "Emissive", "Vector3D", "Vector", "",0,0,0 + P: "Ambient", "Vector3D", "Vector", "",0,0,0 + P: "Diffuse", "Vector3D", "Vector", "",0.984313725490196,0.992156862745098,0.909803921568627 + P: "Specular", "Vector3D", "Vector", "",0.33,0.33,0.33 + P: "Shininess", "double", "Number", "",20 + P: "Opacity", "double", "Number", "",1 + P: "Reflectivity", "double", "Number", "",0 + } + } +} + +; Object connections +;------------------------------------------------------------------ + +Connections: { + + ;Model::Model, Model::RootNode + C: "OO",140593523188736,0 + + ;Model::Group1, Model::Model + C: "OO",140593540972032,140593523188736 + + ;Model::Mesh1, Model::Group1 + C: "OO",140593527199744,140593540972032 + + ;Geometry::, Model::Mesh1 + C: "OO",140593628753696,140593527199744 + + ;Material::_10, Model::Mesh1 + C: "OO",140593628412208,140593527199744 +} +;Takes section +;---------------------------------------------------- + +Takes: { + Current: "" +} diff --git a/src/parts source/kOS Radial dev/Assets/Materials.meta b/src/parts source/kOS Radial dev/Assets/Materials.meta new file mode 100644 index 000000000..97ff32e7f --- /dev/null +++ b/src/parts source/kOS Radial dev/Assets/Materials.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: b75b1cdfc0bed4c849463b33aa00b0a6 +folderAsset: yes +timeCreated: 1430922505 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/parts source/kOS Radial dev/Assets/Materials/colorTexture.mat b/src/parts source/kOS Radial dev/Assets/Materials/colorTexture.mat new file mode 100644 index 000000000..be22b8001 Binary files /dev/null and b/src/parts source/kOS Radial dev/Assets/Materials/colorTexture.mat differ diff --git a/src/parts source/kOS Radial dev/Assets/Materials/colorTexture.mat.meta b/src/parts source/kOS Radial dev/Assets/Materials/colorTexture.mat.meta new file mode 100644 index 000000000..a28bceb0f --- /dev/null +++ b/src/parts source/kOS Radial dev/Assets/Materials/colorTexture.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 114327e43fe144dc38e02caaa2f3a39f +timeCreated: 1430922832 +licenseType: Free +NativeFormatImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/parts source/kOS Radial dev/Assets/Materials/material.mat b/src/parts source/kOS Radial dev/Assets/Materials/material.mat new file mode 100644 index 000000000..a4c955376 Binary files /dev/null and b/src/parts source/kOS Radial dev/Assets/Materials/material.mat differ diff --git a/src/parts source/kOS Radial dev/Assets/Materials/material.mat.meta b/src/parts source/kOS Radial dev/Assets/Materials/material.mat.meta new file mode 100644 index 000000000..382cb556b --- /dev/null +++ b/src/parts source/kOS Radial dev/Assets/Materials/material.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: c7fdc2566443b451fba1b1cf1018af65 +timeCreated: 1430922505 +licenseType: Free +NativeFormatImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/parts source/kOS Radial dev/Assets/PartTools.meta b/src/parts source/kOS Radial dev/Assets/PartTools.meta new file mode 100644 index 000000000..3b47f0fb9 --- /dev/null +++ b/src/parts source/kOS Radial dev/Assets/PartTools.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 7a0ad6da40aca438399e8037d453b540 +folderAsset: yes +timeCreated: 1430922487 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/parts source/kOS Radial dev/Assets/colorTexture.png b/src/parts source/kOS Radial dev/Assets/colorTexture.png new file mode 100644 index 000000000..7f76aa345 Binary files /dev/null and b/src/parts source/kOS Radial dev/Assets/colorTexture.png differ diff --git a/src/parts source/kOS Radial dev/Assets/colorTexture.png.meta b/src/parts source/kOS Radial dev/Assets/colorTexture.png.meta new file mode 100644 index 000000000..ac08a7e55 --- /dev/null +++ b/src/parts source/kOS Radial dev/Assets/colorTexture.png.meta @@ -0,0 +1,55 @@ +fileFormatVersion: 2 +guid: 11bc564fb136948b38849fe630e87070 +timeCreated: 1430929017 +licenseType: Free +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + linearTexture: 0 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: .25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 8 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -1 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: -1 + mipBias: -1 + wrapMode: -1 + nPOTScale: 1 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: .5, y: .5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 0 + textureType: -1 + buildTargetSettings: [] + spriteSheet: + sprites: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/parts source/kOS Radial dev/Assets/kOSRadial.unity b/src/parts source/kOS Radial dev/Assets/kOSRadial.unity new file mode 100644 index 000000000..36e91e35a Binary files /dev/null and b/src/parts source/kOS Radial dev/Assets/kOSRadial.unity differ diff --git a/src/parts source/kOS Radial dev/Assets/kOSRadial.unity.meta b/src/parts source/kOS Radial dev/Assets/kOSRadial.unity.meta new file mode 100644 index 000000000..989ab5cf4 --- /dev/null +++ b/src/parts source/kOS Radial dev/Assets/kOSRadial.unity.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: dfbf7da3a5c354d5b9449d643371f5fe +timeCreated: 1430926976 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/parts source/kOS Radial dev/Assets/kosradial.dae b/src/parts source/kOS Radial dev/Assets/kosradial.dae new file mode 100644 index 000000000..d76a1cd31 --- /dev/null +++ b/src/parts source/kOS Radial dev/Assets/kosradial.dae @@ -0,0 +1,428 @@ + + + + + Blender User + Blender 2.73.0 commit date:2015-01-20, commit time:18:16, hash:bbf09d9 + + 2015-05-06T10:23:57 + 2015-05-06T10:23:57 + + Z_UP + + + + + + + 49.13434 + 1.777778 + 0.1 + 100 + + + + + + 0 + 0 + 0 + + + + + + + + + 1 1 1 + 1 + 0 + 0.00111109 + + + + + 0.000999987 + 1 + 0.1 + 0.1 + 1 + 1 + 1 + 2 + 0 + 1 + 1 + 1 + 1 + 1 + 0 + 2880 + 2 + 30.002 + 1.000799 + 0.04999995 + 29.99998 + 1 + 2 + 0 + 0 + 1 + 1 + 1 + 1 + 8192 + 1 + 1 + 0 + 1 + 1 + 1 + 3 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 1 + 3 + 0.15 + 75 + 1 + 1 + 0 + 1 + 1 + 0 + + + + + + + 1 1 1 + 1 + 0 + 0.001599967 + + + + + 0.000999987 + 0 + 0.1 + 0.1 + 0.1 + 1 + 1 + 2 + 0 + 1 + 1 + 1 + 1 + 1 + 0 + 512 + 2 + 40 + 0.5 + 0.04999995 + 25 + 1 + 2 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 1 + 3 + 0 + 0 + 0 + 0 + 2 + 1 + 1 + 1 + 3 + 0.15 + 45 + 1 + 1 + 0 + 1 + 1 + 4 + + + + + + + 1 1 1 + 1 + 0 + 0.001599967 + + + + + 0.000999987 + 0 + 0.1 + 0.1 + 0.1 + 1 + 1 + 2 + 0 + 1 + 1 + 1 + 1 + 1 + 0 + 512 + 2 + 40 + 0.5 + 0.04999995 + 25 + 1 + 2 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 1 + 3 + 0 + 0 + 0 + 0 + 2 + 1 + 1 + 1 + 3 + 0.15 + 45 + 1 + 1 + 0 + 1 + 1 + 0 + + + + + + + 1 1 1 + 1 + 0 + 0.001599967 + + + + + 0.000999987 + 0 + 0.1 + 0.1 + 0.1 + 1 + 1 + 2 + 0 + 1 + 1 + 1 + 1 + 1 + 0 + 512 + 2 + 40 + 0.5 + 0.04999995 + 25 + 1 + 2 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 1 + 3 + 0 + 0 + 0 + 0 + 2 + 1 + 1 + 1 + 3 + 0.15 + 45 + 1 + 1 + 0 + 1 + 1 + 0 + + + + + + + + + + + + 0 0 0 1 + + + 0 0 0 1 + + + 1 1 1 1 + + + 0.5 0.5 0.5 1 + + + 50 + + + 1 + + + + + + + + + + + + + + + + 0.1983771 12.40921 0.6520971 1.37948 12.49326 0.5537875 0.1983771 12.49326 0.5537875 1.37948 12.40921 0.6520971 1.37948 12.31442 0.7401012 0.1983771 12.31442 0.7401012 1.37948 10.41715 0.6037545 1.37948 11.60391 0.9974553 1.37948 10.41715 0.9974553 1.37948 11.59258 0.6037545 1.37948 11.68207 0.5985973 1.37948 11.72737 0.9903408 1.37948 11.76479 0.5841695 1.37948 11.85479 0.968116 1.37948 11.8453 0.5603354 1.37948 11.92254 0.5274107 1.37948 11.97881 0.9314017 1.37948 11.99549 0.4858313 1.37948 12.09779 0.8806841 1.37948 12.06317 0.4361476 1.37948 12.12471 0.3790173 1.37948 12.21016 0.8166346 1.37948 12.17927 0.315197 1.37948 12.22614 0.2455314 1.37948 12.31442 0.7401012 1.37948 12.26469 0.1709431 1.37948 12.29443 0.09241938 1.37948 12.31772 0 1.37948 12.40921 0.6520971 1.37948 12.69948 0.09619885 1.37948 12.49326 0.5537875 1.37948 12.56546 0.4464739 1.37948 12.62485 0.3315771 1.37948 12.67065 0.2106183 1.37948 12.56546 0.4464739 0.1983771 12.56546 0.4464739 0.1983771 11.60391 0.9974553 0.1983771 10.41715 0.8006049 0.1983771 10.41715 0.9974553 0.1983771 11.59825 0.8006049 0.1983771 11.70472 0.794469 0.1983771 11.72737 0.9903408 0.1983771 11.80979 0.7761427 0.1983771 11.85479 0.968116 0.1983771 11.91205 0.7458686 0.1983771 11.97881 0.9314017 0.1983771 12.01016 0.7040474 0.1983771 12.09779 0.8806841 0.1983771 12.10282 0.651233 0.1983771 12.21016 0.8166346 0.1983771 12.1888 0.5881244 0.1983771 12.26696 0.5155572 0.1983771 12.31442 0.7401012 0.1983771 12.33626 0.4344923 0.1983771 12.40921 0.6520971 0.1983771 12.3958 0.3460027 0.1983771 12.44477 0.2512601 0.1983771 12.49326 0.5537875 0.1983771 12.48254 0.1515189 0.1983771 12.5086 0.04809939 0.1983771 12.56546 0.4464739 0.1983771 12.69948 0.09619885 0.1983771 12.62485 0.3315771 0.1983771 12.67065 0.2106183 0.1983771 12.21016 0.8166346 1.37948 12.21016 0.8166346 1.37948 11.72737 0.9903408 0.1983771 11.85479 0.968116 0.1983771 11.72737 0.9903408 1.37948 11.85479 0.968116 1.37948 11.60391 0.9974553 0.1983771 11.60391 0.9974553 1.37948 10.41715 0.9974553 0.1983771 10.41715 0.9974553 1.37948 10.41715 0.6037545 0.1983771 10.41715 0.8006049 0.1983771 10.41715 0.6037545 1.37948 10.41715 0.9974553 0.1983771 10.41715 0.9974553 0.1983771 11.59258 0.6037545 1.37948 10.41715 0.6037545 0.1983771 10.41715 0.6037545 1.37948 11.59258 0.6037545 0.1983771 11.68207 0.5985973 1.37948 11.68207 0.5985973 1.37948 11.76479 0.5841695 0.1983771 11.76479 0.5841695 0.1983771 11.8453 0.5603354 1.37948 11.8453 0.5603354 1.37948 11.92254 0.5274107 0.1983771 11.92254 0.5274107 1.37948 11.99549 0.4858313 0.1983771 11.99549 0.4858313 1.37948 12.06317 0.4361476 0.1983771 12.06317 0.4361476 1.37948 12.12471 0.3790173 0.1983771 12.12471 0.3790173 1.37948 12.17927 0.315197 0.1983771 12.17927 0.315197 0.1983771 12.22614 0.2455314 1.37948 12.22614 0.2455314 0.1983771 12.26469 0.1709431 1.37948 12.26469 0.1709431 0.1983771 12.29443 0.09241938 1.37948 12.29443 0.09241938 0.1983771 12.31772 0 1.37948 12.31772 0 1.37948 12.69948 0.09619885 0.1983771 12.5086 0.04809939 0.1983771 12.69948 0.09619885 0.1983771 12.31772 0 1.37948 12.31772 0 0.1983771 12.67065 0.2106183 1.37948 12.69948 0.09619885 0.1983771 12.69948 0.09619885 1.37948 12.67065 0.2106183 0.1983771 12.62485 0.3315771 1.37948 12.62485 0.3315771 1.37948 12.09779 0.8806841 0.1983771 12.09779 0.8806841 0.1983771 11.97881 0.9314017 1.37948 11.97881 0.9314017 0.1983771 11.59825 0.8006049 0.1983771 10.41715 0.6037545 0.1983771 10.41715 0.8006049 0.1983771 11.59258 0.6037545 0.1983771 11.68207 0.5985973 0.1983771 11.70472 0.794469 0.1983771 11.76479 0.5841695 0.1983771 11.80979 0.7761427 0.1983771 11.8453 0.5603354 0.1983771 11.91205 0.7458686 0.1983771 11.92254 0.5274107 0.1983771 12.01016 0.7040474 0.1983771 11.99549 0.4858313 0.1983771 12.06317 0.4361476 0.1983771 12.10282 0.651233 0.1983771 12.12471 0.3790173 0.1983771 12.1888 0.5881244 0.1983771 12.17927 0.315197 0.1983771 12.22614 0.2455314 0.1983771 12.26696 0.5155572 0.1983771 12.26469 0.1709431 0.1983771 12.29443 0.09241938 0.1983771 12.33626 0.4344923 0.1983771 12.31772 0 0.1983771 12.5086 0.04809939 0.1983771 12.3958 0.3460027 0.1983771 12.44477 0.2512601 0.1983771 12.48254 0.1515189 1.1949 6.126895 2.064585 5.095647 9.286817 2.064585 1.1949 9.286817 2.064585 5.095647 6.126895 2.064585 1.002006 5.899769 2.458286 5.095647 6.126895 2.064585 1.1949 6.126895 2.064585 5.332715 5.899769 2.458286 5.332715 9.443078 2.458286 5.095647 6.126895 2.064585 5.332715 5.899769 2.458286 5.095647 9.286817 2.064585 5.095647 9.286817 2.064585 1.002006 9.443078 2.458286 1.1949 9.286817 2.064585 5.332715 9.443078 2.458286 1.1949 6.126895 2.064585 1.002006 9.443078 2.458286 1.002006 5.899769 2.458286 1.1949 9.286817 2.064585 -5.04407e-7 10.41159 1.893423 6.299212 10.41715 1.808626 -5.04676e-7 10.41715 1.808626 6.299212 10.41159 1.893423 0 0.04017329 0.7581144 0 0.02344459 0.09608095 0 0.02344459 0.5028831 -5.04676e-7 10.41715 0.09608095 0 0.09007328 1.008978 0 0.1722908 1.251183 0 0.2854189 1.480584 0 0.427522 1.693257 0 0.5961688 1.885562 0 0.7884735 2.054208 0 1.001146 2.196312 0 1.230547 2.30944 0 1.472752 2.391657 0 1.723616 2.441557 0 1.978847 2.458286 -4.73202e-7 9.767485 2.458286 -4.7731e-7 9.852284 2.452728 -4.81348e-7 9.93563 2.436149 -4.85246e-7 10.0161 2.408833 -4.88939e-7 10.09232 2.371248 -4.92362e-7 10.16297 2.324036 -4.95457e-7 10.22686 2.268005 -4.98172e-7 10.28289 2.204113 -5.00459e-7 10.33011 2.133455 -5.0228e-7 10.36769 2.05724 -5.03603e-7 10.39501 1.97677 -5.04407e-7 10.41159 1.893423 -5.04676e-7 10.41715 1.808626 -5.03603e-7 10.39501 1.97677 6.299212 10.39501 1.97677 6.299213 0.02344459 0.09608095 6.299213 0.02609038 0.5432494 6.299213 0.02344459 0.5028831 6.299212 10.41715 0.09608095 6.299213 0.06239557 0.6631978 6.299213 0.1243278 0.7933525 6.299213 0.2050413 0.9127728 6.299213 0.302718 1.018769 6.299213 0.4151577 1.108953 6.299213 0.5398278 1.181294 6.299213 0.6739203 1.234162 6.299213 0.8144148 1.266367 6.299213 0.9581467 1.277183 6.299213 4.895154 1.277183 6.299213 4.898525 2.115783 6.299213 4.908577 2.16632 6.299212 4.92514 2.215113 6.299212 4.947929 2.261326 6.299212 4.976557 2.304169 6.299212 5.010531 2.342909 6.299212 5.049271 2.376883 6.299212 5.092114 2.405511 6.299212 5.138328 2.4283 6.299212 5.18712 2.444863 6.299212 5.237657 2.454916 6.299212 5.289074 2.458286 6.299212 9.767485 2.458286 6.299212 9.852284 2.452728 6.299212 9.93563 2.436149 6.299212 10.0161 2.408833 6.299212 10.09232 2.371248 6.299212 10.16297 2.324036 6.299212 10.22686 2.268005 6.299212 10.28289 2.204113 6.299212 10.33011 2.133455 6.299212 10.36769 2.05724 6.299212 10.39501 1.97677 6.299212 10.41159 1.893423 6.299212 10.41715 1.808626 6.299213 4.895154 2.064366 -5.04676e-7 10.41715 0.09608095 0.1983765 10.41715 0.6037545 6.299212 10.41715 0.09608095 -5.04676e-7 10.41715 1.808626 0.1983765 10.41715 0.8006049 0.1983765 10.41715 0.9974553 1.379479 10.41715 0.9974553 1.379479 10.41715 0.6037545 6.299212 10.41715 1.808626 6.299213 0.02344459 0.09608095 0 0.02344459 0.5028831 0 0.02344459 0.09608095 6.299213 0.02344459 0.5028831 0 0.02344459 0.5028831 2.362205 0.02609038 0.5432494 0 0.04017329 0.7581144 6.299213 0.02344459 0.5028831 6.299213 0.02609038 0.5432494 2.362205 0.04017329 0.7581144 0 0.09007328 1.008978 2.362205 0.09007328 1.008978 0 0.1722908 1.251183 2.362205 0.1722908 1.251183 0 0.2854189 1.480584 2.362205 0.2854189 1.480584 0 0.427522 1.693257 2.362205 0.427522 1.693257 2.362205 0.5961688 1.885562 0 0.5961688 1.885562 2.362205 0.7884735 2.054208 0 0.7884735 2.054208 0 1.001146 2.196312 2.362205 1.001146 2.196312 2.362205 1.230547 2.30944 0 1.230547 2.30944 0 1.472752 2.391657 2.362205 1.472752 2.391657 0 1.723616 2.441557 2.362205 1.723616 2.441557 2.362205 1.978847 2.458286 0 1.978847 2.458286 0 1.978847 2.458286 1.002006 5.899769 2.458286 1.002006 9.443078 2.458286 2.362205 1.978847 2.458286 2.362205 5.289074 2.458286 5.332715 5.899769 2.458286 6.299212 5.289074 2.458286 5.332715 9.443078 2.458286 6.299212 9.767485 2.458286 -4.73202e-7 9.767485 2.458286 -4.73202e-7 9.767485 2.458286 6.299212 9.852284 2.452728 -4.7731e-7 9.852284 2.452728 6.299212 9.767485 2.458286 -4.81348e-7 9.93563 2.436149 6.299212 9.93563 2.436149 6.299212 10.0161 2.408833 -4.85246e-7 10.0161 2.408833 6.299212 10.09232 2.371248 -4.88939e-7 10.09232 2.371248 -4.92362e-7 10.16297 2.324036 6.299212 10.16297 2.324036 6.299212 10.22686 2.268005 -4.95457e-7 10.22686 2.268005 6.299212 10.28289 2.204113 -4.98172e-7 10.28289 2.204113 6.299212 10.33011 2.133455 -5.00459e-7 10.33011 2.133455 6.299212 10.36769 2.05724 -5.0228e-7 10.36769 2.05724 6.299212 10.41715 0.09608095 -5.04676e-7 10.41715 0.09608095 6.299212 5.237657 2.454916 2.362205 5.289074 2.458286 2.362205 5.237657 2.454916 6.299212 5.289074 2.458286 6.299212 5.18712 2.444863 2.362205 5.18712 2.444863 6.299212 5.138328 2.4283 2.362205 5.138328 2.4283 2.362205 5.092114 2.405511 6.299212 5.092114 2.405511 6.299212 5.049271 2.376883 2.362205 5.049271 2.376883 6.299212 5.010531 2.342909 2.362205 5.010531 2.342909 6.299212 4.976557 2.304169 2.362205 4.976557 2.304169 6.299212 4.947929 2.261326 2.362205 4.947929 2.261326 6.299212 4.92514 2.215113 2.362205 4.92514 2.215113 6.299213 4.908577 2.16632 2.362205 4.908577 2.16632 6.299213 4.898525 2.115783 2.362205 4.898525 2.115783 6.299213 4.895154 2.064366 2.362205 4.895154 2.064366 6.299213 4.895154 1.277183 2.362205 4.895154 2.064366 2.362205 4.895154 1.277183 6.299213 4.895154 2.064366 2.362205 0.9581467 1.277183 6.299213 4.895154 1.277183 2.362205 4.895154 1.277183 6.299213 0.9581467 1.277183 6.299213 0.8144148 1.266367 2.362205 0.9581467 1.277183 2.362205 0.8144148 1.266367 6.299213 0.9581467 1.277183 2.362205 0.6739203 1.234162 6.299213 0.6739203 1.234162 6.299213 0.5398278 1.181294 2.362205 0.5398278 1.181294 2.362205 0.4151577 1.108953 6.299213 0.4151577 1.108953 2.362205 0.302718 1.018769 6.299213 0.302718 1.018769 2.362205 0.2050413 0.9127728 6.299213 0.2050413 0.9127728 6.299213 0.1243278 0.7933525 2.362205 0.1243278 0.7933525 6.299213 0.06239557 0.6631978 2.362205 0.06239557 0.6631978 2.362205 0.02609038 0.5432494 6.299213 0.02609038 0.5432494 6.299213 9.421e-4 0.238452 6.299213 0.02063935 0.5252402 6.299213 0 0.3825873 6.299213 0.02344459 0.09608095 6.299213 0.02344459 0.5028831 6.299213 0.02609038 0.5432494 2.362205 0.06239557 0.6631978 2.362205 0.04017329 0.7581144 2.362205 0.02609038 0.5432494 2.362205 0.09007328 1.008978 2.362205 0.1243278 0.7933525 2.362205 0.1722908 1.251183 2.362205 0.2050413 0.9127728 2.362205 0.2854189 1.480584 2.362205 0.302718 1.018769 2.362205 0.427522 1.693257 2.362205 0.4151577 1.108953 2.362205 0.5398278 1.181294 2.362205 0.5961688 1.885562 2.362205 0.6739203 1.234162 2.362205 0.7884735 2.054208 2.362205 0.8144148 1.266367 2.362205 1.001146 2.196312 2.362205 0.9581467 1.277183 2.362205 4.895154 1.277183 2.362205 1.230547 2.30944 2.362205 1.472752 2.391657 2.362205 1.723616 2.441557 2.362205 1.978847 2.458286 2.362205 4.895154 2.064366 2.362205 5.237657 2.454916 2.362205 5.289074 2.458286 2.362205 5.18712 2.444863 2.362205 5.138328 2.4283 2.362205 5.092114 2.405511 2.362205 5.049271 2.376883 2.362205 5.010531 2.342909 2.362205 4.976557 2.304169 2.362205 4.947929 2.261326 2.362205 4.92514 2.215113 2.362205 4.908577 2.16632 2.362205 4.898525 2.115783 + + + + + + + + + + 0 0.721427 0.692465 0 0.7961974 0.604999 0 0.7961974 0.604999 0 0.721427 0.692465 0 0.6371044 0.770745 0 0.6371044 0.770745 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0.8604389 0.5095371 0 0.8604389 0.5095371 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 0.5443587 0.8388317 0 0.5443587 0.8388317 0 0.1148411 0.9933775 0 0.2282174 0.9736015 0 0.1148411 0.9933775 0 0.2282174 0.9736015 0 0.02874839 0.9995728 0 0.02874839 0.9995728 0 0 1 0 0 1 0 -1 0 0 -1 0 0 -1 0 0 -0.02874839 -0.9995728 0 0 -1 0 0 -1 0 -0.02874839 -0.9995728 0 -0.1148411 -0.9933775 0 -0.1148411 -0.9933775 0 -0.2282174 -0.9736015 0 -0.2282174 -0.9736015 0 -0.3385418 -0.9409467 0 -0.3385418 -0.9409467 0 -0.44438 -0.8958098 0 -0.44438 -0.8958098 0 -0.5443587 -0.8388317 0 -0.5443587 -0.8388317 0 -0.6371044 -0.770745 0 -0.6371044 -0.770745 0 -0.721427 -0.692465 0 -0.721427 -0.692465 0 -0.7961974 -0.604999 0 -0.7961974 -0.604999 0 -0.8604389 -0.5095371 0 -0.8604389 -0.5095371 0 -0.9132664 -0.4073305 0 -0.9132664 -0.4073305 0 -0.9540086 -0.2997223 0 -0.9540086 -0.2997223 0 -0.9696646 -0.2443311 0 -0.9696646 -0.2443311 0 0.2443453 -0.9696882 0 0.244346 -0.9696882 0 0.2443456 -0.9696881 0 0.9540086 0.2997223 0 0.9696646 0.2443311 0 0.9696646 0.2443311 0 0.9540086 0.2997223 0 0.9132664 0.4073305 0 0.9132664 0.4073305 0 0.44438 0.8958098 0 0.44438 0.8958098 0 0.3385418 0.9409467 0 0.3385418 0.9409467 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 0 1 0 0 1 0 0.866194 0.4997078 0 0.866194 0.4997078 -0.8566789 0 0.5158501 -0.8566789 0 0.5158501 0 -0.9294664 0.3689069 0 -0.9294664 0.3689069 0.8980076 0 0.43998 0.8980076 0 0.4399799 0 0.9914243 0.1304971 0 0.9978332 0.06540113 0 0.9978332 0.06540113 0 0.9914243 0.1304971 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 0.9659109 0.2587969 0 0.9659109 0.2587969 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 -1.41432e-7 1 0 -2.51906e-7 1 0 -4.03722e-7 1 0 0 1 0 0 1 3.33403e-6 8.64099e-6 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 -0.7070834 -0.7070834 0 -0.9999695 0 0 -0.7070834 -0.7070834 0 -1 0 0 -0.9978332 0.06540113 0 -0.9978332 0.06540113 0 -0.9914243 0.1304971 0 -0.9978588 0.06540429 0 -0.9978588 0.06540429 0 -0.9914243 0.1304971 0 -0.9659109 0.2587969 0 -0.9659109 0.2587969 0 -0.9238563 0.3826716 0 -0.9238563 0.3826716 0 -0.8660237 0.4999848 0 -0.8660237 0.4999848 0 -0.7933287 0.6087527 0 -0.7933287 0.6087527 0 -0.7070834 0.7070834 0 -0.7070834 0.7070834 0 -0.6087527 0.7933287 0 -0.6087527 0.7933287 0 -0.4999848 0.8660237 0 -0.4999848 0.8660237 0 -0.3826716 0.9238563 0 -0.3826716 0.9238563 0 -0.2587969 0.9659109 0 -0.2587969 0.9659109 0 -0.1304971 0.9914243 0 -0.1304971 0.9914243 0 -0.06540113 0.9978332 0 -0.06540113 0.9978332 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0.06537061 0.9978332 0 0.1304971 0.9914243 0 0.1304971 0.9914243 0 0.06537061 0.9978332 0 0.2587969 0.9659109 0 0.2587969 0.9659109 0 0.3826716 0.9238563 0 0.3826716 0.9238563 0 0.4999848 0.8660237 0 0.4999848 0.8660237 0 0.6087527 0.7933287 0 0.6087527 0.7933287 0 0.7070834 0.7070834 0 0.7070834 0.7070834 0 0.7933287 0.6087527 0 0.7933287 0.6087527 0 0.8660237 0.4999848 0 0.8660237 0.4999848 0 0.9238563 0.3826716 0 0.9238563 0.3826716 0 0 -1 0 0 -1 0 -0.1304971 0.9914243 0 -0.06540113 0.9978332 0 -0.1304971 0.9914243 0 -0.06540113 0.9978332 0 -0.2587969 0.9659109 0 -0.2587969 0.9659109 0 -0.3826716 0.9238563 0 -0.3826716 0.9238563 0 -0.4999848 0.8660237 0 -0.4999848 0.8660237 0 -0.6087527 0.7933287 0 -0.6087527 0.7933287 0 -0.7070834 0.7070834 0 -0.7070834 0.7070834 0 -0.7933287 0.6087527 0 -0.7933287 0.6087527 0 -0.8660237 0.4999848 0 -0.8660237 0.4999848 0 -0.9238563 0.3826716 0 -0.9238563 0.3826716 0 -0.9659109 0.2587969 0 -0.9659109 0.2587969 0 -0.9914243 0.1304971 0 -0.9914243 0.1304971 0 -0.9978332 0.06540113 0 -0.9978332 0.06540113 0 -1 0 0 -1 0 0 0 1 0 0 1 0 -0.1496322 0.9887081 0 -0.07501447 0.9971618 0 -0.1496322 0.9887081 0 -0.07501447 0.9971618 0 -0.295938 0.9551988 0 -0.295938 0.9551988 0 -0.4355602 0.9001435 0 -0.4355602 0.9001435 0 -0.5653554 0.8248237 0 -0.5653554 0.8248237 0 -0.6824244 0.7309183 0 -0.6824244 0.7309183 0 -0.7841426 0.6205634 0 -0.7841426 0.6205634 0 -0.86816 0.4962005 0 -0.86816 0.4962005 0 -0.9326762 0.3606982 0 -0.9326762 0.3606982 0 -0.957091 0.2896817 0 -0.957091 0.2896817 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 -1.32807e-7 1 0 -1.73743e-7 1 0 0 1 0 -1.09888e-6 1 0 -3.65905e-7 1 0 -2.16257e-7 1 0 -1.50132e-7 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 + + + + + + + + + + 0.805888 0.06343823 0.7392519 0.05614095 0.8058881 0.05614113 0.7392519 0.05614095 0.805888 0.06343823 0.7392519 0.06343817 0.7392519 0.07073533 0.805888 0.06343823 0.805888 0.07073539 0.805888 0.06343823 0.7392519 0.07073533 0.7392519 0.06343817 0.6998396 0.1739056 0.7221693 0.106989 0.7220516 0.1739447 0.7221693 0.106989 0.6998396 0.1739056 0.6999562 0.1075896 0.7221693 0.106989 0.6999562 0.1075896 0.6996741 0.1025399 0.7221693 0.106989 0.6996741 0.1025399 0.7217802 0.100023 0.7217802 0.100023 0.6996741 0.1025399 0.6988683 0.09787178 0.7217802 0.100023 0.6988683 0.09787178 0.720539 0.0928322 0.720539 0.0928322 0.6988683 0.09787178 0.6975316 0.09332722 0.720539 0.0928322 0.6975316 0.09332722 0.6956818 0.08896619 0.720539 0.0928322 0.6956818 0.08896619 0.7184799 0.08583152 0.7184799 0.08583152 0.6956818 0.08896619 0.6933432 0.08484649 0.7184799 0.08583152 0.6933432 0.08484649 0.7156303 0.07911378 0.7156303 0.07911378 0.6933432 0.08484649 0.6905468 0.08102273 0.7156303 0.07911378 0.6905468 0.08102273 0.6873298 0.07754558 0.7156303 0.07911378 0.6873298 0.07754558 0.7120278 0.07276773 0.7120278 0.07276773 0.6873298 0.07754558 0.6837345 0.07446092 0.7120278 0.07276773 0.6837345 0.07446092 0.6798087 0.0718097 0.7120278 0.07276773 0.6798087 0.0718097 0.7077204 0.06687772 0.7077204 0.06687772 0.6798087 0.0718097 0.6756045 0.06962704 0.7077204 0.06687772 0.6756045 0.06962704 0.6711772 0.06794166 0.7077204 0.06687772 0.6711772 0.06794166 0.6659651 0.06661856 0.7077204 0.06687772 0.6659651 0.06661856 0.7027646 0.06152129 0.7027646 0.06152129 0.6659651 0.06661856 0.6714305 0.0450893 0.7027646 0.06152129 0.6714305 0.0450893 0.6972267 0.05676984 0.6972267 0.05676984 0.6714305 0.0450893 0.6911793 0.05268579 0.6911793 0.05268579 0.6714305 0.0450893 0.6847029 0.04932355 0.6847029 0.04932355 0.6714305 0.0450893 0.677883 0.04672735 0.8058881 0.05614113 0.7392519 0.04884374 0.8058881 0.04884392 0.7392519 0.04884374 0.8058881 0.05614113 0.7392519 0.05614095 0.6341806 0.0801925 0.6438099 0.1473764 0.6327067 0.147132 0.6438099 0.1473764 0.6341806 0.0801925 0.6452769 0.08075666 0.6452769 0.08075666 0.6341806 0.0801925 0.6457552 0.07475852 0.6457552 0.07475852 0.6341806 0.0801925 0.6347352 0.07323765 0.6457552 0.07475852 0.6347352 0.07323765 0.6469194 0.06885492 0.6469194 0.06885492 0.6347352 0.07323765 0.636147 0.06607842 0.6469194 0.06885492 0.636147 0.06607842 0.648754 0.06312447 0.648754 0.06312447 0.636147 0.06607842 0.638372 0.05912864 0.648754 0.06312447 0.638372 0.05912864 0.6512348 0.0576424 0.6512348 0.0576424 0.638372 0.05912864 0.6413804 0.05248057 0.6512348 0.0576424 0.6413804 0.05248057 0.6543288 0.05248165 0.6543288 0.05248165 0.6413804 0.05248057 0.6451327 0.04622197 0.6543288 0.05248165 0.6451327 0.04622197 0.6579952 0.04771059 0.6579952 0.04771059 0.6451327 0.04622197 0.6621854 0.0433923 0.6621854 0.0433923 0.6451327 0.04622197 0.6495791 0.04043596 0.6621854 0.0433923 0.6495791 0.04043596 0.6668439 0.03958368 0.6668439 0.03958368 0.6495791 0.04043596 0.6546606 0.03519886 0.6668439 0.03958368 0.6546606 0.03519886 0.6719091 0.03633564 0.6719091 0.03633564 0.6546606 0.03519886 0.6773139 0.03369081 0.6773139 0.03369081 0.6546606 0.03519886 0.6603102 0.03058034 0.6773139 0.03369081 0.6603102 0.03058034 0.6829867 0.03168445 0.6829867 0.03168445 0.6603102 0.03058034 0.6888526 0.03034293 0.6888526 0.03034293 0.6603102 0.03058034 0.6664528 0.02664124 0.6888526 0.03034293 0.6664528 0.02664124 0.6863766 0.01951646 0.6863766 0.01951646 0.6664528 0.02664124 0.6730073 0.02343386 0.6863766 0.01951646 0.6730073 0.02343386 0.6798868 0.02100068 0.805888 0.07803267 0.7392519 0.07073533 0.805888 0.07073539 0.7392519 0.07073533 0.805888 0.07803267 0.7392519 0.07803249 0.7392517 0.1072213 0.8058879 0.09992432 0.8058879 0.1072215 0.8058879 0.09992432 0.7392517 0.1072213 0.7392518 0.09992408 0.7392517 0.1141982 0.8058879 0.1072215 0.8058879 0.1141983 0.8058879 0.1072215 0.7392517 0.1141982 0.7392517 0.1072213 0.7392516 0.181154 0.8058879 0.1141983 0.8058877 0.1811541 0.8058879 0.1141983 0.7392516 0.181154 0.7392517 0.1141982 0.8999858 0.09476959 0.8333497 0.1058756 0.8333497 0.09476959 0.8333497 0.1058756 0.8999858 0.09476959 0.8999858 0.1169816 0.8333497 0.1058756 0.8999858 0.1169816 0.8333497 0.1169816 0.6566967 0.1138606 0.7241307 0.1793653 0.6574996 0.180172 0.7241307 0.1793653 0.6566967 0.1138606 0.7233279 0.1130537 0.6566355 0.1088035 0.7233279 0.1130537 0.6566967 0.1138606 0.7233279 0.1130537 0.6566355 0.1088035 0.7232667 0.1079968 0.7232093 0.1032599 0.6566355 0.1088035 0.6565782 0.1040666 0.6566355 0.1088035 0.7232093 0.1032599 0.7232667 0.1079968 0.6565209 0.09932988 0.7232093 0.1032599 0.6565782 0.1040666 0.7232093 0.1032599 0.6565209 0.09932988 0.723152 0.09852308 0.7230947 0.09378629 0.6565209 0.09932988 0.6564635 0.09459304 0.6565209 0.09932988 0.7230947 0.09378629 0.723152 0.09852308 0.7230373 0.08904939 0.6564635 0.09459304 0.6564062 0.08985614 0.6564635 0.09459304 0.7230373 0.08904939 0.7230947 0.09378629 0.72298 0.08431261 0.6564062 0.08985614 0.6563488 0.08511924 0.6564062 0.08985614 0.72298 0.08431261 0.7230373 0.08904939 0.7229226 0.07957571 0.6563488 0.08511924 0.6562914 0.08038246 0.6563488 0.08511924 0.7229226 0.07957571 0.72298 0.08431261 0.7228652 0.07483899 0.6562914 0.08038246 0.6562341 0.07564568 0.6562914 0.08038246 0.7228652 0.07483899 0.7229226 0.07957571 0.7228652 0.07483899 0.6561768 0.07090896 0.7228079 0.07010221 0.6561768 0.07090896 0.7228652 0.07483899 0.6562341 0.07564568 0.7228079 0.07010221 0.6561194 0.06617212 0.7227506 0.06536543 0.6561194 0.06617212 0.7228079 0.07010221 0.6561768 0.07090896 0.7227506 0.06536543 0.6560621 0.06143528 0.7226932 0.06062865 0.6560621 0.06143528 0.7227506 0.06536543 0.6561194 0.06617212 0.7226932 0.06062865 0.655997 0.05605852 0.7226281 0.05525183 0.655997 0.05605852 0.7226932 0.06062865 0.6560621 0.06143528 0.8999859 0.1177332 0.8333497 0.1288392 0.8333497 0.1177332 0.8333497 0.1288392 0.8999859 0.1177332 0.8333497 0.1399452 0.8333497 0.1399452 0.8999859 0.1177332 0.8999859 0.1399452 0.8058881 0.03424942 0.739252 0.02759218 0.8058881 0.02759242 0.739252 0.02759218 0.8058881 0.03424942 0.739252 0.03424924 0.8058881 0.04154664 0.739252 0.03424924 0.8058881 0.03424942 0.739252 0.03424924 0.8058881 0.04154664 0.7392519 0.04154658 0.8058881 0.04154664 0.7392519 0.04884374 0.7392519 0.04154658 0.7392519 0.04884374 0.8058881 0.04154664 0.8058881 0.04884392 0.7392518 0.08532971 0.805888 0.07803267 0.8058879 0.08532983 0.805888 0.07803267 0.7392518 0.08532971 0.7392519 0.07803249 0.8058879 0.09262704 0.7392518 0.08532971 0.8058879 0.08532983 0.7392518 0.08532971 0.8058879 0.09262704 0.7392518 0.09262692 0.8058879 0.09992432 0.7392518 0.09262692 0.8058879 0.09262704 0.7392518 0.09262692 0.8058879 0.09992432 0.7392518 0.09992408 0.9046452 0.2291816 0.8794604 0.1857123 0.9007156 0.1626614 0.8794604 0.1857123 0.9046452 0.2291816 0.8935397 0.2295174 0.8935397 0.2295174 0.9046452 0.2291816 0.893547 0.2345748 0.893547 0.2345748 0.9046452 0.2291816 0.9046539 0.2351986 0.893547 0.2345748 0.9046539 0.2351986 0.8930096 0.2392814 0.8930096 0.2392814 0.9046539 0.2351986 0.9039713 0.241177 0.8930096 0.2392814 0.9039713 0.241177 0.8919352 0.2438949 0.8919352 0.2438949 0.9039713 0.241177 0.9026066 0.2470374 0.8919352 0.2438949 0.9026066 0.2470374 0.8903379 0.2483547 0.8903379 0.2483547 0.9026066 0.2470374 0.9005776 0.2527022 0.8903379 0.2483547 0.9005776 0.2527022 0.8882387 0.2526014 0.8882387 0.2526014 0.9005776 0.2527022 0.8856657 0.2565789 0.8856657 0.2565789 0.9005776 0.2527022 0.8979113 0.2580964 0.8856657 0.2565789 0.8979113 0.2580964 0.8826528 0.2602345 0.8826528 0.2602345 0.8979113 0.2580964 0.8946431 0.2631486 0.8826528 0.2602345 0.8946431 0.2631486 0.8792399 0.2635198 0.8792399 0.2635198 0.8946431 0.2631486 0.8754723 0.2663914 0.8754723 0.2663914 0.8946431 0.2631486 0.8908161 0.2677918 0.8754723 0.2663914 0.8908161 0.2677918 0.8713998 0.2688109 0.8713998 0.2688109 0.8908161 0.2677918 0.8670762 0.2707468 0.8670762 0.2707468 0.8908161 0.2677918 0.8864811 0.2719649 0.8670762 0.2707468 0.8864811 0.2719649 0.8619486 0.2723661 0.8619486 0.2723661 0.8864811 0.2719649 0.8652927 0.2829566 0.8652927 0.2829566 0.8864811 0.2719649 0.8816953 0.2756124 0.8652927 0.2829566 0.8816953 0.2756124 0.8765223 0.2786859 0.8652927 0.2829566 0.8765223 0.2786859 0.8710306 0.2811447 0.7577 0.4879786 0.9777747 0.6662568 0.7577 0.6662568 0.9777747 0.6662568 0.7577 0.4879786 0.9777746 0.4879786 0.1410154 0.4449292 0.3719733 0.4705724 0.1518982 0.4705724 0.3719733 0.4705724 0.1410154 0.4449292 0.3853483 0.4449292 0.2487395 0.3982971 0.06164556 0.4242252 0.0488314 0.3982971 0.06164556 0.4242252 0.2487395 0.3982971 0.2399235 0.4242252 0.4130269 0.4193907 0.1675981 0.4400725 0.1784809 0.416175 0.1675981 0.4400725 0.4130269 0.4193907 0.4119307 0.4400725 0.03591895 0.4314084 0.2230131 0.4561432 0.02310484 0.4561432 0.2230131 0.4561432 0.03591895 0.4314084 0.2141971 0.4314084 0.2053067 0.8636897 0.5177334 0.8691433 0.205285 0.869143 0.5177334 0.8691433 0.2053067 0.8636897 0.517755 0.8636898 0.017416 0.5888926 0.01834887 0.6120994 0.01741594 0.5978623 0.01834887 0.6120994 0.017416 0.5888926 0.135105 0.5931532 0.135105 0.5931532 0.017416 0.5888926 0.01858693 0.5799995 0.135105 0.5931532 0.01858693 0.5799995 0.02090859 0.5713352 0.135105 0.5931532 0.02090859 0.5713352 0.02434045 0.56305 0.135105 0.5931532 0.02434045 0.56305 0.02882474 0.5552831 0.135105 0.5931532 0.02882474 0.5552831 0.03428572 0.5481661 0.135105 0.5931532 0.03428572 0.5481661 0.04062932 0.5418225 0.135105 0.5931532 0.04062932 0.5418225 0.04774624 0.5363615 0.135105 0.5931532 0.04774624 0.5363615 0.0555436 0.5317189 0.135105 0.5931532 0.0555436 0.5317189 0.06399804 0.5274468 0.135105 0.5931532 0.06399804 0.5274468 0.07300299 0.5235576 0.135105 0.5931532 0.07300299 0.5235576 0.08042526 0.5200569 0.135105 0.5931532 0.08042526 0.5200569 0.35526 0.5066425 0.135105 0.5931532 0.35526 0.5066425 0.3582399 0.5066911 0.135105 0.5931532 0.3582399 0.5066911 0.3611879 0.5071283 0.135105 0.5931532 0.3611879 0.5071283 0.3640537 0.5079465 0.135105 0.5931532 0.3640537 0.5079465 0.366788 0.5091317 0.135105 0.5931532 0.366788 0.5091317 0.3693442 0.5106637 0.135105 0.5931532 0.3693442 0.5106637 0.3716789 0.5125164 0.135105 0.5931532 0.3716789 0.5125164 0.3737515 0.514658 0.135105 0.5931532 0.3737515 0.514658 0.3755269 0.5170517 0.135105 0.5931532 0.3755269 0.5170517 0.3769752 0.5196573 0.135105 0.5931532 0.3769752 0.5196573 0.3783345 0.5224128 0.135105 0.5931532 0.3783345 0.5224128 0.3795996 0.5252786 0.135105 0.5931532 0.3795996 0.5252786 0.3807644 0.528214 0.2053283 0.8582362 0.517755 0.8636898 0.2053067 0.8636897 0.517755 0.8636898 0.2053283 0.8582362 0.5177766 0.8582363 0.03627306 0.5723607 0.03916299 0.5926004 0.03858023 0.5908151 0.03916299 0.5926004 0.03627306 0.5723607 0.5070922 0.507974 0.03916299 0.5926004 0.5070922 0.507974 0.04272258 0.6003656 0.04272258 0.6003656 0.5070922 0.507974 0.04763519 0.6077696 0.04763519 0.6077696 0.5070922 0.507974 0.05399525 0.6147268 0.05399525 0.6147268 0.5070922 0.507974 0.06198674 0.6211186 0.06198674 0.6211186 0.5070922 0.507974 0.07191914 0.6267797 0.07191914 0.6267797 0.5070922 0.507974 0.08433628 0.6314562 0.08433628 0.6314562 0.5070922 0.507974 0.0976237 0.6360335 0.0976237 0.6360335 0.5070922 0.507974 0.1221578 0.6355697 0.1221578 0.6355697 0.5070922 0.507974 0.1576269 0.6311599 0.1576269 0.6311599 0.5070922 0.507974 0.307152 0.5985581 0.307152 0.5985581 0.5070922 0.507974 0.3142243 0.6303795 0.3142243 0.6303795 0.5070922 0.507974 0.3161256 0.6339011 0.3161256 0.6339011 0.5070922 0.507974 0.318292 0.6372562 0.318292 0.6372562 0.5070922 0.507974 0.3208434 0.6403455 0.3208434 0.6403455 0.5070922 0.507974 0.3238481 0.6430935 0.3238481 0.6430935 0.5070922 0.507974 0.3273076 0.6454655 0.3273076 0.6454655 0.5070922 0.507974 0.3312348 0.6474158 0.3312348 0.6474158 0.5070922 0.507974 0.3356576 0.6488835 0.3356576 0.6488835 0.5070922 0.507974 0.340626 0.6497844 0.340626 0.6497844 0.5070922 0.507974 0.3462248 0.6499955 0.3462248 0.6499955 0.5070922 0.507974 0.3526018 0.6493247 0.3526018 0.6493247 0.5070922 0.507974 0.3600295 0.6474422 0.3600295 0.6474422 0.5070922 0.507974 0.5122643 0.5957686 0.5122643 0.5957686 0.5070922 0.507974 0.5150828 0.5946012 0.5150828 0.5946012 0.5070922 0.507974 0.5177249 0.5930759 0.5177249 0.5930759 0.5070922 0.507974 0.5201451 0.5912188 0.5201451 0.5912188 0.5070922 0.507974 0.5223025 0.5890616 0.5223025 0.5890616 0.5070922 0.507974 0.5241596 0.5866414 0.5241596 0.5866414 0.5070922 0.507974 0.5256851 0.5839992 0.5256851 0.5839992 0.5070922 0.507974 0.5268527 0.5811807 0.5268527 0.5811807 0.5070922 0.507974 0.5276423 0.5782339 0.5276423 0.5782339 0.5070922 0.507974 0.5280405 0.5752085 0.5280405 0.5752085 0.5070922 0.507974 0.5280405 0.5712473 0.5280405 0.5712473 0.5070922 0.507974 0.5272244 0.5652452 0.5272244 0.5652452 0.5070922 0.507974 0.5228158 0.5496596 0.3142243 0.6303795 0.3132684 0.6285399 0.307152 0.5985581 0.1976899 0.6716608 0.2087988 0.6429921 0.5528385 0.6716608 0.2087988 0.6429921 0.1976899 0.6716608 0.1973378 0.5748788 0.2087988 0.6429921 0.1973378 0.5748788 0.2086109 0.6316074 0.2086109 0.6316074 0.1973378 0.5748788 0.2087991 0.6210545 0.2087991 0.6210545 0.1973378 0.5748788 0.2753704 0.6208382 0.5528385 0.6716608 0.2753821 0.6430054 0.5528892 0.5751809 0.2753821 0.6430054 0.5528385 0.6716608 0.2087988 0.6429921 0.5528892 0.5751809 0.2753821 0.6430054 0.2753704 0.6208382 0.5528892 0.5751809 0.2753704 0.6208382 0.1973378 0.5748788 0.4996544 0.7725195 0.4675381 0.5017424 0.4964377 0.4985265 0.4675381 0.5017424 0.4996544 0.7725195 0.4605889 0.7718424 0.02792859 0.7965196 0.1622447 0.7988198 0.02792859 0.8110635 0.1622447 0.7988198 0.02792859 0.7965196 0.1903667 0.7867602 0.1622447 0.7988198 0.1903667 0.7867602 0.2388416 0.7977869 0.02792859 0.8110635 0.1622447 0.7988198 0.1622447 0.8110635 0.1622447 0.8110635 0.02792859 0.8256073 0.02792859 0.8110635 0.02792859 0.8256073 0.1622447 0.8110635 0.1622447 0.8256073 0.1622447 0.8256073 0.02792859 0.8401511 0.02792859 0.8256073 0.02792859 0.8401511 0.1622447 0.8256073 0.1622447 0.8401511 0.1622447 0.8401511 0.02792859 0.8546947 0.02792859 0.8401511 0.02792859 0.8546947 0.1622447 0.8401511 0.1622447 0.8546947 0.1622447 0.8546947 0.02792859 0.8692383 0.02792859 0.8546947 0.02792859 0.8692383 0.1622447 0.8546947 0.1622447 0.8692383 0.1622447 0.8837821 0.02792859 0.8692383 0.1622447 0.8692383 0.02792859 0.8692383 0.1622447 0.8837821 0.02792859 0.8837821 0.02792859 0.8837821 0.1622447 0.8983259 0.02792859 0.8983259 0.1622447 0.8983259 0.02792859 0.8837821 0.1622447 0.8837821 0.1622447 0.8983259 0.02792859 0.9128695 0.02792859 0.8983259 0.02792859 0.9128695 0.1622447 0.8983259 0.1622447 0.9128695 0.02792859 0.9128695 0.1622447 0.9274131 0.02792859 0.9274131 0.1622447 0.9274131 0.02792859 0.9128695 0.1622447 0.9128695 0.1622447 0.9274131 0.02792859 0.9419569 0.02792859 0.9274131 0.02792859 0.9419569 0.1622447 0.9274131 0.1622447 0.9419568 0.1622447 0.9419568 0.02792865 0.9565007 0.02792859 0.9419569 0.02792865 0.9565007 0.1622447 0.9419568 0.1622447 0.9565007 0.02792865 0.9565007 0.1622447 0.9710445 0.02792865 0.9710446 0.1622447 0.9710445 0.02792865 0.9565007 0.1622447 0.9565007 0.01645559 0.5028411 0.06816321 0.5616546 0.02940344 0.7557495 0.06816321 0.5616546 0.01645559 0.5028411 0.09505861 0.504449 0.06816321 0.5616546 0.09505861 0.504449 0.1449036 0.5272001 0.1449036 0.5272001 0.3124958 0.5616551 0.06816321 0.5616546 0.3124958 0.5616551 0.1449036 0.5272001 0.3670243 0.5272005 0.3124958 0.5616551 0.3670243 0.5272005 0.3124961 0.7615634 0.3124961 0.7615634 0.3670243 0.5272005 0.3670243 0.7798659 0.01163113 0.779866 0.02940344 0.7557495 0.3670243 0.7798659 0.02940344 0.7557495 0.01163113 0.779866 0.01645559 0.5028411 0.3670243 0.7798659 0.02940344 0.7557495 0.3124961 0.7615634 0.2054628 0.8037023 0.5178895 0.8091557 0.2054412 0.8091557 0.5178895 0.8091557 0.2054628 0.8037023 0.5179111 0.8037023 0.5178895 0.8091557 0.2054604 0.8146092 0.2054412 0.8091557 0.2054604 0.8146092 0.5178895 0.8091557 0.5179087 0.8146091 0.2054604 0.8146092 0.5178871 0.8200625 0.2054387 0.8200625 0.5178871 0.8200625 0.2054604 0.8146092 0.5179087 0.8146091 0.2054387 0.8200625 0.5178654 0.8255159 0.2054172 0.8255159 0.5178654 0.8255159 0.2054387 0.8200625 0.5178871 0.8200625 0.5178654 0.8255159 0.2054364 0.8309694 0.2054172 0.8255159 0.2054364 0.8309694 0.5178654 0.8255159 0.5178847 0.8309695 0.2054364 0.8309694 0.5178631 0.8364228 0.2054147 0.8364227 0.5178631 0.8364228 0.2054364 0.8309694 0.5178847 0.8309695 0.2054147 0.8364227 0.5178415 0.8418762 0.2053931 0.8418762 0.5178415 0.8418762 0.2054147 0.8364227 0.5178631 0.8364228 0.2053931 0.8418762 0.5178199 0.8473295 0.2053715 0.8473294 0.5178199 0.8473295 0.2053931 0.8418762 0.5178415 0.8418762 0.2053715 0.8473294 0.5177983 0.8527829 0.2053499 0.8527829 0.5177983 0.8527829 0.2053715 0.8473294 0.5178199 0.8473295 0.2053499 0.8527829 0.5177766 0.8582363 0.2053283 0.8582362 0.5177766 0.8582363 0.2053499 0.8527829 0.5177983 0.8527829 0.5810377 0.3290749 0.004902899 -2.63568e-4 0.5810353 -2.67383e-4 0.004902899 -2.63568e-4 0.5810377 0.3290749 0.004905402 0.3258628 0.5006948 0.9424874 0.3083641 0.9458445 0.3083513 0.9424874 0.3083641 0.9458445 0.5006948 0.9424874 0.5007075 0.9458445 0.5006819 0.9391302 0.3083513 0.9424874 0.3083385 0.9391302 0.3083513 0.9424874 0.5006819 0.9391302 0.5006948 0.9424874 0.500669 0.9357731 0.3083385 0.9391302 0.3083257 0.9357731 0.3083385 0.9391302 0.500669 0.9357731 0.5006819 0.9391302 0.3083403 0.932416 0.500669 0.9357731 0.3083257 0.9357731 0.500669 0.9357731 0.3083403 0.932416 0.5006837 0.932416 0.5006709 0.9290589 0.3083403 0.932416 0.3083274 0.9290589 0.3083403 0.932416 0.5006709 0.9290589 0.5006837 0.932416 0.500658 0.9257017 0.3083274 0.9290589 0.3083146 0.9257017 0.3083274 0.9290589 0.500658 0.9257017 0.5006709 0.9290589 0.5006453 0.9223446 0.3083146 0.9257017 0.3083018 0.9223446 0.3083146 0.9257017 0.5006453 0.9223446 0.500658 0.9257017 0.5006324 0.9189875 0.3083018 0.9223446 0.308289 0.9189875 0.3083018 0.9223446 0.5006324 0.9189875 0.5006453 0.9223446 0.5006195 0.9156304 0.308289 0.9189875 0.3082761 0.9156304 0.308289 0.9189875 0.5006195 0.9156304 0.5006324 0.9189875 0.5006069 0.9122732 0.3082761 0.9156304 0.3082634 0.9122732 0.3082761 0.9156304 0.5006069 0.9122732 0.5006195 0.9156304 0.500594 0.9089161 0.3082634 0.9122732 0.3082505 0.9089161 0.3082634 0.9122732 0.500594 0.9089161 0.5006069 0.9122732 0.5005812 0.9055589 0.3082505 0.9089161 0.3082377 0.9055589 0.3082505 0.9089161 0.5005812 0.9055589 0.500594 0.9089161 0.513914 0.6166138 0.543264 0.7623949 0.5141082 0.7624337 0.543264 0.7623949 0.513914 0.6166138 0.5430698 0.616575 0.5783509 0.9348304 0.8004086 0.7126473 0.8004712 0.9347677 0.8004086 0.7126473 0.5783509 0.9348304 0.5782881 0.71271 0.2387915 0.9425332 0.01667326 0.9506654 0.01667326 0.9425332 0.01667326 0.9506654 0.2387915 0.9425332 0.2387915 0.9506654 0.01667326 0.9344012 0.2387915 0.9425332 0.01667326 0.9425332 0.2387915 0.9425332 0.01667326 0.9344012 0.2387915 0.9344012 0.2387915 0.9262689 0.01667326 0.9344012 0.01667326 0.9262689 0.01667326 0.9344012 0.2387915 0.9262689 0.2387915 0.9344012 0.01667326 0.9181368 0.2387915 0.9262689 0.01667326 0.9262689 0.2387915 0.9262689 0.01667326 0.9181368 0.2387915 0.9181368 0.01667326 0.9100046 0.2387915 0.9181368 0.01667326 0.9181368 0.2387915 0.9181368 0.01667326 0.9100046 0.2387915 0.9100046 0.2387915 0.9100046 0.01667326 0.9018725 0.2387915 0.9018725 0.01667326 0.9018725 0.2387915 0.9100046 0.01667326 0.9100046 0.2387915 0.8937404 0.01667326 0.9018725 0.01667326 0.8937404 0.01667326 0.9018725 0.2387915 0.8937404 0.2387915 0.9018725 0.2387915 0.8856082 0.01667326 0.8937404 0.01667326 0.8856082 0.01667326 0.8937404 0.2387915 0.8856082 0.2387915 0.8937404 0.2387915 0.8856082 0.01667326 0.8785375 0.2387915 0.8785375 0.01667326 0.8785375 0.2387915 0.8856082 0.01667326 0.8856082 0.3463059 0.8039488 0.3469521 0.8186389 0.3460763 0.8113182 0.3469521 0.8186389 0.3463059 0.8039488 0.3476359 0.7966968 0.3469521 0.8186389 0.3476359 0.7966968 0.3474103 0.8155959 0.3476358 0.821116 0.3469521 0.8186389 0.3474103 0.8155959 0.02276283 0.649084 0.02326941 0.6542758 0.01886004 0.6436307 0.02326941 0.6542758 0.02276283 0.649084 0.03011286 0.6661288 0.03011286 0.6661288 0.02276283 0.649084 0.02813971 0.6546137 0.03011286 0.6661288 0.02813971 0.6546137 0.03844487 0.6769872 0.03844487 0.6769872 0.02813971 0.6546137 0.03428351 0.6592766 0.03844487 0.6769872 0.03428351 0.6592766 0.04812294 0.6866653 0.04812294 0.6866653 0.03428351 0.6592766 0.04105603 0.6629673 0.04812294 0.6866653 0.04105603 0.6629673 0.05898147 0.6949973 0.05898147 0.6949973 0.04105603 0.6629673 0.04830461 0.665603 0.05898147 0.6949973 0.04830461 0.665603 0.05586606 0.6671242 0.05898147 0.6949973 0.05586606 0.6671242 0.07083457 0.7018406 0.07083457 0.7018406 0.05586606 0.6671242 0.0635699 0.6674966 0.07083457 0.7018406 0.0635699 0.6674966 0.08347952 0.7070783 0.08347952 0.7070783 0.0635699 0.6674966 0.07124274 0.6667118 0.08347952 0.7070783 0.07124274 0.6667118 0.09669995 0.7106207 0.09669995 0.7106207 0.07124274 0.6667118 0.07871174 0.6647876 0.09669995 0.7106207 0.07871174 0.6647876 0.2782015 0.5970696 0.09669995 0.7106207 0.2782015 0.5970696 0.1102693 0.7124071 0.1102693 0.7124071 0.2782015 0.5970696 0.1239554 0.7124071 0.1239554 0.7124071 0.2782015 0.5970696 0.1375257 0.7106205 0.1375257 0.7106205 0.2782015 0.5970696 0.1507464 0.707078 0.1507464 0.707078 0.2782015 0.5970696 0.2917414 0.6369565 0.1507464 0.707078 0.3467264 0.6535217 0.4178983 0.640721 0.3467264 0.6535217 0.1507464 0.707078 0.3289683 0.6547557 0.3289683 0.6547557 0.1507464 0.707078 0.3191681 0.6543058 0.3191681 0.6543058 0.1507464 0.707078 0.3125244 0.6532064 0.3125244 0.6532064 0.1507464 0.707078 0.307578 0.6517596 0.307578 0.6517596 0.1507464 0.707078 0.3037016 0.6500869 0.3037016 0.6500869 0.1507464 0.707078 0.3005734 0.6482448 0.3005734 0.6482448 0.1507464 0.707078 0.2980099 0.6462596 0.2980099 0.6462596 0.1507464 0.707078 0.2959001 0.644142 0.2959001 0.644142 0.1507464 0.707078 0.2941756 0.6418924 0.2941756 0.6418924 0.1507464 0.707078 0.2927965 0.6395036 0.2927965 0.6395036 0.1507464 0.707078 0.2917414 0.6369565 + + + + + + + + + + + + + + + 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 +

0 0 0 1 1 1 2 2 2 1 1 3 0 0 4 3 3 5 4 4 6 0 0 7 5 5 8 0 0 9 4 4 10 3 3 11 6 6 12 7 6 13 8 6 14 7 7 15 6 7 16 9 7 17 7 8 18 9 8 19 10 8 20 7 9 21 10 9 22 11 9 23 11 10 24 10 10 25 12 10 26 11 11 27 12 11 28 13 11 29 13 12 30 12 12 31 14 12 32 13 13 33 14 13 34 15 13 35 13 14 36 15 14 37 16 14 38 16 15 39 15 15 40 17 15 41 16 16 42 17 16 43 18 16 44 18 17 45 17 17 46 19 17 47 18 18 48 19 18 49 20 18 50 18 19 51 20 19 52 21 19 53 21 20 54 20 20 55 22 20 56 21 21 57 22 21 58 23 21 59 21 22 60 23 22 61 24 22 62 24 23 63 23 23 64 25 23 65 24 24 66 25 24 67 26 24 68 24 25 69 26 25 70 27 25 71 24 26 72 27 26 73 28 26 74 28 27 75 27 27 76 29 27 77 28 28 78 29 28 79 30 28 80 30 29 81 29 29 82 31 29 83 31 30 84 29 30 85 32 30 86 32 31 87 29 31 88 33 31 89 2 2 90 34 32 91 35 33 92 34 32 93 2 2 94 1 1 95 36 34 96 37 34 97 38 34 98 37 35 99 36 35 100 39 35 101 39 36 102 36 36 103 40 36 104 40 37 105 36 37 106 41 37 107 40 38 108 41 38 109 42 38 110 42 39 111 41 39 112 43 39 113 42 40 114 43 40 115 44 40 116 44 41 117 43 41 118 45 41 119 44 42 120 45 42 121 46 42 122 46 43 123 45 43 124 47 43 125 46 44 126 47 44 127 48 44 128 48 45 129 47 45 130 49 45 131 48 46 132 49 46 133 50 46 134 50 47 135 49 47 136 51 47 137 51 48 138 49 48 139 52 48 140 51 49 141 52 49 142 53 49 143 53 50 144 52 50 145 54 50 146 53 51 147 54 51 148 55 51 149 55 52 150 54 52 151 56 52 152 56 53 153 54 53 154 57 53 155 56 54 156 57 54 157 58 54 158 58 55 159 57 55 160 59 55 161 59 56 162 57 56 163 60 56 164 59 57 165 60 57 166 61 57 167 61 58 168 60 58 169 62 58 170 61 59 171 62 59 172 63 59 173 64 60 174 4 4 175 5 5 176 4 4 177 64 60 178 65 61 179 66 62 180 67 63 181 68 64 182 67 63 183 66 62 184 69 65 185 70 66 186 68 64 187 71 67 188 68 64 189 70 66 190 66 62 191 72 68 192 71 67 193 73 69 194 71 67 195 72 68 196 70 66 197 74 70 198 75 70 199 76 70 200 75 71 201 74 71 202 77 71 203 75 72 204 77 72 205 78 72 206 79 73 207 80 74 208 81 75 209 80 74 210 79 73 211 82 76 212 83 77 213 82 76 214 79 73 215 82 76 216 83 77 217 84 78 218 85 79 219 83 77 220 86 80 221 83 77 222 85 79 223 84 78 224 87 81 225 85 79 226 86 80 227 85 79 228 87 81 229 88 82 230 89 83 231 87 81 232 90 84 233 87 81 234 89 83 235 88 82 236 91 85 237 90 84 238 92 86 239 90 84 240 91 85 241 89 83 242 93 87 243 92 86 244 94 88 245 92 86 246 93 87 247 91 85 248 95 89 249 94 88 250 96 90 251 94 88 252 95 89 253 93 87 254 97 91 255 96 90 256 98 92 257 96 90 258 97 91 259 95 89 260 97 91 261 99 93 262 100 94 263 99 93 264 97 91 265 98 92 266 100 94 267 101 95 268 102 96 269 101 95 270 100 94 271 99 93 272 102 96 273 103 97 274 104 98 275 103 97 276 102 96 277 101 95 278 104 98 279 105 99 280 106 100 281 105 99 282 104 98 283 103 97 284 107 101 285 108 101 286 109 101 287 108 102 288 107 102 289 110 102 290 110 103 291 107 103 292 111 103 293 112 104 294 113 105 295 114 106 296 113 105 297 112 104 298 115 107 299 116 108 300 115 107 301 112 104 302 115 107 303 116 108 304 117 109 305 116 108 306 34 32 307 117 109 308 34 32 309 116 108 310 35 33 311 118 110 312 64 60 313 119 111 314 64 60 315 118 110 316 65 61 317 120 112 318 118 110 319 119 111 320 118 110 321 120 112 322 121 113 323 67 63 324 121 113 325 120 112 326 121 113 327 67 63 328 69 65 329 122 114 330 123 114 331 124 114 332 123 115 333 122 115 334 125 115 335 125 116 336 122 116 337 126 116 338 126 117 339 122 117 340 127 117 341 126 118 342 127 118 343 128 118 344 128 119 345 127 119 346 129 119 347 128 120 348 129 120 349 130 120 350 130 121 351 129 121 352 131 121 353 130 122 354 131 122 355 132 122 356 132 123 357 131 123 358 133 123 359 132 124 360 133 124 361 134 124 362 134 125 363 133 125 364 135 125 365 135 126 366 133 126 367 136 126 368 135 127 369 136 127 370 137 127 371 137 128 372 136 128 373 138 128 374 137 129 375 138 129 376 139 129 377 139 130 378 138 130 379 140 130 380 140 131 381 138 131 382 141 131 383 140 132 384 141 132 385 142 132 386 142 133 387 141 133 388 143 133 389 143 134 390 141 134 391 144 134 392 143 135 393 144 135 394 145 135 395 145 136 396 144 136 397 146 136 398 146 137 399 144 137 400 147 137 401 146 138 402 147 138 403 148 138 404 146 139 405 148 139 406 149 139 407 150 140 408 151 140 409 152 140 410 151 141 411 150 141 412 153 141 413 154 142 414 155 142 415 156 142 416 155 143 417 154 143 418 157 143 419 158 144 420 159 144 421 160 144 422 159 145 423 158 145 424 161 145 425 162 146 426 163 146 427 164 146 428 163 147 429 162 147 430 165 147 431 166 148 432 167 148 433 168 148 434 167 149 435 166 149 436 169 149 437 170 150 438 171 151 439 172 152 440 171 151 441 170 150 442 173 153 443 174 154 444 175 154 445 176 154 446 175 155 447 174 155 448 177 155 449 177 156 450 174 156 451 178 156 452 177 157 453 178 157 454 179 157 455 177 158 456 179 158 457 180 158 458 177 159 459 180 159 460 181 159 461 177 160 462 181 160 463 182 160 464 177 161 465 182 161 466 183 161 467 177 162 468 183 162 469 184 162 470 177 163 471 184 163 472 185 163 473 177 164 474 185 164 475 186 164 476 177 165 477 186 165 478 187 165 479 177 166 480 187 166 481 188 166 482 177 167 483 188 167 484 189 167 485 177 168 486 189 168 487 190 168 488 177 169 489 190 169 490 191 169 491 177 170 492 191 170 493 192 170 494 177 171 495 192 171 496 193 171 497 177 172 498 193 172 499 194 172 500 177 173 501 194 173 502 195 173 503 177 174 504 195 174 505 196 174 506 177 175 507 196 175 508 197 175 509 177 176 510 197 176 511 198 176 512 177 177 513 198 177 514 199 177 515 177 178 516 199 178 517 200 178 518 177 179 519 200 179 520 201 179 521 202 180 522 173 153 523 170 150 524 173 153 525 202 180 526 203 181 527 204 182 528 205 182 529 206 182 530 205 183 531 204 183 532 207 183 533 205 184 534 207 184 535 208 184 536 208 185 537 207 185 538 209 185 539 209 186 540 207 186 541 210 186 542 210 187 543 207 187 544 211 187 545 211 188 546 207 188 547 212 188 548 212 189 549 207 189 550 213 189 551 213 190 552 207 190 553 214 190 554 214 191 555 207 191 556 215 191 557 215 192 558 207 192 559 216 192 560 216 193 561 207 193 562 217 193 563 217 194 564 207 194 565 218 194 566 218 195 567 207 195 568 219 195 569 219 196 570 207 196 571 220 196 572 220 197 573 207 197 574 221 197 575 221 198 576 207 198 577 222 198 578 222 199 579 207 199 580 223 199 581 223 200 582 207 200 583 224 200 584 224 201 585 207 201 586 225 201 587 225 202 588 207 202 589 226 202 590 226 203 591 207 203 592 227 203 593 227 204 594 207 204 595 228 204 596 228 205 597 207 205 598 229 205 599 229 206 600 207 206 601 230 206 602 230 207 603 207 207 604 231 207 605 231 208 606 207 208 607 232 208 608 232 209 609 207 209 610 233 209 611 233 210 612 207 210 613 234 210 614 234 211 615 207 211 616 235 211 617 235 212 618 207 212 619 236 212 620 236 213 621 207 213 622 237 213 623 237 214 624 207 214 625 238 214 626 238 215 627 207 215 628 239 215 629 239 216 630 207 216 631 240 216 632 240 217 633 207 217 634 241 217 635 241 218 636 207 218 637 242 218 638 218 219 639 243 219 640 217 219 641 244 220 642 245 220 643 246 220 644 245 221 645 244 221 646 247 221 647 245 222 648 247 222 649 248 222 650 248 223 651 247 223 652 249 223 653 249 224 654 247 224 655 250 224 656 246 225 657 251 225 658 252 225 659 251 226 660 246 226 661 245 226 662 252 227 663 251 227 664 250 227 665 252 228 666 250 228 667 247 228 668 253 229 669 254 230 670 255 231 671 254 230 672 253 229 673 256 232 674 257 233 675 258 234 676 259 235 677 258 236 678 257 236 679 260 236 680 258 237 681 260 237 682 261 237 683 259 235 684 258 234 685 262 238 686 262 238 687 263 239 688 259 235 689 263 239 690 262 238 691 264 240 692 264 240 693 265 241 694 263 239 695 265 241 696 264 240 697 266 242 698 266 242 699 267 243 700 265 241 701 267 243 702 266 242 703 268 244 704 268 244 705 269 245 706 267 243 707 269 245 708 268 244 709 270 246 710 271 247 711 269 245 712 270 246 713 269 245 714 271 247 715 272 248 716 272 248 717 273 249 718 274 250 719 273 249 720 272 248 721 271 247 722 273 249 723 275 251 724 274 250 725 275 251 726 273 249 727 276 252 728 275 251 729 277 253 730 278 254 731 277 253 732 275 251 733 276 252 734 277 253 735 279 255 736 278 254 737 279 255 738 277 253 739 280 256 740 280 256 741 281 257 742 279 255 743 281 257 744 280 256 745 282 258 746 281 257 747 283 259 748 284 260 749 283 259 750 281 257 751 282 258 752 285 261 753 286 261 754 287 261 755 286 262 756 285 262 757 288 262 758 286 263 759 288 263 760 289 263 761 289 264 762 290 264 763 286 264 764 290 265 765 289 265 766 291 265 767 290 266 768 291 266 769 292 266 770 292 267 771 291 267 772 293 267 773 294 268 774 287 268 775 293 268 776 287 269 777 294 269 778 285 269 779 293 270 780 287 270 781 292 270 782 295 271 783 296 272 784 297 273 785 296 272 786 295 271 787 298 274 788 296 272 789 299 275 790 297 273 791 299 275 792 296 272 793 300 276 794 299 275 795 301 277 796 302 278 797 301 277 798 299 275 799 300 276 800 302 278 801 303 279 802 304 280 803 303 279 804 302 278 805 301 277 806 303 279 807 305 281 808 304 280 809 305 281 810 303 279 811 306 282 812 305 281 813 307 283 814 308 284 815 307 283 816 305 281 817 306 282 818 308 284 819 309 285 820 310 286 821 309 285 822 308 284 823 307 283 824 310 286 825 311 287 826 312 288 827 311 287 828 310 286 829 309 285 830 312 288 831 313 289 832 314 290 833 313 289 834 312 288 835 311 287 836 314 290 837 203 181 838 202 180 839 203 181 840 314 290 841 313 289 842 315 291 843 255 231 844 316 292 845 255 231 846 315 291 847 253 229 848 317 293 849 318 294 850 319 295 851 318 294 852 317 293 853 320 296 854 321 297 855 319 295 856 322 298 857 319 295 858 321 297 859 317 293 860 323 299 861 322 298 862 324 300 863 322 298 864 323 299 865 321 297 866 325 301 867 323 299 868 324 300 869 323 299 870 325 301 871 326 302 872 327 303 873 325 301 874 328 304 875 325 301 876 327 303 877 326 302 878 329 305 879 328 304 880 330 306 881 328 304 882 329 305 883 327 303 884 331 307 885 330 306 886 332 308 887 330 306 888 331 307 889 329 305 890 333 309 891 332 308 892 334 310 893 332 308 894 333 309 895 331 307 896 335 311 897 334 310 898 336 312 899 334 310 900 335 311 901 333 309 902 337 313 903 336 312 904 338 314 905 336 312 906 337 313 907 335 311 908 339 315 909 338 314 910 340 316 911 338 314 912 339 315 913 337 313 914 341 317 915 340 316 916 342 318 917 340 316 918 341 317 919 339 315 920 343 319 921 344 319 922 345 319 923 344 320 924 343 320 925 346 320 926 347 321 927 348 321 928 349 321 929 348 322 930 347 322 931 350 322 932 351 323 933 352 324 934 353 325 935 352 324 936 351 323 937 354 326 938 355 327 939 351 323 940 353 325 941 351 323 942 355 327 943 356 328 944 357 329 945 355 327 946 358 330 947 355 327 948 357 329 949 356 328 950 359 331 951 357 329 952 358 330 953 357 329 954 359 331 955 360 332 956 361 333 957 360 332 958 359 331 959 360 332 960 361 333 961 362 334 962 362 334 963 363 335 964 364 336 965 363 335 966 362 334 967 361 333 968 365 337 969 363 335 970 366 338 971 363 335 972 365 337 973 364 336 974 367 339 975 366 338 976 368 340 977 366 338 978 367 339 979 365 337 980 367 339 981 369 341 982 370 342 983 369 341 984 367 339 985 368 340 986 371 343 987 372 343 988 373 343 989 372 344 990 371 344 991 374 344 992 372 345 993 374 345 994 375 345 995 376 346 996 372 346 997 375 346 998 377 347 999 378 347 1000 379 347 1001 378 348 1002 377 348 1003 380 348 1004 380 349 1005 377 349 1006 381 349 1007 380 350 1008 381 350 1009 382 350 1010 382 351 1011 381 351 1012 383 351 1013 382 352 1014 383 352 1015 384 352 1016 384 353 1017 383 353 1018 385 353 1019 384 354 1020 385 354 1021 386 354 1022 386 355 1023 385 355 1024 387 355 1025 386 356 1026 387 356 1027 388 356 1028 386 357 1029 388 357 1030 389 357 1031 389 358 1032 388 358 1033 390 358 1034 389 359 1035 390 359 1036 391 359 1037 391 360 1038 390 360 1039 392 360 1040 391 361 1041 392 361 1042 393 361 1043 393 362 1044 392 362 1045 394 362 1046 393 363 1047 394 363 1048 395 363 1049 393 364 1050 395 364 1051 396 364 1052 396 365 1053 395 365 1054 397 365 1055 397 366 1056 395 366 1057 398 366 1058 398 367 1059 395 367 1060 399 367 1061 399 368 1062 395 368 1063 400 368 1064 399 369 1065 401 369 1066 402 369 1067 401 370 1068 399 370 1069 403 370 1070 403 371 1071 399 371 1072 404 371 1073 404 372 1074 399 372 1075 405 372 1076 405 373 1077 399 373 1078 406 373 1079 406 374 1080 399 374 1081 407 374 1082 407 375 1083 399 375 1084 408 375 1085 408 376 1086 399 376 1087 409 376 1088 409 377 1089 399 377 1090 410 377 1091 410 378 1092 399 378 1093 411 378 1094 411 379 1095 399 379 1096 412 379 1097 412 380 1098 399 380 1099 400 380 1100

+
+
+
+
+ + + + + 0.6858805 -0.3173701 0.6548619 7.481132 0.7276338 0.3124686 -0.6106656 -6.50764 -0.01081678 0.8953432 0.4452454 5.343665 0 0 0 1 + + + + -0.2908646 -0.7711008 0.5663932 9.768214 0.9551712 -0.1998834 0.2183912 0.2533256 -0.05518906 0.6045247 0.7946723 6.205874 0 0 0 1 + + + + 0.0254 0 0 0.001409317 0 0.0254 0 -0.003276879 0 0 0.0254 -0.002205567 0 0 0 1 + + 1 0 0 -5.316289 0 1 0 -6.059348 0 0 1 0.002081193 0 0 0 1 + + + + + + + + + + + 1 0 0 0.01970216 0 1 0 -0.3079368 0 0 1 -0.09546833 0 0 0 1 + + + + 1 0 0 -0.3970417 0 1 0 0.02320915 0 0 1 0.04494383 0 0 0 1 + + + + 1 0 0 0.03263873 0 1 0 0.37315 0 0 1 -0.5897875 0 0 0 1 + + + + + + + +
\ No newline at end of file diff --git a/src/parts source/kOS Radial dev/Assets/kosradial.dae.meta b/src/parts source/kOS Radial dev/Assets/kosradial.dae.meta new file mode 100644 index 000000000..f9ecc77da --- /dev/null +++ b/src/parts source/kOS Radial dev/Assets/kosradial.dae.meta @@ -0,0 +1,86 @@ +fileFormatVersion: 2 +guid: 5846abad126214531b92e374087b8026 +timeCreated: 1430922506 +licenseType: Free +ModelImporter: + serializedVersion: 18 + fileIDToRecycleName: + 100000: Area + 100002: Camera + 100004: group_0_002 + 100006: //RootNode + 100008: Lamp + 100010: Point + 100012: Point_001 + 100014: SketchUp + 400000: Area + 400002: Camera + 400004: group_0_002 + 400006: //RootNode + 400008: Lamp + 400010: Point + 400012: Point_001 + 400014: SketchUp + 2300000: group_0_002 + 3300000: group_0_002 + 4300000: group_0_002 + 6400000: group_0_002 + 9500000: //RootNode + materials: + importMaterials: 1 + materialName: 0 + materialSearch: 1 + animations: + legacyGenerateAnimations: 4 + bakeSimulation: 0 + optimizeGameObjects: 0 + motionNodeName: + animationCompression: 1 + animationRotationError: .5 + animationPositionError: .5 + animationScaleError: .5 + animationWrapMode: 0 + extraExposedTransformPaths: [] + clipAnimations: [] + isReadable: 1 + meshes: + lODScreenPercentages: [] + globalScale: 1 + meshCompression: 0 + addColliders: 1 + importBlendShapes: 1 + swapUVChannels: 0 + generateSecondaryUV: 0 + useFileUnits: 1 + optimizeMeshForGPU: 1 + keepQuads: 0 + weldVertices: 1 + secondaryUVAngleDistortion: 8 + secondaryUVAreaDistortion: 15.000001 + secondaryUVHardAngle: 88 + secondaryUVPackMargin: 4 + useFileScale: 1 + tangentSpace: + normalSmoothAngle: 60 + splitTangentsAcrossUV: 1 + normalImportMode: 0 + tangentImportMode: 1 + importAnimation: 0 + copyAvatar: 0 + humanDescription: + human: [] + skeleton: [] + armTwist: .5 + foreArmTwist: .5 + upperLegTwist: .5 + legTwist: .5 + armStretch: .0500000007 + legStretch: .0500000007 + feetSpacing: 0 + rootMotionBoneName: + lastHumanDescriptionAvatarSource: {instanceID: 0} + animationType: 2 + additionalBone: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/parts source/kOS Radial dev/colorTexture.png b/src/parts source/kOS Radial dev/colorTexture.png new file mode 100644 index 000000000..7f76aa345 Binary files /dev/null and b/src/parts source/kOS Radial dev/colorTexture.png differ diff --git a/src/parts source/kOS Radial dev/compumax.dae b/src/parts source/kOS Radial dev/compumax.dae new file mode 100644 index 000000000..4dbc74706 --- /dev/null +++ b/src/parts source/kOS Radial dev/compumax.dae @@ -0,0 +1,167 @@ + + + + + SketchUp 15.3.329 + + 2015-05-05T12:07:56Z + 2015-05-05T12:07:56Z + + Z_UP + + + + + + 1.0000000 0.0000000 0.0000000 -3.1496063 0.0000000 1.0000000 0.0000000 -5.2202950 0.0000000 0.0000000 1.0000000 0.2188796 0.0000000 0.0000000 0.0000000 1.0000000 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.0000000 10.4115875 1.8934231 6.2992126 10.4171454 1.8086255 0.0000000 10.4171454 1.8086255 6.2992126 10.4115875 1.8934231 0.0000000 0.0401733 0.7581144 0.0000000 0.0234446 0.0960810 0.0000000 0.0234446 0.5028831 0.0000000 10.4171454 0.0960810 0.0000000 0.0900733 1.0089785 0.0000000 0.1722908 1.2511833 0.0000000 0.2854189 1.4805844 0.0000000 0.4275220 1.6932568 0.0000000 0.5961688 1.8855616 0.0000000 0.7884735 2.0542083 0.0000000 1.0011459 2.1963115 0.0000000 1.2305471 2.3094396 0.0000000 1.4727518 2.3916570 0.0000000 1.7236160 2.4415570 0.0000000 1.9788473 2.4582857 0.0000000 9.7674851 2.4582857 0.0000000 9.8522828 2.4527278 0.0000000 9.9356296 2.4361491 0.0000000 10.0160993 2.4088333 0.0000000 10.0923153 2.3712478 0.0000000 10.1629732 2.3240356 0.0000000 10.2268643 2.2680047 0.0000000 10.2828953 2.2041136 0.0000000 10.3301074 2.1334556 0.0000000 10.3676929 2.0572397 0.0000000 10.3950088 1.9767699 0.0000000 10.4115875 1.8934231 0.0000000 10.4171454 1.8086255 0.0000000 10.3950088 1.9767699 6.2992126 10.3950088 1.9767699 6.2992126 0.0234446 0.0960810 6.2992126 0.0260904 0.5432494 6.2992126 0.0234446 0.5028831 6.2992126 10.4171454 0.0960810 6.2992126 0.0623956 0.6631978 6.2992126 0.1243279 0.7933525 6.2992126 0.2050413 0.9127728 6.2992126 0.3027180 1.0187687 6.2992126 0.4151577 1.1089528 6.2992126 0.5398278 1.1812938 6.2992126 0.6739203 1.2341622 6.2992126 0.8144148 1.2663672 6.2992126 0.9581467 1.2771834 6.2992126 4.8951546 1.2771834 6.2992126 4.8985246 2.1157832 6.2992126 4.9085771 2.1663202 6.2992126 4.9251399 2.2151128 6.2992126 4.9479298 2.2613261 6.2992126 4.9765567 2.3041693 6.2992126 5.0105309 2.3429094 6.2992126 5.0492710 2.3768836 6.2992126 5.0921143 2.4055106 6.2992126 5.1383275 2.4283004 6.2992126 5.1871201 2.4448633 6.2992126 5.2376571 2.4549157 6.2992126 5.2890739 2.4582857 6.2992126 9.7674851 2.4582857 6.2992126 9.8522828 2.4527278 6.2992126 9.9356296 2.4361491 6.2992126 10.0160993 2.4088333 6.2992126 10.0923153 2.3712478 6.2992126 10.1629732 2.3240356 6.2992126 10.2268643 2.2680047 6.2992126 10.2828953 2.2041136 6.2992126 10.3301074 2.1334556 6.2992126 10.3676929 2.0572397 6.2992126 10.3950088 1.9767699 6.2992126 10.4115875 1.8934231 6.2992126 10.4171454 1.8086255 6.2992126 4.8951546 2.0643664 0.0000000 10.4171454 0.0960810 0.1983771 10.4171454 0.6037545 6.2992126 10.4171454 0.0960810 0.0000000 10.4171454 1.8086255 0.1983771 10.4171454 0.8006049 0.1983771 10.4171454 0.9974553 1.3794795 10.4171454 0.9974553 1.3794795 10.4171454 0.6037545 6.2992126 10.4171454 1.8086255 6.2992126 0.0234446 0.0960810 0.0000000 0.0234446 0.5028831 0.0000000 0.0234446 0.0960810 6.2992126 0.0234446 0.5028831 0.0000000 0.0234446 0.5028831 2.3622047 0.0260904 0.5432494 0.0000000 0.0401733 0.7581144 6.2992126 0.0234446 0.5028831 6.2992126 0.0260904 0.5432494 2.3622047 0.0401733 0.7581144 0.0000000 0.0900733 1.0089785 2.3622047 0.0900733 1.0089785 0.0000000 0.1722908 1.2511833 2.3622047 0.1722908 1.2511833 0.0000000 0.2854189 1.4805844 2.3622047 0.2854189 1.4805844 0.0000000 0.4275220 1.6932568 2.3622047 0.4275220 1.6932568 2.3622047 0.5961688 1.8855616 0.0000000 0.5961688 1.8855616 2.3622047 0.7884735 2.0542083 0.0000000 0.7884735 2.0542083 0.0000000 1.0011459 2.1963115 2.3622047 1.0011459 2.1963115 2.3622047 1.2305471 2.3094396 0.0000000 1.2305471 2.3094396 0.0000000 1.4727518 2.3916570 2.3622047 1.4727518 2.3916570 0.0000000 1.7236160 2.4415570 2.3622047 1.7236160 2.4415570 2.3622047 1.9788473 2.4582857 0.0000000 1.9788473 2.4582857 0.0000000 1.9788473 2.4582857 1.0020063 5.8997693 2.4582857 1.0020063 9.4430764 2.4582857 2.3622047 1.9788473 2.4582857 2.3622047 5.2890739 2.4582857 5.3327150 5.8997693 2.4582857 6.2992126 5.2890739 2.4582857 5.3327150 9.4430764 2.4582857 6.2992126 9.7674851 2.4582857 0.0000000 9.7674851 2.4582857 0.0000000 9.7674851 2.4582857 6.2992126 9.8522828 2.4527278 0.0000000 9.8522828 2.4527278 6.2992126 9.7674851 2.4582857 0.0000000 9.9356296 2.4361491 6.2992126 9.9356296 2.4361491 6.2992126 10.0160993 2.4088333 0.0000000 10.0160993 2.4088333 6.2992126 10.0923153 2.3712478 0.0000000 10.0923153 2.3712478 0.0000000 10.1629732 2.3240356 6.2992126 10.1629732 2.3240356 6.2992126 10.2268643 2.2680047 0.0000000 10.2268643 2.2680047 6.2992126 10.2828953 2.2041136 0.0000000 10.2828953 2.2041136 6.2992126 10.3301074 2.1334556 0.0000000 10.3301074 2.1334556 6.2992126 10.3676929 2.0572397 0.0000000 10.3676929 2.0572397 6.2992126 10.4171454 0.0960810 0.0000000 10.4171454 0.0960810 6.2992126 5.2376571 2.4549157 2.3622047 5.2890739 2.4582857 2.3622047 5.2376571 2.4549157 6.2992126 5.2890739 2.4582857 6.2992126 5.1871201 2.4448633 2.3622047 5.1871201 2.4448633 6.2992126 5.1383275 2.4283004 2.3622047 5.1383275 2.4283004 2.3622047 5.0921143 2.4055106 6.2992126 5.0921143 2.4055106 6.2992126 5.0492710 2.3768836 2.3622047 5.0492710 2.3768836 6.2992126 5.0105309 2.3429094 2.3622047 5.0105309 2.3429094 6.2992126 4.9765567 2.3041693 2.3622047 4.9765567 2.3041693 6.2992126 4.9479298 2.2613261 2.3622047 4.9479298 2.2613261 6.2992126 4.9251399 2.2151128 2.3622047 4.9251399 2.2151128 6.2992126 4.9085771 2.1663202 2.3622047 4.9085771 2.1663202 6.2992126 4.8985246 2.1157832 2.3622047 4.8985246 2.1157832 6.2992126 4.8951546 2.0643664 2.3622047 4.8951546 2.0643664 6.2992126 4.8951546 1.2771834 2.3622047 4.8951546 2.0643664 2.3622047 4.8951546 1.2771834 6.2992126 4.8951546 2.0643664 2.3622047 0.9581467 1.2771834 6.2992126 4.8951546 1.2771834 2.3622047 4.8951546 1.2771834 6.2992126 0.9581467 1.2771834 6.2992126 0.8144148 1.2663672 2.3622047 0.9581467 1.2771834 2.3622047 0.8144148 1.2663672 6.2992126 0.9581467 1.2771834 2.3622047 0.6739203 1.2341622 6.2992126 0.6739203 1.2341622 6.2992126 0.5398278 1.1812938 2.3622047 0.5398278 1.1812938 2.3622047 0.4151577 1.1089528 6.2992126 0.4151577 1.1089528 2.3622047 0.3027180 1.0187687 6.2992126 0.3027180 1.0187687 2.3622047 0.2050413 0.9127728 6.2992126 0.2050413 0.9127728 6.2992126 0.1243279 0.7933525 2.3622047 0.1243279 0.7933525 6.2992126 0.0623956 0.6631978 2.3622047 0.0623956 0.6631978 2.3622047 0.0260904 0.5432494 6.2992126 0.0260904 0.5432494 6.2992126 0.0009421 0.2384520 6.2992126 0.0206394 0.5252402 6.2992126 0.0000000 0.3825873 6.2992126 0.0234446 0.0960810 6.2992126 0.0234446 0.5028831 6.2992126 0.0260904 0.5432494 2.3622047 0.0623956 0.6631978 2.3622047 0.0401733 0.7581144 2.3622047 0.0260904 0.5432494 2.3622047 0.0900733 1.0089785 2.3622047 0.1243279 0.7933525 2.3622047 0.1722908 1.2511833 2.3622047 0.2050413 0.9127728 2.3622047 0.2854189 1.4805844 2.3622047 0.3027180 1.0187687 2.3622047 0.4275220 1.6932568 2.3622047 0.4151577 1.1089528 2.3622047 0.5398278 1.1812938 2.3622047 0.5961688 1.8855616 2.3622047 0.6739203 1.2341622 2.3622047 0.7884735 2.0542083 2.3622047 0.8144148 1.2663672 2.3622047 1.0011459 2.1963115 2.3622047 0.9581467 1.2771834 2.3622047 4.8951546 1.2771834 2.3622047 1.2305471 2.3094396 2.3622047 1.4727518 2.3916570 2.3622047 1.7236160 2.4415570 2.3622047 1.9788473 2.4582857 2.3622047 4.8951546 2.0643664 2.3622047 5.2376571 2.4549157 2.3622047 5.2890739 2.4582857 2.3622047 5.1871201 2.4448633 2.3622047 5.1383275 2.4283004 2.3622047 5.0921143 2.4055106 2.3622047 5.0492710 2.3768836 2.3622047 5.0105309 2.3429094 2.3622047 4.9765567 2.3041693 2.3622047 4.9479298 2.2613261 2.3622047 4.9251399 2.2151128 2.3622047 4.9085771 2.1663202 2.3622047 4.8985246 2.1157832 + + + + + + + + + + -0.0000000 0.9914449 0.1305262 -0.0000000 0.9978589 0.0654031 -0.0000000 0.9978589 0.0654031 -0.0000000 0.9914449 0.1305262 -1.0000000 -0.0000000 0.0000000 -1.0000000 -0.0000000 0.0000000 -1.0000000 -0.0000000 0.0000000 -1.0000000 -0.0000000 0.0000000 -1.0000000 -0.0000000 0.0000000 -1.0000000 -0.0000000 0.0000000 -1.0000000 -0.0000000 0.0000000 -1.0000000 -0.0000000 0.0000000 -1.0000000 -0.0000000 0.0000000 -1.0000000 -0.0000000 0.0000000 -1.0000000 -0.0000000 0.0000000 -1.0000000 -0.0000000 0.0000000 -1.0000000 -0.0000000 0.0000000 -1.0000000 -0.0000000 0.0000000 -1.0000000 -0.0000000 0.0000000 -1.0000000 -0.0000000 0.0000000 -1.0000000 -0.0000000 0.0000000 -1.0000000 -0.0000000 0.0000000 -1.0000000 -0.0000000 0.0000000 -1.0000000 -0.0000000 0.0000000 -1.0000000 -0.0000000 0.0000000 -1.0000000 -0.0000000 0.0000000 -1.0000000 -0.0000000 0.0000000 -1.0000000 -0.0000000 0.0000000 -1.0000000 -0.0000000 0.0000000 -1.0000000 -0.0000000 0.0000000 -1.0000000 -0.0000000 0.0000000 -1.0000000 -0.0000000 0.0000000 -0.0000000 0.9659258 0.2588190 -0.0000000 0.9659258 0.2588190 1.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 -0.0000000 1.0000000 0.0000000 -0.0000000 1.0000000 0.0000000 -0.0000000 1.0000000 0.0000000 -0.0000000 1.0000000 0.0000000 -0.0000000 1.0000000 0.0000000 -0.0000000 1.0000000 0.0000000 -0.0000000 1.0000000 0.0000000 -0.0000000 1.0000000 0.0000000 -0.0000000 1.0000000 0.0000000 0.0000000 -0.7071068 -0.7071068 0.0000000 -1.0000000 -0.0000000 0.0000000 -0.7071068 -0.7071068 0.0000000 -1.0000000 -0.0000000 0.0000000 -0.9978589 0.0654031 0.0000000 -0.9978589 0.0654031 0.0000000 -0.9914449 0.1305262 0.0000000 -0.9978589 0.0654031 0.0000000 -0.9978589 0.0654031 0.0000000 -0.9914449 0.1305262 0.0000000 -0.9659258 0.2588190 0.0000000 -0.9659258 0.2588190 0.0000000 -0.9238795 0.3826834 0.0000000 -0.9238795 0.3826834 0.0000000 -0.8660254 0.5000000 0.0000000 -0.8660254 0.5000000 0.0000000 -0.7933533 0.6087614 0.0000000 -0.7933533 0.6087614 0.0000000 -0.7071068 0.7071068 0.0000000 -0.7071068 0.7071068 0.0000000 -0.6087614 0.7933533 0.0000000 -0.6087614 0.7933533 -0.0000000 -0.5000000 0.8660254 -0.0000000 -0.5000000 0.8660254 -0.0000000 -0.3826834 0.9238795 -0.0000000 -0.3826834 0.9238795 -0.0000000 -0.2588190 0.9659258 -0.0000000 -0.2588190 0.9659258 -0.0000000 -0.1305262 0.9914449 -0.0000000 -0.1305262 0.9914449 -0.0000000 -0.0654031 0.9978589 -0.0000000 -0.0654031 0.9978589 -0.0000000 -0.0000000 1.0000000 -0.0000000 -0.0000000 1.0000000 -0.0000000 -0.0000000 1.0000000 -0.0000000 -0.0000000 1.0000000 -0.0000000 -0.0000000 1.0000000 -0.0000000 -0.0000000 1.0000000 -0.0000000 -0.0000000 1.0000000 -0.0000000 -0.0000000 1.0000000 -0.0000000 -0.0000000 1.0000000 -0.0000000 -0.0000000 1.0000000 -0.0000000 0.0654031 0.9978589 -0.0000000 0.1305262 0.9914449 -0.0000000 0.1305262 0.9914449 -0.0000000 0.0654031 0.9978589 -0.0000000 0.2588190 0.9659258 -0.0000000 0.2588190 0.9659258 -0.0000000 0.3826834 0.9238795 -0.0000000 0.3826834 0.9238795 -0.0000000 0.5000000 0.8660254 -0.0000000 0.5000000 0.8660254 -0.0000000 0.6087614 0.7933533 -0.0000000 0.6087614 0.7933533 -0.0000000 0.7071068 0.7071068 -0.0000000 0.7071068 0.7071068 -0.0000000 0.7933533 0.6087614 -0.0000000 0.7933533 0.6087614 -0.0000000 0.8660254 0.5000000 -0.0000000 0.8660254 0.5000000 -0.0000000 0.9238795 0.3826834 -0.0000000 0.9238795 0.3826834 0.0000000 0.0000000 -1.0000000 0.0000000 0.0000000 -1.0000000 -0.0000000 -0.1305262 0.9914449 -0.0000000 -0.0654031 0.9978589 -0.0000000 -0.1305262 0.9914449 -0.0000000 -0.0654031 0.9978589 0.0000000 -0.2588190 0.9659258 0.0000000 -0.2588190 0.9659258 0.0000000 -0.3826834 0.9238795 0.0000000 -0.3826834 0.9238795 0.0000000 -0.5000000 0.8660254 0.0000000 -0.5000000 0.8660254 0.0000000 -0.6087614 0.7933533 0.0000000 -0.6087614 0.7933533 0.0000000 -0.7071068 0.7071068 0.0000000 -0.7071068 0.7071068 0.0000000 -0.7933533 0.6087614 0.0000000 -0.7933533 0.6087614 0.0000000 -0.8660254 0.5000000 0.0000000 -0.8660254 0.5000000 0.0000000 -0.9238795 0.3826834 0.0000000 -0.9238795 0.3826834 0.0000000 -0.9659258 0.2588190 0.0000000 -0.9659258 0.2588190 0.0000000 -0.9914449 0.1305262 0.0000000 -0.9914449 0.1305262 0.0000000 -0.9978589 0.0654031 0.0000000 -0.9978589 0.0654031 0.0000000 -1.0000000 -0.0000000 0.0000000 -1.0000000 -0.0000000 0.0000000 -1.0000000 -0.0000000 0.0000000 -1.0000000 -0.0000000 -0.0000000 -0.0000000 1.0000000 -0.0000000 -0.0000000 1.0000000 -0.0000000 -0.0000000 1.0000000 -0.0000000 -0.0000000 1.0000000 0.0000000 -0.1496578 0.9887379 0.0000000 -0.0750405 0.9971805 0.0000000 -0.1496578 0.9887379 0.0000000 -0.0750405 0.9971805 0.0000000 -0.2959446 0.9552051 0.0000000 -0.2959446 0.9552051 0.0000000 -0.4355656 0.9001570 0.0000000 -0.4355656 0.9001570 0.0000000 -0.5653757 0.8248335 0.0000000 -0.5653757 0.8248335 0.0000000 -0.6824511 0.7309313 0.0000000 -0.6824511 0.7309313 0.0000000 -0.7841548 0.6205653 0.0000000 -0.7841548 0.6205653 0.0000000 -0.8681959 0.4962215 0.0000000 -0.8681959 0.4962215 0.0000000 -0.9326816 0.3607007 0.0000000 -0.9326816 0.3607007 0.0000000 -0.9571191 0.2896949 0.0000000 -0.9571191 0.2896949 1.0000000 -0.0000000 -0.0000000 1.0000000 -0.0000000 -0.0000000 1.0000000 -0.0000000 -0.0000000 1.0000000 -0.0000000 -0.0000000 1.0000000 -0.0000000 -0.0000000 1.0000000 -0.0000000 -0.0000000 1.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 + + + + + + + + + + + + + + +

0 1 2 1 0 3 4 5 6 5 4 7 7 4 8 7 8 9 7 9 10 7 10 11 7 11 12 7 12 13 7 13 14 7 14 15 7 15 16 7 16 17 7 17 18 7 18 19 7 19 20 7 20 21 7 21 22 7 22 23 7 23 24 7 24 25 7 25 26 7 26 27 7 27 28 7 28 29 7 29 30 7 30 31 32 3 0 3 32 33 34 35 36 35 34 37 35 37 38 38 37 39 39 37 40 40 37 41 41 37 42 42 37 43 43 37 44 44 37 45 45 37 46 46 37 47 47 37 48 48 37 49 49 37 50 50 37 51 51 37 52 52 37 53 53 37 54 54 37 55 55 37 56 56 37 57 57 37 58 58 37 59 59 37 60 60 37 61 61 37 62 62 37 63 63 37 64 64 37 65 65 37 66 66 37 67 67 37 68 68 37 69 69 37 70 70 37 71 71 37 72 48 73 47 74 75 76 75 74 77 75 77 78 78 77 79 79 77 80 76 81 82 81 76 75 82 81 80 82 80 77 83 84 85 84 83 86 87 88 89 88 87 90 88 90 91 89 88 92 92 93 89 93 92 94 94 95 93 95 94 96 96 97 95 97 96 98 98 99 97 99 98 100 101 99 100 99 101 102 102 103 104 103 102 101 103 105 104 105 103 106 105 107 108 107 105 106 107 109 108 109 107 110 110 111 109 111 110 112 111 113 114 113 111 112 115 116 117 116 115 118 116 118 119 119 120 116 120 119 121 120 121 122 122 121 123 124 117 123 117 124 115 123 117 122 125 126 127 126 125 128 126 129 127 129 126 130 129 131 132 131 129 130 132 133 134 133 132 131 133 135 134 135 133 136 135 137 138 137 135 136 138 139 140 139 138 137 140 141 142 141 140 139 142 143 144 143 142 141 144 33 32 33 144 143 145 85 146 85 145 83 147 148 149 148 147 150 151 149 152 149 151 147 153 152 154 152 153 151 155 153 154 153 155 156 157 155 158 155 157 156 159 158 160 158 159 157 161 160 162 160 161 159 163 162 164 162 163 161 165 164 166 164 165 163 167 166 168 166 167 165 169 168 170 168 169 167 171 170 172 170 171 169 173 174 175 174 173 176 177 178 179 178 177 180 181 182 183 182 181 184 185 181 183 181 185 186 187 185 188 185 187 186 189 187 188 187 189 190 191 190 189 190 191 192 192 193 194 193 192 191 195 193 196 193 195 194 197 196 198 196 197 195 197 199 200 199 197 198 201 202 203 202 201 204 202 204 205 206 202 205 207 208 209 208 207 210 210 207 211 210 211 212 212 211 213 212 213 214 214 213 215 214 215 216 216 215 217 216 217 218 216 218 219 219 218 220 219 220 221 221 220 222 221 222 223 223 222 224 223 224 225 223 225 226 226 225 227 227 225 228 228 225 229 229 225 230 229 231 232 231 229 233 233 229 234 234 229 235 235 229 236 236 229 237 237 229 238 238 229 239 239 229 240 240 229 241 241 229 242 242 229 230

+
+
+
+ + + + 1.1949004 6.1268953 2.0645850 5.0956477 9.2868165 2.0645850 1.1949004 9.2868165 2.0645850 5.0956477 6.1268953 2.0645850 1.0020063 5.8997693 2.4582857 5.0956477 6.1268953 2.0645850 1.1949004 6.1268953 2.0645850 5.3327150 5.8997693 2.4582857 5.3327150 9.4430764 2.4582857 5.0956477 6.1268953 2.0645850 5.3327150 5.8997693 2.4582857 5.0956477 9.2868165 2.0645850 5.0956477 9.2868165 2.0645850 1.0020063 9.4430764 2.4582857 1.1949004 9.2868165 2.0645850 5.3327150 9.4430764 2.4582857 1.1949004 6.1268953 2.0645850 1.0020063 9.4430764 2.4582857 1.0020063 5.8997693 2.4582857 1.1949004 9.2868165 2.0645850 + + + + + + + + + + -0.0000000 -0.0000000 1.0000000 -0.0000000 -0.0000000 1.0000000 -0.0000000 -0.0000000 1.0000000 -0.0000000 -0.0000000 1.0000000 -0.0000000 0.8661942 0.4997075 -0.0000000 0.8661942 0.4997075 -0.0000000 0.8661942 0.4997075 -0.0000000 0.8661942 0.4997075 -0.8566789 -0.0000000 0.5158501 -0.8566789 -0.0000000 0.5158501 -0.8566789 -0.0000000 0.5158501 -0.8566789 -0.0000000 0.5158501 0.0000000 -0.9294669 0.3689054 0.0000000 -0.9294669 0.3689054 0.0000000 -0.9294669 0.3689054 0.0000000 -0.9294669 0.3689054 0.8980077 -0.0000000 0.4399798 0.8980077 -0.0000000 0.4399798 0.8980077 -0.0000000 0.4399798 0.8980077 -0.0000000 0.4399798 + + + + + + + + + + + + + + +

0 1 2 1 0 3 4 5 6 5 4 7 8 9 10 9 8 11 12 13 14 13 12 15 16 17 18 17 16 19

+
+
+
+ + + + 0.1983771 12.4092091 0.6520971 1.3794795 12.4932570 0.5537875 0.1983771 12.4932570 0.5537875 1.3794795 12.4092091 0.6520971 1.3794795 12.3144246 0.7401012 0.1983771 12.3144246 0.7401012 1.3794795 10.4171454 0.6037545 1.3794795 11.6039150 0.9974553 1.3794795 10.4171454 0.9974553 1.3794795 11.5925805 0.6037545 1.3794795 11.6820732 0.5985973 1.3794795 11.7273735 0.9903408 1.3794795 11.7647889 0.5841695 1.3794795 11.8547897 0.9681160 1.3794795 11.8452996 0.5603354 1.3794795 11.9225395 0.5274107 1.3794795 11.9788094 0.9314017 1.3794795 11.9954860 0.4858313 1.3794795 12.0977907 0.8806841 1.3794795 12.0631733 0.4361476 1.3794795 12.1247052 0.3790173 1.3794795 12.2101583 0.8166346 1.3794795 12.1792672 0.3151970 1.3794795 12.2261367 0.2455315 1.3794795 12.3144246 0.7401012 1.3794795 12.2646934 0.1709431 1.3794795 12.2944268 0.0924194 1.3794795 12.3177149 0.0000000 1.3794795 12.4092091 0.6520971 1.3794795 12.6994820 0.0961989 1.3794795 12.4932570 0.5537875 1.3794795 12.5654554 0.4464739 1.3794795 12.6248486 0.3315771 1.3794795 12.6706502 0.2106183 1.3794795 12.5654554 0.4464739 0.1983771 12.5654554 0.4464739 0.1983771 11.6039150 0.9974553 0.1983771 10.4171454 0.8006049 0.1983771 10.4171454 0.9974553 0.1983771 11.5982478 0.8006049 0.1983771 11.7047233 0.7944690 0.1983771 11.7273735 0.9903408 0.1983771 11.8097893 0.7761427 0.1983771 11.8547897 0.9681160 0.1983771 11.9120545 0.7458686 0.1983771 11.9788094 0.9314017 0.1983771 12.0101651 0.7040474 0.1983771 12.0977907 0.8806841 0.1983771 12.1028222 0.6512330 0.1983771 12.2101583 0.8166346 0.1983771 12.1887989 0.5881244 0.1983771 12.2669572 0.5155572 0.1983771 12.3144246 0.7401012 0.1983771 12.3362621 0.4344923 0.1983771 12.4092091 0.6520971 0.1983771 12.3957961 0.3460027 0.1983771 12.4447710 0.2512601 0.1983771 12.4932570 0.5537875 0.1983771 12.4825385 0.1515189 0.1983771 12.5085984 0.0480994 0.1983771 12.5654554 0.4464739 0.1983771 12.6994820 0.0961989 0.1983771 12.6248486 0.3315771 0.1983771 12.6706502 0.2106183 0.1983771 12.2101583 0.8166346 1.3794795 12.2101583 0.8166346 1.3794795 11.7273735 0.9903408 0.1983771 11.8547897 0.9681160 0.1983771 11.7273735 0.9903408 1.3794795 11.8547897 0.9681160 1.3794795 11.6039150 0.9974553 0.1983771 11.6039150 0.9974553 1.3794795 10.4171454 0.9974553 0.1983771 10.4171454 0.9974553 1.3794795 10.4171454 0.6037545 0.1983771 10.4171454 0.8006049 0.1983771 10.4171454 0.6037545 1.3794795 10.4171454 0.9974553 0.1983771 10.4171454 0.9974553 0.1983771 11.5925805 0.6037545 1.3794795 10.4171454 0.6037545 0.1983771 10.4171454 0.6037545 1.3794795 11.5925805 0.6037545 0.1983771 11.6820732 0.5985973 1.3794795 11.6820732 0.5985973 1.3794795 11.7647889 0.5841695 0.1983771 11.7647889 0.5841695 0.1983771 11.8452996 0.5603354 1.3794795 11.8452996 0.5603354 1.3794795 11.9225395 0.5274107 0.1983771 11.9225395 0.5274107 1.3794795 11.9954860 0.4858313 0.1983771 11.9954860 0.4858313 1.3794795 12.0631733 0.4361476 0.1983771 12.0631733 0.4361476 1.3794795 12.1247052 0.3790173 0.1983771 12.1247052 0.3790173 1.3794795 12.1792672 0.3151970 0.1983771 12.1792672 0.3151970 0.1983771 12.2261367 0.2455315 1.3794795 12.2261367 0.2455315 0.1983771 12.2646934 0.1709431 1.3794795 12.2646934 0.1709431 0.1983771 12.2944268 0.0924194 1.3794795 12.2944268 0.0924194 0.1983771 12.3177149 0.0000000 1.3794795 12.3177149 0.0000000 1.3794795 12.6994820 0.0961989 0.1983771 12.5085984 0.0480994 0.1983771 12.6994820 0.0961989 0.1983771 12.3177149 0.0000000 1.3794795 12.3177149 0.0000000 0.1983771 12.6706502 0.2106183 1.3794795 12.6994820 0.0961989 0.1983771 12.6994820 0.0961989 1.3794795 12.6706502 0.2106183 0.1983771 12.6248486 0.3315771 1.3794795 12.6248486 0.3315771 1.3794795 12.0977907 0.8806841 0.1983771 12.0977907 0.8806841 0.1983771 11.9788094 0.9314017 1.3794795 11.9788094 0.9314017 0.1983771 11.5982478 0.8006049 0.1983771 10.4171454 0.6037545 0.1983771 10.4171454 0.8006049 0.1983771 11.5925805 0.6037545 0.1983771 11.6820732 0.5985973 0.1983771 11.7047233 0.7944690 0.1983771 11.7647889 0.5841695 0.1983771 11.8097893 0.7761427 0.1983771 11.8452996 0.5603354 0.1983771 11.9120545 0.7458686 0.1983771 11.9225395 0.5274107 0.1983771 12.0101651 0.7040474 0.1983771 11.9954860 0.4858313 0.1983771 12.0631733 0.4361476 0.1983771 12.1028222 0.6512330 0.1983771 12.1247052 0.3790173 0.1983771 12.1887989 0.5881244 0.1983771 12.1792672 0.3151970 0.1983771 12.2261367 0.2455315 0.1983771 12.2669572 0.5155572 0.1983771 12.2646934 0.1709431 0.1983771 12.2944268 0.0924194 0.1983771 12.3362621 0.4344923 0.1983771 12.3177149 0.0000000 0.1983771 12.5085984 0.0480994 0.1983771 12.3957961 0.3460027 0.1983771 12.4447710 0.2512601 0.1983771 12.4825385 0.1515189 + + + + + + + + + + -0.0000000 0.7214430 0.6924739 -0.0000000 0.7962131 0.6050162 -0.0000000 0.7962131 0.6050162 -0.0000000 0.7214430 0.6924739 -0.0000000 0.6371213 0.7707636 -0.0000000 0.6371213 0.7707636 1.0000000 -0.0000000 -0.0000000 1.0000000 -0.0000000 -0.0000000 1.0000000 -0.0000000 -0.0000000 1.0000000 -0.0000000 -0.0000000 1.0000000 -0.0000000 -0.0000000 1.0000000 -0.0000000 -0.0000000 1.0000000 -0.0000000 -0.0000000 1.0000000 -0.0000000 -0.0000000 1.0000000 -0.0000000 -0.0000000 1.0000000 -0.0000000 -0.0000000 1.0000000 -0.0000000 -0.0000000 1.0000000 -0.0000000 -0.0000000 1.0000000 -0.0000000 -0.0000000 1.0000000 -0.0000000 -0.0000000 1.0000000 -0.0000000 -0.0000000 1.0000000 -0.0000000 -0.0000000 1.0000000 -0.0000000 -0.0000000 1.0000000 -0.0000000 -0.0000000 1.0000000 -0.0000000 -0.0000000 1.0000000 -0.0000000 -0.0000000 1.0000000 -0.0000000 -0.0000000 1.0000000 -0.0000000 -0.0000000 1.0000000 -0.0000000 -0.0000000 1.0000000 -0.0000000 -0.0000000 1.0000000 -0.0000000 -0.0000000 1.0000000 -0.0000000 -0.0000000 1.0000000 -0.0000000 -0.0000000 1.0000000 -0.0000000 -0.0000000 -0.0000000 0.8604419 0.5095485 -0.0000000 0.8604419 0.5095485 -1.0000000 0.0000000 0.0000000 -1.0000000 0.0000000 0.0000000 -1.0000000 0.0000000 0.0000000 -1.0000000 0.0000000 0.0000000 -1.0000000 0.0000000 0.0000000 -1.0000000 0.0000000 0.0000000 -1.0000000 0.0000000 0.0000000 -1.0000000 0.0000000 0.0000000 -1.0000000 0.0000000 0.0000000 -1.0000000 0.0000000 0.0000000 -1.0000000 0.0000000 0.0000000 -1.0000000 0.0000000 0.0000000 -1.0000000 0.0000000 0.0000000 -1.0000000 0.0000000 0.0000000 -1.0000000 0.0000000 0.0000000 -1.0000000 0.0000000 0.0000000 -1.0000000 0.0000000 0.0000000 -1.0000000 0.0000000 0.0000000 -1.0000000 0.0000000 0.0000000 -1.0000000 0.0000000 0.0000000 -1.0000000 0.0000000 0.0000000 -1.0000000 0.0000000 0.0000000 -1.0000000 0.0000000 0.0000000 -1.0000000 0.0000000 0.0000000 -1.0000000 0.0000000 0.0000000 -1.0000000 0.0000000 0.0000000 -1.0000000 0.0000000 0.0000000 -1.0000000 0.0000000 0.0000000 -0.0000000 0.5443645 0.8388488 -0.0000000 0.5443645 0.8388488 -0.0000000 0.1148721 0.9933803 -0.0000000 0.2282234 0.9736088 -0.0000000 0.1148721 0.9933803 -0.0000000 0.2282234 0.9736088 -0.0000000 0.0287776 0.9995858 -0.0000000 0.0287776 0.9995858 -0.0000000 -0.0000000 1.0000000 -0.0000000 -0.0000000 1.0000000 0.0000000 -1.0000000 -0.0000000 0.0000000 -1.0000000 -0.0000000 0.0000000 -1.0000000 -0.0000000 0.0000000 -1.0000000 -0.0000000 0.0000000 -1.0000000 -0.0000000 0.0000000 -0.0287776 -0.9995858 0.0000000 0.0000000 -1.0000000 0.0000000 0.0000000 -1.0000000 0.0000000 -0.0287776 -0.9995858 0.0000000 -0.1148721 -0.9933803 0.0000000 -0.1148721 -0.9933803 0.0000000 -0.2282234 -0.9736088 0.0000000 -0.2282234 -0.9736088 0.0000000 -0.3385531 -0.9409473 0.0000000 -0.3385531 -0.9409473 0.0000000 -0.4444006 -0.8958282 0.0000000 -0.4444006 -0.8958282 0.0000000 -0.5443645 -0.8388488 0.0000000 -0.5443645 -0.8388488 0.0000000 -0.6371213 -0.7707636 0.0000000 -0.6371213 -0.7707636 0.0000000 -0.7214430 -0.6924739 0.0000000 -0.7214430 -0.6924739 0.0000000 -0.7962131 -0.6050162 0.0000000 -0.7962131 -0.6050162 0.0000000 -0.8604419 -0.5095485 0.0000000 -0.8604419 -0.5095485 0.0000000 -0.9132790 -0.4073347 0.0000000 -0.9132790 -0.4073347 0.0000000 -0.9540247 -0.2997279 0.0000000 -0.9540247 -0.2997279 0.0000000 -0.9696883 -0.2443452 0.0000000 -0.9696883 -0.2443452 0.0000000 0.2443452 -0.9696883 0.0000000 0.2443452 -0.9696883 0.0000000 0.2443452 -0.9696883 0.0000000 0.2443452 -0.9696883 0.0000000 0.2443452 -0.9696883 -0.0000000 0.9540247 0.2997279 -0.0000000 0.9696883 0.2443452 -0.0000000 0.9696883 0.2443452 -0.0000000 0.9540247 0.2997279 -0.0000000 0.9132790 0.4073347 -0.0000000 0.9132790 0.4073347 -0.0000000 0.4444006 0.8958282 -0.0000000 0.4444006 0.8958282 -0.0000000 0.3385531 0.9409473 -0.0000000 0.3385531 0.9409473 -1.0000000 0.0000000 -0.0000000 -1.0000000 0.0000000 -0.0000000 -1.0000000 0.0000000 -0.0000000 -1.0000000 0.0000000 -0.0000000 -1.0000000 0.0000000 -0.0000000 -1.0000000 0.0000000 -0.0000000 -1.0000000 0.0000000 -0.0000000 -1.0000000 0.0000000 -0.0000000 -1.0000000 0.0000000 -0.0000000 -1.0000000 0.0000000 -0.0000000 -1.0000000 0.0000000 -0.0000000 -1.0000000 0.0000000 -0.0000000 -1.0000000 0.0000000 -0.0000000 -1.0000000 0.0000000 -0.0000000 -1.0000000 0.0000000 -0.0000000 -1.0000000 0.0000000 -0.0000000 -1.0000000 0.0000000 -0.0000000 -1.0000000 0.0000000 -0.0000000 -1.0000000 0.0000000 -0.0000000 -1.0000000 0.0000000 -0.0000000 -1.0000000 0.0000000 -0.0000000 -1.0000000 0.0000000 -0.0000000 -1.0000000 0.0000000 -0.0000000 -1.0000000 0.0000000 -0.0000000 -1.0000000 0.0000000 -0.0000000 -1.0000000 0.0000000 -0.0000000 -1.0000000 0.0000000 -0.0000000 -1.0000000 0.0000000 -0.0000000 + + + + + + + + + + + + + + +

0 1 2 1 0 3 4 0 5 0 4 3 6 7 8 7 6 9 7 9 10 7 10 11 11 10 12 11 12 13 13 12 14 13 14 15 13 15 16 16 15 17 16 17 18 18 17 19 18 19 20 18 20 21 21 20 22 21 22 23 21 23 24 24 23 25 24 25 26 24 26 27 24 27 28 28 27 29 28 29 30 30 29 31 31 29 32 32 29 33 2 34 35 34 2 1 36 37 38 37 36 39 39 36 40 40 36 41 40 41 42 42 41 43 42 43 44 44 43 45 44 45 46 46 45 47 46 47 48 48 47 49 48 49 50 50 49 51 51 49 52 51 52 53 53 52 54 53 54 55 55 54 56 56 54 57 56 57 58 58 57 59 59 57 60 59 60 61 61 60 62 61 62 63 64 4 5 4 64 65 66 67 68 67 66 69 70 68 71 68 70 66 72 71 73 71 72 70 74 75 76 75 74 77 75 77 78 79 80 81 80 79 82 83 82 79 82 83 84 85 83 86 83 85 84 87 85 86 85 87 88 89 87 90 87 89 88 91 90 92 90 91 89 93 92 94 92 93 91 95 94 96 94 95 93 97 96 98 96 97 95 97 99 100 99 97 98 100 101 102 101 100 99 102 103 104 103 102 101 104 105 106 105 104 103 107 108 109 108 107 110 110 107 111 112 113 114 113 112 115 116 115 112 115 116 117 116 34 117 34 116 35 118 64 119 64 118 65 120 118 119 118 120 121 67 121 120 121 67 69 122 123 124 123 122 125 125 122 126 126 122 127 126 127 128 128 127 129 128 129 130 130 129 131 130 131 132 132 131 133 132 133 134 134 133 135 135 133 136 135 136 137 137 136 138 137 138 139 139 138 140 140 138 141 140 141 142 142 141 143 143 141 144 143 144 145 145 144 146 146 144 147 146 147 148 146 148 149

+
+
+
+
+ + + + + + + + + + + + 1.0000000 1.0000000 1.0000000 1.0000000 + + + + + + + + + +
diff --git a/src/parts source/kOS Radial dev/compumax.skp b/src/parts source/kOS Radial dev/compumax.skp new file mode 100644 index 000000000..a51087917 Binary files /dev/null and b/src/parts source/kOS Radial dev/compumax.skp differ diff --git a/src/parts source/kOS Radial dev/kosradial.blend b/src/parts source/kOS Radial dev/kosradial.blend new file mode 100644 index 000000000..d94782d47 Binary files /dev/null and b/src/parts source/kOS Radial dev/kosradial.blend differ diff --git a/src/parts source/kOS Radial dev/kosradial.dae b/src/parts source/kOS Radial dev/kosradial.dae new file mode 100644 index 000000000..d76a1cd31 --- /dev/null +++ b/src/parts source/kOS Radial dev/kosradial.dae @@ -0,0 +1,428 @@ + + + + + Blender User + Blender 2.73.0 commit date:2015-01-20, commit time:18:16, hash:bbf09d9 + + 2015-05-06T10:23:57 + 2015-05-06T10:23:57 + + Z_UP + + + + + + + 49.13434 + 1.777778 + 0.1 + 100 + + + + + + 0 + 0 + 0 + + + + + + + + + 1 1 1 + 1 + 0 + 0.00111109 + + + + + 0.000999987 + 1 + 0.1 + 0.1 + 1 + 1 + 1 + 2 + 0 + 1 + 1 + 1 + 1 + 1 + 0 + 2880 + 2 + 30.002 + 1.000799 + 0.04999995 + 29.99998 + 1 + 2 + 0 + 0 + 1 + 1 + 1 + 1 + 8192 + 1 + 1 + 0 + 1 + 1 + 1 + 3 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 1 + 3 + 0.15 + 75 + 1 + 1 + 0 + 1 + 1 + 0 + + + + + + + 1 1 1 + 1 + 0 + 0.001599967 + + + + + 0.000999987 + 0 + 0.1 + 0.1 + 0.1 + 1 + 1 + 2 + 0 + 1 + 1 + 1 + 1 + 1 + 0 + 512 + 2 + 40 + 0.5 + 0.04999995 + 25 + 1 + 2 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 1 + 3 + 0 + 0 + 0 + 0 + 2 + 1 + 1 + 1 + 3 + 0.15 + 45 + 1 + 1 + 0 + 1 + 1 + 4 + + + + + + + 1 1 1 + 1 + 0 + 0.001599967 + + + + + 0.000999987 + 0 + 0.1 + 0.1 + 0.1 + 1 + 1 + 2 + 0 + 1 + 1 + 1 + 1 + 1 + 0 + 512 + 2 + 40 + 0.5 + 0.04999995 + 25 + 1 + 2 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 1 + 3 + 0 + 0 + 0 + 0 + 2 + 1 + 1 + 1 + 3 + 0.15 + 45 + 1 + 1 + 0 + 1 + 1 + 0 + + + + + + + 1 1 1 + 1 + 0 + 0.001599967 + + + + + 0.000999987 + 0 + 0.1 + 0.1 + 0.1 + 1 + 1 + 2 + 0 + 1 + 1 + 1 + 1 + 1 + 0 + 512 + 2 + 40 + 0.5 + 0.04999995 + 25 + 1 + 2 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 1 + 3 + 0 + 0 + 0 + 0 + 2 + 1 + 1 + 1 + 3 + 0.15 + 45 + 1 + 1 + 0 + 1 + 1 + 0 + + + + + + + + + + + + 0 0 0 1 + + + 0 0 0 1 + + + 1 1 1 1 + + + 0.5 0.5 0.5 1 + + + 50 + + + 1 + + + + + + + + + + + + + + + + 0.1983771 12.40921 0.6520971 1.37948 12.49326 0.5537875 0.1983771 12.49326 0.5537875 1.37948 12.40921 0.6520971 1.37948 12.31442 0.7401012 0.1983771 12.31442 0.7401012 1.37948 10.41715 0.6037545 1.37948 11.60391 0.9974553 1.37948 10.41715 0.9974553 1.37948 11.59258 0.6037545 1.37948 11.68207 0.5985973 1.37948 11.72737 0.9903408 1.37948 11.76479 0.5841695 1.37948 11.85479 0.968116 1.37948 11.8453 0.5603354 1.37948 11.92254 0.5274107 1.37948 11.97881 0.9314017 1.37948 11.99549 0.4858313 1.37948 12.09779 0.8806841 1.37948 12.06317 0.4361476 1.37948 12.12471 0.3790173 1.37948 12.21016 0.8166346 1.37948 12.17927 0.315197 1.37948 12.22614 0.2455314 1.37948 12.31442 0.7401012 1.37948 12.26469 0.1709431 1.37948 12.29443 0.09241938 1.37948 12.31772 0 1.37948 12.40921 0.6520971 1.37948 12.69948 0.09619885 1.37948 12.49326 0.5537875 1.37948 12.56546 0.4464739 1.37948 12.62485 0.3315771 1.37948 12.67065 0.2106183 1.37948 12.56546 0.4464739 0.1983771 12.56546 0.4464739 0.1983771 11.60391 0.9974553 0.1983771 10.41715 0.8006049 0.1983771 10.41715 0.9974553 0.1983771 11.59825 0.8006049 0.1983771 11.70472 0.794469 0.1983771 11.72737 0.9903408 0.1983771 11.80979 0.7761427 0.1983771 11.85479 0.968116 0.1983771 11.91205 0.7458686 0.1983771 11.97881 0.9314017 0.1983771 12.01016 0.7040474 0.1983771 12.09779 0.8806841 0.1983771 12.10282 0.651233 0.1983771 12.21016 0.8166346 0.1983771 12.1888 0.5881244 0.1983771 12.26696 0.5155572 0.1983771 12.31442 0.7401012 0.1983771 12.33626 0.4344923 0.1983771 12.40921 0.6520971 0.1983771 12.3958 0.3460027 0.1983771 12.44477 0.2512601 0.1983771 12.49326 0.5537875 0.1983771 12.48254 0.1515189 0.1983771 12.5086 0.04809939 0.1983771 12.56546 0.4464739 0.1983771 12.69948 0.09619885 0.1983771 12.62485 0.3315771 0.1983771 12.67065 0.2106183 0.1983771 12.21016 0.8166346 1.37948 12.21016 0.8166346 1.37948 11.72737 0.9903408 0.1983771 11.85479 0.968116 0.1983771 11.72737 0.9903408 1.37948 11.85479 0.968116 1.37948 11.60391 0.9974553 0.1983771 11.60391 0.9974553 1.37948 10.41715 0.9974553 0.1983771 10.41715 0.9974553 1.37948 10.41715 0.6037545 0.1983771 10.41715 0.8006049 0.1983771 10.41715 0.6037545 1.37948 10.41715 0.9974553 0.1983771 10.41715 0.9974553 0.1983771 11.59258 0.6037545 1.37948 10.41715 0.6037545 0.1983771 10.41715 0.6037545 1.37948 11.59258 0.6037545 0.1983771 11.68207 0.5985973 1.37948 11.68207 0.5985973 1.37948 11.76479 0.5841695 0.1983771 11.76479 0.5841695 0.1983771 11.8453 0.5603354 1.37948 11.8453 0.5603354 1.37948 11.92254 0.5274107 0.1983771 11.92254 0.5274107 1.37948 11.99549 0.4858313 0.1983771 11.99549 0.4858313 1.37948 12.06317 0.4361476 0.1983771 12.06317 0.4361476 1.37948 12.12471 0.3790173 0.1983771 12.12471 0.3790173 1.37948 12.17927 0.315197 0.1983771 12.17927 0.315197 0.1983771 12.22614 0.2455314 1.37948 12.22614 0.2455314 0.1983771 12.26469 0.1709431 1.37948 12.26469 0.1709431 0.1983771 12.29443 0.09241938 1.37948 12.29443 0.09241938 0.1983771 12.31772 0 1.37948 12.31772 0 1.37948 12.69948 0.09619885 0.1983771 12.5086 0.04809939 0.1983771 12.69948 0.09619885 0.1983771 12.31772 0 1.37948 12.31772 0 0.1983771 12.67065 0.2106183 1.37948 12.69948 0.09619885 0.1983771 12.69948 0.09619885 1.37948 12.67065 0.2106183 0.1983771 12.62485 0.3315771 1.37948 12.62485 0.3315771 1.37948 12.09779 0.8806841 0.1983771 12.09779 0.8806841 0.1983771 11.97881 0.9314017 1.37948 11.97881 0.9314017 0.1983771 11.59825 0.8006049 0.1983771 10.41715 0.6037545 0.1983771 10.41715 0.8006049 0.1983771 11.59258 0.6037545 0.1983771 11.68207 0.5985973 0.1983771 11.70472 0.794469 0.1983771 11.76479 0.5841695 0.1983771 11.80979 0.7761427 0.1983771 11.8453 0.5603354 0.1983771 11.91205 0.7458686 0.1983771 11.92254 0.5274107 0.1983771 12.01016 0.7040474 0.1983771 11.99549 0.4858313 0.1983771 12.06317 0.4361476 0.1983771 12.10282 0.651233 0.1983771 12.12471 0.3790173 0.1983771 12.1888 0.5881244 0.1983771 12.17927 0.315197 0.1983771 12.22614 0.2455314 0.1983771 12.26696 0.5155572 0.1983771 12.26469 0.1709431 0.1983771 12.29443 0.09241938 0.1983771 12.33626 0.4344923 0.1983771 12.31772 0 0.1983771 12.5086 0.04809939 0.1983771 12.3958 0.3460027 0.1983771 12.44477 0.2512601 0.1983771 12.48254 0.1515189 1.1949 6.126895 2.064585 5.095647 9.286817 2.064585 1.1949 9.286817 2.064585 5.095647 6.126895 2.064585 1.002006 5.899769 2.458286 5.095647 6.126895 2.064585 1.1949 6.126895 2.064585 5.332715 5.899769 2.458286 5.332715 9.443078 2.458286 5.095647 6.126895 2.064585 5.332715 5.899769 2.458286 5.095647 9.286817 2.064585 5.095647 9.286817 2.064585 1.002006 9.443078 2.458286 1.1949 9.286817 2.064585 5.332715 9.443078 2.458286 1.1949 6.126895 2.064585 1.002006 9.443078 2.458286 1.002006 5.899769 2.458286 1.1949 9.286817 2.064585 -5.04407e-7 10.41159 1.893423 6.299212 10.41715 1.808626 -5.04676e-7 10.41715 1.808626 6.299212 10.41159 1.893423 0 0.04017329 0.7581144 0 0.02344459 0.09608095 0 0.02344459 0.5028831 -5.04676e-7 10.41715 0.09608095 0 0.09007328 1.008978 0 0.1722908 1.251183 0 0.2854189 1.480584 0 0.427522 1.693257 0 0.5961688 1.885562 0 0.7884735 2.054208 0 1.001146 2.196312 0 1.230547 2.30944 0 1.472752 2.391657 0 1.723616 2.441557 0 1.978847 2.458286 -4.73202e-7 9.767485 2.458286 -4.7731e-7 9.852284 2.452728 -4.81348e-7 9.93563 2.436149 -4.85246e-7 10.0161 2.408833 -4.88939e-7 10.09232 2.371248 -4.92362e-7 10.16297 2.324036 -4.95457e-7 10.22686 2.268005 -4.98172e-7 10.28289 2.204113 -5.00459e-7 10.33011 2.133455 -5.0228e-7 10.36769 2.05724 -5.03603e-7 10.39501 1.97677 -5.04407e-7 10.41159 1.893423 -5.04676e-7 10.41715 1.808626 -5.03603e-7 10.39501 1.97677 6.299212 10.39501 1.97677 6.299213 0.02344459 0.09608095 6.299213 0.02609038 0.5432494 6.299213 0.02344459 0.5028831 6.299212 10.41715 0.09608095 6.299213 0.06239557 0.6631978 6.299213 0.1243278 0.7933525 6.299213 0.2050413 0.9127728 6.299213 0.302718 1.018769 6.299213 0.4151577 1.108953 6.299213 0.5398278 1.181294 6.299213 0.6739203 1.234162 6.299213 0.8144148 1.266367 6.299213 0.9581467 1.277183 6.299213 4.895154 1.277183 6.299213 4.898525 2.115783 6.299213 4.908577 2.16632 6.299212 4.92514 2.215113 6.299212 4.947929 2.261326 6.299212 4.976557 2.304169 6.299212 5.010531 2.342909 6.299212 5.049271 2.376883 6.299212 5.092114 2.405511 6.299212 5.138328 2.4283 6.299212 5.18712 2.444863 6.299212 5.237657 2.454916 6.299212 5.289074 2.458286 6.299212 9.767485 2.458286 6.299212 9.852284 2.452728 6.299212 9.93563 2.436149 6.299212 10.0161 2.408833 6.299212 10.09232 2.371248 6.299212 10.16297 2.324036 6.299212 10.22686 2.268005 6.299212 10.28289 2.204113 6.299212 10.33011 2.133455 6.299212 10.36769 2.05724 6.299212 10.39501 1.97677 6.299212 10.41159 1.893423 6.299212 10.41715 1.808626 6.299213 4.895154 2.064366 -5.04676e-7 10.41715 0.09608095 0.1983765 10.41715 0.6037545 6.299212 10.41715 0.09608095 -5.04676e-7 10.41715 1.808626 0.1983765 10.41715 0.8006049 0.1983765 10.41715 0.9974553 1.379479 10.41715 0.9974553 1.379479 10.41715 0.6037545 6.299212 10.41715 1.808626 6.299213 0.02344459 0.09608095 0 0.02344459 0.5028831 0 0.02344459 0.09608095 6.299213 0.02344459 0.5028831 0 0.02344459 0.5028831 2.362205 0.02609038 0.5432494 0 0.04017329 0.7581144 6.299213 0.02344459 0.5028831 6.299213 0.02609038 0.5432494 2.362205 0.04017329 0.7581144 0 0.09007328 1.008978 2.362205 0.09007328 1.008978 0 0.1722908 1.251183 2.362205 0.1722908 1.251183 0 0.2854189 1.480584 2.362205 0.2854189 1.480584 0 0.427522 1.693257 2.362205 0.427522 1.693257 2.362205 0.5961688 1.885562 0 0.5961688 1.885562 2.362205 0.7884735 2.054208 0 0.7884735 2.054208 0 1.001146 2.196312 2.362205 1.001146 2.196312 2.362205 1.230547 2.30944 0 1.230547 2.30944 0 1.472752 2.391657 2.362205 1.472752 2.391657 0 1.723616 2.441557 2.362205 1.723616 2.441557 2.362205 1.978847 2.458286 0 1.978847 2.458286 0 1.978847 2.458286 1.002006 5.899769 2.458286 1.002006 9.443078 2.458286 2.362205 1.978847 2.458286 2.362205 5.289074 2.458286 5.332715 5.899769 2.458286 6.299212 5.289074 2.458286 5.332715 9.443078 2.458286 6.299212 9.767485 2.458286 -4.73202e-7 9.767485 2.458286 -4.73202e-7 9.767485 2.458286 6.299212 9.852284 2.452728 -4.7731e-7 9.852284 2.452728 6.299212 9.767485 2.458286 -4.81348e-7 9.93563 2.436149 6.299212 9.93563 2.436149 6.299212 10.0161 2.408833 -4.85246e-7 10.0161 2.408833 6.299212 10.09232 2.371248 -4.88939e-7 10.09232 2.371248 -4.92362e-7 10.16297 2.324036 6.299212 10.16297 2.324036 6.299212 10.22686 2.268005 -4.95457e-7 10.22686 2.268005 6.299212 10.28289 2.204113 -4.98172e-7 10.28289 2.204113 6.299212 10.33011 2.133455 -5.00459e-7 10.33011 2.133455 6.299212 10.36769 2.05724 -5.0228e-7 10.36769 2.05724 6.299212 10.41715 0.09608095 -5.04676e-7 10.41715 0.09608095 6.299212 5.237657 2.454916 2.362205 5.289074 2.458286 2.362205 5.237657 2.454916 6.299212 5.289074 2.458286 6.299212 5.18712 2.444863 2.362205 5.18712 2.444863 6.299212 5.138328 2.4283 2.362205 5.138328 2.4283 2.362205 5.092114 2.405511 6.299212 5.092114 2.405511 6.299212 5.049271 2.376883 2.362205 5.049271 2.376883 6.299212 5.010531 2.342909 2.362205 5.010531 2.342909 6.299212 4.976557 2.304169 2.362205 4.976557 2.304169 6.299212 4.947929 2.261326 2.362205 4.947929 2.261326 6.299212 4.92514 2.215113 2.362205 4.92514 2.215113 6.299213 4.908577 2.16632 2.362205 4.908577 2.16632 6.299213 4.898525 2.115783 2.362205 4.898525 2.115783 6.299213 4.895154 2.064366 2.362205 4.895154 2.064366 6.299213 4.895154 1.277183 2.362205 4.895154 2.064366 2.362205 4.895154 1.277183 6.299213 4.895154 2.064366 2.362205 0.9581467 1.277183 6.299213 4.895154 1.277183 2.362205 4.895154 1.277183 6.299213 0.9581467 1.277183 6.299213 0.8144148 1.266367 2.362205 0.9581467 1.277183 2.362205 0.8144148 1.266367 6.299213 0.9581467 1.277183 2.362205 0.6739203 1.234162 6.299213 0.6739203 1.234162 6.299213 0.5398278 1.181294 2.362205 0.5398278 1.181294 2.362205 0.4151577 1.108953 6.299213 0.4151577 1.108953 2.362205 0.302718 1.018769 6.299213 0.302718 1.018769 2.362205 0.2050413 0.9127728 6.299213 0.2050413 0.9127728 6.299213 0.1243278 0.7933525 2.362205 0.1243278 0.7933525 6.299213 0.06239557 0.6631978 2.362205 0.06239557 0.6631978 2.362205 0.02609038 0.5432494 6.299213 0.02609038 0.5432494 6.299213 9.421e-4 0.238452 6.299213 0.02063935 0.5252402 6.299213 0 0.3825873 6.299213 0.02344459 0.09608095 6.299213 0.02344459 0.5028831 6.299213 0.02609038 0.5432494 2.362205 0.06239557 0.6631978 2.362205 0.04017329 0.7581144 2.362205 0.02609038 0.5432494 2.362205 0.09007328 1.008978 2.362205 0.1243278 0.7933525 2.362205 0.1722908 1.251183 2.362205 0.2050413 0.9127728 2.362205 0.2854189 1.480584 2.362205 0.302718 1.018769 2.362205 0.427522 1.693257 2.362205 0.4151577 1.108953 2.362205 0.5398278 1.181294 2.362205 0.5961688 1.885562 2.362205 0.6739203 1.234162 2.362205 0.7884735 2.054208 2.362205 0.8144148 1.266367 2.362205 1.001146 2.196312 2.362205 0.9581467 1.277183 2.362205 4.895154 1.277183 2.362205 1.230547 2.30944 2.362205 1.472752 2.391657 2.362205 1.723616 2.441557 2.362205 1.978847 2.458286 2.362205 4.895154 2.064366 2.362205 5.237657 2.454916 2.362205 5.289074 2.458286 2.362205 5.18712 2.444863 2.362205 5.138328 2.4283 2.362205 5.092114 2.405511 2.362205 5.049271 2.376883 2.362205 5.010531 2.342909 2.362205 4.976557 2.304169 2.362205 4.947929 2.261326 2.362205 4.92514 2.215113 2.362205 4.908577 2.16632 2.362205 4.898525 2.115783 + + + + + + + + + + 0 0.721427 0.692465 0 0.7961974 0.604999 0 0.7961974 0.604999 0 0.721427 0.692465 0 0.6371044 0.770745 0 0.6371044 0.770745 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0.8604389 0.5095371 0 0.8604389 0.5095371 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 0.5443587 0.8388317 0 0.5443587 0.8388317 0 0.1148411 0.9933775 0 0.2282174 0.9736015 0 0.1148411 0.9933775 0 0.2282174 0.9736015 0 0.02874839 0.9995728 0 0.02874839 0.9995728 0 0 1 0 0 1 0 -1 0 0 -1 0 0 -1 0 0 -0.02874839 -0.9995728 0 0 -1 0 0 -1 0 -0.02874839 -0.9995728 0 -0.1148411 -0.9933775 0 -0.1148411 -0.9933775 0 -0.2282174 -0.9736015 0 -0.2282174 -0.9736015 0 -0.3385418 -0.9409467 0 -0.3385418 -0.9409467 0 -0.44438 -0.8958098 0 -0.44438 -0.8958098 0 -0.5443587 -0.8388317 0 -0.5443587 -0.8388317 0 -0.6371044 -0.770745 0 -0.6371044 -0.770745 0 -0.721427 -0.692465 0 -0.721427 -0.692465 0 -0.7961974 -0.604999 0 -0.7961974 -0.604999 0 -0.8604389 -0.5095371 0 -0.8604389 -0.5095371 0 -0.9132664 -0.4073305 0 -0.9132664 -0.4073305 0 -0.9540086 -0.2997223 0 -0.9540086 -0.2997223 0 -0.9696646 -0.2443311 0 -0.9696646 -0.2443311 0 0.2443453 -0.9696882 0 0.244346 -0.9696882 0 0.2443456 -0.9696881 0 0.9540086 0.2997223 0 0.9696646 0.2443311 0 0.9696646 0.2443311 0 0.9540086 0.2997223 0 0.9132664 0.4073305 0 0.9132664 0.4073305 0 0.44438 0.8958098 0 0.44438 0.8958098 0 0.3385418 0.9409467 0 0.3385418 0.9409467 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 0 1 0 0 1 0 0.866194 0.4997078 0 0.866194 0.4997078 -0.8566789 0 0.5158501 -0.8566789 0 0.5158501 0 -0.9294664 0.3689069 0 -0.9294664 0.3689069 0.8980076 0 0.43998 0.8980076 0 0.4399799 0 0.9914243 0.1304971 0 0.9978332 0.06540113 0 0.9978332 0.06540113 0 0.9914243 0.1304971 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 0.9659109 0.2587969 0 0.9659109 0.2587969 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 -1.41432e-7 1 0 -2.51906e-7 1 0 -4.03722e-7 1 0 0 1 0 0 1 3.33403e-6 8.64099e-6 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 -0.7070834 -0.7070834 0 -0.9999695 0 0 -0.7070834 -0.7070834 0 -1 0 0 -0.9978332 0.06540113 0 -0.9978332 0.06540113 0 -0.9914243 0.1304971 0 -0.9978588 0.06540429 0 -0.9978588 0.06540429 0 -0.9914243 0.1304971 0 -0.9659109 0.2587969 0 -0.9659109 0.2587969 0 -0.9238563 0.3826716 0 -0.9238563 0.3826716 0 -0.8660237 0.4999848 0 -0.8660237 0.4999848 0 -0.7933287 0.6087527 0 -0.7933287 0.6087527 0 -0.7070834 0.7070834 0 -0.7070834 0.7070834 0 -0.6087527 0.7933287 0 -0.6087527 0.7933287 0 -0.4999848 0.8660237 0 -0.4999848 0.8660237 0 -0.3826716 0.9238563 0 -0.3826716 0.9238563 0 -0.2587969 0.9659109 0 -0.2587969 0.9659109 0 -0.1304971 0.9914243 0 -0.1304971 0.9914243 0 -0.06540113 0.9978332 0 -0.06540113 0.9978332 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0.06537061 0.9978332 0 0.1304971 0.9914243 0 0.1304971 0.9914243 0 0.06537061 0.9978332 0 0.2587969 0.9659109 0 0.2587969 0.9659109 0 0.3826716 0.9238563 0 0.3826716 0.9238563 0 0.4999848 0.8660237 0 0.4999848 0.8660237 0 0.6087527 0.7933287 0 0.6087527 0.7933287 0 0.7070834 0.7070834 0 0.7070834 0.7070834 0 0.7933287 0.6087527 0 0.7933287 0.6087527 0 0.8660237 0.4999848 0 0.8660237 0.4999848 0 0.9238563 0.3826716 0 0.9238563 0.3826716 0 0 -1 0 0 -1 0 -0.1304971 0.9914243 0 -0.06540113 0.9978332 0 -0.1304971 0.9914243 0 -0.06540113 0.9978332 0 -0.2587969 0.9659109 0 -0.2587969 0.9659109 0 -0.3826716 0.9238563 0 -0.3826716 0.9238563 0 -0.4999848 0.8660237 0 -0.4999848 0.8660237 0 -0.6087527 0.7933287 0 -0.6087527 0.7933287 0 -0.7070834 0.7070834 0 -0.7070834 0.7070834 0 -0.7933287 0.6087527 0 -0.7933287 0.6087527 0 -0.8660237 0.4999848 0 -0.8660237 0.4999848 0 -0.9238563 0.3826716 0 -0.9238563 0.3826716 0 -0.9659109 0.2587969 0 -0.9659109 0.2587969 0 -0.9914243 0.1304971 0 -0.9914243 0.1304971 0 -0.9978332 0.06540113 0 -0.9978332 0.06540113 0 -1 0 0 -1 0 0 0 1 0 0 1 0 -0.1496322 0.9887081 0 -0.07501447 0.9971618 0 -0.1496322 0.9887081 0 -0.07501447 0.9971618 0 -0.295938 0.9551988 0 -0.295938 0.9551988 0 -0.4355602 0.9001435 0 -0.4355602 0.9001435 0 -0.5653554 0.8248237 0 -0.5653554 0.8248237 0 -0.6824244 0.7309183 0 -0.6824244 0.7309183 0 -0.7841426 0.6205634 0 -0.7841426 0.6205634 0 -0.86816 0.4962005 0 -0.86816 0.4962005 0 -0.9326762 0.3606982 0 -0.9326762 0.3606982 0 -0.957091 0.2896817 0 -0.957091 0.2896817 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 -1.32807e-7 1 0 -1.73743e-7 1 0 0 1 0 -1.09888e-6 1 0 -3.65905e-7 1 0 -2.16257e-7 1 0 -1.50132e-7 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 + + + + + + + + + + 0.805888 0.06343823 0.7392519 0.05614095 0.8058881 0.05614113 0.7392519 0.05614095 0.805888 0.06343823 0.7392519 0.06343817 0.7392519 0.07073533 0.805888 0.06343823 0.805888 0.07073539 0.805888 0.06343823 0.7392519 0.07073533 0.7392519 0.06343817 0.6998396 0.1739056 0.7221693 0.106989 0.7220516 0.1739447 0.7221693 0.106989 0.6998396 0.1739056 0.6999562 0.1075896 0.7221693 0.106989 0.6999562 0.1075896 0.6996741 0.1025399 0.7221693 0.106989 0.6996741 0.1025399 0.7217802 0.100023 0.7217802 0.100023 0.6996741 0.1025399 0.6988683 0.09787178 0.7217802 0.100023 0.6988683 0.09787178 0.720539 0.0928322 0.720539 0.0928322 0.6988683 0.09787178 0.6975316 0.09332722 0.720539 0.0928322 0.6975316 0.09332722 0.6956818 0.08896619 0.720539 0.0928322 0.6956818 0.08896619 0.7184799 0.08583152 0.7184799 0.08583152 0.6956818 0.08896619 0.6933432 0.08484649 0.7184799 0.08583152 0.6933432 0.08484649 0.7156303 0.07911378 0.7156303 0.07911378 0.6933432 0.08484649 0.6905468 0.08102273 0.7156303 0.07911378 0.6905468 0.08102273 0.6873298 0.07754558 0.7156303 0.07911378 0.6873298 0.07754558 0.7120278 0.07276773 0.7120278 0.07276773 0.6873298 0.07754558 0.6837345 0.07446092 0.7120278 0.07276773 0.6837345 0.07446092 0.6798087 0.0718097 0.7120278 0.07276773 0.6798087 0.0718097 0.7077204 0.06687772 0.7077204 0.06687772 0.6798087 0.0718097 0.6756045 0.06962704 0.7077204 0.06687772 0.6756045 0.06962704 0.6711772 0.06794166 0.7077204 0.06687772 0.6711772 0.06794166 0.6659651 0.06661856 0.7077204 0.06687772 0.6659651 0.06661856 0.7027646 0.06152129 0.7027646 0.06152129 0.6659651 0.06661856 0.6714305 0.0450893 0.7027646 0.06152129 0.6714305 0.0450893 0.6972267 0.05676984 0.6972267 0.05676984 0.6714305 0.0450893 0.6911793 0.05268579 0.6911793 0.05268579 0.6714305 0.0450893 0.6847029 0.04932355 0.6847029 0.04932355 0.6714305 0.0450893 0.677883 0.04672735 0.8058881 0.05614113 0.7392519 0.04884374 0.8058881 0.04884392 0.7392519 0.04884374 0.8058881 0.05614113 0.7392519 0.05614095 0.6341806 0.0801925 0.6438099 0.1473764 0.6327067 0.147132 0.6438099 0.1473764 0.6341806 0.0801925 0.6452769 0.08075666 0.6452769 0.08075666 0.6341806 0.0801925 0.6457552 0.07475852 0.6457552 0.07475852 0.6341806 0.0801925 0.6347352 0.07323765 0.6457552 0.07475852 0.6347352 0.07323765 0.6469194 0.06885492 0.6469194 0.06885492 0.6347352 0.07323765 0.636147 0.06607842 0.6469194 0.06885492 0.636147 0.06607842 0.648754 0.06312447 0.648754 0.06312447 0.636147 0.06607842 0.638372 0.05912864 0.648754 0.06312447 0.638372 0.05912864 0.6512348 0.0576424 0.6512348 0.0576424 0.638372 0.05912864 0.6413804 0.05248057 0.6512348 0.0576424 0.6413804 0.05248057 0.6543288 0.05248165 0.6543288 0.05248165 0.6413804 0.05248057 0.6451327 0.04622197 0.6543288 0.05248165 0.6451327 0.04622197 0.6579952 0.04771059 0.6579952 0.04771059 0.6451327 0.04622197 0.6621854 0.0433923 0.6621854 0.0433923 0.6451327 0.04622197 0.6495791 0.04043596 0.6621854 0.0433923 0.6495791 0.04043596 0.6668439 0.03958368 0.6668439 0.03958368 0.6495791 0.04043596 0.6546606 0.03519886 0.6668439 0.03958368 0.6546606 0.03519886 0.6719091 0.03633564 0.6719091 0.03633564 0.6546606 0.03519886 0.6773139 0.03369081 0.6773139 0.03369081 0.6546606 0.03519886 0.6603102 0.03058034 0.6773139 0.03369081 0.6603102 0.03058034 0.6829867 0.03168445 0.6829867 0.03168445 0.6603102 0.03058034 0.6888526 0.03034293 0.6888526 0.03034293 0.6603102 0.03058034 0.6664528 0.02664124 0.6888526 0.03034293 0.6664528 0.02664124 0.6863766 0.01951646 0.6863766 0.01951646 0.6664528 0.02664124 0.6730073 0.02343386 0.6863766 0.01951646 0.6730073 0.02343386 0.6798868 0.02100068 0.805888 0.07803267 0.7392519 0.07073533 0.805888 0.07073539 0.7392519 0.07073533 0.805888 0.07803267 0.7392519 0.07803249 0.7392517 0.1072213 0.8058879 0.09992432 0.8058879 0.1072215 0.8058879 0.09992432 0.7392517 0.1072213 0.7392518 0.09992408 0.7392517 0.1141982 0.8058879 0.1072215 0.8058879 0.1141983 0.8058879 0.1072215 0.7392517 0.1141982 0.7392517 0.1072213 0.7392516 0.181154 0.8058879 0.1141983 0.8058877 0.1811541 0.8058879 0.1141983 0.7392516 0.181154 0.7392517 0.1141982 0.8999858 0.09476959 0.8333497 0.1058756 0.8333497 0.09476959 0.8333497 0.1058756 0.8999858 0.09476959 0.8999858 0.1169816 0.8333497 0.1058756 0.8999858 0.1169816 0.8333497 0.1169816 0.6566967 0.1138606 0.7241307 0.1793653 0.6574996 0.180172 0.7241307 0.1793653 0.6566967 0.1138606 0.7233279 0.1130537 0.6566355 0.1088035 0.7233279 0.1130537 0.6566967 0.1138606 0.7233279 0.1130537 0.6566355 0.1088035 0.7232667 0.1079968 0.7232093 0.1032599 0.6566355 0.1088035 0.6565782 0.1040666 0.6566355 0.1088035 0.7232093 0.1032599 0.7232667 0.1079968 0.6565209 0.09932988 0.7232093 0.1032599 0.6565782 0.1040666 0.7232093 0.1032599 0.6565209 0.09932988 0.723152 0.09852308 0.7230947 0.09378629 0.6565209 0.09932988 0.6564635 0.09459304 0.6565209 0.09932988 0.7230947 0.09378629 0.723152 0.09852308 0.7230373 0.08904939 0.6564635 0.09459304 0.6564062 0.08985614 0.6564635 0.09459304 0.7230373 0.08904939 0.7230947 0.09378629 0.72298 0.08431261 0.6564062 0.08985614 0.6563488 0.08511924 0.6564062 0.08985614 0.72298 0.08431261 0.7230373 0.08904939 0.7229226 0.07957571 0.6563488 0.08511924 0.6562914 0.08038246 0.6563488 0.08511924 0.7229226 0.07957571 0.72298 0.08431261 0.7228652 0.07483899 0.6562914 0.08038246 0.6562341 0.07564568 0.6562914 0.08038246 0.7228652 0.07483899 0.7229226 0.07957571 0.7228652 0.07483899 0.6561768 0.07090896 0.7228079 0.07010221 0.6561768 0.07090896 0.7228652 0.07483899 0.6562341 0.07564568 0.7228079 0.07010221 0.6561194 0.06617212 0.7227506 0.06536543 0.6561194 0.06617212 0.7228079 0.07010221 0.6561768 0.07090896 0.7227506 0.06536543 0.6560621 0.06143528 0.7226932 0.06062865 0.6560621 0.06143528 0.7227506 0.06536543 0.6561194 0.06617212 0.7226932 0.06062865 0.655997 0.05605852 0.7226281 0.05525183 0.655997 0.05605852 0.7226932 0.06062865 0.6560621 0.06143528 0.8999859 0.1177332 0.8333497 0.1288392 0.8333497 0.1177332 0.8333497 0.1288392 0.8999859 0.1177332 0.8333497 0.1399452 0.8333497 0.1399452 0.8999859 0.1177332 0.8999859 0.1399452 0.8058881 0.03424942 0.739252 0.02759218 0.8058881 0.02759242 0.739252 0.02759218 0.8058881 0.03424942 0.739252 0.03424924 0.8058881 0.04154664 0.739252 0.03424924 0.8058881 0.03424942 0.739252 0.03424924 0.8058881 0.04154664 0.7392519 0.04154658 0.8058881 0.04154664 0.7392519 0.04884374 0.7392519 0.04154658 0.7392519 0.04884374 0.8058881 0.04154664 0.8058881 0.04884392 0.7392518 0.08532971 0.805888 0.07803267 0.8058879 0.08532983 0.805888 0.07803267 0.7392518 0.08532971 0.7392519 0.07803249 0.8058879 0.09262704 0.7392518 0.08532971 0.8058879 0.08532983 0.7392518 0.08532971 0.8058879 0.09262704 0.7392518 0.09262692 0.8058879 0.09992432 0.7392518 0.09262692 0.8058879 0.09262704 0.7392518 0.09262692 0.8058879 0.09992432 0.7392518 0.09992408 0.9046452 0.2291816 0.8794604 0.1857123 0.9007156 0.1626614 0.8794604 0.1857123 0.9046452 0.2291816 0.8935397 0.2295174 0.8935397 0.2295174 0.9046452 0.2291816 0.893547 0.2345748 0.893547 0.2345748 0.9046452 0.2291816 0.9046539 0.2351986 0.893547 0.2345748 0.9046539 0.2351986 0.8930096 0.2392814 0.8930096 0.2392814 0.9046539 0.2351986 0.9039713 0.241177 0.8930096 0.2392814 0.9039713 0.241177 0.8919352 0.2438949 0.8919352 0.2438949 0.9039713 0.241177 0.9026066 0.2470374 0.8919352 0.2438949 0.9026066 0.2470374 0.8903379 0.2483547 0.8903379 0.2483547 0.9026066 0.2470374 0.9005776 0.2527022 0.8903379 0.2483547 0.9005776 0.2527022 0.8882387 0.2526014 0.8882387 0.2526014 0.9005776 0.2527022 0.8856657 0.2565789 0.8856657 0.2565789 0.9005776 0.2527022 0.8979113 0.2580964 0.8856657 0.2565789 0.8979113 0.2580964 0.8826528 0.2602345 0.8826528 0.2602345 0.8979113 0.2580964 0.8946431 0.2631486 0.8826528 0.2602345 0.8946431 0.2631486 0.8792399 0.2635198 0.8792399 0.2635198 0.8946431 0.2631486 0.8754723 0.2663914 0.8754723 0.2663914 0.8946431 0.2631486 0.8908161 0.2677918 0.8754723 0.2663914 0.8908161 0.2677918 0.8713998 0.2688109 0.8713998 0.2688109 0.8908161 0.2677918 0.8670762 0.2707468 0.8670762 0.2707468 0.8908161 0.2677918 0.8864811 0.2719649 0.8670762 0.2707468 0.8864811 0.2719649 0.8619486 0.2723661 0.8619486 0.2723661 0.8864811 0.2719649 0.8652927 0.2829566 0.8652927 0.2829566 0.8864811 0.2719649 0.8816953 0.2756124 0.8652927 0.2829566 0.8816953 0.2756124 0.8765223 0.2786859 0.8652927 0.2829566 0.8765223 0.2786859 0.8710306 0.2811447 0.7577 0.4879786 0.9777747 0.6662568 0.7577 0.6662568 0.9777747 0.6662568 0.7577 0.4879786 0.9777746 0.4879786 0.1410154 0.4449292 0.3719733 0.4705724 0.1518982 0.4705724 0.3719733 0.4705724 0.1410154 0.4449292 0.3853483 0.4449292 0.2487395 0.3982971 0.06164556 0.4242252 0.0488314 0.3982971 0.06164556 0.4242252 0.2487395 0.3982971 0.2399235 0.4242252 0.4130269 0.4193907 0.1675981 0.4400725 0.1784809 0.416175 0.1675981 0.4400725 0.4130269 0.4193907 0.4119307 0.4400725 0.03591895 0.4314084 0.2230131 0.4561432 0.02310484 0.4561432 0.2230131 0.4561432 0.03591895 0.4314084 0.2141971 0.4314084 0.2053067 0.8636897 0.5177334 0.8691433 0.205285 0.869143 0.5177334 0.8691433 0.2053067 0.8636897 0.517755 0.8636898 0.017416 0.5888926 0.01834887 0.6120994 0.01741594 0.5978623 0.01834887 0.6120994 0.017416 0.5888926 0.135105 0.5931532 0.135105 0.5931532 0.017416 0.5888926 0.01858693 0.5799995 0.135105 0.5931532 0.01858693 0.5799995 0.02090859 0.5713352 0.135105 0.5931532 0.02090859 0.5713352 0.02434045 0.56305 0.135105 0.5931532 0.02434045 0.56305 0.02882474 0.5552831 0.135105 0.5931532 0.02882474 0.5552831 0.03428572 0.5481661 0.135105 0.5931532 0.03428572 0.5481661 0.04062932 0.5418225 0.135105 0.5931532 0.04062932 0.5418225 0.04774624 0.5363615 0.135105 0.5931532 0.04774624 0.5363615 0.0555436 0.5317189 0.135105 0.5931532 0.0555436 0.5317189 0.06399804 0.5274468 0.135105 0.5931532 0.06399804 0.5274468 0.07300299 0.5235576 0.135105 0.5931532 0.07300299 0.5235576 0.08042526 0.5200569 0.135105 0.5931532 0.08042526 0.5200569 0.35526 0.5066425 0.135105 0.5931532 0.35526 0.5066425 0.3582399 0.5066911 0.135105 0.5931532 0.3582399 0.5066911 0.3611879 0.5071283 0.135105 0.5931532 0.3611879 0.5071283 0.3640537 0.5079465 0.135105 0.5931532 0.3640537 0.5079465 0.366788 0.5091317 0.135105 0.5931532 0.366788 0.5091317 0.3693442 0.5106637 0.135105 0.5931532 0.3693442 0.5106637 0.3716789 0.5125164 0.135105 0.5931532 0.3716789 0.5125164 0.3737515 0.514658 0.135105 0.5931532 0.3737515 0.514658 0.3755269 0.5170517 0.135105 0.5931532 0.3755269 0.5170517 0.3769752 0.5196573 0.135105 0.5931532 0.3769752 0.5196573 0.3783345 0.5224128 0.135105 0.5931532 0.3783345 0.5224128 0.3795996 0.5252786 0.135105 0.5931532 0.3795996 0.5252786 0.3807644 0.528214 0.2053283 0.8582362 0.517755 0.8636898 0.2053067 0.8636897 0.517755 0.8636898 0.2053283 0.8582362 0.5177766 0.8582363 0.03627306 0.5723607 0.03916299 0.5926004 0.03858023 0.5908151 0.03916299 0.5926004 0.03627306 0.5723607 0.5070922 0.507974 0.03916299 0.5926004 0.5070922 0.507974 0.04272258 0.6003656 0.04272258 0.6003656 0.5070922 0.507974 0.04763519 0.6077696 0.04763519 0.6077696 0.5070922 0.507974 0.05399525 0.6147268 0.05399525 0.6147268 0.5070922 0.507974 0.06198674 0.6211186 0.06198674 0.6211186 0.5070922 0.507974 0.07191914 0.6267797 0.07191914 0.6267797 0.5070922 0.507974 0.08433628 0.6314562 0.08433628 0.6314562 0.5070922 0.507974 0.0976237 0.6360335 0.0976237 0.6360335 0.5070922 0.507974 0.1221578 0.6355697 0.1221578 0.6355697 0.5070922 0.507974 0.1576269 0.6311599 0.1576269 0.6311599 0.5070922 0.507974 0.307152 0.5985581 0.307152 0.5985581 0.5070922 0.507974 0.3142243 0.6303795 0.3142243 0.6303795 0.5070922 0.507974 0.3161256 0.6339011 0.3161256 0.6339011 0.5070922 0.507974 0.318292 0.6372562 0.318292 0.6372562 0.5070922 0.507974 0.3208434 0.6403455 0.3208434 0.6403455 0.5070922 0.507974 0.3238481 0.6430935 0.3238481 0.6430935 0.5070922 0.507974 0.3273076 0.6454655 0.3273076 0.6454655 0.5070922 0.507974 0.3312348 0.6474158 0.3312348 0.6474158 0.5070922 0.507974 0.3356576 0.6488835 0.3356576 0.6488835 0.5070922 0.507974 0.340626 0.6497844 0.340626 0.6497844 0.5070922 0.507974 0.3462248 0.6499955 0.3462248 0.6499955 0.5070922 0.507974 0.3526018 0.6493247 0.3526018 0.6493247 0.5070922 0.507974 0.3600295 0.6474422 0.3600295 0.6474422 0.5070922 0.507974 0.5122643 0.5957686 0.5122643 0.5957686 0.5070922 0.507974 0.5150828 0.5946012 0.5150828 0.5946012 0.5070922 0.507974 0.5177249 0.5930759 0.5177249 0.5930759 0.5070922 0.507974 0.5201451 0.5912188 0.5201451 0.5912188 0.5070922 0.507974 0.5223025 0.5890616 0.5223025 0.5890616 0.5070922 0.507974 0.5241596 0.5866414 0.5241596 0.5866414 0.5070922 0.507974 0.5256851 0.5839992 0.5256851 0.5839992 0.5070922 0.507974 0.5268527 0.5811807 0.5268527 0.5811807 0.5070922 0.507974 0.5276423 0.5782339 0.5276423 0.5782339 0.5070922 0.507974 0.5280405 0.5752085 0.5280405 0.5752085 0.5070922 0.507974 0.5280405 0.5712473 0.5280405 0.5712473 0.5070922 0.507974 0.5272244 0.5652452 0.5272244 0.5652452 0.5070922 0.507974 0.5228158 0.5496596 0.3142243 0.6303795 0.3132684 0.6285399 0.307152 0.5985581 0.1976899 0.6716608 0.2087988 0.6429921 0.5528385 0.6716608 0.2087988 0.6429921 0.1976899 0.6716608 0.1973378 0.5748788 0.2087988 0.6429921 0.1973378 0.5748788 0.2086109 0.6316074 0.2086109 0.6316074 0.1973378 0.5748788 0.2087991 0.6210545 0.2087991 0.6210545 0.1973378 0.5748788 0.2753704 0.6208382 0.5528385 0.6716608 0.2753821 0.6430054 0.5528892 0.5751809 0.2753821 0.6430054 0.5528385 0.6716608 0.2087988 0.6429921 0.5528892 0.5751809 0.2753821 0.6430054 0.2753704 0.6208382 0.5528892 0.5751809 0.2753704 0.6208382 0.1973378 0.5748788 0.4996544 0.7725195 0.4675381 0.5017424 0.4964377 0.4985265 0.4675381 0.5017424 0.4996544 0.7725195 0.4605889 0.7718424 0.02792859 0.7965196 0.1622447 0.7988198 0.02792859 0.8110635 0.1622447 0.7988198 0.02792859 0.7965196 0.1903667 0.7867602 0.1622447 0.7988198 0.1903667 0.7867602 0.2388416 0.7977869 0.02792859 0.8110635 0.1622447 0.7988198 0.1622447 0.8110635 0.1622447 0.8110635 0.02792859 0.8256073 0.02792859 0.8110635 0.02792859 0.8256073 0.1622447 0.8110635 0.1622447 0.8256073 0.1622447 0.8256073 0.02792859 0.8401511 0.02792859 0.8256073 0.02792859 0.8401511 0.1622447 0.8256073 0.1622447 0.8401511 0.1622447 0.8401511 0.02792859 0.8546947 0.02792859 0.8401511 0.02792859 0.8546947 0.1622447 0.8401511 0.1622447 0.8546947 0.1622447 0.8546947 0.02792859 0.8692383 0.02792859 0.8546947 0.02792859 0.8692383 0.1622447 0.8546947 0.1622447 0.8692383 0.1622447 0.8837821 0.02792859 0.8692383 0.1622447 0.8692383 0.02792859 0.8692383 0.1622447 0.8837821 0.02792859 0.8837821 0.02792859 0.8837821 0.1622447 0.8983259 0.02792859 0.8983259 0.1622447 0.8983259 0.02792859 0.8837821 0.1622447 0.8837821 0.1622447 0.8983259 0.02792859 0.9128695 0.02792859 0.8983259 0.02792859 0.9128695 0.1622447 0.8983259 0.1622447 0.9128695 0.02792859 0.9128695 0.1622447 0.9274131 0.02792859 0.9274131 0.1622447 0.9274131 0.02792859 0.9128695 0.1622447 0.9128695 0.1622447 0.9274131 0.02792859 0.9419569 0.02792859 0.9274131 0.02792859 0.9419569 0.1622447 0.9274131 0.1622447 0.9419568 0.1622447 0.9419568 0.02792865 0.9565007 0.02792859 0.9419569 0.02792865 0.9565007 0.1622447 0.9419568 0.1622447 0.9565007 0.02792865 0.9565007 0.1622447 0.9710445 0.02792865 0.9710446 0.1622447 0.9710445 0.02792865 0.9565007 0.1622447 0.9565007 0.01645559 0.5028411 0.06816321 0.5616546 0.02940344 0.7557495 0.06816321 0.5616546 0.01645559 0.5028411 0.09505861 0.504449 0.06816321 0.5616546 0.09505861 0.504449 0.1449036 0.5272001 0.1449036 0.5272001 0.3124958 0.5616551 0.06816321 0.5616546 0.3124958 0.5616551 0.1449036 0.5272001 0.3670243 0.5272005 0.3124958 0.5616551 0.3670243 0.5272005 0.3124961 0.7615634 0.3124961 0.7615634 0.3670243 0.5272005 0.3670243 0.7798659 0.01163113 0.779866 0.02940344 0.7557495 0.3670243 0.7798659 0.02940344 0.7557495 0.01163113 0.779866 0.01645559 0.5028411 0.3670243 0.7798659 0.02940344 0.7557495 0.3124961 0.7615634 0.2054628 0.8037023 0.5178895 0.8091557 0.2054412 0.8091557 0.5178895 0.8091557 0.2054628 0.8037023 0.5179111 0.8037023 0.5178895 0.8091557 0.2054604 0.8146092 0.2054412 0.8091557 0.2054604 0.8146092 0.5178895 0.8091557 0.5179087 0.8146091 0.2054604 0.8146092 0.5178871 0.8200625 0.2054387 0.8200625 0.5178871 0.8200625 0.2054604 0.8146092 0.5179087 0.8146091 0.2054387 0.8200625 0.5178654 0.8255159 0.2054172 0.8255159 0.5178654 0.8255159 0.2054387 0.8200625 0.5178871 0.8200625 0.5178654 0.8255159 0.2054364 0.8309694 0.2054172 0.8255159 0.2054364 0.8309694 0.5178654 0.8255159 0.5178847 0.8309695 0.2054364 0.8309694 0.5178631 0.8364228 0.2054147 0.8364227 0.5178631 0.8364228 0.2054364 0.8309694 0.5178847 0.8309695 0.2054147 0.8364227 0.5178415 0.8418762 0.2053931 0.8418762 0.5178415 0.8418762 0.2054147 0.8364227 0.5178631 0.8364228 0.2053931 0.8418762 0.5178199 0.8473295 0.2053715 0.8473294 0.5178199 0.8473295 0.2053931 0.8418762 0.5178415 0.8418762 0.2053715 0.8473294 0.5177983 0.8527829 0.2053499 0.8527829 0.5177983 0.8527829 0.2053715 0.8473294 0.5178199 0.8473295 0.2053499 0.8527829 0.5177766 0.8582363 0.2053283 0.8582362 0.5177766 0.8582363 0.2053499 0.8527829 0.5177983 0.8527829 0.5810377 0.3290749 0.004902899 -2.63568e-4 0.5810353 -2.67383e-4 0.004902899 -2.63568e-4 0.5810377 0.3290749 0.004905402 0.3258628 0.5006948 0.9424874 0.3083641 0.9458445 0.3083513 0.9424874 0.3083641 0.9458445 0.5006948 0.9424874 0.5007075 0.9458445 0.5006819 0.9391302 0.3083513 0.9424874 0.3083385 0.9391302 0.3083513 0.9424874 0.5006819 0.9391302 0.5006948 0.9424874 0.500669 0.9357731 0.3083385 0.9391302 0.3083257 0.9357731 0.3083385 0.9391302 0.500669 0.9357731 0.5006819 0.9391302 0.3083403 0.932416 0.500669 0.9357731 0.3083257 0.9357731 0.500669 0.9357731 0.3083403 0.932416 0.5006837 0.932416 0.5006709 0.9290589 0.3083403 0.932416 0.3083274 0.9290589 0.3083403 0.932416 0.5006709 0.9290589 0.5006837 0.932416 0.500658 0.9257017 0.3083274 0.9290589 0.3083146 0.9257017 0.3083274 0.9290589 0.500658 0.9257017 0.5006709 0.9290589 0.5006453 0.9223446 0.3083146 0.9257017 0.3083018 0.9223446 0.3083146 0.9257017 0.5006453 0.9223446 0.500658 0.9257017 0.5006324 0.9189875 0.3083018 0.9223446 0.308289 0.9189875 0.3083018 0.9223446 0.5006324 0.9189875 0.5006453 0.9223446 0.5006195 0.9156304 0.308289 0.9189875 0.3082761 0.9156304 0.308289 0.9189875 0.5006195 0.9156304 0.5006324 0.9189875 0.5006069 0.9122732 0.3082761 0.9156304 0.3082634 0.9122732 0.3082761 0.9156304 0.5006069 0.9122732 0.5006195 0.9156304 0.500594 0.9089161 0.3082634 0.9122732 0.3082505 0.9089161 0.3082634 0.9122732 0.500594 0.9089161 0.5006069 0.9122732 0.5005812 0.9055589 0.3082505 0.9089161 0.3082377 0.9055589 0.3082505 0.9089161 0.5005812 0.9055589 0.500594 0.9089161 0.513914 0.6166138 0.543264 0.7623949 0.5141082 0.7624337 0.543264 0.7623949 0.513914 0.6166138 0.5430698 0.616575 0.5783509 0.9348304 0.8004086 0.7126473 0.8004712 0.9347677 0.8004086 0.7126473 0.5783509 0.9348304 0.5782881 0.71271 0.2387915 0.9425332 0.01667326 0.9506654 0.01667326 0.9425332 0.01667326 0.9506654 0.2387915 0.9425332 0.2387915 0.9506654 0.01667326 0.9344012 0.2387915 0.9425332 0.01667326 0.9425332 0.2387915 0.9425332 0.01667326 0.9344012 0.2387915 0.9344012 0.2387915 0.9262689 0.01667326 0.9344012 0.01667326 0.9262689 0.01667326 0.9344012 0.2387915 0.9262689 0.2387915 0.9344012 0.01667326 0.9181368 0.2387915 0.9262689 0.01667326 0.9262689 0.2387915 0.9262689 0.01667326 0.9181368 0.2387915 0.9181368 0.01667326 0.9100046 0.2387915 0.9181368 0.01667326 0.9181368 0.2387915 0.9181368 0.01667326 0.9100046 0.2387915 0.9100046 0.2387915 0.9100046 0.01667326 0.9018725 0.2387915 0.9018725 0.01667326 0.9018725 0.2387915 0.9100046 0.01667326 0.9100046 0.2387915 0.8937404 0.01667326 0.9018725 0.01667326 0.8937404 0.01667326 0.9018725 0.2387915 0.8937404 0.2387915 0.9018725 0.2387915 0.8856082 0.01667326 0.8937404 0.01667326 0.8856082 0.01667326 0.8937404 0.2387915 0.8856082 0.2387915 0.8937404 0.2387915 0.8856082 0.01667326 0.8785375 0.2387915 0.8785375 0.01667326 0.8785375 0.2387915 0.8856082 0.01667326 0.8856082 0.3463059 0.8039488 0.3469521 0.8186389 0.3460763 0.8113182 0.3469521 0.8186389 0.3463059 0.8039488 0.3476359 0.7966968 0.3469521 0.8186389 0.3476359 0.7966968 0.3474103 0.8155959 0.3476358 0.821116 0.3469521 0.8186389 0.3474103 0.8155959 0.02276283 0.649084 0.02326941 0.6542758 0.01886004 0.6436307 0.02326941 0.6542758 0.02276283 0.649084 0.03011286 0.6661288 0.03011286 0.6661288 0.02276283 0.649084 0.02813971 0.6546137 0.03011286 0.6661288 0.02813971 0.6546137 0.03844487 0.6769872 0.03844487 0.6769872 0.02813971 0.6546137 0.03428351 0.6592766 0.03844487 0.6769872 0.03428351 0.6592766 0.04812294 0.6866653 0.04812294 0.6866653 0.03428351 0.6592766 0.04105603 0.6629673 0.04812294 0.6866653 0.04105603 0.6629673 0.05898147 0.6949973 0.05898147 0.6949973 0.04105603 0.6629673 0.04830461 0.665603 0.05898147 0.6949973 0.04830461 0.665603 0.05586606 0.6671242 0.05898147 0.6949973 0.05586606 0.6671242 0.07083457 0.7018406 0.07083457 0.7018406 0.05586606 0.6671242 0.0635699 0.6674966 0.07083457 0.7018406 0.0635699 0.6674966 0.08347952 0.7070783 0.08347952 0.7070783 0.0635699 0.6674966 0.07124274 0.6667118 0.08347952 0.7070783 0.07124274 0.6667118 0.09669995 0.7106207 0.09669995 0.7106207 0.07124274 0.6667118 0.07871174 0.6647876 0.09669995 0.7106207 0.07871174 0.6647876 0.2782015 0.5970696 0.09669995 0.7106207 0.2782015 0.5970696 0.1102693 0.7124071 0.1102693 0.7124071 0.2782015 0.5970696 0.1239554 0.7124071 0.1239554 0.7124071 0.2782015 0.5970696 0.1375257 0.7106205 0.1375257 0.7106205 0.2782015 0.5970696 0.1507464 0.707078 0.1507464 0.707078 0.2782015 0.5970696 0.2917414 0.6369565 0.1507464 0.707078 0.3467264 0.6535217 0.4178983 0.640721 0.3467264 0.6535217 0.1507464 0.707078 0.3289683 0.6547557 0.3289683 0.6547557 0.1507464 0.707078 0.3191681 0.6543058 0.3191681 0.6543058 0.1507464 0.707078 0.3125244 0.6532064 0.3125244 0.6532064 0.1507464 0.707078 0.307578 0.6517596 0.307578 0.6517596 0.1507464 0.707078 0.3037016 0.6500869 0.3037016 0.6500869 0.1507464 0.707078 0.3005734 0.6482448 0.3005734 0.6482448 0.1507464 0.707078 0.2980099 0.6462596 0.2980099 0.6462596 0.1507464 0.707078 0.2959001 0.644142 0.2959001 0.644142 0.1507464 0.707078 0.2941756 0.6418924 0.2941756 0.6418924 0.1507464 0.707078 0.2927965 0.6395036 0.2927965 0.6395036 0.1507464 0.707078 0.2917414 0.6369565 + + + + + + + + + + + + + + + 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 +

0 0 0 1 1 1 2 2 2 1 1 3 0 0 4 3 3 5 4 4 6 0 0 7 5 5 8 0 0 9 4 4 10 3 3 11 6 6 12 7 6 13 8 6 14 7 7 15 6 7 16 9 7 17 7 8 18 9 8 19 10 8 20 7 9 21 10 9 22 11 9 23 11 10 24 10 10 25 12 10 26 11 11 27 12 11 28 13 11 29 13 12 30 12 12 31 14 12 32 13 13 33 14 13 34 15 13 35 13 14 36 15 14 37 16 14 38 16 15 39 15 15 40 17 15 41 16 16 42 17 16 43 18 16 44 18 17 45 17 17 46 19 17 47 18 18 48 19 18 49 20 18 50 18 19 51 20 19 52 21 19 53 21 20 54 20 20 55 22 20 56 21 21 57 22 21 58 23 21 59 21 22 60 23 22 61 24 22 62 24 23 63 23 23 64 25 23 65 24 24 66 25 24 67 26 24 68 24 25 69 26 25 70 27 25 71 24 26 72 27 26 73 28 26 74 28 27 75 27 27 76 29 27 77 28 28 78 29 28 79 30 28 80 30 29 81 29 29 82 31 29 83 31 30 84 29 30 85 32 30 86 32 31 87 29 31 88 33 31 89 2 2 90 34 32 91 35 33 92 34 32 93 2 2 94 1 1 95 36 34 96 37 34 97 38 34 98 37 35 99 36 35 100 39 35 101 39 36 102 36 36 103 40 36 104 40 37 105 36 37 106 41 37 107 40 38 108 41 38 109 42 38 110 42 39 111 41 39 112 43 39 113 42 40 114 43 40 115 44 40 116 44 41 117 43 41 118 45 41 119 44 42 120 45 42 121 46 42 122 46 43 123 45 43 124 47 43 125 46 44 126 47 44 127 48 44 128 48 45 129 47 45 130 49 45 131 48 46 132 49 46 133 50 46 134 50 47 135 49 47 136 51 47 137 51 48 138 49 48 139 52 48 140 51 49 141 52 49 142 53 49 143 53 50 144 52 50 145 54 50 146 53 51 147 54 51 148 55 51 149 55 52 150 54 52 151 56 52 152 56 53 153 54 53 154 57 53 155 56 54 156 57 54 157 58 54 158 58 55 159 57 55 160 59 55 161 59 56 162 57 56 163 60 56 164 59 57 165 60 57 166 61 57 167 61 58 168 60 58 169 62 58 170 61 59 171 62 59 172 63 59 173 64 60 174 4 4 175 5 5 176 4 4 177 64 60 178 65 61 179 66 62 180 67 63 181 68 64 182 67 63 183 66 62 184 69 65 185 70 66 186 68 64 187 71 67 188 68 64 189 70 66 190 66 62 191 72 68 192 71 67 193 73 69 194 71 67 195 72 68 196 70 66 197 74 70 198 75 70 199 76 70 200 75 71 201 74 71 202 77 71 203 75 72 204 77 72 205 78 72 206 79 73 207 80 74 208 81 75 209 80 74 210 79 73 211 82 76 212 83 77 213 82 76 214 79 73 215 82 76 216 83 77 217 84 78 218 85 79 219 83 77 220 86 80 221 83 77 222 85 79 223 84 78 224 87 81 225 85 79 226 86 80 227 85 79 228 87 81 229 88 82 230 89 83 231 87 81 232 90 84 233 87 81 234 89 83 235 88 82 236 91 85 237 90 84 238 92 86 239 90 84 240 91 85 241 89 83 242 93 87 243 92 86 244 94 88 245 92 86 246 93 87 247 91 85 248 95 89 249 94 88 250 96 90 251 94 88 252 95 89 253 93 87 254 97 91 255 96 90 256 98 92 257 96 90 258 97 91 259 95 89 260 97 91 261 99 93 262 100 94 263 99 93 264 97 91 265 98 92 266 100 94 267 101 95 268 102 96 269 101 95 270 100 94 271 99 93 272 102 96 273 103 97 274 104 98 275 103 97 276 102 96 277 101 95 278 104 98 279 105 99 280 106 100 281 105 99 282 104 98 283 103 97 284 107 101 285 108 101 286 109 101 287 108 102 288 107 102 289 110 102 290 110 103 291 107 103 292 111 103 293 112 104 294 113 105 295 114 106 296 113 105 297 112 104 298 115 107 299 116 108 300 115 107 301 112 104 302 115 107 303 116 108 304 117 109 305 116 108 306 34 32 307 117 109 308 34 32 309 116 108 310 35 33 311 118 110 312 64 60 313 119 111 314 64 60 315 118 110 316 65 61 317 120 112 318 118 110 319 119 111 320 118 110 321 120 112 322 121 113 323 67 63 324 121 113 325 120 112 326 121 113 327 67 63 328 69 65 329 122 114 330 123 114 331 124 114 332 123 115 333 122 115 334 125 115 335 125 116 336 122 116 337 126 116 338 126 117 339 122 117 340 127 117 341 126 118 342 127 118 343 128 118 344 128 119 345 127 119 346 129 119 347 128 120 348 129 120 349 130 120 350 130 121 351 129 121 352 131 121 353 130 122 354 131 122 355 132 122 356 132 123 357 131 123 358 133 123 359 132 124 360 133 124 361 134 124 362 134 125 363 133 125 364 135 125 365 135 126 366 133 126 367 136 126 368 135 127 369 136 127 370 137 127 371 137 128 372 136 128 373 138 128 374 137 129 375 138 129 376 139 129 377 139 130 378 138 130 379 140 130 380 140 131 381 138 131 382 141 131 383 140 132 384 141 132 385 142 132 386 142 133 387 141 133 388 143 133 389 143 134 390 141 134 391 144 134 392 143 135 393 144 135 394 145 135 395 145 136 396 144 136 397 146 136 398 146 137 399 144 137 400 147 137 401 146 138 402 147 138 403 148 138 404 146 139 405 148 139 406 149 139 407 150 140 408 151 140 409 152 140 410 151 141 411 150 141 412 153 141 413 154 142 414 155 142 415 156 142 416 155 143 417 154 143 418 157 143 419 158 144 420 159 144 421 160 144 422 159 145 423 158 145 424 161 145 425 162 146 426 163 146 427 164 146 428 163 147 429 162 147 430 165 147 431 166 148 432 167 148 433 168 148 434 167 149 435 166 149 436 169 149 437 170 150 438 171 151 439 172 152 440 171 151 441 170 150 442 173 153 443 174 154 444 175 154 445 176 154 446 175 155 447 174 155 448 177 155 449 177 156 450 174 156 451 178 156 452 177 157 453 178 157 454 179 157 455 177 158 456 179 158 457 180 158 458 177 159 459 180 159 460 181 159 461 177 160 462 181 160 463 182 160 464 177 161 465 182 161 466 183 161 467 177 162 468 183 162 469 184 162 470 177 163 471 184 163 472 185 163 473 177 164 474 185 164 475 186 164 476 177 165 477 186 165 478 187 165 479 177 166 480 187 166 481 188 166 482 177 167 483 188 167 484 189 167 485 177 168 486 189 168 487 190 168 488 177 169 489 190 169 490 191 169 491 177 170 492 191 170 493 192 170 494 177 171 495 192 171 496 193 171 497 177 172 498 193 172 499 194 172 500 177 173 501 194 173 502 195 173 503 177 174 504 195 174 505 196 174 506 177 175 507 196 175 508 197 175 509 177 176 510 197 176 511 198 176 512 177 177 513 198 177 514 199 177 515 177 178 516 199 178 517 200 178 518 177 179 519 200 179 520 201 179 521 202 180 522 173 153 523 170 150 524 173 153 525 202 180 526 203 181 527 204 182 528 205 182 529 206 182 530 205 183 531 204 183 532 207 183 533 205 184 534 207 184 535 208 184 536 208 185 537 207 185 538 209 185 539 209 186 540 207 186 541 210 186 542 210 187 543 207 187 544 211 187 545 211 188 546 207 188 547 212 188 548 212 189 549 207 189 550 213 189 551 213 190 552 207 190 553 214 190 554 214 191 555 207 191 556 215 191 557 215 192 558 207 192 559 216 192 560 216 193 561 207 193 562 217 193 563 217 194 564 207 194 565 218 194 566 218 195 567 207 195 568 219 195 569 219 196 570 207 196 571 220 196 572 220 197 573 207 197 574 221 197 575 221 198 576 207 198 577 222 198 578 222 199 579 207 199 580 223 199 581 223 200 582 207 200 583 224 200 584 224 201 585 207 201 586 225 201 587 225 202 588 207 202 589 226 202 590 226 203 591 207 203 592 227 203 593 227 204 594 207 204 595 228 204 596 228 205 597 207 205 598 229 205 599 229 206 600 207 206 601 230 206 602 230 207 603 207 207 604 231 207 605 231 208 606 207 208 607 232 208 608 232 209 609 207 209 610 233 209 611 233 210 612 207 210 613 234 210 614 234 211 615 207 211 616 235 211 617 235 212 618 207 212 619 236 212 620 236 213 621 207 213 622 237 213 623 237 214 624 207 214 625 238 214 626 238 215 627 207 215 628 239 215 629 239 216 630 207 216 631 240 216 632 240 217 633 207 217 634 241 217 635 241 218 636 207 218 637 242 218 638 218 219 639 243 219 640 217 219 641 244 220 642 245 220 643 246 220 644 245 221 645 244 221 646 247 221 647 245 222 648 247 222 649 248 222 650 248 223 651 247 223 652 249 223 653 249 224 654 247 224 655 250 224 656 246 225 657 251 225 658 252 225 659 251 226 660 246 226 661 245 226 662 252 227 663 251 227 664 250 227 665 252 228 666 250 228 667 247 228 668 253 229 669 254 230 670 255 231 671 254 230 672 253 229 673 256 232 674 257 233 675 258 234 676 259 235 677 258 236 678 257 236 679 260 236 680 258 237 681 260 237 682 261 237 683 259 235 684 258 234 685 262 238 686 262 238 687 263 239 688 259 235 689 263 239 690 262 238 691 264 240 692 264 240 693 265 241 694 263 239 695 265 241 696 264 240 697 266 242 698 266 242 699 267 243 700 265 241 701 267 243 702 266 242 703 268 244 704 268 244 705 269 245 706 267 243 707 269 245 708 268 244 709 270 246 710 271 247 711 269 245 712 270 246 713 269 245 714 271 247 715 272 248 716 272 248 717 273 249 718 274 250 719 273 249 720 272 248 721 271 247 722 273 249 723 275 251 724 274 250 725 275 251 726 273 249 727 276 252 728 275 251 729 277 253 730 278 254 731 277 253 732 275 251 733 276 252 734 277 253 735 279 255 736 278 254 737 279 255 738 277 253 739 280 256 740 280 256 741 281 257 742 279 255 743 281 257 744 280 256 745 282 258 746 281 257 747 283 259 748 284 260 749 283 259 750 281 257 751 282 258 752 285 261 753 286 261 754 287 261 755 286 262 756 285 262 757 288 262 758 286 263 759 288 263 760 289 263 761 289 264 762 290 264 763 286 264 764 290 265 765 289 265 766 291 265 767 290 266 768 291 266 769 292 266 770 292 267 771 291 267 772 293 267 773 294 268 774 287 268 775 293 268 776 287 269 777 294 269 778 285 269 779 293 270 780 287 270 781 292 270 782 295 271 783 296 272 784 297 273 785 296 272 786 295 271 787 298 274 788 296 272 789 299 275 790 297 273 791 299 275 792 296 272 793 300 276 794 299 275 795 301 277 796 302 278 797 301 277 798 299 275 799 300 276 800 302 278 801 303 279 802 304 280 803 303 279 804 302 278 805 301 277 806 303 279 807 305 281 808 304 280 809 305 281 810 303 279 811 306 282 812 305 281 813 307 283 814 308 284 815 307 283 816 305 281 817 306 282 818 308 284 819 309 285 820 310 286 821 309 285 822 308 284 823 307 283 824 310 286 825 311 287 826 312 288 827 311 287 828 310 286 829 309 285 830 312 288 831 313 289 832 314 290 833 313 289 834 312 288 835 311 287 836 314 290 837 203 181 838 202 180 839 203 181 840 314 290 841 313 289 842 315 291 843 255 231 844 316 292 845 255 231 846 315 291 847 253 229 848 317 293 849 318 294 850 319 295 851 318 294 852 317 293 853 320 296 854 321 297 855 319 295 856 322 298 857 319 295 858 321 297 859 317 293 860 323 299 861 322 298 862 324 300 863 322 298 864 323 299 865 321 297 866 325 301 867 323 299 868 324 300 869 323 299 870 325 301 871 326 302 872 327 303 873 325 301 874 328 304 875 325 301 876 327 303 877 326 302 878 329 305 879 328 304 880 330 306 881 328 304 882 329 305 883 327 303 884 331 307 885 330 306 886 332 308 887 330 306 888 331 307 889 329 305 890 333 309 891 332 308 892 334 310 893 332 308 894 333 309 895 331 307 896 335 311 897 334 310 898 336 312 899 334 310 900 335 311 901 333 309 902 337 313 903 336 312 904 338 314 905 336 312 906 337 313 907 335 311 908 339 315 909 338 314 910 340 316 911 338 314 912 339 315 913 337 313 914 341 317 915 340 316 916 342 318 917 340 316 918 341 317 919 339 315 920 343 319 921 344 319 922 345 319 923 344 320 924 343 320 925 346 320 926 347 321 927 348 321 928 349 321 929 348 322 930 347 322 931 350 322 932 351 323 933 352 324 934 353 325 935 352 324 936 351 323 937 354 326 938 355 327 939 351 323 940 353 325 941 351 323 942 355 327 943 356 328 944 357 329 945 355 327 946 358 330 947 355 327 948 357 329 949 356 328 950 359 331 951 357 329 952 358 330 953 357 329 954 359 331 955 360 332 956 361 333 957 360 332 958 359 331 959 360 332 960 361 333 961 362 334 962 362 334 963 363 335 964 364 336 965 363 335 966 362 334 967 361 333 968 365 337 969 363 335 970 366 338 971 363 335 972 365 337 973 364 336 974 367 339 975 366 338 976 368 340 977 366 338 978 367 339 979 365 337 980 367 339 981 369 341 982 370 342 983 369 341 984 367 339 985 368 340 986 371 343 987 372 343 988 373 343 989 372 344 990 371 344 991 374 344 992 372 345 993 374 345 994 375 345 995 376 346 996 372 346 997 375 346 998 377 347 999 378 347 1000 379 347 1001 378 348 1002 377 348 1003 380 348 1004 380 349 1005 377 349 1006 381 349 1007 380 350 1008 381 350 1009 382 350 1010 382 351 1011 381 351 1012 383 351 1013 382 352 1014 383 352 1015 384 352 1016 384 353 1017 383 353 1018 385 353 1019 384 354 1020 385 354 1021 386 354 1022 386 355 1023 385 355 1024 387 355 1025 386 356 1026 387 356 1027 388 356 1028 386 357 1029 388 357 1030 389 357 1031 389 358 1032 388 358 1033 390 358 1034 389 359 1035 390 359 1036 391 359 1037 391 360 1038 390 360 1039 392 360 1040 391 361 1041 392 361 1042 393 361 1043 393 362 1044 392 362 1045 394 362 1046 393 363 1047 394 363 1048 395 363 1049 393 364 1050 395 364 1051 396 364 1052 396 365 1053 395 365 1054 397 365 1055 397 366 1056 395 366 1057 398 366 1058 398 367 1059 395 367 1060 399 367 1061 399 368 1062 395 368 1063 400 368 1064 399 369 1065 401 369 1066 402 369 1067 401 370 1068 399 370 1069 403 370 1070 403 371 1071 399 371 1072 404 371 1073 404 372 1074 399 372 1075 405 372 1076 405 373 1077 399 373 1078 406 373 1079 406 374 1080 399 374 1081 407 374 1082 407 375 1083 399 375 1084 408 375 1085 408 376 1086 399 376 1087 409 376 1088 409 377 1089 399 377 1090 410 377 1091 410 378 1092 399 378 1093 411 378 1094 411 379 1095 399 379 1096 412 379 1097 412 380 1098 399 380 1099 400 380 1100

+
+
+
+
+ + + + + 0.6858805 -0.3173701 0.6548619 7.481132 0.7276338 0.3124686 -0.6106656 -6.50764 -0.01081678 0.8953432 0.4452454 5.343665 0 0 0 1 + + + + -0.2908646 -0.7711008 0.5663932 9.768214 0.9551712 -0.1998834 0.2183912 0.2533256 -0.05518906 0.6045247 0.7946723 6.205874 0 0 0 1 + + + + 0.0254 0 0 0.001409317 0 0.0254 0 -0.003276879 0 0 0.0254 -0.002205567 0 0 0 1 + + 1 0 0 -5.316289 0 1 0 -6.059348 0 0 1 0.002081193 0 0 0 1 + + + + + + + + + + + 1 0 0 0.01970216 0 1 0 -0.3079368 0 0 1 -0.09546833 0 0 0 1 + + + + 1 0 0 -0.3970417 0 1 0 0.02320915 0 0 1 0.04494383 0 0 0 1 + + + + 1 0 0 0.03263873 0 1 0 0.37315 0 0 1 -0.5897875 0 0 0 1 + + + + + + + +
\ No newline at end of file diff --git a/src/parts source/kOS new 0M/new 0M meshes/kOS0m.fbx b/src/parts source/kOS new 0M/new 0M meshes/kOS0m.fbx new file mode 100644 index 000000000..9c1b966e4 Binary files /dev/null and b/src/parts source/kOS new 0M/new 0M meshes/kOS0m.fbx differ diff --git a/src/parts source/kOS new 0M/new 0M meshes/new0M.dae b/src/parts source/kOS new 0M/new 0M meshes/new0M.dae new file mode 100644 index 000000000..34f92e882 --- /dev/null +++ b/src/parts source/kOS new 0M/new 0M meshes/new0M.dae @@ -0,0 +1,187 @@ + + + + + Blender User + Blender 2.73.0 commit date:2015-01-20, commit time:18:16, hash:bbf09d9 + + 2016-02-19T12:25:08 + 2016-02-19T12:25:08 + + Z_UP + + + + + + 1 1 1 + 1 + 0 + 0.00111109 + + + + + 0.000999987 + 1 + 0.1 + 0.1 + 1 + 1 + 1 + 2 + 0 + 1 + 1 + 1 + 1 + 1 + 0 + 2880 + 2 + 30.002 + 1.000799 + 0.04999995 + 29.99998 + 1 + 2 + 0 + 0 + 1 + 1 + 1 + 1 + 8192 + 1 + 1 + 0 + 1 + 1 + 1 + 3 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 1 + 3 + 0.15 + 75 + 1 + 1 + 0 + 1 + 1 + 0 + + + + + + + + + + + + 0 0 0 1 + + + 0 0 0 1 + + + 0.8 0.8 0.8 1 + + + 0.165 0.165 0.165 1 + + + 103 + + + 1 + + + + + + + + + + + + + + + + 0.212099 0.07084095 0 0.206044 0.07671391 0 0.1990232 0.07671391 0.05332809 0.2048719 0.07084095 0.05489522 0.212099 0.06182485 0 0.212099 0.07084095 0 0.2048719 0.07084095 0.05489522 0.2048719 0.06182485 0.05489522 0.249799 0.03977394 0 0.233553 0.06182485 0 0.2255948 0.06182485 0.06044793 0.2412873 0.03977394 0.06465274 0.25 0.006965994 0 0.249799 0.03977394 0 0.2412873 0.03977394 0.06465274 0.2414814 0.006965994 0.06470471 0.243041 0 0 0.25 0.006965994 0 0.2414814 0.006965994 0.06470471 0.2347596 0 0.06290364 0.1784393 0.07671391 0.103022 0.1836831 0.07084095 0.1060495 0.1836831 0.07084095 0.1060495 0.1836831 0.06182485 0.1060495 0.2022628 0.06182485 0.1167765 0.2163323 0.03977394 0.1248995 0.2163323 0.03977394 0.1248995 0.2165063 0.006965994 0.125 0.2165063 0.006965994 0.125 0.2104796 0 0.1215205 0.1456951 0.07671391 0.1456951 0.1499766 0.07084095 0.1499766 0.1499766 0.07084095 0.1499766 0.1499766 0.06182485 0.1499766 0.1651469 0.06182485 0.1651469 0.1766346 0.03977394 0.1766346 0.1766346 0.03977394 0.1766346 0.1767767 0.006965994 0.1767767 0.1767767 0.006965994 0.1767767 0.1718559 0 0.1718559 0.103022 0.07671391 0.1784393 0.1060495 0.07084095 0.1836831 0.1060495 0.07084095 0.1836831 0.1060495 0.06182485 0.1836831 0.1167765 0.06182485 0.2022628 0.1248995 0.03977394 0.2163323 0.1248995 0.03977394 0.2163323 0.125 0.006965994 0.2165063 0.125 0.006965994 0.2165063 0.1215205 0 0.2104796 0.05332809 0.07671391 0.1990232 0.05489522 0.07084095 0.2048719 0.05489522 0.07084095 0.2048719 0.05489522 0.06182485 0.2048719 0.06044793 0.06182485 0.2255948 0.06465274 0.03977394 0.2412873 0.06465274 0.03977394 0.2412873 0.06470471 0.006965994 0.2414814 0.06470471 0.006965994 0.2414814 0.06290364 0 0.2347596 0 0.07671391 0.206044 0 0.07084095 0.212099 0 0.07084095 0.212099 0 0.06182485 0.212099 0 0.06182485 0.233553 0 0.03977394 0.249799 0 0.03977394 0.249799 0 0.006965994 0.25 0 0.006965994 0.25 0 0 0.243041 -0.05332809 0.07671391 0.1990232 -0.05489522 0.07084095 0.2048719 -0.05489522 0.07084095 0.2048719 -0.05489522 0.06182485 0.2048719 -0.06044793 0.06182485 0.2255948 -0.06465274 0.03977394 0.2412873 -0.06465274 0.03977394 0.2412873 -0.06470471 0.006965994 0.2414814 -0.06470471 0.006965994 0.2414814 -0.06290364 0 0.2347596 -0.103022 0.07671391 0.1784393 -0.1060495 0.07084095 0.1836831 -0.1060495 0.07084095 0.1836831 -0.1060495 0.06182485 0.1836831 -0.1167765 0.06182485 0.2022628 -0.1248995 0.03977394 0.2163323 -0.1248995 0.03977394 0.2163323 -0.125 0.006965994 0.2165063 -0.125 0.006965994 0.2165063 -0.1215205 0 0.2104796 -0.1456951 0.07671391 0.1456951 -0.1499766 0.07084095 0.1499766 -0.1499766 0.07084095 0.1499766 -0.1499766 0.06182485 0.1499766 -0.1651469 0.06182485 0.1651469 -0.1766346 0.03977394 0.1766346 -0.1766346 0.03977394 0.1766346 -0.1767767 0.006965994 0.1767767 -0.1767767 0.006965994 0.1767767 -0.1718559 0 0.1718559 -0.1784393 0.07671391 0.103022 -0.1836831 0.07084095 0.1060495 -0.1836831 0.07084095 0.1060495 -0.1836831 0.06182485 0.1060495 -0.2022628 0.06182485 0.1167765 -0.2163323 0.03977394 0.1248995 -0.2163323 0.03977394 0.1248995 -0.2165063 0.006965994 0.125 -0.2165063 0.006965994 0.125 -0.2104796 0 0.1215205 -0.1990232 0.07671391 0.05332809 -0.2048719 0.07084095 0.05489522 -0.2048719 0.07084095 0.05489522 -0.2048719 0.06182485 0.05489522 -0.2255948 0.06182485 0.06044793 -0.2412873 0.03977394 0.06465274 -0.2412873 0.03977394 0.06465274 -0.2414814 0.006965994 0.06470471 -0.2414814 0.006965994 0.06470471 -0.2347596 0 0.06290364 -0.206044 0.07671391 0 -0.212099 0.07084095 0 -0.212099 0.07084095 0 -0.212099 0.06182485 0 -0.233553 0.06182485 0 -0.249799 0.03977394 0 -0.249799 0.03977394 0 -0.25 0.006965994 0 -0.25 0.006965994 0 -0.243041 0 0 -0.1990232 0.07671391 -0.05332809 -0.2048719 0.07084095 -0.05489522 -0.2048719 0.07084095 -0.05489522 -0.2048719 0.06182485 -0.05489522 -0.2255948 0.06182485 -0.06044793 -0.2412873 0.03977394 -0.06465274 -0.2412873 0.03977394 -0.06465274 -0.2414814 0.006965994 -0.06470471 -0.2414814 0.006965994 -0.06470471 -0.2347596 0 -0.06290364 -0.1784393 0.07671391 -0.103022 -0.1836831 0.07084095 -0.1060495 -0.1836831 0.07084095 -0.1060495 -0.1836831 0.06182485 -0.1060495 -0.2022628 0.06182485 -0.1167765 -0.2163323 0.03977394 -0.1248995 -0.2163323 0.03977394 -0.1248995 -0.2165063 0.006965994 -0.125 -0.2165063 0.006965994 -0.125 -0.2104796 0 -0.1215205 -0.1456951 0.07671391 -0.1456951 -0.1499766 0.07084095 -0.1499766 -0.1499766 0.07084095 -0.1499766 -0.1499766 0.06182485 -0.1499766 -0.1651469 0.06182485 -0.1651469 -0.1766346 0.03977394 -0.1766346 -0.1766346 0.03977394 -0.1766346 -0.1767767 0.006965994 -0.1767767 -0.1767767 0.006965994 -0.1767767 -0.1718559 0 -0.1718559 -0.103022 0.07671391 -0.1784393 -0.1060495 0.07084095 -0.1836831 -0.1060495 0.07084095 -0.1836831 -0.1060495 0.06182485 -0.1836831 -0.1167765 0.06182485 -0.2022628 -0.1248995 0.03977394 -0.2163323 -0.1248995 0.03977394 -0.2163323 -0.125 0.006965994 -0.2165063 -0.125 0.006965994 -0.2165063 -0.1215205 0 -0.2104796 -0.05332809 0.07671391 -0.1990232 -0.05489522 0.07084095 -0.2048719 -0.05489522 0.07084095 -0.2048719 -0.05489522 0.06182485 -0.2048719 -0.06044793 0.06182485 -0.2255948 -0.06465274 0.03977394 -0.2412873 -0.06465274 0.03977394 -0.2412873 -0.06470471 0.006965994 -0.2414814 -0.06470471 0.006965994 -0.2414814 -0.06290364 0 -0.2347596 0 0.07671391 -0.206044 0 0.07084095 -0.212099 0 0.07084095 -0.212099 0 0.06182485 -0.212099 0 0.06182485 -0.233553 0 0.03977394 -0.249799 0 0.03977394 -0.249799 0 0.006965994 -0.25 0 0.006965994 -0.25 0 0 -0.243041 0.05332809 0.07671391 -0.1990232 0.05489522 0.07084095 -0.2048719 0.05489522 0.07084095 -0.2048719 0.05489522 0.06182485 -0.2048719 0.06044793 0.06182485 -0.2255948 0.06465274 0.03977394 -0.2412873 0.06465274 0.03977394 -0.2412873 0.06470471 0.006965994 -0.2414814 0.06470471 0.006965994 -0.2414814 0.06290364 0 -0.2347596 0.103022 0.07671391 -0.1784393 0.1060495 0.07084095 -0.1836831 0.1060495 0.07084095 -0.1836831 0.1060495 0.06182485 -0.1836831 0.1167765 0.06182485 -0.2022628 0.1248995 0.03977394 -0.2163323 0.1248995 0.03977394 -0.2163323 0.125 0.006965994 -0.2165063 0.125 0.006965994 -0.2165063 0.1215205 0 -0.2104796 0.1456951 0.07671391 -0.1456951 0.1499766 0.07084095 -0.1499766 0.1499766 0.07084095 -0.1499766 0.1499766 0.06182485 -0.1499766 0.1651469 0.06182485 -0.1651469 0.1766346 0.03977394 -0.1766346 0.1766346 0.03977394 -0.1766346 0.1767767 0.006965994 -0.1767767 0.1767767 0.006965994 -0.1767767 0.1718559 0 -0.1718559 0.1784393 0.07671391 -0.103022 0.1836831 0.07084095 -0.1060495 0.1836831 0.07084095 -0.1060495 0.1836831 0.06182485 -0.1060495 0.2022628 0.06182485 -0.1167765 0.2163323 0.03977394 -0.1248995 0.2163323 0.03977394 -0.1248995 0.2165063 0.006965994 -0.125 0.2165063 0.006965994 -0.125 0.2104796 0 -0.1215205 0.1990232 0.07671391 -0.05332809 0.2048719 0.07084095 -0.05489522 0.2048719 0.07084095 -0.05489522 0.2048719 0.06182485 -0.05489522 0.2255948 0.06182485 -0.06044793 0.2412873 0.03977394 -0.06465274 0.2412873 0.03977394 -0.06465274 0.2414814 0.006965994 -0.06470471 0.2414814 0.006965994 -0.06470471 0.2347596 0 -0.06290364 0.2048719 0.06182485 -0.05489522 0.212099 0.06182485 0 0.233553 0.06182485 0 0.2255948 0.06182485 -0.06044793 -0.243041 0 0 -0.2347596 0 -0.06290364 -0.2104796 0 -0.1215205 -0.1718559 0 -0.1718559 -0.1215205 0 -0.2104796 -0.06290364 0 -0.2347596 0 0 -0.243041 0.06290364 0 -0.2347596 0.1215205 0 -0.2104796 0.1718559 0 -0.1718559 0.2104796 0 -0.1215205 0.2347596 0 -0.06290364 0.243041 0 0 0.2347596 0 0.06290364 0.2104796 0 0.1215205 0.1718559 0 0.1718559 0.1215205 0 0.2104796 0.06290364 0 0.2347596 0 0 0.243041 -0.06290364 0 0.2347596 -0.1215205 0 0.2104796 -0.1718559 0 0.1718559 -0.2104796 0 0.1215205 -0.2347596 0 0.06290364 -0.05332809 0.07671391 0.1990232 0 0.07671391 0.206044 0.05332809 0.07671391 0.1990232 0.103022 0.07671391 0.1784393 0.1456951 0.07671391 0.1456951 0.1784393 0.07671391 0.103022 0.1990232 0.07671391 0.05332809 0.206044 0.07671391 0 0.1990232 0.07671391 -0.05332809 0.1784393 0.07671391 -0.103022 0.1456951 0.07671391 -0.1456951 0.103022 0.07671391 -0.1784393 0.05332809 0.07671391 -0.1990232 0 0.07671391 -0.206044 -0.05332809 0.07671391 -0.1990232 -0.103022 0.07671391 -0.1784393 -0.1456951 0.07671391 -0.1456951 -0.1784393 0.07671391 -0.103022 -0.1990232 0.07671391 -0.05332809 -0.206044 0.07671391 0 -0.1990232 0.07671391 0.05332809 -0.1784393 0.07671391 0.103022 -0.1456951 0.07671391 0.1456951 -0.103022 0.07671391 0.1784393 0.1836831 0.06182485 -0.1060495 0.2022628 0.06182485 -0.1167765 0.1499766 0.06182485 -0.1499766 0.1651469 0.06182485 -0.1651469 0.1060495 0.06182485 -0.1836831 0.1167765 0.06182485 -0.2022628 0.05489522 0.06182485 -0.2048719 0.06044793 0.06182485 -0.2255948 -0.05489522 0.06182485 -0.2048719 0 0.06182485 -0.212099 0 0.06182485 -0.233553 -0.06044793 0.06182485 -0.2255948 -0.1499766 0.06182485 -0.1499766 -0.1060495 0.06182485 -0.1836831 -0.1167765 0.06182485 -0.2022628 -0.1651469 0.06182485 -0.1651469 -0.1836831 0.06182485 -0.1060495 -0.2022628 0.06182485 -0.1167765 -0.2048719 0.06182485 -0.05489522 -0.2255948 0.06182485 -0.06044793 -0.212099 0.06182485 0 -0.233553 0.06182485 0 -0.1836831 0.06182485 0.1060495 -0.2048719 0.06182485 0.05489522 -0.2255948 0.06182485 0.06044793 -0.2022628 0.06182485 0.1167765 -0.1499766 0.06182485 0.1499766 -0.1651469 0.06182485 0.1651469 -0.1060495 0.06182485 0.1836831 -0.1167765 0.06182485 0.2022628 -0.05489522 0.06182485 0.2048719 -0.06044793 0.06182485 0.2255948 0 0.06182485 0.212099 0 0.06182485 0.233553 0.05489522 0.06182485 0.2048719 0.06044793 0.06182485 0.2255948 0.1060495 0.06182485 0.1836831 0.1167765 0.06182485 0.2022628 0.1499766 0.06182485 0.1499766 0.1651469 0.06182485 0.1651469 0.1836831 0.06182485 0.1060495 0.2022628 0.06182485 0.1167765 0.2048719 0.06182485 0.05489522 0.2255948 0.06182485 0.06044793 -0.05332809 0.07671391 0.1990232 0 0.07671391 0.206044 0.05332809 0.07671391 0.1990232 0.103022 0.07671391 0.1784393 0.1456951 0.07671391 0.1456951 0.1784393 0.07671391 0.103022 0.1990232 0.07671391 0.05332809 0.206044 0.07671391 0 0.1990232 0.07671391 -0.05332809 0.1784393 0.07671391 -0.103022 0.1456951 0.07671391 -0.1456951 0.103022 0.07671391 -0.1784393 0.05332809 0.07671391 -0.1990232 0 0.07671391 -0.206044 -0.05332809 0.07671391 -0.1990232 -0.103022 0.07671391 -0.1784393 -0.1456951 0.07671391 -0.1456951 -0.1784393 0.07671391 -0.103022 -0.1990232 0.07671391 -0.05332809 -0.206044 0.07671391 0 -0.1990232 0.07671391 0.05332809 -0.1784393 0.07671391 0.103022 -0.1456951 0.07671391 0.1456951 -0.103022 0.07671391 0.1784393 -0.05332809 0.07671391 0.1990232 0 0.07671391 0.206044 0.05332809 0.07671391 0.1990232 0.103022 0.07671391 0.1784393 0.1456951 0.07671391 0.1456951 0.1784393 0.07671391 0.103022 0.1990232 0.07671391 0.05332809 0.206044 0.07671391 0 0.1990232 0.07671391 -0.05332809 0.1784393 0.07671391 -0.103022 0.1456951 0.07671391 -0.1456951 0.103022 0.07671391 -0.1784393 0.05332809 0.07671391 -0.1990232 0 0.07671391 -0.206044 -0.05332809 0.07671391 -0.1990232 -0.103022 0.07671391 -0.1784393 -0.1456951 0.07671391 -0.1456951 -0.1784393 0.07671391 -0.103022 -0.1990232 0.07671391 -0.05332809 -0.206044 0.07671391 0 -0.1990232 0.07671391 0.05332809 -0.1784393 0.07671391 0.103022 -0.1456951 0.07671391 0.1456951 -0.103022 0.07671391 0.1784393 -0.05332809 0.07671391 0.1990232 0 0.07671391 0.206044 0.05332809 0.07671391 0.1990232 0.103022 0.07671391 0.1784393 0.1456951 0.07671391 0.1456951 0.1784393 0.07671391 0.103022 0.1990232 0.07671391 0.05332809 0.206044 0.07671391 0 0.1990232 0.07671391 -0.05332809 0.1784393 0.07671391 -0.103022 0.1456951 0.07671391 -0.1456951 0.103022 0.07671391 -0.1784393 0.05332809 0.07671391 -0.1990232 0 0.07671391 -0.206044 -0.05332809 0.07671391 -0.1990232 -0.103022 0.07671391 -0.1784393 -0.1456951 0.07671391 -0.1456951 -0.1784393 0.07671391 -0.103022 -0.1990232 0.07671391 -0.05332809 -0.206044 0.07671391 0 -0.1990232 0.07671391 0.05332809 -0.1784393 0.07671391 0.103022 -0.1456951 0.07671391 0.1456951 -0.103022 0.07671391 0.1784393 -0.05332809 0.07671391 0.1990232 0 0.07671391 0.206044 0.05332809 0.07671391 0.1990232 0.103022 0.07671391 0.1784393 0.1456951 0.07671391 0.1456951 0.1784393 0.07671391 0.103022 0.1990232 0.07671391 0.05332809 0.206044 0.07671391 0 0.1990232 0.07671391 -0.05332809 0.1784393 0.07671391 -0.103022 0.1456951 0.07671391 -0.1456951 0.103022 0.07671391 -0.1784393 0.05332809 0.07671391 -0.1990232 0 0.07671391 -0.206044 -0.05332809 0.07671391 -0.1990232 -0.103022 0.07671391 -0.1784393 -0.1456951 0.07671391 -0.1456951 -0.1784393 0.07671391 -0.103022 -0.1990232 0.07671391 -0.05332809 -0.206044 0.07671391 0 -0.1990232 0.07671391 0.05332809 -0.1784393 0.07671391 0.103022 -0.1456951 0.07671391 0.1456951 -0.103022 0.07671391 0.1784393 -0.05332809 0.07671391 0.1990232 0 0.07671391 0.206044 0.05332809 0.07671391 0.1990232 0.103022 0.07671391 0.1784393 0.1456951 0.07671391 0.1456951 0.1784393 0.07671391 0.103022 0.1990232 0.07671391 0.05332809 0.206044 0.07671391 0 0.1990232 0.07671391 -0.05332809 0.1784393 0.07671391 -0.103022 0.1456951 0.07671391 -0.1456951 0.103022 0.07671391 -0.1784393 0.05332809 0.07671391 -0.1990232 0 0.07671391 -0.206044 -0.05332809 0.07671391 -0.1990232 -0.103022 0.07671391 -0.1784393 -0.1456951 0.07671391 -0.1456951 -0.1784393 0.07671391 -0.103022 -0.1990232 0.07671391 -0.05332809 -0.206044 0.07671391 0 -0.1990232 0.07671391 0.05332809 -0.1784393 0.07671391 0.103022 -0.1456951 0.07671391 0.1456951 -0.103022 0.07671391 0.1784393 + + + + + + + + + + 0.6962187 0.7177954 0 0.6725059 0.7177954 0.1801813 0.6725059 0.7177954 0.1801813 0.9999695 0 0 0.9659109 0 0.2587969 0.9659109 0 0.2587969 0.8050783 0.5931273 0 0.8050783 0.5931273 0 0.7776421 0.5931273 0.2083498 0.9999695 0.006103694 0 0.9658803 0.006103694 0.2587969 0.9658803 0.006103694 0.2587969 0.7074496 -0.7067477 0 0.7074496 -0.7067477 0 0.68334 -0.7067477 0.1830805 0.6029542 0.7177954 0.3480941 0.6029542 0.7177954 0.3480941 0.8660237 0 0.4999848 0.8660237 0 0.4999848 0.6972259 0.5931273 0.4025391 0.6972259 0.5931273 0.4025391 0.8659932 0.006103694 0.4999848 0.6126591 -0.7067477 0.3537095 0.6126591 -0.7067477 0.3537095 0.4922941 0.7177954 0.4922941 0.4922941 0.7177954 0.4922941 0.7070834 0 0.7070834 0.7070834 0 0.7070834 0.5692617 0.5931273 0.5692617 0.5692617 0.5931273 0.5692617 0.8659932 0.006103694 0.4999848 0.7070834 0.006103694 0.7070834 0.5002289 -0.7067477 0.5002289 0.5002289 -0.7067477 0.5002289 0.3480941 0.7177954 0.6029542 0.4999848 0 0.8660237 0.4999848 0 0.8660237 0.4025391 0.5931273 0.6972259 0.4999848 0.006103694 0.8659932 0.4999848 0.006103694 0.8659932 0.3537095 -0.7067477 0.6126591 0.3480941 0.7177954 0.6029542 0.1801813 0.7177954 0.6725059 0.2587969 0 0.9659109 0.2587969 0 0.9659109 0.2083498 0.5931273 0.7776421 0.2083498 0.5931273 0.7776421 0.2587969 0.006103694 0.9658803 0.2587969 0.006103694 0.9658803 0.3537095 -0.7067477 0.6126591 0.1830805 -0.7067477 0.68334 0.1801813 0.7177954 0.6725059 0 0.7177954 0.6962187 0 0 1 0 0 1 0 0.5931273 0.8050783 0 0.5931273 0.8050783 0 0.006103694 0.9999695 0 -0.7067477 0.7074496 0 -0.7067477 0.7074496 -0.1801813 0.7177954 0.6725059 -0.1801813 0.7177954 0.6725059 -0.2587969 0 0.9659109 -0.2587969 0 0.9659109 -0.2083498 0.5931273 0.7776421 -0.2083498 0.5931273 0.7776421 -0.2587969 0.006103694 0.9658803 -0.2587969 0.006103694 0.9658803 -0.1830805 -0.7067477 0.68334 -0.3480941 0.7177954 0.6029542 -0.3480941 0.7177954 0.6029542 -0.4999848 0 0.8660237 -0.4999848 0 0.8660237 -0.4025391 0.5931273 0.6972259 -0.4025391 0.5931273 0.6972259 -0.4999848 0.006103694 0.8659932 -0.3537095 -0.7067477 0.6126591 -0.3537095 -0.7067477 0.6126591 -0.4922941 0.7177954 0.4922941 -0.4922941 0.7177954 0.4922941 -0.7070834 0 0.7070834 -0.7070834 0 0.7070834 -0.5692617 0.5931273 0.5692617 -0.5692617 0.5931273 0.5692617 -0.4999848 0.006103694 0.8659932 -0.7070834 0.006103694 0.7070834 -0.5002289 -0.7067477 0.5002289 -0.5002289 -0.7067477 0.5002289 -0.6029542 0.7177954 0.3480941 -0.8660237 0 0.4999848 -0.8660237 0 0.4999848 -0.6972259 0.5931273 0.4025391 -0.8659932 0.006103694 0.4999848 -0.8659932 0.006103694 0.4999848 -0.6126591 -0.7067477 0.3537095 -0.6029542 0.7177954 0.3480941 -0.6725059 0.7177954 0.1801813 -0.9659109 0 0.2587969 -0.9659109 0 0.2587969 -0.7776421 0.5931273 0.2083498 -0.7776421 0.5931273 0.2083498 -0.9658803 0.006103694 0.2587969 -0.9658803 0.006103694 0.2587969 -0.6126591 -0.7067477 0.3537095 -0.68334 -0.7067477 0.1830805 -0.6725059 0.7177954 0.1801813 -0.6962187 0.7177954 0 -0.9999695 0 0 -0.9999695 0 0 -0.8050783 0.5931273 0 -0.8050783 0.5931273 0 -0.9999695 0.006103694 0 -0.7074496 -0.7067477 0 -0.7074496 -0.7067477 0 -0.6725059 0.7177954 -0.1801813 -0.6725059 0.7177954 -0.1801813 -0.9659109 0 -0.2587969 -0.9659109 0 -0.2587969 -0.7776421 0.5931273 -0.2083498 -0.9658803 0.006103694 -0.2587969 -0.9658803 0.006103694 -0.2587969 -0.68334 -0.7067477 -0.1830805 -0.6029542 0.7177954 -0.3480941 -0.6029542 0.7177954 -0.3480941 -0.8660237 0 -0.4999848 -0.8660237 0 -0.4999848 -0.6972259 0.5931273 -0.4025391 -0.6972259 0.5931273 -0.4025391 -0.8659932 0.006103694 -0.4999848 -0.6126591 -0.7067477 -0.3537095 -0.6126591 -0.7067477 -0.3537095 -0.4922941 0.7177954 -0.4922941 -0.4922941 0.7177954 -0.4922941 -0.7070834 0 -0.7070834 -0.7070834 0 -0.7070834 -0.5692617 0.5931273 -0.5692617 -0.5692617 0.5931273 -0.5692617 -0.8659932 0.006103694 -0.4999848 -0.7070834 0.006103694 -0.7070834 -0.5002289 -0.7067477 -0.5002289 -0.5002289 -0.7067477 -0.5002289 -0.3480941 0.7177954 -0.6029542 -0.4999848 0 -0.8660237 -0.4999848 0 -0.8660237 -0.4025391 0.5931273 -0.6972259 -0.4999848 0.006103694 -0.8659932 -0.4999848 0.006103694 -0.8659932 -0.3537095 -0.7067477 -0.6126591 -0.3480941 0.7177954 -0.6029542 -0.1801813 0.7177954 -0.6725059 -0.2587969 0 -0.9659109 -0.2587969 0 -0.9659109 -0.2083498 0.5931273 -0.7776421 -0.2083498 0.5931273 -0.7776421 -0.2587969 0.006103694 -0.9658803 -0.2587969 0.006103694 -0.9658803 -0.3537095 -0.7067477 -0.6126591 -0.1830805 -0.7067477 -0.68334 -0.1801813 0.7177954 -0.6725059 0 0.7177954 -0.6962187 0 0 -1 0 0 -1 0 0.5931273 -0.8050783 0 0.5931273 -0.8050783 0 0.006103694 -0.9999695 0 -0.7067477 -0.7074496 0 -0.7067477 -0.7074496 0.1801813 0.7177954 -0.6725059 0.1801813 0.7177954 -0.6725059 0.2587969 0 -0.9659109 0.2587969 0 -0.9659109 0.2083498 0.5931273 -0.7776421 0.2083498 0.5931273 -0.7776421 0.2587969 0.006103694 -0.9658803 0.2587969 0.006103694 -0.9658803 0.1830805 -0.7067477 -0.68334 0.3480941 0.7177954 -0.6029542 0.3480941 0.7177954 -0.6029542 0.4999848 0 -0.8660237 0.4999848 0 -0.8660237 0.4025391 0.5931273 -0.6972259 0.4025391 0.5931273 -0.6972259 0.4999848 0.006103694 -0.8659932 0.3537095 -0.7067477 -0.6126591 0.3537095 -0.7067477 -0.6126591 0.4922941 0.7177954 -0.4922941 0.4922941 0.7177954 -0.4922941 0.7070834 0 -0.7070834 0.7070834 0 -0.7070834 0.5692617 0.5931273 -0.5692617 0.5692617 0.5931273 -0.5692617 0.4999848 0.006103694 -0.8659932 0.7070834 0.006103694 -0.7070834 0.5002289 -0.7067477 -0.5002289 0.5002289 -0.7067477 -0.5002289 0.6029542 0.7177954 -0.3480941 0.8660237 0 -0.4999848 0.8660237 0 -0.4999848 0.6972259 0.5931273 -0.4025391 0.8659932 0.006103694 -0.4999848 0.8659932 0.006103694 -0.4999848 0.6126591 -0.7067477 -0.3537095 0.6029542 0.7177954 -0.3480941 0.6725059 0.7177954 -0.1801813 0.9659109 0 -0.2587969 0.9659109 0 -0.2587969 0.7776421 0.5931273 -0.2083498 0.7776421 0.5931273 -0.2083498 0.9658803 0.006103694 -0.2587969 0.9658803 0.006103694 -0.2587969 0.6126591 -0.7067477 -0.3537095 0.68334 -0.7067477 -0.1830805 0.6725059 0.7177954 -0.1801813 0.9999695 0 0 0 0.9999695 0 0 1 0 0 1 0 0 -1 0 0 -1 0 0 -1 0 0 -0.6757103 0.7371441 0 -0.6757103 0.7371441 0 -0.6757103 0.7371441 0 0.9999695 0 0 1 0 0 0.9999695 0 0 1 0 0 1 0 0 1 0 0 0.9999695 0 0 1 0 0 0.9999695 0 0 1 0 0 1 0 0 0.9999695 0 0 0.9999695 0 0 0.9999695 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0.9999695 0 0 1 0 0 0.9999695 0 0 1 0 0 0.9999695 0 0 0.9999695 0 0 1 0 0 1 0 0 0.9999695 0 0 1 0 0 1 0 0 1 0 0 0.9999695 0 0 1 0 0 0.9999695 0 0 1 0 0 0.9999695 0 0 1 0 0 0.9999695 0 0 1 0 0 0.9999695 0 0 1 0 0 1 0 0 1 0 0 0.9999695 0 0 1 0 0 0.9999695 0 0 0 1 0 0 1 0 0 1 0 -0.6757103 0.7371441 0 0 1 0 0 1 0 -0.6757103 0.7371441 0 0 1 0 0 1 0 -0.6757103 0.7371441 0 0 1 0 -0.6757103 0.7371441 0 0 1 0 0 1 0 -0.6757103 0.7371441 0 0 1 0 0 1 0 -0.6757103 0.7371441 0 0 1 0 0 1 0 -0.6757103 0.7371441 0 -0.6757103 0.7371441 0 0 1 0 -0.6757103 0.7371441 0 -0.6757103 0.7371441 0 0 1 0 0 1 0 0 1 0 0 1 0 -0.6757103 0.7371441 0 0 1 0 0 1 0 -0.6757103 0.7371441 0 0 1 0 -0.6757103 0.7371441 0 0 1 0 -0.6757103 0.7371441 0 0 1 0 -0.6757103 0.7371441 0 0 1 0 -0.6757103 0.7371441 0 -0.6757103 0.7371441 0 -0.6757103 0.7371441 0 0 1 0 -0.6757103 0.7371441 0 -0.6757103 0.7371441 0 -0.6757103 0.7371441 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0.6757103 0.7371441 0 0.6757103 0.7371441 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0.6757103 0.7371441 0 0.6757103 0.7371441 0 0.6757103 0.7371441 0 0.6757103 0.7371441 0 0.6757103 0.7371441 0 0.6757103 0.7371441 0 0.6757103 0.7371441 0 0.6757103 0.7371441 0 0.6757103 0.7371441 0 0.6757103 0.7371441 0 0.6757103 0.7371441 0 0.6757103 0.7371441 0 0.6757103 0.7371441 0 0.6757103 0.7371441 0 0.6757103 0.7371441 0 0.6757103 0.7371441 0 0.6757103 0.7371441 0 0.6757103 0.7371441 0 0.6757103 0.7371441 0 0.6757103 0.7371441 0 0.6757103 0.7371441 0 0.6757103 0.7371441 0.6962187 0.7177954 0 0.7776421 0.5931273 0.2083498 0.9999695 0.006103694 0 0.68334 -0.7067477 0.1830805 0.7070834 0.006103694 0.7070834 0.4025391 0.5931273 0.6972259 0.1830805 -0.7067477 0.68334 0 0.7177954 0.6962187 0 0.006103694 0.9999695 -0.1830805 -0.7067477 0.68334 -0.7070834 0.006103694 0.7070834 -0.6972259 0.5931273 0.4025391 -0.68334 -0.7067477 0.1830805 -0.6962187 0.7177954 0 -0.9999695 0.006103694 0 -0.7776421 0.5931273 -0.2083498 -0.68334 -0.7067477 -0.1830805 -0.7070834 0.006103694 -0.7070834 -0.4025391 0.5931273 -0.6972259 -0.1830805 -0.7067477 -0.68334 0 0.7177954 -0.6962187 0 0.006103694 -0.9999695 0.1830805 -0.7067477 -0.68334 0.7070834 0.006103694 -0.7070834 0.6972259 0.5931273 -0.4025391 0.68334 -0.7067477 -0.1830805 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 + + + + + + + + + + 0.3819991 0.1617419 0.3564673 0.1617419 0.3564673 0.1362102 0.7292794 0.1219733 0.7619407 0.1219732 0.7619407 0.1272917 0.3813945 0.07066529 0.3813945 0.09623175 0.3558281 0.09623175 0.6887959 0.07109808 0.7144529 0.07109808 0.7144529 0.09675514 0.6861039 0.09626013 0.6861039 0.07074493 0.7116191 0.07074493 0.3564673 0.1617419 0.330936 0.1617419 0.330936 0.1362102 0.7619407 0.1219732 0.794602 0.1219732 0.794602 0.1272916 0.3558281 0.09623175 0.3302617 0.09623175 0.3302617 0.07066529 0.7144529 0.09675514 0.7144529 0.07109808 0.7401099 0.07109808 0.7116191 0.07074493 0.7371343 0.07074493 0.7371343 0.09626013 0.330936 0.1617419 0.3054045 0.1617419 0.3054045 0.1362102 0.794602 0.1219732 0.8272631 0.1219731 0.8272632 0.1272915 0.3302617 0.09623175 0.3046953 0.09623175 0.3046953 0.07066529 0.7401099 0.09675514 0.7401099 0.07109808 0.7657669 0.07109808 0.7371343 0.07074493 0.7626495 0.07074493 0.7626495 0.09626013 0.3054045 0.1362102 0.3054045 0.1617419 0.2798728 0.1617419 0.8272631 0.1219731 0.8599242 0.1219729 0.8599242 0.1272913 0.3046953 0.07066529 0.3046953 0.09623175 0.2791289 0.09623175 0.7657669 0.07109808 0.7914239 0.07109808 0.7914239 0.09675514 0.7626495 0.09626013 0.7626495 0.07074493 0.7881646 0.07074493 0.2798728 0.1362102 0.2798728 0.1617419 0.2543411 0.1617419 0.8599242 0.1219729 0.8925849 0.1219726 0.892585 0.127291 0.2791289 0.09623175 0.2535625 0.09623175 0.2535625 0.07066529 0.7914239 0.07109808 0.8170809 0.07109808 0.8170809 0.09675514 0.7881646 0.09626013 0.7881646 0.07074493 0.8136797 0.07074493 0.2543411 0.1362102 0.2543411 0.1617419 0.2288097 0.1617419 0.8925849 0.1219726 0.9252457 0.1219723 0.9252458 0.1272906 0.2535625 0.09623175 0.227996 0.09623175 0.227996 0.07066529 0.8170809 0.09675514 0.8170809 0.07109808 0.8427379 0.07109808 0.8136797 0.07074493 0.839195 0.07074493 0.839195 0.09626013 0.8415674 0.1617419 0.8160358 0.1617419 0.8160358 0.1362102 0.1413546 0.1219764 0.1740181 0.1219756 0.1740182 0.1272944 0.8415897 0.09623175 0.8160232 0.09623175 0.8160232 0.07066529 0.2269698 0.07109808 0.2526268 0.07109808 0.2526268 0.09675514 0.226831 0.09626013 0.226831 0.07074493 0.2523462 0.07074493 0.8160358 0.1617419 0.7905042 0.1617419 0.7905042 0.1362102 0.1740181 0.1219756 0.2066815 0.1219749 0.2066816 0.1272937 0.8160232 0.09623175 0.7904569 0.09623175 0.7904569 0.07066529 0.2526268 0.09675514 0.2526268 0.07109808 0.2782838 0.07109808 0.2523462 0.07074493 0.2778614 0.07074493 0.2778614 0.09626013 0.7905042 0.1617419 0.7649723 0.1617419 0.7649723 0.1362102 0.2066815 0.1219749 0.2393448 0.1219744 0.2393449 0.1272931 0.7904569 0.09623175 0.7648904 0.09623175 0.7648904 0.07066529 0.2782838 0.09675514 0.2782838 0.07109808 0.3039408 0.07109808 0.2778614 0.07074493 0.3033765 0.07074493 0.3033765 0.09626013 0.7649723 0.1362102 0.7649723 0.1617419 0.7394411 0.1617419 0.2393448 0.1219744 0.272008 0.1219739 0.2720081 0.1272926 0.7648904 0.07066529 0.7648904 0.09623175 0.739324 0.09623175 0.3039408 0.07109808 0.3295978 0.07109808 0.3295978 0.09675514 0.3033765 0.09626013 0.3033765 0.07074493 0.3288917 0.07074493 0.7394411 0.1362102 0.7394411 0.1617419 0.7139095 0.1617419 0.272008 0.1219739 0.3046709 0.1219735 0.304671 0.1272923 0.739324 0.09623175 0.7137577 0.09623175 0.7137577 0.07066529 0.3295978 0.07109808 0.3552548 0.07109808 0.3552548 0.09675514 0.3288917 0.09626013 0.3288917 0.07074493 0.3544068 0.07074493 0.7139095 0.1362102 0.7139095 0.1617419 0.6883778 0.1617419 0.3046709 0.1219735 0.3373338 0.1219733 0.3373339 0.127292 0.7137577 0.09623175 0.6881914 0.09623175 0.6881914 0.07066529 0.3552548 0.09675514 0.3552548 0.07109808 0.3809118 0.07109808 0.3544068 0.07074493 0.379922 0.07074493 0.379922 0.09626013 0.6883778 0.1617419 0.6628463 0.1617419 0.6628463 0.1362102 0.3373338 0.1219733 0.3699966 0.1219731 0.3699966 0.1272917 0.6881914 0.07066529 0.6881914 0.09623175 0.6626249 0.09623175 0.3809118 0.07109808 0.4065688 0.07109808 0.4065688 0.09675514 0.379922 0.09626013 0.379922 0.07074493 0.4054372 0.07074493 0.6628463 0.1617419 0.6373147 0.1617419 0.6373147 0.1362102 0.3699966 0.1219731 0.4026593 0.1219729 0.4026594 0.1272916 0.6626249 0.09623175 0.6370586 0.09623175 0.6370586 0.07066529 0.4065688 0.09675514 0.4065688 0.07109808 0.4322258 0.07109808 0.4054372 0.07074493 0.4309523 0.07074493 0.4309523 0.09626013 0.6373147 0.1617419 0.6117832 0.1617419 0.6117832 0.1362102 0.4026593 0.1219729 0.4353219 0.1219729 0.4353219 0.1272915 0.6370586 0.09623175 0.6114922 0.09623175 0.6114922 0.07066529 0.4322258 0.09675514 0.4322258 0.07109808 0.4578828 0.07109808 0.4309523 0.07074493 0.4564675 0.07074493 0.4564675 0.09626013 0.6117832 0.1362102 0.6117832 0.1617419 0.5862517 0.1617419 0.4353219 0.1219729 0.4679843 0.1219729 0.4679843 0.1272915 0.6114922 0.07066529 0.6114922 0.09623175 0.5859257 0.09623175 0.4578828 0.07109808 0.4835398 0.07109808 0.4835398 0.09675514 0.4564675 0.09626013 0.4564675 0.07074493 0.4819826 0.07074493 0.5862517 0.1362102 0.5862517 0.1617419 0.56072 0.1617419 0.4679843 0.1219729 0.5006466 0.1219729 0.5006466 0.1272915 0.5859257 0.09623175 0.5603592 0.09623175 0.5603592 0.07066529 0.4835398 0.07109808 0.5091968 0.07109808 0.5091968 0.09675514 0.4819826 0.09626013 0.4819826 0.07074493 0.5074979 0.07074493 0.56072 0.1362102 0.56072 0.1617419 0.5351884 0.1617419 0.5006466 0.1219729 0.5333088 0.1219729 0.5333088 0.1272915 0.5603592 0.09623175 0.5347929 0.09623175 0.5347929 0.07066529 0.5091968 0.09675514 0.5091968 0.07109808 0.5348538 0.07109808 0.5074979 0.07074493 0.533013 0.07074493 0.533013 0.09626013 0.5351884 0.1617419 0.5096572 0.1617419 0.5096572 0.1362102 0.5333088 0.1219729 0.5659708 0.121973 0.5659708 0.1272915 0.5347929 0.09623175 0.5092265 0.09623175 0.5092265 0.07066529 0.5348538 0.07109808 0.5605109 0.07109808 0.5605109 0.09675514 0.533013 0.09626013 0.533013 0.07074493 0.5585281 0.07074493 0.5096572 0.1617419 0.4841254 0.1617419 0.4841254 0.1362102 0.5659708 0.121973 0.5986328 0.1219731 0.5986328 0.1272916 0.5092265 0.09623175 0.4836601 0.09623175 0.4836601 0.07066529 0.5605109 0.09675514 0.5605109 0.07109808 0.5861679 0.07109808 0.5585281 0.07074493 0.5840433 0.07074493 0.5840433 0.09626013 0.4841254 0.1617419 0.4585937 0.1617419 0.4585937 0.1362102 0.5986328 0.1219731 0.6312947 0.1219732 0.6312947 0.1272917 0.4836601 0.09623175 0.4580937 0.09623175 0.4580937 0.07066529 0.5861679 0.09675514 0.5861679 0.07109808 0.6118249 0.07109808 0.5840433 0.07074493 0.6095585 0.07074493 0.6095585 0.09626013 0.4585937 0.1362102 0.4585937 0.1617419 0.4330623 0.1617419 0.6312947 0.1219732 0.6639564 0.1219732 0.6639564 0.1272917 0.4580937 0.07066529 0.4580937 0.09623175 0.4325273 0.09623175 0.6118249 0.07109808 0.6374819 0.07109808 0.6374819 0.09675514 0.6095585 0.09626013 0.6095585 0.07074493 0.6350737 0.07074493 0.4330623 0.1362102 0.4330623 0.1617419 0.4075309 0.1617419 0.6639564 0.1219732 0.696618 0.1219732 0.696618 0.1272917 0.4325273 0.09623175 0.4069609 0.09623175 0.4069609 0.07066529 0.6374819 0.07109808 0.6631389 0.07109808 0.6631389 0.09675514 0.6350737 0.09626013 0.6350737 0.07074493 0.6605889 0.07074493 0.4075309 0.1362102 0.4075309 0.1617419 0.3819991 0.1617419 0.696618 0.1219732 0.7292794 0.1219733 0.7292794 0.1272917 0.4069609 0.09623175 0.3813945 0.09623175 0.3813945 0.07066529 0.6631389 0.09675514 0.6631389 0.07109808 0.6887959 0.07109808 0.6605889 0.07074493 0.6861039 0.07074493 0.6861039 0.09626013 0.3995902 0.09744018 0.3742105 0.09744018 0.3742105 0.07206052 0.0574823 0.6471351 0.4438057 0.5962749 0.2946904 0.9562707 0.651207 0.3524509 0.6863479 0.619374 0.899939 0.4554796 0.4249699 0.09744018 0.3995902 0.09744018 0.3995902 0.07206052 0.4503495 0.09744018 0.4249699 0.09744018 0.4249699 0.07206052 0.4503495 0.09744018 0.4503495 0.07206052 0.4757291 0.07206052 0.4757291 0.09744018 0.4757291 0.07206052 0.5011088 0.07206052 0.5518681 0.09744018 0.5264884 0.09744018 0.5264884 0.07206052 0.5011088 0.09744018 0.5011088 0.07206052 0.5264884 0.07206052 0.6026274 0.09744018 0.5772477 0.09744018 0.5772477 0.07206052 0.5772477 0.09744018 0.5518681 0.09744018 0.5518681 0.07206052 0.6026274 0.09744018 0.6026274 0.07206052 0.628007 0.07206052 0.628007 0.09744018 0.628007 0.07206052 0.6533865 0.07206052 0.6533865 0.09744018 0.6533865 0.07206052 0.6787661 0.07206052 0.7295252 0.09744018 0.7041456 0.09744018 0.7041456 0.07206052 0.7041456 0.09744018 0.6787661 0.09744018 0.6787661 0.07206052 0.7549047 0.09744018 0.7295252 0.09744018 0.7295252 0.07206052 0.7549047 0.09744018 0.7549047 0.07206052 0.7802842 0.07206052 0.7802842 0.09744018 0.7802842 0.07206052 0.8056637 0.07206052 0.8056637 0.09744018 0.8056637 0.07206052 0.8310433 0.07206052 0.2473123 0.09744018 0.2219326 0.09744018 0.2219326 0.07206052 0.2726919 0.09744018 0.2473123 0.09744018 0.2473123 0.07206052 0.2980716 0.09744018 0.2726919 0.09744018 0.2726919 0.07206052 0.2980716 0.09744018 0.2980716 0.07206052 0.3234512 0.07206052 0.3234512 0.09744018 0.3234512 0.07206052 0.3488309 0.07206052 0.3742105 0.07206052 0.3742105 0.09744018 0.3488309 0.09744018 0.5917232 0.4960566 0.5917232 0.4960566 0.6022254 0.5352516 0.899939 0.4960572 0.899939 0.4960572 0.899939 0.4554796 0.8053147 0.3321624 0.8053147 0.3321624 0.7661201 0.3216602 0.5917232 0.4960566 0.5917232 0.4960566 0.6022254 0.5352516 0.869148 0.5703927 0.869148 0.5703927 0.8894367 0.5352519 0.7661198 0.6298761 0.7661198 0.6298761 0.8053144 0.619374 0.6512069 0.5990853 0.6512069 0.5990853 0.6863479 0.619374 0.8894367 0.5352519 0.8894367 0.5352519 0.899939 0.4960572 0.8053144 0.619374 0.8053144 0.619374 0.8404555 0.5990853 0.8404555 0.5990853 0.8404555 0.5990853 0.869148 0.5703927 0.7255429 0.3216602 0.7255429 0.3216602 0.6863481 0.3321623 0.651207 0.3524509 0.651207 0.3524509 0.6225144 0.3811434 0.8691482 0.3811439 0.8691482 0.3811439 0.8404557 0.3524512 0.5917232 0.4554793 0.5917232 0.4554793 0.5917232 0.4960566 0.6022255 0.4162846 0.6022255 0.4162846 0.5917232 0.4554793 0.6225143 0.5703926 0.6225143 0.5703926 0.6512069 0.5990853 0.8404557 0.3524512 0.8404557 0.3524512 0.8053147 0.3321624 0.899939 0.4554796 0.899939 0.4554796 0.889437 0.4162849 0.6863481 0.3321623 0.6863481 0.3321623 0.651207 0.3524509 0.889437 0.4162849 0.889437 0.4162849 0.8691482 0.3811439 0.6225144 0.3811434 0.6225144 0.3811434 0.6022255 0.4162846 0.6863479 0.619374 0.6863479 0.619374 0.7255425 0.6298761 0.7255425 0.6298761 0.7255425 0.6298761 0.7661198 0.6298761 0.7661201 0.3216602 0.7661201 0.3216602 0.7255429 0.3216602 0.6022254 0.5352516 0.6022254 0.5352516 0.6225143 0.5703926 0.6225144 0.3811434 0.6225144 0.3811434 0.6022255 0.4162846 0.6863479 0.619374 0.6863479 0.619374 0.7255425 0.6298761 0.8404557 0.3524512 0.8404557 0.3524512 0.8053147 0.3321624 0.899939 0.4960572 0.899939 0.4960572 0.899939 0.4554796 0.6225144 0.3811434 0.6225144 0.3811434 0.6022255 0.4162846 0.7255429 0.3216602 0.7255429 0.3216602 0.6863481 0.3321623 0.7661201 0.3216602 0.7661201 0.3216602 0.7255429 0.3216602 0.7661198 0.6298761 0.7661198 0.6298761 0.8053144 0.619374 0.6225143 0.5703926 0.6225143 0.5703926 0.6512069 0.5990853 0.6022254 0.5352516 0.6022254 0.5352516 0.6225143 0.5703926 0.7255425 0.6298761 0.7255425 0.6298761 0.7661198 0.6298761 0.8404555 0.5990853 0.8404555 0.5990853 0.869148 0.5703927 0.899939 0.4554796 0.899939 0.4554796 0.889437 0.4162849 0.651207 0.3524509 0.651207 0.3524509 0.6225144 0.3811434 0.6863481 0.3321623 0.6863481 0.3321623 0.651207 0.3524509 0.6512069 0.5990853 0.6512069 0.5990853 0.6863479 0.619374 0.8053144 0.619374 0.8053144 0.619374 0.8404555 0.5990853 0.8691482 0.3811439 0.8691482 0.3811439 0.8404557 0.3524512 0.8894367 0.5352519 0.8894367 0.5352519 0.899939 0.4960572 0.869148 0.5703927 0.869148 0.5703927 0.8894367 0.5352519 0.6022255 0.4162846 0.6022255 0.4162846 0.5917232 0.4554793 0.889437 0.4162849 0.889437 0.4162849 0.8691482 0.3811439 0.8053147 0.3321624 0.8053147 0.3321624 0.7661201 0.3216602 0.5917232 0.4554793 0.5917232 0.4554793 0.5917232 0.4960566 0.6022254 0.5352516 0.6022254 0.5352516 0.6225143 0.5703926 0.7255429 0.3216602 0.7255429 0.3216602 0.6863481 0.3321623 0.7661201 0.3216602 0.7661201 0.3216602 0.7255429 0.3216602 0.7661198 0.6298761 0.7661198 0.6298761 0.8053144 0.619374 0.6225143 0.5703926 0.6225143 0.5703926 0.6512069 0.5990853 0.6022254 0.5352516 0.6022254 0.5352516 0.6225143 0.5703926 0.7255425 0.6298761 0.7255425 0.6298761 0.7661198 0.6298761 0.8404555 0.5990853 0.8404555 0.5990853 0.869148 0.5703927 0.899939 0.4554796 0.899939 0.4554796 0.889437 0.4162849 0.651207 0.3524509 0.651207 0.3524509 0.6225144 0.3811434 0.6863481 0.3321623 0.6863481 0.3321623 0.651207 0.3524509 0.6512069 0.5990853 0.6512069 0.5990853 0.6863479 0.619374 0.8053144 0.619374 0.8053144 0.619374 0.8404555 0.5990853 0.8691482 0.3811439 0.8691482 0.3811439 0.8404557 0.3524512 0.8894367 0.5352519 0.8894367 0.5352519 0.899939 0.4960572 0.869148 0.5703927 0.869148 0.5703927 0.8894367 0.5352519 0.6022255 0.4162846 0.6022255 0.4162846 0.5917232 0.4554793 0.889437 0.4162849 0.889437 0.4162849 0.8691482 0.3811439 0.8053147 0.3321624 0.8053147 0.3321624 0.7661201 0.3216602 0.5917232 0.4554793 0.5917232 0.4554793 0.5917232 0.4960566 0.5917232 0.4960566 0.5917232 0.4960566 0.6022254 0.5352516 0.6863479 0.619374 0.6863479 0.619374 0.7255425 0.6298761 0.8404557 0.3524512 0.8404557 0.3524512 0.8053147 0.3321624 0.899939 0.4960572 0.899939 0.4960572 0.899939 0.4554796 0.651207 0.3524509 0.651207 0.3524509 0.6225144 0.3811434 0.7255425 0.6298761 0.7255425 0.6298761 0.7661198 0.6298761 0.8404555 0.5990853 0.8404555 0.5990853 0.869148 0.5703927 0.899939 0.4554796 0.899939 0.4554796 0.889437 0.4162849 0.651207 0.3524509 0.651207 0.3524509 0.6225144 0.3811434 0.6863481 0.3321623 0.6863481 0.3321623 0.651207 0.3524509 0.6512069 0.5990853 0.6512069 0.5990853 0.6863479 0.619374 0.8053144 0.619374 0.8053144 0.619374 0.8404555 0.5990853 0.8691482 0.3811439 0.8691482 0.3811439 0.8404557 0.3524512 0.8894367 0.5352519 0.8894367 0.5352519 0.899939 0.4960572 0.869148 0.5703927 0.869148 0.5703927 0.8894367 0.5352519 0.6022255 0.4162846 0.6022255 0.4162846 0.5917232 0.4554793 0.889437 0.4162849 0.889437 0.4162849 0.8691482 0.3811439 0.8053147 0.3321624 0.8053147 0.3321624 0.7661201 0.3216602 0.5917232 0.4554793 0.5917232 0.4554793 0.5917232 0.4960566 0.5917232 0.4960566 0.5917232 0.4960566 0.6022254 0.5352516 0.6863479 0.619374 0.6863479 0.619374 0.7255425 0.6298761 0.8404557 0.3524512 0.8404557 0.3524512 0.8053147 0.3321624 0.899939 0.4960572 0.899939 0.4960572 0.899939 0.4554796 0.6225144 0.3811434 0.6225144 0.3811434 0.6022255 0.4162846 0.7255429 0.3216602 0.7255429 0.3216602 0.6863481 0.3321623 0.7661201 0.3216602 0.7661201 0.3216602 0.7255429 0.3216602 0.7661198 0.6298761 0.7661198 0.6298761 0.8053144 0.619374 0.6225143 0.5703926 0.6225143 0.5703926 0.6512069 0.5990853 0.651207 0.3524509 0.899939 0.4554796 0.6863479 0.619374 0.6863481 0.3321623 0.6863481 0.3321623 0.651207 0.3524509 0.6512069 0.5990853 0.6512069 0.5990853 0.6863479 0.619374 0.8053144 0.619374 0.8053144 0.619374 0.8404555 0.5990853 0.8691482 0.3811439 0.8691482 0.3811439 0.8404557 0.3524512 0.8894367 0.5352519 0.8894367 0.5352519 0.899939 0.4960572 0.869148 0.5703927 0.869148 0.5703927 0.8894367 0.5352519 0.6022255 0.4162846 0.6022255 0.4162846 0.5917232 0.4554793 0.889437 0.4162849 0.889437 0.4162849 0.8691482 0.3811439 0.8053147 0.3321624 0.8053147 0.3321624 0.7661201 0.3216602 0.5917232 0.4554793 0.5917232 0.4554793 0.5917232 0.4960566 0.5917232 0.4960566 0.5917232 0.4960566 0.6022254 0.5352516 0.6863479 0.619374 0.6863479 0.619374 0.7255425 0.6298761 0.8404557 0.3524512 0.8404557 0.3524512 0.8053147 0.3321624 0.899939 0.4960572 0.899939 0.4960572 0.899939 0.4554796 0.6225144 0.3811434 0.6225144 0.3811434 0.6022255 0.4162846 0.7255429 0.3216602 0.7255429 0.3216602 0.6863481 0.3321623 0.7661201 0.3216602 0.7661201 0.3216602 0.7255429 0.3216602 0.7661198 0.6298761 0.7661198 0.6298761 0.8053144 0.619374 0.6225143 0.5703926 0.6225143 0.5703926 0.6512069 0.5990853 0.6022254 0.5352516 0.6022254 0.5352516 0.6225143 0.5703926 0.7255425 0.6298761 0.7255425 0.6298761 0.7661198 0.6298761 0.8404555 0.5990853 0.8404555 0.5990853 0.869148 0.5703927 0.899939 0.4554796 0.899939 0.4554796 0.889437 0.4162849 0.3819991 0.1362102 0.3819991 0.1617419 0.3564673 0.1362102 0.7292794 0.1272917 0.7292794 0.1219733 0.7619407 0.1272917 0.3558281 0.07066529 0.3813945 0.07066529 0.3558281 0.09623175 0.6887959 0.09675514 0.6887959 0.07109808 0.7144529 0.09675514 0.7116191 0.09626013 0.6861039 0.09626013 0.7116191 0.07074493 0.3564673 0.1362102 0.3564673 0.1617419 0.330936 0.1362102 0.7619407 0.1272917 0.7619407 0.1219732 0.794602 0.1272916 0.3558281 0.07066529 0.3558281 0.09623175 0.3302617 0.07066529 0.7401099 0.09675514 0.7144529 0.09675514 0.7401099 0.07109808 0.7116191 0.09626013 0.7116191 0.07074493 0.7371343 0.09626013 0.330936 0.1362102 0.330936 0.1617419 0.3054045 0.1362102 0.794602 0.1272916 0.794602 0.1219732 0.8272632 0.1272915 0.3302617 0.07066529 0.3302617 0.09623175 0.3046953 0.07066529 0.7657669 0.09675514 0.7401099 0.09675514 0.7657669 0.07109808 0.7371343 0.09626013 0.7371343 0.07074493 0.7626495 0.09626013 0.2798728 0.1362102 0.3054045 0.1362102 0.2798728 0.1617419 0.8272632 0.1272915 0.8272631 0.1219731 0.8599242 0.1272913 0.2791289 0.07066529 0.3046953 0.07066529 0.2791289 0.09623175 0.7657669 0.09675514 0.7657669 0.07109808 0.7914239 0.09675514 0.7881646 0.09626013 0.7626495 0.09626013 0.7881646 0.07074493 0.2543411 0.1362102 0.2798728 0.1362102 0.2543411 0.1617419 0.8599242 0.1272913 0.8599242 0.1219729 0.892585 0.127291 0.2791289 0.07066529 0.2791289 0.09623175 0.2535625 0.07066529 0.7914239 0.09675514 0.7914239 0.07109808 0.8170809 0.09675514 0.8136797 0.09626013 0.7881646 0.09626013 0.8136797 0.07074493 0.2288097 0.1362102 0.2543411 0.1362102 0.2288097 0.1617419 0.892585 0.127291 0.8925849 0.1219726 0.9252458 0.1272906 0.2535625 0.07066529 0.2535625 0.09623175 0.227996 0.07066529 0.8427379 0.09675514 0.8170809 0.09675514 0.8427379 0.07109808 0.8136797 0.09626013 0.8136797 0.07074493 0.839195 0.09626013 0.8415674 0.1362102 0.8415674 0.1617419 0.8160358 0.1362102 0.1413547 0.1272951 0.1413546 0.1219764 0.1740182 0.1272944 0.8415897 0.07066529 0.8415897 0.09623175 0.8160232 0.07066529 0.2269698 0.09675514 0.2269698 0.07109808 0.2526268 0.09675514 0.2523462 0.09626013 0.226831 0.09626013 0.2523462 0.07074493 0.8160358 0.1362102 0.8160358 0.1617419 0.7905042 0.1362102 0.1740182 0.1272944 0.1740181 0.1219756 0.2066816 0.1272937 0.8160232 0.07066529 0.8160232 0.09623175 0.7904569 0.07066529 0.2782838 0.09675514 0.2526268 0.09675514 0.2782838 0.07109808 0.2523462 0.09626013 0.2523462 0.07074493 0.2778614 0.09626013 0.7905042 0.1362102 0.7905042 0.1617419 0.7649723 0.1362102 0.2066816 0.1272937 0.2066815 0.1219749 0.2393449 0.1272931 0.7904569 0.07066529 0.7904569 0.09623175 0.7648904 0.07066529 0.3039408 0.09675514 0.2782838 0.09675514 0.3039408 0.07109808 0.2778614 0.09626013 0.2778614 0.07074493 0.3033765 0.09626013 0.7394411 0.1362102 0.7649723 0.1362102 0.7394411 0.1617419 0.2393449 0.1272931 0.2393448 0.1219744 0.2720081 0.1272926 0.739324 0.07066529 0.7648904 0.07066529 0.739324 0.09623175 0.3039408 0.09675514 0.3039408 0.07109808 0.3295978 0.09675514 0.3288917 0.09626013 0.3033765 0.09626013 0.3288917 0.07074493 0.7139095 0.1362102 0.7394411 0.1362102 0.7139095 0.1617419 0.2720081 0.1272926 0.272008 0.1219739 0.304671 0.1272923 0.739324 0.07066529 0.739324 0.09623175 0.7137577 0.07066529 0.3295978 0.09675514 0.3295978 0.07109808 0.3552548 0.09675514 0.3544068 0.09626013 0.3288917 0.09626013 0.3544068 0.07074493 0.6883778 0.1362102 0.7139095 0.1362102 0.6883778 0.1617419 0.304671 0.1272923 0.3046709 0.1219735 0.3373339 0.127292 0.7137577 0.07066529 0.7137577 0.09623175 0.6881914 0.07066529 0.3809118 0.09675514 0.3552548 0.09675514 0.3809118 0.07109808 0.3544068 0.09626013 0.3544068 0.07074493 0.379922 0.09626013 0.6883778 0.1362102 0.6883778 0.1617419 0.6628463 0.1362102 0.3373339 0.127292 0.3373338 0.1219733 0.3699966 0.1272917 0.6626249 0.07066529 0.6881914 0.07066529 0.6626249 0.09623175 0.3809118 0.09675514 0.3809118 0.07109808 0.4065688 0.09675514 0.4054372 0.09626013 0.379922 0.09626013 0.4054372 0.07074493 0.6628463 0.1362102 0.6628463 0.1617419 0.6373147 0.1362102 0.3699966 0.1272917 0.3699966 0.1219731 0.4026594 0.1272916 0.6626249 0.07066529 0.6626249 0.09623175 0.6370586 0.07066529 0.4322258 0.09675514 0.4065688 0.09675514 0.4322258 0.07109808 0.4054372 0.09626013 0.4054372 0.07074493 0.4309523 0.09626013 0.6373147 0.1362102 0.6373147 0.1617419 0.6117832 0.1362102 0.4026594 0.1272916 0.4026593 0.1219729 0.4353219 0.1272915 0.6370586 0.07066529 0.6370586 0.09623175 0.6114922 0.07066529 0.4578828 0.09675514 0.4322258 0.09675514 0.4578828 0.07109808 0.4309523 0.09626013 0.4309523 0.07074493 0.4564675 0.09626013 0.5862517 0.1362102 0.6117832 0.1362102 0.5862517 0.1617419 0.4353219 0.1272915 0.4353219 0.1219729 0.4679843 0.1272915 0.5859257 0.07066529 0.6114922 0.07066529 0.5859257 0.09623175 0.4578828 0.09675514 0.4578828 0.07109808 0.4835398 0.09675514 0.4819826 0.09626013 0.4564675 0.09626013 0.4819826 0.07074493 0.56072 0.1362102 0.5862517 0.1362102 0.56072 0.1617419 0.4679843 0.1272915 0.4679843 0.1219729 0.5006466 0.1272915 0.5859257 0.07066529 0.5859257 0.09623175 0.5603592 0.07066529 0.4835398 0.09675514 0.4835398 0.07109808 0.5091968 0.09675514 0.5074979 0.09626013 0.4819826 0.09626013 0.5074979 0.07074493 0.5351884 0.1362102 0.56072 0.1362102 0.5351884 0.1617419 0.5006466 0.1272915 0.5006466 0.1219729 0.5333088 0.1272915 0.5603592 0.07066529 0.5603592 0.09623175 0.5347929 0.07066529 0.5348538 0.09675514 0.5091968 0.09675514 0.5348538 0.07109808 0.5074979 0.09626013 0.5074979 0.07074493 0.533013 0.09626013 0.5351884 0.1362102 0.5351884 0.1617419 0.5096572 0.1362102 0.5333088 0.1272915 0.5333088 0.1219729 0.5659708 0.1272915 0.5347929 0.07066529 0.5347929 0.09623175 0.5092265 0.07066529 0.5348538 0.09675514 0.5348538 0.07109808 0.5605109 0.09675514 0.5585281 0.09626013 0.533013 0.09626013 0.5585281 0.07074493 0.5096572 0.1362102 0.5096572 0.1617419 0.4841254 0.1362102 0.5659708 0.1272915 0.5659708 0.121973 0.5986328 0.1272916 0.5092265 0.07066529 0.5092265 0.09623175 0.4836601 0.07066529 0.5861679 0.09675514 0.5605109 0.09675514 0.5861679 0.07109808 0.5585281 0.09626013 0.5585281 0.07074493 0.5840433 0.09626013 0.4841254 0.1362102 0.4841254 0.1617419 0.4585937 0.1362102 0.5986328 0.1272916 0.5986328 0.1219731 0.6312947 0.1272917 0.4836601 0.07066529 0.4836601 0.09623175 0.4580937 0.07066529 0.6118249 0.09675514 0.5861679 0.09675514 0.6118249 0.07109808 0.5840433 0.09626013 0.5840433 0.07074493 0.6095585 0.09626013 0.4330623 0.1362102 0.4585937 0.1362102 0.4330623 0.1617419 0.6312947 0.1272917 0.6312947 0.1219732 0.6639564 0.1272917 0.4325273 0.07066529 0.4580937 0.07066529 0.4325273 0.09623175 0.6118249 0.09675514 0.6118249 0.07109808 0.6374819 0.09675514 0.6350737 0.09626013 0.6095585 0.09626013 0.6350737 0.07074493 0.4075309 0.1362102 0.4330623 0.1362102 0.4075309 0.1617419 0.6639564 0.1272917 0.6639564 0.1219732 0.696618 0.1272917 0.4325273 0.07066529 0.4325273 0.09623175 0.4069609 0.07066529 0.6374819 0.09675514 0.6374819 0.07109808 0.6631389 0.09675514 0.6605889 0.09626013 0.6350737 0.09626013 0.6605889 0.07074493 0.3819991 0.1362102 0.4075309 0.1362102 0.3819991 0.1617419 0.696618 0.1272917 0.696618 0.1219732 0.7292794 0.1272917 0.4069609 0.07066529 0.4069609 0.09623175 0.3813945 0.07066529 0.6887959 0.09675514 0.6631389 0.09675514 0.6887959 0.07109808 0.6605889 0.09626013 0.6605889 0.07074493 0.6861039 0.09626013 0.3995902 0.07206052 0.3995902 0.09744018 0.3742105 0.07206052 0.04228228 0.7625911 0.04228222 0.7038627 0.0574823 0.6471351 0.08684664 0.8701789 0.05748236 0.8193187 0.04228228 0.7625911 0.1792343 0.9410706 0.1283738 0.9117062 0.08684664 0.8701789 0.2946904 0.9562707 0.2359619 0.9562707 0.1792343 0.9410706 0.4731699 0.8193185 0.351418 0.9410706 0.2946904 0.9562707 0.4731699 0.8193185 0.4438055 0.8701789 0.4022783 0.9117064 0.48837 0.7038625 0.48837 0.7625908 0.4731699 0.8193185 0.4438057 0.5962749 0.4731699 0.647135 0.48837 0.7038625 0.3514181 0.5253832 0.4022786 0.5547476 0.4438057 0.5962749 0.2359617 0.5101831 0.2946906 0.5101831 0.3514181 0.5253832 0.0574823 0.6471351 0.1792345 0.525383 0.2359617 0.5101831 0.0574823 0.6471351 0.08684653 0.5962749 0.1283739 0.5547474 0.08684664 0.8701789 0.04228228 0.7625911 0.0574823 0.6471351 0.2946904 0.9562707 0.1792343 0.9410706 0.08684664 0.8701789 0.4731699 0.8193185 0.4022783 0.9117064 0.351418 0.9410706 0.4438057 0.5962749 0.48837 0.7038625 0.4731699 0.8193185 0.2359617 0.5101831 0.3514181 0.5253832 0.4438057 0.5962749 0.0574823 0.6471351 0.1283739 0.5547474 0.1792345 0.525383 0.2946904 0.9562707 0.08684664 0.8701789 0.0574823 0.6471351 0.4438057 0.5962749 0.4731699 0.8193185 0.2946904 0.9562707 0.0574823 0.6471351 0.2359617 0.5101831 0.4438057 0.5962749 0.7255429 0.3216602 0.6863481 0.3321623 0.651207 0.3524509 0.899939 0.4554796 0.7661201 0.3216602 0.7255429 0.3216602 0.8691482 0.3811439 0.8404557 0.3524512 0.8053147 0.3321624 0.899939 0.4554796 0.889437 0.4162849 0.8691482 0.3811439 0.8894367 0.5352519 0.899939 0.4960572 0.899939 0.4554796 0.899939 0.4554796 0.869148 0.5703927 0.8894367 0.5352519 0.7661198 0.6298761 0.8053144 0.619374 0.8404555 0.5990853 0.6863479 0.619374 0.7255425 0.6298761 0.7661198 0.6298761 0.6225143 0.5703926 0.6512069 0.5990853 0.6863479 0.619374 0.5917232 0.4960566 0.6022254 0.5352516 0.6225143 0.5703926 0.6022255 0.4162846 0.5917232 0.4554793 0.5917232 0.4960566 0.5917232 0.4960566 0.6225144 0.3811434 0.6022255 0.4162846 0.899939 0.4554796 0.7255429 0.3216602 0.651207 0.3524509 0.899939 0.4554796 0.8691482 0.3811439 0.8053147 0.3321624 0.8404555 0.5990853 0.869148 0.5703927 0.899939 0.4554796 0.6863479 0.619374 0.7661198 0.6298761 0.8404555 0.5990853 0.5917232 0.4960566 0.6225143 0.5703926 0.6863479 0.619374 0.651207 0.3524509 0.6225144 0.3811434 0.5917232 0.4960566 0.899939 0.4554796 0.8053147 0.3321624 0.7661201 0.3216602 0.6863479 0.619374 0.8404555 0.5990853 0.899939 0.4554796 0.651207 0.3524509 0.5917232 0.4960566 0.6863479 0.619374 0.4249699 0.07206052 0.4249699 0.09744018 0.3995902 0.07206052 0.4503495 0.07206052 0.4503495 0.09744018 0.4249699 0.07206052 0.4757291 0.09744018 0.4503495 0.09744018 0.4757291 0.07206052 0.5011088 0.09744018 0.4757291 0.09744018 0.5011088 0.07206052 0.5518681 0.07206052 0.5518681 0.09744018 0.5264884 0.07206052 0.5264884 0.09744018 0.5011088 0.09744018 0.5264884 0.07206052 0.6026274 0.07206052 0.6026274 0.09744018 0.5772477 0.07206052 0.5772477 0.07206052 0.5772477 0.09744018 0.5518681 0.07206052 0.628007 0.09744018 0.6026274 0.09744018 0.628007 0.07206052 0.6533865 0.09744018 0.628007 0.09744018 0.6533865 0.07206052 0.6787661 0.09744018 0.6533865 0.09744018 0.6787661 0.07206052 0.7295252 0.07206052 0.7295252 0.09744018 0.7041456 0.07206052 0.7041456 0.07206052 0.7041456 0.09744018 0.6787661 0.07206052 0.7549047 0.07206052 0.7549047 0.09744018 0.7295252 0.07206052 0.7802842 0.09744018 0.7549047 0.09744018 0.7802842 0.07206052 0.8056637 0.09744018 0.7802842 0.09744018 0.8056637 0.07206052 0.8310433 0.09744018 0.8056637 0.09744018 0.8310433 0.07206052 0.2473123 0.07206052 0.2473123 0.09744018 0.2219326 0.07206052 0.2726919 0.07206052 0.2726919 0.09744018 0.2473123 0.07206052 0.2980716 0.07206052 0.2980716 0.09744018 0.2726919 0.07206052 0.3234512 0.09744018 0.2980716 0.09744018 0.3234512 0.07206052 0.3488309 0.09744018 0.3234512 0.09744018 0.3488309 0.07206052 0.3488309 0.07206052 0.3742105 0.07206052 0.3488309 0.09744018 0.6022254 0.5352516 0.5917232 0.4960566 0.6022254 0.5352516 0.899939 0.4554796 0.899939 0.4960572 0.899939 0.4554796 0.7661201 0.3216602 0.8053147 0.3321624 0.7661201 0.3216602 0.6022254 0.5352516 0.5917232 0.4960566 0.6022254 0.5352516 0.8894367 0.5352519 0.869148 0.5703927 0.8894367 0.5352519 0.8053144 0.619374 0.7661198 0.6298761 0.8053144 0.619374 0.6863479 0.619374 0.6512069 0.5990853 0.6863479 0.619374 0.899939 0.4960572 0.8894367 0.5352519 0.899939 0.4960572 0.8404555 0.5990853 0.8053144 0.619374 0.8404555 0.5990853 0.869148 0.5703927 0.8404555 0.5990853 0.869148 0.5703927 0.6863481 0.3321623 0.7255429 0.3216602 0.6863481 0.3321623 0.6225144 0.3811434 0.651207 0.3524509 0.6225144 0.3811434 0.8404557 0.3524512 0.8691482 0.3811439 0.8404557 0.3524512 0.5917232 0.4960566 0.5917232 0.4554793 0.5917232 0.4960566 0.5917232 0.4554793 0.6022255 0.4162846 0.5917232 0.4554793 0.6512069 0.5990853 0.6225143 0.5703926 0.6512069 0.5990853 0.8053147 0.3321624 0.8404557 0.3524512 0.8053147 0.3321624 0.889437 0.4162849 0.899939 0.4554796 0.889437 0.4162849 0.651207 0.3524509 0.6863481 0.3321623 0.651207 0.3524509 0.8691482 0.3811439 0.889437 0.4162849 0.8691482 0.3811439 0.6022255 0.4162846 0.6225144 0.3811434 0.6022255 0.4162846 0.7255425 0.6298761 0.6863479 0.619374 0.7255425 0.6298761 0.7661198 0.6298761 0.7255425 0.6298761 0.7661198 0.6298761 0.7255429 0.3216602 0.7661201 0.3216602 0.7255429 0.3216602 0.6225143 0.5703926 0.6022254 0.5352516 0.6225143 0.5703926 0.6022255 0.4162846 0.6225144 0.3811434 0.6022255 0.4162846 0.7255425 0.6298761 0.6863479 0.619374 0.7255425 0.6298761 0.8053147 0.3321624 0.8404557 0.3524512 0.8053147 0.3321624 0.899939 0.4554796 0.899939 0.4960572 0.899939 0.4554796 0.6022255 0.4162846 0.6225144 0.3811434 0.6022255 0.4162846 0.6863481 0.3321623 0.7255429 0.3216602 0.6863481 0.3321623 0.7255429 0.3216602 0.7661201 0.3216602 0.7255429 0.3216602 0.8053144 0.619374 0.7661198 0.6298761 0.8053144 0.619374 0.6512069 0.5990853 0.6225143 0.5703926 0.6512069 0.5990853 0.6225143 0.5703926 0.6022254 0.5352516 0.6225143 0.5703926 0.7661198 0.6298761 0.7255425 0.6298761 0.7661198 0.6298761 0.869148 0.5703927 0.8404555 0.5990853 0.869148 0.5703927 0.889437 0.4162849 0.899939 0.4554796 0.889437 0.4162849 0.6225144 0.3811434 0.651207 0.3524509 0.6225144 0.3811434 0.651207 0.3524509 0.6863481 0.3321623 0.651207 0.3524509 0.6863479 0.619374 0.6512069 0.5990853 0.6863479 0.619374 0.8404555 0.5990853 0.8053144 0.619374 0.8404555 0.5990853 0.8404557 0.3524512 0.8691482 0.3811439 0.8404557 0.3524512 0.899939 0.4960572 0.8894367 0.5352519 0.899939 0.4960572 0.8894367 0.5352519 0.869148 0.5703927 0.8894367 0.5352519 0.5917232 0.4554793 0.6022255 0.4162846 0.5917232 0.4554793 0.8691482 0.3811439 0.889437 0.4162849 0.8691482 0.3811439 0.7661201 0.3216602 0.8053147 0.3321624 0.7661201 0.3216602 0.5917232 0.4960566 0.5917232 0.4554793 0.5917232 0.4960566 0.6225143 0.5703926 0.6022254 0.5352516 0.6225143 0.5703926 0.6863481 0.3321623 0.7255429 0.3216602 0.6863481 0.3321623 0.7255429 0.3216602 0.7661201 0.3216602 0.7255429 0.3216602 0.8053144 0.619374 0.7661198 0.6298761 0.8053144 0.619374 0.6512069 0.5990853 0.6225143 0.5703926 0.6512069 0.5990853 0.6225143 0.5703926 0.6022254 0.5352516 0.6225143 0.5703926 0.7661198 0.6298761 0.7255425 0.6298761 0.7661198 0.6298761 0.869148 0.5703927 0.8404555 0.5990853 0.869148 0.5703927 0.889437 0.4162849 0.899939 0.4554796 0.889437 0.4162849 0.6225144 0.3811434 0.651207 0.3524509 0.6225144 0.3811434 0.651207 0.3524509 0.6863481 0.3321623 0.651207 0.3524509 0.6863479 0.619374 0.6512069 0.5990853 0.6863479 0.619374 0.8404555 0.5990853 0.8053144 0.619374 0.8404555 0.5990853 0.8404557 0.3524512 0.8691482 0.3811439 0.8404557 0.3524512 0.899939 0.4960572 0.8894367 0.5352519 0.899939 0.4960572 0.8894367 0.5352519 0.869148 0.5703927 0.8894367 0.5352519 0.5917232 0.4554793 0.6022255 0.4162846 0.5917232 0.4554793 0.8691482 0.3811439 0.889437 0.4162849 0.8691482 0.3811439 0.7661201 0.3216602 0.8053147 0.3321624 0.7661201 0.3216602 0.5917232 0.4960566 0.5917232 0.4554793 0.5917232 0.4960566 0.6022254 0.5352516 0.5917232 0.4960566 0.6022254 0.5352516 0.7255425 0.6298761 0.6863479 0.619374 0.7255425 0.6298761 0.8053147 0.3321624 0.8404557 0.3524512 0.8053147 0.3321624 0.899939 0.4554796 0.899939 0.4960572 0.899939 0.4554796 0.6225144 0.3811434 0.651207 0.3524509 0.6225144 0.3811434 0.7661198 0.6298761 0.7255425 0.6298761 0.7661198 0.6298761 0.869148 0.5703927 0.8404555 0.5990853 0.869148 0.5703927 0.889437 0.4162849 0.899939 0.4554796 0.889437 0.4162849 0.6225144 0.3811434 0.651207 0.3524509 0.6225144 0.3811434 0.651207 0.3524509 0.6863481 0.3321623 0.651207 0.3524509 0.6863479 0.619374 0.6512069 0.5990853 0.6863479 0.619374 0.8404555 0.5990853 0.8053144 0.619374 0.8404555 0.5990853 0.8404557 0.3524512 0.8691482 0.3811439 0.8404557 0.3524512 0.899939 0.4960572 0.8894367 0.5352519 0.899939 0.4960572 0.8894367 0.5352519 0.869148 0.5703927 0.8894367 0.5352519 0.5917232 0.4554793 0.6022255 0.4162846 0.5917232 0.4554793 0.8691482 0.3811439 0.889437 0.4162849 0.8691482 0.3811439 0.7661201 0.3216602 0.8053147 0.3321624 0.7661201 0.3216602 0.5917232 0.4960566 0.5917232 0.4554793 0.5917232 0.4960566 0.6022254 0.5352516 0.5917232 0.4960566 0.6022254 0.5352516 0.7255425 0.6298761 0.6863479 0.619374 0.7255425 0.6298761 0.8053147 0.3321624 0.8404557 0.3524512 0.8053147 0.3321624 0.899939 0.4554796 0.899939 0.4960572 0.899939 0.4554796 0.6022255 0.4162846 0.6225144 0.3811434 0.6022255 0.4162846 0.6863481 0.3321623 0.7255429 0.3216602 0.6863481 0.3321623 0.7255429 0.3216602 0.7661201 0.3216602 0.7255429 0.3216602 0.8053144 0.619374 0.7661198 0.6298761 0.8053144 0.619374 0.6512069 0.5990853 0.6225143 0.5703926 0.6512069 0.5990853 0.6022255 0.4162846 0.6225144 0.3811434 0.651207 0.3524509 0.651207 0.3524509 0.5917232 0.4554793 0.6022255 0.4162846 0.6225143 0.5703926 0.6022254 0.5352516 0.5917232 0.4960566 0.6863479 0.619374 0.6512069 0.5990853 0.6225143 0.5703926 0.7661198 0.6298761 0.7255425 0.6298761 0.6863479 0.619374 0.8404555 0.5990853 0.8053144 0.619374 0.7661198 0.6298761 0.8894367 0.5352519 0.869148 0.5703927 0.8404555 0.5990853 0.8404555 0.5990853 0.899939 0.4960572 0.8894367 0.5352519 0.8691482 0.3811439 0.889437 0.4162849 0.899939 0.4554796 0.651207 0.3524509 0.8404557 0.3524512 0.8691482 0.3811439 0.7255429 0.3216602 0.7661201 0.3216602 0.8053147 0.3321624 0.651207 0.3524509 0.6863481 0.3321623 0.7255429 0.3216602 0.6863479 0.619374 0.5917232 0.4554793 0.651207 0.3524509 0.6863479 0.619374 0.6225143 0.5703926 0.5917232 0.4960566 0.8404555 0.5990853 0.7661198 0.6298761 0.6863479 0.619374 0.899939 0.4554796 0.899939 0.4960572 0.8404555 0.5990853 0.651207 0.3524509 0.8691482 0.3811439 0.899939 0.4554796 0.651207 0.3524509 0.7255429 0.3216602 0.8053147 0.3321624 0.6863479 0.619374 0.5917232 0.4960566 0.5917232 0.4554793 0.899939 0.4554796 0.8404555 0.5990853 0.6863479 0.619374 0.651207 0.3524509 0.8053147 0.3321624 0.8404557 0.3524512 0.651207 0.3524509 0.6863481 0.3321623 0.651207 0.3524509 0.6863479 0.619374 0.6512069 0.5990853 0.6863479 0.619374 0.8404555 0.5990853 0.8053144 0.619374 0.8404555 0.5990853 0.8404557 0.3524512 0.8691482 0.3811439 0.8404557 0.3524512 0.899939 0.4960572 0.8894367 0.5352519 0.899939 0.4960572 0.8894367 0.5352519 0.869148 0.5703927 0.8894367 0.5352519 0.5917232 0.4554793 0.6022255 0.4162846 0.5917232 0.4554793 0.8691482 0.3811439 0.889437 0.4162849 0.8691482 0.3811439 0.7661201 0.3216602 0.8053147 0.3321624 0.7661201 0.3216602 0.5917232 0.4960566 0.5917232 0.4554793 0.5917232 0.4960566 0.6022254 0.5352516 0.5917232 0.4960566 0.6022254 0.5352516 0.7255425 0.6298761 0.6863479 0.619374 0.7255425 0.6298761 0.8053147 0.3321624 0.8404557 0.3524512 0.8053147 0.3321624 0.899939 0.4554796 0.899939 0.4960572 0.899939 0.4554796 0.6022255 0.4162846 0.6225144 0.3811434 0.6022255 0.4162846 0.6863481 0.3321623 0.7255429 0.3216602 0.6863481 0.3321623 0.7255429 0.3216602 0.7661201 0.3216602 0.7255429 0.3216602 0.8053144 0.619374 0.7661198 0.6298761 0.8053144 0.619374 0.6512069 0.5990853 0.6225143 0.5703926 0.6512069 0.5990853 0.6225143 0.5703926 0.6022254 0.5352516 0.6225143 0.5703926 0.7661198 0.6298761 0.7255425 0.6298761 0.7661198 0.6298761 0.869148 0.5703927 0.8404555 0.5990853 0.869148 0.5703927 0.889437 0.4162849 0.899939 0.4554796 0.889437 0.4162849 + + + + + + + + + + + + + + + 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 +

1 0 0 2 1 1 3 2 2 5 3 3 6 4 4 7 5 5 8 6 6 9 7 7 10 8 8 13 9 9 14 10 10 15 11 11 16 12 12 17 13 13 18 14 14 2 1 15 20 15 16 21 16 17 6 4 18 22 17 19 23 18 20 10 8 21 24 19 22 25 20 23 15 11 24 14 10 25 26 21 26 18 14 27 28 22 28 29 23 29 20 15 30 30 24 31 31 25 32 22 17 33 32 26 34 33 27 35 24 19 36 34 28 37 35 29 38 27 30 39 26 21 40 36 31 41 28 22 42 38 32 43 39 33 44 31 25 45 30 24 46 40 34 47 32 26 48 42 35 49 43 36 50 35 29 51 34 28 52 44 37 53 36 31 54 46 38 55 47 39 56 39 33 57 38 32 58 48 40 59 41 41 60 40 34 61 50 42 62 42 35 63 52 43 64 53 44 65 44 37 66 54 45 67 55 46 68 46 38 69 56 47 70 57 48 71 49 49 72 48 40 73 58 50 74 51 51 75 50 42 76 60 52 77 52 43 78 62 53 79 63 54 80 54 45 81 64 55 82 65 56 83 57 48 84 56 47 85 66 57 86 58 50 87 68 58 88 69 59 89 60 52 90 70 60 91 71 61 92 62 53 93 72 62 94 73 63 95 64 55 96 74 64 97 75 65 98 66 57 99 76 66 100 77 67 101 69 59 102 68 58 103 78 68 104 70 60 105 80 69 106 81 70 107 72 62 108 82 71 109 83 72 110 74 64 111 84 73 112 85 74 113 77 67 114 76 66 115 86 75 116 78 68 117 88 76 118 89 77 119 80 69 120 90 78 121 91 79 122 82 71 123 92 80 124 93 81 125 84 73 126 94 82 127 95 83 128 87 84 129 86 75 130 96 85 131 88 76 132 98 86 133 99 87 134 91 79 135 90 78 136 100 88 137 92 80 138 102 89 139 103 90 140 95 83 141 94 82 142 104 91 143 96 85 144 106 92 145 107 93 146 99 87 147 98 86 148 108 94 149 101 95 150 100 88 151 110 96 152 102 89 153 112 97 154 113 98 155 104 91 156 114 99 157 115 100 158 106 92 159 116 101 160 117 102 161 109 103 162 108 94 163 118 104 164 111 105 165 110 96 166 120 106 167 112 97 168 122 107 169 123 108 170 114 99 171 124 109 172 125 110 173 117 102 174 116 101 175 126 111 176 118 104 177 128 112 178 129 113 179 120 106 180 130 114 181 131 115 182 122 107 183 132 116 184 133 117 185 125 110 186 124 109 187 134 118 188 126 111 189 136 119 190 137 120 191 129 113 192 128 112 193 138 121 194 130 114 195 140 122 196 141 123 197 132 116 198 142 124 199 143 125 200 134 118 201 144 126 202 145 127 203 137 120 204 136 119 205 146 128 206 138 121 207 148 129 208 149 130 209 140 122 210 150 131 211 151 132 212 142 124 213 152 133 214 153 134 215 144 126 216 154 135 217 155 136 218 147 137 219 146 128 220 156 138 221 148 129 222 158 139 223 159 140 224 151 132 225 150 131 226 160 141 227 152 133 228 162 142 229 163 143 230 155 136 231 154 135 232 164 144 233 156 138 234 166 145 235 167 146 236 159 140 237 158 139 238 168 147 239 161 148 240 160 141 241 170 149 242 162 142 243 172 150 244 173 151 245 164 144 246 174 152 247 175 153 248 166 145 249 176 154 250 177 155 251 169 156 252 168 147 253 178 157 254 171 158 255 170 149 256 180 159 257 172 150 258 182 160 259 183 161 260 174 152 261 184 162 262 185 163 263 177 155 264 176 154 265 186 164 266 178 157 267 188 165 268 189 166 269 180 159 270 190 167 271 191 168 272 182 160 273 192 169 274 193 170 275 184 162 276 194 171 277 195 172 278 186 164 279 196 173 280 197 174 281 189 166 282 188 165 283 198 175 284 190 167 285 200 176 286 201 177 287 192 169 288 202 178 289 203 179 290 194 171 291 204 180 292 205 181 293 197 174 294 196 173 295 206 182 296 198 175 297 208 183 298 209 184 299 200 176 300 210 185 301 211 186 302 202 178 303 212 187 304 213 188 305 204 180 306 214 189 307 215 190 308 207 191 309 206 182 310 216 192 311 208 183 312 218 193 313 219 194 314 211 186 315 210 185 316 220 195 317 212 187 318 222 196 319 223 197 320 215 190 321 214 189 322 224 198 323 216 192 324 226 199 325 227 200 326 219 194 327 218 193 328 228 201 329 221 202 330 220 195 331 230 203 332 222 196 333 232 204 334 233 205 335 224 198 336 234 206 337 235 207 338 226 199 339 236 208 340 237 209 341 229 210 342 228 201 343 238 211 344 231 212 345 230 203 346 1 0 347 232 204 348 5 3 349 4 213 350 234 206 351 9 7 352 8 6 353 237 209 354 236 208 355 13 9 356 238 211 357 17 13 358 16 12 359 240 214 360 241 215 361 242 216 362 244 217 363 252 218 364 260 219 365 268 220 366 284 221 367 276 222 368 292 223 369 240 214 370 243 224 371 294 225 372 292 223 373 293 226 374 294 225 375 295 227 376 297 228 377 296 229 378 297 228 379 299 230 380 300 231 381 301 232 382 302 233 383 298 234 384 299 230 385 302 233 386 304 235 387 305 236 388 306 237 389 305 236 390 300 231 391 303 238 392 304 235 393 307 239 394 309 240 395 308 241 396 309 240 397 311 242 398 310 243 399 311 242 400 313 244 401 314 245 402 315 246 403 316 247 404 315 246 405 312 248 406 313 244 407 318 249 408 314 245 409 317 250 410 318 249 411 319 251 412 321 252 413 320 253 414 321 252 415 323 254 416 322 255 417 323 254 418 325 256 419 326 257 420 324 258 421 325 256 422 328 259 423 326 257 424 327 260 425 330 261 426 328 259 427 329 262 428 330 261 429 331 263 430 333 264 431 332 265 432 333 264 433 335 266 434 242 216 435 241 215 436 334 267 437 356 268 438 380 269 439 379 270 440 277 271 441 345 272 442 344 273 443 272 274 444 340 275 445 339 276 446 288 277 447 356 268 448 355 278 449 279 279 450 347 280 451 346 281 452 282 282 453 350 283 454 349 284 455 285 285 456 353 286 457 352 287 458 278 288 459 346 281 460 345 272 461 281 289 462 349 284 463 348 290 464 280 291 465 348 290 466 347 280 467 270 292 468 338 293 469 337 294 470 268 220 471 336 295 472 359 296 473 274 297 474 342 298 475 341 299 476 289 300 477 357 301 478 356 268 479 290 302 480 358 303 481 357 301 482 286 304 483 354 305 484 353 286 485 273 306 486 341 299 487 340 275 488 276 222 489 344 273 490 343 307 491 269 308 492 337 294 493 336 295 494 275 309 495 343 307 496 342 298 497 291 310 498 359 296 499 358 303 500 284 221 501 352 287 502 351 311 503 283 312 504 351 311 505 350 283 506 271 313 507 339 276 508 338 293 509 287 314 510 355 278 511 354 305 512 383 315 513 407 316 514 406 317 515 352 287 516 376 318 517 375 319 518 341 299 519 365 320 520 364 321 521 345 272 522 369 322 523 368 323 524 359 296 525 383 315 526 382 324 527 338 293 528 362 325 529 361 326 530 339 276 531 363 327 532 362 325 533 350 283 534 374 328 535 373 329 536 354 305 537 378 330 538 377 331 539 355 278 540 379 270 541 378 330 542 351 311 543 375 319 544 374 328 545 348 290 546 372 332 547 371 333 548 344 273 549 368 323 550 367 334 551 336 295 552 360 335 553 383 315 554 337 294 555 361 326 556 360 335 557 353 286 558 377 331 559 376 318 560 349 284 561 373 329 562 372 332 563 342 298 564 366 336 565 365 320 566 346 281 567 370 337 568 369 322 569 347 280 570 371 333 571 370 337 572 358 303 573 382 324 574 381 338 575 343 307 576 367 334 577 366 336 578 340 275 579 364 321 580 363 327 581 357 301 582 381 338 583 380 269 584 403 339 585 427 340 586 426 341 587 362 325 588 386 342 589 385 343 590 363 327 591 387 344 592 386 342 593 374 328 594 398 345 595 397 346 596 378 330 597 402 347 598 401 348 599 379 270 600 403 339 601 402 347 602 375 319 603 399 349 604 398 345 605 372 332 606 396 350 607 395 351 608 368 323 609 392 352 610 391 353 611 360 335 612 384 354 613 407 316 614 361 326 615 385 343 616 384 354 617 377 331 618 401 348 619 400 355 620 373 329 621 397 346 622 396 350 623 366 336 624 390 356 625 389 357 626 370 337 627 394 358 628 393 359 629 371 333 630 395 351 631 394 358 632 382 324 633 406 317 634 405 360 635 367 334 636 391 353 637 390 356 638 364 321 639 388 361 640 387 344 641 381 338 642 405 360 643 404 362 644 380 269 645 404 362 646 403 339 647 376 318 648 400 355 649 399 349 650 365 320 651 389 357 652 388 361 653 369 322 654 393 359 655 392 352 656 408 363 657 432 364 658 455 365 659 399 349 660 423 366 661 422 367 662 396 350 663 420 368 664 419 369 665 392 352 666 416 370 667 415 371 668 384 354 669 408 363 670 431 372 671 385 343 672 409 373 673 408 363 674 401 348 675 425 374 676 424 375 677 397 346 678 421 376 679 420 368 680 390 356 681 414 377 682 413 378 683 394 358 684 418 379 685 417 380 686 395 351 687 419 369 688 418 379 689 406 317 690 430 381 691 429 382 692 391 353 693 415 371 694 414 377 695 388 361 696 412 383 697 411 384 698 405 360 699 429 382 700 428 385 701 404 362 702 428 385 703 427 340 704 400 355 705 424 375 706 423 366 707 389 357 708 413 378 709 412 383 710 393 359 711 417 380 712 416 370 713 407 316 714 431 372 715 430 381 716 386 342 717 410 386 718 409 373 719 387 344 720 411 384 721 410 386 722 398 345 723 422 367 724 421 376 725 402 347 726 426 341 727 425 374 728 432 364 729 440 387 730 448 388 731 409 373 732 433 389 733 432 364 734 425 374 735 449 390 736 448 388 737 421 376 738 445 391 739 444 392 740 414 377 741 438 393 742 437 394 743 418 379 744 442 395 745 441 396 746 419 369 747 443 397 748 442 395 749 430 381 750 454 398 751 453 399 752 415 371 753 439 400 754 438 393 755 412 383 756 436 401 757 435 402 758 429 382 759 453 399 760 452 403 761 428 385 762 452 403 763 451 404 764 424 375 765 448 388 766 447 405 767 413 378 768 437 394 769 436 401 770 417 380 771 441 396 772 440 387 773 431 372 774 455 365 775 454 398 776 410 386 777 434 406 778 433 389 779 411 384 780 435 402 781 434 406 782 422 367 783 446 407 784 445 391 785 426 341 786 450 408 787 449 390 788 427 340 789 451 404 790 450 408 791 423 366 792 447 405 793 446 407 794 420 368 795 444 392 796 443 397 797 416 370 798 440 387 799 439 400 800 0 409 801 1 0 802 3 2 803 4 213 804 5 3 805 7 5 806 11 410 807 8 6 808 10 8 809 12 411 810 13 9 811 15 11 812 19 412 813 16 12 814 18 14 815 3 2 816 2 1 817 21 16 818 7 5 819 6 4 820 23 18 821 11 410 822 10 8 823 25 20 824 27 30 825 15 11 826 26 21 827 19 412 828 18 14 829 29 23 830 21 16 831 20 15 832 31 25 833 23 18 834 22 17 835 33 27 836 25 20 837 24 19 838 35 29 839 37 413 840 27 30 841 36 31 842 29 23 843 28 22 844 39 33 845 41 41 846 31 25 847 40 34 848 33 27 849 32 26 850 43 36 851 45 414 852 35 29 853 44 37 854 37 413 855 36 31 856 47 39 857 49 49 858 39 33 859 48 40 860 51 51 861 41 41 862 50 42 863 43 36 864 42 35 865 53 44 866 45 414 867 44 37 868 55 46 869 47 39 870 46 38 871 57 48 872 59 415 873 49 49 874 58 50 875 61 416 876 51 51 877 60 52 878 53 44 879 52 43 880 63 54 881 55 46 882 54 45 883 65 56 884 67 417 885 57 48 886 66 57 887 59 415 888 58 50 889 69 59 890 61 416 891 60 52 892 71 61 893 63 54 894 62 53 895 73 63 896 65 56 897 64 55 898 75 65 899 67 417 900 66 57 901 77 67 902 79 418 903 69 59 904 78 68 905 71 61 906 70 60 907 81 70 908 73 63 909 72 62 910 83 72 911 75 65 912 74 64 913 85 74 914 87 84 915 77 67 916 86 75 917 79 418 918 78 68 919 89 77 920 81 70 921 80 69 922 91 79 923 83 72 924 82 71 925 93 81 926 85 74 927 84 73 928 95 83 929 97 419 930 87 84 931 96 85 932 89 77 933 88 76 934 99 87 935 101 95 936 91 79 937 100 88 938 93 81 939 92 80 940 103 90 941 105 420 942 95 83 943 104 91 944 97 419 945 96 85 946 107 93 947 109 103 948 99 87 949 108 94 950 111 105 951 101 95 952 110 96 953 103 90 954 102 89 955 113 98 956 105 420 957 104 91 958 115 100 959 107 93 960 106 92 961 117 102 962 119 421 963 109 103 964 118 104 965 121 422 966 111 105 967 120 106 968 113 98 969 112 97 970 123 108 971 115 100 972 114 99 973 125 110 974 127 423 975 117 102 976 126 111 977 119 421 978 118 104 979 129 113 980 121 422 981 120 106 982 131 115 983 123 108 984 122 107 985 133 117 986 135 424 987 125 110 988 134 118 989 127 423 990 126 111 991 137 120 992 139 425 993 129 113 994 138 121 995 131 115 996 130 114 997 141 123 998 133 117 999 132 116 1000 143 125 1001 135 424 1002 134 118 1003 145 127 1004 147 137 1005 137 120 1006 146 128 1007 139 425 1008 138 121 1009 149 130 1010 141 123 1011 140 122 1012 151 132 1013 143 125 1014 142 124 1015 153 134 1016 145 127 1017 144 126 1018 155 136 1019 157 426 1020 147 137 1021 156 138 1022 149 130 1023 148 129 1024 159 140 1025 161 148 1026 151 132 1027 160 141 1028 153 134 1029 152 133 1030 163 143 1031 165 427 1032 155 136 1033 164 144 1034 157 426 1035 156 138 1036 167 146 1037 169 156 1038 159 140 1039 168 147 1040 171 158 1041 161 148 1042 170 149 1043 163 143 1044 162 142 1045 173 151 1046 165 427 1047 164 144 1048 175 153 1049 167 146 1050 166 145 1051 177 155 1052 179 428 1053 169 156 1054 178 157 1055 181 429 1056 171 158 1057 180 159 1058 173 151 1059 172 150 1060 183 161 1061 175 153 1062 174 152 1063 185 163 1064 187 430 1065 177 155 1066 186 164 1067 179 428 1068 178 157 1069 189 166 1070 181 429 1071 180 159 1072 191 168 1073 183 161 1074 182 160 1075 193 170 1076 185 163 1077 184 162 1078 195 172 1079 187 430 1080 186 164 1081 197 174 1082 199 431 1083 189 166 1084 198 175 1085 191 168 1086 190 167 1087 201 177 1088 193 170 1089 192 169 1090 203 179 1091 195 172 1092 194 171 1093 205 181 1094 207 191 1095 197 174 1096 206 182 1097 199 431 1098 198 175 1099 209 184 1100 201 177 1101 200 176 1102 211 186 1103 203 179 1104 202 178 1105 213 188 1106 205 181 1107 204 180 1108 215 190 1109 217 432 1110 207 191 1111 216 192 1112 209 184 1113 208 183 1114 219 194 1115 221 202 1116 211 186 1117 220 195 1118 213 188 1119 212 187 1120 223 197 1121 225 433 1122 215 190 1123 224 198 1124 217 432 1125 216 192 1126 227 200 1127 229 210 1128 219 194 1129 228 201 1130 231 212 1131 221 202 1132 230 203 1133 223 197 1134 222 196 1135 233 205 1136 225 433 1137 224 198 1138 235 207 1139 227 200 1140 226 199 1141 237 209 1142 239 434 1143 229 210 1144 238 211 1145 0 409 1146 231 212 1147 1 0 1148 233 205 1149 232 204 1150 4 213 1151 235 207 1152 234 206 1153 8 6 1154 12 411 1155 237 209 1156 13 9 1157 239 434 1158 238 211 1159 16 12 1160 243 224 1161 240 214 1162 242 216 1163 266 435 1164 267 436 1165 244 217 1166 264 437 1167 265 438 1168 266 435 1169 262 439 1170 263 440 1171 264 437 1172 260 219 1173 261 441 1174 262 439 1175 256 442 1176 259 443 1177 260 219 1178 256 442 1179 257 444 1180 258 445 1181 254 446 1182 255 447 1183 256 442 1184 252 218 1185 253 448 1186 254 446 1187 250 449 1188 251 450 1189 252 218 1190 248 451 1191 249 452 1192 250 449 1193 244 217 1194 247 453 1195 248 451 1196 244 217 1197 245 454 1198 246 455 1199 264 437 1200 266 435 1201 244 217 1202 260 219 1203 262 439 1204 264 437 1205 256 442 1206 258 445 1207 259 443 1208 252 218 1209 254 446 1210 256 442 1211 248 451 1212 250 449 1213 252 218 1214 244 217 1215 246 455 1216 247 453 1217 260 219 1218 264 437 1219 244 217 1220 252 218 1221 256 442 1222 260 219 1223 244 217 1224 248 451 1225 252 218 1226 270 292 1227 269 308 1228 268 220 1229 276 222 1230 271 313 1231 270 292 1232 274 297 1233 273 306 1234 272 274 1235 276 222 1236 275 309 1237 274 297 1238 278 288 1239 277 271 1240 276 222 1241 276 222 1242 279 279 1243 278 288 1244 282 282 1245 281 289 1246 280 291 1247 284 221 1248 283 312 1249 282 282 1250 286 304 1251 285 285 1252 284 221 1253 288 277 1254 287 314 1255 286 304 1256 290 302 1257 289 300 1258 288 277 1259 288 277 1260 291 310 1261 290 302 1262 276 222 1263 270 292 1264 268 220 1265 276 222 1266 274 297 1267 272 274 1268 280 291 1269 279 279 1270 276 222 1271 284 221 1272 282 282 1273 280 291 1274 288 277 1275 286 304 1276 284 221 1277 268 220 1278 291 310 1279 288 277 1280 276 222 1281 272 274 1282 271 313 1283 284 221 1284 280 291 1285 276 222 1286 268 220 1287 288 277 1288 284 221 1289 293 226 1290 292 223 1291 243 224 1292 295 227 1293 294 225 1294 293 226 1295 296 229 1296 294 225 1297 297 228 1298 298 234 1299 296 229 1300 299 230 1301 303 238 1302 300 231 1303 302 233 1304 301 232 1305 298 234 1306 302 233 1307 307 239 1308 304 235 1309 306 237 1310 306 237 1311 305 236 1312 303 238 1313 308 241 1314 304 235 1315 309 240 1316 310 243 1317 308 241 1318 311 242 1319 312 248 1320 310 243 1321 313 244 1322 317 250 1323 314 245 1324 316 247 1325 316 247 1326 315 246 1327 313 244 1328 319 251 1329 318 249 1330 317 250 1331 320 253 1332 318 249 1333 321 252 1334 322 255 1335 320 253 1336 323 254 1337 324 258 1338 322 255 1339 325 256 1340 327 260 1341 326 257 1342 325 256 1343 329 262 1344 328 259 1345 327 260 1346 331 263 1347 330 261 1348 329 262 1349 332 265 1350 330 261 1351 333 264 1352 334 267 1353 332 265 1354 335 266 1355 335 266 1356 242 216 1357 334 267 1358 355 278 1359 356 268 1360 379 270 1361 276 222 1362 277 271 1363 344 273 1364 271 313 1365 272 274 1366 339 276 1367 287 314 1368 288 277 1369 355 278 1370 278 288 1371 279 279 1372 346 281 1373 281 289 1374 282 282 1375 349 284 1376 284 221 1377 285 285 1378 352 287 1379 277 271 1380 278 288 1381 345 272 1382 280 291 1383 281 289 1384 348 290 1385 279 279 1386 280 291 1387 347 280 1388 269 308 1389 270 292 1390 337 294 1391 291 310 1392 268 220 1393 359 296 1394 273 306 1395 274 297 1396 341 299 1397 288 277 1398 289 300 1399 356 268 1400 289 300 1401 290 302 1402 357 301 1403 285 285 1404 286 304 1405 353 286 1406 272 274 1407 273 306 1408 340 275 1409 275 309 1410 276 222 1411 343 307 1412 268 220 1413 269 308 1414 336 295 1415 274 297 1416 275 309 1417 342 298 1418 290 302 1419 291 310 1420 358 303 1421 283 312 1422 284 221 1423 351 311 1424 282 282 1425 283 312 1426 350 283 1427 270 292 1428 271 313 1429 338 293 1430 286 304 1431 287 314 1432 354 305 1433 382 324 1434 383 315 1435 406 317 1436 351 311 1437 352 287 1438 375 319 1439 340 275 1440 341 299 1441 364 321 1442 344 273 1443 345 272 1444 368 323 1445 358 303 1446 359 296 1447 382 324 1448 337 294 1449 338 293 1450 361 326 1451 338 293 1452 339 276 1453 362 325 1454 349 284 1455 350 283 1456 373 329 1457 353 286 1458 354 305 1459 377 331 1460 354 305 1461 355 278 1462 378 330 1463 350 283 1464 351 311 1465 374 328 1466 347 280 1467 348 290 1468 371 333 1469 343 307 1470 344 273 1471 367 334 1472 359 296 1473 336 295 1474 383 315 1475 336 295 1476 337 294 1477 360 335 1478 352 287 1479 353 286 1480 376 318 1481 348 290 1482 349 284 1483 372 332 1484 341 299 1485 342 298 1486 365 320 1487 345 272 1488 346 281 1489 369 322 1490 346 281 1491 347 280 1492 370 337 1493 357 301 1494 358 303 1495 381 338 1496 342 298 1497 343 307 1498 366 336 1499 339 276 1500 340 275 1501 363 327 1502 356 268 1503 357 301 1504 380 269 1505 402 347 1506 403 339 1507 426 341 1508 361 326 1509 362 325 1510 385 343 1511 362 325 1512 363 327 1513 386 342 1514 373 329 1515 374 328 1516 397 346 1517 377 331 1518 378 330 1519 401 348 1520 378 330 1521 379 270 1522 402 347 1523 374 328 1524 375 319 1525 398 345 1526 371 333 1527 372 332 1528 395 351 1529 367 334 1530 368 323 1531 391 353 1532 383 315 1533 360 335 1534 407 316 1535 360 335 1536 361 326 1537 384 354 1538 376 318 1539 377 331 1540 400 355 1541 372 332 1542 373 329 1543 396 350 1544 365 320 1545 366 336 1546 389 357 1547 369 322 1548 370 337 1549 393 359 1550 370 337 1551 371 333 1552 394 358 1553 381 338 1554 382 324 1555 405 360 1556 366 336 1557 367 334 1558 390 356 1559 363 327 1560 364 321 1561 387 344 1562 380 269 1563 381 338 1564 404 362 1565 379 270 1566 380 269 1567 403 339 1568 375 319 1569 376 318 1570 399 349 1571 364 321 1572 365 320 1573 388 361 1574 368 323 1575 369 322 1576 392 352 1577 431 372 1578 408 363 1579 455 365 1580 398 345 1581 399 349 1582 422 367 1583 395 351 1584 396 350 1585 419 369 1586 391 353 1587 392 352 1588 415 371 1589 407 316 1590 384 354 1591 431 372 1592 384 354 1593 385 343 1594 408 363 1595 400 355 1596 401 348 1597 424 375 1598 396 350 1599 397 346 1600 420 368 1601 389 357 1602 390 356 1603 413 378 1604 393 359 1605 394 358 1606 417 380 1607 394 358 1608 395 351 1609 418 379 1610 405 360 1611 406 317 1612 429 382 1613 390 356 1614 391 353 1615 414 377 1616 387 344 1617 388 361 1618 411 384 1619 404 362 1620 405 360 1621 428 385 1622 403 339 1623 404 362 1624 427 340 1625 399 349 1626 400 355 1627 423 366 1628 388 361 1629 389 357 1630 412 383 1631 392 352 1632 393 359 1633 416 370 1634 406 317 1635 407 316 1636 430 381 1637 385 343 1638 386 342 1639 409 373 1640 386 342 1641 387 344 1642 410 386 1643 397 346 1644 398 345 1645 421 376 1646 401 348 1647 402 347 1648 425 374 1649 454 398 1650 455 365 1651 432 364 1652 432 364 1653 453 399 1654 454 398 1655 450 408 1656 451 404 1657 452 403 1658 448 388 1659 449 390 1660 450 408 1661 446 407 1662 447 405 1663 448 388 1664 444 392 1665 445 391 1666 446 407 1667 442 395 1668 443 397 1669 444 392 1670 444 392 1671 441 396 1672 442 395 1673 438 393 1674 439 400 1675 440 387 1676 432 364 1677 437 394 1678 438 393 1679 434 406 1680 435 402 1681 436 401 1682 432 364 1683 433 389 1684 434 406 1685 448 388 1686 453 399 1687 432 364 1688 448 388 1689 450 408 1690 452 403 1691 444 392 1692 446 407 1693 448 388 1694 440 387 1695 441 396 1696 444 392 1697 432 364 1698 438 393 1699 440 387 1700 432 364 1701 434 406 1702 436 401 1703 448 388 1704 452 403 1705 453 399 1706 440 387 1707 444 392 1708 448 388 1709 432 364 1710 436 401 1711 437 394 1712 408 363 1713 409 373 1714 432 364 1715 424 375 1716 425 374 1717 448 388 1718 420 368 1719 421 376 1720 444 392 1721 413 378 1722 414 377 1723 437 394 1724 417 380 1725 418 379 1726 441 396 1727 418 379 1728 419 369 1729 442 395 1730 429 382 1731 430 381 1732 453 399 1733 414 377 1734 415 371 1735 438 393 1736 411 384 1737 412 383 1738 435 402 1739 428 385 1740 429 382 1741 452 403 1742 427 340 1743 428 385 1744 451 404 1745 423 366 1746 424 375 1747 447 405 1748 412 383 1749 413 378 1750 436 401 1751 416 370 1752 417 380 1753 440 387 1754 430 381 1755 431 372 1756 454 398 1757 409 373 1758 410 386 1759 433 389 1760 410 386 1761 411 384 1762 434 406 1763 421 376 1764 422 367 1765 445 391 1766 425 374 1767 426 341 1768 449 390 1769 426 341 1770 427 340 1771 450 408 1772 422 367 1773 423 366 1774 446 407 1775 419 369 1776 420 368 1777 443 397 1778 415 371 1779 416 370 1780 439 400 1781

+
+
+
+
+ + + + + -0.2908646 -0.7711008 0.5663932 4.076245 0.9551712 -0.1998834 0.2183912 1.005454 -0.05518906 0.6045247 0.7946723 5.903862 0 0 0 1 + + + + -1 -1.4243e-14 -8.74228e-8 0 -8.74228e-8 1.62921e-7 1 0 0 1 -1.62921e-7 0 0 0 0 1 + + 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 + + + + + + + + + + + + + + +
\ No newline at end of file diff --git a/src/parts source/kOS0m dev/Assets/Materials.meta b/src/parts source/kOS0m dev/Assets/Materials.meta new file mode 100644 index 000000000..ab48b81cf --- /dev/null +++ b/src/parts source/kOS0m dev/Assets/Materials.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 0309a0dd6023645ffbd6ca1a5a02a66a +folderAsset: yes +timeCreated: 1431182775 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/parts source/kOS0m dev/Assets/Materials/GameObject.controller b/src/parts source/kOS0m dev/Assets/Materials/GameObject.controller new file mode 100644 index 000000000..5eccf37e3 Binary files /dev/null and b/src/parts source/kOS0m dev/Assets/Materials/GameObject.controller differ diff --git a/src/parts source/kOS0m dev/Assets/Materials/GameObject.controller.meta b/src/parts source/kOS0m dev/Assets/Materials/GameObject.controller.meta new file mode 100644 index 000000000..26cdb7438 --- /dev/null +++ b/src/parts source/kOS0m dev/Assets/Materials/GameObject.controller.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: c8f6765d0ea754a95940d6758896e01b +timeCreated: 1431264432 +licenseType: Free +NativeFormatImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/parts source/kOS0m dev/Assets/Materials/KR-2042_uv_layout_1_EMIS.png b/src/parts source/kOS0m dev/Assets/Materials/KR-2042_uv_layout_1_EMIS.png new file mode 100644 index 000000000..0cc7299bf Binary files /dev/null and b/src/parts source/kOS0m dev/Assets/Materials/KR-2042_uv_layout_1_EMIS.png differ diff --git a/src/parts source/kOS0m dev/Assets/Materials/KR-2042_uv_layout_1_EMIS.png.meta b/src/parts source/kOS0m dev/Assets/Materials/KR-2042_uv_layout_1_EMIS.png.meta new file mode 100644 index 000000000..ea74b5250 --- /dev/null +++ b/src/parts source/kOS0m dev/Assets/Materials/KR-2042_uv_layout_1_EMIS.png.meta @@ -0,0 +1,55 @@ +fileFormatVersion: 2 +guid: 411bce4713c3a46b090c6566e91d04b9 +timeCreated: 1431257233 +licenseType: Free +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + linearTexture: 0 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: .25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 8 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -1 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: -1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 1 + lightmap: 1 + rGBM: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: .5, y: .5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 0 + textureType: 6 + buildTargetSettings: [] + spriteSheet: + sprites: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/parts source/kOS0m dev/Assets/Materials/KR-2042_uv_layout_1_d_NRM.png b/src/parts source/kOS0m dev/Assets/Materials/KR-2042_uv_layout_1_d_NRM.png new file mode 100644 index 000000000..04ec7bb3b Binary files /dev/null and b/src/parts source/kOS0m dev/Assets/Materials/KR-2042_uv_layout_1_d_NRM.png differ diff --git a/src/parts source/kOS0m dev/Assets/Materials/KR-2042_uv_layout_1_d_NRM.png.meta b/src/parts source/kOS0m dev/Assets/Materials/KR-2042_uv_layout_1_d_NRM.png.meta new file mode 100644 index 000000000..cf9c901b4 --- /dev/null +++ b/src/parts source/kOS0m dev/Assets/Materials/KR-2042_uv_layout_1_d_NRM.png.meta @@ -0,0 +1,55 @@ +fileFormatVersion: 2 +guid: d1356fc4154b74edfaa905dfb4d07029 +timeCreated: 1431190172 +licenseType: Free +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 1 + heightScale: .25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 8 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -1 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: -1 + mipBias: -1 + wrapMode: -1 + nPOTScale: 1 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: .5, y: .5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 0 + textureType: 1 + buildTargetSettings: [] + spriteSheet: + sprites: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/parts source/kOS0m dev/Assets/Materials/KR-2042_uv_layout_d.png b/src/parts source/kOS0m dev/Assets/Materials/KR-2042_uv_layout_d.png new file mode 100644 index 000000000..451faf31f Binary files /dev/null and b/src/parts source/kOS0m dev/Assets/Materials/KR-2042_uv_layout_d.png differ diff --git a/src/parts source/kOS0m dev/Assets/Materials/KR-2042_uv_layout_d.png.meta b/src/parts source/kOS0m dev/Assets/Materials/KR-2042_uv_layout_d.png.meta new file mode 100644 index 000000000..8ff6f9ec1 --- /dev/null +++ b/src/parts source/kOS0m dev/Assets/Materials/KR-2042_uv_layout_d.png.meta @@ -0,0 +1,55 @@ +fileFormatVersion: 2 +guid: dc223f2cad8a24437bf1b947a6bf9863 +timeCreated: 1431257231 +licenseType: Free +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + linearTexture: 0 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: .25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 8 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -1 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: -1 + mipBias: -1 + wrapMode: -1 + nPOTScale: 1 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: .5, y: .5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 0 + textureType: -1 + buildTargetSettings: [] + spriteSheet: + sprites: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/parts source/kOS0m dev/Assets/Materials/Material_001__Instance_.mat b/src/parts source/kOS0m dev/Assets/Materials/Material_001__Instance_.mat new file mode 100644 index 000000000..406e8f7e0 Binary files /dev/null and b/src/parts source/kOS0m dev/Assets/Materials/Material_001__Instance_.mat differ diff --git a/src/parts source/kOS0m dev/Assets/Materials/Material_001__Instance_.mat.meta b/src/parts source/kOS0m dev/Assets/Materials/Material_001__Instance_.mat.meta new file mode 100644 index 000000000..22f5beb1b --- /dev/null +++ b/src/parts source/kOS0m dev/Assets/Materials/Material_001__Instance_.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 5be43c4bb23534f848cf85f35d43b4d1 +timeCreated: 1431182775 +licenseType: Free +NativeFormatImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/parts source/kOS0m dev/Assets/Materials/Materials.meta b/src/parts source/kOS0m dev/Assets/Materials/Materials.meta new file mode 100644 index 000000000..d75638eb6 --- /dev/null +++ b/src/parts source/kOS0m dev/Assets/Materials/Materials.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 2242cbd3dfe684042bab0b841b939102 +folderAsset: yes +timeCreated: 1431264346 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/parts source/kOS0m dev/Assets/Materials/Materials/KR-2042_uv_layout_1_EMIS.mat b/src/parts source/kOS0m dev/Assets/Materials/Materials/KR-2042_uv_layout_1_EMIS.mat new file mode 100644 index 000000000..97d2fb1ba Binary files /dev/null and b/src/parts source/kOS0m dev/Assets/Materials/Materials/KR-2042_uv_layout_1_EMIS.mat differ diff --git a/src/parts source/kOS0m dev/Assets/Materials/Materials/KR-2042_uv_layout_1_EMIS.mat.meta b/src/parts source/kOS0m dev/Assets/Materials/Materials/KR-2042_uv_layout_1_EMIS.mat.meta new file mode 100644 index 000000000..46969e856 --- /dev/null +++ b/src/parts source/kOS0m dev/Assets/Materials/Materials/KR-2042_uv_layout_1_EMIS.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: be70651774f054bd2a8910e59f8c5a5d +timeCreated: 1431264346 +licenseType: Free +NativeFormatImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/parts source/kOS0m dev/Assets/Materials/Materials/KR-2042_uv_layout_d.mat b/src/parts source/kOS0m dev/Assets/Materials/Materials/KR-2042_uv_layout_d.mat new file mode 100644 index 000000000..4bbda1f36 Binary files /dev/null and b/src/parts source/kOS0m dev/Assets/Materials/Materials/KR-2042_uv_layout_d.mat differ diff --git a/src/parts source/kOS0m dev/Assets/Materials/Materials/KR-2042_uv_layout_d.mat.meta b/src/parts source/kOS0m dev/Assets/Materials/Materials/KR-2042_uv_layout_d.mat.meta new file mode 100644 index 000000000..efa21874f --- /dev/null +++ b/src/parts source/kOS0m dev/Assets/Materials/Materials/KR-2042_uv_layout_d.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 28ad5b47e0da6406faa3412799d771e9 +timeCreated: 1431264371 +licenseType: Free +NativeFormatImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/parts source/kOS0m dev/Assets/Materials/New Animation.anim b/src/parts source/kOS0m dev/Assets/Materials/New Animation.anim new file mode 100644 index 000000000..57f0fe51c Binary files /dev/null and b/src/parts source/kOS0m dev/Assets/Materials/New Animation.anim differ diff --git a/src/parts source/kOS0m dev/Assets/Materials/New Animation.anim.meta b/src/parts source/kOS0m dev/Assets/Materials/New Animation.anim.meta new file mode 100644 index 000000000..0b01cc65f --- /dev/null +++ b/src/parts source/kOS0m dev/Assets/Materials/New Animation.anim.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 5c114ccf7f7614092a76b7177d643af7 +timeCreated: 1431264431 +licenseType: Free +NativeFormatImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/parts source/kOS0m dev/Assets/Materials/No Name.mat b/src/parts source/kOS0m dev/Assets/Materials/No Name.mat new file mode 100644 index 000000000..bcb9ddaff Binary files /dev/null and b/src/parts source/kOS0m dev/Assets/Materials/No Name.mat differ diff --git a/src/parts source/kOS0m dev/Assets/Materials/No Name.mat.meta b/src/parts source/kOS0m dev/Assets/Materials/No Name.mat.meta new file mode 100644 index 000000000..450e2cec0 --- /dev/null +++ b/src/parts source/kOS0m dev/Assets/Materials/No Name.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 9e0b9ca56385a4cff9bffffe89cf032e +timeCreated: 1431217332 +licenseType: Free +NativeFormatImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/parts source/kOS0m dev/Assets/New Animation.anim b/src/parts source/kOS0m dev/Assets/New Animation.anim new file mode 100644 index 000000000..d2f80f673 Binary files /dev/null and b/src/parts source/kOS0m dev/Assets/New Animation.anim differ diff --git a/src/parts source/kOS0m dev/Assets/New Animation.anim.meta b/src/parts source/kOS0m dev/Assets/New Animation.anim.meta new file mode 100644 index 000000000..bb0160a3f --- /dev/null +++ b/src/parts source/kOS0m dev/Assets/New Animation.anim.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 9c00b0b5caf5c405a8b1cda1c81936f7 +timeCreated: 1431263918 +licenseType: Free +NativeFormatImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/parts source/kOS0m dev/Assets/PartTools.meta b/src/parts source/kOS0m dev/Assets/PartTools.meta new file mode 100644 index 000000000..03d1d2159 --- /dev/null +++ b/src/parts source/kOS0m dev/Assets/PartTools.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 5382d917042964e1a9b92e75497e5c41 +folderAsset: yes +timeCreated: 1431182651 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/parts source/kOS0m dev/Assets/untitled.dae b/src/parts source/kOS0m dev/Assets/untitled.dae new file mode 100644 index 000000000..dcc60e92f --- /dev/null +++ b/src/parts source/kOS0m dev/Assets/untitled.dae @@ -0,0 +1,222 @@ + + + + + Blender User + Blender 2.73.0 commit date:2015-01-20, commit time:18:16, hash:bbf09d9 + + 2015-05-10T09:12:23 + 2015-05-10T09:12:23 + + Z_UP + + + + + + + 49.13434 + 1.777778 + 0.1 + 100 + + + + + + 0 + 0 + 0 + + + + + + + + + 1 1 1 + 1 + 0 + 0.00111109 + + + + + 0.000999987 + 1 + 0.1 + 0.1 + 1 + 1 + 1 + 2 + 0 + 1 + 1 + 1 + 1 + 1 + 0 + 2880 + 2 + 30.002 + 1.000799 + 0.04999995 + 29.99998 + 1 + 2 + 0 + 0 + 1 + 1 + 1 + 1 + 8192 + 1 + 1 + 0 + 1 + 1 + 1 + 3 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 1 + 3 + 0.15 + 75 + 1 + 1 + 0 + 1 + 1 + 0 + + + + + + + + + + + + 0 0 0 1 + + + 0 0 0 1 + + + 0.64 0.64 0.64 1 + + + 0.5 0.5 0.5 1 + + + 50 + + + 1 + + + + + + + + + + + + + + + + 0.25 0 0.02842795 0.23476 -0.062904 0.03539395 0.243041 0 0.03539395 0.241481 -0.06470495 0.02842795 0.21048 -0.12152 0.03539395 0.216506 -0.125 0.02842795 0.171856 -0.171856 0.03539395 0.176777 -0.176777 0.02842795 0.216332 -0.1249 -0.004379987 0.176635 -0.176635 -0.004379987 0.202262 -0.116776 -0.02643096 0.165147 -0.165147 -0.02643096 0.12152 -0.21048 0.03539395 0.125 -0.216506 0.02842795 0.1249 -0.216333 -0.004379987 0.116776 -0.2022629 -0.02643096 0.062904 -0.234759 0.03539395 0.06470495 -0.241481 0.02842795 0.06465297 -0.241288 -0.004379987 0.06044799 -0.2255949 -0.02642995 0 -0.243041 0.03539395 0 -0.25 0.02842795 0 -0.249799 -0.004379987 0 -0.233553 -0.02642995 -0.062904 -0.234759 0.03539395 -0.06470495 -0.241481 0.02842795 -0.06465297 -0.241288 -0.004379987 -0.06044799 -0.225594 -0.02642995 -0.121521 -0.210479 0.03539395 -0.125 -0.216506 0.02842795 -0.1249 -0.216332 -0.004379987 -0.116776 -0.202262 -0.02643096 -0.171856 -0.171856 0.03539395 -0.176777 -0.176777 0.02842795 -0.176635 -0.176635 -0.004379987 -0.21048 -0.12152 0.03539395 -0.216506 -0.125 0.02842795 -0.23476 -0.06290298 0.03539395 -0.241482 -0.064704 0.02842795 -0.243041 0 0.03539395 -0.25 0 0.02842795 0.249799 0 -0.004379987 0.241481 -0.06470495 0.02842795 0.25 0 0.02842795 0.241288 -0.06465297 -0.004379987 0.233553 0 -0.02643096 0.225594 -0.06044799 -0.02643096 0.216506 -0.125 0.02842795 0.216332 -0.1249 -0.004379987 0.202262 -0.116776 -0.02643096 0.241288 0.06465196 -0.004379987 0.241482 0.064704 0.028427 0.216333 0.124899 -0.004380941 0.216507 0.125 0.028427 0.176635 0.176634 -0.004380941 0.176777 0.176776 0.028427 0.1249 0.216332 -0.004380941 0.125 0.216506 0.028427 0.06465297 0.2412869 -0.004380941 0.06470495 0.241481 0.028427 0 0.249799 -0.004380941 0 0.25 0.028427 -0.06465196 0.241288 -0.004380941 -0.064704 0.241482 0.028427 -0.124899 0.216333 -0.004380941 -0.125 0.216507 0.028427 -0.176635 0.176635 -0.004380941 -0.176776 0.176777 0.028427 -0.216332 0.1249 -0.004380941 -0.216506 0.125 0.028427 -0.202262 0.116776 -0.02643096 -0.1651459 0.165147 -0.02643096 -0.116776 0.2022629 -0.02643096 -0.06044799 0.225594 -0.02643197 0 0.233552 -0.02643197 0.06044799 0.225594 -0.02643197 0.116777 0.202262 -0.02643096 0.165147 0.1651459 -0.02643096 0.2022629 0.116776 -0.02643096 0.2255949 0.06044697 -0.02643096 0.212099 0 -0.02643096 0.225594 -0.06044799 -0.02643096 0.233553 0 -0.02643096 0.204872 -0.05489498 -0.02643096 0.202262 -0.116776 -0.02643096 0.183683 -0.10605 -0.02643096 0.165147 -0.165147 -0.02643096 0.149977 -0.149977 -0.02643096 0.116776 -0.2022629 -0.02643096 0.106049 -0.183683 -0.02643096 0.06044799 -0.2255949 -0.02642995 0.05489498 -0.204872 -0.02643096 0 -0.233553 -0.02642995 0 -0.212099 -0.02643096 -0.06044799 -0.225594 -0.02642995 -0.05489498 -0.204872 -0.02643096 -0.116776 -0.202262 -0.02643096 -0.10605 -0.183683 -0.02643096 -0.165147 -0.165147 -0.02643096 -0.176635 -0.176635 -0.004379987 -0.1249 -0.216332 -0.004379987 -0.149977 -0.149977 -0.02643096 -0.216333 -0.124899 -0.004379987 -0.216506 -0.125 0.02842795 -0.176777 -0.176777 0.02842795 -0.2022629 -0.116776 -0.02643096 -0.183683 -0.106049 -0.02643096 -0.241482 -0.064704 0.02842795 -0.241288 -0.06465297 -0.004379987 -0.2255949 -0.06044799 -0.02643096 -0.204872 -0.05489498 -0.02643096 -0.25 0 0.02842795 -0.249799 0 -0.004379987 -0.233553 0 -0.02643096 -0.212099 0 -0.02643096 0.212099 0 -0.035447 0.204872 -0.05489498 -0.02643096 0.212099 0 -0.02643096 0.204872 -0.05489498 -0.035447 0.206044 0 -0.04131996 0.199023 -0.05332797 -0.04131996 0.183683 -0.10605 -0.02643096 0.183683 -0.10605 -0.035447 0.178439 -0.103022 -0.04131996 0.149977 -0.149977 -0.02643096 0.149977 -0.149977 -0.035447 0.145695 -0.145695 -0.04131996 0.106049 -0.183683 -0.02643096 0.106049 -0.183683 -0.035447 0.103022 -0.17844 -0.04131996 0.05489498 -0.204872 -0.02643096 0.05489498 -0.204872 -0.035447 0.05332797 -0.199023 -0.04131996 0 -0.212099 -0.02643096 0 -0.212099 -0.035447 0 -0.206044 -0.04131996 -0.05489498 -0.204872 -0.02643096 -0.05489498 -0.204872 -0.035447 -0.05332797 -0.199023 -0.04131996 -0.10605 -0.183683 -0.02643096 -0.10605 -0.183683 -0.035447 -0.103022 -0.178439 -0.04131996 -0.149977 -0.149977 -0.02643096 -0.149977 -0.149977 -0.035447 -0.145695 -0.145695 -0.04131996 -0.183683 -0.106049 -0.02643096 -0.183683 -0.106049 -0.035447 -0.17844 -0.103022 -0.04131996 -0.204872 -0.05489498 -0.02643096 -0.204872 -0.05489498 -0.035447 -0.199023 -0.05332797 -0.04131996 -0.212099 0 -0.02643096 -0.212099 0 -0.035447 -0.206044 0 -0.04131996 -0.25 0 0.02842795 -0.23476 0.062904 0.03539395 -0.243041 0 0.03539395 -0.241481 0.06470495 0.028427 -0.21048 0.121521 0.03539299 -0.216506 0.125 0.028427 -0.171856 0.171856 0.03539299 -0.176776 0.176777 0.028427 -0.12152 0.21048 0.03539299 -0.125 0.216507 0.028427 -0.06290298 0.23476 0.03539299 -0.064704 0.241482 0.028427 0 0.243041 0.03539299 0 0.25 0.028427 0.062904 0.23476 0.03539299 0.06470495 0.241481 0.028427 0.121521 0.21048 0.03539299 0.125 0.216506 0.028427 0.171856 0.171856 0.03539299 0.176777 0.176776 0.028427 0.21048 0.12152 0.03539299 0.216507 0.125 0.028427 0.23476 0.06290298 0.03539395 0.241482 0.064704 0.028427 -0.249799 0 -0.004379987 -0.241481 0.06470495 0.028427 -0.25 0 0.02842795 -0.2412869 0.06465297 -0.004379987 -0.233553 0 -0.02643096 -0.225594 0.06044799 -0.02643096 -0.212099 0 -0.02643096 -0.204872 0.05489498 -0.02643096 -0.216506 0.125 0.028427 -0.216332 0.1249 -0.004380941 -0.202262 0.116776 -0.02643096 -0.183683 0.10605 -0.02643096 -0.1651459 0.165147 -0.02643096 -0.149976 0.149977 -0.02643096 -0.116776 0.2022629 -0.02643096 -0.106049 0.183683 -0.02643096 -0.06044799 0.225594 -0.02643197 -0.05489498 0.204872 -0.02643197 0 0.233552 -0.02643197 0 0.212099 -0.02643197 0.06044799 0.225594 -0.02643197 0.05489599 0.204872 -0.02643197 0.116777 0.202262 -0.02643096 0.10605 0.183683 -0.02643096 0.165147 0.1651459 -0.02643096 0.149977 0.149976 -0.02643096 0.2022629 0.116776 -0.02643096 0.183683 0.106049 -0.02643096 0.2255949 0.06044697 -0.02643096 0.204872 0.05489498 -0.02643096 -0.212099 0 -0.035447 -0.204872 0.05489498 -0.02643096 -0.212099 0 -0.02643096 -0.204872 0.05489498 -0.035447 -0.206044 0 -0.04131996 -0.199023 0.05332797 -0.04131996 -0.183683 0.10605 -0.02643096 -0.183683 0.10605 -0.03544795 -0.178439 0.103022 -0.04131996 -0.149976 0.149977 -0.02643096 -0.149976 0.149977 -0.03544795 -0.145695 0.145695 -0.04132097 -0.106049 0.183683 -0.02643096 -0.106049 0.183683 -0.03544795 -0.103022 0.178439 -0.04132097 -0.05489498 0.204872 -0.02643197 -0.05489498 0.204872 -0.03544795 -0.05332797 0.199023 -0.04132097 0 0.212099 -0.02643197 0 0.212099 -0.03544795 0 0.206044 -0.04132097 0.05489599 0.204872 -0.02643197 0.05489599 0.204872 -0.03544795 0.05332899 0.199023 -0.04132097 0.10605 0.183683 -0.02643096 0.10605 0.183683 -0.03544795 0.103022 0.178439 -0.04132097 0.149977 0.149976 -0.02643096 0.149977 0.149976 -0.03544795 0.145696 0.145695 -0.04132097 0.183683 0.106049 -0.02643096 0.183683 0.106049 -0.03544795 0.17844 0.103022 -0.04131996 0.204872 0.05489498 -0.02643096 0.204872 0.05489498 -0.035447 0.199023 0.05332797 -0.04131996 0.243041 0 0.03539395 0.23476 -0.062904 0.03539395 2.97e-4 2.97e-4 0.03539395 0.21048 -0.12152 0.03539395 0.171856 -0.171856 0.03539395 0.12152 -0.21048 0.03539395 0.062904 -0.234759 0.03539395 0 -0.243041 0.03539395 -0.062904 -0.234759 0.03539395 -0.121521 -0.210479 0.03539395 -0.171856 -0.171856 0.03539395 -0.21048 -0.12152 0.03539395 -0.23476 -0.06290298 0.03539395 -0.243041 0 0.03539395 -0.23476 0.062904 0.03539395 -0.21048 0.121521 0.03539299 -0.171856 0.171856 0.03539299 -0.12152 0.21048 0.03539299 -0.06290298 0.23476 0.03539299 0 0.243041 0.03539299 0.062904 0.23476 0.03539299 0.121521 0.21048 0.03539299 0.171856 0.171856 0.03539299 0.21048 0.12152 0.03539299 0.23476 0.06290298 0.03539395 2.97e-4 2.96e-4 -0.03986597 0.199023 -0.05332797 -0.04131996 0.206044 0 -0.04131996 0.178439 -0.103022 -0.04131996 0.145695 -0.145695 -0.04131996 0.103022 -0.17844 -0.04131996 0.05332797 -0.199023 -0.04131996 0 -0.206044 -0.04131996 -0.05332797 -0.199023 -0.04131996 -0.103022 -0.178439 -0.04131996 -0.145695 -0.145695 -0.04131996 -0.17844 -0.103022 -0.04131996 -0.199023 -0.05332797 -0.04131996 -0.206044 0 -0.04131996 -0.199023 0.05332797 -0.04131996 -0.178439 0.103022 -0.04131996 -0.145695 0.145695 -0.04132097 -0.103022 0.178439 -0.04132097 -0.05332797 0.199023 -0.04132097 0 0.206044 -0.04132097 0.05332899 0.199023 -0.04132097 0.103022 0.178439 -0.04132097 0.145696 0.145695 -0.04132097 0.17844 0.103022 -0.04131996 0.199023 0.05332797 -0.04131996 + + + + + + + + + + 0.7074496 0 0.7067477 0.7074496 0 0.7067477 0.6833705 -0.183111 0.7066866 0.6833705 -0.183111 0.7066866 0.6126896 -0.3537095 0.7067171 0.7273171 -0.4763634 0.4940031 0.5002289 -0.5002289 0.7067477 0.6572161 -0.6572161 0.3688162 0.7554857 -0.5796686 -0.3052766 0.672811 -0.6727805 -0.3076266 0.640614 -0.4915616 -0.5898618 0.5692617 -0.5692617 -0.5931578 0.3537095 -0.6126896 0.7067171 0.4647359 -0.8049562 0.3688162 0.4757225 -0.8239998 -0.3076266 0.4025086 -0.6971954 -0.5931578 0.1830805 -0.68334 0.7067477 0.2405469 -0.8977935 0.3688162 0.2462538 -0.9190649 -0.3076266 0.2083498 -0.7776116 -0.5931578 0 -0.7074496 0.7067477 0 -0.9294717 0.3688162 0 -0.9514756 -0.3076571 0 -0.8050478 -0.5931578 -0.1830805 -0.68334 0.7067477 -0.2405469 -0.8978241 0.3688162 -0.2462538 -0.9190649 -0.3076571 -0.2083498 -0.7776116 -0.5931883 -0.3537095 -0.6126591 0.7067477 -0.4647359 -0.8049562 0.3688162 -0.4582049 -0.8650472 -0.2041688 -0.3089999 -0.746025 -0.5898618 -0.5002289 -0.5002289 0.7067477 -0.5792413 -0.6483657 0.4940336 -0.6087222 -0.7933287 -0.006042659 -0.6126896 -0.3537095 0.7067171 -0.6126896 -0.3537095 0.7067171 -0.68334 -0.1830805 0.7067477 -0.68334 -0.1830805 0.7067477 -0.7043977 -0.0927152 0.7036958 -0.7043977 -0.0927152 0.7036958 0.9999695 0 -0.006103694 0.9658803 -0.2587969 -0.006073176 0.9514756 0 -0.3076266 0.9190649 -0.2462538 -0.3076266 0.8050783 0 -0.5931273 0.7776116 -0.2083498 -0.5931578 0.9238563 -0.3826716 -0.006042659 0.8797571 -0.3644215 -0.3052766 0.746025 -0.3089999 -0.5898618 0.9190649 0.2462538 -0.3076571 0.9658803 0.2587969 -0.006103694 0.8239998 0.4757225 -0.3076571 0.8659932 0.4999848 -0.006103694 0.6727805 0.6727805 -0.3076571 0.7070834 0.7070834 -0.006103694 0.4757225 0.8239998 -0.3076571 0.4999848 0.8659932 -0.006103694 0.2462538 0.9190649 -0.3076571 0.2587969 0.9658803 -0.006103694 0 0.9514756 -0.3076571 0 0.9999695 -0.006103694 -0.2462538 0.9190649 -0.3076571 -0.2587969 0.9658803 -0.006103694 -0.4757225 0.8239998 -0.3076571 -0.4999848 0.8659932 -0.006103694 -0.672811 0.6727805 -0.3076571 -0.7070834 0.7070834 -0.006073176 -0.7554552 0.5796686 -0.3052766 -0.7933287 0.6087222 -0.006042659 -0.640614 0.4915311 -0.5898618 -0.5692617 0.5692617 -0.5931883 -0.4025086 0.6971954 -0.5931578 -0.2083498 0.7776116 -0.5931578 0 0.8050478 -0.5931578 0.2083498 0.7776421 -0.5931578 0.4025391 0.6971954 -0.5931578 0.5692617 0.5692617 -0.5931578 0.6971954 0.4025086 -0.5931578 0.7776421 0.2083498 -0.5931578 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -0.9999695 0 0 -1 0 -3.05185e-5 -1 0 -3.05185e-5 -1 0 -3.05185e-5 -0.9999695 0 -3.05185e-5 -1 0 -3.05185e-5 -1 0 -3.05185e-5 -1 -0.1987975 -0.2590716 -0.9451583 0 0 -1 -0.3393658 -0.3393658 -0.8772851 -0.6779382 -0.6109806 -0.4087649 -0.4915616 -0.640614 -0.5898618 0 0 -1 -0.8239998 -0.4757225 -0.3076266 -0.8659932 -0.4999848 -0.006103694 -0.7933287 -0.6087222 -0.006042659 -0.4156316 -0.239967 -0.8772851 0 0 -1 -0.9658803 -0.2587969 -0.006103694 -0.9190649 -0.2462538 -0.3076266 -0.4635761 -0.1242103 -0.8772851 0 0 -1 -0.9914243 -0.1304971 -0.006042659 -0.9440901 -0.1242713 -0.3052461 -0.478988 -0.06305122 -0.8755455 0 0 -1 1 0 0 0.9659109 -0.2587969 0 0.9255654 0 -0.3785516 0.8940092 -0.2395398 -0.3785516 0.6962187 0 -0.7177954 0.6724753 -0.1801813 -0.7178259 0.8660237 -0.4999848 0 0.8015686 -0.4627827 -0.3785516 0.6029237 -0.3480941 -0.7178259 0.7070834 -0.7070834 0 0.6544694 -0.6544694 -0.3785516 0.4922636 -0.4922636 -0.7178259 0.4999848 -0.8660237 0 0.4627827 -0.8015686 -0.3785211 0.3481246 -0.6029847 -0.7177343 0.2587969 -0.9659109 0 0.2395398 -0.8940092 -0.3785516 0.1801813 -0.6724753 -0.7178259 0 -1 0 0 -0.9255654 -0.3785516 0 -0.6962187 -0.7177954 -0.2587969 -0.9659109 0 -0.2395398 -0.8940092 -0.3785516 -0.1801813 -0.6724753 -0.7178259 -0.4999848 -0.8660237 0 -0.4627827 -0.8015686 -0.3785516 -0.3480941 -0.6029237 -0.7178259 -0.7070834 -0.7070834 0 -0.6544694 -0.6544694 -0.3785516 -0.4922636 -0.4922636 -0.7178259 -0.8660237 -0.4999848 0 -0.8015686 -0.4627827 -0.3785211 -0.6029847 -0.3481246 -0.7177343 -0.9659109 -0.2587969 0 -0.8940092 -0.2395398 -0.3785516 -0.6724753 -0.1801813 -0.7178259 -0.9914243 -0.1304971 0 -0.9187597 -0.1209448 -0.3757439 -0.6933195 -0.09128081 -0.7148045 -0.7043977 0.0927152 0.7036958 -0.6834315 0.183111 0.7066561 -0.7043977 0.0927152 0.7036958 -0.6834315 0.183111 0.7066561 -0.6126896 0.35374 0.7066866 -0.6126896 0.35374 0.7066866 -0.5002594 0.5002594 0.7067171 -0.5002289 0.5002594 0.7067171 -0.3537095 0.6126286 0.7067477 -0.3537095 0.6126286 0.7067477 -0.1830805 0.68334 0.7067477 -0.1830805 0.68334 0.7067477 0 0.7074496 0.7067477 0 0.7074496 0.7067477 0.183111 0.6833705 0.7066866 0.183111 0.6833705 0.7066866 0.35374 0.6126896 0.7066866 0.35374 0.6126896 0.7066866 0.5002594 0.5002594 0.7067171 0.5002594 0.5002289 0.7067171 0.6126286 0.3537095 0.7067477 0.6126286 0.3537095 0.7067477 0.6833705 0.183111 0.7066866 0.6833705 0.183111 0.7066866 -0.9914243 0.1305276 -0.006073176 -0.9658803 0.2587969 -0.006103694 -0.9440901 0.1242713 -0.3052461 -0.9190649 0.2462538 -0.3076571 -0.478988 0.06305122 -0.8755455 -0.4635761 0.1242103 -0.8772851 0 0 -1 0 0 -1 -0.9238563 0.3826716 -0.006042659 -0.8797571 0.364391 -0.3052766 -0.301706 0.1249732 -0.9451583 0 0 -0.9999695 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -0.9999695 0 0 -1 0 0 -1 0 0 -0.9999695 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 -0.9914243 0.1304971 0 -0.9659109 0.2587969 0 -0.9187597 0.1209448 -0.3757439 -0.8940092 0.2395398 -0.3785516 -0.6933195 0.0912503 -0.7148045 -0.6724753 0.1801813 -0.7178259 -0.8659932 0.4999848 0 -0.8015381 0.4627827 -0.3785821 -0.6028627 0.3480636 -0.7178869 -0.7070834 0.7070834 0 -0.6544694 0.6544694 -0.3785516 -0.4922941 0.4922941 -0.7177954 -0.4999848 0.8660237 0 -0.4627827 0.8015686 -0.3785211 -0.3480941 0.6029542 -0.7177954 -0.2587969 0.9659109 0 -0.2395398 0.8940092 -0.3785516 -0.1801813 0.6724753 -0.7178259 0 1 0 0 0.9255654 -0.3785516 0 0.6962187 -0.7177954 0.2587969 0.9659109 0 0.2395398 0.8940092 -0.3785516 0.1801813 0.6724753 -0.7178259 0.4999848 0.8659932 0 0.4627827 0.8015381 -0.3785516 0.3480941 0.6029237 -0.7178259 0.7070834 0.7070834 0 0.6544694 0.6544694 -0.3785211 0.4923246 0.4923246 -0.7177648 0.8660237 0.4999848 0 0.8015686 0.4627827 -0.3785516 0.6029542 0.3480941 -0.7177954 0.9659109 0.2587969 0 0.8940092 0.2395398 -0.3785516 0.6724753 0.1801813 -0.7178259 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0.9999695 0 0 1 0 0 1 0 0 0.9999695 0 0 1 0 0 1 0 0 1 0 0 0.9999695 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0.9999695 -0.007049739 0 -0.9999695 -0.006805598 0.001800537 -0.9999695 0 0 -1 -0.006103694 0.003509581 -0.9999695 -0.004974484 0.004974484 -0.9999695 -0.003509581 0.006103694 -0.9999695 -0.001800537 0.006805598 -0.9999695 0 0.007019221 -0.9999695 0.001800537 0.006775081 -0.9999695 0.003509581 0.006073176 -0.9999695 0.004974484 0.004974484 -0.9999695 0.006073176 0.003509581 -0.9999695 0.006775081 0.001800537 -0.9999695 0.007019221 0 -0.9999695 0.006805598 -0.001800537 -0.9999695 0.006103694 -0.003509581 -0.9999695 0.004974484 -0.004974484 -0.9999695 0.003509581 -0.006103694 -0.9999695 0.001800537 -0.006805598 -0.9999695 0 -0.007049739 -0.9999695 -0.001800537 -0.006805598 -0.9999695 -0.003509581 -0.006103694 -0.9999695 -0.004974484 -0.005005002 -0.9999695 -0.006103694 -0.003540098 -0.9999695 -0.006805598 -0.001800537 -0.9999695 + + + + + + + + + + 0.497981 0.08877295 0.497935 0.07082295 0.543138 0.07082295 0.497981 0.08877295 0.543138 0.07082295 0.542671 0.08877295 0.543138 0.07082295 0.587414 0.07082295 0.542671 0.08877295 0.587414 0.07082295 0.586501 0.08877295 0.542671 0.08877295 0.587414 0.07082295 0.631396 0.07082295 0.586501 0.08877295 0.631396 0.07082295 0.629985 0.08877295 0.586501 0.08877295 0.586501 0.08877295 0.629985 0.08877295 0.583796 0.101898 0.629985 0.08877295 0.626102 0.101898 0.583796 0.101898 0.583796 0.101898 0.626102 0.101898 0.581227 0.113775 0.626102 0.101898 0.622231 0.113775 0.581227 0.113775 0.631396 0.07082295 0.675506 0.07082295 0.629985 0.08877295 0.675506 0.07082295 0.673603 0.08877295 0.629985 0.08877295 0.629985 0.08877295 0.673603 0.08877295 0.626102 0.101898 0.673603 0.08877295 0.668071 0.101898 0.626102 0.101898 0.626102 0.101898 0.668071 0.101898 0.622231 0.113775 0.668071 0.101898 0.662932 0.113775 0.622231 0.113775 0.675506 0.07082295 0.719293 0.07082295 0.673603 0.08877295 0.719293 0.07082295 0.716869 0.08877295 0.673603 0.08877295 0.673603 0.08877295 0.716869 0.08877295 0.668071 0.101898 0.716869 0.08877295 0.709731 0.101898 0.668071 0.101898 0.668071 0.101898 0.709731 0.101898 0.662932 0.113775 0.709731 0.101898 0.703263 0.113775 0.662932 0.113775 0.719293 0.07082295 0.762508 0.07082295 0.716869 0.08877295 0.762508 0.07082295 0.759456 0.08877295 0.716869 0.08877295 0.716869 0.08877295 0.759456 0.08877295 0.709731 0.101898 0.759456 0.08877295 0.750727 0.101898 0.709731 0.101898 0.709731 0.101898 0.750727 0.101898 0.703263 0.113775 0.750727 0.101898 0.742873 0.113775 0.703263 0.113775 0.762508 0.07082295 0.803989 0.07082295 0.759456 0.08877295 0.803989 0.07082295 0.800498 0.08877295 0.759456 0.08877295 0.759456 0.08877295 0.800498 0.08877295 0.750727 0.101898 0.800498 0.08877295 0.790296 0.101898 0.750727 0.101898 0.750727 0.101898 0.790296 0.101898 0.742873 0.113775 0.790296 0.101898 0.781143 0.113775 0.742873 0.113775 0.803989 0.07082295 0.843235 0.07082295 0.800498 0.08877295 0.843235 0.07082295 0.839306 0.08877295 0.800498 0.08877295 0.800498 0.08877295 0.839306 0.08877295 0.790296 0.101898 0.839306 0.08877295 0.827857 0.101898 0.790296 0.101898 0.790296 0.101898 0.827857 0.101898 0.781143 0.113775 0.827857 0.101898 0.817555 0.113775 0.781143 0.113775 0.843235 0.07082295 0.880223 0.07082295 0.839306 0.08877295 0.880223 0.07082295 0.875888 0.08877295 0.839306 0.08877295 0.839306 0.08877295 0.875888 0.08877295 0.827857 0.101898 0.875888 0.08877295 0.863285 0.101898 0.827857 0.101898 0.880223 0.07082295 0.914794 0.07082295 0.875888 0.08877295 0.914794 0.07082295 0.910102 0.08877295 0.875888 0.08877295 0.914794 0.07082295 0.94703 0.07082295 0.910102 0.08877295 0.94703 0.07082295 0.942129 0.08877295 0.910102 0.08877295 0.94703 0.07082295 0.979042 0.07082295 0.942129 0.08877295 0.979042 0.07082295 0.974419 0.08877295 0.942129 0.08877295 0.497981 0.08877295 0.542671 0.08877295 0.497931 0.101898 0.542671 0.08877295 0.541093 0.101898 0.497931 0.101898 0.497931 0.101898 0.541093 0.101898 0.498033 0.113775 0.541093 0.101898 0.539807 0.113775 0.498033 0.113775 0.542671 0.08877295 0.586501 0.08877295 0.541093 0.101898 0.586501 0.08877295 0.583796 0.101898 0.541093 0.101898 0.541093 0.101898 0.583796 0.101898 0.539807 0.113775 0.583796 0.101898 0.581227 0.113775 0.539807 0.113775 0.497981 0.08877295 0.497931 0.101898 0.454715 0.101898 0.453182 0.08877295 0.497981 0.08877295 0.454715 0.101898 0.453182 0.08877295 0.454715 0.101898 0.411786 0.101898 0.408822 0.08877295 0.453182 0.08877295 0.411786 0.101898 0.408822 0.08877295 0.411786 0.101898 0.369753 0.101898 0.365246 0.08877295 0.408822 0.08877295 0.369753 0.101898 0.365246 0.08877295 0.369753 0.101898 0.328558 0.101898 0.322708 0.08877295 0.365246 0.08877295 0.328558 0.101898 0.322708 0.08877295 0.328558 0.101898 0.288415 0.101898 0.281408 0.08877295 0.322708 0.08877295 0.288415 0.101898 0.281408 0.08877295 0.288415 0.101898 0.249914 0.101898 0.241666 0.08877295 0.281408 0.08877295 0.249914 0.101898 0.241666 0.08877295 0.249914 0.101898 0.212984 0.101898 0.2036049 0.08877295 0.241666 0.08877295 0.212984 0.101898 0.2036049 0.08877295 0.212984 0.101898 0.1773999 0.101898 0.166799 0.08877295 0.2036049 0.08877295 0.1773999 0.101898 0.166799 0.08877295 0.1773999 0.101898 0.143133 0.101898 0.131163 0.08877295 0.166799 0.08877295 0.143133 0.101898 0.131163 0.08877295 0.143133 0.101898 0.110489 0.101898 0.09727698 0.08877295 0.131163 0.08877295 0.110489 0.101898 0.110489 0.101898 0.143133 0.101898 0.122662 0.113775 0.143133 0.101898 0.154218 0.113775 0.122662 0.113775 0.143133 0.101898 0.1773999 0.101898 0.154218 0.113775 0.1773999 0.101898 0.187257 0.113775 0.154218 0.113775 0.1773999 0.101898 0.212984 0.101898 0.187257 0.113775 0.212984 0.101898 0.221674 0.113775 0.187257 0.113775 0.212984 0.101898 0.249914 0.101898 0.221674 0.113775 0.249914 0.101898 0.25753 0.113775 0.221674 0.113775 0.249914 0.101898 0.288415 0.101898 0.25753 0.113775 0.288415 0.101898 0.294852 0.113775 0.25753 0.113775 0.288415 0.101898 0.328558 0.101898 0.294852 0.113775 0.328558 0.101898 0.333843 0.113775 0.294852 0.113775 0.328558 0.101898 0.369753 0.101898 0.333843 0.113775 0.369753 0.101898 0.373768 0.113775 0.333843 0.113775 0.369753 0.101898 0.411786 0.101898 0.373768 0.113775 0.411786 0.101898 0.414559 0.113775 0.373768 0.113775 0.411786 0.101898 0.454715 0.101898 0.414559 0.113775 0.454715 0.101898 0.456228 0.113775 0.414559 0.113775 0.454715 0.101898 0.497931 0.101898 0.456228 0.113775 0.497931 0.101898 0.498033 0.113775 0.456228 0.113775 0.498033 0.113775 0.539807 0.113775 0.498193 0.1297259 0.539807 0.113775 0.53888 0.1297259 0.498193 0.1297259 0.539807 0.113775 0.581227 0.113775 0.53888 0.1297259 0.581227 0.113775 0.579117 0.1297259 0.53888 0.1297259 0.581227 0.113775 0.622231 0.113775 0.579117 0.1297259 0.622231 0.113775 0.618878 0.1297259 0.579117 0.1297259 0.622231 0.113775 0.662932 0.113775 0.618878 0.1297259 0.662932 0.113775 0.658384 0.1297259 0.618878 0.1297259 0.662932 0.113775 0.703263 0.113775 0.658384 0.1297259 0.703263 0.113775 0.697492 0.1297259 0.658384 0.1297259 0.703263 0.113775 0.742873 0.113775 0.697492 0.1297259 0.742873 0.113775 0.735859 0.1297259 0.697492 0.1297259 0.742873 0.113775 0.781143 0.113775 0.735859 0.1297259 0.781143 0.113775 0.772949 0.1297259 0.735859 0.1297259 0.781143 0.113775 0.817555 0.113775 0.772949 0.1297259 0.817555 0.113775 0.808293 0.1297259 0.772949 0.1297259 0.817555 0.113775 0.851912 0.113775 0.808293 0.1297259 0.863285 0.101898 0.851912 0.113775 0.817555 0.113775 0.827857 0.101898 0.863285 0.101898 0.817555 0.113775 0.851912 0.113775 0.841643 0.1297259 0.808293 0.1297259 0.863285 0.101898 0.896463 0.101898 0.851912 0.113775 0.910102 0.08877295 0.896463 0.101898 0.863285 0.101898 0.875888 0.08877295 0.910102 0.08877295 0.863285 0.101898 0.896463 0.101898 0.884073 0.113775 0.851912 0.113775 0.851912 0.113775 0.884073 0.113775 0.841643 0.1297259 0.884073 0.113775 0.872809 0.1297259 0.841643 0.1297259 0.910102 0.08877295 0.942129 0.08877295 0.896463 0.101898 0.942129 0.08877295 0.927625 0.101898 0.896463 0.101898 0.896463 0.101898 0.927625 0.101898 0.884073 0.113775 0.927625 0.101898 0.914106 0.113775 0.884073 0.113775 0.884073 0.113775 0.914106 0.113775 0.872809 0.1297259 0.914106 0.113775 0.901486 0.1297259 0.872809 0.1297259 0.942129 0.08877295 0.974419 0.08877295 0.927625 0.101898 0.974419 0.08877295 0.958449 0.101898 0.927625 0.101898 0.927625 0.101898 0.958449 0.101898 0.914106 0.113775 0.958449 0.101898 0.942298 0.113775 0.914106 0.113775 0.914106 0.113775 0.942298 0.113775 0.901486 0.1297259 0.942298 0.113775 0.927269 0.1297259 0.901486 0.1297259 0.498193 0.1297259 0.53888 0.1297259 0.498246 0.140136 0.53888 0.1297259 0.538478 0.140136 0.498246 0.140136 0.498246 0.140136 0.538478 0.140136 0.498315 0.152971 0.538478 0.140136 0.538046 0.152971 0.498315 0.152971 0.53888 0.1297259 0.579117 0.1297259 0.538478 0.140136 0.579117 0.1297259 0.578292 0.140136 0.538478 0.140136 0.538478 0.140136 0.578292 0.140136 0.538046 0.152971 0.578292 0.140136 0.577423 0.152971 0.538046 0.152971 0.579117 0.1297259 0.618878 0.1297259 0.578292 0.140136 0.618878 0.1297259 0.617612 0.140136 0.578292 0.140136 0.578292 0.140136 0.617612 0.140136 0.577423 0.152971 0.617612 0.140136 0.616245 0.152971 0.577423 0.152971 0.618878 0.1297259 0.658384 0.1297259 0.617612 0.140136 0.658384 0.1297259 0.656693 0.140136 0.617612 0.140136 0.617612 0.140136 0.656693 0.140136 0.616245 0.152971 0.656693 0.140136 0.654864 0.152971 0.616245 0.152971 0.658384 0.1297259 0.697492 0.1297259 0.656693 0.140136 0.697492 0.1297259 0.69538 0.140136 0.656693 0.140136 0.656693 0.140136 0.69538 0.140136 0.654864 0.152971 0.69538 0.140136 0.693096 0.152971 0.654864 0.152971 0.697492 0.1297259 0.735859 0.1297259 0.69538 0.140136 0.735859 0.1297259 0.733325 0.140136 0.69538 0.140136 0.69538 0.140136 0.733325 0.140136 0.693096 0.152971 0.733325 0.140136 0.730592 0.152971 0.693096 0.152971 0.735859 0.1297259 0.772949 0.1297259 0.733325 0.140136 0.772949 0.1297259 0.770015 0.140136 0.733325 0.140136 0.733325 0.140136 0.770015 0.140136 0.730592 0.152971 0.770015 0.140136 0.766855 0.152971 0.730592 0.152971 0.772949 0.1297259 0.808293 0.1297259 0.770015 0.140136 0.808293 0.1297259 0.804989 0.140136 0.770015 0.140136 0.770015 0.140136 0.804989 0.140136 0.766855 0.152971 0.804989 0.140136 0.801428 0.152971 0.766855 0.152971 0.808293 0.1297259 0.841643 0.1297259 0.804989 0.140136 0.841643 0.1297259 0.837988 0.140136 0.804989 0.140136 0.804989 0.140136 0.837988 0.140136 0.801428 0.152971 0.837988 0.140136 0.834047 0.152971 0.801428 0.152971 0.841643 0.1297259 0.872809 0.1297259 0.837988 0.140136 0.872809 0.1297259 0.868808 0.140136 0.837988 0.140136 0.837988 0.140136 0.868808 0.140136 0.834047 0.152971 0.868808 0.140136 0.864493 0.152971 0.834047 0.152971 0.872809 0.1297259 0.901486 0.1297259 0.868808 0.140136 0.901486 0.1297259 0.897175 0.140136 0.868808 0.140136 0.868808 0.140136 0.897175 0.140136 0.864493 0.152971 0.897175 0.140136 0.892456 0.152971 0.864493 0.152971 0.901486 0.1297259 0.927269 0.1297259 0.897175 0.140136 0.927269 0.1297259 0.922834 0.140136 0.897175 0.140136 0.897175 0.140136 0.922834 0.140136 0.892456 0.152971 0.922834 0.140136 0.917439 0.152971 0.892456 0.152971 0.028638 0.07082295 0.06044697 0.07082295 0.03358 0.08877295 0.06044697 0.07082295 0.06551897 0.08877295 0.03358 0.08877295 0.06044697 0.07082295 0.09260195 0.07082295 0.06551897 0.08877295 0.09260195 0.07082295 0.09727698 0.08877295 0.06551897 0.08877295 0.09260195 0.07082295 0.126944 0.07082295 0.09727698 0.08877295 0.126944 0.07082295 0.131163 0.08877295 0.09727698 0.08877295 0.126944 0.07082295 0.163057 0.07082295 0.131163 0.08877295 0.163057 0.07082295 0.166799 0.08877295 0.131163 0.08877295 0.163057 0.07082295 0.200381 0.07082295 0.166799 0.08877295 0.200381 0.07082295 0.2036049 0.08877295 0.166799 0.08877295 0.200381 0.07082295 0.238752 0.07082295 0.2036049 0.08877295 0.238752 0.07082295 0.241666 0.08877295 0.2036049 0.08877295 0.238752 0.07082295 0.278904 0.07082295 0.241666 0.08877295 0.278904 0.07082295 0.281408 0.08877295 0.241666 0.08877295 0.278904 0.07082295 0.32068 0.07082295 0.281408 0.08877295 0.32068 0.07082295 0.322708 0.08877295 0.281408 0.08877295 0.32068 0.07082295 0.36368 0.07082295 0.322708 0.08877295 0.36368 0.07082295 0.365246 0.08877295 0.322708 0.08877295 0.36368 0.07082295 0.407726 0.07082295 0.365246 0.08877295 0.407726 0.07082295 0.408822 0.08877295 0.365246 0.08877295 0.407726 0.07082295 0.452605 0.07082295 0.408822 0.08877295 0.452605 0.07082295 0.453182 0.08877295 0.408822 0.08877295 0.452605 0.07082295 0.497935 0.07082295 0.453182 0.08877295 0.497935 0.07082295 0.497981 0.08877295 0.453182 0.08877295 0.03358 0.08877295 0.06551897 0.08877295 0.05011695 0.101898 0.06551897 0.08877295 0.07987499 0.101898 0.05011695 0.101898 0.05011695 0.101898 0.07987499 0.101898 0.06625896 0.113775 0.07987499 0.101898 0.09322595 0.113775 0.06625896 0.113775 0.06625896 0.113775 0.09322595 0.113775 0.080531 0.1297259 0.09322595 0.113775 0.10576 0.1297259 0.080531 0.1297259 0.06551897 0.08877295 0.09727698 0.08877295 0.07987499 0.101898 0.09727698 0.08877295 0.110489 0.101898 0.07987499 0.101898 0.07987499 0.101898 0.110489 0.101898 0.09322595 0.113775 0.110489 0.101898 0.122662 0.113775 0.09322595 0.113775 0.09322595 0.113775 0.122662 0.113775 0.10576 0.1297259 0.122662 0.113775 0.134295 0.1297259 0.10576 0.1297259 0.122662 0.113775 0.154218 0.113775 0.134295 0.1297259 0.154218 0.113775 0.16442 0.1297259 0.134295 0.1297259 0.154218 0.113775 0.187257 0.113775 0.16442 0.1297259 0.187257 0.113775 0.196301 0.1297259 0.16442 0.1297259 0.187257 0.113775 0.221674 0.113775 0.196301 0.1297259 0.221674 0.113775 0.229607 0.1297259 0.196301 0.1297259 0.221674 0.113775 0.25753 0.113775 0.229607 0.1297259 0.25753 0.113775 0.264349 0.1297259 0.229607 0.1297259 0.25753 0.113775 0.294852 0.113775 0.264349 0.1297259 0.294852 0.113775 0.300955 0.1297259 0.264349 0.1297259 0.294852 0.113775 0.333843 0.113775 0.300955 0.1297259 0.333843 0.113775 0.338598 0.1297259 0.300955 0.1297259 0.333843 0.113775 0.373768 0.113775 0.338598 0.1297259 0.373768 0.113775 0.37738 0.1297259 0.338598 0.1297259 0.373768 0.113775 0.414559 0.113775 0.37738 0.1297259 0.414559 0.113775 0.417199 0.1297259 0.37738 0.1297259 0.414559 0.113775 0.456228 0.113775 0.417199 0.1297259 0.456228 0.113775 0.457525 0.1297259 0.417199 0.1297259 0.456228 0.113775 0.498033 0.113775 0.457525 0.1297259 0.498033 0.113775 0.498193 0.1297259 0.457525 0.1297259 0.080531 0.1297259 0.10576 0.1297259 0.08523398 0.140136 0.10576 0.1297259 0.110186 0.140136 0.08523398 0.140136 0.08523398 0.140136 0.110186 0.140136 0.09042799 0.152971 0.110186 0.140136 0.114798 0.152971 0.09042799 0.152971 0.10576 0.1297259 0.134295 0.1297259 0.110186 0.140136 0.134295 0.1297259 0.138254 0.140136 0.110186 0.140136 0.110186 0.140136 0.138254 0.140136 0.114798 0.152971 0.138254 0.140136 0.142554 0.152971 0.114798 0.152971 0.134295 0.1297259 0.16442 0.1297259 0.138254 0.140136 0.16442 0.1297259 0.168044 0.140136 0.138254 0.140136 0.138254 0.140136 0.168044 0.140136 0.142554 0.152971 0.168044 0.140136 0.17198 0.152971 0.142554 0.152971 0.16442 0.1297259 0.196301 0.1297259 0.168044 0.140136 0.196301 0.1297259 0.19953 0.140136 0.168044 0.140136 0.168044 0.140136 0.19953 0.140136 0.17198 0.152971 0.19953 0.140136 0.20304 0.152971 0.17198 0.152971 0.196301 0.1297259 0.229607 0.1297259 0.19953 0.140136 0.229607 0.1297259 0.23245 0.140136 0.19953 0.140136 0.19953 0.140136 0.23245 0.140136 0.20304 0.152971 0.23245 0.140136 0.2355369 0.152971 0.20304 0.152971 0.229607 0.1297259 0.264349 0.1297259 0.23245 0.140136 0.264349 0.1297259 0.266794 0.140136 0.23245 0.140136 0.23245 0.140136 0.266794 0.140136 0.2355369 0.152971 0.266794 0.140136 0.269436 0.152971 0.2355369 0.152971 0.264349 0.1297259 0.300955 0.1297259 0.266794 0.140136 0.300955 0.1297259 0.303016 0.140136 0.266794 0.140136 0.266794 0.140136 0.303016 0.140136 0.269436 0.152971 0.303016 0.140136 0.305259 0.152971 0.269436 0.152971 0.300955 0.1297259 0.338598 0.1297259 0.303016 0.140136 0.338598 0.1297259 0.340322 0.140136 0.303016 0.140136 0.303016 0.140136 0.340322 0.140136 0.305259 0.152971 0.340322 0.140136 0.342198 0.152971 0.305259 0.152971 0.338598 0.1297259 0.37738 0.1297259 0.340322 0.140136 0.37738 0.1297259 0.378667 0.140136 0.340322 0.140136 0.340322 0.140136 0.378667 0.140136 0.342198 0.152971 0.378667 0.140136 0.380062 0.152971 0.342198 0.152971 0.37738 0.1297259 0.417199 0.1297259 0.378667 0.140136 0.417199 0.1297259 0.418079 0.140136 0.378667 0.140136 0.378667 0.140136 0.418079 0.140136 0.380062 0.152971 0.418079 0.140136 0.419045 0.152971 0.380062 0.152971 0.417199 0.1297259 0.457525 0.1297259 0.418079 0.140136 0.457525 0.1297259 0.458044 0.140136 0.418079 0.140136 0.418079 0.140136 0.458044 0.140136 0.419045 0.152971 0.458044 0.140136 0.458621 0.152971 0.419045 0.152971 0.457525 0.1297259 0.498193 0.1297259 0.458044 0.140136 0.498193 0.1297259 0.498246 0.140136 0.458044 0.140136 0.458044 0.140136 0.498246 0.140136 0.458621 0.152971 0.498246 0.140136 0.498315 0.152971 0.458621 0.152971 0.263502 0.732761 0.23444 0.956097 0.1776 0.940866 0.263502 0.732761 0.293284 0.956097 0.23444 0.956097 0.263502 0.732761 0.350124 0.940866 0.293284 0.956097 0.263502 0.732761 0.401085 0.911444 0.350124 0.940866 0.263502 0.732761 0.442694 0.869835 0.401085 0.911444 0.263502 0.732761 0.472116 0.818874 0.442694 0.869835 0.263502 0.732761 0.487347 0.762034 0.472116 0.818874 0.263502 0.732761 0.487347 0.703189 0.487347 0.762034 0.263502 0.732761 0.472116 0.64635 0.487347 0.703189 0.263502 0.732761 0.442694 0.595389 0.472116 0.64635 0.263502 0.732761 0.401085 0.553779 0.442694 0.595389 0.263502 0.732761 0.350124 0.524357 0.401085 0.553779 0.263502 0.732761 0.293284 0.509127 0.350124 0.524357 0.263502 0.732761 0.234439 0.509127 0.293284 0.509127 0.263502 0.732761 0.1776 0.524357 0.234439 0.509127 0.263502 0.732761 0.126639 0.55378 0.1776 0.524357 0.263502 0.732761 0.085029 0.595389 0.126639 0.55378 0.263502 0.732761 0.05560696 0.64635 0.085029 0.595389 0.263502 0.732761 0.04037696 0.70319 0.05560696 0.64635 0.263502 0.732761 0.04037696 0.762035 0.04037696 0.70319 0.263502 0.732761 0.05560696 0.818874 0.04037696 0.762035 0.263502 0.732761 0.08502995 0.869835 0.05560696 0.818874 0.263502 0.732761 0.126639 0.911444 0.08502995 0.869835 0.263502 0.732761 0.1776 0.940866 0.126639 0.911444 0.556957 0.497392 0.556957 0.447505 0.746185 0.472757 0.556957 0.447505 0.569869 0.399317 0.746185 0.472757 0.569869 0.399317 0.594812 0.356114 0.746185 0.472757 0.594812 0.356114 0.630088 0.320839 0.746185 0.472757 0.630088 0.320839 0.673291 0.295895 0.746185 0.472757 0.673291 0.295895 0.721478 0.282983 0.746185 0.472757 0.721478 0.282983 0.771365 0.282983 0.746185 0.472757 0.771365 0.282983 0.819552 0.295895 0.746185 0.472757 0.819552 0.295895 0.862756 0.320838 0.746185 0.472757 0.862756 0.320838 0.898031 0.356114 0.746185 0.472757 0.898031 0.356114 0.922975 0.399317 0.746185 0.472757 0.922975 0.399317 0.935887 0.447505 0.746185 0.472757 0.935887 0.447505 0.935887 0.497392 0.746185 0.472757 0.935887 0.497392 0.922975 0.545579 0.746185 0.472757 0.922975 0.545579 0.898031 0.588782 0.746185 0.472757 0.898031 0.588782 0.862756 0.624058 0.746185 0.472757 0.862756 0.624058 0.819552 0.649001 0.746185 0.472757 0.819552 0.649001 0.771365 0.661913 0.746185 0.472757 0.771365 0.661913 0.721478 0.661913 0.746185 0.472757 0.721478 0.661913 0.673291 0.649001 0.746185 0.472757 0.673291 0.649001 0.630087 0.624058 0.746185 0.472757 0.630087 0.624058 0.594812 0.588782 0.746185 0.472757 0.594812 0.588782 0.569868 0.545579 0.746185 0.472757 0.569868 0.545579 0.556957 0.497392 0.746185 0.472757 + + + + + + + + + 0.2350667 0.5944423 0.236442 0.5852586 0.1800367 0.5688781 0.2350667 0.5944423 0.1800367 0.5688781 0.1761345 0.5773187 0.1800367 0.5688781 0.1311475 0.5370425 0.1761345 0.5773187 0.1311475 0.5370425 0.1245415 0.5436798 0.1761345 0.5773187 0.1311475 0.5370425 0.09787863 0.4901666 0.1245415 0.5436798 0.09787863 0.4901666 0.09049338 0.4943432 0.1245415 0.5436798 0.1245415 0.5436798 0.09049338 0.4943432 0.09589761 0.5627111 0.09049338 0.4943432 0.0641511 0.5072736 0.09589761 0.5627111 0.09589761 0.5627111 0.0641511 0.5072736 0.06957656 0.5749213 0.0641511 0.5072736 0.03961127 0.5188692 0.06957656 0.5749213 0.09787863 0.4901666 0.07653158 0.442074 0.09049338 0.4943432 0.07653158 0.442074 0.06883269 0.4446325 0.09049338 0.4943432 0.09049338 0.4943432 0.06883269 0.4446325 0.0641511 0.5072736 0.06883269 0.4446325 0.0417397 0.4527056 0.0641511 0.5072736 0.0641511 0.5072736 0.0417397 0.4527056 0.03961127 0.5188692 0.0417397 0.4527056 0.01629096 0.460441 0.03961127 0.5188692 0.07653158 0.442074 0.06556189 0.3927496 0.06883269 0.4446325 0.06556189 0.3927496 0.05767703 0.3936865 0.06883269 0.4446325 0.06883269 0.4446325 0.05767703 0.3936865 0.0417397 0.4527056 0.05767703 0.3936865 0.0300439 0.3963494 0.0417397 0.4527056 0.0417397 0.4527056 0.0300439 0.3963494 0.01629096 0.460441 0.0300439 0.3963494 0.00390625 0.3991305 0.01629096 0.460441 0.06556189 0.3927496 0.06497049 0.3430217 0.05767703 0.3936865 0.06497049 0.3430217 0.05707472 0.3423448 0.05767703 0.3936865 0.05767703 0.3936865 0.05707472 0.3423448 0.0300439 0.3963494 0.05707472 0.3423448 0.02971023 0.3395568 0.0300439 0.3963494 0.0300439 0.3963494 0.02971023 0.3395568 0.00390625 0.3991305 0.02971023 0.3395568 0.00390625 0.3372796 0.00390625 0.3991305 0.06497049 0.3430217 0.07437455 0.2938694 0.05707472 0.3423448 0.07437455 0.2938694 0.06659692 0.2915712 0.05707472 0.3423448 0.05707472 0.3423448 0.06659692 0.2915712 0.02971023 0.3395568 0.06659692 0.2915712 0.03990733 0.2838791 0.02971023 0.3395568 0.02971023 0.3395568 0.03990733 0.2838791 0.00390625 0.3372796 0.03990733 0.2838791 0.01529473 0.2776388 0.00390625 0.3372796 0.07437455 0.2938694 0.09369289 0.245186 0.06659692 0.2915712 0.09369289 0.245186 0.08613568 0.2410319 0.06659692 0.2915712 0.06659692 0.2915712 0.08613568 0.2410319 0.03990733 0.2838791 0.08613568 0.2410319 0.05916076 0.2271876 0.03990733 0.2838791 0.03990733 0.2838791 0.05916076 0.2271876 0.01529473 0.2776388 0.05916076 0.2271876 0.03322398 0.221123 0.01529473 0.2776388 0.09369289 0.245186 0.1262683 0.1996575 0.08613568 0.2410319 0.1262683 0.1996575 0.1197991 0.1930412 0.08613568 0.2410319 0.08613568 0.2410319 0.1197991 0.1930412 0.05916076 0.2271876 0.1197991 0.1930412 0.09383791 0.1756151 0.05916076 0.2271876 0.1262683 0.1996575 0.1738846 0.1667155 0.1197991 0.1930412 0.1738846 0.1667155 0.1698107 0.1584594 0.1197991 0.1930412 0.1738846 0.1667155 0.2292709 0.1485136 0.1698107 0.1584594 0.2292709 0.1485136 0.2276279 0.1394425 0.1698107 0.1584594 0.2292709 0.1485136 0.2876806 0.1458148 0.2276279 0.1394425 0.2876806 0.1458148 0.2885111 0.1366223 0.2276279 0.1394425 0.5831499 0.09723418 0.6392333 0.07750499 0.5745477 0.06898558 0.6392333 0.07750499 0.6284694 0.04977446 0.5745477 0.06898558 0.5745477 0.06898558 0.6284694 0.04977446 0.5672938 0.04553133 0.6284694 0.04977446 0.6193705 0.02707022 0.5672938 0.04553133 0.6392333 0.07750499 0.6943629 0.05367654 0.6284694 0.04977446 0.6943629 0.05367654 0.6819697 0.0257048 0.6284694 0.04977446 0.6284694 0.04977446 0.6819697 0.0257048 0.6193705 0.02707022 0.6819697 0.0257048 0.6698388 0.00390625 0.6193705 0.02707022 0.5831499 0.09723418 0.5745477 0.06898558 0.5193687 0.08390897 0.525815 0.1127023 0.5831499 0.09723418 0.5193687 0.08390897 0.525815 0.1127023 0.5193687 0.08390897 0.4632171 0.0946123 0.4674758 0.1238127 0.525815 0.1127023 0.4632171 0.0946123 0.4674758 0.1238127 0.4632171 0.0946123 0.4064087 0.1010535 0.4084558 0.1304971 0.4674758 0.1238127 0.4064087 0.1010535 0.4084558 0.1304971 0.4064087 0.1010535 0.3492653 0.1031962 0.3490877 0.1327161 0.4084558 0.1304971 0.3492653 0.1031962 0.3490877 0.1327161 0.3492653 0.1031962 0.2921115 0.1010265 0.2897101 0.130455 0.3490877 0.1327161 0.2921115 0.1010265 0.2897101 0.130455 0.2921115 0.1010265 0.2352721 0.09455591 0.2306596 0.1237252 0.2897101 0.130455 0.2352721 0.09455591 0.2306596 0.1237252 0.2352721 0.09455591 0.1790698 0.08382123 0.1722739 0.112564 0.2306596 0.1237252 0.1790698 0.08382123 0.1722739 0.112564 0.1790698 0.08382123 0.1238058 0.06889402 0.114885 0.09703874 0.1722739 0.112564 0.1238058 0.06889402 0.114885 0.09703874 0.1238058 0.06889402 0.0696392 0.04993075 0.05882787 0.07730001 0.114885 0.09703874 0.0696392 0.04993075 0.05882787 0.07730001 0.0696392 0.04993075 0.01560503 0.0264728 0.00390625 0.05407291 0.05882787 0.07730001 0.01560503 0.0264728 0.01560503 0.0264728 0.0696392 0.04993075 0.02767962 0.00390625 0.0696392 0.04993075 0.07888078 0.02687853 0.02767962 0.00390625 0.0696392 0.04993075 0.1238058 0.06889402 0.07888078 0.02687853 0.1238058 0.06889402 0.1311852 0.0453937 0.07888078 0.02687853 0.1238058 0.06889402 0.1790698 0.08382123 0.1311852 0.0453937 0.1790698 0.08382123 0.1846489 0.05986011 0.1311852 0.0453937 0.1790698 0.08382123 0.2352721 0.09455591 0.1846489 0.05986011 0.2352721 0.09455591 0.2390297 0.07025092 0.1846489 0.05986011 0.2352721 0.09455591 0.2921115 0.1010265 0.2390297 0.07025092 0.2921115 0.1010265 0.2940266 0.07651305 0.2390297 0.07025092 0.2921115 0.1010265 0.3492653 0.1031962 0.2940266 0.07651305 0.3492653 0.1031962 0.3493282 0.07861375 0.2940266 0.07651305 0.3492653 0.1031962 0.4064087 0.1010535 0.3493282 0.07861375 0.4064087 0.1010535 0.4046192 0.076541 0.3493282 0.07861375 0.4064087 0.1010535 0.4632171 0.0946123 0.4046192 0.076541 0.4632171 0.0946123 0.459586 0.07030946 0.4046192 0.076541 0.4632171 0.0946123 0.5193687 0.08390897 0.459586 0.07030946 0.5193687 0.08390897 0.5139161 0.05995464 0.459586 0.07030946 0.5193687 0.08390897 0.5745477 0.06898558 0.5139161 0.05995464 0.5745477 0.06898558 0.5672938 0.04553133 0.5139161 0.05995464 0.9582458 0.3222229 0.9390272 0.2623018 0.9364184 0.3260506 0.9390272 0.2623018 0.9192036 0.2717746 0.9364184 0.3260506 0.9390272 0.2623018 0.9047072 0.2103503 0.9192036 0.2717746 0.9047072 0.2103503 0.8884084 0.2246392 0.9192036 0.2717746 0.9047072 0.2103503 0.8582402 0.1703261 0.8884084 0.2246392 0.8582402 0.1703261 0.846688 0.1882102 0.8884084 0.2246392 0.8582402 0.1703261 0.8035733 0.1451821 0.846688 0.1882102 0.8035733 0.1451821 0.7975903 0.165144 0.846688 0.1882102 0.8035733 0.1451821 0.7453272 0.1366223 0.7975903 0.165144 0.7453272 0.1366223 0.7452702 0.1569747 0.7975903 0.165144 0.7453272 0.1366223 0.6884095 0.1449695 0.7452702 0.1569747 0.6884095 0.1449695 0.6941417 0.1639945 0.7452702 0.1569747 0.6884095 0.1449695 0.6376188 0.1691383 0.6941417 0.1639945 0.6376188 0.1691383 0.6485199 0.1852265 0.6941417 0.1639945 0.6376188 0.1691383 0.5972502 0.206721 0.6485199 0.1852265 0.5972502 0.206721 0.6122664 0.2185064 0.6485199 0.1852265 0.5972502 0.206721 0.5716609 0.2529014 0.6122664 0.2185064 0.549771 0.2438524 0.5716609 0.2529014 0.5972502 0.206721 0.5771115 0.1936393 0.549771 0.2438524 0.5972502 0.206721 0.5716609 0.2529014 0.5885241 0.2601137 0.6122664 0.2185064 0.549771 0.2438524 0.5352486 0.2963944 0.5716609 0.2529014 0.5085309 0.2908549 0.5352486 0.2963944 0.549771 0.2438524 0.5225851 0.2367655 0.5085309 0.2908549 0.549771 0.2438524 0.5352486 0.2963944 0.5572178 0.301274 0.5716609 0.2529014 0.5716609 0.2529014 0.5572178 0.301274 0.5885241 0.2601137 0.5572178 0.301274 0.5746446 0.3051185 0.5885241 0.2601137 0.5085309 0.2908549 0.5007624 0.3462888 0.5352486 0.2963944 0.5007624 0.3462888 0.5281035 0.3483402 0.5352486 0.2963944 0.5352486 0.2963944 0.5281035 0.3483402 0.5572178 0.301274 0.5281035 0.3483402 0.5503051 0.3500352 0.5572178 0.301274 0.5572178 0.301274 0.5503051 0.3500352 0.5746446 0.3051185 0.5503051 0.3500352 0.567955 0.3512266 0.5746446 0.3051185 0.5007624 0.3462888 0.5007624 0.4023982 0.5281035 0.3483402 0.5007624 0.4023982 0.5282323 0.4006037 0.5281035 0.3483402 0.5281035 0.3483402 0.5282323 0.4006037 0.5503051 0.3500352 0.5282323 0.4006037 0.5504519 0.3990953 0.5503051 0.3500352 0.5503051 0.3500352 0.5504519 0.3990953 0.567955 0.3512266 0.5504519 0.3990953 0.5680606 0.3976911 0.567955 0.3512266 0.00390625 0.7716867 0.003906309 0.8240724 0.01235991 0.7728291 0.003906309 0.8240724 0.0123676 0.8229879 0.01235991 0.7728291 0.01235991 0.7728291 0.0123676 0.8229879 0.02005803 0.7738682 0.0123676 0.8229879 0.02007251 0.8219993 0.02005803 0.7738682 0.003906309 0.8240724 0.01746517 0.8746736 0.0123676 0.8229879 0.01746517 0.8746736 0.02535736 0.8714362 0.0123676 0.8229879 0.0123676 0.8229879 0.02535736 0.8714362 0.02007251 0.8219993 0.02535736 0.8714362 0.03254371 0.8684865 0.02007251 0.8219993 0.01746517 0.8746736 0.04365783 0.9200402 0.02535736 0.8714362 0.04365783 0.9200402 0.05044317 0.9148704 0.02535736 0.8714362 0.02535736 0.8714362 0.05044317 0.9148704 0.03254371 0.8684865 0.05044317 0.9148704 0.05662149 0.9101615 0.03254371 0.8684865 0.04365783 0.9200402 0.08070057 0.9570817 0.05044317 0.9148704 0.08070057 0.9570817 0.08591663 0.9503319 0.05044317 0.9148704 0.05044317 0.9148704 0.08591663 0.9503319 0.05662149 0.9101615 0.08591663 0.9503319 0.09066498 0.9441852 0.05662149 0.9101615 0.08070057 0.9570817 0.1260671 0.9832739 0.08591663 0.9503319 0.1260671 0.9832739 0.1293585 0.9754042 0.08591663 0.9503319 0.08591663 0.9503319 0.1293585 0.9754042 0.09066498 0.9441852 0.1293585 0.9754042 0.1323543 0.9682372 0.09066498 0.9441852 0.1260671 0.9832739 0.1766665 0.9968319 0.1293585 0.9754042 0.1766665 0.9968319 0.177809 0.9883784 0.1293585 0.9754042 0.1293585 0.9754042 0.177809 0.9883784 0.1323543 0.9682372 0.177809 0.9883784 0.1788479 0.9806805 0.1323543 0.9682372 0.1766665 0.9968319 0.2290507 0.9968319 0.177809 0.9883784 0.2290507 0.9968319 0.2279663 0.9883708 0.177809 0.9883784 0.177809 0.9883784 0.2279663 0.9883708 0.1788479 0.9806805 0.2279663 0.9883708 0.2269777 0.9806662 0.1788479 0.9806805 0.2290507 0.9968319 0.2796507 0.983274 0.2279663 0.9883708 0.2796507 0.983274 0.2764135 0.975382 0.2279663 0.9883708 0.2279663 0.9883708 0.2764135 0.975382 0.2269777 0.9806662 0.2764135 0.975382 0.273464 0.9681957 0.2269777 0.9806662 0.2796507 0.983274 0.3250167 0.9570827 0.2764135 0.975382 0.3250167 0.9570827 0.3198472 0.9502974 0.2764135 0.975382 0.2764135 0.975382 0.3198472 0.9502974 0.273464 0.9681957 0.3198472 0.9502974 0.3151385 0.9441192 0.273464 0.9681957 0.3250167 0.9570827 0.3620584 0.9200416 0.3198472 0.9502974 0.3620584 0.9200416 0.3553088 0.9148254 0.3198472 0.9502974 0.3198472 0.9502974 0.3553088 0.9148254 0.3151385 0.9441192 0.3553088 0.9148254 0.3491623 0.910077 0.3151385 0.9441192 0.3620584 0.9200416 0.3882515 0.8746762 0.3553088 0.9148254 0.3882515 0.8746762 0.380382 0.8713846 0.3553088 0.9148254 0.3553088 0.9148254 0.380382 0.8713846 0.3491623 0.910077 0.380382 0.8713846 0.3732151 0.8683887 0.3491623 0.910077 0.3882515 0.8746762 0.4018109 0.8240774 0.380382 0.8713846 0.4018109 0.8240774 0.3933575 0.8229348 0.380382 0.8713846 0.380382 0.8713846 0.3933575 0.8229348 0.3732151 0.8683887 0.3933575 0.8229348 0.3856596 0.8218955 0.3732151 0.8683887 0.2876806 0.1458148 0.3448049 0.158658 0.2885111 0.1366223 0.3448049 0.158658 0.3480328 0.1500026 0.2885111 0.1366223 0.3448049 0.158658 0.3965741 0.186105 0.3480328 0.1500026 0.3965741 0.186105 0.4019686 0.1785997 0.3480328 0.1500026 0.3965741 0.186105 0.4393269 0.2262251 0.4019686 0.1785997 0.4393269 0.2262251 0.4465098 0.2203998 0.4019686 0.1785997 0.4393269 0.2262251 0.4700425 0.2762028 0.4465098 0.2203998 0.4700425 0.2762028 0.4785091 0.2724682 0.4465098 0.2203998 0.4700425 0.2762028 0.4865443 0.332527 0.4785091 0.2724682 0.4865443 0.332527 0.4956995 0.3311497 0.4785091 0.2724682 0.4865443 0.332527 0.4876552 0.3912376 0.4956995 0.3311497 0.4876552 0.3912376 0.4968561 0.3923168 0.4956995 0.3311497 0.4876552 0.3912376 0.4732818 0.4482042 0.4968561 0.3923168 0.4732818 0.4482042 0.4818778 0.4516662 0.4968561 0.3923168 0.4732818 0.4482042 0.4444195 0.4994119 0.4818778 0.4516662 0.4444195 0.4994119 0.4518064 0.5050151 0.4818778 0.4516662 0.4444195 0.4994119 0.403086 0.541247 0.4518064 0.5050151 0.403086 0.541247 0.4087414 0.5486003 0.4518064 0.5050151 0.403086 0.541247 0.3521791 0.570749 0.4087414 0.5486003 0.3521791 0.570749 0.3557021 0.5793358 0.4087414 0.5486003 0.3521791 0.570749 0.2952822 0.5858036 0.3557021 0.5793358 0.2952822 0.5858036 0.2964122 0.5950196 0.3557021 0.5793358 0.2952822 0.5858036 0.236442 0.5852586 0.2964122 0.5950196 0.236442 0.5852586 0.2350667 0.5944423 0.2964122 0.5950196 0.5007624 0.4023982 0.5086093 0.4581709 0.5282323 0.4006037 0.5086093 0.4581709 0.5359614 0.4526122 0.5282323 0.4006037 0.5282323 0.4006037 0.5359614 0.4526122 0.5504519 0.3990953 0.5359614 0.4526122 0.5578754 0.4478012 0.5504519 0.3990953 0.5504519 0.3990953 0.5578754 0.4478012 0.5680606 0.3976911 0.5578754 0.4478012 0.5750622 0.4436005 0.5680606 0.3976911 0.5086093 0.4581709 0.5235196 0.5133897 0.5359614 0.4526122 0.5235196 0.5133897 0.5515438 0.5054265 0.5359614 0.4526122 0.5359614 0.4526122 0.5515438 0.5054265 0.5578754 0.4478012 0.5515438 0.5054265 0.5737707 0.4964572 0.5578754 0.4478012 0.5578754 0.4478012 0.5737707 0.4964572 0.5750622 0.4436005 0.5737707 0.4964572 0.59014 0.4877992 0.5750622 0.4436005 0.5737707 0.4964572 0.605697 0.5394954 0.59014 0.4877992 0.605697 0.5394954 0.6189324 0.5259033 0.59014 0.4877992 0.605697 0.5394954 0.6502678 0.5716481 0.6189324 0.5259033 0.6502678 0.5716481 0.6590859 0.5542367 0.6189324 0.5259033 0.6502678 0.5716481 0.703812 0.5897448 0.6590859 0.5542367 0.703812 0.5897448 0.7073009 0.569949 0.6590859 0.5542367 0.703812 0.5897448 0.7619094 0.5917937 0.7073009 0.569949 0.7619094 0.5917937 0.7596024 0.5712465 0.7073009 0.569949 0.7619094 0.5917937 0.8197503 0.5771416 0.7596024 0.5712465 0.8197503 0.5771416 0.8116669 0.5575442 0.7596024 0.5712465 0.8197503 0.5771416 0.8725323 0.5465329 0.8116669 0.5575442 0.8725323 0.5465329 0.8591743 0.5295135 0.8116669 0.5575442 0.8725323 0.5465329 0.9158528 0.5020529 0.8591743 0.5295135 0.9158528 0.5020529 0.8981696 0.4890326 0.8591743 0.5295135 0.9158528 0.5020529 0.9460767 0.4469625 0.8981696 0.4890326 0.9460767 0.4469625 0.9253852 0.4390378 0.8981696 0.4890326 0.9460767 0.4469625 0.9606349 0.3854345 0.9253852 0.4390378 0.9606349 0.3854345 0.9385173 0.3832853 0.9253852 0.4390378 0.9606349 0.3854345 0.9582458 0.3222229 0.9385173 0.3832853 0.9582458 0.3222229 0.9364184 0.3260506 0.9385173 0.3832853 0.4018109 0.8240774 0.4018126 0.7716931 0.3933575 0.8229348 0.4018126 0.7716931 0.3933514 0.7727771 0.3933575 0.8229348 0.3933575 0.8229348 0.3933514 0.7727771 0.3856596 0.8218955 0.3933514 0.7727771 0.3856467 0.7737655 0.3856596 0.8218955 0.4018126 0.7716931 0.3882562 0.7210919 0.3933514 0.7727771 0.3882562 0.7210919 0.3803631 0.7243294 0.3933514 0.7727771 0.3933514 0.7727771 0.3803631 0.7243294 0.3856467 0.7737655 0.3803631 0.7243294 0.3731773 0.7272785 0.3856467 0.7737655 0.3882562 0.7210919 0.362065 0.675724 0.3803631 0.7243294 0.362065 0.675724 0.3552787 0.6808941 0.3803631 0.7243294 0.3803631 0.7243294 0.3552787 0.6808941 0.3731773 0.7272785 0.3552787 0.6808941 0.349101 0.685603 0.3731773 0.7272785 0.362065 0.675724 0.3250243 0.6386809 0.3552787 0.6808941 0.3250243 0.6386809 0.3198074 0.6454313 0.3552787 0.6808941 0.3552787 0.6808941 0.3198074 0.6454313 0.349101 0.685603 0.3198074 0.6454313 0.3150587 0.6515786 0.349101 0.685603 0.3250243 0.6386809 0.2796576 0.6124872 0.3198074 0.6454313 0.2796576 0.6124872 0.2763658 0.620357 0.3198074 0.6454313 0.3198074 0.6454313 0.2763658 0.620357 0.3150587 0.6515786 0.2763658 0.620357 0.2733696 0.627524 0.3150587 0.6515786 0.2796576 0.6124872 0.2290573 0.5989271 0.2763658 0.620357 0.2290573 0.5989271 0.2279145 0.6073809 0.2763658 0.620357 0.2763658 0.620357 0.2279145 0.6073809 0.2733696 0.627524 0.2279145 0.6073809 0.2268753 0.615079 0.2733696 0.627524 0.2290573 0.5989271 0.1766705 0.5989258 0.2279145 0.6073809 0.1766705 0.5989258 0.1777548 0.6073872 0.2279145 0.6073809 0.2279145 0.6073809 0.1777548 0.6073872 0.2268753 0.615079 0.1777548 0.6073872 0.1787433 0.6150922 0.2268753 0.615079 0.1766705 0.5989258 0.126069 0.6124826 0.1777548 0.6073872 0.126069 0.6124826 0.1293067 0.6203759 0.1777548 0.6073872 0.1777548 0.6073872 0.1293067 0.6203759 0.1787433 0.6150922 0.1293067 0.6203759 0.1322562 0.6275624 0.1787433 0.6150922 0.126069 0.6124826 0.08070051 0.6386756 0.1293067 0.6203759 0.08070051 0.6386756 0.08587092 0.6454619 0.1293067 0.6203759 0.1293067 0.6203759 0.08587092 0.6454619 0.1322562 0.6275624 0.08587092 0.6454619 0.09057927 0.6516396 0.1322562 0.6275624 0.08070051 0.6386756 0.04365783 0.675718 0.08587092 0.6454619 0.04365783 0.675718 0.05040848 0.6809349 0.08587092 0.6454619 0.08587092 0.6454619 0.05040848 0.6809349 0.09057927 0.6516396 0.05040848 0.6809349 0.05655473 0.685683 0.09057927 0.6516396 0.04365783 0.675718 0.01746469 0.7210858 0.05040848 0.6809349 0.01746469 0.7210858 0.02533459 0.7243773 0.05040848 0.6809349 0.05040848 0.6809349 0.02533459 0.7243773 0.05655473 0.685683 0.02533459 0.7243773 0.03250175 0.7273733 0.05655473 0.685683 0.01746469 0.7210858 0.00390625 0.7716867 0.02533459 0.7243773 0.00390625 0.7716867 0.01235991 0.7728291 0.02533459 0.7243773 0.02533459 0.7243773 0.01235991 0.7728291 0.03250175 0.7273733 0.01235991 0.7728291 0.02005803 0.7738682 0.03250175 0.7273733 0.2679725 0.365907 0.1800367 0.5688781 0.236442 0.5852586 0.2679725 0.365907 0.1311475 0.5370425 0.1800367 0.5688781 0.2679725 0.365907 0.09787863 0.4901666 0.1311475 0.5370425 0.2679725 0.365907 0.07653158 0.442074 0.09787863 0.4901666 0.2679725 0.365907 0.06556189 0.3927496 0.07653158 0.442074 0.2679725 0.365907 0.06497049 0.3430217 0.06556189 0.3927496 0.2679725 0.365907 0.07437455 0.2938694 0.06497049 0.3430217 0.2679725 0.365907 0.09369289 0.245186 0.07437455 0.2938694 0.2679725 0.365907 0.1262683 0.1996575 0.09369289 0.245186 0.2679725 0.365907 0.1738846 0.1667155 0.1262683 0.1996575 0.2679725 0.365907 0.2292709 0.1485136 0.1738846 0.1667155 0.2679725 0.365907 0.2876806 0.1458148 0.2292709 0.1485136 0.2679725 0.365907 0.3448049 0.158658 0.2876806 0.1458148 0.2679725 0.365907 0.3965741 0.186105 0.3448049 0.158658 0.2679725 0.365907 0.4393269 0.2262251 0.3965741 0.186105 0.2679725 0.365907 0.4700425 0.2762028 0.4393269 0.2262251 0.2679725 0.365907 0.4865443 0.332527 0.4700425 0.2762028 0.2679725 0.365907 0.4876552 0.3912376 0.4865443 0.332527 0.2679725 0.365907 0.4732818 0.4482042 0.4876552 0.3912376 0.2679725 0.365907 0.4444195 0.4994119 0.4732818 0.4482042 0.2679725 0.365907 0.403086 0.541247 0.4444195 0.4994119 0.2679725 0.365907 0.3521791 0.570749 0.403086 0.541247 0.2679725 0.365907 0.2952822 0.5858036 0.3521791 0.570749 0.2679725 0.365907 0.236442 0.5852586 0.2952822 0.5858036 0.02005803 0.7738682 0.02007251 0.8219993 0.2026326 0.7975854 0.02007251 0.8219993 0.03254371 0.8684865 0.2026326 0.7975854 0.03254371 0.8684865 0.05662149 0.9101615 0.2026326 0.7975854 0.05662149 0.9101615 0.09066498 0.9441852 0.2026326 0.7975854 0.09066498 0.9441852 0.1323543 0.9682372 0.2026326 0.7975854 0.1323543 0.9682372 0.1788479 0.9806805 0.2026326 0.7975854 0.1788479 0.9806805 0.2269777 0.9806662 0.2026326 0.7975854 0.2269777 0.9806662 0.273464 0.9681957 0.2026326 0.7975854 0.273464 0.9681957 0.3151385 0.9441192 0.2026326 0.7975854 0.3151385 0.9441192 0.3491623 0.910077 0.2026326 0.7975854 0.3491623 0.910077 0.3732151 0.8683887 0.2026326 0.7975854 0.3732151 0.8683887 0.3856596 0.8218955 0.2026326 0.7975854 0.3856596 0.8218955 0.3856467 0.7737655 0.2026326 0.7975854 0.3856467 0.7737655 0.3731773 0.7272785 0.2026326 0.7975854 0.3731773 0.7272785 0.349101 0.685603 0.2026326 0.7975854 0.349101 0.685603 0.3150587 0.6515786 0.2026326 0.7975854 0.3150587 0.6515786 0.2733696 0.627524 0.2026326 0.7975854 0.2733696 0.627524 0.2268753 0.615079 0.2026326 0.7975854 0.2268753 0.615079 0.1787433 0.6150922 0.2026326 0.7975854 0.1787433 0.6150922 0.1322562 0.6275624 0.2026326 0.7975854 0.1322562 0.6275624 0.09057927 0.6516396 0.2026326 0.7975854 0.09057927 0.6516396 0.05655473 0.685683 0.2026326 0.7975854 0.05655473 0.685683 0.03250175 0.7273733 0.2026326 0.7975854 0.03250175 0.7273733 0.02005803 0.7738682 0.2026326 0.7975854 + + + + + + + + + + + + + + + + 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 +

0 0 0 2 1 1 1 2 2 0 0 3 1 2 4 3 3 5 1 2 6 4 4 7 3 3 8 4 4 9 5 5 10 3 3 11 4 4 12 6 6 13 5 5 14 6 6 15 7 7 16 5 5 17 5 5 18 7 7 19 8 8 20 7 7 21 9 9 22 8 8 23 8 8 24 9 9 25 10 10 26 9 9 27 11 11 28 10 10 29 6 6 30 12 12 31 7 7 32 12 12 33 13 13 34 7 7 35 7 7 36 13 13 37 9 9 38 13 13 39 14 14 40 9 9 41 9 9 42 14 14 43 11 11 44 14 14 45 15 15 46 11 11 47 12 12 48 16 16 49 13 13 50 16 16 51 17 17 52 13 13 53 13 13 54 17 17 55 14 14 56 17 17 57 18 18 58 14 14 59 14 14 60 18 18 61 15 15 62 18 18 63 19 19 64 15 15 65 16 16 66 20 20 67 17 17 68 20 20 69 21 21 70 17 17 71 17 17 72 21 21 73 18 18 74 21 21 75 22 22 76 18 18 77 18 18 78 22 22 79 19 19 80 22 22 81 23 23 82 19 19 83 20 20 84 24 24 85 21 21 86 24 24 87 25 25 88 21 21 89 21 21 90 25 25 91 22 22 92 25 25 93 26 26 94 22 22 95 22 22 96 26 26 97 23 23 98 26 26 99 27 27 100 23 23 101 24 24 102 28 28 103 25 25 104 28 28 105 29 29 106 25 25 107 25 25 108 29 29 109 26 26 110 29 29 111 30 30 112 26 26 113 26 26 114 30 30 115 27 27 116 30 30 117 31 31 118 27 27 119 28 28 120 32 32 121 29 29 122 32 32 123 33 33 124 29 29 125 29 29 126 33 33 127 30 30 128 33 33 129 34 34 130 30 30 131 32 32 132 35 35 133 33 33 134 35 35 135 36 36 136 33 33 137 35 35 138 37 37 139 36 36 140 37 37 141 38 38 142 36 36 143 37 37 144 39 39 145 38 38 146 39 39 147 40 40 148 38 38 149 43 41 150 42 42 151 41 43 152 42 42 153 44 44 154 41 43 155 41 43 156 44 44 157 45 45 158 44 44 159 46 46 160 45 45 161 42 42 162 47 47 163 44 44 164 47 47 165 48 48 166 44 44 167 44 44 168 48 48 169 46 46 170 48 48 171 49 49 172 46 46 173 43 41 174 41 43 175 50 50 176 51 51 177 43 41 178 50 50 179 51 51 180 50 50 181 52 52 182 53 53 183 51 51 184 52 52 185 53 53 186 52 52 187 54 54 188 55 55 189 53 53 190 54 54 191 55 55 192 54 54 193 56 56 194 57 57 195 55 55 196 56 56 197 57 57 198 56 56 199 58 58 200 59 59 201 57 57 202 58 58 203 59 59 204 58 58 205 60 60 206 61 61 207 59 59 208 60 60 209 61 61 210 60 60 211 62 62 212 63 63 213 61 61 214 62 62 215 63 63 216 62 62 217 64 64 218 65 65 219 63 63 220 64 64 221 65 65 222 64 64 223 66 66 224 67 67 225 65 65 226 66 66 227 67 67 228 66 66 229 68 68 230 69 69 231 67 67 232 68 68 233 68 68 234 66 66 235 70 70 236 66 66 237 71 71 238 70 70 239 66 66 240 64 64 241 71 71 242 64 64 243 72 72 244 71 71 245 64 64 246 62 62 247 72 72 248 62 62 249 73 73 250 72 72 251 62 62 252 60 60 253 73 73 254 60 60 255 74 74 256 73 73 257 60 60 258 58 58 259 74 74 260 58 58 261 75 75 262 74 74 263 58 58 264 56 56 265 75 75 266 56 56 267 76 76 268 75 75 269 56 56 270 54 54 271 76 76 272 54 54 273 77 77 274 76 76 275 54 54 276 52 52 277 77 77 278 52 52 279 78 78 280 77 77 281 52 52 282 50 50 283 78 78 284 50 50 285 79 79 286 78 78 287 50 50 288 41 43 289 79 79 290 41 43 291 45 45 292 79 79 293 82 80 294 81 81 295 80 82 296 81 81 297 83 83 298 80 82 299 81 81 300 84 84 301 83 83 302 84 84 303 85 85 304 83 83 305 84 84 306 86 86 307 85 85 308 86 86 309 87 87 310 85 85 311 86 86 312 88 88 313 87 87 314 88 88 315 89 89 316 87 87 317 88 88 318 90 90 319 89 89 320 90 90 321 91 91 322 89 89 323 90 90 324 92 92 325 91 91 326 92 92 327 93 93 328 91 91 329 92 92 330 94 94 331 93 93 332 94 94 333 95 95 334 93 93 335 94 94 336 96 96 337 95 95 338 96 96 339 97 97 340 95 95 341 96 96 342 98 98 343 97 97 344 99 99 345 98 98 346 96 96 347 100 100 348 99 99 349 96 96 350 98 98 351 101 101 352 97 97 353 99 99 354 102 102 355 98 98 356 103 103 357 102 102 358 99 99 359 104 104 360 103 103 361 99 99 362 102 102 363 105 105 364 98 98 365 98 98 366 105 105 367 101 101 368 105 105 369 106 106 370 101 101 371 103 103 372 107 107 373 102 102 374 107 107 375 108 108 376 102 102 377 102 102 378 108 108 379 105 105 380 108 108 381 109 109 382 105 105 383 105 105 384 109 109 385 106 106 386 109 109 387 110 110 388 106 106 389 107 107 390 111 111 391 108 108 392 111 111 393 112 112 394 108 108 395 108 108 396 112 112 397 109 109 398 112 112 399 113 113 400 109 109 401 109 109 402 113 113 403 110 110 404 113 113 405 114 114 406 110 110 407 117 115 408 116 116 409 115 117 410 116 116 411 118 118 412 115 117 413 115 117 414 118 118 415 119 119 416 118 118 417 120 120 418 119 119 419 116 116 420 121 121 421 118 118 422 121 121 423 122 122 424 118 118 425 118 118 426 122 122 427 120 120 428 122 122 429 123 123 430 120 120 431 121 121 432 124 124 433 122 122 434 124 124 435 125 125 436 122 122 437 122 122 438 125 125 439 123 123 440 125 125 441 126 126 442 123 123 443 124 124 444 127 127 445 125 125 446 127 127 447 128 128 448 125 125 449 125 125 450 128 128 451 126 126 452 128 128 453 129 129 454 126 126 455 127 127 456 130 130 457 128 128 458 130 130 459 131 131 460 128 128 461 128 128 462 131 131 463 129 129 464 131 131 465 132 132 466 129 129 467 130 130 468 133 133 469 131 131 470 133 133 471 134 134 472 131 131 473 131 131 474 134 134 475 132 132 476 134 134 477 135 135 478 132 132 479 133 133 480 136 136 481 134 134 482 136 136 483 137 137 484 134 134 485 134 134 486 137 137 487 135 135 488 137 137 489 138 138 490 135 135 491 136 136 492 139 139 493 137 137 494 139 139 495 140 140 496 137 137 497 137 137 498 140 140 499 138 138 500 140 140 501 141 141 502 138 138 503 139 139 504 142 142 505 140 140 506 142 142 507 143 143 508 140 140 509 140 140 510 143 143 511 141 141 512 143 143 513 144 144 514 141 141 515 142 142 516 145 145 517 143 143 518 145 145 519 146 146 520 143 143 521 143 143 522 146 146 523 144 144 524 146 146 525 147 147 526 144 144 527 145 145 528 148 148 529 146 146 530 148 148 531 149 149 532 146 146 533 146 146 534 149 149 535 147 147 536 149 149 537 150 150 538 147 147 539 148 148 540 151 151 541 149 149 542 151 151 543 152 152 544 149 149 545 149 149 546 152 152 547 150 150 548 152 152 549 153 153 550 150 150 551 156 154 552 155 155 553 154 156 554 155 155 555 157 157 556 154 156 557 155 155 558 158 158 559 157 157 560 158 158 561 159 159 562 157 157 563 158 158 564 160 160 565 159 159 566 160 160 567 161 161 568 159 159 569 160 160 570 162 162 571 161 161 572 162 162 573 163 163 574 161 161 575 162 162 576 164 164 577 163 163 578 164 164 579 165 165 580 163 163 581 164 164 582 166 166 583 165 165 584 166 166 585 167 167 586 165 165 587 166 166 588 168 168 589 167 167 590 168 168 591 169 169 592 167 167 593 168 168 594 170 170 595 169 169 596 170 170 597 171 171 598 169 169 599 170 170 600 172 172 601 171 171 602 172 172 603 173 173 604 171 171 605 172 172 606 174 174 607 173 173 608 174 174 609 175 175 610 173 173 611 174 174 612 176 176 613 175 175 614 176 176 615 177 177 616 175 175 617 176 176 618 2 1 619 177 177 620 2 1 621 0 0 622 177 177 623 180 178 624 179 179 625 178 180 626 179 179 627 181 181 628 178 180 629 178 180 630 181 181 631 182 182 632 181 181 633 183 183 634 182 182 635 182 182 636 183 183 637 184 184 638 183 183 639 185 185 640 184 184 641 179 179 642 186 186 643 181 181 644 186 186 645 187 187 646 181 181 647 181 181 648 187 187 649 183 183 650 187 187 651 188 188 652 183 183 653 183 183 654 188 188 655 185 185 656 188 188 657 189 189 658 185 185 659 188 188 660 190 190 661 189 189 662 190 190 663 191 191 664 189 189 665 190 190 666 192 192 667 191 191 668 192 192 669 193 193 670 191 191 671 192 192 672 194 194 673 193 193 674 194 194 675 195 195 676 193 193 677 194 194 678 196 196 679 195 195 680 196 196 681 197 197 682 195 195 683 196 196 684 198 198 685 197 197 686 198 198 687 199 199 688 197 197 689 198 198 690 200 200 691 199 199 692 200 200 693 201 201 694 199 199 695 200 200 696 202 202 697 201 201 698 202 202 699 203 203 700 201 201 701 202 202 702 204 204 703 203 203 704 204 204 705 205 205 706 203 203 707 204 204 708 206 206 709 205 205 710 206 206 711 207 207 712 205 205 713 206 206 714 82 80 715 207 207 716 82 80 717 80 82 718 207 207 719 210 208 720 209 209 721 208 210 722 209 209 723 211 211 724 208 210 725 208 210 726 211 211 727 212 212 728 211 211 729 213 213 730 212 212 731 209 209 732 214 214 733 211 211 734 214 214 735 215 215 736 211 211 737 211 211 738 215 215 739 213 213 740 215 215 741 216 216 742 213 213 743 214 214 744 217 217 745 215 215 746 217 217 747 218 218 748 215 215 749 215 215 750 218 218 751 216 216 752 218 218 753 219 219 754 216 216 755 217 217 756 220 220 757 218 218 758 220 220 759 221 221 760 218 218 761 218 218 762 221 221 763 219 219 764 221 221 765 222 222 766 219 219 767 220 220 768 223 223 769 221 221 770 223 223 771 224 224 772 221 221 773 221 221 774 224 224 775 222 222 776 224 224 777 225 225 778 222 222 779 223 223 780 226 226 781 224 224 782 226 226 783 227 227 784 224 224 785 224 224 786 227 227 787 225 225 788 227 227 789 228 228 790 225 225 791 226 226 792 229 229 793 227 227 794 229 229 795 230 230 796 227 227 797 227 227 798 230 230 799 228 228 800 230 230 801 231 231 802 228 228 803 229 229 804 232 232 805 230 230 806 232 232 807 233 233 808 230 230 809 230 230 810 233 233 811 231 231 812 233 233 813 234 234 814 231 231 815 232 232 816 235 235 817 233 233 818 235 235 819 236 236 820 233 233 821 233 233 822 236 236 823 234 234 824 236 236 825 237 237 826 234 234 827 235 235 828 238 238 829 236 236 830 238 238 831 239 239 832 236 236 833 236 236 834 239 239 835 237 237 836 239 239 837 240 240 838 237 237 839 238 238 840 241 241 841 239 239 842 241 241 843 242 242 844 239 239 845 239 239 846 242 242 847 240 240 848 242 242 849 243 243 850 240 240 851 241 241 852 117 115 853 242 242 854 117 115 855 115 117 856 242 242 857 242 242 858 115 117 859 243 243 860 115 117 861 119 119 862 243 243 863 246 244 864 245 245 865 244 246 866 246 244 867 247 247 868 245 245 869 246 244 870 248 248 871 247 247 872 246 244 873 249 249 874 248 248 875 246 244 876 250 250 877 249 249 878 246 244 879 251 251 880 250 250 881 246 244 882 252 252 883 251 251 884 246 244 885 253 253 886 252 252 887 246 244 888 254 254 889 253 253 890 246 244 891 255 255 892 254 254 893 246 244 894 256 256 895 255 255 896 246 244 897 257 257 898 256 256 899 246 244 900 258 258 901 257 257 902 246 244 903 259 259 904 258 258 905 246 244 906 260 260 907 259 259 908 246 244 909 261 261 910 260 260 911 246 244 912 262 262 913 261 261 914 246 244 915 263 263 916 262 262 917 246 244 918 264 264 919 263 263 920 246 244 921 265 265 922 264 264 923 246 244 924 266 266 925 265 265 926 246 244 927 267 267 928 266 266 929 246 244 930 268 268 931 267 267 932 246 244 933 244 246 934 268 268 935 271 269 936 270 270 937 269 271 938 270 270 939 272 272 940 269 271 941 272 272 942 273 273 943 269 271 944 273 273 945 274 274 946 269 271 947 274 274 948 275 275 949 269 271 950 275 275 951 276 276 952 269 271 953 276 276 954 277 277 955 269 271 956 277 277 957 278 278 958 269 271 959 278 278 960 279 279 961 269 271 962 279 279 963 280 280 964 269 271 965 280 280 966 281 281 967 269 271 968 281 281 969 282 282 970 269 271 971 282 282 972 283 283 973 269 271 974 283 283 975 284 284 976 269 271 977 284 284 978 285 285 979 269 271 980 285 285 981 286 286 982 269 271 983 286 286 984 287 287 985 269 271 986 287 287 987 288 288 988 269 271 989 288 288 990 289 289 991 269 271 992 289 289 993 290 290 994 269 271 995 290 290 996 291 291 997 269 271 998 291 291 999 292 292 1000 269 271 1001 292 292 1002 293 293 1003 269 271 1004 293 293 1005 271 269 1006 269 271 1007

+
+
+
+
+ + + + + 0.6858805 -0.3173701 0.6548619 7.481132 0.7276338 0.3124686 -0.6106656 -6.50764 -0.01081678 0.8953432 0.4452454 5.343665 0 0 0 1 + + + + -0.2908646 -0.7711008 0.5663932 4.076245 0.9551712 -0.1998834 0.2183912 1.005454 -0.05518906 0.6045247 0.7946723 5.903862 0 0 0 1 + + + + 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 + + 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 + + + + + + + + + + + + + + +
\ No newline at end of file diff --git a/src/parts source/kOS0m dev/Assets/untitled.dae.meta b/src/parts source/kOS0m dev/Assets/untitled.dae.meta new file mode 100644 index 000000000..603f1b7d3 --- /dev/null +++ b/src/parts source/kOS0m dev/Assets/untitled.dae.meta @@ -0,0 +1,80 @@ +fileFormatVersion: 2 +guid: 12b6a5adc93c745c594cde7741e07893 +timeCreated: 1431263577 +licenseType: Free +ModelImporter: + serializedVersion: 18 + fileIDToRecycleName: + 100000: Camera + 100002: GameObject + 100004: KR-2042 + 100006: Lamp + 100008: //RootNode + 400000: Camera + 400002: GameObject + 400004: KR-2042 + 400006: Lamp + 400008: //RootNode + 2300000: KR-2042 + 3300000: KR-2042 + 4300000: KR-2042 + 6400000: KR-2042 + 9500000: //RootNode + materials: + importMaterials: 1 + materialName: 0 + materialSearch: 1 + animations: + legacyGenerateAnimations: 4 + bakeSimulation: 0 + optimizeGameObjects: 0 + motionNodeName: + animationCompression: 1 + animationRotationError: .5 + animationPositionError: .5 + animationScaleError: .5 + animationWrapMode: 0 + extraExposedTransformPaths: [] + clipAnimations: [] + isReadable: 1 + meshes: + lODScreenPercentages: [] + globalScale: 1 + meshCompression: 0 + addColliders: 1 + importBlendShapes: 1 + swapUVChannels: 0 + generateSecondaryUV: 1 + useFileUnits: 1 + optimizeMeshForGPU: 1 + keepQuads: 0 + weldVertices: 1 + secondaryUVAngleDistortion: 8 + secondaryUVAreaDistortion: 15.000001 + secondaryUVHardAngle: 88 + secondaryUVPackMargin: 4 + useFileScale: 1 + tangentSpace: + normalSmoothAngle: 60 + splitTangentsAcrossUV: 1 + normalImportMode: 0 + tangentImportMode: 1 + importAnimation: 0 + copyAvatar: 0 + humanDescription: + human: [] + skeleton: [] + armTwist: .5 + foreArmTwist: .5 + upperLegTwist: .5 + legTwist: .5 + armStretch: .0500000007 + legStretch: .0500000007 + feetSpacing: 0 + rootMotionBoneName: + lastHumanDescriptionAvatarSource: {instanceID: 0} + animationType: 0 + additionalBone: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/parts source/kOS0m dev/kOSMachine0m copy.dae b/src/parts source/kOS0m dev/kOSMachine0m copy.dae new file mode 100644 index 000000000..dcc60e92f --- /dev/null +++ b/src/parts source/kOS0m dev/kOSMachine0m copy.dae @@ -0,0 +1,222 @@ + + + + + Blender User + Blender 2.73.0 commit date:2015-01-20, commit time:18:16, hash:bbf09d9 + + 2015-05-10T09:12:23 + 2015-05-10T09:12:23 + + Z_UP + + + + + + + 49.13434 + 1.777778 + 0.1 + 100 + + + + + + 0 + 0 + 0 + + + + + + + + + 1 1 1 + 1 + 0 + 0.00111109 + + + + + 0.000999987 + 1 + 0.1 + 0.1 + 1 + 1 + 1 + 2 + 0 + 1 + 1 + 1 + 1 + 1 + 0 + 2880 + 2 + 30.002 + 1.000799 + 0.04999995 + 29.99998 + 1 + 2 + 0 + 0 + 1 + 1 + 1 + 1 + 8192 + 1 + 1 + 0 + 1 + 1 + 1 + 3 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 1 + 3 + 0.15 + 75 + 1 + 1 + 0 + 1 + 1 + 0 + + + + + + + + + + + + 0 0 0 1 + + + 0 0 0 1 + + + 0.64 0.64 0.64 1 + + + 0.5 0.5 0.5 1 + + + 50 + + + 1 + + + + + + + + + + + + + + + + 0.25 0 0.02842795 0.23476 -0.062904 0.03539395 0.243041 0 0.03539395 0.241481 -0.06470495 0.02842795 0.21048 -0.12152 0.03539395 0.216506 -0.125 0.02842795 0.171856 -0.171856 0.03539395 0.176777 -0.176777 0.02842795 0.216332 -0.1249 -0.004379987 0.176635 -0.176635 -0.004379987 0.202262 -0.116776 -0.02643096 0.165147 -0.165147 -0.02643096 0.12152 -0.21048 0.03539395 0.125 -0.216506 0.02842795 0.1249 -0.216333 -0.004379987 0.116776 -0.2022629 -0.02643096 0.062904 -0.234759 0.03539395 0.06470495 -0.241481 0.02842795 0.06465297 -0.241288 -0.004379987 0.06044799 -0.2255949 -0.02642995 0 -0.243041 0.03539395 0 -0.25 0.02842795 0 -0.249799 -0.004379987 0 -0.233553 -0.02642995 -0.062904 -0.234759 0.03539395 -0.06470495 -0.241481 0.02842795 -0.06465297 -0.241288 -0.004379987 -0.06044799 -0.225594 -0.02642995 -0.121521 -0.210479 0.03539395 -0.125 -0.216506 0.02842795 -0.1249 -0.216332 -0.004379987 -0.116776 -0.202262 -0.02643096 -0.171856 -0.171856 0.03539395 -0.176777 -0.176777 0.02842795 -0.176635 -0.176635 -0.004379987 -0.21048 -0.12152 0.03539395 -0.216506 -0.125 0.02842795 -0.23476 -0.06290298 0.03539395 -0.241482 -0.064704 0.02842795 -0.243041 0 0.03539395 -0.25 0 0.02842795 0.249799 0 -0.004379987 0.241481 -0.06470495 0.02842795 0.25 0 0.02842795 0.241288 -0.06465297 -0.004379987 0.233553 0 -0.02643096 0.225594 -0.06044799 -0.02643096 0.216506 -0.125 0.02842795 0.216332 -0.1249 -0.004379987 0.202262 -0.116776 -0.02643096 0.241288 0.06465196 -0.004379987 0.241482 0.064704 0.028427 0.216333 0.124899 -0.004380941 0.216507 0.125 0.028427 0.176635 0.176634 -0.004380941 0.176777 0.176776 0.028427 0.1249 0.216332 -0.004380941 0.125 0.216506 0.028427 0.06465297 0.2412869 -0.004380941 0.06470495 0.241481 0.028427 0 0.249799 -0.004380941 0 0.25 0.028427 -0.06465196 0.241288 -0.004380941 -0.064704 0.241482 0.028427 -0.124899 0.216333 -0.004380941 -0.125 0.216507 0.028427 -0.176635 0.176635 -0.004380941 -0.176776 0.176777 0.028427 -0.216332 0.1249 -0.004380941 -0.216506 0.125 0.028427 -0.202262 0.116776 -0.02643096 -0.1651459 0.165147 -0.02643096 -0.116776 0.2022629 -0.02643096 -0.06044799 0.225594 -0.02643197 0 0.233552 -0.02643197 0.06044799 0.225594 -0.02643197 0.116777 0.202262 -0.02643096 0.165147 0.1651459 -0.02643096 0.2022629 0.116776 -0.02643096 0.2255949 0.06044697 -0.02643096 0.212099 0 -0.02643096 0.225594 -0.06044799 -0.02643096 0.233553 0 -0.02643096 0.204872 -0.05489498 -0.02643096 0.202262 -0.116776 -0.02643096 0.183683 -0.10605 -0.02643096 0.165147 -0.165147 -0.02643096 0.149977 -0.149977 -0.02643096 0.116776 -0.2022629 -0.02643096 0.106049 -0.183683 -0.02643096 0.06044799 -0.2255949 -0.02642995 0.05489498 -0.204872 -0.02643096 0 -0.233553 -0.02642995 0 -0.212099 -0.02643096 -0.06044799 -0.225594 -0.02642995 -0.05489498 -0.204872 -0.02643096 -0.116776 -0.202262 -0.02643096 -0.10605 -0.183683 -0.02643096 -0.165147 -0.165147 -0.02643096 -0.176635 -0.176635 -0.004379987 -0.1249 -0.216332 -0.004379987 -0.149977 -0.149977 -0.02643096 -0.216333 -0.124899 -0.004379987 -0.216506 -0.125 0.02842795 -0.176777 -0.176777 0.02842795 -0.2022629 -0.116776 -0.02643096 -0.183683 -0.106049 -0.02643096 -0.241482 -0.064704 0.02842795 -0.241288 -0.06465297 -0.004379987 -0.2255949 -0.06044799 -0.02643096 -0.204872 -0.05489498 -0.02643096 -0.25 0 0.02842795 -0.249799 0 -0.004379987 -0.233553 0 -0.02643096 -0.212099 0 -0.02643096 0.212099 0 -0.035447 0.204872 -0.05489498 -0.02643096 0.212099 0 -0.02643096 0.204872 -0.05489498 -0.035447 0.206044 0 -0.04131996 0.199023 -0.05332797 -0.04131996 0.183683 -0.10605 -0.02643096 0.183683 -0.10605 -0.035447 0.178439 -0.103022 -0.04131996 0.149977 -0.149977 -0.02643096 0.149977 -0.149977 -0.035447 0.145695 -0.145695 -0.04131996 0.106049 -0.183683 -0.02643096 0.106049 -0.183683 -0.035447 0.103022 -0.17844 -0.04131996 0.05489498 -0.204872 -0.02643096 0.05489498 -0.204872 -0.035447 0.05332797 -0.199023 -0.04131996 0 -0.212099 -0.02643096 0 -0.212099 -0.035447 0 -0.206044 -0.04131996 -0.05489498 -0.204872 -0.02643096 -0.05489498 -0.204872 -0.035447 -0.05332797 -0.199023 -0.04131996 -0.10605 -0.183683 -0.02643096 -0.10605 -0.183683 -0.035447 -0.103022 -0.178439 -0.04131996 -0.149977 -0.149977 -0.02643096 -0.149977 -0.149977 -0.035447 -0.145695 -0.145695 -0.04131996 -0.183683 -0.106049 -0.02643096 -0.183683 -0.106049 -0.035447 -0.17844 -0.103022 -0.04131996 -0.204872 -0.05489498 -0.02643096 -0.204872 -0.05489498 -0.035447 -0.199023 -0.05332797 -0.04131996 -0.212099 0 -0.02643096 -0.212099 0 -0.035447 -0.206044 0 -0.04131996 -0.25 0 0.02842795 -0.23476 0.062904 0.03539395 -0.243041 0 0.03539395 -0.241481 0.06470495 0.028427 -0.21048 0.121521 0.03539299 -0.216506 0.125 0.028427 -0.171856 0.171856 0.03539299 -0.176776 0.176777 0.028427 -0.12152 0.21048 0.03539299 -0.125 0.216507 0.028427 -0.06290298 0.23476 0.03539299 -0.064704 0.241482 0.028427 0 0.243041 0.03539299 0 0.25 0.028427 0.062904 0.23476 0.03539299 0.06470495 0.241481 0.028427 0.121521 0.21048 0.03539299 0.125 0.216506 0.028427 0.171856 0.171856 0.03539299 0.176777 0.176776 0.028427 0.21048 0.12152 0.03539299 0.216507 0.125 0.028427 0.23476 0.06290298 0.03539395 0.241482 0.064704 0.028427 -0.249799 0 -0.004379987 -0.241481 0.06470495 0.028427 -0.25 0 0.02842795 -0.2412869 0.06465297 -0.004379987 -0.233553 0 -0.02643096 -0.225594 0.06044799 -0.02643096 -0.212099 0 -0.02643096 -0.204872 0.05489498 -0.02643096 -0.216506 0.125 0.028427 -0.216332 0.1249 -0.004380941 -0.202262 0.116776 -0.02643096 -0.183683 0.10605 -0.02643096 -0.1651459 0.165147 -0.02643096 -0.149976 0.149977 -0.02643096 -0.116776 0.2022629 -0.02643096 -0.106049 0.183683 -0.02643096 -0.06044799 0.225594 -0.02643197 -0.05489498 0.204872 -0.02643197 0 0.233552 -0.02643197 0 0.212099 -0.02643197 0.06044799 0.225594 -0.02643197 0.05489599 0.204872 -0.02643197 0.116777 0.202262 -0.02643096 0.10605 0.183683 -0.02643096 0.165147 0.1651459 -0.02643096 0.149977 0.149976 -0.02643096 0.2022629 0.116776 -0.02643096 0.183683 0.106049 -0.02643096 0.2255949 0.06044697 -0.02643096 0.204872 0.05489498 -0.02643096 -0.212099 0 -0.035447 -0.204872 0.05489498 -0.02643096 -0.212099 0 -0.02643096 -0.204872 0.05489498 -0.035447 -0.206044 0 -0.04131996 -0.199023 0.05332797 -0.04131996 -0.183683 0.10605 -0.02643096 -0.183683 0.10605 -0.03544795 -0.178439 0.103022 -0.04131996 -0.149976 0.149977 -0.02643096 -0.149976 0.149977 -0.03544795 -0.145695 0.145695 -0.04132097 -0.106049 0.183683 -0.02643096 -0.106049 0.183683 -0.03544795 -0.103022 0.178439 -0.04132097 -0.05489498 0.204872 -0.02643197 -0.05489498 0.204872 -0.03544795 -0.05332797 0.199023 -0.04132097 0 0.212099 -0.02643197 0 0.212099 -0.03544795 0 0.206044 -0.04132097 0.05489599 0.204872 -0.02643197 0.05489599 0.204872 -0.03544795 0.05332899 0.199023 -0.04132097 0.10605 0.183683 -0.02643096 0.10605 0.183683 -0.03544795 0.103022 0.178439 -0.04132097 0.149977 0.149976 -0.02643096 0.149977 0.149976 -0.03544795 0.145696 0.145695 -0.04132097 0.183683 0.106049 -0.02643096 0.183683 0.106049 -0.03544795 0.17844 0.103022 -0.04131996 0.204872 0.05489498 -0.02643096 0.204872 0.05489498 -0.035447 0.199023 0.05332797 -0.04131996 0.243041 0 0.03539395 0.23476 -0.062904 0.03539395 2.97e-4 2.97e-4 0.03539395 0.21048 -0.12152 0.03539395 0.171856 -0.171856 0.03539395 0.12152 -0.21048 0.03539395 0.062904 -0.234759 0.03539395 0 -0.243041 0.03539395 -0.062904 -0.234759 0.03539395 -0.121521 -0.210479 0.03539395 -0.171856 -0.171856 0.03539395 -0.21048 -0.12152 0.03539395 -0.23476 -0.06290298 0.03539395 -0.243041 0 0.03539395 -0.23476 0.062904 0.03539395 -0.21048 0.121521 0.03539299 -0.171856 0.171856 0.03539299 -0.12152 0.21048 0.03539299 -0.06290298 0.23476 0.03539299 0 0.243041 0.03539299 0.062904 0.23476 0.03539299 0.121521 0.21048 0.03539299 0.171856 0.171856 0.03539299 0.21048 0.12152 0.03539299 0.23476 0.06290298 0.03539395 2.97e-4 2.96e-4 -0.03986597 0.199023 -0.05332797 -0.04131996 0.206044 0 -0.04131996 0.178439 -0.103022 -0.04131996 0.145695 -0.145695 -0.04131996 0.103022 -0.17844 -0.04131996 0.05332797 -0.199023 -0.04131996 0 -0.206044 -0.04131996 -0.05332797 -0.199023 -0.04131996 -0.103022 -0.178439 -0.04131996 -0.145695 -0.145695 -0.04131996 -0.17844 -0.103022 -0.04131996 -0.199023 -0.05332797 -0.04131996 -0.206044 0 -0.04131996 -0.199023 0.05332797 -0.04131996 -0.178439 0.103022 -0.04131996 -0.145695 0.145695 -0.04132097 -0.103022 0.178439 -0.04132097 -0.05332797 0.199023 -0.04132097 0 0.206044 -0.04132097 0.05332899 0.199023 -0.04132097 0.103022 0.178439 -0.04132097 0.145696 0.145695 -0.04132097 0.17844 0.103022 -0.04131996 0.199023 0.05332797 -0.04131996 + + + + + + + + + + 0.7074496 0 0.7067477 0.7074496 0 0.7067477 0.6833705 -0.183111 0.7066866 0.6833705 -0.183111 0.7066866 0.6126896 -0.3537095 0.7067171 0.7273171 -0.4763634 0.4940031 0.5002289 -0.5002289 0.7067477 0.6572161 -0.6572161 0.3688162 0.7554857 -0.5796686 -0.3052766 0.672811 -0.6727805 -0.3076266 0.640614 -0.4915616 -0.5898618 0.5692617 -0.5692617 -0.5931578 0.3537095 -0.6126896 0.7067171 0.4647359 -0.8049562 0.3688162 0.4757225 -0.8239998 -0.3076266 0.4025086 -0.6971954 -0.5931578 0.1830805 -0.68334 0.7067477 0.2405469 -0.8977935 0.3688162 0.2462538 -0.9190649 -0.3076266 0.2083498 -0.7776116 -0.5931578 0 -0.7074496 0.7067477 0 -0.9294717 0.3688162 0 -0.9514756 -0.3076571 0 -0.8050478 -0.5931578 -0.1830805 -0.68334 0.7067477 -0.2405469 -0.8978241 0.3688162 -0.2462538 -0.9190649 -0.3076571 -0.2083498 -0.7776116 -0.5931883 -0.3537095 -0.6126591 0.7067477 -0.4647359 -0.8049562 0.3688162 -0.4582049 -0.8650472 -0.2041688 -0.3089999 -0.746025 -0.5898618 -0.5002289 -0.5002289 0.7067477 -0.5792413 -0.6483657 0.4940336 -0.6087222 -0.7933287 -0.006042659 -0.6126896 -0.3537095 0.7067171 -0.6126896 -0.3537095 0.7067171 -0.68334 -0.1830805 0.7067477 -0.68334 -0.1830805 0.7067477 -0.7043977 -0.0927152 0.7036958 -0.7043977 -0.0927152 0.7036958 0.9999695 0 -0.006103694 0.9658803 -0.2587969 -0.006073176 0.9514756 0 -0.3076266 0.9190649 -0.2462538 -0.3076266 0.8050783 0 -0.5931273 0.7776116 -0.2083498 -0.5931578 0.9238563 -0.3826716 -0.006042659 0.8797571 -0.3644215 -0.3052766 0.746025 -0.3089999 -0.5898618 0.9190649 0.2462538 -0.3076571 0.9658803 0.2587969 -0.006103694 0.8239998 0.4757225 -0.3076571 0.8659932 0.4999848 -0.006103694 0.6727805 0.6727805 -0.3076571 0.7070834 0.7070834 -0.006103694 0.4757225 0.8239998 -0.3076571 0.4999848 0.8659932 -0.006103694 0.2462538 0.9190649 -0.3076571 0.2587969 0.9658803 -0.006103694 0 0.9514756 -0.3076571 0 0.9999695 -0.006103694 -0.2462538 0.9190649 -0.3076571 -0.2587969 0.9658803 -0.006103694 -0.4757225 0.8239998 -0.3076571 -0.4999848 0.8659932 -0.006103694 -0.672811 0.6727805 -0.3076571 -0.7070834 0.7070834 -0.006073176 -0.7554552 0.5796686 -0.3052766 -0.7933287 0.6087222 -0.006042659 -0.640614 0.4915311 -0.5898618 -0.5692617 0.5692617 -0.5931883 -0.4025086 0.6971954 -0.5931578 -0.2083498 0.7776116 -0.5931578 0 0.8050478 -0.5931578 0.2083498 0.7776421 -0.5931578 0.4025391 0.6971954 -0.5931578 0.5692617 0.5692617 -0.5931578 0.6971954 0.4025086 -0.5931578 0.7776421 0.2083498 -0.5931578 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -0.9999695 0 0 -1 0 -3.05185e-5 -1 0 -3.05185e-5 -1 0 -3.05185e-5 -0.9999695 0 -3.05185e-5 -1 0 -3.05185e-5 -1 0 -3.05185e-5 -1 -0.1987975 -0.2590716 -0.9451583 0 0 -1 -0.3393658 -0.3393658 -0.8772851 -0.6779382 -0.6109806 -0.4087649 -0.4915616 -0.640614 -0.5898618 0 0 -1 -0.8239998 -0.4757225 -0.3076266 -0.8659932 -0.4999848 -0.006103694 -0.7933287 -0.6087222 -0.006042659 -0.4156316 -0.239967 -0.8772851 0 0 -1 -0.9658803 -0.2587969 -0.006103694 -0.9190649 -0.2462538 -0.3076266 -0.4635761 -0.1242103 -0.8772851 0 0 -1 -0.9914243 -0.1304971 -0.006042659 -0.9440901 -0.1242713 -0.3052461 -0.478988 -0.06305122 -0.8755455 0 0 -1 1 0 0 0.9659109 -0.2587969 0 0.9255654 0 -0.3785516 0.8940092 -0.2395398 -0.3785516 0.6962187 0 -0.7177954 0.6724753 -0.1801813 -0.7178259 0.8660237 -0.4999848 0 0.8015686 -0.4627827 -0.3785516 0.6029237 -0.3480941 -0.7178259 0.7070834 -0.7070834 0 0.6544694 -0.6544694 -0.3785516 0.4922636 -0.4922636 -0.7178259 0.4999848 -0.8660237 0 0.4627827 -0.8015686 -0.3785211 0.3481246 -0.6029847 -0.7177343 0.2587969 -0.9659109 0 0.2395398 -0.8940092 -0.3785516 0.1801813 -0.6724753 -0.7178259 0 -1 0 0 -0.9255654 -0.3785516 0 -0.6962187 -0.7177954 -0.2587969 -0.9659109 0 -0.2395398 -0.8940092 -0.3785516 -0.1801813 -0.6724753 -0.7178259 -0.4999848 -0.8660237 0 -0.4627827 -0.8015686 -0.3785516 -0.3480941 -0.6029237 -0.7178259 -0.7070834 -0.7070834 0 -0.6544694 -0.6544694 -0.3785516 -0.4922636 -0.4922636 -0.7178259 -0.8660237 -0.4999848 0 -0.8015686 -0.4627827 -0.3785211 -0.6029847 -0.3481246 -0.7177343 -0.9659109 -0.2587969 0 -0.8940092 -0.2395398 -0.3785516 -0.6724753 -0.1801813 -0.7178259 -0.9914243 -0.1304971 0 -0.9187597 -0.1209448 -0.3757439 -0.6933195 -0.09128081 -0.7148045 -0.7043977 0.0927152 0.7036958 -0.6834315 0.183111 0.7066561 -0.7043977 0.0927152 0.7036958 -0.6834315 0.183111 0.7066561 -0.6126896 0.35374 0.7066866 -0.6126896 0.35374 0.7066866 -0.5002594 0.5002594 0.7067171 -0.5002289 0.5002594 0.7067171 -0.3537095 0.6126286 0.7067477 -0.3537095 0.6126286 0.7067477 -0.1830805 0.68334 0.7067477 -0.1830805 0.68334 0.7067477 0 0.7074496 0.7067477 0 0.7074496 0.7067477 0.183111 0.6833705 0.7066866 0.183111 0.6833705 0.7066866 0.35374 0.6126896 0.7066866 0.35374 0.6126896 0.7066866 0.5002594 0.5002594 0.7067171 0.5002594 0.5002289 0.7067171 0.6126286 0.3537095 0.7067477 0.6126286 0.3537095 0.7067477 0.6833705 0.183111 0.7066866 0.6833705 0.183111 0.7066866 -0.9914243 0.1305276 -0.006073176 -0.9658803 0.2587969 -0.006103694 -0.9440901 0.1242713 -0.3052461 -0.9190649 0.2462538 -0.3076571 -0.478988 0.06305122 -0.8755455 -0.4635761 0.1242103 -0.8772851 0 0 -1 0 0 -1 -0.9238563 0.3826716 -0.006042659 -0.8797571 0.364391 -0.3052766 -0.301706 0.1249732 -0.9451583 0 0 -0.9999695 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -0.9999695 0 0 -1 0 0 -1 0 0 -0.9999695 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 -0.9914243 0.1304971 0 -0.9659109 0.2587969 0 -0.9187597 0.1209448 -0.3757439 -0.8940092 0.2395398 -0.3785516 -0.6933195 0.0912503 -0.7148045 -0.6724753 0.1801813 -0.7178259 -0.8659932 0.4999848 0 -0.8015381 0.4627827 -0.3785821 -0.6028627 0.3480636 -0.7178869 -0.7070834 0.7070834 0 -0.6544694 0.6544694 -0.3785516 -0.4922941 0.4922941 -0.7177954 -0.4999848 0.8660237 0 -0.4627827 0.8015686 -0.3785211 -0.3480941 0.6029542 -0.7177954 -0.2587969 0.9659109 0 -0.2395398 0.8940092 -0.3785516 -0.1801813 0.6724753 -0.7178259 0 1 0 0 0.9255654 -0.3785516 0 0.6962187 -0.7177954 0.2587969 0.9659109 0 0.2395398 0.8940092 -0.3785516 0.1801813 0.6724753 -0.7178259 0.4999848 0.8659932 0 0.4627827 0.8015381 -0.3785516 0.3480941 0.6029237 -0.7178259 0.7070834 0.7070834 0 0.6544694 0.6544694 -0.3785211 0.4923246 0.4923246 -0.7177648 0.8660237 0.4999848 0 0.8015686 0.4627827 -0.3785516 0.6029542 0.3480941 -0.7177954 0.9659109 0.2587969 0 0.8940092 0.2395398 -0.3785516 0.6724753 0.1801813 -0.7178259 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0.9999695 0 0 1 0 0 1 0 0 0.9999695 0 0 1 0 0 1 0 0 1 0 0 0.9999695 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0.9999695 -0.007049739 0 -0.9999695 -0.006805598 0.001800537 -0.9999695 0 0 -1 -0.006103694 0.003509581 -0.9999695 -0.004974484 0.004974484 -0.9999695 -0.003509581 0.006103694 -0.9999695 -0.001800537 0.006805598 -0.9999695 0 0.007019221 -0.9999695 0.001800537 0.006775081 -0.9999695 0.003509581 0.006073176 -0.9999695 0.004974484 0.004974484 -0.9999695 0.006073176 0.003509581 -0.9999695 0.006775081 0.001800537 -0.9999695 0.007019221 0 -0.9999695 0.006805598 -0.001800537 -0.9999695 0.006103694 -0.003509581 -0.9999695 0.004974484 -0.004974484 -0.9999695 0.003509581 -0.006103694 -0.9999695 0.001800537 -0.006805598 -0.9999695 0 -0.007049739 -0.9999695 -0.001800537 -0.006805598 -0.9999695 -0.003509581 -0.006103694 -0.9999695 -0.004974484 -0.005005002 -0.9999695 -0.006103694 -0.003540098 -0.9999695 -0.006805598 -0.001800537 -0.9999695 + + + + + + + + + + 0.497981 0.08877295 0.497935 0.07082295 0.543138 0.07082295 0.497981 0.08877295 0.543138 0.07082295 0.542671 0.08877295 0.543138 0.07082295 0.587414 0.07082295 0.542671 0.08877295 0.587414 0.07082295 0.586501 0.08877295 0.542671 0.08877295 0.587414 0.07082295 0.631396 0.07082295 0.586501 0.08877295 0.631396 0.07082295 0.629985 0.08877295 0.586501 0.08877295 0.586501 0.08877295 0.629985 0.08877295 0.583796 0.101898 0.629985 0.08877295 0.626102 0.101898 0.583796 0.101898 0.583796 0.101898 0.626102 0.101898 0.581227 0.113775 0.626102 0.101898 0.622231 0.113775 0.581227 0.113775 0.631396 0.07082295 0.675506 0.07082295 0.629985 0.08877295 0.675506 0.07082295 0.673603 0.08877295 0.629985 0.08877295 0.629985 0.08877295 0.673603 0.08877295 0.626102 0.101898 0.673603 0.08877295 0.668071 0.101898 0.626102 0.101898 0.626102 0.101898 0.668071 0.101898 0.622231 0.113775 0.668071 0.101898 0.662932 0.113775 0.622231 0.113775 0.675506 0.07082295 0.719293 0.07082295 0.673603 0.08877295 0.719293 0.07082295 0.716869 0.08877295 0.673603 0.08877295 0.673603 0.08877295 0.716869 0.08877295 0.668071 0.101898 0.716869 0.08877295 0.709731 0.101898 0.668071 0.101898 0.668071 0.101898 0.709731 0.101898 0.662932 0.113775 0.709731 0.101898 0.703263 0.113775 0.662932 0.113775 0.719293 0.07082295 0.762508 0.07082295 0.716869 0.08877295 0.762508 0.07082295 0.759456 0.08877295 0.716869 0.08877295 0.716869 0.08877295 0.759456 0.08877295 0.709731 0.101898 0.759456 0.08877295 0.750727 0.101898 0.709731 0.101898 0.709731 0.101898 0.750727 0.101898 0.703263 0.113775 0.750727 0.101898 0.742873 0.113775 0.703263 0.113775 0.762508 0.07082295 0.803989 0.07082295 0.759456 0.08877295 0.803989 0.07082295 0.800498 0.08877295 0.759456 0.08877295 0.759456 0.08877295 0.800498 0.08877295 0.750727 0.101898 0.800498 0.08877295 0.790296 0.101898 0.750727 0.101898 0.750727 0.101898 0.790296 0.101898 0.742873 0.113775 0.790296 0.101898 0.781143 0.113775 0.742873 0.113775 0.803989 0.07082295 0.843235 0.07082295 0.800498 0.08877295 0.843235 0.07082295 0.839306 0.08877295 0.800498 0.08877295 0.800498 0.08877295 0.839306 0.08877295 0.790296 0.101898 0.839306 0.08877295 0.827857 0.101898 0.790296 0.101898 0.790296 0.101898 0.827857 0.101898 0.781143 0.113775 0.827857 0.101898 0.817555 0.113775 0.781143 0.113775 0.843235 0.07082295 0.880223 0.07082295 0.839306 0.08877295 0.880223 0.07082295 0.875888 0.08877295 0.839306 0.08877295 0.839306 0.08877295 0.875888 0.08877295 0.827857 0.101898 0.875888 0.08877295 0.863285 0.101898 0.827857 0.101898 0.880223 0.07082295 0.914794 0.07082295 0.875888 0.08877295 0.914794 0.07082295 0.910102 0.08877295 0.875888 0.08877295 0.914794 0.07082295 0.94703 0.07082295 0.910102 0.08877295 0.94703 0.07082295 0.942129 0.08877295 0.910102 0.08877295 0.94703 0.07082295 0.979042 0.07082295 0.942129 0.08877295 0.979042 0.07082295 0.974419 0.08877295 0.942129 0.08877295 0.497981 0.08877295 0.542671 0.08877295 0.497931 0.101898 0.542671 0.08877295 0.541093 0.101898 0.497931 0.101898 0.497931 0.101898 0.541093 0.101898 0.498033 0.113775 0.541093 0.101898 0.539807 0.113775 0.498033 0.113775 0.542671 0.08877295 0.586501 0.08877295 0.541093 0.101898 0.586501 0.08877295 0.583796 0.101898 0.541093 0.101898 0.541093 0.101898 0.583796 0.101898 0.539807 0.113775 0.583796 0.101898 0.581227 0.113775 0.539807 0.113775 0.497981 0.08877295 0.497931 0.101898 0.454715 0.101898 0.453182 0.08877295 0.497981 0.08877295 0.454715 0.101898 0.453182 0.08877295 0.454715 0.101898 0.411786 0.101898 0.408822 0.08877295 0.453182 0.08877295 0.411786 0.101898 0.408822 0.08877295 0.411786 0.101898 0.369753 0.101898 0.365246 0.08877295 0.408822 0.08877295 0.369753 0.101898 0.365246 0.08877295 0.369753 0.101898 0.328558 0.101898 0.322708 0.08877295 0.365246 0.08877295 0.328558 0.101898 0.322708 0.08877295 0.328558 0.101898 0.288415 0.101898 0.281408 0.08877295 0.322708 0.08877295 0.288415 0.101898 0.281408 0.08877295 0.288415 0.101898 0.249914 0.101898 0.241666 0.08877295 0.281408 0.08877295 0.249914 0.101898 0.241666 0.08877295 0.249914 0.101898 0.212984 0.101898 0.2036049 0.08877295 0.241666 0.08877295 0.212984 0.101898 0.2036049 0.08877295 0.212984 0.101898 0.1773999 0.101898 0.166799 0.08877295 0.2036049 0.08877295 0.1773999 0.101898 0.166799 0.08877295 0.1773999 0.101898 0.143133 0.101898 0.131163 0.08877295 0.166799 0.08877295 0.143133 0.101898 0.131163 0.08877295 0.143133 0.101898 0.110489 0.101898 0.09727698 0.08877295 0.131163 0.08877295 0.110489 0.101898 0.110489 0.101898 0.143133 0.101898 0.122662 0.113775 0.143133 0.101898 0.154218 0.113775 0.122662 0.113775 0.143133 0.101898 0.1773999 0.101898 0.154218 0.113775 0.1773999 0.101898 0.187257 0.113775 0.154218 0.113775 0.1773999 0.101898 0.212984 0.101898 0.187257 0.113775 0.212984 0.101898 0.221674 0.113775 0.187257 0.113775 0.212984 0.101898 0.249914 0.101898 0.221674 0.113775 0.249914 0.101898 0.25753 0.113775 0.221674 0.113775 0.249914 0.101898 0.288415 0.101898 0.25753 0.113775 0.288415 0.101898 0.294852 0.113775 0.25753 0.113775 0.288415 0.101898 0.328558 0.101898 0.294852 0.113775 0.328558 0.101898 0.333843 0.113775 0.294852 0.113775 0.328558 0.101898 0.369753 0.101898 0.333843 0.113775 0.369753 0.101898 0.373768 0.113775 0.333843 0.113775 0.369753 0.101898 0.411786 0.101898 0.373768 0.113775 0.411786 0.101898 0.414559 0.113775 0.373768 0.113775 0.411786 0.101898 0.454715 0.101898 0.414559 0.113775 0.454715 0.101898 0.456228 0.113775 0.414559 0.113775 0.454715 0.101898 0.497931 0.101898 0.456228 0.113775 0.497931 0.101898 0.498033 0.113775 0.456228 0.113775 0.498033 0.113775 0.539807 0.113775 0.498193 0.1297259 0.539807 0.113775 0.53888 0.1297259 0.498193 0.1297259 0.539807 0.113775 0.581227 0.113775 0.53888 0.1297259 0.581227 0.113775 0.579117 0.1297259 0.53888 0.1297259 0.581227 0.113775 0.622231 0.113775 0.579117 0.1297259 0.622231 0.113775 0.618878 0.1297259 0.579117 0.1297259 0.622231 0.113775 0.662932 0.113775 0.618878 0.1297259 0.662932 0.113775 0.658384 0.1297259 0.618878 0.1297259 0.662932 0.113775 0.703263 0.113775 0.658384 0.1297259 0.703263 0.113775 0.697492 0.1297259 0.658384 0.1297259 0.703263 0.113775 0.742873 0.113775 0.697492 0.1297259 0.742873 0.113775 0.735859 0.1297259 0.697492 0.1297259 0.742873 0.113775 0.781143 0.113775 0.735859 0.1297259 0.781143 0.113775 0.772949 0.1297259 0.735859 0.1297259 0.781143 0.113775 0.817555 0.113775 0.772949 0.1297259 0.817555 0.113775 0.808293 0.1297259 0.772949 0.1297259 0.817555 0.113775 0.851912 0.113775 0.808293 0.1297259 0.863285 0.101898 0.851912 0.113775 0.817555 0.113775 0.827857 0.101898 0.863285 0.101898 0.817555 0.113775 0.851912 0.113775 0.841643 0.1297259 0.808293 0.1297259 0.863285 0.101898 0.896463 0.101898 0.851912 0.113775 0.910102 0.08877295 0.896463 0.101898 0.863285 0.101898 0.875888 0.08877295 0.910102 0.08877295 0.863285 0.101898 0.896463 0.101898 0.884073 0.113775 0.851912 0.113775 0.851912 0.113775 0.884073 0.113775 0.841643 0.1297259 0.884073 0.113775 0.872809 0.1297259 0.841643 0.1297259 0.910102 0.08877295 0.942129 0.08877295 0.896463 0.101898 0.942129 0.08877295 0.927625 0.101898 0.896463 0.101898 0.896463 0.101898 0.927625 0.101898 0.884073 0.113775 0.927625 0.101898 0.914106 0.113775 0.884073 0.113775 0.884073 0.113775 0.914106 0.113775 0.872809 0.1297259 0.914106 0.113775 0.901486 0.1297259 0.872809 0.1297259 0.942129 0.08877295 0.974419 0.08877295 0.927625 0.101898 0.974419 0.08877295 0.958449 0.101898 0.927625 0.101898 0.927625 0.101898 0.958449 0.101898 0.914106 0.113775 0.958449 0.101898 0.942298 0.113775 0.914106 0.113775 0.914106 0.113775 0.942298 0.113775 0.901486 0.1297259 0.942298 0.113775 0.927269 0.1297259 0.901486 0.1297259 0.498193 0.1297259 0.53888 0.1297259 0.498246 0.140136 0.53888 0.1297259 0.538478 0.140136 0.498246 0.140136 0.498246 0.140136 0.538478 0.140136 0.498315 0.152971 0.538478 0.140136 0.538046 0.152971 0.498315 0.152971 0.53888 0.1297259 0.579117 0.1297259 0.538478 0.140136 0.579117 0.1297259 0.578292 0.140136 0.538478 0.140136 0.538478 0.140136 0.578292 0.140136 0.538046 0.152971 0.578292 0.140136 0.577423 0.152971 0.538046 0.152971 0.579117 0.1297259 0.618878 0.1297259 0.578292 0.140136 0.618878 0.1297259 0.617612 0.140136 0.578292 0.140136 0.578292 0.140136 0.617612 0.140136 0.577423 0.152971 0.617612 0.140136 0.616245 0.152971 0.577423 0.152971 0.618878 0.1297259 0.658384 0.1297259 0.617612 0.140136 0.658384 0.1297259 0.656693 0.140136 0.617612 0.140136 0.617612 0.140136 0.656693 0.140136 0.616245 0.152971 0.656693 0.140136 0.654864 0.152971 0.616245 0.152971 0.658384 0.1297259 0.697492 0.1297259 0.656693 0.140136 0.697492 0.1297259 0.69538 0.140136 0.656693 0.140136 0.656693 0.140136 0.69538 0.140136 0.654864 0.152971 0.69538 0.140136 0.693096 0.152971 0.654864 0.152971 0.697492 0.1297259 0.735859 0.1297259 0.69538 0.140136 0.735859 0.1297259 0.733325 0.140136 0.69538 0.140136 0.69538 0.140136 0.733325 0.140136 0.693096 0.152971 0.733325 0.140136 0.730592 0.152971 0.693096 0.152971 0.735859 0.1297259 0.772949 0.1297259 0.733325 0.140136 0.772949 0.1297259 0.770015 0.140136 0.733325 0.140136 0.733325 0.140136 0.770015 0.140136 0.730592 0.152971 0.770015 0.140136 0.766855 0.152971 0.730592 0.152971 0.772949 0.1297259 0.808293 0.1297259 0.770015 0.140136 0.808293 0.1297259 0.804989 0.140136 0.770015 0.140136 0.770015 0.140136 0.804989 0.140136 0.766855 0.152971 0.804989 0.140136 0.801428 0.152971 0.766855 0.152971 0.808293 0.1297259 0.841643 0.1297259 0.804989 0.140136 0.841643 0.1297259 0.837988 0.140136 0.804989 0.140136 0.804989 0.140136 0.837988 0.140136 0.801428 0.152971 0.837988 0.140136 0.834047 0.152971 0.801428 0.152971 0.841643 0.1297259 0.872809 0.1297259 0.837988 0.140136 0.872809 0.1297259 0.868808 0.140136 0.837988 0.140136 0.837988 0.140136 0.868808 0.140136 0.834047 0.152971 0.868808 0.140136 0.864493 0.152971 0.834047 0.152971 0.872809 0.1297259 0.901486 0.1297259 0.868808 0.140136 0.901486 0.1297259 0.897175 0.140136 0.868808 0.140136 0.868808 0.140136 0.897175 0.140136 0.864493 0.152971 0.897175 0.140136 0.892456 0.152971 0.864493 0.152971 0.901486 0.1297259 0.927269 0.1297259 0.897175 0.140136 0.927269 0.1297259 0.922834 0.140136 0.897175 0.140136 0.897175 0.140136 0.922834 0.140136 0.892456 0.152971 0.922834 0.140136 0.917439 0.152971 0.892456 0.152971 0.028638 0.07082295 0.06044697 0.07082295 0.03358 0.08877295 0.06044697 0.07082295 0.06551897 0.08877295 0.03358 0.08877295 0.06044697 0.07082295 0.09260195 0.07082295 0.06551897 0.08877295 0.09260195 0.07082295 0.09727698 0.08877295 0.06551897 0.08877295 0.09260195 0.07082295 0.126944 0.07082295 0.09727698 0.08877295 0.126944 0.07082295 0.131163 0.08877295 0.09727698 0.08877295 0.126944 0.07082295 0.163057 0.07082295 0.131163 0.08877295 0.163057 0.07082295 0.166799 0.08877295 0.131163 0.08877295 0.163057 0.07082295 0.200381 0.07082295 0.166799 0.08877295 0.200381 0.07082295 0.2036049 0.08877295 0.166799 0.08877295 0.200381 0.07082295 0.238752 0.07082295 0.2036049 0.08877295 0.238752 0.07082295 0.241666 0.08877295 0.2036049 0.08877295 0.238752 0.07082295 0.278904 0.07082295 0.241666 0.08877295 0.278904 0.07082295 0.281408 0.08877295 0.241666 0.08877295 0.278904 0.07082295 0.32068 0.07082295 0.281408 0.08877295 0.32068 0.07082295 0.322708 0.08877295 0.281408 0.08877295 0.32068 0.07082295 0.36368 0.07082295 0.322708 0.08877295 0.36368 0.07082295 0.365246 0.08877295 0.322708 0.08877295 0.36368 0.07082295 0.407726 0.07082295 0.365246 0.08877295 0.407726 0.07082295 0.408822 0.08877295 0.365246 0.08877295 0.407726 0.07082295 0.452605 0.07082295 0.408822 0.08877295 0.452605 0.07082295 0.453182 0.08877295 0.408822 0.08877295 0.452605 0.07082295 0.497935 0.07082295 0.453182 0.08877295 0.497935 0.07082295 0.497981 0.08877295 0.453182 0.08877295 0.03358 0.08877295 0.06551897 0.08877295 0.05011695 0.101898 0.06551897 0.08877295 0.07987499 0.101898 0.05011695 0.101898 0.05011695 0.101898 0.07987499 0.101898 0.06625896 0.113775 0.07987499 0.101898 0.09322595 0.113775 0.06625896 0.113775 0.06625896 0.113775 0.09322595 0.113775 0.080531 0.1297259 0.09322595 0.113775 0.10576 0.1297259 0.080531 0.1297259 0.06551897 0.08877295 0.09727698 0.08877295 0.07987499 0.101898 0.09727698 0.08877295 0.110489 0.101898 0.07987499 0.101898 0.07987499 0.101898 0.110489 0.101898 0.09322595 0.113775 0.110489 0.101898 0.122662 0.113775 0.09322595 0.113775 0.09322595 0.113775 0.122662 0.113775 0.10576 0.1297259 0.122662 0.113775 0.134295 0.1297259 0.10576 0.1297259 0.122662 0.113775 0.154218 0.113775 0.134295 0.1297259 0.154218 0.113775 0.16442 0.1297259 0.134295 0.1297259 0.154218 0.113775 0.187257 0.113775 0.16442 0.1297259 0.187257 0.113775 0.196301 0.1297259 0.16442 0.1297259 0.187257 0.113775 0.221674 0.113775 0.196301 0.1297259 0.221674 0.113775 0.229607 0.1297259 0.196301 0.1297259 0.221674 0.113775 0.25753 0.113775 0.229607 0.1297259 0.25753 0.113775 0.264349 0.1297259 0.229607 0.1297259 0.25753 0.113775 0.294852 0.113775 0.264349 0.1297259 0.294852 0.113775 0.300955 0.1297259 0.264349 0.1297259 0.294852 0.113775 0.333843 0.113775 0.300955 0.1297259 0.333843 0.113775 0.338598 0.1297259 0.300955 0.1297259 0.333843 0.113775 0.373768 0.113775 0.338598 0.1297259 0.373768 0.113775 0.37738 0.1297259 0.338598 0.1297259 0.373768 0.113775 0.414559 0.113775 0.37738 0.1297259 0.414559 0.113775 0.417199 0.1297259 0.37738 0.1297259 0.414559 0.113775 0.456228 0.113775 0.417199 0.1297259 0.456228 0.113775 0.457525 0.1297259 0.417199 0.1297259 0.456228 0.113775 0.498033 0.113775 0.457525 0.1297259 0.498033 0.113775 0.498193 0.1297259 0.457525 0.1297259 0.080531 0.1297259 0.10576 0.1297259 0.08523398 0.140136 0.10576 0.1297259 0.110186 0.140136 0.08523398 0.140136 0.08523398 0.140136 0.110186 0.140136 0.09042799 0.152971 0.110186 0.140136 0.114798 0.152971 0.09042799 0.152971 0.10576 0.1297259 0.134295 0.1297259 0.110186 0.140136 0.134295 0.1297259 0.138254 0.140136 0.110186 0.140136 0.110186 0.140136 0.138254 0.140136 0.114798 0.152971 0.138254 0.140136 0.142554 0.152971 0.114798 0.152971 0.134295 0.1297259 0.16442 0.1297259 0.138254 0.140136 0.16442 0.1297259 0.168044 0.140136 0.138254 0.140136 0.138254 0.140136 0.168044 0.140136 0.142554 0.152971 0.168044 0.140136 0.17198 0.152971 0.142554 0.152971 0.16442 0.1297259 0.196301 0.1297259 0.168044 0.140136 0.196301 0.1297259 0.19953 0.140136 0.168044 0.140136 0.168044 0.140136 0.19953 0.140136 0.17198 0.152971 0.19953 0.140136 0.20304 0.152971 0.17198 0.152971 0.196301 0.1297259 0.229607 0.1297259 0.19953 0.140136 0.229607 0.1297259 0.23245 0.140136 0.19953 0.140136 0.19953 0.140136 0.23245 0.140136 0.20304 0.152971 0.23245 0.140136 0.2355369 0.152971 0.20304 0.152971 0.229607 0.1297259 0.264349 0.1297259 0.23245 0.140136 0.264349 0.1297259 0.266794 0.140136 0.23245 0.140136 0.23245 0.140136 0.266794 0.140136 0.2355369 0.152971 0.266794 0.140136 0.269436 0.152971 0.2355369 0.152971 0.264349 0.1297259 0.300955 0.1297259 0.266794 0.140136 0.300955 0.1297259 0.303016 0.140136 0.266794 0.140136 0.266794 0.140136 0.303016 0.140136 0.269436 0.152971 0.303016 0.140136 0.305259 0.152971 0.269436 0.152971 0.300955 0.1297259 0.338598 0.1297259 0.303016 0.140136 0.338598 0.1297259 0.340322 0.140136 0.303016 0.140136 0.303016 0.140136 0.340322 0.140136 0.305259 0.152971 0.340322 0.140136 0.342198 0.152971 0.305259 0.152971 0.338598 0.1297259 0.37738 0.1297259 0.340322 0.140136 0.37738 0.1297259 0.378667 0.140136 0.340322 0.140136 0.340322 0.140136 0.378667 0.140136 0.342198 0.152971 0.378667 0.140136 0.380062 0.152971 0.342198 0.152971 0.37738 0.1297259 0.417199 0.1297259 0.378667 0.140136 0.417199 0.1297259 0.418079 0.140136 0.378667 0.140136 0.378667 0.140136 0.418079 0.140136 0.380062 0.152971 0.418079 0.140136 0.419045 0.152971 0.380062 0.152971 0.417199 0.1297259 0.457525 0.1297259 0.418079 0.140136 0.457525 0.1297259 0.458044 0.140136 0.418079 0.140136 0.418079 0.140136 0.458044 0.140136 0.419045 0.152971 0.458044 0.140136 0.458621 0.152971 0.419045 0.152971 0.457525 0.1297259 0.498193 0.1297259 0.458044 0.140136 0.498193 0.1297259 0.498246 0.140136 0.458044 0.140136 0.458044 0.140136 0.498246 0.140136 0.458621 0.152971 0.498246 0.140136 0.498315 0.152971 0.458621 0.152971 0.263502 0.732761 0.23444 0.956097 0.1776 0.940866 0.263502 0.732761 0.293284 0.956097 0.23444 0.956097 0.263502 0.732761 0.350124 0.940866 0.293284 0.956097 0.263502 0.732761 0.401085 0.911444 0.350124 0.940866 0.263502 0.732761 0.442694 0.869835 0.401085 0.911444 0.263502 0.732761 0.472116 0.818874 0.442694 0.869835 0.263502 0.732761 0.487347 0.762034 0.472116 0.818874 0.263502 0.732761 0.487347 0.703189 0.487347 0.762034 0.263502 0.732761 0.472116 0.64635 0.487347 0.703189 0.263502 0.732761 0.442694 0.595389 0.472116 0.64635 0.263502 0.732761 0.401085 0.553779 0.442694 0.595389 0.263502 0.732761 0.350124 0.524357 0.401085 0.553779 0.263502 0.732761 0.293284 0.509127 0.350124 0.524357 0.263502 0.732761 0.234439 0.509127 0.293284 0.509127 0.263502 0.732761 0.1776 0.524357 0.234439 0.509127 0.263502 0.732761 0.126639 0.55378 0.1776 0.524357 0.263502 0.732761 0.085029 0.595389 0.126639 0.55378 0.263502 0.732761 0.05560696 0.64635 0.085029 0.595389 0.263502 0.732761 0.04037696 0.70319 0.05560696 0.64635 0.263502 0.732761 0.04037696 0.762035 0.04037696 0.70319 0.263502 0.732761 0.05560696 0.818874 0.04037696 0.762035 0.263502 0.732761 0.08502995 0.869835 0.05560696 0.818874 0.263502 0.732761 0.126639 0.911444 0.08502995 0.869835 0.263502 0.732761 0.1776 0.940866 0.126639 0.911444 0.556957 0.497392 0.556957 0.447505 0.746185 0.472757 0.556957 0.447505 0.569869 0.399317 0.746185 0.472757 0.569869 0.399317 0.594812 0.356114 0.746185 0.472757 0.594812 0.356114 0.630088 0.320839 0.746185 0.472757 0.630088 0.320839 0.673291 0.295895 0.746185 0.472757 0.673291 0.295895 0.721478 0.282983 0.746185 0.472757 0.721478 0.282983 0.771365 0.282983 0.746185 0.472757 0.771365 0.282983 0.819552 0.295895 0.746185 0.472757 0.819552 0.295895 0.862756 0.320838 0.746185 0.472757 0.862756 0.320838 0.898031 0.356114 0.746185 0.472757 0.898031 0.356114 0.922975 0.399317 0.746185 0.472757 0.922975 0.399317 0.935887 0.447505 0.746185 0.472757 0.935887 0.447505 0.935887 0.497392 0.746185 0.472757 0.935887 0.497392 0.922975 0.545579 0.746185 0.472757 0.922975 0.545579 0.898031 0.588782 0.746185 0.472757 0.898031 0.588782 0.862756 0.624058 0.746185 0.472757 0.862756 0.624058 0.819552 0.649001 0.746185 0.472757 0.819552 0.649001 0.771365 0.661913 0.746185 0.472757 0.771365 0.661913 0.721478 0.661913 0.746185 0.472757 0.721478 0.661913 0.673291 0.649001 0.746185 0.472757 0.673291 0.649001 0.630087 0.624058 0.746185 0.472757 0.630087 0.624058 0.594812 0.588782 0.746185 0.472757 0.594812 0.588782 0.569868 0.545579 0.746185 0.472757 0.569868 0.545579 0.556957 0.497392 0.746185 0.472757 + + + + + + + + + 0.2350667 0.5944423 0.236442 0.5852586 0.1800367 0.5688781 0.2350667 0.5944423 0.1800367 0.5688781 0.1761345 0.5773187 0.1800367 0.5688781 0.1311475 0.5370425 0.1761345 0.5773187 0.1311475 0.5370425 0.1245415 0.5436798 0.1761345 0.5773187 0.1311475 0.5370425 0.09787863 0.4901666 0.1245415 0.5436798 0.09787863 0.4901666 0.09049338 0.4943432 0.1245415 0.5436798 0.1245415 0.5436798 0.09049338 0.4943432 0.09589761 0.5627111 0.09049338 0.4943432 0.0641511 0.5072736 0.09589761 0.5627111 0.09589761 0.5627111 0.0641511 0.5072736 0.06957656 0.5749213 0.0641511 0.5072736 0.03961127 0.5188692 0.06957656 0.5749213 0.09787863 0.4901666 0.07653158 0.442074 0.09049338 0.4943432 0.07653158 0.442074 0.06883269 0.4446325 0.09049338 0.4943432 0.09049338 0.4943432 0.06883269 0.4446325 0.0641511 0.5072736 0.06883269 0.4446325 0.0417397 0.4527056 0.0641511 0.5072736 0.0641511 0.5072736 0.0417397 0.4527056 0.03961127 0.5188692 0.0417397 0.4527056 0.01629096 0.460441 0.03961127 0.5188692 0.07653158 0.442074 0.06556189 0.3927496 0.06883269 0.4446325 0.06556189 0.3927496 0.05767703 0.3936865 0.06883269 0.4446325 0.06883269 0.4446325 0.05767703 0.3936865 0.0417397 0.4527056 0.05767703 0.3936865 0.0300439 0.3963494 0.0417397 0.4527056 0.0417397 0.4527056 0.0300439 0.3963494 0.01629096 0.460441 0.0300439 0.3963494 0.00390625 0.3991305 0.01629096 0.460441 0.06556189 0.3927496 0.06497049 0.3430217 0.05767703 0.3936865 0.06497049 0.3430217 0.05707472 0.3423448 0.05767703 0.3936865 0.05767703 0.3936865 0.05707472 0.3423448 0.0300439 0.3963494 0.05707472 0.3423448 0.02971023 0.3395568 0.0300439 0.3963494 0.0300439 0.3963494 0.02971023 0.3395568 0.00390625 0.3991305 0.02971023 0.3395568 0.00390625 0.3372796 0.00390625 0.3991305 0.06497049 0.3430217 0.07437455 0.2938694 0.05707472 0.3423448 0.07437455 0.2938694 0.06659692 0.2915712 0.05707472 0.3423448 0.05707472 0.3423448 0.06659692 0.2915712 0.02971023 0.3395568 0.06659692 0.2915712 0.03990733 0.2838791 0.02971023 0.3395568 0.02971023 0.3395568 0.03990733 0.2838791 0.00390625 0.3372796 0.03990733 0.2838791 0.01529473 0.2776388 0.00390625 0.3372796 0.07437455 0.2938694 0.09369289 0.245186 0.06659692 0.2915712 0.09369289 0.245186 0.08613568 0.2410319 0.06659692 0.2915712 0.06659692 0.2915712 0.08613568 0.2410319 0.03990733 0.2838791 0.08613568 0.2410319 0.05916076 0.2271876 0.03990733 0.2838791 0.03990733 0.2838791 0.05916076 0.2271876 0.01529473 0.2776388 0.05916076 0.2271876 0.03322398 0.221123 0.01529473 0.2776388 0.09369289 0.245186 0.1262683 0.1996575 0.08613568 0.2410319 0.1262683 0.1996575 0.1197991 0.1930412 0.08613568 0.2410319 0.08613568 0.2410319 0.1197991 0.1930412 0.05916076 0.2271876 0.1197991 0.1930412 0.09383791 0.1756151 0.05916076 0.2271876 0.1262683 0.1996575 0.1738846 0.1667155 0.1197991 0.1930412 0.1738846 0.1667155 0.1698107 0.1584594 0.1197991 0.1930412 0.1738846 0.1667155 0.2292709 0.1485136 0.1698107 0.1584594 0.2292709 0.1485136 0.2276279 0.1394425 0.1698107 0.1584594 0.2292709 0.1485136 0.2876806 0.1458148 0.2276279 0.1394425 0.2876806 0.1458148 0.2885111 0.1366223 0.2276279 0.1394425 0.5831499 0.09723418 0.6392333 0.07750499 0.5745477 0.06898558 0.6392333 0.07750499 0.6284694 0.04977446 0.5745477 0.06898558 0.5745477 0.06898558 0.6284694 0.04977446 0.5672938 0.04553133 0.6284694 0.04977446 0.6193705 0.02707022 0.5672938 0.04553133 0.6392333 0.07750499 0.6943629 0.05367654 0.6284694 0.04977446 0.6943629 0.05367654 0.6819697 0.0257048 0.6284694 0.04977446 0.6284694 0.04977446 0.6819697 0.0257048 0.6193705 0.02707022 0.6819697 0.0257048 0.6698388 0.00390625 0.6193705 0.02707022 0.5831499 0.09723418 0.5745477 0.06898558 0.5193687 0.08390897 0.525815 0.1127023 0.5831499 0.09723418 0.5193687 0.08390897 0.525815 0.1127023 0.5193687 0.08390897 0.4632171 0.0946123 0.4674758 0.1238127 0.525815 0.1127023 0.4632171 0.0946123 0.4674758 0.1238127 0.4632171 0.0946123 0.4064087 0.1010535 0.4084558 0.1304971 0.4674758 0.1238127 0.4064087 0.1010535 0.4084558 0.1304971 0.4064087 0.1010535 0.3492653 0.1031962 0.3490877 0.1327161 0.4084558 0.1304971 0.3492653 0.1031962 0.3490877 0.1327161 0.3492653 0.1031962 0.2921115 0.1010265 0.2897101 0.130455 0.3490877 0.1327161 0.2921115 0.1010265 0.2897101 0.130455 0.2921115 0.1010265 0.2352721 0.09455591 0.2306596 0.1237252 0.2897101 0.130455 0.2352721 0.09455591 0.2306596 0.1237252 0.2352721 0.09455591 0.1790698 0.08382123 0.1722739 0.112564 0.2306596 0.1237252 0.1790698 0.08382123 0.1722739 0.112564 0.1790698 0.08382123 0.1238058 0.06889402 0.114885 0.09703874 0.1722739 0.112564 0.1238058 0.06889402 0.114885 0.09703874 0.1238058 0.06889402 0.0696392 0.04993075 0.05882787 0.07730001 0.114885 0.09703874 0.0696392 0.04993075 0.05882787 0.07730001 0.0696392 0.04993075 0.01560503 0.0264728 0.00390625 0.05407291 0.05882787 0.07730001 0.01560503 0.0264728 0.01560503 0.0264728 0.0696392 0.04993075 0.02767962 0.00390625 0.0696392 0.04993075 0.07888078 0.02687853 0.02767962 0.00390625 0.0696392 0.04993075 0.1238058 0.06889402 0.07888078 0.02687853 0.1238058 0.06889402 0.1311852 0.0453937 0.07888078 0.02687853 0.1238058 0.06889402 0.1790698 0.08382123 0.1311852 0.0453937 0.1790698 0.08382123 0.1846489 0.05986011 0.1311852 0.0453937 0.1790698 0.08382123 0.2352721 0.09455591 0.1846489 0.05986011 0.2352721 0.09455591 0.2390297 0.07025092 0.1846489 0.05986011 0.2352721 0.09455591 0.2921115 0.1010265 0.2390297 0.07025092 0.2921115 0.1010265 0.2940266 0.07651305 0.2390297 0.07025092 0.2921115 0.1010265 0.3492653 0.1031962 0.2940266 0.07651305 0.3492653 0.1031962 0.3493282 0.07861375 0.2940266 0.07651305 0.3492653 0.1031962 0.4064087 0.1010535 0.3493282 0.07861375 0.4064087 0.1010535 0.4046192 0.076541 0.3493282 0.07861375 0.4064087 0.1010535 0.4632171 0.0946123 0.4046192 0.076541 0.4632171 0.0946123 0.459586 0.07030946 0.4046192 0.076541 0.4632171 0.0946123 0.5193687 0.08390897 0.459586 0.07030946 0.5193687 0.08390897 0.5139161 0.05995464 0.459586 0.07030946 0.5193687 0.08390897 0.5745477 0.06898558 0.5139161 0.05995464 0.5745477 0.06898558 0.5672938 0.04553133 0.5139161 0.05995464 0.9582458 0.3222229 0.9390272 0.2623018 0.9364184 0.3260506 0.9390272 0.2623018 0.9192036 0.2717746 0.9364184 0.3260506 0.9390272 0.2623018 0.9047072 0.2103503 0.9192036 0.2717746 0.9047072 0.2103503 0.8884084 0.2246392 0.9192036 0.2717746 0.9047072 0.2103503 0.8582402 0.1703261 0.8884084 0.2246392 0.8582402 0.1703261 0.846688 0.1882102 0.8884084 0.2246392 0.8582402 0.1703261 0.8035733 0.1451821 0.846688 0.1882102 0.8035733 0.1451821 0.7975903 0.165144 0.846688 0.1882102 0.8035733 0.1451821 0.7453272 0.1366223 0.7975903 0.165144 0.7453272 0.1366223 0.7452702 0.1569747 0.7975903 0.165144 0.7453272 0.1366223 0.6884095 0.1449695 0.7452702 0.1569747 0.6884095 0.1449695 0.6941417 0.1639945 0.7452702 0.1569747 0.6884095 0.1449695 0.6376188 0.1691383 0.6941417 0.1639945 0.6376188 0.1691383 0.6485199 0.1852265 0.6941417 0.1639945 0.6376188 0.1691383 0.5972502 0.206721 0.6485199 0.1852265 0.5972502 0.206721 0.6122664 0.2185064 0.6485199 0.1852265 0.5972502 0.206721 0.5716609 0.2529014 0.6122664 0.2185064 0.549771 0.2438524 0.5716609 0.2529014 0.5972502 0.206721 0.5771115 0.1936393 0.549771 0.2438524 0.5972502 0.206721 0.5716609 0.2529014 0.5885241 0.2601137 0.6122664 0.2185064 0.549771 0.2438524 0.5352486 0.2963944 0.5716609 0.2529014 0.5085309 0.2908549 0.5352486 0.2963944 0.549771 0.2438524 0.5225851 0.2367655 0.5085309 0.2908549 0.549771 0.2438524 0.5352486 0.2963944 0.5572178 0.301274 0.5716609 0.2529014 0.5716609 0.2529014 0.5572178 0.301274 0.5885241 0.2601137 0.5572178 0.301274 0.5746446 0.3051185 0.5885241 0.2601137 0.5085309 0.2908549 0.5007624 0.3462888 0.5352486 0.2963944 0.5007624 0.3462888 0.5281035 0.3483402 0.5352486 0.2963944 0.5352486 0.2963944 0.5281035 0.3483402 0.5572178 0.301274 0.5281035 0.3483402 0.5503051 0.3500352 0.5572178 0.301274 0.5572178 0.301274 0.5503051 0.3500352 0.5746446 0.3051185 0.5503051 0.3500352 0.567955 0.3512266 0.5746446 0.3051185 0.5007624 0.3462888 0.5007624 0.4023982 0.5281035 0.3483402 0.5007624 0.4023982 0.5282323 0.4006037 0.5281035 0.3483402 0.5281035 0.3483402 0.5282323 0.4006037 0.5503051 0.3500352 0.5282323 0.4006037 0.5504519 0.3990953 0.5503051 0.3500352 0.5503051 0.3500352 0.5504519 0.3990953 0.567955 0.3512266 0.5504519 0.3990953 0.5680606 0.3976911 0.567955 0.3512266 0.00390625 0.7716867 0.003906309 0.8240724 0.01235991 0.7728291 0.003906309 0.8240724 0.0123676 0.8229879 0.01235991 0.7728291 0.01235991 0.7728291 0.0123676 0.8229879 0.02005803 0.7738682 0.0123676 0.8229879 0.02007251 0.8219993 0.02005803 0.7738682 0.003906309 0.8240724 0.01746517 0.8746736 0.0123676 0.8229879 0.01746517 0.8746736 0.02535736 0.8714362 0.0123676 0.8229879 0.0123676 0.8229879 0.02535736 0.8714362 0.02007251 0.8219993 0.02535736 0.8714362 0.03254371 0.8684865 0.02007251 0.8219993 0.01746517 0.8746736 0.04365783 0.9200402 0.02535736 0.8714362 0.04365783 0.9200402 0.05044317 0.9148704 0.02535736 0.8714362 0.02535736 0.8714362 0.05044317 0.9148704 0.03254371 0.8684865 0.05044317 0.9148704 0.05662149 0.9101615 0.03254371 0.8684865 0.04365783 0.9200402 0.08070057 0.9570817 0.05044317 0.9148704 0.08070057 0.9570817 0.08591663 0.9503319 0.05044317 0.9148704 0.05044317 0.9148704 0.08591663 0.9503319 0.05662149 0.9101615 0.08591663 0.9503319 0.09066498 0.9441852 0.05662149 0.9101615 0.08070057 0.9570817 0.1260671 0.9832739 0.08591663 0.9503319 0.1260671 0.9832739 0.1293585 0.9754042 0.08591663 0.9503319 0.08591663 0.9503319 0.1293585 0.9754042 0.09066498 0.9441852 0.1293585 0.9754042 0.1323543 0.9682372 0.09066498 0.9441852 0.1260671 0.9832739 0.1766665 0.9968319 0.1293585 0.9754042 0.1766665 0.9968319 0.177809 0.9883784 0.1293585 0.9754042 0.1293585 0.9754042 0.177809 0.9883784 0.1323543 0.9682372 0.177809 0.9883784 0.1788479 0.9806805 0.1323543 0.9682372 0.1766665 0.9968319 0.2290507 0.9968319 0.177809 0.9883784 0.2290507 0.9968319 0.2279663 0.9883708 0.177809 0.9883784 0.177809 0.9883784 0.2279663 0.9883708 0.1788479 0.9806805 0.2279663 0.9883708 0.2269777 0.9806662 0.1788479 0.9806805 0.2290507 0.9968319 0.2796507 0.983274 0.2279663 0.9883708 0.2796507 0.983274 0.2764135 0.975382 0.2279663 0.9883708 0.2279663 0.9883708 0.2764135 0.975382 0.2269777 0.9806662 0.2764135 0.975382 0.273464 0.9681957 0.2269777 0.9806662 0.2796507 0.983274 0.3250167 0.9570827 0.2764135 0.975382 0.3250167 0.9570827 0.3198472 0.9502974 0.2764135 0.975382 0.2764135 0.975382 0.3198472 0.9502974 0.273464 0.9681957 0.3198472 0.9502974 0.3151385 0.9441192 0.273464 0.9681957 0.3250167 0.9570827 0.3620584 0.9200416 0.3198472 0.9502974 0.3620584 0.9200416 0.3553088 0.9148254 0.3198472 0.9502974 0.3198472 0.9502974 0.3553088 0.9148254 0.3151385 0.9441192 0.3553088 0.9148254 0.3491623 0.910077 0.3151385 0.9441192 0.3620584 0.9200416 0.3882515 0.8746762 0.3553088 0.9148254 0.3882515 0.8746762 0.380382 0.8713846 0.3553088 0.9148254 0.3553088 0.9148254 0.380382 0.8713846 0.3491623 0.910077 0.380382 0.8713846 0.3732151 0.8683887 0.3491623 0.910077 0.3882515 0.8746762 0.4018109 0.8240774 0.380382 0.8713846 0.4018109 0.8240774 0.3933575 0.8229348 0.380382 0.8713846 0.380382 0.8713846 0.3933575 0.8229348 0.3732151 0.8683887 0.3933575 0.8229348 0.3856596 0.8218955 0.3732151 0.8683887 0.2876806 0.1458148 0.3448049 0.158658 0.2885111 0.1366223 0.3448049 0.158658 0.3480328 0.1500026 0.2885111 0.1366223 0.3448049 0.158658 0.3965741 0.186105 0.3480328 0.1500026 0.3965741 0.186105 0.4019686 0.1785997 0.3480328 0.1500026 0.3965741 0.186105 0.4393269 0.2262251 0.4019686 0.1785997 0.4393269 0.2262251 0.4465098 0.2203998 0.4019686 0.1785997 0.4393269 0.2262251 0.4700425 0.2762028 0.4465098 0.2203998 0.4700425 0.2762028 0.4785091 0.2724682 0.4465098 0.2203998 0.4700425 0.2762028 0.4865443 0.332527 0.4785091 0.2724682 0.4865443 0.332527 0.4956995 0.3311497 0.4785091 0.2724682 0.4865443 0.332527 0.4876552 0.3912376 0.4956995 0.3311497 0.4876552 0.3912376 0.4968561 0.3923168 0.4956995 0.3311497 0.4876552 0.3912376 0.4732818 0.4482042 0.4968561 0.3923168 0.4732818 0.4482042 0.4818778 0.4516662 0.4968561 0.3923168 0.4732818 0.4482042 0.4444195 0.4994119 0.4818778 0.4516662 0.4444195 0.4994119 0.4518064 0.5050151 0.4818778 0.4516662 0.4444195 0.4994119 0.403086 0.541247 0.4518064 0.5050151 0.403086 0.541247 0.4087414 0.5486003 0.4518064 0.5050151 0.403086 0.541247 0.3521791 0.570749 0.4087414 0.5486003 0.3521791 0.570749 0.3557021 0.5793358 0.4087414 0.5486003 0.3521791 0.570749 0.2952822 0.5858036 0.3557021 0.5793358 0.2952822 0.5858036 0.2964122 0.5950196 0.3557021 0.5793358 0.2952822 0.5858036 0.236442 0.5852586 0.2964122 0.5950196 0.236442 0.5852586 0.2350667 0.5944423 0.2964122 0.5950196 0.5007624 0.4023982 0.5086093 0.4581709 0.5282323 0.4006037 0.5086093 0.4581709 0.5359614 0.4526122 0.5282323 0.4006037 0.5282323 0.4006037 0.5359614 0.4526122 0.5504519 0.3990953 0.5359614 0.4526122 0.5578754 0.4478012 0.5504519 0.3990953 0.5504519 0.3990953 0.5578754 0.4478012 0.5680606 0.3976911 0.5578754 0.4478012 0.5750622 0.4436005 0.5680606 0.3976911 0.5086093 0.4581709 0.5235196 0.5133897 0.5359614 0.4526122 0.5235196 0.5133897 0.5515438 0.5054265 0.5359614 0.4526122 0.5359614 0.4526122 0.5515438 0.5054265 0.5578754 0.4478012 0.5515438 0.5054265 0.5737707 0.4964572 0.5578754 0.4478012 0.5578754 0.4478012 0.5737707 0.4964572 0.5750622 0.4436005 0.5737707 0.4964572 0.59014 0.4877992 0.5750622 0.4436005 0.5737707 0.4964572 0.605697 0.5394954 0.59014 0.4877992 0.605697 0.5394954 0.6189324 0.5259033 0.59014 0.4877992 0.605697 0.5394954 0.6502678 0.5716481 0.6189324 0.5259033 0.6502678 0.5716481 0.6590859 0.5542367 0.6189324 0.5259033 0.6502678 0.5716481 0.703812 0.5897448 0.6590859 0.5542367 0.703812 0.5897448 0.7073009 0.569949 0.6590859 0.5542367 0.703812 0.5897448 0.7619094 0.5917937 0.7073009 0.569949 0.7619094 0.5917937 0.7596024 0.5712465 0.7073009 0.569949 0.7619094 0.5917937 0.8197503 0.5771416 0.7596024 0.5712465 0.8197503 0.5771416 0.8116669 0.5575442 0.7596024 0.5712465 0.8197503 0.5771416 0.8725323 0.5465329 0.8116669 0.5575442 0.8725323 0.5465329 0.8591743 0.5295135 0.8116669 0.5575442 0.8725323 0.5465329 0.9158528 0.5020529 0.8591743 0.5295135 0.9158528 0.5020529 0.8981696 0.4890326 0.8591743 0.5295135 0.9158528 0.5020529 0.9460767 0.4469625 0.8981696 0.4890326 0.9460767 0.4469625 0.9253852 0.4390378 0.8981696 0.4890326 0.9460767 0.4469625 0.9606349 0.3854345 0.9253852 0.4390378 0.9606349 0.3854345 0.9385173 0.3832853 0.9253852 0.4390378 0.9606349 0.3854345 0.9582458 0.3222229 0.9385173 0.3832853 0.9582458 0.3222229 0.9364184 0.3260506 0.9385173 0.3832853 0.4018109 0.8240774 0.4018126 0.7716931 0.3933575 0.8229348 0.4018126 0.7716931 0.3933514 0.7727771 0.3933575 0.8229348 0.3933575 0.8229348 0.3933514 0.7727771 0.3856596 0.8218955 0.3933514 0.7727771 0.3856467 0.7737655 0.3856596 0.8218955 0.4018126 0.7716931 0.3882562 0.7210919 0.3933514 0.7727771 0.3882562 0.7210919 0.3803631 0.7243294 0.3933514 0.7727771 0.3933514 0.7727771 0.3803631 0.7243294 0.3856467 0.7737655 0.3803631 0.7243294 0.3731773 0.7272785 0.3856467 0.7737655 0.3882562 0.7210919 0.362065 0.675724 0.3803631 0.7243294 0.362065 0.675724 0.3552787 0.6808941 0.3803631 0.7243294 0.3803631 0.7243294 0.3552787 0.6808941 0.3731773 0.7272785 0.3552787 0.6808941 0.349101 0.685603 0.3731773 0.7272785 0.362065 0.675724 0.3250243 0.6386809 0.3552787 0.6808941 0.3250243 0.6386809 0.3198074 0.6454313 0.3552787 0.6808941 0.3552787 0.6808941 0.3198074 0.6454313 0.349101 0.685603 0.3198074 0.6454313 0.3150587 0.6515786 0.349101 0.685603 0.3250243 0.6386809 0.2796576 0.6124872 0.3198074 0.6454313 0.2796576 0.6124872 0.2763658 0.620357 0.3198074 0.6454313 0.3198074 0.6454313 0.2763658 0.620357 0.3150587 0.6515786 0.2763658 0.620357 0.2733696 0.627524 0.3150587 0.6515786 0.2796576 0.6124872 0.2290573 0.5989271 0.2763658 0.620357 0.2290573 0.5989271 0.2279145 0.6073809 0.2763658 0.620357 0.2763658 0.620357 0.2279145 0.6073809 0.2733696 0.627524 0.2279145 0.6073809 0.2268753 0.615079 0.2733696 0.627524 0.2290573 0.5989271 0.1766705 0.5989258 0.2279145 0.6073809 0.1766705 0.5989258 0.1777548 0.6073872 0.2279145 0.6073809 0.2279145 0.6073809 0.1777548 0.6073872 0.2268753 0.615079 0.1777548 0.6073872 0.1787433 0.6150922 0.2268753 0.615079 0.1766705 0.5989258 0.126069 0.6124826 0.1777548 0.6073872 0.126069 0.6124826 0.1293067 0.6203759 0.1777548 0.6073872 0.1777548 0.6073872 0.1293067 0.6203759 0.1787433 0.6150922 0.1293067 0.6203759 0.1322562 0.6275624 0.1787433 0.6150922 0.126069 0.6124826 0.08070051 0.6386756 0.1293067 0.6203759 0.08070051 0.6386756 0.08587092 0.6454619 0.1293067 0.6203759 0.1293067 0.6203759 0.08587092 0.6454619 0.1322562 0.6275624 0.08587092 0.6454619 0.09057927 0.6516396 0.1322562 0.6275624 0.08070051 0.6386756 0.04365783 0.675718 0.08587092 0.6454619 0.04365783 0.675718 0.05040848 0.6809349 0.08587092 0.6454619 0.08587092 0.6454619 0.05040848 0.6809349 0.09057927 0.6516396 0.05040848 0.6809349 0.05655473 0.685683 0.09057927 0.6516396 0.04365783 0.675718 0.01746469 0.7210858 0.05040848 0.6809349 0.01746469 0.7210858 0.02533459 0.7243773 0.05040848 0.6809349 0.05040848 0.6809349 0.02533459 0.7243773 0.05655473 0.685683 0.02533459 0.7243773 0.03250175 0.7273733 0.05655473 0.685683 0.01746469 0.7210858 0.00390625 0.7716867 0.02533459 0.7243773 0.00390625 0.7716867 0.01235991 0.7728291 0.02533459 0.7243773 0.02533459 0.7243773 0.01235991 0.7728291 0.03250175 0.7273733 0.01235991 0.7728291 0.02005803 0.7738682 0.03250175 0.7273733 0.2679725 0.365907 0.1800367 0.5688781 0.236442 0.5852586 0.2679725 0.365907 0.1311475 0.5370425 0.1800367 0.5688781 0.2679725 0.365907 0.09787863 0.4901666 0.1311475 0.5370425 0.2679725 0.365907 0.07653158 0.442074 0.09787863 0.4901666 0.2679725 0.365907 0.06556189 0.3927496 0.07653158 0.442074 0.2679725 0.365907 0.06497049 0.3430217 0.06556189 0.3927496 0.2679725 0.365907 0.07437455 0.2938694 0.06497049 0.3430217 0.2679725 0.365907 0.09369289 0.245186 0.07437455 0.2938694 0.2679725 0.365907 0.1262683 0.1996575 0.09369289 0.245186 0.2679725 0.365907 0.1738846 0.1667155 0.1262683 0.1996575 0.2679725 0.365907 0.2292709 0.1485136 0.1738846 0.1667155 0.2679725 0.365907 0.2876806 0.1458148 0.2292709 0.1485136 0.2679725 0.365907 0.3448049 0.158658 0.2876806 0.1458148 0.2679725 0.365907 0.3965741 0.186105 0.3448049 0.158658 0.2679725 0.365907 0.4393269 0.2262251 0.3965741 0.186105 0.2679725 0.365907 0.4700425 0.2762028 0.4393269 0.2262251 0.2679725 0.365907 0.4865443 0.332527 0.4700425 0.2762028 0.2679725 0.365907 0.4876552 0.3912376 0.4865443 0.332527 0.2679725 0.365907 0.4732818 0.4482042 0.4876552 0.3912376 0.2679725 0.365907 0.4444195 0.4994119 0.4732818 0.4482042 0.2679725 0.365907 0.403086 0.541247 0.4444195 0.4994119 0.2679725 0.365907 0.3521791 0.570749 0.403086 0.541247 0.2679725 0.365907 0.2952822 0.5858036 0.3521791 0.570749 0.2679725 0.365907 0.236442 0.5852586 0.2952822 0.5858036 0.02005803 0.7738682 0.02007251 0.8219993 0.2026326 0.7975854 0.02007251 0.8219993 0.03254371 0.8684865 0.2026326 0.7975854 0.03254371 0.8684865 0.05662149 0.9101615 0.2026326 0.7975854 0.05662149 0.9101615 0.09066498 0.9441852 0.2026326 0.7975854 0.09066498 0.9441852 0.1323543 0.9682372 0.2026326 0.7975854 0.1323543 0.9682372 0.1788479 0.9806805 0.2026326 0.7975854 0.1788479 0.9806805 0.2269777 0.9806662 0.2026326 0.7975854 0.2269777 0.9806662 0.273464 0.9681957 0.2026326 0.7975854 0.273464 0.9681957 0.3151385 0.9441192 0.2026326 0.7975854 0.3151385 0.9441192 0.3491623 0.910077 0.2026326 0.7975854 0.3491623 0.910077 0.3732151 0.8683887 0.2026326 0.7975854 0.3732151 0.8683887 0.3856596 0.8218955 0.2026326 0.7975854 0.3856596 0.8218955 0.3856467 0.7737655 0.2026326 0.7975854 0.3856467 0.7737655 0.3731773 0.7272785 0.2026326 0.7975854 0.3731773 0.7272785 0.349101 0.685603 0.2026326 0.7975854 0.349101 0.685603 0.3150587 0.6515786 0.2026326 0.7975854 0.3150587 0.6515786 0.2733696 0.627524 0.2026326 0.7975854 0.2733696 0.627524 0.2268753 0.615079 0.2026326 0.7975854 0.2268753 0.615079 0.1787433 0.6150922 0.2026326 0.7975854 0.1787433 0.6150922 0.1322562 0.6275624 0.2026326 0.7975854 0.1322562 0.6275624 0.09057927 0.6516396 0.2026326 0.7975854 0.09057927 0.6516396 0.05655473 0.685683 0.2026326 0.7975854 0.05655473 0.685683 0.03250175 0.7273733 0.2026326 0.7975854 0.03250175 0.7273733 0.02005803 0.7738682 0.2026326 0.7975854 + + + + + + + + + + + + + + + + 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 +

0 0 0 2 1 1 1 2 2 0 0 3 1 2 4 3 3 5 1 2 6 4 4 7 3 3 8 4 4 9 5 5 10 3 3 11 4 4 12 6 6 13 5 5 14 6 6 15 7 7 16 5 5 17 5 5 18 7 7 19 8 8 20 7 7 21 9 9 22 8 8 23 8 8 24 9 9 25 10 10 26 9 9 27 11 11 28 10 10 29 6 6 30 12 12 31 7 7 32 12 12 33 13 13 34 7 7 35 7 7 36 13 13 37 9 9 38 13 13 39 14 14 40 9 9 41 9 9 42 14 14 43 11 11 44 14 14 45 15 15 46 11 11 47 12 12 48 16 16 49 13 13 50 16 16 51 17 17 52 13 13 53 13 13 54 17 17 55 14 14 56 17 17 57 18 18 58 14 14 59 14 14 60 18 18 61 15 15 62 18 18 63 19 19 64 15 15 65 16 16 66 20 20 67 17 17 68 20 20 69 21 21 70 17 17 71 17 17 72 21 21 73 18 18 74 21 21 75 22 22 76 18 18 77 18 18 78 22 22 79 19 19 80 22 22 81 23 23 82 19 19 83 20 20 84 24 24 85 21 21 86 24 24 87 25 25 88 21 21 89 21 21 90 25 25 91 22 22 92 25 25 93 26 26 94 22 22 95 22 22 96 26 26 97 23 23 98 26 26 99 27 27 100 23 23 101 24 24 102 28 28 103 25 25 104 28 28 105 29 29 106 25 25 107 25 25 108 29 29 109 26 26 110 29 29 111 30 30 112 26 26 113 26 26 114 30 30 115 27 27 116 30 30 117 31 31 118 27 27 119 28 28 120 32 32 121 29 29 122 32 32 123 33 33 124 29 29 125 29 29 126 33 33 127 30 30 128 33 33 129 34 34 130 30 30 131 32 32 132 35 35 133 33 33 134 35 35 135 36 36 136 33 33 137 35 35 138 37 37 139 36 36 140 37 37 141 38 38 142 36 36 143 37 37 144 39 39 145 38 38 146 39 39 147 40 40 148 38 38 149 43 41 150 42 42 151 41 43 152 42 42 153 44 44 154 41 43 155 41 43 156 44 44 157 45 45 158 44 44 159 46 46 160 45 45 161 42 42 162 47 47 163 44 44 164 47 47 165 48 48 166 44 44 167 44 44 168 48 48 169 46 46 170 48 48 171 49 49 172 46 46 173 43 41 174 41 43 175 50 50 176 51 51 177 43 41 178 50 50 179 51 51 180 50 50 181 52 52 182 53 53 183 51 51 184 52 52 185 53 53 186 52 52 187 54 54 188 55 55 189 53 53 190 54 54 191 55 55 192 54 54 193 56 56 194 57 57 195 55 55 196 56 56 197 57 57 198 56 56 199 58 58 200 59 59 201 57 57 202 58 58 203 59 59 204 58 58 205 60 60 206 61 61 207 59 59 208 60 60 209 61 61 210 60 60 211 62 62 212 63 63 213 61 61 214 62 62 215 63 63 216 62 62 217 64 64 218 65 65 219 63 63 220 64 64 221 65 65 222 64 64 223 66 66 224 67 67 225 65 65 226 66 66 227 67 67 228 66 66 229 68 68 230 69 69 231 67 67 232 68 68 233 68 68 234 66 66 235 70 70 236 66 66 237 71 71 238 70 70 239 66 66 240 64 64 241 71 71 242 64 64 243 72 72 244 71 71 245 64 64 246 62 62 247 72 72 248 62 62 249 73 73 250 72 72 251 62 62 252 60 60 253 73 73 254 60 60 255 74 74 256 73 73 257 60 60 258 58 58 259 74 74 260 58 58 261 75 75 262 74 74 263 58 58 264 56 56 265 75 75 266 56 56 267 76 76 268 75 75 269 56 56 270 54 54 271 76 76 272 54 54 273 77 77 274 76 76 275 54 54 276 52 52 277 77 77 278 52 52 279 78 78 280 77 77 281 52 52 282 50 50 283 78 78 284 50 50 285 79 79 286 78 78 287 50 50 288 41 43 289 79 79 290 41 43 291 45 45 292 79 79 293 82 80 294 81 81 295 80 82 296 81 81 297 83 83 298 80 82 299 81 81 300 84 84 301 83 83 302 84 84 303 85 85 304 83 83 305 84 84 306 86 86 307 85 85 308 86 86 309 87 87 310 85 85 311 86 86 312 88 88 313 87 87 314 88 88 315 89 89 316 87 87 317 88 88 318 90 90 319 89 89 320 90 90 321 91 91 322 89 89 323 90 90 324 92 92 325 91 91 326 92 92 327 93 93 328 91 91 329 92 92 330 94 94 331 93 93 332 94 94 333 95 95 334 93 93 335 94 94 336 96 96 337 95 95 338 96 96 339 97 97 340 95 95 341 96 96 342 98 98 343 97 97 344 99 99 345 98 98 346 96 96 347 100 100 348 99 99 349 96 96 350 98 98 351 101 101 352 97 97 353 99 99 354 102 102 355 98 98 356 103 103 357 102 102 358 99 99 359 104 104 360 103 103 361 99 99 362 102 102 363 105 105 364 98 98 365 98 98 366 105 105 367 101 101 368 105 105 369 106 106 370 101 101 371 103 103 372 107 107 373 102 102 374 107 107 375 108 108 376 102 102 377 102 102 378 108 108 379 105 105 380 108 108 381 109 109 382 105 105 383 105 105 384 109 109 385 106 106 386 109 109 387 110 110 388 106 106 389 107 107 390 111 111 391 108 108 392 111 111 393 112 112 394 108 108 395 108 108 396 112 112 397 109 109 398 112 112 399 113 113 400 109 109 401 109 109 402 113 113 403 110 110 404 113 113 405 114 114 406 110 110 407 117 115 408 116 116 409 115 117 410 116 116 411 118 118 412 115 117 413 115 117 414 118 118 415 119 119 416 118 118 417 120 120 418 119 119 419 116 116 420 121 121 421 118 118 422 121 121 423 122 122 424 118 118 425 118 118 426 122 122 427 120 120 428 122 122 429 123 123 430 120 120 431 121 121 432 124 124 433 122 122 434 124 124 435 125 125 436 122 122 437 122 122 438 125 125 439 123 123 440 125 125 441 126 126 442 123 123 443 124 124 444 127 127 445 125 125 446 127 127 447 128 128 448 125 125 449 125 125 450 128 128 451 126 126 452 128 128 453 129 129 454 126 126 455 127 127 456 130 130 457 128 128 458 130 130 459 131 131 460 128 128 461 128 128 462 131 131 463 129 129 464 131 131 465 132 132 466 129 129 467 130 130 468 133 133 469 131 131 470 133 133 471 134 134 472 131 131 473 131 131 474 134 134 475 132 132 476 134 134 477 135 135 478 132 132 479 133 133 480 136 136 481 134 134 482 136 136 483 137 137 484 134 134 485 134 134 486 137 137 487 135 135 488 137 137 489 138 138 490 135 135 491 136 136 492 139 139 493 137 137 494 139 139 495 140 140 496 137 137 497 137 137 498 140 140 499 138 138 500 140 140 501 141 141 502 138 138 503 139 139 504 142 142 505 140 140 506 142 142 507 143 143 508 140 140 509 140 140 510 143 143 511 141 141 512 143 143 513 144 144 514 141 141 515 142 142 516 145 145 517 143 143 518 145 145 519 146 146 520 143 143 521 143 143 522 146 146 523 144 144 524 146 146 525 147 147 526 144 144 527 145 145 528 148 148 529 146 146 530 148 148 531 149 149 532 146 146 533 146 146 534 149 149 535 147 147 536 149 149 537 150 150 538 147 147 539 148 148 540 151 151 541 149 149 542 151 151 543 152 152 544 149 149 545 149 149 546 152 152 547 150 150 548 152 152 549 153 153 550 150 150 551 156 154 552 155 155 553 154 156 554 155 155 555 157 157 556 154 156 557 155 155 558 158 158 559 157 157 560 158 158 561 159 159 562 157 157 563 158 158 564 160 160 565 159 159 566 160 160 567 161 161 568 159 159 569 160 160 570 162 162 571 161 161 572 162 162 573 163 163 574 161 161 575 162 162 576 164 164 577 163 163 578 164 164 579 165 165 580 163 163 581 164 164 582 166 166 583 165 165 584 166 166 585 167 167 586 165 165 587 166 166 588 168 168 589 167 167 590 168 168 591 169 169 592 167 167 593 168 168 594 170 170 595 169 169 596 170 170 597 171 171 598 169 169 599 170 170 600 172 172 601 171 171 602 172 172 603 173 173 604 171 171 605 172 172 606 174 174 607 173 173 608 174 174 609 175 175 610 173 173 611 174 174 612 176 176 613 175 175 614 176 176 615 177 177 616 175 175 617 176 176 618 2 1 619 177 177 620 2 1 621 0 0 622 177 177 623 180 178 624 179 179 625 178 180 626 179 179 627 181 181 628 178 180 629 178 180 630 181 181 631 182 182 632 181 181 633 183 183 634 182 182 635 182 182 636 183 183 637 184 184 638 183 183 639 185 185 640 184 184 641 179 179 642 186 186 643 181 181 644 186 186 645 187 187 646 181 181 647 181 181 648 187 187 649 183 183 650 187 187 651 188 188 652 183 183 653 183 183 654 188 188 655 185 185 656 188 188 657 189 189 658 185 185 659 188 188 660 190 190 661 189 189 662 190 190 663 191 191 664 189 189 665 190 190 666 192 192 667 191 191 668 192 192 669 193 193 670 191 191 671 192 192 672 194 194 673 193 193 674 194 194 675 195 195 676 193 193 677 194 194 678 196 196 679 195 195 680 196 196 681 197 197 682 195 195 683 196 196 684 198 198 685 197 197 686 198 198 687 199 199 688 197 197 689 198 198 690 200 200 691 199 199 692 200 200 693 201 201 694 199 199 695 200 200 696 202 202 697 201 201 698 202 202 699 203 203 700 201 201 701 202 202 702 204 204 703 203 203 704 204 204 705 205 205 706 203 203 707 204 204 708 206 206 709 205 205 710 206 206 711 207 207 712 205 205 713 206 206 714 82 80 715 207 207 716 82 80 717 80 82 718 207 207 719 210 208 720 209 209 721 208 210 722 209 209 723 211 211 724 208 210 725 208 210 726 211 211 727 212 212 728 211 211 729 213 213 730 212 212 731 209 209 732 214 214 733 211 211 734 214 214 735 215 215 736 211 211 737 211 211 738 215 215 739 213 213 740 215 215 741 216 216 742 213 213 743 214 214 744 217 217 745 215 215 746 217 217 747 218 218 748 215 215 749 215 215 750 218 218 751 216 216 752 218 218 753 219 219 754 216 216 755 217 217 756 220 220 757 218 218 758 220 220 759 221 221 760 218 218 761 218 218 762 221 221 763 219 219 764 221 221 765 222 222 766 219 219 767 220 220 768 223 223 769 221 221 770 223 223 771 224 224 772 221 221 773 221 221 774 224 224 775 222 222 776 224 224 777 225 225 778 222 222 779 223 223 780 226 226 781 224 224 782 226 226 783 227 227 784 224 224 785 224 224 786 227 227 787 225 225 788 227 227 789 228 228 790 225 225 791 226 226 792 229 229 793 227 227 794 229 229 795 230 230 796 227 227 797 227 227 798 230 230 799 228 228 800 230 230 801 231 231 802 228 228 803 229 229 804 232 232 805 230 230 806 232 232 807 233 233 808 230 230 809 230 230 810 233 233 811 231 231 812 233 233 813 234 234 814 231 231 815 232 232 816 235 235 817 233 233 818 235 235 819 236 236 820 233 233 821 233 233 822 236 236 823 234 234 824 236 236 825 237 237 826 234 234 827 235 235 828 238 238 829 236 236 830 238 238 831 239 239 832 236 236 833 236 236 834 239 239 835 237 237 836 239 239 837 240 240 838 237 237 839 238 238 840 241 241 841 239 239 842 241 241 843 242 242 844 239 239 845 239 239 846 242 242 847 240 240 848 242 242 849 243 243 850 240 240 851 241 241 852 117 115 853 242 242 854 117 115 855 115 117 856 242 242 857 242 242 858 115 117 859 243 243 860 115 117 861 119 119 862 243 243 863 246 244 864 245 245 865 244 246 866 246 244 867 247 247 868 245 245 869 246 244 870 248 248 871 247 247 872 246 244 873 249 249 874 248 248 875 246 244 876 250 250 877 249 249 878 246 244 879 251 251 880 250 250 881 246 244 882 252 252 883 251 251 884 246 244 885 253 253 886 252 252 887 246 244 888 254 254 889 253 253 890 246 244 891 255 255 892 254 254 893 246 244 894 256 256 895 255 255 896 246 244 897 257 257 898 256 256 899 246 244 900 258 258 901 257 257 902 246 244 903 259 259 904 258 258 905 246 244 906 260 260 907 259 259 908 246 244 909 261 261 910 260 260 911 246 244 912 262 262 913 261 261 914 246 244 915 263 263 916 262 262 917 246 244 918 264 264 919 263 263 920 246 244 921 265 265 922 264 264 923 246 244 924 266 266 925 265 265 926 246 244 927 267 267 928 266 266 929 246 244 930 268 268 931 267 267 932 246 244 933 244 246 934 268 268 935 271 269 936 270 270 937 269 271 938 270 270 939 272 272 940 269 271 941 272 272 942 273 273 943 269 271 944 273 273 945 274 274 946 269 271 947 274 274 948 275 275 949 269 271 950 275 275 951 276 276 952 269 271 953 276 276 954 277 277 955 269 271 956 277 277 957 278 278 958 269 271 959 278 278 960 279 279 961 269 271 962 279 279 963 280 280 964 269 271 965 280 280 966 281 281 967 269 271 968 281 281 969 282 282 970 269 271 971 282 282 972 283 283 973 269 271 974 283 283 975 284 284 976 269 271 977 284 284 978 285 285 979 269 271 980 285 285 981 286 286 982 269 271 983 286 286 984 287 287 985 269 271 986 287 287 987 288 288 988 269 271 989 288 288 990 289 289 991 269 271 992 289 289 993 290 290 994 269 271 995 290 290 996 291 291 997 269 271 998 291 291 999 292 292 1000 269 271 1001 292 292 1002 293 293 1003 269 271 1004 293 293 1005 271 269 1006 269 271 1007

+
+
+
+
+ + + + + 0.6858805 -0.3173701 0.6548619 7.481132 0.7276338 0.3124686 -0.6106656 -6.50764 -0.01081678 0.8953432 0.4452454 5.343665 0 0 0 1 + + + + -0.2908646 -0.7711008 0.5663932 4.076245 0.9551712 -0.1998834 0.2183912 1.005454 -0.05518906 0.6045247 0.7946723 5.903862 0 0 0 1 + + + + 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 + + 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 + + + + + + + + + + + + + + +
\ No newline at end of file diff --git a/src/parts source/kOS0m dev/kOSMachine0m.blend b/src/parts source/kOS0m dev/kOSMachine0m.blend new file mode 100644 index 000000000..e0d61e5c0 Binary files /dev/null and b/src/parts source/kOS0m dev/kOSMachine0m.blend differ diff --git a/src/parts source/kOS0m dev/kOSMachine0m.dae b/src/parts source/kOS0m dev/kOSMachine0m.dae new file mode 100644 index 000000000..54a15b40b --- /dev/null +++ b/src/parts source/kOS0m dev/kOSMachine0m.dae @@ -0,0 +1,356 @@ + + + + + Blender User + Blender 2.73.0 commit date:2015-01-20, commit time:18:16, hash:bbf09d9 + + 2015-05-09T20:21:18 + 2015-05-09T20:21:18 + + Z_UP + + + + + + + 49.13434 + 1.777778 + 0.1 + 100 + + + + + + 0 + 0 + 0 + + + + + + + + + 1 1 1 + 1 + 0 + 0.00111109 + + + + + 0.000999987 + 1 + 0.1 + 0.1 + 1 + 1 + 1 + 2 + 0 + 1 + 1 + 1 + 1 + 1 + 0 + 2880 + 2 + 30.002 + 1.000799 + 0.04999995 + 29.99998 + 1 + 2 + 0 + 0 + 1 + 1 + 1 + 1 + 8192 + 1 + 1 + 0 + 1 + 1 + 1 + 3 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 1 + 3 + 0.15 + 75 + 1 + 1 + 0 + 1 + 1 + 0 + + + + + + + 0.5862063 5 0 + 1 + 0 + 1 + 162 + 0.15 + + + + + 0.000999987 + 0 + 0.1 + 0.1 + 0.1 + 1 + 1 + 2 + 0 + 1 + 1 + 1 + 0 + 1 + 0 + 512 + 2 + 40 + 0.5 + 0.04999995 + 1 + 5 + 2 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0.1172412 + 3 + 0 + 0 + 0 + 0 + 2 + 1 + 1 + 1 + 3 + 0.15 + 162 + 1 + 1 + 0 + 1 + 1 + 2 + + + + + + + + + + + + 0 0 0 1 + + + 0 0 0 1 + + + 0.64 0.64 0.64 1 + + + 0.5 0.5 0.5 1 + + + 50 + + + 1 + + + + + + + + + + + + + + + + 0.25 0 0.02842795 0.23476 -0.062904 0.03539395 0.243041 0 0.03539395 0.241481 -0.06470495 0.02842795 0.21048 -0.12152 0.03539395 0.216506 -0.125 0.02842795 0.171856 -0.171856 0.03539395 0.176777 -0.176777 0.02842795 0.216332 -0.1249 -0.004379987 0.176635 -0.176635 -0.004379987 0.202262 -0.116776 -0.02643096 0.165147 -0.165147 -0.02643096 0.12152 -0.21048 0.03539395 0.125 -0.216506 0.02842795 0.1249 -0.216333 -0.004379987 0.116776 -0.2022629 -0.02643096 0.062904 -0.234759 0.03539395 0.06470495 -0.241481 0.02842795 0.06465297 -0.241288 -0.004379987 0.06044799 -0.2255949 -0.02642995 0 -0.243041 0.03539395 0 -0.25 0.02842795 0 -0.249799 -0.004379987 0 -0.233553 -0.02642995 -0.062904 -0.234759 0.03539395 -0.06470495 -0.241481 0.02842795 -0.06465297 -0.241288 -0.004379987 -0.06044799 -0.225594 -0.02642995 -0.121521 -0.210479 0.03539395 -0.125 -0.216506 0.02842795 -0.1249 -0.216332 -0.004379987 -0.116776 -0.202262 -0.02643096 -0.171856 -0.171856 0.03539395 -0.176777 -0.176777 0.02842795 -0.176635 -0.176635 -0.004379987 -0.21048 -0.12152 0.03539395 -0.216506 -0.125 0.02842795 -0.23476 -0.06290298 0.03539395 -0.241482 -0.064704 0.02842795 -0.243041 0 0.03539395 -0.25 0 0.02842795 0.249799 0 -0.004379987 0.241481 -0.06470495 0.02842795 0.25 0 0.02842795 0.241288 -0.06465297 -0.004379987 0.233553 0 -0.02643096 0.225594 -0.06044799 -0.02643096 0.216506 -0.125 0.02842795 0.216332 -0.1249 -0.004379987 0.202262 -0.116776 -0.02643096 0.241288 0.06465196 -0.004379987 0.241482 0.064704 0.028427 0.216333 0.124899 -0.004380941 0.216507 0.125 0.028427 0.176635 0.176634 -0.004380941 0.176777 0.176776 0.028427 0.1249 0.216332 -0.004380941 0.125 0.216506 0.028427 0.06465297 0.2412869 -0.004380941 0.06470495 0.241481 0.028427 0 0.249799 -0.004380941 0 0.25 0.028427 -0.06465196 0.241288 -0.004380941 -0.064704 0.241482 0.028427 -0.124899 0.216333 -0.004380941 -0.125 0.216507 0.028427 -0.176635 0.176635 -0.004380941 -0.176776 0.176777 0.028427 -0.216332 0.1249 -0.004380941 -0.216506 0.125 0.028427 -0.202262 0.116776 -0.02643096 -0.1651459 0.165147 -0.02643096 -0.116776 0.2022629 -0.02643096 -0.06044799 0.225594 -0.02643197 0 0.233552 -0.02643197 0.06044799 0.225594 -0.02643197 0.116777 0.202262 -0.02643096 0.165147 0.1651459 -0.02643096 0.2022629 0.116776 -0.02643096 0.2255949 0.06044697 -0.02643096 0.212099 0 -0.02643096 0.225594 -0.06044799 -0.02643096 0.233553 0 -0.02643096 0.204872 -0.05489498 -0.02643096 0.202262 -0.116776 -0.02643096 0.183683 -0.10605 -0.02643096 0.165147 -0.165147 -0.02643096 0.149977 -0.149977 -0.02643096 0.116776 -0.2022629 -0.02643096 0.106049 -0.183683 -0.02643096 0.06044799 -0.2255949 -0.02642995 0.05489498 -0.204872 -0.02643096 0 -0.233553 -0.02642995 0 -0.212099 -0.02643096 -0.06044799 -0.225594 -0.02642995 -0.05489498 -0.204872 -0.02643096 -0.116776 -0.202262 -0.02643096 -0.10605 -0.183683 -0.02643096 -0.165147 -0.165147 -0.02643096 -0.176635 -0.176635 -0.004379987 -0.1249 -0.216332 -0.004379987 -0.149977 -0.149977 -0.02643096 -0.216333 -0.124899 -0.004379987 -0.216506 -0.125 0.02842795 -0.176777 -0.176777 0.02842795 -0.2022629 -0.116776 -0.02643096 -0.183683 -0.106049 -0.02643096 -0.241482 -0.064704 0.02842795 -0.241288 -0.06465297 -0.004379987 -0.2255949 -0.06044799 -0.02643096 -0.204872 -0.05489498 -0.02643096 -0.25 0 0.02842795 -0.249799 0 -0.004379987 -0.233553 0 -0.02643096 -0.212099 0 -0.02643096 0.212099 0 -0.035447 0.204872 -0.05489498 -0.02643096 0.212099 0 -0.02643096 0.204872 -0.05489498 -0.035447 0.206044 0 -0.04131996 0.199023 -0.05332797 -0.04131996 0.183683 -0.10605 -0.02643096 0.183683 -0.10605 -0.035447 0.178439 -0.103022 -0.04131996 0.149977 -0.149977 -0.02643096 0.149977 -0.149977 -0.035447 0.145695 -0.145695 -0.04131996 0.106049 -0.183683 -0.02643096 0.106049 -0.183683 -0.035447 0.103022 -0.17844 -0.04131996 0.05489498 -0.204872 -0.02643096 0.05489498 -0.204872 -0.035447 0.05332797 -0.199023 -0.04131996 0 -0.212099 -0.02643096 0 -0.212099 -0.035447 0 -0.206044 -0.04131996 -0.05489498 -0.204872 -0.02643096 -0.05489498 -0.204872 -0.035447 -0.05332797 -0.199023 -0.04131996 -0.10605 -0.183683 -0.02643096 -0.10605 -0.183683 -0.035447 -0.103022 -0.178439 -0.04131996 -0.149977 -0.149977 -0.02643096 -0.149977 -0.149977 -0.035447 -0.145695 -0.145695 -0.04131996 -0.183683 -0.106049 -0.02643096 -0.183683 -0.106049 -0.035447 -0.17844 -0.103022 -0.04131996 -0.204872 -0.05489498 -0.02643096 -0.204872 -0.05489498 -0.035447 -0.199023 -0.05332797 -0.04131996 -0.212099 0 -0.02643096 -0.212099 0 -0.035447 -0.206044 0 -0.04131996 -0.25 0 0.02842795 -0.23476 0.062904 0.03539395 -0.243041 0 0.03539395 -0.241481 0.06470495 0.028427 -0.21048 0.121521 0.03539299 -0.216506 0.125 0.028427 -0.171856 0.171856 0.03539299 -0.176776 0.176777 0.028427 -0.12152 0.21048 0.03539299 -0.125 0.216507 0.028427 -0.06290298 0.23476 0.03539299 -0.064704 0.241482 0.028427 0 0.243041 0.03539299 0 0.25 0.028427 0.062904 0.23476 0.03539299 0.06470495 0.241481 0.028427 0.121521 0.21048 0.03539299 0.125 0.216506 0.028427 0.171856 0.171856 0.03539299 0.176777 0.176776 0.028427 0.21048 0.12152 0.03539299 0.216507 0.125 0.028427 0.23476 0.06290298 0.03539395 0.241482 0.064704 0.028427 -0.249799 0 -0.004379987 -0.241481 0.06470495 0.028427 -0.25 0 0.02842795 -0.2412869 0.06465297 -0.004379987 -0.233553 0 -0.02643096 -0.225594 0.06044799 -0.02643096 -0.212099 0 -0.02643096 -0.204872 0.05489498 -0.02643096 -0.216506 0.125 0.028427 -0.216332 0.1249 -0.004380941 -0.202262 0.116776 -0.02643096 -0.183683 0.10605 -0.02643096 -0.1651459 0.165147 -0.02643096 -0.149976 0.149977 -0.02643096 -0.116776 0.2022629 -0.02643096 -0.106049 0.183683 -0.02643096 -0.06044799 0.225594 -0.02643197 -0.05489498 0.204872 -0.02643197 0 0.233552 -0.02643197 0 0.212099 -0.02643197 0.06044799 0.225594 -0.02643197 0.05489599 0.204872 -0.02643197 0.116777 0.202262 -0.02643096 0.10605 0.183683 -0.02643096 0.165147 0.1651459 -0.02643096 0.149977 0.149976 -0.02643096 0.2022629 0.116776 -0.02643096 0.183683 0.106049 -0.02643096 0.2255949 0.06044697 -0.02643096 0.204872 0.05489498 -0.02643096 -0.212099 0 -0.035447 -0.204872 0.05489498 -0.02643096 -0.212099 0 -0.02643096 -0.204872 0.05489498 -0.035447 -0.206044 0 -0.04131996 -0.199023 0.05332797 -0.04131996 -0.183683 0.10605 -0.02643096 -0.183683 0.10605 -0.03544795 -0.178439 0.103022 -0.04131996 -0.149976 0.149977 -0.02643096 -0.149976 0.149977 -0.03544795 -0.145695 0.145695 -0.04132097 -0.106049 0.183683 -0.02643096 -0.106049 0.183683 -0.03544795 -0.103022 0.178439 -0.04132097 -0.05489498 0.204872 -0.02643197 -0.05489498 0.204872 -0.03544795 -0.05332797 0.199023 -0.04132097 0 0.212099 -0.02643197 0 0.212099 -0.03544795 0 0.206044 -0.04132097 0.05489599 0.204872 -0.02643197 0.05489599 0.204872 -0.03544795 0.05332899 0.199023 -0.04132097 0.10605 0.183683 -0.02643096 0.10605 0.183683 -0.03544795 0.103022 0.178439 -0.04132097 0.149977 0.149976 -0.02643096 0.149977 0.149976 -0.03544795 0.145696 0.145695 -0.04132097 0.183683 0.106049 -0.02643096 0.183683 0.106049 -0.03544795 0.17844 0.103022 -0.04131996 0.204872 0.05489498 -0.02643096 0.204872 0.05489498 -0.035447 0.199023 0.05332797 -0.04131996 0.243041 0 0.03539395 0.23476 -0.062904 0.03539395 2.97e-4 2.97e-4 0.03539395 0.21048 -0.12152 0.03539395 0.171856 -0.171856 0.03539395 0.12152 -0.21048 0.03539395 0.062904 -0.234759 0.03539395 0 -0.243041 0.03539395 -0.062904 -0.234759 0.03539395 -0.121521 -0.210479 0.03539395 -0.171856 -0.171856 0.03539395 -0.21048 -0.12152 0.03539395 -0.23476 -0.06290298 0.03539395 -0.243041 0 0.03539395 -0.23476 0.062904 0.03539395 -0.21048 0.121521 0.03539299 -0.171856 0.171856 0.03539299 -0.12152 0.21048 0.03539299 -0.06290298 0.23476 0.03539299 0 0.243041 0.03539299 0.062904 0.23476 0.03539299 0.121521 0.21048 0.03539299 0.171856 0.171856 0.03539299 0.21048 0.12152 0.03539299 0.23476 0.06290298 0.03539395 2.97e-4 2.96e-4 -0.03986597 0.199023 -0.05332797 -0.04131996 0.206044 0 -0.04131996 0.178439 -0.103022 -0.04131996 0.145695 -0.145695 -0.04131996 0.103022 -0.17844 -0.04131996 0.05332797 -0.199023 -0.04131996 0 -0.206044 -0.04131996 -0.05332797 -0.199023 -0.04131996 -0.103022 -0.178439 -0.04131996 -0.145695 -0.145695 -0.04131996 -0.17844 -0.103022 -0.04131996 -0.199023 -0.05332797 -0.04131996 -0.206044 0 -0.04131996 -0.199023 0.05332797 -0.04131996 -0.178439 0.103022 -0.04131996 -0.145695 0.145695 -0.04132097 -0.103022 0.178439 -0.04132097 -0.05332797 0.199023 -0.04132097 0 0.206044 -0.04132097 0.05332899 0.199023 -0.04132097 0.103022 0.178439 -0.04132097 0.145696 0.145695 -0.04132097 0.17844 0.103022 -0.04131996 0.199023 0.05332797 -0.04131996 + + + + + + + + + + 0.7044135 -0.09273242 0.7037061 0.7044572 -0.0927481 0.7036604 0.6564477 -0.2719146 0.7036612 0.656429 -0.2719017 0.7036833 0.5636811 -0.4325258 0.7036939 0.5636621 -0.4325034 0.7037228 0.7933454 -0.6087417 -0.006063044 0.7933436 -0.6087439 -0.006068825 0.6406349 -0.4915683 -0.5898708 0.6406487 -0.4915686 -0.5898555 0.4325081 -0.5636581 0.7037232 0.4325206 -0.5636845 0.7036943 0.6087417 -0.7933454 -0.006068825 0.6087537 -0.7933364 -0.006038904 0.4915824 -0.6406371 -0.5898566 0.4915702 -0.6406335 -0.5898705 0.2718967 -0.6564314 0.703683 0.2718921 -0.6564056 0.703709 0.3826764 -0.9238627 -0.006038129 0.3826749 -0.9238634 -0.006041288 0.3090159 -0.7460339 -0.5898666 0.3090071 -0.7460286 -0.589878 0.09274274 -0.7044069 0.7037114 0.09274226 -0.7044129 0.7037054 0.1305301 -0.9914259 -0.006039083 0.1305127 -0.9914281 -0.00607407 0.1053901 -0.8005865 -0.5898765 0.1053988 -0.8005957 -0.5898625 -0.09274351 -0.7044128 0.7037054 -0.09274148 -0.7044072 0.7037113 -0.1305301 -0.9914258 -0.006074011 -0.1305127 -0.9914282 -0.006039083 -0.1053913 -0.8005962 -0.589863 -0.1054081 -0.8005658 -0.5899014 -0.2718925 -0.6564055 0.703709 -0.2718913 -0.6564038 0.7037111 -0.3826764 -0.9238627 -0.006041288 -0.3826879 -0.9238578 -0.006066203 -0.3090174 -0.7460078 -0.5898989 -0.3090103 -0.7460366 -0.5898662 -0.4325186 -0.5636749 0.7037033 -0.4325034 -0.5636621 0.7037228 -0.6087417 -0.7933454 -0.006063044 -0.6087439 -0.7933436 -0.006068825 -0.5636581 -0.4325081 0.7037232 -0.5636845 -0.4325206 0.7036943 -0.6564289 -0.2719022 0.7036834 -0.6564038 -0.2718977 0.7037086 -0.7044088 -0.09273332 0.7037107 -0.7044135 -0.0927329 0.703706 0.9914258 -0.1305301 -0.006074011 0.9914282 -0.1305127 -0.006039083 0.8006089 -0.105393 -0.5898456 0.8005784 -0.1054098 -0.5898839 0.9238627 -0.3826764 -0.006041288 0.9238578 -0.3826879 -0.006066203 0.7460196 -0.3090223 -0.5898815 0.7460324 -0.3090191 -0.5898668 0.9914278 0.1305146 -0.00607407 0.9914276 0.130517 -0.006069481 0.9238631 0.3826747 -0.0060696 0.9238647 0.3826708 -0.006077826 0.7933361 0.6087535 -0.006081581 0.7933323 0.6087586 -0.006068825 0.6087536 0.7933362 -0.006068885 0.6087512 0.793338 -0.006063103 0.3826746 0.9238633 -0.006066203 0.3826763 0.9238625 -0.006069839 0.1305279 0.9914261 -0.006069719 0.1305301 0.9914258 -0.006074011 -0.1305146 0.9914278 -0.00607407 -0.130517 0.9914275 -0.006069302 -0.3826748 0.9238632 -0.006069421 -0.3826708 0.9238647 -0.006077826 -0.6087462 0.7933418 -0.006081581 -0.6087587 0.7933324 -0.006050348 -0.7933437 0.608744 -0.006044685 -0.793338 0.6087512 -0.006063103 -0.6406248 0.4915606 -0.5898882 -0.6406206 0.4915605 -0.5898928 -0.4915624 0.6406234 -0.5898883 -0.4915757 0.6406272 -0.589873 -0.3090136 0.7460284 -0.5898749 -0.309015 0.7460293 -0.589873 -0.1053913 0.800584 -0.5898796 -0.1053979 0.8005908 -0.5898691 0.1054031 0.8005904 -0.5898688 0.1053989 0.8005981 -0.5898591 0.3090176 0.7460386 -0.5898599 0.309021 0.746025 -0.5898753 0.4915751 0.6406277 -0.5898729 0.4915751 0.6406263 -0.5898743 0.6406269 0.4915745 -0.5898743 0.6406272 0.4915757 -0.589873 0.7460321 0.3090053 -0.5898743 0.7460387 0.3090162 -0.5898602 0.8005989 0.1053933 -0.5898593 0.800608 0.1054022 -0.589845 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 -1.43304e-5 -8.27352e-6 -1 1.79958e-5 -4.3445e-5 -1 6.13787e-6 -4.66224e-5 -1 6.13792e-6 -4.66225e-5 -1 -6.13865e-6 -4.66225e-5 -1 -6.13819e-6 -4.66246e-5 -1 -2.01314e-6 -4.773e-5 -1 0 0 -1 0 0 -1 -0.4915686 -0.6406487 -0.5898555 -0.4915683 -0.6406349 -0.5898708 0 0 -1 -0.640642 -0.4915766 -0.589856 -0.7933419 -0.6087462 -0.006057441 -0.7933454 -0.6087417 -0.006068825 -0.640642 -0.4915767 -0.589856 0 0 -1 0 0 -1 -0.9238594 -0.382684 -0.006049752 -0.923861 -0.3826803 -0.006057739 -0.7460382 -0.3090227 -0.5898578 -0.746037 -0.309021 -0.5898599 0 0 -1 0 0 -1 -0.9914275 -0.130517 -0.006065309 -0.9914281 -0.1305127 -0.00607407 -0.8005991 -0.1053918 -0.5898591 -0.8006082 -0.1054005 -0.5898451 0 0 -1 0 0 -1 0.991445 -0.1305251 0 0.991445 -0.1305251 0 0.6933302 -0.09127783 -0.7148159 0.6933116 -0.09127938 -0.7148337 0.9238802 -0.382682 0 0.9238802 -0.382682 0 0.6460677 -0.2676089 -0.71483 0.6460596 -0.2676073 -0.714838 0.7933566 -0.6087571 0 0.7933566 -0.6087571 0 0.5547822 -0.4256946 -0.7148432 0.5547721 -0.4256898 -0.7148538 0.6087484 -0.7933634 0 0.6087484 -0.7933634 0 0.4256822 -0.5547788 -0.7148532 0.4257559 -0.5548413 -0.7147608 0.3826884 -0.9238774 0 0.3826884 -0.9238774 0 0.2676398 -0.6461299 -0.7147622 0.2675992 -0.6460711 -0.7148307 0.1305251 -0.991445 0 0.1305251 -0.991445 0 0.09127551 -0.6933124 -0.7148333 0.09128177 -0.6933299 -0.7148156 -0.1305251 -0.991445 0 -0.1305251 -0.991445 0 -0.09127783 -0.6933302 -0.7148159 -0.09127938 -0.6933116 -0.7148337 -0.382682 -0.9238802 0 -0.382682 -0.9238802 0 -0.2676089 -0.6460677 -0.71483 -0.2676073 -0.6460596 -0.714838 -0.6087571 -0.7933566 0 -0.6087571 -0.7933566 0 -0.4256946 -0.5547822 -0.7148432 -0.4256898 -0.5547721 -0.7148538 -0.7933634 -0.6087484 0 -0.7933634 -0.6087484 0 -0.5547788 -0.4256822 -0.7148532 -0.5548413 -0.4257559 -0.7147608 -0.9238774 -0.3826884 0 -0.9238774 -0.3826884 0 -0.6461299 -0.2676398 -0.7147622 -0.6460711 -0.2675992 -0.7148307 -0.991445 -0.1305251 0 -0.991445 -0.1305251 0 -0.6933124 -0.09127551 -0.7148333 -0.6933299 -0.09128177 -0.7148156 -0.7044135 0.09273242 0.7037061 -0.7045052 0.09276527 0.7036101 -0.656492 0.2719404 0.7036097 -0.6564472 0.2719092 0.7036637 -0.5637019 0.4325504 0.703662 -0.5636884 0.4325345 0.7036827 -0.4325268 0.5636825 0.7036921 -0.4325087 0.5636439 0.7037341 -0.2718842 0.6563854 0.703731 -0.2718881 0.6564069 0.7037094 -0.09273326 0.7044087 0.7037108 -0.0927329 0.7044134 0.7037061 0.09273242 0.7044135 0.7037062 0.0927481 0.7044571 0.7036604 0.2719104 0.6564489 0.7036616 0.2719092 0.6564472 0.7036637 0.4325504 0.5637019 0.703662 0.4325345 0.5636884 0.7036827 0.5636825 0.4325268 0.7036921 0.5636439 0.4325087 0.7037341 0.6563805 0.2718942 0.7037317 0.6564537 0.2719075 0.7036583 0.7044589 0.09273988 0.7036597 0.7044128 0.09274369 0.7037053 -0.9914258 0.13053 -0.006074011 -0.9914261 0.1305279 -0.006069898 -0.8006078 0.1054054 -0.5898448 -0.8005957 0.105412 -0.5898599 0 0 -1 0 0 -1 -0.9238626 0.3826763 -0.006070017 -0.9238633 0.3826745 -0.006066203 -0.7460417 0.3090091 -0.5898604 -0.7460207 0.3090143 -0.5898842 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 -1.43305e-5 -8.27359e-6 -1 -1.75999e-5 -4.71635e-6 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 1.59833e-5 -4.28237e-6 -1 1.57797e-5 -9.11074e-6 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 -0.991445 0.1305251 0 -0.991445 0.1305251 0 -0.6933302 0.09127783 -0.7148159 -0.6933116 0.09127938 -0.7148337 -0.9238802 0.382682 0 -0.9238801 0.382682 0 -0.646072 0.2675966 -0.7148309 -0.6460034 0.2675842 -0.7148974 -0.793348 0.6087685 0 -0.793348 0.6087685 0 -0.5547285 0.425666 -0.714902 -0.5548183 0.4257085 -0.7148069 -0.6087572 0.7933567 0 -0.6087572 0.7933567 0 -0.42571 0.5548024 -0.7148184 -0.4257186 0.5548096 -0.7148077 -0.3826884 0.9238775 0 -0.3826884 0.9238775 0 -0.2676188 0.6460793 -0.7148159 -0.2676105 0.6460672 -0.7148299 -0.1305251 0.991445 0 -0.1305251 0.991445 0 -0.09127551 0.6933124 -0.7148333 -0.09128177 0.6933299 -0.7148156 0.1305227 0.9914453 0 0.1305227 0.9914453 0 0.09127622 0.6933302 -0.7148159 0.09127771 0.6933119 -0.7148335 0.3826885 0.9238775 0 0.3826885 0.9238775 0 0.2676135 0.6460661 -0.7148298 0.2676118 0.6460573 -0.7148383 0.6087685 0.793348 0 0.6087685 0.793348 0 0.4257029 0.5547767 -0.7148426 0.4257346 0.5548434 -0.7147718 0.7933567 0.6087572 0 0.7933567 0.6087572 0 0.5548398 0.4257388 -0.7147722 0.5548062 0.4256992 -0.7148218 0.9238775 0.3826884 0 0.9238774 0.3826884 0 0.6460795 0.2676051 -0.7148209 0.6460711 0.2675992 -0.7148307 0.991445 0.1305251 0 0.991445 0.1305251 0 0.6933124 0.09127551 -0.7148333 0.6933299 0.09128177 -0.7148156 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 4.10099e-6 1.53971e-5 1 -3.2986e-6 2.53114e-6 1 -2.53226e-6 3.30013e-6 1 -1.59255e-6 3.84476e-6 1 -5.43382e-7 4.12757e-6 1 5.43548e-7 4.1289e-6 1 1.59406e-6 3.84839e-6 1 2.5361e-6 3.30506e-6 1 3.30509e-6 2.53607e-6 1 -4.11028e-6 1.53932e-5 1 0 0 1 -0.007065355 9.30212e-4 -0.9999747 -0.006580829 0.002725839 -0.9999747 -0.005648195 0.004333972 -0.9999747 -0.004331707 0.005645096 -0.9999747 -0.002721488 0.006570518 -0.9999747 -9.2789e-4 0.007047772 -0.9999747 9.27538e-4 0.00704509 -0.9999747 0.002718567 0.006563186 -0.9999749 0.004324018 0.005635201 -0.9999747 0.005635082 0.004324078 -0.9999748 0.006563246 0.002718448 -0.9999748 0.00704503 9.27534e-4 -0.9999747 0.007047712 -9.27885e-4 -0.9999747 0.006570458 -0.002721548 -0.9999747 0.005635797 -0.00434786 -0.9999747 0.004336893 -0.00565201 -0.9999747 0.002727687 -0.006585299 -0.9999747 9.30845e-4 -0.007070183 -0.9999746 -9.31182e-4 -0.007072865 -0.9999746 -0.002730786 -0.006592631 -0.9999746 -0.004344522 -0.005662083 -0.9999746 -0.005648791 -0.004357814 -0.9999745 -0.00658816 -0.00272876 -0.9999745 -0.007068037 -9.30564e-4 -0.9999746 + + + + + + + + + + 0.497981 0.08877295 0.497935 0.07082295 0.543138 0.07082295 0.497981 0.08877295 0.543138 0.07082295 0.542671 0.08877295 0.543138 0.07082295 0.587414 0.07082295 0.542671 0.08877295 0.587414 0.07082295 0.586501 0.08877295 0.542671 0.08877295 0.587414 0.07082295 0.631396 0.07082295 0.586501 0.08877295 0.631396 0.07082295 0.629985 0.08877295 0.586501 0.08877295 0.586501 0.08877295 0.629985 0.08877295 0.583796 0.101898 0.629985 0.08877295 0.626102 0.101898 0.583796 0.101898 0.583796 0.101898 0.626102 0.101898 0.581227 0.113775 0.626102 0.101898 0.622231 0.113775 0.581227 0.113775 0.631396 0.07082295 0.675506 0.07082295 0.629985 0.08877295 0.675506 0.07082295 0.673603 0.08877295 0.629985 0.08877295 0.629985 0.08877295 0.673603 0.08877295 0.626102 0.101898 0.673603 0.08877295 0.668071 0.101898 0.626102 0.101898 0.626102 0.101898 0.668071 0.101898 0.622231 0.113775 0.668071 0.101898 0.662932 0.113775 0.622231 0.113775 0.675506 0.07082295 0.719293 0.07082295 0.673603 0.08877295 0.719293 0.07082295 0.716869 0.08877295 0.673603 0.08877295 0.673603 0.08877295 0.716869 0.08877295 0.668071 0.101898 0.716869 0.08877295 0.709731 0.101898 0.668071 0.101898 0.668071 0.101898 0.709731 0.101898 0.662932 0.113775 0.709731 0.101898 0.703263 0.113775 0.662932 0.113775 0.719293 0.07082295 0.762508 0.07082295 0.716869 0.08877295 0.762508 0.07082295 0.759456 0.08877295 0.716869 0.08877295 0.716869 0.08877295 0.759456 0.08877295 0.709731 0.101898 0.759456 0.08877295 0.750727 0.101898 0.709731 0.101898 0.709731 0.101898 0.750727 0.101898 0.703263 0.113775 0.750727 0.101898 0.742873 0.113775 0.703263 0.113775 0.762508 0.07082295 0.803989 0.07082295 0.759456 0.08877295 0.803989 0.07082295 0.800498 0.08877295 0.759456 0.08877295 0.759456 0.08877295 0.800498 0.08877295 0.750727 0.101898 0.800498 0.08877295 0.790296 0.101898 0.750727 0.101898 0.750727 0.101898 0.790296 0.101898 0.742873 0.113775 0.790296 0.101898 0.781143 0.113775 0.742873 0.113775 0.803989 0.07082295 0.843235 0.07082295 0.800498 0.08877295 0.843235 0.07082295 0.839306 0.08877295 0.800498 0.08877295 0.800498 0.08877295 0.839306 0.08877295 0.790296 0.101898 0.839306 0.08877295 0.827857 0.101898 0.790296 0.101898 0.790296 0.101898 0.827857 0.101898 0.781143 0.113775 0.827857 0.101898 0.817555 0.113775 0.781143 0.113775 0.843235 0.07082295 0.880223 0.07082295 0.839306 0.08877295 0.880223 0.07082295 0.875888 0.08877295 0.839306 0.08877295 0.839306 0.08877295 0.875888 0.08877295 0.827857 0.101898 0.875888 0.08877295 0.863285 0.101898 0.827857 0.101898 0.880223 0.07082295 0.914794 0.07082295 0.875888 0.08877295 0.914794 0.07082295 0.910102 0.08877295 0.875888 0.08877295 0.914794 0.07082295 0.94703 0.07082295 0.910102 0.08877295 0.94703 0.07082295 0.942129 0.08877295 0.910102 0.08877295 0.94703 0.07082295 0.979042 0.07082295 0.942129 0.08877295 0.979042 0.07082295 0.974419 0.08877295 0.942129 0.08877295 0.497981 0.08877295 0.542671 0.08877295 0.497931 0.101898 0.542671 0.08877295 0.541093 0.101898 0.497931 0.101898 0.497931 0.101898 0.541093 0.101898 0.498033 0.113775 0.541093 0.101898 0.539807 0.113775 0.498033 0.113775 0.542671 0.08877295 0.586501 0.08877295 0.541093 0.101898 0.586501 0.08877295 0.583796 0.101898 0.541093 0.101898 0.541093 0.101898 0.583796 0.101898 0.539807 0.113775 0.583796 0.101898 0.581227 0.113775 0.539807 0.113775 0.497981 0.08877295 0.497931 0.101898 0.454715 0.101898 0.453182 0.08877295 0.497981 0.08877295 0.454715 0.101898 0.453182 0.08877295 0.454715 0.101898 0.411786 0.101898 0.408822 0.08877295 0.453182 0.08877295 0.411786 0.101898 0.408822 0.08877295 0.411786 0.101898 0.369753 0.101898 0.365246 0.08877295 0.408822 0.08877295 0.369753 0.101898 0.365246 0.08877295 0.369753 0.101898 0.328558 0.101898 0.322708 0.08877295 0.365246 0.08877295 0.328558 0.101898 0.322708 0.08877295 0.328558 0.101898 0.288415 0.101898 0.281408 0.08877295 0.322708 0.08877295 0.288415 0.101898 0.281408 0.08877295 0.288415 0.101898 0.249914 0.101898 0.241666 0.08877295 0.281408 0.08877295 0.249914 0.101898 0.241666 0.08877295 0.249914 0.101898 0.212984 0.101898 0.2036049 0.08877295 0.241666 0.08877295 0.212984 0.101898 0.2036049 0.08877295 0.212984 0.101898 0.1773999 0.101898 0.166799 0.08877295 0.2036049 0.08877295 0.1773999 0.101898 0.166799 0.08877295 0.1773999 0.101898 0.143133 0.101898 0.131163 0.08877295 0.166799 0.08877295 0.143133 0.101898 0.131163 0.08877295 0.143133 0.101898 0.110489 0.101898 0.09727698 0.08877295 0.131163 0.08877295 0.110489 0.101898 0.110489 0.101898 0.143133 0.101898 0.122662 0.113775 0.143133 0.101898 0.154218 0.113775 0.122662 0.113775 0.143133 0.101898 0.1773999 0.101898 0.154218 0.113775 0.1773999 0.101898 0.187257 0.113775 0.154218 0.113775 0.1773999 0.101898 0.212984 0.101898 0.187257 0.113775 0.212984 0.101898 0.221674 0.113775 0.187257 0.113775 0.212984 0.101898 0.249914 0.101898 0.221674 0.113775 0.249914 0.101898 0.25753 0.113775 0.221674 0.113775 0.249914 0.101898 0.288415 0.101898 0.25753 0.113775 0.288415 0.101898 0.294852 0.113775 0.25753 0.113775 0.288415 0.101898 0.328558 0.101898 0.294852 0.113775 0.328558 0.101898 0.333843 0.113775 0.294852 0.113775 0.328558 0.101898 0.369753 0.101898 0.333843 0.113775 0.369753 0.101898 0.373768 0.113775 0.333843 0.113775 0.369753 0.101898 0.411786 0.101898 0.373768 0.113775 0.411786 0.101898 0.414559 0.113775 0.373768 0.113775 0.411786 0.101898 0.454715 0.101898 0.414559 0.113775 0.454715 0.101898 0.456228 0.113775 0.414559 0.113775 0.454715 0.101898 0.497931 0.101898 0.456228 0.113775 0.497931 0.101898 0.498033 0.113775 0.456228 0.113775 0.498033 0.113775 0.539807 0.113775 0.498193 0.1297259 0.539807 0.113775 0.53888 0.1297259 0.498193 0.1297259 0.539807 0.113775 0.581227 0.113775 0.53888 0.1297259 0.581227 0.113775 0.579117 0.1297259 0.53888 0.1297259 0.581227 0.113775 0.622231 0.113775 0.579117 0.1297259 0.622231 0.113775 0.618878 0.1297259 0.579117 0.1297259 0.622231 0.113775 0.662932 0.113775 0.618878 0.1297259 0.662932 0.113775 0.658384 0.1297259 0.618878 0.1297259 0.662932 0.113775 0.703263 0.113775 0.658384 0.1297259 0.703263 0.113775 0.697492 0.1297259 0.658384 0.1297259 0.703263 0.113775 0.742873 0.113775 0.697492 0.1297259 0.742873 0.113775 0.735859 0.1297259 0.697492 0.1297259 0.742873 0.113775 0.781143 0.113775 0.735859 0.1297259 0.781143 0.113775 0.772949 0.1297259 0.735859 0.1297259 0.781143 0.113775 0.817555 0.113775 0.772949 0.1297259 0.817555 0.113775 0.808293 0.1297259 0.772949 0.1297259 0.817555 0.113775 0.851912 0.113775 0.808293 0.1297259 0.863285 0.101898 0.851912 0.113775 0.817555 0.113775 0.827857 0.101898 0.863285 0.101898 0.817555 0.113775 0.851912 0.113775 0.841643 0.1297259 0.808293 0.1297259 0.863285 0.101898 0.896463 0.101898 0.851912 0.113775 0.910102 0.08877295 0.896463 0.101898 0.863285 0.101898 0.875888 0.08877295 0.910102 0.08877295 0.863285 0.101898 0.896463 0.101898 0.884073 0.113775 0.851912 0.113775 0.851912 0.113775 0.884073 0.113775 0.841643 0.1297259 0.884073 0.113775 0.872809 0.1297259 0.841643 0.1297259 0.910102 0.08877295 0.942129 0.08877295 0.896463 0.101898 0.942129 0.08877295 0.927625 0.101898 0.896463 0.101898 0.896463 0.101898 0.927625 0.101898 0.884073 0.113775 0.927625 0.101898 0.914106 0.113775 0.884073 0.113775 0.884073 0.113775 0.914106 0.113775 0.872809 0.1297259 0.914106 0.113775 0.901486 0.1297259 0.872809 0.1297259 0.942129 0.08877295 0.974419 0.08877295 0.927625 0.101898 0.974419 0.08877295 0.958449 0.101898 0.927625 0.101898 0.927625 0.101898 0.958449 0.101898 0.914106 0.113775 0.958449 0.101898 0.942298 0.113775 0.914106 0.113775 0.914106 0.113775 0.942298 0.113775 0.901486 0.1297259 0.942298 0.113775 0.927269 0.1297259 0.901486 0.1297259 0.498193 0.1297259 0.53888 0.1297259 0.498246 0.140136 0.53888 0.1297259 0.538478 0.140136 0.498246 0.140136 0.498246 0.140136 0.538478 0.140136 0.498315 0.152971 0.538478 0.140136 0.538046 0.152971 0.498315 0.152971 0.53888 0.1297259 0.579117 0.1297259 0.538478 0.140136 0.579117 0.1297259 0.578292 0.140136 0.538478 0.140136 0.538478 0.140136 0.578292 0.140136 0.538046 0.152971 0.578292 0.140136 0.577423 0.152971 0.538046 0.152971 0.579117 0.1297259 0.618878 0.1297259 0.578292 0.140136 0.618878 0.1297259 0.617612 0.140136 0.578292 0.140136 0.578292 0.140136 0.617612 0.140136 0.577423 0.152971 0.617612 0.140136 0.616245 0.152971 0.577423 0.152971 0.618878 0.1297259 0.658384 0.1297259 0.617612 0.140136 0.658384 0.1297259 0.656693 0.140136 0.617612 0.140136 0.617612 0.140136 0.656693 0.140136 0.616245 0.152971 0.656693 0.140136 0.654864 0.152971 0.616245 0.152971 0.658384 0.1297259 0.697492 0.1297259 0.656693 0.140136 0.697492 0.1297259 0.69538 0.140136 0.656693 0.140136 0.656693 0.140136 0.69538 0.140136 0.654864 0.152971 0.69538 0.140136 0.693096 0.152971 0.654864 0.152971 0.697492 0.1297259 0.735859 0.1297259 0.69538 0.140136 0.735859 0.1297259 0.733325 0.140136 0.69538 0.140136 0.69538 0.140136 0.733325 0.140136 0.693096 0.152971 0.733325 0.140136 0.730592 0.152971 0.693096 0.152971 0.735859 0.1297259 0.772949 0.1297259 0.733325 0.140136 0.772949 0.1297259 0.770015 0.140136 0.733325 0.140136 0.733325 0.140136 0.770015 0.140136 0.730592 0.152971 0.770015 0.140136 0.766855 0.152971 0.730592 0.152971 0.772949 0.1297259 0.808293 0.1297259 0.770015 0.140136 0.808293 0.1297259 0.804989 0.140136 0.770015 0.140136 0.770015 0.140136 0.804989 0.140136 0.766855 0.152971 0.804989 0.140136 0.801428 0.152971 0.766855 0.152971 0.808293 0.1297259 0.841643 0.1297259 0.804989 0.140136 0.841643 0.1297259 0.837988 0.140136 0.804989 0.140136 0.804989 0.140136 0.837988 0.140136 0.801428 0.152971 0.837988 0.140136 0.834047 0.152971 0.801428 0.152971 0.841643 0.1297259 0.872809 0.1297259 0.837988 0.140136 0.872809 0.1297259 0.868808 0.140136 0.837988 0.140136 0.837988 0.140136 0.868808 0.140136 0.834047 0.152971 0.868808 0.140136 0.864493 0.152971 0.834047 0.152971 0.872809 0.1297259 0.901486 0.1297259 0.868808 0.140136 0.901486 0.1297259 0.897175 0.140136 0.868808 0.140136 0.868808 0.140136 0.897175 0.140136 0.864493 0.152971 0.897175 0.140136 0.892456 0.152971 0.864493 0.152971 0.901486 0.1297259 0.927269 0.1297259 0.897175 0.140136 0.927269 0.1297259 0.922834 0.140136 0.897175 0.140136 0.897175 0.140136 0.922834 0.140136 0.892456 0.152971 0.922834 0.140136 0.917439 0.152971 0.892456 0.152971 0.028638 0.07082295 0.06044697 0.07082295 0.03358 0.08877295 0.06044697 0.07082295 0.06551897 0.08877295 0.03358 0.08877295 0.06044697 0.07082295 0.09260195 0.07082295 0.06551897 0.08877295 0.09260195 0.07082295 0.09727698 0.08877295 0.06551897 0.08877295 0.09260195 0.07082295 0.126944 0.07082295 0.09727698 0.08877295 0.126944 0.07082295 0.131163 0.08877295 0.09727698 0.08877295 0.126944 0.07082295 0.163057 0.07082295 0.131163 0.08877295 0.163057 0.07082295 0.166799 0.08877295 0.131163 0.08877295 0.163057 0.07082295 0.200381 0.07082295 0.166799 0.08877295 0.200381 0.07082295 0.2036049 0.08877295 0.166799 0.08877295 0.200381 0.07082295 0.238752 0.07082295 0.2036049 0.08877295 0.238752 0.07082295 0.241666 0.08877295 0.2036049 0.08877295 0.238752 0.07082295 0.278904 0.07082295 0.241666 0.08877295 0.278904 0.07082295 0.281408 0.08877295 0.241666 0.08877295 0.278904 0.07082295 0.32068 0.07082295 0.281408 0.08877295 0.32068 0.07082295 0.322708 0.08877295 0.281408 0.08877295 0.32068 0.07082295 0.36368 0.07082295 0.322708 0.08877295 0.36368 0.07082295 0.365246 0.08877295 0.322708 0.08877295 0.36368 0.07082295 0.407726 0.07082295 0.365246 0.08877295 0.407726 0.07082295 0.408822 0.08877295 0.365246 0.08877295 0.407726 0.07082295 0.452605 0.07082295 0.408822 0.08877295 0.452605 0.07082295 0.453182 0.08877295 0.408822 0.08877295 0.452605 0.07082295 0.497935 0.07082295 0.453182 0.08877295 0.497935 0.07082295 0.497981 0.08877295 0.453182 0.08877295 0.03358 0.08877295 0.06551897 0.08877295 0.05011695 0.101898 0.06551897 0.08877295 0.07987499 0.101898 0.05011695 0.101898 0.05011695 0.101898 0.07987499 0.101898 0.06625896 0.113775 0.07987499 0.101898 0.09322595 0.113775 0.06625896 0.113775 0.06625896 0.113775 0.09322595 0.113775 0.080531 0.1297259 0.09322595 0.113775 0.10576 0.1297259 0.080531 0.1297259 0.06551897 0.08877295 0.09727698 0.08877295 0.07987499 0.101898 0.09727698 0.08877295 0.110489 0.101898 0.07987499 0.101898 0.07987499 0.101898 0.110489 0.101898 0.09322595 0.113775 0.110489 0.101898 0.122662 0.113775 0.09322595 0.113775 0.09322595 0.113775 0.122662 0.113775 0.10576 0.1297259 0.122662 0.113775 0.134295 0.1297259 0.10576 0.1297259 0.122662 0.113775 0.154218 0.113775 0.134295 0.1297259 0.154218 0.113775 0.16442 0.1297259 0.134295 0.1297259 0.154218 0.113775 0.187257 0.113775 0.16442 0.1297259 0.187257 0.113775 0.196301 0.1297259 0.16442 0.1297259 0.187257 0.113775 0.221674 0.113775 0.196301 0.1297259 0.221674 0.113775 0.229607 0.1297259 0.196301 0.1297259 0.221674 0.113775 0.25753 0.113775 0.229607 0.1297259 0.25753 0.113775 0.264349 0.1297259 0.229607 0.1297259 0.25753 0.113775 0.294852 0.113775 0.264349 0.1297259 0.294852 0.113775 0.300955 0.1297259 0.264349 0.1297259 0.294852 0.113775 0.333843 0.113775 0.300955 0.1297259 0.333843 0.113775 0.338598 0.1297259 0.300955 0.1297259 0.333843 0.113775 0.373768 0.113775 0.338598 0.1297259 0.373768 0.113775 0.37738 0.1297259 0.338598 0.1297259 0.373768 0.113775 0.414559 0.113775 0.37738 0.1297259 0.414559 0.113775 0.417199 0.1297259 0.37738 0.1297259 0.414559 0.113775 0.456228 0.113775 0.417199 0.1297259 0.456228 0.113775 0.457525 0.1297259 0.417199 0.1297259 0.456228 0.113775 0.498033 0.113775 0.457525 0.1297259 0.498033 0.113775 0.498193 0.1297259 0.457525 0.1297259 0.080531 0.1297259 0.10576 0.1297259 0.08523398 0.140136 0.10576 0.1297259 0.110186 0.140136 0.08523398 0.140136 0.08523398 0.140136 0.110186 0.140136 0.09042799 0.152971 0.110186 0.140136 0.114798 0.152971 0.09042799 0.152971 0.10576 0.1297259 0.134295 0.1297259 0.110186 0.140136 0.134295 0.1297259 0.138254 0.140136 0.110186 0.140136 0.110186 0.140136 0.138254 0.140136 0.114798 0.152971 0.138254 0.140136 0.142554 0.152971 0.114798 0.152971 0.134295 0.1297259 0.16442 0.1297259 0.138254 0.140136 0.16442 0.1297259 0.168044 0.140136 0.138254 0.140136 0.138254 0.140136 0.168044 0.140136 0.142554 0.152971 0.168044 0.140136 0.17198 0.152971 0.142554 0.152971 0.16442 0.1297259 0.196301 0.1297259 0.168044 0.140136 0.196301 0.1297259 0.19953 0.140136 0.168044 0.140136 0.168044 0.140136 0.19953 0.140136 0.17198 0.152971 0.19953 0.140136 0.20304 0.152971 0.17198 0.152971 0.196301 0.1297259 0.229607 0.1297259 0.19953 0.140136 0.229607 0.1297259 0.23245 0.140136 0.19953 0.140136 0.19953 0.140136 0.23245 0.140136 0.20304 0.152971 0.23245 0.140136 0.2355369 0.152971 0.20304 0.152971 0.229607 0.1297259 0.264349 0.1297259 0.23245 0.140136 0.264349 0.1297259 0.266794 0.140136 0.23245 0.140136 0.23245 0.140136 0.266794 0.140136 0.2355369 0.152971 0.266794 0.140136 0.269436 0.152971 0.2355369 0.152971 0.264349 0.1297259 0.300955 0.1297259 0.266794 0.140136 0.300955 0.1297259 0.303016 0.140136 0.266794 0.140136 0.266794 0.140136 0.303016 0.140136 0.269436 0.152971 0.303016 0.140136 0.305259 0.152971 0.269436 0.152971 0.300955 0.1297259 0.338598 0.1297259 0.303016 0.140136 0.338598 0.1297259 0.340322 0.140136 0.303016 0.140136 0.303016 0.140136 0.340322 0.140136 0.305259 0.152971 0.340322 0.140136 0.342198 0.152971 0.305259 0.152971 0.338598 0.1297259 0.37738 0.1297259 0.340322 0.140136 0.37738 0.1297259 0.378667 0.140136 0.340322 0.140136 0.340322 0.140136 0.378667 0.140136 0.342198 0.152971 0.378667 0.140136 0.380062 0.152971 0.342198 0.152971 0.37738 0.1297259 0.417199 0.1297259 0.378667 0.140136 0.417199 0.1297259 0.418079 0.140136 0.378667 0.140136 0.378667 0.140136 0.418079 0.140136 0.380062 0.152971 0.418079 0.140136 0.419045 0.152971 0.380062 0.152971 0.417199 0.1297259 0.457525 0.1297259 0.418079 0.140136 0.457525 0.1297259 0.458044 0.140136 0.418079 0.140136 0.418079 0.140136 0.458044 0.140136 0.419045 0.152971 0.458044 0.140136 0.458621 0.152971 0.419045 0.152971 0.457525 0.1297259 0.498193 0.1297259 0.458044 0.140136 0.498193 0.1297259 0.498246 0.140136 0.458044 0.140136 0.458044 0.140136 0.498246 0.140136 0.458621 0.152971 0.498246 0.140136 0.498315 0.152971 0.458621 0.152971 0.263502 0.732761 0.23444 0.956097 0.1776 0.940866 0.263502 0.732761 0.293284 0.956097 0.23444 0.956097 0.263502 0.732761 0.350124 0.940866 0.293284 0.956097 0.263502 0.732761 0.401085 0.911444 0.350124 0.940866 0.263502 0.732761 0.442694 0.869835 0.401085 0.911444 0.263502 0.732761 0.472116 0.818874 0.442694 0.869835 0.263502 0.732761 0.487347 0.762034 0.472116 0.818874 0.263502 0.732761 0.487347 0.703189 0.487347 0.762034 0.263502 0.732761 0.472116 0.64635 0.487347 0.703189 0.263502 0.732761 0.442694 0.595389 0.472116 0.64635 0.263502 0.732761 0.401085 0.553779 0.442694 0.595389 0.263502 0.732761 0.350124 0.524357 0.401085 0.553779 0.263502 0.732761 0.293284 0.509127 0.350124 0.524357 0.263502 0.732761 0.234439 0.509127 0.293284 0.509127 0.263502 0.732761 0.1776 0.524357 0.234439 0.509127 0.263502 0.732761 0.126639 0.55378 0.1776 0.524357 0.263502 0.732761 0.085029 0.595389 0.126639 0.55378 0.263502 0.732761 0.05560696 0.64635 0.085029 0.595389 0.263502 0.732761 0.04037696 0.70319 0.05560696 0.64635 0.263502 0.732761 0.04037696 0.762035 0.04037696 0.70319 0.263502 0.732761 0.05560696 0.818874 0.04037696 0.762035 0.263502 0.732761 0.08502995 0.869835 0.05560696 0.818874 0.263502 0.732761 0.126639 0.911444 0.08502995 0.869835 0.263502 0.732761 0.1776 0.940866 0.126639 0.911444 0.556957 0.497392 0.556957 0.447505 0.746185 0.472757 0.556957 0.447505 0.569869 0.399317 0.746185 0.472757 0.569869 0.399317 0.594812 0.356114 0.746185 0.472757 0.594812 0.356114 0.630088 0.320839 0.746185 0.472757 0.630088 0.320839 0.673291 0.295895 0.746185 0.472757 0.673291 0.295895 0.721478 0.282983 0.746185 0.472757 0.721478 0.282983 0.771365 0.282983 0.746185 0.472757 0.771365 0.282983 0.819552 0.295895 0.746185 0.472757 0.819552 0.295895 0.862756 0.320838 0.746185 0.472757 0.862756 0.320838 0.898031 0.356114 0.746185 0.472757 0.898031 0.356114 0.922975 0.399317 0.746185 0.472757 0.922975 0.399317 0.935887 0.447505 0.746185 0.472757 0.935887 0.447505 0.935887 0.497392 0.746185 0.472757 0.935887 0.497392 0.922975 0.545579 0.746185 0.472757 0.922975 0.545579 0.898031 0.588782 0.746185 0.472757 0.898031 0.588782 0.862756 0.624058 0.746185 0.472757 0.862756 0.624058 0.819552 0.649001 0.746185 0.472757 0.819552 0.649001 0.771365 0.661913 0.746185 0.472757 0.771365 0.661913 0.721478 0.661913 0.746185 0.472757 0.721478 0.661913 0.673291 0.649001 0.746185 0.472757 0.673291 0.649001 0.630087 0.624058 0.746185 0.472757 0.630087 0.624058 0.594812 0.588782 0.746185 0.472757 0.594812 0.588782 0.569868 0.545579 0.746185 0.472757 0.569868 0.545579 0.556957 0.497392 0.746185 0.472757 + + + + + + + + + 0.2350667 0.5944423 0.236442 0.5852586 0.1800367 0.5688781 0.2350667 0.5944423 0.1800367 0.5688781 0.1761345 0.5773187 0.1800367 0.5688781 0.1311475 0.5370425 0.1761345 0.5773187 0.1311475 0.5370425 0.1245415 0.5436798 0.1761345 0.5773187 0.1311475 0.5370425 0.09787863 0.4901666 0.1245415 0.5436798 0.09787863 0.4901666 0.09049338 0.4943432 0.1245415 0.5436798 0.1245415 0.5436798 0.09049338 0.4943432 0.09589761 0.5627111 0.09049338 0.4943432 0.0641511 0.5072736 0.09589761 0.5627111 0.09589761 0.5627111 0.0641511 0.5072736 0.06957656 0.5749213 0.0641511 0.5072736 0.03961127 0.5188692 0.06957656 0.5749213 0.09787863 0.4901666 0.07653158 0.442074 0.09049338 0.4943432 0.07653158 0.442074 0.06883269 0.4446325 0.09049338 0.4943432 0.09049338 0.4943432 0.06883269 0.4446325 0.0641511 0.5072736 0.06883269 0.4446325 0.0417397 0.4527056 0.0641511 0.5072736 0.0641511 0.5072736 0.0417397 0.4527056 0.03961127 0.5188692 0.0417397 0.4527056 0.01629096 0.460441 0.03961127 0.5188692 0.07653158 0.442074 0.06556189 0.3927496 0.06883269 0.4446325 0.06556189 0.3927496 0.05767703 0.3936865 0.06883269 0.4446325 0.06883269 0.4446325 0.05767703 0.3936865 0.0417397 0.4527056 0.05767703 0.3936865 0.0300439 0.3963494 0.0417397 0.4527056 0.0417397 0.4527056 0.0300439 0.3963494 0.01629096 0.460441 0.0300439 0.3963494 0.00390625 0.3991305 0.01629096 0.460441 0.06556189 0.3927496 0.06497049 0.3430217 0.05767703 0.3936865 0.06497049 0.3430217 0.05707472 0.3423448 0.05767703 0.3936865 0.05767703 0.3936865 0.05707472 0.3423448 0.0300439 0.3963494 0.05707472 0.3423448 0.02971023 0.3395568 0.0300439 0.3963494 0.0300439 0.3963494 0.02971023 0.3395568 0.00390625 0.3991305 0.02971023 0.3395568 0.00390625 0.3372796 0.00390625 0.3991305 0.06497049 0.3430217 0.07437455 0.2938694 0.05707472 0.3423448 0.07437455 0.2938694 0.06659692 0.2915712 0.05707472 0.3423448 0.05707472 0.3423448 0.06659692 0.2915712 0.02971023 0.3395568 0.06659692 0.2915712 0.03990733 0.2838791 0.02971023 0.3395568 0.02971023 0.3395568 0.03990733 0.2838791 0.00390625 0.3372796 0.03990733 0.2838791 0.01529473 0.2776388 0.00390625 0.3372796 0.07437455 0.2938694 0.09369289 0.245186 0.06659692 0.2915712 0.09369289 0.245186 0.08613568 0.2410319 0.06659692 0.2915712 0.06659692 0.2915712 0.08613568 0.2410319 0.03990733 0.2838791 0.08613568 0.2410319 0.05916076 0.2271876 0.03990733 0.2838791 0.03990733 0.2838791 0.05916076 0.2271876 0.01529473 0.2776388 0.05916076 0.2271876 0.03322398 0.221123 0.01529473 0.2776388 0.09369289 0.245186 0.1262683 0.1996575 0.08613568 0.2410319 0.1262683 0.1996575 0.1197991 0.1930412 0.08613568 0.2410319 0.08613568 0.2410319 0.1197991 0.1930412 0.05916076 0.2271876 0.1197991 0.1930412 0.09383791 0.1756151 0.05916076 0.2271876 0.1262683 0.1996575 0.1738846 0.1667155 0.1197991 0.1930412 0.1738846 0.1667155 0.1698107 0.1584594 0.1197991 0.1930412 0.1738846 0.1667155 0.2292709 0.1485136 0.1698107 0.1584594 0.2292709 0.1485136 0.2276279 0.1394425 0.1698107 0.1584594 0.2292709 0.1485136 0.2876806 0.1458148 0.2276279 0.1394425 0.2876806 0.1458148 0.2885111 0.1366223 0.2276279 0.1394425 0.5831499 0.09723418 0.6392333 0.07750499 0.5745477 0.06898558 0.6392333 0.07750499 0.6284694 0.04977446 0.5745477 0.06898558 0.5745477 0.06898558 0.6284694 0.04977446 0.5672938 0.04553133 0.6284694 0.04977446 0.6193705 0.02707022 0.5672938 0.04553133 0.6392333 0.07750499 0.6943629 0.05367654 0.6284694 0.04977446 0.6943629 0.05367654 0.6819697 0.0257048 0.6284694 0.04977446 0.6284694 0.04977446 0.6819697 0.0257048 0.6193705 0.02707022 0.6819697 0.0257048 0.6698388 0.00390625 0.6193705 0.02707022 0.5831499 0.09723418 0.5745477 0.06898558 0.5193687 0.08390897 0.525815 0.1127023 0.5831499 0.09723418 0.5193687 0.08390897 0.525815 0.1127023 0.5193687 0.08390897 0.4632171 0.0946123 0.4674758 0.1238127 0.525815 0.1127023 0.4632171 0.0946123 0.4674758 0.1238127 0.4632171 0.0946123 0.4064087 0.1010535 0.4084558 0.1304971 0.4674758 0.1238127 0.4064087 0.1010535 0.4084558 0.1304971 0.4064087 0.1010535 0.3492653 0.1031962 0.3490877 0.1327161 0.4084558 0.1304971 0.3492653 0.1031962 0.3490877 0.1327161 0.3492653 0.1031962 0.2921115 0.1010265 0.2897101 0.130455 0.3490877 0.1327161 0.2921115 0.1010265 0.2897101 0.130455 0.2921115 0.1010265 0.2352721 0.09455591 0.2306596 0.1237252 0.2897101 0.130455 0.2352721 0.09455591 0.2306596 0.1237252 0.2352721 0.09455591 0.1790698 0.08382123 0.1722739 0.112564 0.2306596 0.1237252 0.1790698 0.08382123 0.1722739 0.112564 0.1790698 0.08382123 0.1238058 0.06889402 0.114885 0.09703874 0.1722739 0.112564 0.1238058 0.06889402 0.114885 0.09703874 0.1238058 0.06889402 0.0696392 0.04993075 0.05882787 0.07730001 0.114885 0.09703874 0.0696392 0.04993075 0.05882787 0.07730001 0.0696392 0.04993075 0.01560503 0.0264728 0.00390625 0.05407291 0.05882787 0.07730001 0.01560503 0.0264728 0.01560503 0.0264728 0.0696392 0.04993075 0.02767962 0.00390625 0.0696392 0.04993075 0.07888078 0.02687853 0.02767962 0.00390625 0.0696392 0.04993075 0.1238058 0.06889402 0.07888078 0.02687853 0.1238058 0.06889402 0.1311852 0.0453937 0.07888078 0.02687853 0.1238058 0.06889402 0.1790698 0.08382123 0.1311852 0.0453937 0.1790698 0.08382123 0.1846489 0.05986011 0.1311852 0.0453937 0.1790698 0.08382123 0.2352721 0.09455591 0.1846489 0.05986011 0.2352721 0.09455591 0.2390297 0.07025092 0.1846489 0.05986011 0.2352721 0.09455591 0.2921115 0.1010265 0.2390297 0.07025092 0.2921115 0.1010265 0.2940266 0.07651305 0.2390297 0.07025092 0.2921115 0.1010265 0.3492653 0.1031962 0.2940266 0.07651305 0.3492653 0.1031962 0.3493282 0.07861375 0.2940266 0.07651305 0.3492653 0.1031962 0.4064087 0.1010535 0.3493282 0.07861375 0.4064087 0.1010535 0.4046192 0.076541 0.3493282 0.07861375 0.4064087 0.1010535 0.4632171 0.0946123 0.4046192 0.076541 0.4632171 0.0946123 0.459586 0.07030946 0.4046192 0.076541 0.4632171 0.0946123 0.5193687 0.08390897 0.459586 0.07030946 0.5193687 0.08390897 0.5139161 0.05995464 0.459586 0.07030946 0.5193687 0.08390897 0.5745477 0.06898558 0.5139161 0.05995464 0.5745477 0.06898558 0.5672938 0.04553133 0.5139161 0.05995464 0.9582458 0.3222229 0.9390272 0.2623018 0.9364184 0.3260506 0.9390272 0.2623018 0.9192036 0.2717746 0.9364184 0.3260506 0.9390272 0.2623018 0.9047072 0.2103503 0.9192036 0.2717746 0.9047072 0.2103503 0.8884084 0.2246392 0.9192036 0.2717746 0.9047072 0.2103503 0.8582402 0.1703261 0.8884084 0.2246392 0.8582402 0.1703261 0.846688 0.1882102 0.8884084 0.2246392 0.8582402 0.1703261 0.8035733 0.1451821 0.846688 0.1882102 0.8035733 0.1451821 0.7975903 0.165144 0.846688 0.1882102 0.8035733 0.1451821 0.7453272 0.1366223 0.7975903 0.165144 0.7453272 0.1366223 0.7452702 0.1569747 0.7975903 0.165144 0.7453272 0.1366223 0.6884095 0.1449695 0.7452702 0.1569747 0.6884095 0.1449695 0.6941417 0.1639945 0.7452702 0.1569747 0.6884095 0.1449695 0.6376188 0.1691383 0.6941417 0.1639945 0.6376188 0.1691383 0.6485199 0.1852265 0.6941417 0.1639945 0.6376188 0.1691383 0.5972502 0.206721 0.6485199 0.1852265 0.5972502 0.206721 0.6122664 0.2185064 0.6485199 0.1852265 0.5972502 0.206721 0.5716609 0.2529014 0.6122664 0.2185064 0.549771 0.2438524 0.5716609 0.2529014 0.5972502 0.206721 0.5771115 0.1936393 0.549771 0.2438524 0.5972502 0.206721 0.5716609 0.2529014 0.5885241 0.2601137 0.6122664 0.2185064 0.549771 0.2438524 0.5352486 0.2963944 0.5716609 0.2529014 0.5085309 0.2908549 0.5352486 0.2963944 0.549771 0.2438524 0.5225851 0.2367655 0.5085309 0.2908549 0.549771 0.2438524 0.5352486 0.2963944 0.5572178 0.301274 0.5716609 0.2529014 0.5716609 0.2529014 0.5572178 0.301274 0.5885241 0.2601137 0.5572178 0.301274 0.5746446 0.3051185 0.5885241 0.2601137 0.5085309 0.2908549 0.5007624 0.3462888 0.5352486 0.2963944 0.5007624 0.3462888 0.5281035 0.3483402 0.5352486 0.2963944 0.5352486 0.2963944 0.5281035 0.3483402 0.5572178 0.301274 0.5281035 0.3483402 0.5503051 0.3500352 0.5572178 0.301274 0.5572178 0.301274 0.5503051 0.3500352 0.5746446 0.3051185 0.5503051 0.3500352 0.567955 0.3512266 0.5746446 0.3051185 0.5007624 0.3462888 0.5007624 0.4023982 0.5281035 0.3483402 0.5007624 0.4023982 0.5282323 0.4006037 0.5281035 0.3483402 0.5281035 0.3483402 0.5282323 0.4006037 0.5503051 0.3500352 0.5282323 0.4006037 0.5504519 0.3990953 0.5503051 0.3500352 0.5503051 0.3500352 0.5504519 0.3990953 0.567955 0.3512266 0.5504519 0.3990953 0.5680606 0.3976911 0.567955 0.3512266 0.00390625 0.7716867 0.003906309 0.8240724 0.01235991 0.7728291 0.003906309 0.8240724 0.0123676 0.8229879 0.01235991 0.7728291 0.01235991 0.7728291 0.0123676 0.8229879 0.02005803 0.7738682 0.0123676 0.8229879 0.02007251 0.8219993 0.02005803 0.7738682 0.003906309 0.8240724 0.01746517 0.8746736 0.0123676 0.8229879 0.01746517 0.8746736 0.02535736 0.8714362 0.0123676 0.8229879 0.0123676 0.8229879 0.02535736 0.8714362 0.02007251 0.8219993 0.02535736 0.8714362 0.03254371 0.8684865 0.02007251 0.8219993 0.01746517 0.8746736 0.04365783 0.9200402 0.02535736 0.8714362 0.04365783 0.9200402 0.05044317 0.9148704 0.02535736 0.8714362 0.02535736 0.8714362 0.05044317 0.9148704 0.03254371 0.8684865 0.05044317 0.9148704 0.05662149 0.9101615 0.03254371 0.8684865 0.04365783 0.9200402 0.08070057 0.9570817 0.05044317 0.9148704 0.08070057 0.9570817 0.08591663 0.9503319 0.05044317 0.9148704 0.05044317 0.9148704 0.08591663 0.9503319 0.05662149 0.9101615 0.08591663 0.9503319 0.09066498 0.9441852 0.05662149 0.9101615 0.08070057 0.9570817 0.1260671 0.9832739 0.08591663 0.9503319 0.1260671 0.9832739 0.1293585 0.9754042 0.08591663 0.9503319 0.08591663 0.9503319 0.1293585 0.9754042 0.09066498 0.9441852 0.1293585 0.9754042 0.1323543 0.9682372 0.09066498 0.9441852 0.1260671 0.9832739 0.1766665 0.9968319 0.1293585 0.9754042 0.1766665 0.9968319 0.177809 0.9883784 0.1293585 0.9754042 0.1293585 0.9754042 0.177809 0.9883784 0.1323543 0.9682372 0.177809 0.9883784 0.1788479 0.9806805 0.1323543 0.9682372 0.1766665 0.9968319 0.2290507 0.9968319 0.177809 0.9883784 0.2290507 0.9968319 0.2279663 0.9883708 0.177809 0.9883784 0.177809 0.9883784 0.2279663 0.9883708 0.1788479 0.9806805 0.2279663 0.9883708 0.2269777 0.9806662 0.1788479 0.9806805 0.2290507 0.9968319 0.2796507 0.983274 0.2279663 0.9883708 0.2796507 0.983274 0.2764135 0.975382 0.2279663 0.9883708 0.2279663 0.9883708 0.2764135 0.975382 0.2269777 0.9806662 0.2764135 0.975382 0.273464 0.9681957 0.2269777 0.9806662 0.2796507 0.983274 0.3250167 0.9570827 0.2764135 0.975382 0.3250167 0.9570827 0.3198472 0.9502974 0.2764135 0.975382 0.2764135 0.975382 0.3198472 0.9502974 0.273464 0.9681957 0.3198472 0.9502974 0.3151385 0.9441192 0.273464 0.9681957 0.3250167 0.9570827 0.3620584 0.9200416 0.3198472 0.9502974 0.3620584 0.9200416 0.3553088 0.9148254 0.3198472 0.9502974 0.3198472 0.9502974 0.3553088 0.9148254 0.3151385 0.9441192 0.3553088 0.9148254 0.3491623 0.910077 0.3151385 0.9441192 0.3620584 0.9200416 0.3882515 0.8746762 0.3553088 0.9148254 0.3882515 0.8746762 0.380382 0.8713846 0.3553088 0.9148254 0.3553088 0.9148254 0.380382 0.8713846 0.3491623 0.910077 0.380382 0.8713846 0.3732151 0.8683887 0.3491623 0.910077 0.3882515 0.8746762 0.4018109 0.8240774 0.380382 0.8713846 0.4018109 0.8240774 0.3933575 0.8229348 0.380382 0.8713846 0.380382 0.8713846 0.3933575 0.8229348 0.3732151 0.8683887 0.3933575 0.8229348 0.3856596 0.8218955 0.3732151 0.8683887 0.2876806 0.1458148 0.3448049 0.158658 0.2885111 0.1366223 0.3448049 0.158658 0.3480328 0.1500026 0.2885111 0.1366223 0.3448049 0.158658 0.3965741 0.186105 0.3480328 0.1500026 0.3965741 0.186105 0.4019686 0.1785997 0.3480328 0.1500026 0.3965741 0.186105 0.4393269 0.2262251 0.4019686 0.1785997 0.4393269 0.2262251 0.4465098 0.2203998 0.4019686 0.1785997 0.4393269 0.2262251 0.4700425 0.2762028 0.4465098 0.2203998 0.4700425 0.2762028 0.4785091 0.2724682 0.4465098 0.2203998 0.4700425 0.2762028 0.4865443 0.332527 0.4785091 0.2724682 0.4865443 0.332527 0.4956995 0.3311497 0.4785091 0.2724682 0.4865443 0.332527 0.4876552 0.3912376 0.4956995 0.3311497 0.4876552 0.3912376 0.4968561 0.3923168 0.4956995 0.3311497 0.4876552 0.3912376 0.4732818 0.4482042 0.4968561 0.3923168 0.4732818 0.4482042 0.4818778 0.4516662 0.4968561 0.3923168 0.4732818 0.4482042 0.4444195 0.4994119 0.4818778 0.4516662 0.4444195 0.4994119 0.4518064 0.5050151 0.4818778 0.4516662 0.4444195 0.4994119 0.403086 0.541247 0.4518064 0.5050151 0.403086 0.541247 0.4087414 0.5486003 0.4518064 0.5050151 0.403086 0.541247 0.3521791 0.570749 0.4087414 0.5486003 0.3521791 0.570749 0.3557021 0.5793358 0.4087414 0.5486003 0.3521791 0.570749 0.2952822 0.5858036 0.3557021 0.5793358 0.2952822 0.5858036 0.2964122 0.5950196 0.3557021 0.5793358 0.2952822 0.5858036 0.236442 0.5852586 0.2964122 0.5950196 0.236442 0.5852586 0.2350667 0.5944423 0.2964122 0.5950196 0.5007624 0.4023982 0.5086093 0.4581709 0.5282323 0.4006037 0.5086093 0.4581709 0.5359614 0.4526122 0.5282323 0.4006037 0.5282323 0.4006037 0.5359614 0.4526122 0.5504519 0.3990953 0.5359614 0.4526122 0.5578754 0.4478012 0.5504519 0.3990953 0.5504519 0.3990953 0.5578754 0.4478012 0.5680606 0.3976911 0.5578754 0.4478012 0.5750622 0.4436005 0.5680606 0.3976911 0.5086093 0.4581709 0.5235196 0.5133897 0.5359614 0.4526122 0.5235196 0.5133897 0.5515438 0.5054265 0.5359614 0.4526122 0.5359614 0.4526122 0.5515438 0.5054265 0.5578754 0.4478012 0.5515438 0.5054265 0.5737707 0.4964572 0.5578754 0.4478012 0.5578754 0.4478012 0.5737707 0.4964572 0.5750622 0.4436005 0.5737707 0.4964572 0.59014 0.4877992 0.5750622 0.4436005 0.5737707 0.4964572 0.605697 0.5394954 0.59014 0.4877992 0.605697 0.5394954 0.6189324 0.5259033 0.59014 0.4877992 0.605697 0.5394954 0.6502678 0.5716481 0.6189324 0.5259033 0.6502678 0.5716481 0.6590859 0.5542367 0.6189324 0.5259033 0.6502678 0.5716481 0.703812 0.5897448 0.6590859 0.5542367 0.703812 0.5897448 0.7073009 0.569949 0.6590859 0.5542367 0.703812 0.5897448 0.7619094 0.5917937 0.7073009 0.569949 0.7619094 0.5917937 0.7596024 0.5712465 0.7073009 0.569949 0.7619094 0.5917937 0.8197503 0.5771416 0.7596024 0.5712465 0.8197503 0.5771416 0.8116669 0.5575442 0.7596024 0.5712465 0.8197503 0.5771416 0.8725323 0.5465329 0.8116669 0.5575442 0.8725323 0.5465329 0.8591743 0.5295135 0.8116669 0.5575442 0.8725323 0.5465329 0.9158528 0.5020529 0.8591743 0.5295135 0.9158528 0.5020529 0.8981696 0.4890326 0.8591743 0.5295135 0.9158528 0.5020529 0.9460767 0.4469625 0.8981696 0.4890326 0.9460767 0.4469625 0.9253852 0.4390378 0.8981696 0.4890326 0.9460767 0.4469625 0.9606349 0.3854345 0.9253852 0.4390378 0.9606349 0.3854345 0.9385173 0.3832853 0.9253852 0.4390378 0.9606349 0.3854345 0.9582458 0.3222229 0.9385173 0.3832853 0.9582458 0.3222229 0.9364184 0.3260506 0.9385173 0.3832853 0.4018109 0.8240774 0.4018126 0.7716931 0.3933575 0.8229348 0.4018126 0.7716931 0.3933514 0.7727771 0.3933575 0.8229348 0.3933575 0.8229348 0.3933514 0.7727771 0.3856596 0.8218955 0.3933514 0.7727771 0.3856467 0.7737655 0.3856596 0.8218955 0.4018126 0.7716931 0.3882562 0.7210919 0.3933514 0.7727771 0.3882562 0.7210919 0.3803631 0.7243294 0.3933514 0.7727771 0.3933514 0.7727771 0.3803631 0.7243294 0.3856467 0.7737655 0.3803631 0.7243294 0.3731773 0.7272785 0.3856467 0.7737655 0.3882562 0.7210919 0.362065 0.675724 0.3803631 0.7243294 0.362065 0.675724 0.3552787 0.6808941 0.3803631 0.7243294 0.3803631 0.7243294 0.3552787 0.6808941 0.3731773 0.7272785 0.3552787 0.6808941 0.349101 0.685603 0.3731773 0.7272785 0.362065 0.675724 0.3250243 0.6386809 0.3552787 0.6808941 0.3250243 0.6386809 0.3198074 0.6454313 0.3552787 0.6808941 0.3552787 0.6808941 0.3198074 0.6454313 0.349101 0.685603 0.3198074 0.6454313 0.3150587 0.6515786 0.349101 0.685603 0.3250243 0.6386809 0.2796576 0.6124872 0.3198074 0.6454313 0.2796576 0.6124872 0.2763658 0.620357 0.3198074 0.6454313 0.3198074 0.6454313 0.2763658 0.620357 0.3150587 0.6515786 0.2763658 0.620357 0.2733696 0.627524 0.3150587 0.6515786 0.2796576 0.6124872 0.2290573 0.5989271 0.2763658 0.620357 0.2290573 0.5989271 0.2279145 0.6073809 0.2763658 0.620357 0.2763658 0.620357 0.2279145 0.6073809 0.2733696 0.627524 0.2279145 0.6073809 0.2268753 0.615079 0.2733696 0.627524 0.2290573 0.5989271 0.1766705 0.5989258 0.2279145 0.6073809 0.1766705 0.5989258 0.1777548 0.6073872 0.2279145 0.6073809 0.2279145 0.6073809 0.1777548 0.6073872 0.2268753 0.615079 0.1777548 0.6073872 0.1787433 0.6150922 0.2268753 0.615079 0.1766705 0.5989258 0.126069 0.6124826 0.1777548 0.6073872 0.126069 0.6124826 0.1293067 0.6203759 0.1777548 0.6073872 0.1777548 0.6073872 0.1293067 0.6203759 0.1787433 0.6150922 0.1293067 0.6203759 0.1322562 0.6275624 0.1787433 0.6150922 0.126069 0.6124826 0.08070051 0.6386756 0.1293067 0.6203759 0.08070051 0.6386756 0.08587092 0.6454619 0.1293067 0.6203759 0.1293067 0.6203759 0.08587092 0.6454619 0.1322562 0.6275624 0.08587092 0.6454619 0.09057927 0.6516396 0.1322562 0.6275624 0.08070051 0.6386756 0.04365783 0.675718 0.08587092 0.6454619 0.04365783 0.675718 0.05040848 0.6809349 0.08587092 0.6454619 0.08587092 0.6454619 0.05040848 0.6809349 0.09057927 0.6516396 0.05040848 0.6809349 0.05655473 0.685683 0.09057927 0.6516396 0.04365783 0.675718 0.01746469 0.7210858 0.05040848 0.6809349 0.01746469 0.7210858 0.02533459 0.7243773 0.05040848 0.6809349 0.05040848 0.6809349 0.02533459 0.7243773 0.05655473 0.685683 0.02533459 0.7243773 0.03250175 0.7273733 0.05655473 0.685683 0.01746469 0.7210858 0.00390625 0.7716867 0.02533459 0.7243773 0.00390625 0.7716867 0.01235991 0.7728291 0.02533459 0.7243773 0.02533459 0.7243773 0.01235991 0.7728291 0.03250175 0.7273733 0.01235991 0.7728291 0.02005803 0.7738682 0.03250175 0.7273733 0.2679725 0.365907 0.1800367 0.5688781 0.236442 0.5852586 0.2679725 0.365907 0.1311475 0.5370425 0.1800367 0.5688781 0.2679725 0.365907 0.09787863 0.4901666 0.1311475 0.5370425 0.2679725 0.365907 0.07653158 0.442074 0.09787863 0.4901666 0.2679725 0.365907 0.06556189 0.3927496 0.07653158 0.442074 0.2679725 0.365907 0.06497049 0.3430217 0.06556189 0.3927496 0.2679725 0.365907 0.07437455 0.2938694 0.06497049 0.3430217 0.2679725 0.365907 0.09369289 0.245186 0.07437455 0.2938694 0.2679725 0.365907 0.1262683 0.1996575 0.09369289 0.245186 0.2679725 0.365907 0.1738846 0.1667155 0.1262683 0.1996575 0.2679725 0.365907 0.2292709 0.1485136 0.1738846 0.1667155 0.2679725 0.365907 0.2876806 0.1458148 0.2292709 0.1485136 0.2679725 0.365907 0.3448049 0.158658 0.2876806 0.1458148 0.2679725 0.365907 0.3965741 0.186105 0.3448049 0.158658 0.2679725 0.365907 0.4393269 0.2262251 0.3965741 0.186105 0.2679725 0.365907 0.4700425 0.2762028 0.4393269 0.2262251 0.2679725 0.365907 0.4865443 0.332527 0.4700425 0.2762028 0.2679725 0.365907 0.4876552 0.3912376 0.4865443 0.332527 0.2679725 0.365907 0.4732818 0.4482042 0.4876552 0.3912376 0.2679725 0.365907 0.4444195 0.4994119 0.4732818 0.4482042 0.2679725 0.365907 0.403086 0.541247 0.4444195 0.4994119 0.2679725 0.365907 0.3521791 0.570749 0.403086 0.541247 0.2679725 0.365907 0.2952822 0.5858036 0.3521791 0.570749 0.2679725 0.365907 0.236442 0.5852586 0.2952822 0.5858036 0.02005803 0.7738682 0.02007251 0.8219993 0.2026326 0.7975854 0.02007251 0.8219993 0.03254371 0.8684865 0.2026326 0.7975854 0.03254371 0.8684865 0.05662149 0.9101615 0.2026326 0.7975854 0.05662149 0.9101615 0.09066498 0.9441852 0.2026326 0.7975854 0.09066498 0.9441852 0.1323543 0.9682372 0.2026326 0.7975854 0.1323543 0.9682372 0.1788479 0.9806805 0.2026326 0.7975854 0.1788479 0.9806805 0.2269777 0.9806662 0.2026326 0.7975854 0.2269777 0.9806662 0.273464 0.9681957 0.2026326 0.7975854 0.273464 0.9681957 0.3151385 0.9441192 0.2026326 0.7975854 0.3151385 0.9441192 0.3491623 0.910077 0.2026326 0.7975854 0.3491623 0.910077 0.3732151 0.8683887 0.2026326 0.7975854 0.3732151 0.8683887 0.3856596 0.8218955 0.2026326 0.7975854 0.3856596 0.8218955 0.3856467 0.7737655 0.2026326 0.7975854 0.3856467 0.7737655 0.3731773 0.7272785 0.2026326 0.7975854 0.3731773 0.7272785 0.349101 0.685603 0.2026326 0.7975854 0.349101 0.685603 0.3150587 0.6515786 0.2026326 0.7975854 0.3150587 0.6515786 0.2733696 0.627524 0.2026326 0.7975854 0.2733696 0.627524 0.2268753 0.615079 0.2026326 0.7975854 0.2268753 0.615079 0.1787433 0.6150922 0.2026326 0.7975854 0.1787433 0.6150922 0.1322562 0.6275624 0.2026326 0.7975854 0.1322562 0.6275624 0.09057927 0.6516396 0.2026326 0.7975854 0.09057927 0.6516396 0.05655473 0.685683 0.2026326 0.7975854 0.05655473 0.685683 0.03250175 0.7273733 0.2026326 0.7975854 0.03250175 0.7273733 0.02005803 0.7738682 0.2026326 0.7975854 + + + + + + + + + + + + + + + + 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 +

0 0 0 2 0 1 1 0 2 0 1 3 1 1 4 3 1 5 1 2 6 4 2 7 3 2 8 4 3 9 5 3 10 3 3 11 4 4 12 6 4 13 5 4 14 6 5 15 7 5 16 5 5 17 5 6 18 7 6 19 8 6 20 7 7 21 9 7 22 8 7 23 8 8 24 9 8 25 10 8 26 9 9 27 11 9 28 10 9 29 6 10 30 12 10 31 7 10 32 12 11 33 13 11 34 7 11 35 7 12 36 13 12 37 9 12 38 13 13 39 14 13 40 9 13 41 9 14 42 14 14 43 11 14 44 14 15 45 15 15 46 11 15 47 12 16 48 16 16 49 13 16 50 16 17 51 17 17 52 13 17 53 13 18 54 17 18 55 14 18 56 17 19 57 18 19 58 14 19 59 14 20 60 18 20 61 15 20 62 18 21 63 19 21 64 15 21 65 16 22 66 20 22 67 17 22 68 20 23 69 21 23 70 17 23 71 17 24 72 21 24 73 18 24 74 21 25 75 22 25 76 18 25 77 18 26 78 22 26 79 19 26 80 22 27 81 23 27 82 19 27 83 20 28 84 24 28 85 21 28 86 24 29 87 25 29 88 21 29 89 21 30 90 25 30 91 22 30 92 25 31 93 26 31 94 22 31 95 22 32 96 26 32 97 23 32 98 26 33 99 27 33 100 23 33 101 24 34 102 28 34 103 25 34 104 28 35 105 29 35 106 25 35 107 25 36 108 29 36 109 26 36 110 29 37 111 30 37 112 26 37 113 26 38 114 30 38 115 27 38 116 30 39 117 31 39 118 27 39 119 28 40 120 32 40 121 29 40 122 32 41 123 33 41 124 29 41 125 29 42 126 33 42 127 30 42 128 33 43 129 34 43 130 30 43 131 32 44 132 35 44 133 33 44 134 35 45 135 36 45 136 33 45 137 35 46 138 37 46 139 36 46 140 37 47 141 38 47 142 36 47 143 37 48 144 39 48 145 38 48 146 39 49 147 40 49 148 38 49 149 43 50 150 42 50 151 41 50 152 42 51 153 44 51 154 41 51 155 41 52 156 44 52 157 45 52 158 44 53 159 46 53 160 45 53 161 42 54 162 47 54 163 44 54 164 47 55 165 48 55 166 44 55 167 44 56 168 48 56 169 46 56 170 48 57 171 49 57 172 46 57 173 43 58 174 41 58 175 50 58 176 51 59 177 43 59 178 50 59 179 51 60 180 50 60 181 52 60 182 53 61 183 51 61 184 52 61 185 53 62 186 52 62 187 54 62 188 55 63 189 53 63 190 54 63 191 55 64 192 54 64 193 56 64 194 57 65 195 55 65 196 56 65 197 57 66 198 56 66 199 58 66 200 59 67 201 57 67 202 58 67 203 59 68 204 58 68 205 60 68 206 61 69 207 59 69 208 60 69 209 61 70 210 60 70 211 62 70 212 63 71 213 61 71 214 62 71 215 63 72 216 62 72 217 64 72 218 65 73 219 63 73 220 64 73 221 65 74 222 64 74 223 66 74 224 67 75 225 65 75 226 66 75 227 67 76 228 66 76 229 68 76 230 69 77 231 67 77 232 68 77 233 68 78 234 66 78 235 70 78 236 66 79 237 71 79 238 70 79 239 66 80 240 64 80 241 71 80 242 64 81 243 72 81 244 71 81 245 64 82 246 62 82 247 72 82 248 62 83 249 73 83 250 72 83 251 62 84 252 60 84 253 73 84 254 60 85 255 74 85 256 73 85 257 60 86 258 58 86 259 74 86 260 58 87 261 75 87 262 74 87 263 58 88 264 56 88 265 75 88 266 56 89 267 76 89 268 75 89 269 56 90 270 54 90 271 76 90 272 54 91 273 77 91 274 76 91 275 54 92 276 52 92 277 77 92 278 52 93 279 78 93 280 77 93 281 52 94 282 50 94 283 78 94 284 50 95 285 79 95 286 78 95 287 50 96 288 41 96 289 79 96 290 41 97 291 45 97 292 79 97 293 82 98 294 81 98 295 80 98 296 81 99 297 83 99 298 80 99 299 81 100 300 84 100 301 83 100 302 84 101 303 85 101 304 83 101 305 84 102 306 86 102 307 85 102 308 86 103 309 87 103 310 85 103 311 86 104 312 88 104 313 87 104 314 88 105 315 89 105 316 87 105 317 88 106 318 90 106 319 89 106 320 90 107 321 91 107 322 89 107 323 90 108 324 92 108 325 91 108 326 92 109 327 93 109 328 91 109 329 92 110 330 94 110 331 93 110 332 94 111 333 95 111 334 93 111 335 94 112 336 96 112 337 95 112 338 96 113 339 97 113 340 95 113 341 96 114 342 98 114 343 97 114 344 99 115 345 98 115 346 96 115 347 100 116 348 99 116 349 96 116 350 98 117 351 101 117 352 97 117 353 99 118 354 102 118 355 98 118 356 103 119 357 102 119 358 99 119 359 104 120 360 103 120 361 99 120 362 102 121 363 105 121 364 98 121 365 98 122 366 105 122 367 101 122 368 105 123 369 106 123 370 101 123 371 103 124 372 107 124 373 102 124 374 107 125 375 108 125 376 102 125 377 102 126 378 108 126 379 105 126 380 108 127 381 109 127 382 105 127 383 105 128 384 109 128 385 106 128 386 109 129 387 110 129 388 106 129 389 107 130 390 111 130 391 108 130 392 111 131 393 112 131 394 108 131 395 108 132 396 112 132 397 109 132 398 112 133 399 113 133 400 109 133 401 109 134 402 113 134 403 110 134 404 113 135 405 114 135 406 110 135 407 117 136 408 116 136 409 115 136 410 116 137 411 118 137 412 115 137 413 115 138 414 118 138 415 119 138 416 118 139 417 120 139 418 119 139 419 116 140 420 121 140 421 118 140 422 121 141 423 122 141 424 118 141 425 118 142 426 122 142 427 120 142 428 122 143 429 123 143 430 120 143 431 121 144 432 124 144 433 122 144 434 124 145 435 125 145 436 122 145 437 122 146 438 125 146 439 123 146 440 125 147 441 126 147 442 123 147 443 124 148 444 127 148 445 125 148 446 127 149 447 128 149 448 125 149 449 125 150 450 128 150 451 126 150 452 128 151 453 129 151 454 126 151 455 127 152 456 130 152 457 128 152 458 130 153 459 131 153 460 128 153 461 128 154 462 131 154 463 129 154 464 131 155 465 132 155 466 129 155 467 130 156 468 133 156 469 131 156 470 133 157 471 134 157 472 131 157 473 131 158 474 134 158 475 132 158 476 134 159 477 135 159 478 132 159 479 133 160 480 136 160 481 134 160 482 136 161 483 137 161 484 134 161 485 134 162 486 137 162 487 135 162 488 137 163 489 138 163 490 135 163 491 136 164 492 139 164 493 137 164 494 139 165 495 140 165 496 137 165 497 137 166 498 140 166 499 138 166 500 140 167 501 141 167 502 138 167 503 139 168 504 142 168 505 140 168 506 142 169 507 143 169 508 140 169 509 140 170 510 143 170 511 141 170 512 143 171 513 144 171 514 141 171 515 142 172 516 145 172 517 143 172 518 145 173 519 146 173 520 143 173 521 143 174 522 146 174 523 144 174 524 146 175 525 147 175 526 144 175 527 145 176 528 148 176 529 146 176 530 148 177 531 149 177 532 146 177 533 146 178 534 149 178 535 147 178 536 149 179 537 150 179 538 147 179 539 148 180 540 151 180 541 149 180 542 151 181 543 152 181 544 149 181 545 149 182 546 152 182 547 150 182 548 152 183 549 153 183 550 150 183 551 156 184 552 155 184 553 154 184 554 155 185 555 157 185 556 154 185 557 155 186 558 158 186 559 157 186 560 158 187 561 159 187 562 157 187 563 158 188 564 160 188 565 159 188 566 160 189 567 161 189 568 159 189 569 160 190 570 162 190 571 161 190 572 162 191 573 163 191 574 161 191 575 162 192 576 164 192 577 163 192 578 164 193 579 165 193 580 163 193 581 164 194 582 166 194 583 165 194 584 166 195 585 167 195 586 165 195 587 166 196 588 168 196 589 167 196 590 168 197 591 169 197 592 167 197 593 168 198 594 170 198 595 169 198 596 170 199 597 171 199 598 169 199 599 170 200 600 172 200 601 171 200 602 172 201 603 173 201 604 171 201 605 172 202 606 174 202 607 173 202 608 174 203 609 175 203 610 173 203 611 174 204 612 176 204 613 175 204 614 176 205 615 177 205 616 175 205 617 176 206 618 2 206 619 177 206 620 2 207 621 0 207 622 177 207 623 180 208 624 179 208 625 178 208 626 179 209 627 181 209 628 178 209 629 178 210 630 181 210 631 182 210 632 181 211 633 183 211 634 182 211 635 182 212 636 183 212 637 184 212 638 183 213 639 185 213 640 184 213 641 179 214 642 186 214 643 181 214 644 186 215 645 187 215 646 181 215 647 181 216 648 187 216 649 183 216 650 187 217 651 188 217 652 183 217 653 183 218 654 188 218 655 185 218 656 188 219 657 189 219 658 185 219 659 188 220 660 190 220 661 189 220 662 190 221 663 191 221 664 189 221 665 190 222 666 192 222 667 191 222 668 192 223 669 193 223 670 191 223 671 192 224 672 194 224 673 193 224 674 194 225 675 195 225 676 193 225 677 194 226 678 196 226 679 195 226 680 196 227 681 197 227 682 195 227 683 196 228 684 198 228 685 197 228 686 198 229 687 199 229 688 197 229 689 198 230 690 200 230 691 199 230 692 200 231 693 201 231 694 199 231 695 200 232 696 202 232 697 201 232 698 202 233 699 203 233 700 201 233 701 202 234 702 204 234 703 203 234 704 204 235 705 205 235 706 203 235 707 204 236 708 206 236 709 205 236 710 206 237 711 207 237 712 205 237 713 206 238 714 82 238 715 207 238 716 82 239 717 80 239 718 207 239 719 210 240 720 209 240 721 208 240 722 209 241 723 211 241 724 208 241 725 208 242 726 211 242 727 212 242 728 211 243 729 213 243 730 212 243 731 209 244 732 214 244 733 211 244 734 214 245 735 215 245 736 211 245 737 211 246 738 215 246 739 213 246 740 215 247 741 216 247 742 213 247 743 214 248 744 217 248 745 215 248 746 217 249 747 218 249 748 215 249 749 215 250 750 218 250 751 216 250 752 218 251 753 219 251 754 216 251 755 217 252 756 220 252 757 218 252 758 220 253 759 221 253 760 218 253 761 218 254 762 221 254 763 219 254 764 221 255 765 222 255 766 219 255 767 220 256 768 223 256 769 221 256 770 223 257 771 224 257 772 221 257 773 221 258 774 224 258 775 222 258 776 224 259 777 225 259 778 222 259 779 223 260 780 226 260 781 224 260 782 226 261 783 227 261 784 224 261 785 224 262 786 227 262 787 225 262 788 227 263 789 228 263 790 225 263 791 226 264 792 229 264 793 227 264 794 229 265 795 230 265 796 227 265 797 227 266 798 230 266 799 228 266 800 230 267 801 231 267 802 228 267 803 229 268 804 232 268 805 230 268 806 232 269 807 233 269 808 230 269 809 230 270 810 233 270 811 231 270 812 233 271 813 234 271 814 231 271 815 232 272 816 235 272 817 233 272 818 235 273 819 236 273 820 233 273 821 233 274 822 236 274 823 234 274 824 236 275 825 237 275 826 234 275 827 235 276 828 238 276 829 236 276 830 238 277 831 239 277 832 236 277 833 236 278 834 239 278 835 237 278 836 239 279 837 240 279 838 237 279 839 238 280 840 241 280 841 239 280 842 241 281 843 242 281 844 239 281 845 239 282 846 242 282 847 240 282 848 242 283 849 243 283 850 240 283 851 241 284 852 117 284 853 242 284 854 117 285 855 115 285 856 242 285 857 242 286 858 115 286 859 243 286 860 115 287 861 119 287 862 243 287 863 246 288 864 245 288 865 244 288 866 246 289 867 247 289 868 245 289 869 246 290 870 248 290 871 247 290 872 246 291 873 249 291 874 248 291 875 246 292 876 250 292 877 249 292 878 246 293 879 251 293 880 250 293 881 246 294 882 252 294 883 251 294 884 246 295 885 253 295 886 252 295 887 246 296 888 254 296 889 253 296 890 246 297 891 255 297 892 254 297 893 246 298 894 256 298 895 255 298 896 246 299 897 257 299 898 256 299 899 246 300 900 258 300 901 257 300 902 246 301 903 259 301 904 258 301 905 246 302 906 260 302 907 259 302 908 246 303 909 261 303 910 260 303 911 246 304 912 262 304 913 261 304 914 246 305 915 263 305 916 262 305 917 246 306 918 264 306 919 263 306 920 246 307 921 265 307 922 264 307 923 246 308 924 266 308 925 265 308 926 246 309 927 267 309 928 266 309 929 246 310 930 268 310 931 267 310 932 246 311 933 244 311 934 268 311 935 271 312 936 270 312 937 269 312 938 270 313 939 272 313 940 269 313 941 272 314 942 273 314 943 269 314 944 273 315 945 274 315 946 269 315 947 274 316 948 275 316 949 269 316 950 275 317 951 276 317 952 269 317 953 276 318 954 277 318 955 269 318 956 277 319 957 278 319 958 269 319 959 278 320 960 279 320 961 269 320 962 279 321 963 280 321 964 269 321 965 280 322 966 281 322 967 269 322 968 281 323 969 282 323 970 269 323 971 282 324 972 283 324 973 269 324 974 283 325 975 284 325 976 269 325 977 284 326 978 285 326 979 269 326 980 285 327 981 286 327 982 269 327 983 286 328 984 287 328 985 269 328 986 287 329 987 288 329 988 269 329 989 288 330 990 289 330 991 269 330 992 289 331 993 290 331 994 269 331 995 290 332 996 291 332 997 269 332 998 291 333 999 292 333 1000 269 333 1001 292 334 1002 293 334 1003 269 334 1004 293 335 1005 271 335 1006 269 335 1007

+
+
+
+ + + + 0.25 0 0.02842795 0.23476 -0.062904 0.03539395 0.243041 0 0.03539395 0.241481 -0.06470495 0.02842795 0.21048 -0.12152 0.03539395 0.216506 -0.125 0.02842795 0.171856 -0.171856 0.03539395 0.176777 -0.176777 0.02842795 0.216332 -0.1249 -0.004379987 0.176635 -0.176635 -0.004379987 0.202262 -0.116776 -0.02643096 0.165147 -0.165147 -0.02643096 0.12152 -0.21048 0.03539395 0.125 -0.216506 0.02842795 0.1249 -0.216333 -0.004379987 0.116776 -0.2022629 -0.02643096 0.062904 -0.234759 0.03539395 0.06470495 -0.241481 0.02842795 0.06465297 -0.241288 -0.004379987 0.06044799 -0.2255949 -0.02642995 0 -0.243041 0.03539395 0 -0.25 0.02842795 0 -0.249799 -0.004379987 0 -0.233553 -0.02642995 -0.062904 -0.234759 0.03539395 -0.06470495 -0.241481 0.02842795 -0.06465297 -0.241288 -0.004379987 -0.06044799 -0.225594 -0.02642995 -0.121521 -0.210479 0.03539395 -0.125 -0.216506 0.02842795 -0.1249 -0.216332 -0.004379987 -0.116776 -0.202262 -0.02643096 -0.171856 -0.171856 0.03539395 -0.176777 -0.176777 0.02842795 -0.176635 -0.176635 -0.004379987 -0.21048 -0.12152 0.03539395 -0.216506 -0.125 0.02842795 -0.23476 -0.06290298 0.03539395 -0.241482 -0.064704 0.02842795 -0.243041 0 0.03539395 -0.25 0 0.02842795 0.249799 0 -0.004379987 0.241481 -0.06470495 0.02842795 0.25 0 0.02842795 0.241288 -0.06465297 -0.004379987 0.233553 0 -0.02643096 0.225594 -0.06044799 -0.02643096 0.216506 -0.125 0.02842795 0.216332 -0.1249 -0.004379987 0.202262 -0.116776 -0.02643096 0.241288 0.06465196 -0.004379987 0.241482 0.064704 0.028427 0.216333 0.124899 -0.004380941 0.216507 0.125 0.028427 0.176635 0.176634 -0.004380941 0.176777 0.176776 0.028427 0.1249 0.216332 -0.004380941 0.125 0.216506 0.028427 0.06465297 0.2412869 -0.004380941 0.06470495 0.241481 0.028427 0 0.249799 -0.004380941 0 0.25 0.028427 -0.06465196 0.241288 -0.004380941 -0.064704 0.241482 0.028427 -0.124899 0.216333 -0.004380941 -0.125 0.216507 0.028427 -0.176635 0.176635 -0.004380941 -0.176776 0.176777 0.028427 -0.216332 0.1249 -0.004380941 -0.216506 0.125 0.028427 -0.202262 0.116776 -0.02643096 -0.1651459 0.165147 -0.02643096 -0.116776 0.2022629 -0.02643096 -0.06044799 0.225594 -0.02643197 0 0.233552 -0.02643197 0.06044799 0.225594 -0.02643197 0.116777 0.202262 -0.02643096 0.165147 0.1651459 -0.02643096 0.2022629 0.116776 -0.02643096 0.2255949 0.06044697 -0.02643096 0.212099 0 -0.02643096 0.225594 -0.06044799 -0.02643096 0.233553 0 -0.02643096 0.204872 -0.05489498 -0.02643096 0.202262 -0.116776 -0.02643096 0.183683 -0.10605 -0.02643096 0.165147 -0.165147 -0.02643096 0.149977 -0.149977 -0.02643096 0.116776 -0.2022629 -0.02643096 0.106049 -0.183683 -0.02643096 0.06044799 -0.2255949 -0.02642995 0.05489498 -0.204872 -0.02643096 0 -0.233553 -0.02642995 0 -0.212099 -0.02643096 -0.06044799 -0.225594 -0.02642995 -0.05489498 -0.204872 -0.02643096 -0.116776 -0.202262 -0.02643096 -0.10605 -0.183683 -0.02643096 -0.165147 -0.165147 -0.02643096 -0.176635 -0.176635 -0.004379987 -0.1249 -0.216332 -0.004379987 -0.149977 -0.149977 -0.02643096 -0.216333 -0.124899 -0.004379987 -0.216506 -0.125 0.02842795 -0.176777 -0.176777 0.02842795 -0.2022629 -0.116776 -0.02643096 -0.183683 -0.106049 -0.02643096 -0.241482 -0.064704 0.02842795 -0.241288 -0.06465297 -0.004379987 -0.2255949 -0.06044799 -0.02643096 -0.204872 -0.05489498 -0.02643096 -0.25 0 0.02842795 -0.249799 0 -0.004379987 -0.233553 0 -0.02643096 -0.212099 0 -0.02643096 0.212099 0 -0.035447 0.204872 -0.05489498 -0.02643096 0.212099 0 -0.02643096 0.204872 -0.05489498 -0.035447 0.206044 0 -0.04131996 0.199023 -0.05332797 -0.04131996 0.183683 -0.10605 -0.02643096 0.183683 -0.10605 -0.035447 0.178439 -0.103022 -0.04131996 0.149977 -0.149977 -0.02643096 0.149977 -0.149977 -0.035447 0.145695 -0.145695 -0.04131996 0.106049 -0.183683 -0.02643096 0.106049 -0.183683 -0.035447 0.103022 -0.17844 -0.04131996 0.05489498 -0.204872 -0.02643096 0.05489498 -0.204872 -0.035447 0.05332797 -0.199023 -0.04131996 0 -0.212099 -0.02643096 0 -0.212099 -0.035447 0 -0.206044 -0.04131996 -0.05489498 -0.204872 -0.02643096 -0.05489498 -0.204872 -0.035447 -0.05332797 -0.199023 -0.04131996 -0.10605 -0.183683 -0.02643096 -0.10605 -0.183683 -0.035447 -0.103022 -0.178439 -0.04131996 -0.149977 -0.149977 -0.02643096 -0.149977 -0.149977 -0.035447 -0.145695 -0.145695 -0.04131996 -0.183683 -0.106049 -0.02643096 -0.183683 -0.106049 -0.035447 -0.17844 -0.103022 -0.04131996 -0.204872 -0.05489498 -0.02643096 -0.204872 -0.05489498 -0.035447 -0.199023 -0.05332797 -0.04131996 -0.212099 0 -0.02643096 -0.212099 0 -0.035447 -0.206044 0 -0.04131996 -0.25 0 0.02842795 -0.23476 0.062904 0.03539395 -0.243041 0 0.03539395 -0.241481 0.06470495 0.028427 -0.21048 0.121521 0.03539299 -0.216506 0.125 0.028427 -0.171856 0.171856 0.03539299 -0.176776 0.176777 0.028427 -0.12152 0.21048 0.03539299 -0.125 0.216507 0.028427 -0.06290298 0.23476 0.03539299 -0.064704 0.241482 0.028427 0 0.243041 0.03539299 0 0.25 0.028427 0.062904 0.23476 0.03539299 0.06470495 0.241481 0.028427 0.121521 0.21048 0.03539299 0.125 0.216506 0.028427 0.171856 0.171856 0.03539299 0.176777 0.176776 0.028427 0.21048 0.12152 0.03539299 0.216507 0.125 0.028427 0.23476 0.06290298 0.03539395 0.241482 0.064704 0.028427 -0.249799 0 -0.004379987 -0.241481 0.06470495 0.028427 -0.25 0 0.02842795 -0.2412869 0.06465297 -0.004379987 -0.233553 0 -0.02643096 -0.225594 0.06044799 -0.02643096 -0.212099 0 -0.02643096 -0.204872 0.05489498 -0.02643096 -0.216506 0.125 0.028427 -0.216332 0.1249 -0.004380941 -0.202262 0.116776 -0.02643096 -0.183683 0.10605 -0.02643096 -0.1651459 0.165147 -0.02643096 -0.149976 0.149977 -0.02643096 -0.116776 0.2022629 -0.02643096 -0.106049 0.183683 -0.02643096 -0.06044799 0.225594 -0.02643197 -0.05489498 0.204872 -0.02643197 0 0.233552 -0.02643197 0 0.212099 -0.02643197 0.06044799 0.225594 -0.02643197 0.05489599 0.204872 -0.02643197 0.116777 0.202262 -0.02643096 0.10605 0.183683 -0.02643096 0.165147 0.1651459 -0.02643096 0.149977 0.149976 -0.02643096 0.2022629 0.116776 -0.02643096 0.183683 0.106049 -0.02643096 0.2255949 0.06044697 -0.02643096 0.204872 0.05489498 -0.02643096 -0.212099 0 -0.035447 -0.204872 0.05489498 -0.02643096 -0.212099 0 -0.02643096 -0.204872 0.05489498 -0.035447 -0.206044 0 -0.04131996 -0.199023 0.05332797 -0.04131996 -0.183683 0.10605 -0.02643096 -0.183683 0.10605 -0.03544795 -0.178439 0.103022 -0.04131996 -0.149976 0.149977 -0.02643096 -0.149976 0.149977 -0.03544795 -0.145695 0.145695 -0.04132097 -0.106049 0.183683 -0.02643096 -0.106049 0.183683 -0.03544795 -0.103022 0.178439 -0.04132097 -0.05489498 0.204872 -0.02643197 -0.05489498 0.204872 -0.03544795 -0.05332797 0.199023 -0.04132097 0 0.212099 -0.02643197 0 0.212099 -0.03544795 0 0.206044 -0.04132097 0.05489599 0.204872 -0.02643197 0.05489599 0.204872 -0.03544795 0.05332899 0.199023 -0.04132097 0.10605 0.183683 -0.02643096 0.10605 0.183683 -0.03544795 0.103022 0.178439 -0.04132097 0.149977 0.149976 -0.02643096 0.149977 0.149976 -0.03544795 0.145696 0.145695 -0.04132097 0.183683 0.106049 -0.02643096 0.183683 0.106049 -0.03544795 0.17844 0.103022 -0.04131996 0.204872 0.05489498 -0.02643096 0.204872 0.05489498 -0.035447 0.199023 0.05332797 -0.04131996 0.243041 0 0.03539395 0.23476 -0.062904 0.03539395 2.97e-4 2.97e-4 0.03539395 0.21048 -0.12152 0.03539395 0.171856 -0.171856 0.03539395 0.12152 -0.21048 0.03539395 0.062904 -0.234759 0.03539395 0 -0.243041 0.03539395 -0.062904 -0.234759 0.03539395 -0.121521 -0.210479 0.03539395 -0.171856 -0.171856 0.03539395 -0.21048 -0.12152 0.03539395 -0.23476 -0.06290298 0.03539395 -0.243041 0 0.03539395 -0.23476 0.062904 0.03539395 -0.21048 0.121521 0.03539299 -0.171856 0.171856 0.03539299 -0.12152 0.21048 0.03539299 -0.06290298 0.23476 0.03539299 0 0.243041 0.03539299 0.062904 0.23476 0.03539299 0.121521 0.21048 0.03539299 0.171856 0.171856 0.03539299 0.21048 0.12152 0.03539299 0.23476 0.06290298 0.03539395 2.97e-4 2.96e-4 -0.03986597 0.199023 -0.05332797 -0.04131996 0.206044 0 -0.04131996 0.178439 -0.103022 -0.04131996 0.145695 -0.145695 -0.04131996 0.103022 -0.17844 -0.04131996 0.05332797 -0.199023 -0.04131996 0 -0.206044 -0.04131996 -0.05332797 -0.199023 -0.04131996 -0.103022 -0.178439 -0.04131996 -0.145695 -0.145695 -0.04131996 -0.17844 -0.103022 -0.04131996 -0.199023 -0.05332797 -0.04131996 -0.206044 0 -0.04131996 -0.199023 0.05332797 -0.04131996 -0.178439 0.103022 -0.04131996 -0.145695 0.145695 -0.04132097 -0.103022 0.178439 -0.04132097 -0.05332797 0.199023 -0.04132097 0 0.206044 -0.04132097 0.05332899 0.199023 -0.04132097 0.103022 0.178439 -0.04132097 0.145696 0.145695 -0.04132097 0.17844 0.103022 -0.04131996 0.199023 0.05332797 -0.04131996 + + + + + + + + + + 0.7074496 0 0.7067477 0.7074496 0 0.7067477 0.6833705 -0.183111 0.7066866 0.6833705 -0.183111 0.7066866 0.6126896 -0.3537095 0.7067171 0.7273171 -0.4763634 0.4940031 0.5002289 -0.5002289 0.7067477 0.6572161 -0.6572161 0.3688162 0.7554857 -0.5796686 -0.3052766 0.672811 -0.6727805 -0.3076266 0.640614 -0.4915616 -0.5898618 0.5692617 -0.5692617 -0.5931578 0.3537095 -0.6126896 0.7067171 0.4647359 -0.8049562 0.3688162 0.4757225 -0.8239998 -0.3076266 0.4025086 -0.6971954 -0.5931578 0.1830805 -0.68334 0.7067477 0.2405469 -0.8977935 0.3688162 0.2462538 -0.9190649 -0.3076571 0.2083498 -0.7776116 -0.5931578 0 -0.7074496 0.7067477 0 -0.9295023 0.3688162 0 -0.9514756 -0.3076571 0 -0.8050478 -0.5931578 -0.1830805 -0.68334 0.7067477 -0.2405469 -0.8978241 0.3688162 -0.2462538 -0.9190649 -0.3076571 -0.2083498 -0.7776116 -0.5931883 -0.3537095 -0.6126591 0.7067477 -0.4647359 -0.8049562 0.3688162 -0.4582049 -0.8650472 -0.2041688 -0.3089999 -0.746025 -0.5898618 -0.5002289 -0.5002289 0.7067477 -0.5792413 -0.6483657 0.4940336 -0.6087222 -0.7933287 -0.006042659 -0.6126896 -0.3537095 0.7067171 -0.6126896 -0.3537095 0.7067171 -0.68334 -0.1830805 0.7067477 -0.68334 -0.1830805 0.7067477 -0.7043977 -0.0927152 0.7036958 -0.7043977 -0.0927152 0.7036958 0.9999695 0 -0.006103694 0.9658803 -0.2587969 -0.006073176 0.9514756 0 -0.3076266 0.9190649 -0.2462538 -0.3076266 0.8050783 0 -0.5931273 0.7776116 -0.2083498 -0.5931578 0.9238563 -0.3826716 -0.006042659 0.8797571 -0.3644215 -0.3052766 0.746025 -0.3089999 -0.5898618 0.9190649 0.2462538 -0.3076571 0.9658803 0.2587969 -0.006103694 0.8239998 0.4757225 -0.3076571 0.8659932 0.4999848 -0.006103694 0.6727805 0.6727805 -0.3076571 0.7070834 0.7070834 -0.006103694 0.4757225 0.8239998 -0.3076571 0.4999848 0.8659932 -0.006103694 0.2462538 0.9190649 -0.3076571 0.2587969 0.9658803 -0.006103694 0 0.9514756 -0.3076571 0 0.9999695 -0.006103694 -0.2462538 0.9190649 -0.3076571 -0.2587969 0.9658803 -0.006103694 -0.4757225 0.8239998 -0.3076571 -0.4999848 0.8659932 -0.006103694 -0.672811 0.6727805 -0.3076571 -0.7070834 0.7070834 -0.006073176 -0.7554552 0.5796686 -0.3052766 -0.7933287 0.6087222 -0.006042659 -0.640614 0.4915311 -0.5898618 -0.5692617 0.5692617 -0.5931883 -0.4025086 0.6971954 -0.5931578 -0.2083498 0.7776116 -0.5931578 0 0.8050478 -0.5931578 0.2083498 0.7776421 -0.5931578 0.4025391 0.6971954 -0.5931578 0.5692617 0.5692617 -0.5931578 0.6971954 0.4025086 -0.5931578 0.7776421 0.2083498 -0.5931578 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -0.9999695 0 0 -1 0 -3.05185e-5 -1 0 -3.05185e-5 -1 0 -3.05185e-5 -0.9999695 0 -3.05185e-5 -1 0 -3.05185e-5 -1 0 -3.05185e-5 -1 -0.1987975 -0.2590716 -0.9451583 0 0 -1 -0.3393658 -0.3393658 -0.8772851 -0.6779382 -0.6109806 -0.4087649 -0.4915616 -0.640614 -0.5898618 0 0 -1 -0.8239998 -0.4757225 -0.3076266 -0.8659932 -0.4999848 -0.006103694 -0.7933287 -0.6087222 -0.006042659 -0.4156316 -0.239967 -0.8772851 0 0 -1 -0.9658803 -0.2587969 -0.006103694 -0.9190649 -0.2462538 -0.3076266 -0.4635761 -0.1242103 -0.8772851 0 0 -1 -0.9914243 -0.1304971 -0.006042659 -0.9440901 -0.1242713 -0.3052461 -0.478988 -0.06305122 -0.8755455 0 0 -1 1 0 0 0.9659109 -0.2587969 0 0.9255654 0 -0.3785516 0.8940092 -0.2395398 -0.3785516 0.6962187 0 -0.7177954 0.6724753 -0.1801813 -0.7178259 0.8660237 -0.4999848 0 0.8015686 -0.4627827 -0.3785516 0.6029237 -0.3480941 -0.7178259 0.7070834 -0.7070834 0 0.6544694 -0.6544694 -0.3785516 0.4922636 -0.4922636 -0.7178259 0.4999848 -0.8660237 0 0.4627827 -0.8015686 -0.3785211 0.3481246 -0.6029847 -0.7177343 0.2587969 -0.9659109 0 0.2395398 -0.8940092 -0.3785516 0.1801813 -0.6724753 -0.7178259 0 -1 0 0 -0.9255654 -0.3785516 0 -0.6962187 -0.7177954 -0.2587969 -0.9659109 0 -0.2395398 -0.8940092 -0.3785516 -0.1801813 -0.6724753 -0.7178259 -0.4999848 -0.8660237 0 -0.4627827 -0.8015686 -0.3785516 -0.3480941 -0.6029237 -0.7178259 -0.7070834 -0.7070834 0 -0.6544694 -0.6544694 -0.3785516 -0.4922636 -0.4922636 -0.7178259 -0.8660237 -0.4999848 0 -0.8015686 -0.4627827 -0.3785211 -0.6029847 -0.3481246 -0.7177343 -0.9659109 -0.2587969 0 -0.8940092 -0.2395398 -0.3785516 -0.6724753 -0.1801813 -0.7178259 -0.9914243 -0.1304971 0 -0.9187597 -0.1209448 -0.3757439 -0.6933195 -0.09128081 -0.7148045 -0.7043977 0.0927152 0.7036958 -0.6834315 0.183111 0.7066561 -0.7043977 0.0927152 0.7036958 -0.6834315 0.183111 0.7066561 -0.6126896 0.35374 0.7066866 -0.6126896 0.35374 0.7066866 -0.5002594 0.5002594 0.7067171 -0.5002594 0.5002594 0.7067171 -0.3537095 0.6126286 0.7067477 -0.3537095 0.6126286 0.7067477 -0.1830805 0.68334 0.7067477 -0.1830805 0.68334 0.7067477 0 0.7074496 0.7067477 0 0.7074496 0.7067477 0.183111 0.6833705 0.7066866 0.183111 0.6833705 0.7066866 0.35374 0.6126896 0.7066866 0.35374 0.6126896 0.7066866 0.5002594 0.5002594 0.7067171 0.5002594 0.5002289 0.7067171 0.6126286 0.3537095 0.7067477 0.6126286 0.3537095 0.7067477 0.6833705 0.183111 0.7066866 0.6833705 0.183111 0.7066866 -0.9914243 0.1305276 -0.006073176 -0.9658803 0.2587969 -0.006103694 -0.9440901 0.1242713 -0.3052461 -0.9190649 0.2462538 -0.3076571 -0.478988 0.06305122 -0.8755455 -0.4635761 0.1242103 -0.8772851 0 0 -1 0 0 -1 -0.9238563 0.3826716 -0.006042659 -0.8797571 0.364391 -0.3052766 -0.301706 0.1249732 -0.9451583 0 0 -0.9999695 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -0.9999695 0 0 -1 0 0 -1 0 0 -0.9999695 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 -0.9914243 0.1304971 0 -0.9659109 0.2587969 0 -0.9187597 0.1209448 -0.3757439 -0.8940092 0.2395398 -0.3785516 -0.6933195 0.0912503 -0.7148045 -0.6724753 0.1801813 -0.7178259 -0.8659932 0.4999848 0 -0.8015381 0.4627827 -0.3785821 -0.6028627 0.3480636 -0.7178869 -0.7070834 0.7070834 0 -0.6544694 0.6544694 -0.3785516 -0.4922941 0.4922941 -0.7177954 -0.4999848 0.8660237 0 -0.4627827 0.8015686 -0.3785211 -0.3480941 0.6029542 -0.7177954 -0.2587969 0.9659109 0 -0.2395398 0.8940092 -0.3785516 -0.1801813 0.6724753 -0.7178259 0 1 0 0 0.9255654 -0.3785516 0 0.6962187 -0.7177954 0.2587969 0.9659109 0 0.2395398 0.8940092 -0.3785516 0.1801813 0.6724753 -0.7178259 0.4999848 0.8659932 0 0.4627827 0.8015381 -0.3785516 0.3480941 0.6029237 -0.7178259 0.7070834 0.7070834 0 0.6544694 0.6544694 -0.3785211 0.4923246 0.4923246 -0.7177648 0.8660237 0.4999848 0 0.8015686 0.4627827 -0.3785516 0.6029542 0.3480941 -0.7177954 0.9659109 0.2587969 0 0.8940092 0.2395398 -0.3785516 0.6724753 0.1801813 -0.7178259 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0.9999695 0 0 1 0 0 1 0 0 0.9999695 0 0 1 0 0 1 0 0 1 0 0 0.9999695 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 -0.007049739 0 -0.9999695 -0.006805598 0.001800537 -0.9999695 0 0 -1 -0.006103694 0.003509581 -0.9999695 -0.004974484 0.004974484 -0.9999695 -0.003509581 0.006103694 -0.9999695 -0.001800537 0.006805598 -0.9999695 0 0.007019221 -0.9999695 0.001800537 0.006775081 -0.9999695 0.003509581 0.006073176 -0.9999695 0.004974484 0.004974484 -0.9999695 0.006073176 0.003509581 -0.9999695 0.006775081 0.001800537 -0.9999695 0.007019221 0 -0.9999695 0.006805598 -0.001800537 -0.9999695 0.006103694 -0.003509581 -0.9999695 0.004974484 -0.004974484 -0.9999695 0.003509581 -0.006103694 -0.9999695 0.001800537 -0.006805598 -0.9999695 0 -0.007049739 -0.9999695 -0.001800537 -0.006805598 -0.9999695 -0.003509581 -0.006103694 -0.9999695 -0.004974484 -0.005005002 -0.9999695 -0.006103694 -0.003540098 -0.9999695 -0.006805598 -0.001800537 -0.9999695 + + + + + + + + + + 0.497981 0.08877295 0.497935 0.07082295 0.543138 0.07082295 0.497981 0.08877295 0.543138 0.07082295 0.542671 0.08877295 0.543138 0.07082295 0.587414 0.07082295 0.542671 0.08877295 0.587414 0.07082295 0.586501 0.08877295 0.542671 0.08877295 0.587414 0.07082295 0.631396 0.07082295 0.586501 0.08877295 0.631396 0.07082295 0.629985 0.08877295 0.586501 0.08877295 0.586501 0.08877295 0.629985 0.08877295 0.583796 0.101898 0.629985 0.08877295 0.626102 0.101898 0.583796 0.101898 0.583796 0.101898 0.626102 0.101898 0.581227 0.113775 0.626102 0.101898 0.622231 0.113775 0.581227 0.113775 0.631396 0.07082295 0.675506 0.07082295 0.629985 0.08877295 0.675506 0.07082295 0.673603 0.08877295 0.629985 0.08877295 0.629985 0.08877295 0.673603 0.08877295 0.626102 0.101898 0.673603 0.08877295 0.668071 0.101898 0.626102 0.101898 0.626102 0.101898 0.668071 0.101898 0.622231 0.113775 0.668071 0.101898 0.662932 0.113775 0.622231 0.113775 0.675506 0.07082295 0.719293 0.07082295 0.673603 0.08877295 0.719293 0.07082295 0.716869 0.08877295 0.673603 0.08877295 0.673603 0.08877295 0.716869 0.08877295 0.668071 0.101898 0.716869 0.08877295 0.709731 0.101898 0.668071 0.101898 0.668071 0.101898 0.709731 0.101898 0.662932 0.113775 0.709731 0.101898 0.703263 0.113775 0.662932 0.113775 0.719293 0.07082295 0.762508 0.07082295 0.716869 0.08877295 0.762508 0.07082295 0.759456 0.08877295 0.716869 0.08877295 0.716869 0.08877295 0.759456 0.08877295 0.709731 0.101898 0.759456 0.08877295 0.750727 0.101898 0.709731 0.101898 0.709731 0.101898 0.750727 0.101898 0.703263 0.113775 0.750727 0.101898 0.742873 0.113775 0.703263 0.113775 0.762508 0.07082295 0.803989 0.07082295 0.759456 0.08877295 0.803989 0.07082295 0.800498 0.08877295 0.759456 0.08877295 0.759456 0.08877295 0.800498 0.08877295 0.750727 0.101898 0.800498 0.08877295 0.790296 0.101898 0.750727 0.101898 0.750727 0.101898 0.790296 0.101898 0.742873 0.113775 0.790296 0.101898 0.781143 0.113775 0.742873 0.113775 0.803989 0.07082295 0.843235 0.07082295 0.800498 0.08877295 0.843235 0.07082295 0.839306 0.08877295 0.800498 0.08877295 0.800498 0.08877295 0.839306 0.08877295 0.790296 0.101898 0.839306 0.08877295 0.827857 0.101898 0.790296 0.101898 0.790296 0.101898 0.827857 0.101898 0.781143 0.113775 0.827857 0.101898 0.817555 0.113775 0.781143 0.113775 0.843235 0.07082295 0.880223 0.07082295 0.839306 0.08877295 0.880223 0.07082295 0.875888 0.08877295 0.839306 0.08877295 0.839306 0.08877295 0.875888 0.08877295 0.827857 0.101898 0.875888 0.08877295 0.863285 0.101898 0.827857 0.101898 0.880223 0.07082295 0.914794 0.07082295 0.875888 0.08877295 0.914794 0.07082295 0.910102 0.08877295 0.875888 0.08877295 0.914794 0.07082295 0.94703 0.07082295 0.910102 0.08877295 0.94703 0.07082295 0.942129 0.08877295 0.910102 0.08877295 0.94703 0.07082295 0.979042 0.07082295 0.942129 0.08877295 0.979042 0.07082295 0.974419 0.08877295 0.942129 0.08877295 0.497981 0.08877295 0.542671 0.08877295 0.497931 0.101898 0.542671 0.08877295 0.541093 0.101898 0.497931 0.101898 0.497931 0.101898 0.541093 0.101898 0.498033 0.113775 0.541093 0.101898 0.539807 0.113775 0.498033 0.113775 0.542671 0.08877295 0.586501 0.08877295 0.541093 0.101898 0.586501 0.08877295 0.583796 0.101898 0.541093 0.101898 0.541093 0.101898 0.583796 0.101898 0.539807 0.113775 0.583796 0.101898 0.581227 0.113775 0.539807 0.113775 0.497981 0.08877295 0.497931 0.101898 0.454715 0.101898 0.453182 0.08877295 0.497981 0.08877295 0.454715 0.101898 0.453182 0.08877295 0.454715 0.101898 0.411786 0.101898 0.408822 0.08877295 0.453182 0.08877295 0.411786 0.101898 0.408822 0.08877295 0.411786 0.101898 0.369753 0.101898 0.365246 0.08877295 0.408822 0.08877295 0.369753 0.101898 0.365246 0.08877295 0.369753 0.101898 0.328558 0.101898 0.322708 0.08877295 0.365246 0.08877295 0.328558 0.101898 0.322708 0.08877295 0.328558 0.101898 0.288415 0.101898 0.281408 0.08877295 0.322708 0.08877295 0.288415 0.101898 0.281408 0.08877295 0.288415 0.101898 0.249914 0.101898 0.241666 0.08877295 0.281408 0.08877295 0.249914 0.101898 0.241666 0.08877295 0.249914 0.101898 0.212984 0.101898 0.2036049 0.08877295 0.241666 0.08877295 0.212984 0.101898 0.2036049 0.08877295 0.212984 0.101898 0.1773999 0.101898 0.166799 0.08877295 0.2036049 0.08877295 0.1773999 0.101898 0.166799 0.08877295 0.1773999 0.101898 0.143133 0.101898 0.131163 0.08877295 0.166799 0.08877295 0.143133 0.101898 0.131163 0.08877295 0.143133 0.101898 0.110489 0.101898 0.09727698 0.08877295 0.131163 0.08877295 0.110489 0.101898 0.110489 0.101898 0.143133 0.101898 0.122662 0.113775 0.143133 0.101898 0.154218 0.113775 0.122662 0.113775 0.143133 0.101898 0.1773999 0.101898 0.154218 0.113775 0.1773999 0.101898 0.187257 0.113775 0.154218 0.113775 0.1773999 0.101898 0.212984 0.101898 0.187257 0.113775 0.212984 0.101898 0.221674 0.113775 0.187257 0.113775 0.212984 0.101898 0.249914 0.101898 0.221674 0.113775 0.249914 0.101898 0.25753 0.113775 0.221674 0.113775 0.249914 0.101898 0.288415 0.101898 0.25753 0.113775 0.288415 0.101898 0.294852 0.113775 0.25753 0.113775 0.288415 0.101898 0.328558 0.101898 0.294852 0.113775 0.328558 0.101898 0.333843 0.113775 0.294852 0.113775 0.328558 0.101898 0.369753 0.101898 0.333843 0.113775 0.369753 0.101898 0.373768 0.113775 0.333843 0.113775 0.369753 0.101898 0.411786 0.101898 0.373768 0.113775 0.411786 0.101898 0.414559 0.113775 0.373768 0.113775 0.411786 0.101898 0.454715 0.101898 0.414559 0.113775 0.454715 0.101898 0.456228 0.113775 0.414559 0.113775 0.454715 0.101898 0.497931 0.101898 0.456228 0.113775 0.497931 0.101898 0.498033 0.113775 0.456228 0.113775 0.498033 0.113775 0.539807 0.113775 0.498193 0.1297259 0.539807 0.113775 0.53888 0.1297259 0.498193 0.1297259 0.539807 0.113775 0.581227 0.113775 0.53888 0.1297259 0.581227 0.113775 0.579117 0.1297259 0.53888 0.1297259 0.581227 0.113775 0.622231 0.113775 0.579117 0.1297259 0.622231 0.113775 0.618878 0.1297259 0.579117 0.1297259 0.622231 0.113775 0.662932 0.113775 0.618878 0.1297259 0.662932 0.113775 0.658384 0.1297259 0.618878 0.1297259 0.662932 0.113775 0.703263 0.113775 0.658384 0.1297259 0.703263 0.113775 0.697492 0.1297259 0.658384 0.1297259 0.703263 0.113775 0.742873 0.113775 0.697492 0.1297259 0.742873 0.113775 0.735859 0.1297259 0.697492 0.1297259 0.742873 0.113775 0.781143 0.113775 0.735859 0.1297259 0.781143 0.113775 0.772949 0.1297259 0.735859 0.1297259 0.781143 0.113775 0.817555 0.113775 0.772949 0.1297259 0.817555 0.113775 0.808293 0.1297259 0.772949 0.1297259 0.817555 0.113775 0.851912 0.113775 0.808293 0.1297259 0.863285 0.101898 0.851912 0.113775 0.817555 0.113775 0.827857 0.101898 0.863285 0.101898 0.817555 0.113775 0.851912 0.113775 0.841643 0.1297259 0.808293 0.1297259 0.863285 0.101898 0.896463 0.101898 0.851912 0.113775 0.910102 0.08877295 0.896463 0.101898 0.863285 0.101898 0.875888 0.08877295 0.910102 0.08877295 0.863285 0.101898 0.896463 0.101898 0.884073 0.113775 0.851912 0.113775 0.851912 0.113775 0.884073 0.113775 0.841643 0.1297259 0.884073 0.113775 0.872809 0.1297259 0.841643 0.1297259 0.910102 0.08877295 0.942129 0.08877295 0.896463 0.101898 0.942129 0.08877295 0.927625 0.101898 0.896463 0.101898 0.896463 0.101898 0.927625 0.101898 0.884073 0.113775 0.927625 0.101898 0.914106 0.113775 0.884073 0.113775 0.884073 0.113775 0.914106 0.113775 0.872809 0.1297259 0.914106 0.113775 0.901486 0.1297259 0.872809 0.1297259 0.942129 0.08877295 0.974419 0.08877295 0.927625 0.101898 0.974419 0.08877295 0.958449 0.101898 0.927625 0.101898 0.927625 0.101898 0.958449 0.101898 0.914106 0.113775 0.958449 0.101898 0.942298 0.113775 0.914106 0.113775 0.914106 0.113775 0.942298 0.113775 0.901486 0.1297259 0.942298 0.113775 0.927269 0.1297259 0.901486 0.1297259 0.498193 0.1297259 0.53888 0.1297259 0.498246 0.140136 0.53888 0.1297259 0.538478 0.140136 0.498246 0.140136 0.498246 0.140136 0.538478 0.140136 0.498315 0.152971 0.538478 0.140136 0.538046 0.152971 0.498315 0.152971 0.53888 0.1297259 0.579117 0.1297259 0.538478 0.140136 0.579117 0.1297259 0.578292 0.140136 0.538478 0.140136 0.538478 0.140136 0.578292 0.140136 0.538046 0.152971 0.578292 0.140136 0.577423 0.152971 0.538046 0.152971 0.579117 0.1297259 0.618878 0.1297259 0.578292 0.140136 0.618878 0.1297259 0.617612 0.140136 0.578292 0.140136 0.578292 0.140136 0.617612 0.140136 0.577423 0.152971 0.617612 0.140136 0.616245 0.152971 0.577423 0.152971 0.618878 0.1297259 0.658384 0.1297259 0.617612 0.140136 0.658384 0.1297259 0.656693 0.140136 0.617612 0.140136 0.617612 0.140136 0.656693 0.140136 0.616245 0.152971 0.656693 0.140136 0.654864 0.152971 0.616245 0.152971 0.658384 0.1297259 0.697492 0.1297259 0.656693 0.140136 0.697492 0.1297259 0.69538 0.140136 0.656693 0.140136 0.656693 0.140136 0.69538 0.140136 0.654864 0.152971 0.69538 0.140136 0.693096 0.152971 0.654864 0.152971 0.697492 0.1297259 0.735859 0.1297259 0.69538 0.140136 0.735859 0.1297259 0.733325 0.140136 0.69538 0.140136 0.69538 0.140136 0.733325 0.140136 0.693096 0.152971 0.733325 0.140136 0.730592 0.152971 0.693096 0.152971 0.735859 0.1297259 0.772949 0.1297259 0.733325 0.140136 0.772949 0.1297259 0.770015 0.140136 0.733325 0.140136 0.733325 0.140136 0.770015 0.140136 0.730592 0.152971 0.770015 0.140136 0.766855 0.152971 0.730592 0.152971 0.772949 0.1297259 0.808293 0.1297259 0.770015 0.140136 0.808293 0.1297259 0.804989 0.140136 0.770015 0.140136 0.770015 0.140136 0.804989 0.140136 0.766855 0.152971 0.804989 0.140136 0.801428 0.152971 0.766855 0.152971 0.808293 0.1297259 0.841643 0.1297259 0.804989 0.140136 0.841643 0.1297259 0.837988 0.140136 0.804989 0.140136 0.804989 0.140136 0.837988 0.140136 0.801428 0.152971 0.837988 0.140136 0.834047 0.152971 0.801428 0.152971 0.841643 0.1297259 0.872809 0.1297259 0.837988 0.140136 0.872809 0.1297259 0.868808 0.140136 0.837988 0.140136 0.837988 0.140136 0.868808 0.140136 0.834047 0.152971 0.868808 0.140136 0.864493 0.152971 0.834047 0.152971 0.872809 0.1297259 0.901486 0.1297259 0.868808 0.140136 0.901486 0.1297259 0.897175 0.140136 0.868808 0.140136 0.868808 0.140136 0.897175 0.140136 0.864493 0.152971 0.897175 0.140136 0.892456 0.152971 0.864493 0.152971 0.901486 0.1297259 0.927269 0.1297259 0.897175 0.140136 0.927269 0.1297259 0.922834 0.140136 0.897175 0.140136 0.897175 0.140136 0.922834 0.140136 0.892456 0.152971 0.922834 0.140136 0.917439 0.152971 0.892456 0.152971 0.028638 0.07082295 0.06044697 0.07082295 0.03358 0.08877295 0.06044697 0.07082295 0.06551897 0.08877295 0.03358 0.08877295 0.06044697 0.07082295 0.09260195 0.07082295 0.06551897 0.08877295 0.09260195 0.07082295 0.09727698 0.08877295 0.06551897 0.08877295 0.09260195 0.07082295 0.126944 0.07082295 0.09727698 0.08877295 0.126944 0.07082295 0.131163 0.08877295 0.09727698 0.08877295 0.126944 0.07082295 0.163057 0.07082295 0.131163 0.08877295 0.163057 0.07082295 0.166799 0.08877295 0.131163 0.08877295 0.163057 0.07082295 0.200381 0.07082295 0.166799 0.08877295 0.200381 0.07082295 0.2036049 0.08877295 0.166799 0.08877295 0.200381 0.07082295 0.238752 0.07082295 0.2036049 0.08877295 0.238752 0.07082295 0.241666 0.08877295 0.2036049 0.08877295 0.238752 0.07082295 0.278904 0.07082295 0.241666 0.08877295 0.278904 0.07082295 0.281408 0.08877295 0.241666 0.08877295 0.278904 0.07082295 0.32068 0.07082295 0.281408 0.08877295 0.32068 0.07082295 0.322708 0.08877295 0.281408 0.08877295 0.32068 0.07082295 0.36368 0.07082295 0.322708 0.08877295 0.36368 0.07082295 0.365246 0.08877295 0.322708 0.08877295 0.36368 0.07082295 0.407726 0.07082295 0.365246 0.08877295 0.407726 0.07082295 0.408822 0.08877295 0.365246 0.08877295 0.407726 0.07082295 0.452605 0.07082295 0.408822 0.08877295 0.452605 0.07082295 0.453182 0.08877295 0.408822 0.08877295 0.452605 0.07082295 0.497935 0.07082295 0.453182 0.08877295 0.497935 0.07082295 0.497981 0.08877295 0.453182 0.08877295 0.03358 0.08877295 0.06551897 0.08877295 0.05011695 0.101898 0.06551897 0.08877295 0.07987499 0.101898 0.05011695 0.101898 0.05011695 0.101898 0.07987499 0.101898 0.06625896 0.113775 0.07987499 0.101898 0.09322595 0.113775 0.06625896 0.113775 0.06625896 0.113775 0.09322595 0.113775 0.080531 0.1297259 0.09322595 0.113775 0.10576 0.1297259 0.080531 0.1297259 0.06551897 0.08877295 0.09727698 0.08877295 0.07987499 0.101898 0.09727698 0.08877295 0.110489 0.101898 0.07987499 0.101898 0.07987499 0.101898 0.110489 0.101898 0.09322595 0.113775 0.110489 0.101898 0.122662 0.113775 0.09322595 0.113775 0.09322595 0.113775 0.122662 0.113775 0.10576 0.1297259 0.122662 0.113775 0.134295 0.1297259 0.10576 0.1297259 0.122662 0.113775 0.154218 0.113775 0.134295 0.1297259 0.154218 0.113775 0.16442 0.1297259 0.134295 0.1297259 0.154218 0.113775 0.187257 0.113775 0.16442 0.1297259 0.187257 0.113775 0.196301 0.1297259 0.16442 0.1297259 0.187257 0.113775 0.221674 0.113775 0.196301 0.1297259 0.221674 0.113775 0.229607 0.1297259 0.196301 0.1297259 0.221674 0.113775 0.25753 0.113775 0.229607 0.1297259 0.25753 0.113775 0.264349 0.1297259 0.229607 0.1297259 0.25753 0.113775 0.294852 0.113775 0.264349 0.1297259 0.294852 0.113775 0.300955 0.1297259 0.264349 0.1297259 0.294852 0.113775 0.333843 0.113775 0.300955 0.1297259 0.333843 0.113775 0.338598 0.1297259 0.300955 0.1297259 0.333843 0.113775 0.373768 0.113775 0.338598 0.1297259 0.373768 0.113775 0.37738 0.1297259 0.338598 0.1297259 0.373768 0.113775 0.414559 0.113775 0.37738 0.1297259 0.414559 0.113775 0.417199 0.1297259 0.37738 0.1297259 0.414559 0.113775 0.456228 0.113775 0.417199 0.1297259 0.456228 0.113775 0.457525 0.1297259 0.417199 0.1297259 0.456228 0.113775 0.498033 0.113775 0.457525 0.1297259 0.498033 0.113775 0.498193 0.1297259 0.457525 0.1297259 0.080531 0.1297259 0.10576 0.1297259 0.08523398 0.140136 0.10576 0.1297259 0.110186 0.140136 0.08523398 0.140136 0.08523398 0.140136 0.110186 0.140136 0.09042799 0.152971 0.110186 0.140136 0.114798 0.152971 0.09042799 0.152971 0.10576 0.1297259 0.134295 0.1297259 0.110186 0.140136 0.134295 0.1297259 0.138254 0.140136 0.110186 0.140136 0.110186 0.140136 0.138254 0.140136 0.114798 0.152971 0.138254 0.140136 0.142554 0.152971 0.114798 0.152971 0.134295 0.1297259 0.16442 0.1297259 0.138254 0.140136 0.16442 0.1297259 0.168044 0.140136 0.138254 0.140136 0.138254 0.140136 0.168044 0.140136 0.142554 0.152971 0.168044 0.140136 0.17198 0.152971 0.142554 0.152971 0.16442 0.1297259 0.196301 0.1297259 0.168044 0.140136 0.196301 0.1297259 0.19953 0.140136 0.168044 0.140136 0.168044 0.140136 0.19953 0.140136 0.17198 0.152971 0.19953 0.140136 0.20304 0.152971 0.17198 0.152971 0.196301 0.1297259 0.229607 0.1297259 0.19953 0.140136 0.229607 0.1297259 0.23245 0.140136 0.19953 0.140136 0.19953 0.140136 0.23245 0.140136 0.20304 0.152971 0.23245 0.140136 0.2355369 0.152971 0.20304 0.152971 0.229607 0.1297259 0.264349 0.1297259 0.23245 0.140136 0.264349 0.1297259 0.266794 0.140136 0.23245 0.140136 0.23245 0.140136 0.266794 0.140136 0.2355369 0.152971 0.266794 0.140136 0.269436 0.152971 0.2355369 0.152971 0.264349 0.1297259 0.300955 0.1297259 0.266794 0.140136 0.300955 0.1297259 0.303016 0.140136 0.266794 0.140136 0.266794 0.140136 0.303016 0.140136 0.269436 0.152971 0.303016 0.140136 0.305259 0.152971 0.269436 0.152971 0.300955 0.1297259 0.338598 0.1297259 0.303016 0.140136 0.338598 0.1297259 0.340322 0.140136 0.303016 0.140136 0.303016 0.140136 0.340322 0.140136 0.305259 0.152971 0.340322 0.140136 0.342198 0.152971 0.305259 0.152971 0.338598 0.1297259 0.37738 0.1297259 0.340322 0.140136 0.37738 0.1297259 0.378667 0.140136 0.340322 0.140136 0.340322 0.140136 0.378667 0.140136 0.342198 0.152971 0.378667 0.140136 0.380062 0.152971 0.342198 0.152971 0.37738 0.1297259 0.417199 0.1297259 0.378667 0.140136 0.417199 0.1297259 0.418079 0.140136 0.378667 0.140136 0.378667 0.140136 0.418079 0.140136 0.380062 0.152971 0.418079 0.140136 0.419045 0.152971 0.380062 0.152971 0.417199 0.1297259 0.457525 0.1297259 0.418079 0.140136 0.457525 0.1297259 0.458044 0.140136 0.418079 0.140136 0.418079 0.140136 0.458044 0.140136 0.419045 0.152971 0.458044 0.140136 0.458621 0.152971 0.419045 0.152971 0.457525 0.1297259 0.498193 0.1297259 0.458044 0.140136 0.498193 0.1297259 0.498246 0.140136 0.458044 0.140136 0.458044 0.140136 0.498246 0.140136 0.458621 0.152971 0.498246 0.140136 0.498315 0.152971 0.458621 0.152971 0.263502 0.732761 0.23444 0.956097 0.1776 0.940866 0.263502 0.732761 0.293284 0.956097 0.23444 0.956097 0.263502 0.732761 0.350124 0.940866 0.293284 0.956097 0.263502 0.732761 0.401085 0.911444 0.350124 0.940866 0.263502 0.732761 0.442694 0.869835 0.401085 0.911444 0.263502 0.732761 0.472116 0.818874 0.442694 0.869835 0.263502 0.732761 0.487347 0.762034 0.472116 0.818874 0.263502 0.732761 0.487347 0.703189 0.487347 0.762034 0.263502 0.732761 0.472116 0.64635 0.487347 0.703189 0.263502 0.732761 0.442694 0.595389 0.472116 0.64635 0.263502 0.732761 0.401085 0.553779 0.442694 0.595389 0.263502 0.732761 0.350124 0.524357 0.401085 0.553779 0.263502 0.732761 0.293284 0.509127 0.350124 0.524357 0.263502 0.732761 0.234439 0.509127 0.293284 0.509127 0.263502 0.732761 0.1776 0.524357 0.234439 0.509127 0.263502 0.732761 0.126639 0.55378 0.1776 0.524357 0.263502 0.732761 0.085029 0.595389 0.126639 0.55378 0.263502 0.732761 0.05560696 0.64635 0.085029 0.595389 0.263502 0.732761 0.04037696 0.70319 0.05560696 0.64635 0.263502 0.732761 0.04037696 0.762035 0.04037696 0.70319 0.263502 0.732761 0.05560696 0.818874 0.04037696 0.762035 0.263502 0.732761 0.08502995 0.869835 0.05560696 0.818874 0.263502 0.732761 0.126639 0.911444 0.08502995 0.869835 0.263502 0.732761 0.1776 0.940866 0.126639 0.911444 0.556957 0.497392 0.556957 0.447505 0.746185 0.472757 0.556957 0.447505 0.569869 0.399317 0.746185 0.472757 0.569869 0.399317 0.594812 0.356114 0.746185 0.472757 0.594812 0.356114 0.630088 0.320839 0.746185 0.472757 0.630088 0.320839 0.673291 0.295895 0.746185 0.472757 0.673291 0.295895 0.721478 0.282983 0.746185 0.472757 0.721478 0.282983 0.771365 0.282983 0.746185 0.472757 0.771365 0.282983 0.819552 0.295895 0.746185 0.472757 0.819552 0.295895 0.862756 0.320838 0.746185 0.472757 0.862756 0.320838 0.898031 0.356114 0.746185 0.472757 0.898031 0.356114 0.922975 0.399317 0.746185 0.472757 0.922975 0.399317 0.935887 0.447505 0.746185 0.472757 0.935887 0.447505 0.935887 0.497392 0.746185 0.472757 0.935887 0.497392 0.922975 0.545579 0.746185 0.472757 0.922975 0.545579 0.898031 0.588782 0.746185 0.472757 0.898031 0.588782 0.862756 0.624058 0.746185 0.472757 0.862756 0.624058 0.819552 0.649001 0.746185 0.472757 0.819552 0.649001 0.771365 0.661913 0.746185 0.472757 0.771365 0.661913 0.721478 0.661913 0.746185 0.472757 0.721478 0.661913 0.673291 0.649001 0.746185 0.472757 0.673291 0.649001 0.630087 0.624058 0.746185 0.472757 0.630087 0.624058 0.594812 0.588782 0.746185 0.472757 0.594812 0.588782 0.569868 0.545579 0.746185 0.472757 0.569868 0.545579 0.556957 0.497392 0.746185 0.472757 + + + + + + + + + 0.2350667 0.5944423 0.236442 0.5852586 0.1800367 0.5688781 0.2350667 0.5944423 0.1800367 0.5688781 0.1761345 0.5773187 0.1800367 0.5688781 0.1311475 0.5370425 0.1761345 0.5773187 0.1311475 0.5370425 0.1245415 0.5436798 0.1761345 0.5773187 0.1311475 0.5370425 0.09787863 0.4901666 0.1245415 0.5436798 0.09787863 0.4901666 0.09049338 0.4943432 0.1245415 0.5436798 0.1245415 0.5436798 0.09049338 0.4943432 0.09589761 0.5627111 0.09049338 0.4943432 0.0641511 0.5072736 0.09589761 0.5627111 0.09589761 0.5627111 0.0641511 0.5072736 0.06957656 0.5749213 0.0641511 0.5072736 0.03961127 0.5188692 0.06957656 0.5749213 0.09787863 0.4901666 0.07653158 0.442074 0.09049338 0.4943432 0.07653158 0.442074 0.06883269 0.4446325 0.09049338 0.4943432 0.09049338 0.4943432 0.06883269 0.4446325 0.0641511 0.5072736 0.06883269 0.4446325 0.0417397 0.4527056 0.0641511 0.5072736 0.0641511 0.5072736 0.0417397 0.4527056 0.03961127 0.5188692 0.0417397 0.4527056 0.01629096 0.460441 0.03961127 0.5188692 0.07653158 0.442074 0.06556189 0.3927496 0.06883269 0.4446325 0.06556189 0.3927496 0.05767703 0.3936865 0.06883269 0.4446325 0.06883269 0.4446325 0.05767703 0.3936865 0.0417397 0.4527056 0.05767703 0.3936865 0.0300439 0.3963494 0.0417397 0.4527056 0.0417397 0.4527056 0.0300439 0.3963494 0.01629096 0.460441 0.0300439 0.3963494 0.00390625 0.3991305 0.01629096 0.460441 0.06556189 0.3927496 0.06497049 0.3430217 0.05767703 0.3936865 0.06497049 0.3430217 0.05707472 0.3423448 0.05767703 0.3936865 0.05767703 0.3936865 0.05707472 0.3423448 0.0300439 0.3963494 0.05707472 0.3423448 0.02971023 0.3395568 0.0300439 0.3963494 0.0300439 0.3963494 0.02971023 0.3395568 0.00390625 0.3991305 0.02971023 0.3395568 0.00390625 0.3372796 0.00390625 0.3991305 0.06497049 0.3430217 0.07437455 0.2938694 0.05707472 0.3423448 0.07437455 0.2938694 0.06659692 0.2915712 0.05707472 0.3423448 0.05707472 0.3423448 0.06659692 0.2915712 0.02971023 0.3395568 0.06659692 0.2915712 0.03990733 0.2838791 0.02971023 0.3395568 0.02971023 0.3395568 0.03990733 0.2838791 0.00390625 0.3372796 0.03990733 0.2838791 0.01529473 0.2776388 0.00390625 0.3372796 0.07437455 0.2938694 0.09369289 0.245186 0.06659692 0.2915712 0.09369289 0.245186 0.08613568 0.2410319 0.06659692 0.2915712 0.06659692 0.2915712 0.08613568 0.2410319 0.03990733 0.2838791 0.08613568 0.2410319 0.05916076 0.2271876 0.03990733 0.2838791 0.03990733 0.2838791 0.05916076 0.2271876 0.01529473 0.2776388 0.05916076 0.2271876 0.03322398 0.221123 0.01529473 0.2776388 0.09369289 0.245186 0.1262683 0.1996575 0.08613568 0.2410319 0.1262683 0.1996575 0.1197991 0.1930412 0.08613568 0.2410319 0.08613568 0.2410319 0.1197991 0.1930412 0.05916076 0.2271876 0.1197991 0.1930412 0.09383791 0.1756151 0.05916076 0.2271876 0.1262683 0.1996575 0.1738846 0.1667155 0.1197991 0.1930412 0.1738846 0.1667155 0.1698107 0.1584594 0.1197991 0.1930412 0.1738846 0.1667155 0.2292709 0.1485136 0.1698107 0.1584594 0.2292709 0.1485136 0.2276279 0.1394425 0.1698107 0.1584594 0.2292709 0.1485136 0.2876806 0.1458148 0.2276279 0.1394425 0.2876806 0.1458148 0.2885111 0.1366223 0.2276279 0.1394425 0.5831499 0.09723418 0.6392333 0.07750499 0.5745477 0.06898558 0.6392333 0.07750499 0.6284694 0.04977446 0.5745477 0.06898558 0.5745477 0.06898558 0.6284694 0.04977446 0.5672938 0.04553133 0.6284694 0.04977446 0.6193705 0.02707022 0.5672938 0.04553133 0.6392333 0.07750499 0.6943629 0.05367654 0.6284694 0.04977446 0.6943629 0.05367654 0.6819697 0.0257048 0.6284694 0.04977446 0.6284694 0.04977446 0.6819697 0.0257048 0.6193705 0.02707022 0.6819697 0.0257048 0.6698388 0.00390625 0.6193705 0.02707022 0.5831499 0.09723418 0.5745477 0.06898558 0.5193687 0.08390897 0.525815 0.1127023 0.5831499 0.09723418 0.5193687 0.08390897 0.525815 0.1127023 0.5193687 0.08390897 0.4632171 0.0946123 0.4674758 0.1238127 0.525815 0.1127023 0.4632171 0.0946123 0.4674758 0.1238127 0.4632171 0.0946123 0.4064087 0.1010535 0.4084558 0.1304971 0.4674758 0.1238127 0.4064087 0.1010535 0.4084558 0.1304971 0.4064087 0.1010535 0.3492653 0.1031962 0.3490877 0.1327161 0.4084558 0.1304971 0.3492653 0.1031962 0.3490877 0.1327161 0.3492653 0.1031962 0.2921115 0.1010265 0.2897101 0.130455 0.3490877 0.1327161 0.2921115 0.1010265 0.2897101 0.130455 0.2921115 0.1010265 0.2352721 0.09455591 0.2306596 0.1237252 0.2897101 0.130455 0.2352721 0.09455591 0.2306596 0.1237252 0.2352721 0.09455591 0.1790698 0.08382123 0.1722739 0.112564 0.2306596 0.1237252 0.1790698 0.08382123 0.1722739 0.112564 0.1790698 0.08382123 0.1238058 0.06889402 0.114885 0.09703874 0.1722739 0.112564 0.1238058 0.06889402 0.114885 0.09703874 0.1238058 0.06889402 0.0696392 0.04993075 0.05882787 0.07730001 0.114885 0.09703874 0.0696392 0.04993075 0.05882787 0.07730001 0.0696392 0.04993075 0.01560503 0.0264728 0.00390625 0.05407291 0.05882787 0.07730001 0.01560503 0.0264728 0.01560503 0.0264728 0.0696392 0.04993075 0.02767962 0.00390625 0.0696392 0.04993075 0.07888078 0.02687853 0.02767962 0.00390625 0.0696392 0.04993075 0.1238058 0.06889402 0.07888078 0.02687853 0.1238058 0.06889402 0.1311852 0.0453937 0.07888078 0.02687853 0.1238058 0.06889402 0.1790698 0.08382123 0.1311852 0.0453937 0.1790698 0.08382123 0.1846489 0.05986011 0.1311852 0.0453937 0.1790698 0.08382123 0.2352721 0.09455591 0.1846489 0.05986011 0.2352721 0.09455591 0.2390297 0.07025092 0.1846489 0.05986011 0.2352721 0.09455591 0.2921115 0.1010265 0.2390297 0.07025092 0.2921115 0.1010265 0.2940266 0.07651305 0.2390297 0.07025092 0.2921115 0.1010265 0.3492653 0.1031962 0.2940266 0.07651305 0.3492653 0.1031962 0.3493282 0.07861375 0.2940266 0.07651305 0.3492653 0.1031962 0.4064087 0.1010535 0.3493282 0.07861375 0.4064087 0.1010535 0.4046192 0.076541 0.3493282 0.07861375 0.4064087 0.1010535 0.4632171 0.0946123 0.4046192 0.076541 0.4632171 0.0946123 0.459586 0.07030946 0.4046192 0.076541 0.4632171 0.0946123 0.5193687 0.08390897 0.459586 0.07030946 0.5193687 0.08390897 0.5139161 0.05995464 0.459586 0.07030946 0.5193687 0.08390897 0.5745477 0.06898558 0.5139161 0.05995464 0.5745477 0.06898558 0.5672938 0.04553133 0.5139161 0.05995464 0.9582458 0.3222229 0.9390272 0.2623018 0.9364184 0.3260506 0.9390272 0.2623018 0.9192036 0.2717746 0.9364184 0.3260506 0.9390272 0.2623018 0.9047072 0.2103503 0.9192036 0.2717746 0.9047072 0.2103503 0.8884084 0.2246392 0.9192036 0.2717746 0.9047072 0.2103503 0.8582402 0.1703261 0.8884084 0.2246392 0.8582402 0.1703261 0.846688 0.1882102 0.8884084 0.2246392 0.8582402 0.1703261 0.8035733 0.1451821 0.846688 0.1882102 0.8035733 0.1451821 0.7975903 0.165144 0.846688 0.1882102 0.8035733 0.1451821 0.7453272 0.1366223 0.7975903 0.165144 0.7453272 0.1366223 0.7452702 0.1569747 0.7975903 0.165144 0.7453272 0.1366223 0.6884095 0.1449695 0.7452702 0.1569747 0.6884095 0.1449695 0.6941417 0.1639945 0.7452702 0.1569747 0.6884095 0.1449695 0.6376188 0.1691383 0.6941417 0.1639945 0.6376188 0.1691383 0.6485199 0.1852265 0.6941417 0.1639945 0.6376188 0.1691383 0.5972502 0.206721 0.6485199 0.1852265 0.5972502 0.206721 0.6122664 0.2185064 0.6485199 0.1852265 0.5972502 0.206721 0.5716609 0.2529014 0.6122664 0.2185064 0.549771 0.2438524 0.5716609 0.2529014 0.5972502 0.206721 0.5771115 0.1936393 0.549771 0.2438524 0.5972502 0.206721 0.5716609 0.2529014 0.5885241 0.2601137 0.6122664 0.2185064 0.549771 0.2438524 0.5352486 0.2963944 0.5716609 0.2529014 0.5085309 0.2908549 0.5352486 0.2963944 0.549771 0.2438524 0.5225851 0.2367655 0.5085309 0.2908549 0.549771 0.2438524 0.5352486 0.2963944 0.5572178 0.301274 0.5716609 0.2529014 0.5716609 0.2529014 0.5572178 0.301274 0.5885241 0.2601137 0.5572178 0.301274 0.5746446 0.3051185 0.5885241 0.2601137 0.5085309 0.2908549 0.5007624 0.3462888 0.5352486 0.2963944 0.5007624 0.3462888 0.5281035 0.3483402 0.5352486 0.2963944 0.5352486 0.2963944 0.5281035 0.3483402 0.5572178 0.301274 0.5281035 0.3483402 0.5503051 0.3500352 0.5572178 0.301274 0.5572178 0.301274 0.5503051 0.3500352 0.5746446 0.3051185 0.5503051 0.3500352 0.567955 0.3512266 0.5746446 0.3051185 0.5007624 0.3462888 0.5007624 0.4023982 0.5281035 0.3483402 0.5007624 0.4023982 0.5282323 0.4006037 0.5281035 0.3483402 0.5281035 0.3483402 0.5282323 0.4006037 0.5503051 0.3500352 0.5282323 0.4006037 0.5504519 0.3990953 0.5503051 0.3500352 0.5503051 0.3500352 0.5504519 0.3990953 0.567955 0.3512266 0.5504519 0.3990953 0.5680606 0.3976911 0.567955 0.3512266 0.00390625 0.7716867 0.003906309 0.8240724 0.01235991 0.7728291 0.003906309 0.8240724 0.0123676 0.8229879 0.01235991 0.7728291 0.01235991 0.7728291 0.0123676 0.8229879 0.02005803 0.7738682 0.0123676 0.8229879 0.02007251 0.8219993 0.02005803 0.7738682 0.003906309 0.8240724 0.01746517 0.8746736 0.0123676 0.8229879 0.01746517 0.8746736 0.02535736 0.8714362 0.0123676 0.8229879 0.0123676 0.8229879 0.02535736 0.8714362 0.02007251 0.8219993 0.02535736 0.8714362 0.03254371 0.8684865 0.02007251 0.8219993 0.01746517 0.8746736 0.04365783 0.9200402 0.02535736 0.8714362 0.04365783 0.9200402 0.05044317 0.9148704 0.02535736 0.8714362 0.02535736 0.8714362 0.05044317 0.9148704 0.03254371 0.8684865 0.05044317 0.9148704 0.05662149 0.9101615 0.03254371 0.8684865 0.04365783 0.9200402 0.08070057 0.9570817 0.05044317 0.9148704 0.08070057 0.9570817 0.08591663 0.9503319 0.05044317 0.9148704 0.05044317 0.9148704 0.08591663 0.9503319 0.05662149 0.9101615 0.08591663 0.9503319 0.09066498 0.9441852 0.05662149 0.9101615 0.08070057 0.9570817 0.1260671 0.9832739 0.08591663 0.9503319 0.1260671 0.9832739 0.1293585 0.9754042 0.08591663 0.9503319 0.08591663 0.9503319 0.1293585 0.9754042 0.09066498 0.9441852 0.1293585 0.9754042 0.1323543 0.9682372 0.09066498 0.9441852 0.1260671 0.9832739 0.1766665 0.9968319 0.1293585 0.9754042 0.1766665 0.9968319 0.177809 0.9883784 0.1293585 0.9754042 0.1293585 0.9754042 0.177809 0.9883784 0.1323543 0.9682372 0.177809 0.9883784 0.1788479 0.9806805 0.1323543 0.9682372 0.1766665 0.9968319 0.2290507 0.9968319 0.177809 0.9883784 0.2290507 0.9968319 0.2279663 0.9883708 0.177809 0.9883784 0.177809 0.9883784 0.2279663 0.9883708 0.1788479 0.9806805 0.2279663 0.9883708 0.2269777 0.9806662 0.1788479 0.9806805 0.2290507 0.9968319 0.2796507 0.983274 0.2279663 0.9883708 0.2796507 0.983274 0.2764135 0.975382 0.2279663 0.9883708 0.2279663 0.9883708 0.2764135 0.975382 0.2269777 0.9806662 0.2764135 0.975382 0.273464 0.9681957 0.2269777 0.9806662 0.2796507 0.983274 0.3250167 0.9570827 0.2764135 0.975382 0.3250167 0.9570827 0.3198472 0.9502974 0.2764135 0.975382 0.2764135 0.975382 0.3198472 0.9502974 0.273464 0.9681957 0.3198472 0.9502974 0.3151385 0.9441192 0.273464 0.9681957 0.3250167 0.9570827 0.3620584 0.9200416 0.3198472 0.9502974 0.3620584 0.9200416 0.3553088 0.9148254 0.3198472 0.9502974 0.3198472 0.9502974 0.3553088 0.9148254 0.3151385 0.9441192 0.3553088 0.9148254 0.3491623 0.910077 0.3151385 0.9441192 0.3620584 0.9200416 0.3882515 0.8746762 0.3553088 0.9148254 0.3882515 0.8746762 0.380382 0.8713846 0.3553088 0.9148254 0.3553088 0.9148254 0.380382 0.8713846 0.3491623 0.910077 0.380382 0.8713846 0.3732151 0.8683887 0.3491623 0.910077 0.3882515 0.8746762 0.4018109 0.8240774 0.380382 0.8713846 0.4018109 0.8240774 0.3933575 0.8229348 0.380382 0.8713846 0.380382 0.8713846 0.3933575 0.8229348 0.3732151 0.8683887 0.3933575 0.8229348 0.3856596 0.8218955 0.3732151 0.8683887 0.2876806 0.1458148 0.3448049 0.158658 0.2885111 0.1366223 0.3448049 0.158658 0.3480328 0.1500026 0.2885111 0.1366223 0.3448049 0.158658 0.3965741 0.186105 0.3480328 0.1500026 0.3965741 0.186105 0.4019686 0.1785997 0.3480328 0.1500026 0.3965741 0.186105 0.4393269 0.2262251 0.4019686 0.1785997 0.4393269 0.2262251 0.4465098 0.2203998 0.4019686 0.1785997 0.4393269 0.2262251 0.4700425 0.2762028 0.4465098 0.2203998 0.4700425 0.2762028 0.4785091 0.2724682 0.4465098 0.2203998 0.4700425 0.2762028 0.4865443 0.332527 0.4785091 0.2724682 0.4865443 0.332527 0.4956995 0.3311497 0.4785091 0.2724682 0.4865443 0.332527 0.4876552 0.3912376 0.4956995 0.3311497 0.4876552 0.3912376 0.4968561 0.3923168 0.4956995 0.3311497 0.4876552 0.3912376 0.4732818 0.4482042 0.4968561 0.3923168 0.4732818 0.4482042 0.4818778 0.4516662 0.4968561 0.3923168 0.4732818 0.4482042 0.4444195 0.4994119 0.4818778 0.4516662 0.4444195 0.4994119 0.4518064 0.5050151 0.4818778 0.4516662 0.4444195 0.4994119 0.403086 0.541247 0.4518064 0.5050151 0.403086 0.541247 0.4087414 0.5486003 0.4518064 0.5050151 0.403086 0.541247 0.3521791 0.570749 0.4087414 0.5486003 0.3521791 0.570749 0.3557021 0.5793358 0.4087414 0.5486003 0.3521791 0.570749 0.2952822 0.5858036 0.3557021 0.5793358 0.2952822 0.5858036 0.2964122 0.5950196 0.3557021 0.5793358 0.2952822 0.5858036 0.236442 0.5852586 0.2964122 0.5950196 0.236442 0.5852586 0.2350667 0.5944423 0.2964122 0.5950196 0.5007624 0.4023982 0.5086093 0.4581709 0.5282323 0.4006037 0.5086093 0.4581709 0.5359614 0.4526122 0.5282323 0.4006037 0.5282323 0.4006037 0.5359614 0.4526122 0.5504519 0.3990953 0.5359614 0.4526122 0.5578754 0.4478012 0.5504519 0.3990953 0.5504519 0.3990953 0.5578754 0.4478012 0.5680606 0.3976911 0.5578754 0.4478012 0.5750622 0.4436005 0.5680606 0.3976911 0.5086093 0.4581709 0.5235196 0.5133897 0.5359614 0.4526122 0.5235196 0.5133897 0.5515438 0.5054265 0.5359614 0.4526122 0.5359614 0.4526122 0.5515438 0.5054265 0.5578754 0.4478012 0.5515438 0.5054265 0.5737707 0.4964572 0.5578754 0.4478012 0.5578754 0.4478012 0.5737707 0.4964572 0.5750622 0.4436005 0.5737707 0.4964572 0.59014 0.4877992 0.5750622 0.4436005 0.5737707 0.4964572 0.605697 0.5394954 0.59014 0.4877992 0.605697 0.5394954 0.6189324 0.5259033 0.59014 0.4877992 0.605697 0.5394954 0.6502678 0.5716481 0.6189324 0.5259033 0.6502678 0.5716481 0.6590859 0.5542367 0.6189324 0.5259033 0.6502678 0.5716481 0.703812 0.5897448 0.6590859 0.5542367 0.703812 0.5897448 0.7073009 0.569949 0.6590859 0.5542367 0.703812 0.5897448 0.7619094 0.5917937 0.7073009 0.569949 0.7619094 0.5917937 0.7596024 0.5712465 0.7073009 0.569949 0.7619094 0.5917937 0.8197503 0.5771416 0.7596024 0.5712465 0.8197503 0.5771416 0.8116669 0.5575442 0.7596024 0.5712465 0.8197503 0.5771416 0.8725323 0.5465329 0.8116669 0.5575442 0.8725323 0.5465329 0.8591743 0.5295135 0.8116669 0.5575442 0.8725323 0.5465329 0.9158528 0.5020529 0.8591743 0.5295135 0.9158528 0.5020529 0.8981696 0.4890326 0.8591743 0.5295135 0.9158528 0.5020529 0.9460767 0.4469625 0.8981696 0.4890326 0.9460767 0.4469625 0.9253852 0.4390378 0.8981696 0.4890326 0.9460767 0.4469625 0.9606349 0.3854345 0.9253852 0.4390378 0.9606349 0.3854345 0.9385173 0.3832853 0.9253852 0.4390378 0.9606349 0.3854345 0.9582458 0.3222229 0.9385173 0.3832853 0.9582458 0.3222229 0.9364184 0.3260506 0.9385173 0.3832853 0.4018109 0.8240774 0.4018126 0.7716931 0.3933575 0.8229348 0.4018126 0.7716931 0.3933514 0.7727771 0.3933575 0.8229348 0.3933575 0.8229348 0.3933514 0.7727771 0.3856596 0.8218955 0.3933514 0.7727771 0.3856467 0.7737655 0.3856596 0.8218955 0.4018126 0.7716931 0.3882562 0.7210919 0.3933514 0.7727771 0.3882562 0.7210919 0.3803631 0.7243294 0.3933514 0.7727771 0.3933514 0.7727771 0.3803631 0.7243294 0.3856467 0.7737655 0.3803631 0.7243294 0.3731773 0.7272785 0.3856467 0.7737655 0.3882562 0.7210919 0.362065 0.675724 0.3803631 0.7243294 0.362065 0.675724 0.3552787 0.6808941 0.3803631 0.7243294 0.3803631 0.7243294 0.3552787 0.6808941 0.3731773 0.7272785 0.3552787 0.6808941 0.349101 0.685603 0.3731773 0.7272785 0.362065 0.675724 0.3250243 0.6386809 0.3552787 0.6808941 0.3250243 0.6386809 0.3198074 0.6454313 0.3552787 0.6808941 0.3552787 0.6808941 0.3198074 0.6454313 0.349101 0.685603 0.3198074 0.6454313 0.3150587 0.6515786 0.349101 0.685603 0.3250243 0.6386809 0.2796576 0.6124872 0.3198074 0.6454313 0.2796576 0.6124872 0.2763658 0.620357 0.3198074 0.6454313 0.3198074 0.6454313 0.2763658 0.620357 0.3150587 0.6515786 0.2763658 0.620357 0.2733696 0.627524 0.3150587 0.6515786 0.2796576 0.6124872 0.2290573 0.5989271 0.2763658 0.620357 0.2290573 0.5989271 0.2279145 0.6073809 0.2763658 0.620357 0.2763658 0.620357 0.2279145 0.6073809 0.2733696 0.627524 0.2279145 0.6073809 0.2268753 0.615079 0.2733696 0.627524 0.2290573 0.5989271 0.1766705 0.5989258 0.2279145 0.6073809 0.1766705 0.5989258 0.1777548 0.6073872 0.2279145 0.6073809 0.2279145 0.6073809 0.1777548 0.6073872 0.2268753 0.615079 0.1777548 0.6073872 0.1787433 0.6150922 0.2268753 0.615079 0.1766705 0.5989258 0.126069 0.6124826 0.1777548 0.6073872 0.126069 0.6124826 0.1293067 0.6203759 0.1777548 0.6073872 0.1777548 0.6073872 0.1293067 0.6203759 0.1787433 0.6150922 0.1293067 0.6203759 0.1322562 0.6275624 0.1787433 0.6150922 0.126069 0.6124826 0.08070051 0.6386756 0.1293067 0.6203759 0.08070051 0.6386756 0.08587092 0.6454619 0.1293067 0.6203759 0.1293067 0.6203759 0.08587092 0.6454619 0.1322562 0.6275624 0.08587092 0.6454619 0.09057927 0.6516396 0.1322562 0.6275624 0.08070051 0.6386756 0.04365783 0.675718 0.08587092 0.6454619 0.04365783 0.675718 0.05040848 0.6809349 0.08587092 0.6454619 0.08587092 0.6454619 0.05040848 0.6809349 0.09057927 0.6516396 0.05040848 0.6809349 0.05655473 0.685683 0.09057927 0.6516396 0.04365783 0.675718 0.01746469 0.7210858 0.05040848 0.6809349 0.01746469 0.7210858 0.02533459 0.7243773 0.05040848 0.6809349 0.05040848 0.6809349 0.02533459 0.7243773 0.05655473 0.685683 0.02533459 0.7243773 0.03250175 0.7273733 0.05655473 0.685683 0.01746469 0.7210858 0.00390625 0.7716867 0.02533459 0.7243773 0.00390625 0.7716867 0.01235991 0.7728291 0.02533459 0.7243773 0.02533459 0.7243773 0.01235991 0.7728291 0.03250175 0.7273733 0.01235991 0.7728291 0.02005803 0.7738682 0.03250175 0.7273733 0.2679725 0.365907 0.1800367 0.5688781 0.236442 0.5852586 0.2679725 0.365907 0.1311475 0.5370425 0.1800367 0.5688781 0.2679725 0.365907 0.09787863 0.4901666 0.1311475 0.5370425 0.2679725 0.365907 0.07653158 0.442074 0.09787863 0.4901666 0.2679725 0.365907 0.06556189 0.3927496 0.07653158 0.442074 0.2679725 0.365907 0.06497049 0.3430217 0.06556189 0.3927496 0.2679725 0.365907 0.07437455 0.2938694 0.06497049 0.3430217 0.2679725 0.365907 0.09369289 0.245186 0.07437455 0.2938694 0.2679725 0.365907 0.1262683 0.1996575 0.09369289 0.245186 0.2679725 0.365907 0.1738846 0.1667155 0.1262683 0.1996575 0.2679725 0.365907 0.2292709 0.1485136 0.1738846 0.1667155 0.2679725 0.365907 0.2876806 0.1458148 0.2292709 0.1485136 0.2679725 0.365907 0.3448049 0.158658 0.2876806 0.1458148 0.2679725 0.365907 0.3965741 0.186105 0.3448049 0.158658 0.2679725 0.365907 0.4393269 0.2262251 0.3965741 0.186105 0.2679725 0.365907 0.4700425 0.2762028 0.4393269 0.2262251 0.2679725 0.365907 0.4865443 0.332527 0.4700425 0.2762028 0.2679725 0.365907 0.4876552 0.3912376 0.4865443 0.332527 0.2679725 0.365907 0.4732818 0.4482042 0.4876552 0.3912376 0.2679725 0.365907 0.4444195 0.4994119 0.4732818 0.4482042 0.2679725 0.365907 0.403086 0.541247 0.4444195 0.4994119 0.2679725 0.365907 0.3521791 0.570749 0.403086 0.541247 0.2679725 0.365907 0.2952822 0.5858036 0.3521791 0.570749 0.2679725 0.365907 0.236442 0.5852586 0.2952822 0.5858036 0.02005803 0.7738682 0.02007251 0.8219993 0.2026326 0.7975854 0.02007251 0.8219993 0.03254371 0.8684865 0.2026326 0.7975854 0.03254371 0.8684865 0.05662149 0.9101615 0.2026326 0.7975854 0.05662149 0.9101615 0.09066498 0.9441852 0.2026326 0.7975854 0.09066498 0.9441852 0.1323543 0.9682372 0.2026326 0.7975854 0.1323543 0.9682372 0.1788479 0.9806805 0.2026326 0.7975854 0.1788479 0.9806805 0.2269777 0.9806662 0.2026326 0.7975854 0.2269777 0.9806662 0.273464 0.9681957 0.2026326 0.7975854 0.273464 0.9681957 0.3151385 0.9441192 0.2026326 0.7975854 0.3151385 0.9441192 0.3491623 0.910077 0.2026326 0.7975854 0.3491623 0.910077 0.3732151 0.8683887 0.2026326 0.7975854 0.3732151 0.8683887 0.3856596 0.8218955 0.2026326 0.7975854 0.3856596 0.8218955 0.3856467 0.7737655 0.2026326 0.7975854 0.3856467 0.7737655 0.3731773 0.7272785 0.2026326 0.7975854 0.3731773 0.7272785 0.349101 0.685603 0.2026326 0.7975854 0.349101 0.685603 0.3150587 0.6515786 0.2026326 0.7975854 0.3150587 0.6515786 0.2733696 0.627524 0.2026326 0.7975854 0.2733696 0.627524 0.2268753 0.615079 0.2026326 0.7975854 0.2268753 0.615079 0.1787433 0.6150922 0.2026326 0.7975854 0.1787433 0.6150922 0.1322562 0.6275624 0.2026326 0.7975854 0.1322562 0.6275624 0.09057927 0.6516396 0.2026326 0.7975854 0.09057927 0.6516396 0.05655473 0.685683 0.2026326 0.7975854 0.05655473 0.685683 0.03250175 0.7273733 0.2026326 0.7975854 0.03250175 0.7273733 0.02005803 0.7738682 0.2026326 0.7975854 + + + + + + + + + + + + + + + + 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 +

0 0 0 2 1 1 1 2 2 0 0 3 1 2 4 3 3 5 1 2 6 4 4 7 3 3 8 4 4 9 5 5 10 3 3 11 4 4 12 6 6 13 5 5 14 6 6 15 7 7 16 5 5 17 5 5 18 7 7 19 8 8 20 7 7 21 9 9 22 8 8 23 8 8 24 9 9 25 10 10 26 9 9 27 11 11 28 10 10 29 6 6 30 12 12 31 7 7 32 12 12 33 13 13 34 7 7 35 7 7 36 13 13 37 9 9 38 13 13 39 14 14 40 9 9 41 9 9 42 14 14 43 11 11 44 14 14 45 15 15 46 11 11 47 12 12 48 16 16 49 13 13 50 16 16 51 17 17 52 13 13 53 13 13 54 17 17 55 14 14 56 17 17 57 18 18 58 14 14 59 14 14 60 18 18 61 15 15 62 18 18 63 19 19 64 15 15 65 16 16 66 20 20 67 17 17 68 20 20 69 21 21 70 17 17 71 17 17 72 21 21 73 18 18 74 21 21 75 22 22 76 18 18 77 18 18 78 22 22 79 19 19 80 22 22 81 23 23 82 19 19 83 20 20 84 24 24 85 21 21 86 24 24 87 25 25 88 21 21 89 21 21 90 25 25 91 22 22 92 25 25 93 26 26 94 22 22 95 22 22 96 26 26 97 23 23 98 26 26 99 27 27 100 23 23 101 24 24 102 28 28 103 25 25 104 28 28 105 29 29 106 25 25 107 25 25 108 29 29 109 26 26 110 29 29 111 30 30 112 26 26 113 26 26 114 30 30 115 27 27 116 30 30 117 31 31 118 27 27 119 28 28 120 32 32 121 29 29 122 32 32 123 33 33 124 29 29 125 29 29 126 33 33 127 30 30 128 33 33 129 34 34 130 30 30 131 32 32 132 35 35 133 33 33 134 35 35 135 36 36 136 33 33 137 35 35 138 37 37 139 36 36 140 37 37 141 38 38 142 36 36 143 37 37 144 39 39 145 38 38 146 39 39 147 40 40 148 38 38 149 43 41 150 42 42 151 41 43 152 42 42 153 44 44 154 41 43 155 41 43 156 44 44 157 45 45 158 44 44 159 46 46 160 45 45 161 42 42 162 47 47 163 44 44 164 47 47 165 48 48 166 44 44 167 44 44 168 48 48 169 46 46 170 48 48 171 49 49 172 46 46 173 43 41 174 41 43 175 50 50 176 51 51 177 43 41 178 50 50 179 51 51 180 50 50 181 52 52 182 53 53 183 51 51 184 52 52 185 53 53 186 52 52 187 54 54 188 55 55 189 53 53 190 54 54 191 55 55 192 54 54 193 56 56 194 57 57 195 55 55 196 56 56 197 57 57 198 56 56 199 58 58 200 59 59 201 57 57 202 58 58 203 59 59 204 58 58 205 60 60 206 61 61 207 59 59 208 60 60 209 61 61 210 60 60 211 62 62 212 63 63 213 61 61 214 62 62 215 63 63 216 62 62 217 64 64 218 65 65 219 63 63 220 64 64 221 65 65 222 64 64 223 66 66 224 67 67 225 65 65 226 66 66 227 67 67 228 66 66 229 68 68 230 69 69 231 67 67 232 68 68 233 68 68 234 66 66 235 70 70 236 66 66 237 71 71 238 70 70 239 66 66 240 64 64 241 71 71 242 64 64 243 72 72 244 71 71 245 64 64 246 62 62 247 72 72 248 62 62 249 73 73 250 72 72 251 62 62 252 60 60 253 73 73 254 60 60 255 74 74 256 73 73 257 60 60 258 58 58 259 74 74 260 58 58 261 75 75 262 74 74 263 58 58 264 56 56 265 75 75 266 56 56 267 76 76 268 75 75 269 56 56 270 54 54 271 76 76 272 54 54 273 77 77 274 76 76 275 54 54 276 52 52 277 77 77 278 52 52 279 78 78 280 77 77 281 52 52 282 50 50 283 78 78 284 50 50 285 79 79 286 78 78 287 50 50 288 41 43 289 79 79 290 41 43 291 45 45 292 79 79 293 82 80 294 81 81 295 80 82 296 81 81 297 83 83 298 80 82 299 81 81 300 84 84 301 83 83 302 84 84 303 85 85 304 83 83 305 84 84 306 86 86 307 85 85 308 86 86 309 87 87 310 85 85 311 86 86 312 88 88 313 87 87 314 88 88 315 89 89 316 87 87 317 88 88 318 90 90 319 89 89 320 90 90 321 91 91 322 89 89 323 90 90 324 92 92 325 91 91 326 92 92 327 93 93 328 91 91 329 92 92 330 94 94 331 93 93 332 94 94 333 95 95 334 93 93 335 94 94 336 96 96 337 95 95 338 96 96 339 97 97 340 95 95 341 96 96 342 98 98 343 97 97 344 99 99 345 98 98 346 96 96 347 100 100 348 99 99 349 96 96 350 98 98 351 101 101 352 97 97 353 99 99 354 102 102 355 98 98 356 103 103 357 102 102 358 99 99 359 104 104 360 103 103 361 99 99 362 102 102 363 105 105 364 98 98 365 98 98 366 105 105 367 101 101 368 105 105 369 106 106 370 101 101 371 103 103 372 107 107 373 102 102 374 107 107 375 108 108 376 102 102 377 102 102 378 108 108 379 105 105 380 108 108 381 109 109 382 105 105 383 105 105 384 109 109 385 106 106 386 109 109 387 110 110 388 106 106 389 107 107 390 111 111 391 108 108 392 111 111 393 112 112 394 108 108 395 108 108 396 112 112 397 109 109 398 112 112 399 113 113 400 109 109 401 109 109 402 113 113 403 110 110 404 113 113 405 114 114 406 110 110 407 117 115 408 116 116 409 115 117 410 116 116 411 118 118 412 115 117 413 115 117 414 118 118 415 119 119 416 118 118 417 120 120 418 119 119 419 116 116 420 121 121 421 118 118 422 121 121 423 122 122 424 118 118 425 118 118 426 122 122 427 120 120 428 122 122 429 123 123 430 120 120 431 121 121 432 124 124 433 122 122 434 124 124 435 125 125 436 122 122 437 122 122 438 125 125 439 123 123 440 125 125 441 126 126 442 123 123 443 124 124 444 127 127 445 125 125 446 127 127 447 128 128 448 125 125 449 125 125 450 128 128 451 126 126 452 128 128 453 129 129 454 126 126 455 127 127 456 130 130 457 128 128 458 130 130 459 131 131 460 128 128 461 128 128 462 131 131 463 129 129 464 131 131 465 132 132 466 129 129 467 130 130 468 133 133 469 131 131 470 133 133 471 134 134 472 131 131 473 131 131 474 134 134 475 132 132 476 134 134 477 135 135 478 132 132 479 133 133 480 136 136 481 134 134 482 136 136 483 137 137 484 134 134 485 134 134 486 137 137 487 135 135 488 137 137 489 138 138 490 135 135 491 136 136 492 139 139 493 137 137 494 139 139 495 140 140 496 137 137 497 137 137 498 140 140 499 138 138 500 140 140 501 141 141 502 138 138 503 139 139 504 142 142 505 140 140 506 142 142 507 143 143 508 140 140 509 140 140 510 143 143 511 141 141 512 143 143 513 144 144 514 141 141 515 142 142 516 145 145 517 143 143 518 145 145 519 146 146 520 143 143 521 143 143 522 146 146 523 144 144 524 146 146 525 147 147 526 144 144 527 145 145 528 148 148 529 146 146 530 148 148 531 149 149 532 146 146 533 146 146 534 149 149 535 147 147 536 149 149 537 150 150 538 147 147 539 148 148 540 151 151 541 149 149 542 151 151 543 152 152 544 149 149 545 149 149 546 152 152 547 150 150 548 152 152 549 153 153 550 150 150 551 156 154 552 155 155 553 154 156 554 155 155 555 157 157 556 154 156 557 155 155 558 158 158 559 157 157 560 158 158 561 159 159 562 157 157 563 158 158 564 160 160 565 159 159 566 160 160 567 161 161 568 159 159 569 160 160 570 162 162 571 161 161 572 162 162 573 163 163 574 161 161 575 162 162 576 164 164 577 163 163 578 164 164 579 165 165 580 163 163 581 164 164 582 166 166 583 165 165 584 166 166 585 167 167 586 165 165 587 166 166 588 168 168 589 167 167 590 168 168 591 169 169 592 167 167 593 168 168 594 170 170 595 169 169 596 170 170 597 171 171 598 169 169 599 170 170 600 172 172 601 171 171 602 172 172 603 173 173 604 171 171 605 172 172 606 174 174 607 173 173 608 174 174 609 175 175 610 173 173 611 174 174 612 176 176 613 175 175 614 176 176 615 177 177 616 175 175 617 176 176 618 2 1 619 177 177 620 2 1 621 0 0 622 177 177 623 180 178 624 179 179 625 178 180 626 179 179 627 181 181 628 178 180 629 178 180 630 181 181 631 182 182 632 181 181 633 183 183 634 182 182 635 182 182 636 183 183 637 184 184 638 183 183 639 185 185 640 184 184 641 179 179 642 186 186 643 181 181 644 186 186 645 187 187 646 181 181 647 181 181 648 187 187 649 183 183 650 187 187 651 188 188 652 183 183 653 183 183 654 188 188 655 185 185 656 188 188 657 189 189 658 185 185 659 188 188 660 190 190 661 189 189 662 190 190 663 191 191 664 189 189 665 190 190 666 192 192 667 191 191 668 192 192 669 193 193 670 191 191 671 192 192 672 194 194 673 193 193 674 194 194 675 195 195 676 193 193 677 194 194 678 196 196 679 195 195 680 196 196 681 197 197 682 195 195 683 196 196 684 198 198 685 197 197 686 198 198 687 199 199 688 197 197 689 198 198 690 200 200 691 199 199 692 200 200 693 201 201 694 199 199 695 200 200 696 202 202 697 201 201 698 202 202 699 203 203 700 201 201 701 202 202 702 204 204 703 203 203 704 204 204 705 205 205 706 203 203 707 204 204 708 206 206 709 205 205 710 206 206 711 207 207 712 205 205 713 206 206 714 82 80 715 207 207 716 82 80 717 80 82 718 207 207 719 210 208 720 209 209 721 208 210 722 209 209 723 211 211 724 208 210 725 208 210 726 211 211 727 212 212 728 211 211 729 213 213 730 212 212 731 209 209 732 214 214 733 211 211 734 214 214 735 215 215 736 211 211 737 211 211 738 215 215 739 213 213 740 215 215 741 216 216 742 213 213 743 214 214 744 217 217 745 215 215 746 217 217 747 218 218 748 215 215 749 215 215 750 218 218 751 216 216 752 218 218 753 219 219 754 216 216 755 217 217 756 220 220 757 218 218 758 220 220 759 221 221 760 218 218 761 218 218 762 221 221 763 219 219 764 221 221 765 222 222 766 219 219 767 220 220 768 223 223 769 221 221 770 223 223 771 224 224 772 221 221 773 221 221 774 224 224 775 222 222 776 224 224 777 225 225 778 222 222 779 223 223 780 226 226 781 224 224 782 226 226 783 227 227 784 224 224 785 224 224 786 227 227 787 225 225 788 227 227 789 228 228 790 225 225 791 226 226 792 229 229 793 227 227 794 229 229 795 230 230 796 227 227 797 227 227 798 230 230 799 228 228 800 230 230 801 231 231 802 228 228 803 229 229 804 232 232 805 230 230 806 232 232 807 233 233 808 230 230 809 230 230 810 233 233 811 231 231 812 233 233 813 234 234 814 231 231 815 232 232 816 235 235 817 233 233 818 235 235 819 236 236 820 233 233 821 233 233 822 236 236 823 234 234 824 236 236 825 237 237 826 234 234 827 235 235 828 238 238 829 236 236 830 238 238 831 239 239 832 236 236 833 236 236 834 239 239 835 237 237 836 239 239 837 240 240 838 237 237 839 238 238 840 241 241 841 239 239 842 241 241 843 242 242 844 239 239 845 239 239 846 242 242 847 240 240 848 242 242 849 243 243 850 240 240 851 241 241 852 117 115 853 242 242 854 117 115 855 115 117 856 242 242 857 242 242 858 115 117 859 243 243 860 115 117 861 119 119 862 243 243 863 246 244 864 245 245 865 244 246 866 246 244 867 247 247 868 245 245 869 246 244 870 248 248 871 247 247 872 246 244 873 249 249 874 248 248 875 246 244 876 250 250 877 249 249 878 246 244 879 251 251 880 250 250 881 246 244 882 252 252 883 251 251 884 246 244 885 253 253 886 252 252 887 246 244 888 254 254 889 253 253 890 246 244 891 255 255 892 254 254 893 246 244 894 256 256 895 255 255 896 246 244 897 257 257 898 256 256 899 246 244 900 258 258 901 257 257 902 246 244 903 259 259 904 258 258 905 246 244 906 260 260 907 259 259 908 246 244 909 261 261 910 260 260 911 246 244 912 262 262 913 261 261 914 246 244 915 263 263 916 262 262 917 246 244 918 264 264 919 263 263 920 246 244 921 265 265 922 264 264 923 246 244 924 266 266 925 265 265 926 246 244 927 267 267 928 266 266 929 246 244 930 268 268 931 267 267 932 246 244 933 244 246 934 268 268 935 271 269 936 270 270 937 269 271 938 270 270 939 272 272 940 269 271 941 272 272 942 273 273 943 269 271 944 273 273 945 274 274 946 269 271 947 274 274 948 275 275 949 269 271 950 275 275 951 276 276 952 269 271 953 276 276 954 277 277 955 269 271 956 277 277 957 278 278 958 269 271 959 278 278 960 279 279 961 269 271 962 279 279 963 280 280 964 269 271 965 280 280 966 281 281 967 269 271 968 281 281 969 282 282 970 269 271 971 282 282 972 283 283 973 269 271 974 283 283 975 284 284 976 269 271 977 284 284 978 285 285 979 269 271 980 285 285 981 286 286 982 269 271 983 286 286 984 287 287 985 269 271 986 287 287 987 288 288 988 269 271 989 288 288 990 289 289 991 269 271 992 289 289 993 290 290 994 269 271 995 290 290 996 291 291 997 269 271 998 291 291 999 292 292 1000 269 271 1001 292 292 1002 293 293 1003 269 271 1004 293 293 1005 271 269 1006 269 271 1007

+
+
+
+
+ + + + + 0.6858805 -0.3173701 0.6548619 7.481132 0.7276338 0.3124686 -0.6106656 -6.50764 -0.01081678 0.8953432 0.4452454 5.343665 0 0 0 1 + + + + -0.2908646 -0.7711008 0.5663932 4.076245 0.9551712 -0.1998834 0.2183912 1.005454 -0.05518906 0.6045247 0.7946723 5.903862 0 0 0 1 + + + + 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 + + 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 + + + + + + + + + + + + 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 + + + + 1 0 0 0 0 1 0 0 0 0 1 -0.003676087 0 0 0 1 + + + + + + + + + +
\ No newline at end of file diff --git a/src/parts source/kOS1m dev/Assets/Materials.meta b/src/parts source/kOS1m dev/Assets/Materials.meta new file mode 100644 index 000000000..1b8e0c1de --- /dev/null +++ b/src/parts source/kOS1m dev/Assets/Materials.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 090c59c8a407b440c91d211eb30b8606 +folderAsset: yes +timeCreated: 1431174478 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/parts source/kOS1m dev/Assets/Materials/model001.png b/src/parts source/kOS1m dev/Assets/Materials/model001.png new file mode 100644 index 000000000..4b95c4b94 Binary files /dev/null and b/src/parts source/kOS1m dev/Assets/Materials/model001.png differ diff --git a/src/parts source/kOS1m dev/Assets/Materials/model001.png.meta b/src/parts source/kOS1m dev/Assets/Materials/model001.png.meta new file mode 100644 index 000000000..d38a7cdfc --- /dev/null +++ b/src/parts source/kOS1m dev/Assets/Materials/model001.png.meta @@ -0,0 +1,55 @@ +fileFormatVersion: 2 +guid: e92cc9ff9bc6941ccb6da6df5ad7df92 +timeCreated: 1431177905 +licenseType: Free +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + linearTexture: 0 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: .25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 8 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -1 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: -1 + mipBias: -1 + wrapMode: -1 + nPOTScale: 1 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: .5, y: .5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 0 + textureType: -1 + buildTargetSettings: [] + spriteSheet: + sprites: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/parts source/kOS1m dev/Assets/Materials/model002.png b/src/parts source/kOS1m dev/Assets/Materials/model002.png new file mode 100644 index 000000000..8f500f0df Binary files /dev/null and b/src/parts source/kOS1m dev/Assets/Materials/model002.png differ diff --git a/src/parts source/kOS1m dev/Assets/Materials/model002.png.meta b/src/parts source/kOS1m dev/Assets/Materials/model002.png.meta new file mode 100644 index 000000000..f8897912a --- /dev/null +++ b/src/parts source/kOS1m dev/Assets/Materials/model002.png.meta @@ -0,0 +1,55 @@ +fileFormatVersion: 2 +guid: 6a1dcf36ac9c44de794a039913a2f4f4 +timeCreated: 1431180860 +licenseType: Free +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + linearTexture: 0 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: .25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 8 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -1 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: -1 + mipBias: -1 + wrapMode: -1 + nPOTScale: 1 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: .5, y: .5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 0 + textureType: 0 + buildTargetSettings: [] + spriteSheet: + sprites: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/parts source/kOS1m dev/Assets/Materials/unnamed.mat b/src/parts source/kOS1m dev/Assets/Materials/unnamed.mat new file mode 100644 index 000000000..fd9dddcb4 Binary files /dev/null and b/src/parts source/kOS1m dev/Assets/Materials/unnamed.mat differ diff --git a/src/parts source/kOS1m dev/Assets/Materials/unnamed.mat.meta b/src/parts source/kOS1m dev/Assets/Materials/unnamed.mat.meta new file mode 100644 index 000000000..5acdaba22 --- /dev/null +++ b/src/parts source/kOS1m dev/Assets/Materials/unnamed.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 9e4e0691e1f0c42feb10f4519cbf8237 +timeCreated: 1431174478 +licenseType: Free +NativeFormatImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/parts source/kOS1m dev/Assets/PartTools.meta b/src/parts source/kOS1m dev/Assets/PartTools.meta new file mode 100644 index 000000000..8b4b55ade --- /dev/null +++ b/src/parts source/kOS1m dev/Assets/PartTools.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 7361ac65e97d94f3ba48328c740c0b68 +folderAsset: yes +timeCreated: 1431175221 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/parts source/kOS1m dev/Assets/kOSMachine1m.dae b/src/parts source/kOS1m dev/Assets/kOSMachine1m.dae new file mode 100644 index 000000000..a49bc321c --- /dev/null +++ b/src/parts source/kOS1m dev/Assets/kOSMachine1m.dae @@ -0,0 +1,340 @@ + + + + + Blender User + Blender 2.73.0 commit date:2015-01-20, commit time:18:16, hash:bbf09d9 + + 2015-05-09T08:26:29 + 2015-05-09T08:26:29 + + Z_UP + + + + + + + 49.13434 + 1.777778 + 0.1 + 100 + + + + + + 0 + 0 + 0 + + + + + + + + + 1 1 1 + 1 + 0 + 0.00111109 + + + + + 0.000999987 + 1 + 0.1 + 0.1 + 1 + 1 + 1 + 2 + 0 + 1 + 1 + 1 + 1 + 1 + 0 + 2880 + 2 + 30.002 + 1.000799 + 0.04999995 + 29.99998 + 1 + 2 + 0 + 0 + 1 + 1 + 1 + 1 + 8192 + 1 + 1 + 0 + 1 + 1 + 1 + 3 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 1 + 3 + 0.15 + 75 + 1 + 1 + 0 + 1 + 1 + 0 + + + + + + + 1 1 1 + 1 + 0 + 0.001599967 + + + + + 0.000999987 + 0 + 0.1 + 0.1 + 0.1 + 1 + 1 + 2 + 0 + 1 + 1 + 1 + 1 + 1 + 0 + 512 + 2 + 40 + 0.5 + 0.04999995 + 25 + 1 + 2 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 1 + 3 + 0 + 0 + 0 + 0 + 2 + 1 + 1 + 1 + 3 + 0.15 + 45 + 1 + 1 + 0 + 1 + 1 + 4 + + + + + + + + + + + + 0 0 0 1 + + + 0 0 0 1 + + + 0.64 0.64 0.64 1 + + + 0.5 0.5 0.5 1 + + + 50 + + + 1 + + + + + + + + + + + + + + + + 0 -0.1 0.45 -0.08779096 0.1 0.441353 0 0.1 0.45 -0.08779096 -0.1 0.441353 -0.08779096 -0.1 0.441353 -0.172208 0.1 0.415746 -0.08779096 0.1 0.441353 -0.172208 -0.1 0.415746 -0.172208 -0.1 0.415746 -0.250007 0.1 0.374161 -0.172208 0.1 0.415746 -0.250007 -0.1 0.374161 -0.250007 -0.1 0.374161 -0.318198 0.1 0.318198 -0.250007 0.1 0.374161 -0.318198 -0.1 0.318198 -0.318198 -0.1 0.318198 -0.374161 0.1 0.250007 -0.318198 0.1 0.318198 -0.374161 -0.1 0.250007 -0.374161 -0.1 0.250007 -0.415746 0.1 0.172208 -0.374161 0.1 0.250007 -0.415746 -0.1 0.172208 -0.415746 -0.1 0.172208 -0.441353 0.1 0.08779096 -0.415746 0.1 0.172208 -0.441353 -0.1 0.08779096 -0.441353 -0.1 0.08779096 -0.45 0.1 0 -0.441353 0.1 0.08779096 -0.45 -0.1 0 -0.45 -0.1 0 -0.441353 0.1 -0.08779096 -0.45 0.1 0 -0.441353 -0.1 -0.08779096 -0.441353 -0.1 -0.08779096 -0.415746 0.1 -0.1722069 -0.441353 0.1 -0.08779096 -0.415746 -0.1 -0.1722069 -0.415746 -0.1 -0.1722069 -0.374161 0.1 -0.250007 -0.415746 0.1 -0.1722069 -0.374161 -0.1 -0.250007 -0.374161 -0.1 -0.250007 -0.318198 0.1 -0.318198 -0.374161 0.1 -0.250007 -0.318198 -0.1 -0.318198 -0.318198 -0.1 -0.318198 -0.250007 0.1 -0.374161 -0.318198 0.1 -0.318198 -0.250007 -0.1 -0.374161 -0.250007 -0.1 -0.374161 -0.1722069 0.1 -0.415746 -0.250007 0.1 -0.374161 -0.1722069 -0.1 -0.415746 -0.1722069 -0.1 -0.415746 -0.08779096 0.1 -0.441353 -0.1722069 0.1 -0.415746 -0.08779096 -0.1 -0.441353 -0.08779096 -0.1 -0.441353 0 0.1 -0.45 -0.08779096 0.1 -0.441353 0 -0.1 -0.45 0 -0.1 -0.45 0.08779096 0.1 -0.441353 0 0.1 -0.45 0.08779096 -0.1 -0.441353 0.08779096 -0.1 -0.441353 0.172208 0.1 -0.415746 0.08779096 0.1 -0.441353 0.172208 -0.1 -0.415746 0.172208 -0.1 -0.415746 0.250007 0.1 -0.374161 0.172208 0.1 -0.415746 0.250007 -0.1 -0.374161 0.250007 -0.1 -0.374161 0.318198 0.1 -0.318198 0.250007 0.1 -0.374161 0.318198 -0.1 -0.318198 0.318198 -0.1 -0.318198 0.374161 0.1 -0.250006 0.318198 0.1 -0.318198 0.374161 -0.1 -0.250006 0.374161 -0.1 -0.250006 0.415746 0.1 -0.1722069 0.374161 0.1 -0.250006 0.415746 -0.1 -0.1722069 0.415746 -0.1 -0.1722069 0.441353 0.1 -0.08778995 0.415746 0.1 -0.1722069 0.441353 -0.1 -0.08778995 0.441353 -0.1 -0.08778995 0.45 0.1 0 0.441353 0.1 -0.08778995 0.45 -0.1 0 0.45 -0.1 0 0.441353 0.1 0.08779096 0.45 0.1 0 0.441353 -0.1 0.08779096 0.441353 -0.1 0.08779096 0.415746 0.1 0.172208 0.441353 0.1 0.08779096 0.415746 -0.1 0.172208 0.415746 -0.1 0.172208 0.374161 0.1 0.250007 0.415746 0.1 0.172208 0.374161 -0.1 0.250007 0.374161 -0.1 0.250007 0.318198 0.1 0.318198 0.374161 0.1 0.250007 0.318198 -0.1 0.318198 0.318198 -0.1 0.318198 0.250006 0.1 0.374162 0.318198 0.1 0.318198 0.250006 -0.1 0.374162 0.250006 -0.1 0.374162 0.1722069 0.1 0.415746 0.250006 0.1 0.374162 0.1722069 -0.1 0.415746 -0.08779096 0.1 0.441353 0.08778995 0.1 0.441353 0 0.1 0.45 0.1722069 0.1 0.415746 -0.172208 0.1 0.415746 0.250006 0.1 0.374162 -0.250007 0.1 0.374161 0.318198 0.1 0.318198 -0.318198 0.1 0.318198 0.374161 0.1 0.250007 -0.374161 0.1 0.250007 0.415746 0.1 0.172208 -0.415746 0.1 0.172208 0.441353 0.1 0.08779096 -0.441353 0.1 0.08779096 0.45 0.1 0 -0.45 0.1 0 0.441353 0.1 -0.08778995 -0.441353 0.1 -0.08779096 0.415746 0.1 -0.1722069 -0.415746 0.1 -0.1722069 0.374161 0.1 -0.250006 -0.374161 0.1 -0.250007 0.318198 0.1 -0.318198 -0.318198 0.1 -0.318198 0.250007 0.1 -0.374161 -0.250007 0.1 -0.374161 0.172208 0.1 -0.415746 -0.1722069 0.1 -0.415746 0.08779096 0.1 -0.441353 -0.08779096 0.1 -0.441353 0 0.1 -0.45 0 0.1 0.45 0.08778995 -0.1 0.441353 0 -0.1 0.45 0.08778995 0.1 0.441353 0.1722069 -0.1 0.415746 0.08778995 0.1 0.441353 0.1722069 0.1 0.415746 0.08778995 -0.1 0.441353 0 -0.1 0.45 0.08778995 -0.1 0.441353 -0.08779096 -0.1 0.441353 0.1722069 -0.1 0.415746 -0.172208 -0.1 0.415746 0.250006 -0.1 0.374162 -0.250007 -0.1 0.374161 0.318198 -0.1 0.318198 -0.318198 -0.1 0.318198 0.374161 -0.1 0.250007 -0.374161 -0.1 0.250007 0.415746 -0.1 0.172208 -0.415746 -0.1 0.172208 0.441353 -0.1 0.08779096 -0.441353 -0.1 0.08779096 0.45 -0.1 0 -0.45 -0.1 0 0.441353 -0.1 -0.08778995 -0.441353 -0.1 -0.08779096 0.415746 -0.1 -0.1722069 -0.415746 -0.1 -0.1722069 0.374161 -0.1 -0.250006 -0.374161 -0.1 -0.250007 0.318198 -0.1 -0.318198 -0.318198 -0.1 -0.318198 0.250007 -0.1 -0.374161 -0.250007 -0.1 -0.374161 0.172208 -0.1 -0.415746 -0.1722069 -0.1 -0.415746 0.08779096 -0.1 -0.441353 -0.08779096 -0.1 -0.441353 0 -0.1 -0.45 + + + + + + + + + + -0.09799492 0 0.9951781 -0.09799492 0 0.9951781 -0.09799492 0 0.9951781 -0.09799492 0 0.9951781 -0.2902615 0 0.9569384 -0.2902615 0 0.9569384 -0.2902615 0 0.9569384 -0.2902615 0 0.9569384 -0.4713889 0 0.8818934 -0.4713889 0 0.8818934 -0.4713889 0 0.8818934 -0.4713889 0 0.8818934 -0.6343883 0 0.7730033 -0.6343883 0 0.7730033 -0.6343883 0 0.7730033 -0.6343883 0 0.7730033 -0.7730033 0 0.6343883 -0.7730033 0 0.6343883 -0.7730033 0 0.6343883 -0.7730033 0 0.6343883 -0.8818934 0 0.4713889 -0.8818934 0 0.4713889 -0.8818934 0 0.4713889 -0.8818934 0 0.4713889 -0.9569384 0 0.2902615 -0.9569384 0 0.2902615 -0.9569384 0 0.2902615 -0.9569384 0 0.2902615 -0.9951781 0 0.09799492 -0.9951781 0 0.09799492 -0.9951781 0 0.09799492 -0.9951781 0 0.09799492 -0.9951781 0 -0.09799492 -0.9951781 0 -0.09799492 -0.9951781 0 -0.09799492 -0.9951781 0 -0.09799492 -0.9569384 0 -0.2902615 -0.9569384 0 -0.2902615 -0.9569384 0 -0.2902615 -0.9569384 0 -0.2902615 -0.8818934 0 -0.4713889 -0.8818934 0 -0.4713889 -0.8818934 0 -0.4713889 -0.8818934 0 -0.4713889 -0.7730033 0 -0.6343883 -0.7730033 0 -0.6343883 -0.7730033 0 -0.6343883 -0.7730033 0 -0.6343883 -0.6343883 0 -0.7730033 -0.6343883 0 -0.7730033 -0.6343883 0 -0.7730033 -0.6343883 0 -0.7730033 -0.4713889 0 -0.8818934 -0.4713889 0 -0.8818934 -0.4713889 0 -0.8818934 -0.4713889 0 -0.8818934 -0.2902615 0 -0.9569384 -0.2902615 0 -0.9569384 -0.2902615 0 -0.9569384 -0.2902615 0 -0.9569384 -0.09799492 0 -0.9951781 -0.09799492 0 -0.9951781 -0.09799492 0 -0.9951781 -0.09799492 0 -0.9951781 0.09799492 0 -0.9951781 0.09799492 0 -0.9951781 0.09799492 0 -0.9951781 0.09799492 0 -0.9951781 0.2902615 0 -0.9569384 0.2902615 0 -0.9569384 0.2902615 0 -0.9569384 0.2902615 0 -0.9569384 0.4713889 0 -0.8818934 0.4713889 0 -0.8818934 0.4713889 0 -0.8818934 0.4713889 0 -0.8818934 0.6343883 0 -0.7730033 0.6343883 0 -0.7730033 0.6343883 0 -0.7730033 0.6343883 0 -0.7730033 0.7730033 0 -0.6343883 0.7730033 0 -0.6343883 0.7730033 0 -0.6343883 0.7730033 0 -0.6343883 0.8818934 0 -0.4713889 0.8818934 0 -0.4713889 0.8818934 0 -0.4713889 0.8818934 0 -0.4713889 0.9569384 0 -0.2902615 0.9569384 0 -0.2902615 0.9569384 0 -0.2902615 0.9569384 0 -0.2902615 0.9951781 0 -0.09799492 0.9951781 0 -0.09799492 0.9951781 0 -0.09799492 0.9951781 0 -0.09799492 0.9951781 0 0.09799492 0.9951781 0 0.09799492 0.9951781 0 0.09799492 0.9951781 0 0.09799492 0.9569384 0 0.2902615 0.9569384 0 0.2902615 0.9569384 0 0.2902615 0.9569384 0 0.2902615 0.8818934 0 0.4713889 0.8818934 0 0.4713889 0.8818934 0 0.4713889 0.8818934 0 0.4713889 0.7730033 0 0.6343883 0.7730033 0 0.6343883 0.7730033 0 0.6343883 0.7730033 0 0.6343883 0.6343883 0 0.7730033 0.6343883 0 0.7730033 0.6343883 0 0.7730033 0.6343883 0 0.7730033 0.4713889 0 0.8818934 0.4713889 0 0.8818934 0.4713889 0 0.8818934 0.4713889 0 0.8818934 0 1 0 0 0.9999695 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0.9999695 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0.9999695 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0.09799492 0 0.9951781 0.09799492 0 0.9951781 0.09799492 0 0.9951781 0.09799492 0 0.9951781 0.2902615 0 0.9569384 0.2902615 0 0.9569384 0.2902615 0 0.9569384 0.2902615 0 0.9569384 0 -1 0 0 -0.9999695 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -0.9999695 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -0.9999695 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 + + + + + + + + + + 0.4827008 0.7076991 0.4823486 0.7353461 0.4701541 0.7351908 0.4827008 0.7076991 0.4701541 0.7351908 0.4705063 0.7075438 0.4819946 0.7631602 0.4698001 0.7630048 0.4823468 0.7355132 0.4698001 0.7630048 0.4701524 0.7353578 0.4823468 0.7355132 0.4081793 0.7344012 0.3959848 0.7342458 0.4085315 0.7067542 0.3959848 0.7342458 0.396337 0.7065988 0.4085315 0.7067542 0.4325481 0.7625302 0.4203537 0.7623748 0.4329003 0.7348832 0.4203537 0.7623748 0.4207059 0.7347278 0.4329003 0.7348832 0.3831021 0.7619003 0.3709077 0.7617449 0.3834543 0.7342532 0.3709077 0.7617449 0.3712599 0.7340978 0.3834543 0.7342532 0.3958178 0.7342437 0.3836233 0.7340884 0.39617 0.7065967 0.3836233 0.7340884 0.3839755 0.7064413 0.39617 0.7065967 0.4696331 0.7630027 0.4574387 0.7628473 0.4699854 0.7353557 0.4574387 0.7628473 0.4577909 0.7352003 0.4699854 0.7353557 0.4452639 0.7348737 0.4330694 0.7347183 0.4456162 0.7072266 0.4330694 0.7347183 0.4334216 0.7070713 0.4456162 0.7072266 0.4329024 0.7347162 0.4207079 0.7345608 0.4332547 0.7070692 0.4207079 0.7345608 0.4210601 0.7069138 0.4332547 0.7070692 0.3460178 0.7614278 0.3338235 0.7612724 0.3463701 0.7337808 0.3338235 0.7612724 0.3341757 0.7336254 0.3463701 0.7337808 0.5317951 0.7359761 0.5196005 0.7358208 0.5321473 0.7083291 0.5196005 0.7358208 0.5199527 0.7081737 0.5321473 0.7083291 0.4201865 0.7623727 0.4079921 0.7622174 0.4205387 0.7347257 0.4079921 0.7622174 0.4083443 0.7345703 0.4205387 0.7347257 0.3707407 0.7617428 0.3585463 0.7615874 0.3710929 0.7340957 0.3585463 0.7615874 0.3588985 0.7339404 0.3710929 0.7340957 0.5194334 0.7358186 0.5072388 0.7356632 0.5197857 0.7081716 0.5072388 0.7356632 0.507591 0.7080162 0.5197857 0.7081716 0.3463718 0.7336137 0.3341775 0.7334584 0.346724 0.7059667 0.3341775 0.7334584 0.3345297 0.7058113 0.346724 0.7059667 0.4947102 0.7355036 0.4825156 0.7353482 0.4950624 0.7078566 0.4825156 0.7353482 0.4828678 0.7077012 0.4950624 0.7078566 0.469987 0.7351886 0.4577925 0.7350333 0.4703392 0.7075417 0.4577925 0.7350333 0.4581448 0.7073863 0.4703392 0.7075417 0.5067176 0.7634751 0.4945232 0.7633198 0.5070698 0.7358281 0.4945232 0.7633198 0.4948754 0.7356728 0.5070698 0.7358281 0.3834563 0.7340862 0.3712617 0.7339308 0.3838085 0.7064392 0.3712617 0.7339308 0.371614 0.7062839 0.3838085 0.7064392 0.3954635 0.7620577 0.3832691 0.7619024 0.3958157 0.7344107 0.3832691 0.7619024 0.3836214 0.7342553 0.3958157 0.7344107 0.4205408 0.7345587 0.4083464 0.7344033 0.4208931 0.7069116 0.4083464 0.7344033 0.4086986 0.7067563 0.4208931 0.7069116 0.5314407 0.7637901 0.5192462 0.7636348 0.5317929 0.7361431 0.5192462 0.7636348 0.5195984 0.7359877 0.5317929 0.7361431 0.4943561 0.7633177 0.4821616 0.7631623 0.4947083 0.7356706 0.4821616 0.7631623 0.4825139 0.7355153 0.4947083 0.7356706 0.3587332 0.7337712 0.3465389 0.7336159 0.3590855 0.7061243 0.3465389 0.7336159 0.3468911 0.7059689 0.3590855 0.7061243 0.4576255 0.7350311 0.445431 0.7348757 0.4579777 0.7073841 0.445431 0.7348757 0.4457833 0.7072288 0.4579777 0.7073841 0.4572711 0.7628452 0.4450767 0.7626898 0.4576234 0.7351981 0.4450767 0.7626898 0.4454289 0.7350428 0.4576234 0.7351981 0.3710947 0.7339287 0.3589002 0.7337734 0.371447 0.7062817 0.3589002 0.7337734 0.3592524 0.7061263 0.371447 0.7062817 0.4078249 0.7622152 0.3956305 0.7620599 0.4081771 0.7345682 0.3956305 0.7620599 0.3959828 0.7344129 0.4081771 0.7345682 0.5070718 0.7356612 0.4948772 0.7355058 0.507424 0.7080141 0.4948772 0.7355058 0.4952294 0.7078588 0.507424 0.7080141 0.4449096 0.7626877 0.4327152 0.7625324 0.4452619 0.7350407 0.4327152 0.7625324 0.4330675 0.7348853 0.4452619 0.7350407 0.5189511 0.3171389 0.5350208 0.3064016 0.5052849 0.3308052 0.5350208 0.3064016 0.5528766 0.2990053 0.5052849 0.3308052 0.5528766 0.2990053 0.4945474 0.3468747 0.5052849 0.3308052 0.571832 0.2952348 0.4945474 0.3468747 0.5528766 0.2990053 0.4871514 0.3647305 0.4945474 0.3468747 0.571832 0.2952348 0.5911591 0.2952349 0.4871514 0.3647305 0.571832 0.2952348 0.4833809 0.383686 0.4871514 0.3647305 0.5911591 0.2952349 0.6101145 0.2990053 0.4833809 0.383686 0.5911591 0.2952349 0.4833809 0.4030128 0.4833809 0.383686 0.6101145 0.2990053 0.6279702 0.3064013 0.4833809 0.4030128 0.6101145 0.2990053 0.4871513 0.4219684 0.4833809 0.4030128 0.6279702 0.3064013 0.6440399 0.3171389 0.4871513 0.4219684 0.6279702 0.3064013 0.4945475 0.4398241 0.4871513 0.4219684 0.6440399 0.3171389 0.6577062 0.3308051 0.4945475 0.4398241 0.6440399 0.3171389 0.505285 0.4558939 0.4945475 0.4398241 0.6577062 0.3308051 0.6684435 0.3468747 0.505285 0.4558939 0.6577062 0.3308051 0.5189513 0.4695601 0.505285 0.4558939 0.6684435 0.3468747 0.6758396 0.3647302 0.5189513 0.4695601 0.6684435 0.3468747 0.5350208 0.4802975 0.5189513 0.4695601 0.6758396 0.3647302 0.6796101 0.3836858 0.5350208 0.4802975 0.6758396 0.3647302 0.5528768 0.4876936 0.5350208 0.4802975 0.6796101 0.3836858 0.6796101 0.4030128 0.5528768 0.4876936 0.6796101 0.3836858 0.5718322 0.491464 0.5528768 0.4876936 0.6796101 0.4030128 0.6758398 0.4219682 0.5718322 0.491464 0.6796101 0.4030128 0.5911591 0.491464 0.5718322 0.491464 0.6758398 0.4219682 0.6684438 0.439824 0.5911591 0.491464 0.6758398 0.4219682 0.6101148 0.4876936 0.5911591 0.491464 0.6684438 0.439824 0.6577064 0.4558935 0.6101148 0.4876936 0.6684438 0.439824 0.6279703 0.4802974 0.6101148 0.4876936 0.6577064 0.4558935 0.6440402 0.4695599 0.6279703 0.4802974 0.6577064 0.4558935 0.3465371 0.7337829 0.3587315 0.7339382 0.3461848 0.7614299 0.3587315 0.7339382 0.3583793 0.7615852 0.3461848 0.7614299 0.519079 0.7636327 0.5068846 0.7634773 0.5194313 0.7359856 0.5068846 0.7634773 0.5072368 0.7358303 0.5194313 0.7359856 0.8762223 0.2625701 0.9071549 0.2371844 0.8929389 0.2514006 0.9183247 0.220468 0.9071549 0.2371844 0.8762223 0.2625701 0.857648 0.2702639 0.9183247 0.220468 0.8762223 0.2625701 0.9260185 0.2018937 0.9183247 0.220468 0.857648 0.2702639 0.8379296 0.274186 0.9260185 0.2018937 0.857648 0.2702639 0.9299408 0.1821751 0.9260185 0.2018937 0.8379296 0.274186 0.817825 0.274186 0.9299408 0.1821751 0.8379296 0.274186 0.9299409 0.1620705 0.9299408 0.1821751 0.817825 0.274186 0.7981067 0.2702637 0.9299409 0.1620705 0.817825 0.274186 0.9260187 0.1423519 0.9299409 0.1620705 0.7981067 0.2702637 0.7795322 0.26257 0.9260187 0.1423519 0.7981067 0.2702637 0.9183249 0.1237776 0.9260187 0.1423519 0.7795322 0.26257 0.7628158 0.2514003 0.9183249 0.1237776 0.7795322 0.26257 0.9071553 0.107061 0.9183249 0.1237776 0.7628158 0.2514003 0.7485997 0.2371841 0.9071553 0.107061 0.7628158 0.2514003 0.8929392 0.09284496 0.9071553 0.107061 0.7485997 0.2371841 0.73743 0.2204676 0.8929392 0.09284496 0.7485997 0.2371841 0.8762227 0.08167523 0.8929392 0.09284496 0.73743 0.2204676 0.7297363 0.2018935 0.8762227 0.08167523 0.73743 0.2204676 0.8576483 0.07398158 0.8762227 0.08167523 0.7297363 0.2018935 0.7258141 0.1821749 0.8576483 0.07398158 0.7297363 0.2018935 0.8379297 0.07005918 0.8576483 0.07398158 0.7258141 0.1821749 0.7258141 0.1620703 0.8379297 0.07005918 0.7258141 0.1821749 0.8178251 0.07005918 0.8379297 0.07005918 0.7258141 0.1620703 0.7297363 0.142352 0.8178251 0.07005918 0.7258141 0.1620703 0.7981066 0.07398134 0.8178251 0.07005918 0.7297363 0.142352 0.73743 0.1237774 0.7981066 0.07398134 0.7297363 0.142352 0.7795324 0.08167523 0.7981066 0.07398134 0.73743 0.1237774 0.7485995 0.1070613 0.7795324 0.08167523 0.73743 0.1237774 0.7628157 0.09284496 0.7795324 0.08167523 0.7485995 0.1070613 + + + + + + + + + + + + + + + 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 +

0 0 0 2 1 1 1 2 2 0 0 3 1 2 4 3 3 5 6 4 6 5 5 7 4 6 8 5 5 9 7 7 10 4 6 11 10 8 12 9 9 13 8 10 14 9 9 15 11 11 16 8 10 17 14 12 18 13 13 19 12 14 20 13 13 21 15 15 22 12 14 23 18 16 24 17 17 25 16 18 26 17 17 27 19 19 28 16 18 29 22 20 30 21 21 31 20 22 32 21 21 33 23 23 34 20 22 35 26 24 36 25 25 37 24 26 38 25 25 39 27 27 40 24 26 41 30 28 42 29 29 43 28 30 44 29 29 45 31 31 46 28 30 47 34 32 48 33 33 49 32 34 50 33 33 51 35 35 52 32 34 53 38 36 54 37 37 55 36 38 56 37 37 57 39 39 58 36 38 59 42 40 60 41 41 61 40 42 62 41 41 63 43 43 64 40 42 65 46 44 66 45 45 67 44 46 68 45 45 69 47 47 70 44 46 71 50 48 72 49 49 73 48 50 74 49 49 75 51 51 76 48 50 77 54 52 78 53 53 79 52 54 80 53 53 81 55 55 82 52 54 83 58 56 84 57 57 85 56 58 86 57 57 87 59 59 88 56 58 89 62 60 90 61 61 91 60 62 92 61 61 93 63 63 94 60 62 95 66 64 96 65 65 97 64 66 98 65 65 99 67 67 100 64 66 101 70 68 102 69 69 103 68 70 104 69 69 105 71 71 106 68 70 107 74 72 108 73 73 109 72 74 110 73 73 111 75 75 112 72 74 113 78 76 114 77 77 115 76 78 116 77 77 117 79 79 118 76 78 119 82 80 120 81 81 121 80 82 122 81 81 123 83 83 124 80 82 125 86 84 126 85 85 127 84 86 128 85 85 129 87 87 130 84 86 131 90 88 132 89 89 133 88 90 134 89 89 135 91 91 136 88 90 137 94 92 138 93 93 139 92 94 140 93 93 141 95 95 142 92 94 143 98 96 144 97 97 145 96 98 146 97 97 147 99 99 148 96 98 149 102 100 150 101 101 151 100 102 152 101 101 153 103 103 154 100 102 155 106 104 156 105 105 157 104 106 158 105 105 159 107 107 160 104 106 161 110 108 162 109 109 163 108 110 164 109 109 165 111 111 166 108 110 167 114 112 168 113 113 169 112 114 170 113 113 171 115 115 172 112 114 173 118 116 174 117 117 175 116 118 176 117 117 177 119 119 178 116 118 179 122 120 180 121 121 181 120 122 182 121 121 183 123 123 184 120 122 185 123 123 186 124 124 187 120 122 188 125 125 189 124 124 190 123 123 191 126 126 192 124 124 193 125 125 194 127 127 195 126 126 196 125 125 197 128 128 198 126 126 199 127 127 200 129 129 201 128 128 202 127 127 203 130 130 204 128 128 205 129 129 206 131 131 207 130 130 208 129 129 209 132 132 210 130 130 211 131 131 212 133 133 213 132 132 214 131 131 215 134 134 216 132 132 217 133 133 218 135 135 219 134 134 220 133 133 221 136 136 222 134 134 223 135 135 224 137 137 225 136 136 226 135 135 227 138 138 228 136 136 229 137 137 230 139 139 231 138 138 232 137 137 233 140 140 234 138 138 235 139 139 236 141 141 237 140 140 238 139 139 239 142 142 240 140 140 241 141 141 242 143 143 243 142 142 244 141 141 245 144 144 246 142 142 247 143 143 248 145 145 249 144 144 250 143 143 251 146 146 252 144 144 253 145 145 254 147 147 255 146 146 256 145 145 257 148 148 258 146 146 259 147 147 260 149 149 261 148 148 262 147 147 263 150 150 264 148 148 265 149 149 266 151 151 267 150 150 268 149 149 269 154 152 270 153 153 271 152 154 272 153 153 273 155 155 274 152 154 275 158 156 276 157 157 277 156 158 278 157 157 279 159 159 280 156 158 281 162 160 282 161 161 283 160 162 284 163 163 285 161 161 286 162 160 287 164 164 288 163 163 289 162 160 290 165 165 291 163 163 292 164 164 293 166 166 294 165 165 295 164 164 296 167 167 297 165 165 298 166 166 299 168 168 300 167 167 301 166 166 302 169 169 303 167 167 304 168 168 305 170 170 306 169 169 307 168 168 308 171 171 309 169 169 310 170 170 311 172 172 312 171 171 313 170 170 314 173 173 315 171 171 316 172 172 317 174 174 318 173 173 319 172 172 320 175 175 321 173 173 322 174 174 323 176 176 324 175 175 325 174 174 326 177 177 327 175 175 328 176 176 329 178 178 330 177 177 331 176 176 332 179 179 333 177 177 334 178 178 335 180 180 336 179 179 337 178 178 338 181 181 339 179 179 340 180 180 341 182 182 342 181 181 343 180 180 344 183 183 345 181 181 346 182 182 347 184 184 348 183 183 349 182 182 350 185 185 351 183 183 352 184 184 353 186 186 354 185 185 355 184 184 356 187 187 357 185 185 358 186 186 359 188 188 360 187 187 361 186 186 362 189 189 363 187 187 364 188 188 365 190 190 366 189 189 367 188 188 368 191 191 369 189 189 370 190 190 371

+
+
+
+ + + + 0.4829 -0.14 10e-7 0.475563 0.14 0.08385497 0.4829 0.14 10e-7 0.475564 -0.14 0.08385497 0.453777 0.14 0.165162 0.453777 -0.14 0.165162 0.418203 0.14 0.24145 0.418204 -0.14 0.24145 0.369923 0.14 0.310402 0.369923 -0.14 0.310402 0.310402 0.14 0.369923 0.310402 -0.14 0.369923 0.24145 0.14 0.418204 0.24145 -0.14 0.418204 0.165161 0.14 0.453778 0.165161 -0.14 0.453778 0.08385396 0.14 0.475564 0.08385396 -0.14 0.475564 0.475564 -0.14 -0.083853 0.453778 -0.14 -0.16516 0.475563 0.14 -0.083853 0.453778 0.14 -0.16516 0.418204 -0.14 -0.2414489 0.418204 0.14 -0.2414489 0.369923 -0.14 -0.310401 0.369923 0.14 -0.310401 0.310403 -0.14 -0.369922 0.310403 0.14 -0.369922 0.241451 -0.14 -0.418203 0.241451 0.14 -0.418203 0.165162 -0.14 -0.453777 0.165162 0.14 -0.453777 0.08385598 -0.14 -0.475564 0.08385598 0.14 -0.475563 10e-7 -0.14 -0.4829 10e-7 0.14 -0.4829 -0.08385396 -0.14 -0.475564 -0.08385396 0.14 -0.475564 0.4829 0.14 10e-7 0.406627 0.14 0.07169896 0.4129 0.14 0 0.475563 0.14 0.08385497 0.387999 0.14 0.14122 0.453777 0.14 0.165162 0.357582 0.14 0.20645 0.418203 0.14 0.24145 0.316299 0.14 0.265407 0.369923 0.14 0.310402 0.265407 0.14 0.3163 0.310402 0.14 0.369923 0.20645 0.14 0.357582 0.24145 0.14 0.418204 0.14122 0.14 0.387999 0.165161 0.14 0.453778 0.07169896 0.14 0.406627 0.08385396 0.14 0.475564 0 0.14 0.4129 -10e-7 0.14 0.4829 -0.07169997 0.14 0.406627 -0.08385497 0.14 0.475563 -0.141221 0.14 0.387999 -0.165162 0.14 0.453777 -0.20645 0.14 0.357582 -0.241451 0.14 0.418203 -0.265407 0.14 0.316299 -0.310403 0.14 0.369922 -0.3163 0.14 0.265407 -0.369923 0.14 0.310402 -0.357582 0.14 0.206449 -0.418204 0.14 0.2414489 -0.387999 0.14 0.14122 -0.453778 0.14 0.165161 -0.406627 0.14 0.07169896 -0.475564 0.14 0.08385396 -0.4129 0.14 -10e-7 -0.4829 0.14 -10e-7 -0.406627 0.14 -0.07169997 -0.475564 0.14 -0.08385497 -0.387999 0.14 -0.141221 -0.453777 0.14 -0.165162 -0.357582 0.14 -0.2064509 -0.418203 0.14 -0.241451 -0.316299 0.14 -0.265408 -0.369922 0.14 -0.310403 -0.265407 0.14 -0.3163 -0.310402 0.14 -0.369923 -0.206449 0.14 -0.357582 -0.2414489 0.14 -0.418204 -0.141219 0.14 -0.387999 -0.165161 0.14 -0.453778 -0.07169896 0.14 -0.406627 -0.08385396 0.14 -0.475564 10e-7 0.14 -0.4129 10e-7 0.14 -0.4829 0.07169997 0.14 -0.406627 0.08385598 0.14 -0.475563 0.141221 0.14 -0.387999 0.165162 0.14 -0.453777 0.2064509 0.14 -0.357581 0.241451 0.14 -0.418203 0.265408 0.14 -0.316299 0.310403 0.14 -0.369922 0.3163 0.14 -0.265406 0.369923 0.14 -0.310401 0.357582 0.14 -0.206449 0.418204 0.14 -0.2414489 0.387999 0.14 -0.141219 0.453778 0.14 -0.16516 0.406627 0.14 -0.071698 0.475563 0.14 -0.083853 0.4129 0.14 0 0.406627 -0.14 0.07169896 0.4129 -0.14 10e-7 0.406627 0.14 0.07169896 0.387999 -0.14 0.14122 0.387999 0.14 0.14122 0.357582 -0.14 0.20645 0.357582 0.14 0.20645 0.3163 -0.14 0.265407 0.316299 0.14 0.265407 0.265407 -0.14 0.3163 0.265407 0.14 0.3163 0.20645 -0.14 0.357582 0.20645 0.14 0.357582 0.14122 -0.14 0.387999 0.14122 0.14 0.387999 0.07169896 -0.14 0.406627 0.07169896 0.14 0.406627 0.4829 -0.14 10e-7 0.406627 -0.14 0.07169896 0.475564 -0.14 0.08385497 0.4129 -0.14 10e-7 0.387999 -0.14 0.14122 0.453777 -0.14 0.165162 0.357582 -0.14 0.20645 0.418204 -0.14 0.24145 0.3163 -0.14 0.265407 0.369923 -0.14 0.310402 0.265407 -0.14 0.3163 0.310402 -0.14 0.369923 0.20645 -0.14 0.357582 0.24145 -0.14 0.418204 0.14122 -0.14 0.387999 0.165161 -0.14 0.453778 0.07169896 -0.14 0.406627 0.08385396 -0.14 0.475564 0 -0.14 0.4129 -10e-7 -0.14 0.4829 -0.07169997 -0.14 0.406627 -0.08385497 -0.14 0.475564 -0.141221 -0.14 0.387999 -0.165162 -0.14 0.453777 -0.20645 -0.14 0.357582 -0.241451 -0.14 0.418203 -0.265407 -0.14 0.316299 -0.310403 -0.14 0.369923 -0.3163 -0.14 0.265407 -0.369923 -0.14 0.310402 -0.357582 -0.14 0.20645 -0.418204 -0.14 0.2414489 -0.387999 -0.14 0.14122 -0.453778 -0.14 0.165161 -0.406627 -0.14 0.07169896 -0.475564 -0.14 0.08385396 -0.4129 -0.14 -10e-7 -0.4829 -0.14 -10e-7 -0.406627 -0.14 -0.07169997 -0.475564 -0.14 -0.08385598 -0.387999 -0.14 -0.141221 -0.453778 -0.14 -0.165162 -0.357582 -0.14 -0.2064509 -0.418203 -0.14 -0.241451 -0.316299 -0.14 -0.265408 -0.369923 -0.14 -0.310403 -0.265407 -0.14 -0.3163 -0.310402 -0.14 -0.369924 -0.206449 -0.14 -0.357582 -0.2414489 -0.14 -0.418204 -0.141219 -0.14 -0.387999 -0.165161 -0.14 -0.453778 -0.07169896 -0.14 -0.406627 -0.08385396 -0.14 -0.475564 10e-7 -0.14 -0.4129 10e-7 -0.14 -0.4829 0.07169997 -0.14 -0.406627 0.08385598 -0.14 -0.475564 0.141221 -0.14 -0.387999 0.165162 -0.14 -0.453777 0.2064509 -0.14 -0.357581 0.241451 -0.14 -0.418203 0.265408 -0.14 -0.316299 0.310403 -0.14 -0.369922 0.3163 -0.14 -0.265406 0.369923 -0.14 -0.310401 0.357582 -0.14 -0.206449 0.418204 -0.14 -0.2414489 0.387999 -0.14 -0.141219 0.453778 -0.14 -0.16516 0.406627 -0.14 -0.071698 0.475564 -0.14 -0.083853 0.08385396 -0.14 0.475564 -10e-7 0.14 0.4829 0.08385396 0.14 0.475564 -10e-7 -0.14 0.4829 -0.08385497 0.14 0.475563 -0.08385497 -0.14 0.475564 -0.165162 0.14 0.453777 -0.165162 -0.14 0.453777 -0.241451 0.14 0.418203 -0.241451 -0.14 0.418203 -0.310403 0.14 0.369922 -0.310403 -0.14 0.369923 -0.369923 0.14 0.310402 -0.369923 -0.14 0.310402 -0.418204 0.14 0.2414489 -0.418204 -0.14 0.2414489 -0.453778 0.14 0.165161 -0.453778 -0.14 0.165161 -0.475564 0.14 0.08385396 -0.475564 -0.14 0.08385396 -0.4829 0.14 -10e-7 -0.4829 -0.14 -10e-7 -0.475564 0.14 -0.08385497 -0.475564 -0.14 -0.08385598 -0.453777 0.14 -0.165162 -0.453778 -0.14 -0.165162 -0.418203 0.14 -0.241451 -0.418203 -0.14 -0.241451 -0.369922 0.14 -0.310403 -0.369923 -0.14 -0.310403 -0.310402 0.14 -0.369923 -0.310402 -0.14 -0.369924 -0.2414489 0.14 -0.418204 -0.2414489 -0.14 -0.418204 -0.165161 0.14 -0.453778 -0.165161 -0.14 -0.453778 -0.08385396 0.14 -0.475564 -0.08385396 -0.14 -0.475564 0.07169896 0.14 0.406627 0 -0.14 0.4129 0.07169896 -0.14 0.406627 0 0.14 0.4129 -0.07169997 -0.14 0.406627 -0.07169997 0.14 0.406627 -0.141221 -0.14 0.387999 -0.141221 0.14 0.387999 -0.20645 -0.14 0.357582 -0.20645 0.14 0.357582 -0.265407 -0.14 0.316299 -0.265407 0.14 0.316299 -0.3163 -0.14 0.265407 -0.3163 0.14 0.265407 -0.357582 -0.14 0.20645 -0.357582 0.14 0.206449 -0.387999 -0.14 0.14122 -0.387999 0.14 0.14122 -0.406627 -0.14 0.07169896 -0.406627 0.14 0.07169896 -0.406627 0.14 0.07169896 -0.4129 -0.14 -10e-7 -0.406627 -0.14 0.07169896 -0.4129 0.14 -10e-7 -0.406627 -0.14 -0.07169997 -0.406627 0.14 -0.07169997 -0.387999 -0.14 -0.141221 -0.387999 0.14 -0.141221 -0.357582 -0.14 -0.2064509 -0.357582 0.14 -0.2064509 -0.316299 -0.14 -0.265408 -0.316299 0.14 -0.265408 -0.265407 -0.14 -0.3163 -0.265407 0.14 -0.3163 -0.206449 -0.14 -0.357582 -0.206449 0.14 -0.357582 -0.141219 -0.14 -0.387999 -0.141219 0.14 -0.387999 -0.07169896 -0.14 -0.406627 -0.07169896 0.14 -0.406627 -0.07169896 0.14 -0.406627 10e-7 -0.14 -0.4129 -0.07169896 -0.14 -0.406627 10e-7 0.14 -0.4129 0.07169997 -0.14 -0.406627 0.07169997 0.14 -0.406627 0.141221 -0.14 -0.387999 0.141221 0.14 -0.387999 0.2064509 -0.14 -0.357581 0.2064509 0.14 -0.357581 0.265408 -0.14 -0.316299 0.265408 0.14 -0.316299 0.3163 -0.14 -0.265406 0.3163 0.14 -0.265406 0.357582 -0.14 -0.206449 0.357582 0.14 -0.206449 0.387999 -0.14 -0.141219 0.387999 0.14 -0.141219 0.406627 -0.14 -0.071698 0.406627 0.14 -0.071698 0.406627 0.14 -0.071698 0.4129 -0.14 10e-7 0.406627 -0.14 -0.071698 0.4129 0.14 0 + + + + + + + + + + 1 0 0 1 0 0 0.9848018 0 0.1736503 0.9848018 0 0.1736503 0.9396649 0 0.3420209 0.9396649 0 0.3420209 0.8660237 0 0.4999848 0.8660237 0 0.4999848 0.7660451 0 0.6427809 0.7660146 0 0.6427809 0.6427809 0 0.7660146 0.6427809 0 0.7660146 0.4999848 0 0.8660237 0.4999848 0 0.8660237 0.3419904 0 0.9396649 0.3419904 0 0.9396649 0.2587969 0 0.9659109 0.2587969 0 0.9659109 0.9848018 0 -0.1736198 0.9848018 0 -0.1736198 0.9396649 0 -0.3419904 0.9396649 0 -0.3419904 0.8660237 0 -0.4999848 0.8660237 0 -0.4999848 0.7660451 0 -0.6427809 0.7660451 0 -0.6427809 0.6427809 0 -0.7660146 0.6427809 0 -0.7660146 0.4999848 0 -0.8660237 0.4999848 0 -0.8660237 0.3420209 0 -0.9396649 0.3420209 0 -0.9396649 0.1736503 0 -0.9848018 0.1736503 0 -0.9848018 0 0 -1 0 0 -1 -0.0871303 0 -0.9961852 -0.0871303 0 -0.9961852 0 1 0 0 1 0 0 1 0 0 1 0 0 0.9999695 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0.9999695 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0.9999695 0 0 1 0 0 0.9999695 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0.9999695 0 0 1 0 0 0.9999695 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0.9999695 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0.9999695 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0.9999695 0 0 1 0 -0.9961852 0 -0.0871303 -0.9848018 0 -0.1736198 -0.9961852 0 -0.0871303 -0.9848018 0 -0.1736198 -0.9396649 0 -0.3419904 -0.9396649 0 -0.3419904 -0.8660237 0 -0.4999848 -0.8660237 0 -0.4999848 -0.7660146 0 -0.6427809 -0.7660146 0 -0.6427809 -0.6427809 0 -0.7660146 -0.6427809 0 -0.7660146 -0.4999848 0 -0.8660237 -0.4999848 0 -0.8660237 -0.3419904 0 -0.9396649 -0.3419904 0 -0.9396649 -0.2587969 0 -0.9659109 -0.2587969 0 -0.9659109 0 -0.9999695 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -0.9999695 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -0.9999695 0 0 -1 0 0 -0.9999695 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -0.9999695 0 0 -1 0 0 -1 0 0 -0.9999695 0 0 -1 0 0 -0.9999695 0 0 -1 0 0 -0.9999695 0 0 -1 0 0 -1 0 0 -0.9999695 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -0.9999695 0 0 -1 0 0 -1 0 0 -0.9999695 0 0 -0.9999695 0 0 -0.9999695 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -0.9999695 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -0.9999695 0 0 -0.9999695 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0.0871303 0 0.9961852 0 0 0.9999695 0.0871303 0 0.9961852 0 0 1 -0.1736503 0 0.9848018 -0.1736503 0 0.9848018 -0.3419904 0 0.9396649 -0.3420209 0 0.9396649 -0.4999848 0 0.8660237 -0.4999848 0 0.8660237 -0.6427809 0 0.7660146 -0.6427809 0 0.7660146 -0.7660451 0 0.6427809 -0.7660451 0 0.6427809 -0.8660237 0 0.4999848 -0.8660237 0 0.4999848 -0.9396649 0 0.3420209 -0.9396649 0 0.3419904 -0.9848018 0 0.1736198 -0.9848018 0 0.1736198 -1 0 0 -1 0 0 -0.9848018 0 -0.1736503 -0.9848018 0 -0.1736198 -0.9396649 0 -0.3420209 -0.9396649 0 -0.3420209 -0.8660237 0 -0.4999848 -0.8660237 0 -0.4999848 -0.7660146 0 -0.6427809 -0.7660451 0 -0.6427809 -0.6427809 0 -0.7660451 -0.6427809 0 -0.7660451 -0.4999848 0 -0.8660237 -0.4999848 0 -0.8660237 -0.3420209 0 -0.9396649 -0.3419904 0 -0.9396649 -0.2587969 0 -0.9659109 -0.2587969 0 -0.9659109 -0.0871303 0 -0.9961852 0 0 -1 -0.0871303 0 -0.9961852 0 0 -1 0.1736198 0 -0.9848018 0.1736198 0 -0.9848018 0.3419904 0 -0.9396649 0.3419904 0 -0.9396649 0.4999848 0 -0.8659932 0.4999848 0 -0.8659932 0.6427809 0 -0.7660146 0.6427809 0 -0.7660146 0.7660146 0 -0.6427809 0.7660146 0 -0.6427809 0.8660237 0 -0.4999848 0.8660237 0 -0.4999848 0.9396649 0 -0.3419904 0.9396649 0 -0.3419904 0.9659109 0 -0.2587969 0.9659109 0 -0.2587969 0.9961852 0 -0.0871303 1 0 0 0.9961852 0 -0.0871303 1 0 0 0.9848018 0 0.1736198 0.9848018 0 0.1736198 0.9396649 0 0.3419904 0.9396649 0 0.3419904 0.8660237 0 0.4999848 0.8660237 0 0.4999848 0.7660146 0 0.6427809 0.7660146 0 0.6427809 0.6427809 0 0.7660451 0.6427809 0 0.7660451 0.4999848 0 0.8660237 0.4999848 0 0.8660237 0.3419904 0 0.9396649 0.3419904 0 0.9396649 0.2587969 0 0.9659109 0.2587969 0 0.9659109 0.0871303 0 0.9961852 0 0 1 0.0871303 0 0.9961852 0 0 1 -0.1736198 0 0.9848018 -0.1736198 0 0.9848018 -0.3420209 0 0.9396649 -0.3420209 0 0.9396649 -0.4999848 0 0.8659932 -0.4999848 0 0.8659932 -0.6427809 0 0.7660146 -0.6427809 0 0.7660146 -0.7660451 0 0.6427809 -0.7660451 0 0.6427809 -0.8660237 0 0.4999848 -0.8660237 0 0.4999848 -0.9396649 0 0.3419904 -0.9396649 0 0.3419904 -0.9659109 0 0.2587969 -0.9659109 0 0.2587969 -0.9961852 0 0.0871303 -0.9961852 0 0.0871303 -0.9961852 0 0.0871303 -0.9961852 0 0.0871303 + + + + + + + + + + 0.446618 0.832038 0.446618 0.989969 0.392159 0.989969 0.446618 0.832038 0.392159 0.989969 0.392159 0.832038 0.392159 0.989969 0.3377 0.989969 0.392159 0.832038 0.3377 0.989969 0.3377 0.832038 0.392159 0.832038 0.3377 0.989969 0.283242 0.989969 0.3377 0.832038 0.283242 0.989969 0.283242 0.832038 0.3377 0.832038 0.283242 0.989969 0.228783 0.989969 0.283242 0.832038 0.228783 0.989969 0.228783 0.832038 0.283242 0.832038 0.228783 0.989969 0.174324 0.989969 0.228783 0.832038 0.174324 0.989969 0.174324 0.832038 0.228783 0.832038 0.174324 0.989969 0.119865 0.989969 0.174324 0.832038 0.119865 0.989969 0.119865 0.832038 0.174324 0.832038 0.119865 0.989969 0.06540596 0.989969 0.119865 0.832038 0.06540596 0.989969 0.06540596 0.832038 0.119865 0.832038 0.06540596 0.989969 0.010948 0.989969 0.06540596 0.832038 0.010948 0.989969 0.010948 0.832038 0.06540596 0.832038 0.446618 0.832038 0.501083 0.832038 0.446618 0.989969 0.501083 0.989963 0.501083 0.832038 0.555542 0.832038 0.555542 0.989963 0.501083 0.989963 0.555542 0.832038 0.555542 0.989963 0.555542 0.832038 0.610001 0.832038 0.610001 0.989963 0.555542 0.989963 0.610001 0.832038 0.610001 0.989963 0.610001 0.832038 0.66446 0.832038 0.66446 0.989963 0.610001 0.989963 0.66446 0.832038 0.66446 0.989963 0.66446 0.832038 0.718919 0.832038 0.718919 0.989963 0.66446 0.989963 0.718919 0.832038 0.718919 0.989963 0.718919 0.832038 0.77332 0.832038 0.77332 0.989963 0.718919 0.989963 0.77332 0.832038 0.77332 0.989963 0.77332 0.832038 0.827836 0.832038 0.827836 0.989963 0.77332 0.989963 0.827836 0.832038 0.827836 0.989963 0.827836 0.832038 0.882295 0.832038 0.882295 0.989963 0.827836 0.989963 0.882295 0.832038 0.882295 0.989963 0.882295 0.832038 0.936754 0.832038 0.936754 0.989963 0.882295 0.989963 0.936754 0.832038 0.936754 0.989963 0.936754 0.832038 0.991213 0.832038 0.991213 0.989963 0.936754 0.989963 0.991213 0.832038 0.296563 0.08183699 0.276893 0.06533098 0.314222 0.06417798 0.276893 0.06533098 0.291217 0.04487395 0.314222 0.06417798 0.276893 0.06533098 0.254656 0.05249297 0.291217 0.04487395 0.254656 0.05249297 0.26521 0.029859 0.291217 0.04487395 0.254656 0.05249297 0.230526 0.04370999 0.26521 0.029859 0.230526 0.04370999 0.23699 0.01958799 0.26521 0.029859 0.230526 0.04370999 0.2052389 0.03925096 0.23699 0.01958799 0.2052389 0.03925096 0.207415 0.014373 0.23699 0.01958799 0.2052389 0.03925096 0.179561 0.03925096 0.207415 0.014373 0.179561 0.03925096 0.177384 0.014373 0.207415 0.014373 0.179561 0.03925096 0.154274 0.04370999 0.177384 0.014373 0.154274 0.04370999 0.14781 0.01958799 0.177384 0.014373 0.154274 0.04370999 0.130144 0.05249297 0.14781 0.01958799 0.130144 0.05249297 0.11959 0.029859 0.14781 0.01958799 0.130144 0.05249297 0.1079069 0.06533199 0.11959 0.029859 0.1079069 0.06533199 0.09358298 0.04487395 0.11959 0.029859 0.1079069 0.06533199 0.08823698 0.08183699 0.09358298 0.04487395 0.08823698 0.08183699 0.07057797 0.06417798 0.09358298 0.04487395 0.08823698 0.08183699 0.07173097 0.101507 0.07057797 0.06417798 0.07173097 0.101507 0.051274 0.08718299 0.07057797 0.06417798 0.07173097 0.101507 0.05889296 0.123745 0.051274 0.08718299 0.05889296 0.123745 0.03625899 0.11319 0.051274 0.08718299 0.05889296 0.123745 0.05010998 0.1478739 0.03625899 0.11319 0.05010998 0.1478739 0.02598798 0.1414099 0.03625899 0.11319 0.05010998 0.1478739 0.04565197 0.173161 0.02598798 0.1414099 0.04565197 0.173161 0.02077299 0.170985 0.02598798 0.1414099 0.04565197 0.173161 0.04565197 0.198839 0.02077299 0.170985 0.04565197 0.198839 0.02077299 0.201016 0.02077299 0.170985 0.04565197 0.198839 0.05010998 0.2241269 0.02077299 0.201016 0.05010998 0.2241269 0.02598798 0.23059 0.02077299 0.201016 0.05010998 0.2241269 0.05889296 0.248256 0.02598798 0.23059 0.05889296 0.248256 0.03625899 0.25881 0.02598798 0.23059 0.05889296 0.248256 0.07173198 0.270493 0.03625899 0.25881 0.07173198 0.270493 0.051274 0.284818 0.03625899 0.25881 0.07173198 0.270493 0.08823698 0.290163 0.051274 0.284818 0.08823698 0.290163 0.07057797 0.307822 0.051274 0.284818 0.08823698 0.290163 0.1079069 0.306669 0.07057797 0.307822 0.1079069 0.306669 0.09358298 0.327126 0.07057797 0.307822 0.1079069 0.306669 0.130145 0.319507 0.09358298 0.327126 0.130145 0.319507 0.11959 0.342141 0.09358298 0.327126 0.130145 0.319507 0.154274 0.32829 0.11959 0.342141 0.154274 0.32829 0.14781 0.352412 0.11959 0.342141 0.154274 0.32829 0.179561 0.332749 0.14781 0.352412 0.179561 0.332749 0.177385 0.357627 0.14781 0.352412 0.179561 0.332749 0.2052389 0.332748 0.177385 0.357627 0.2052389 0.332748 0.2074159 0.357627 0.177385 0.357627 0.2052389 0.332748 0.230527 0.32829 0.2074159 0.357627 0.230527 0.32829 0.23699 0.352412 0.2074159 0.357627 0.230527 0.32829 0.254656 0.319507 0.23699 0.352412 0.254656 0.319507 0.26521 0.342141 0.23699 0.352412 0.254656 0.319507 0.276893 0.306668 0.26521 0.342141 0.276893 0.306668 0.291218 0.327126 0.26521 0.342141 0.276893 0.306668 0.296563 0.290163 0.291218 0.327126 0.296563 0.290163 0.314223 0.307822 0.291218 0.327126 0.296563 0.290163 0.313069 0.270493 0.314223 0.307822 0.313069 0.270493 0.333526 0.284817 0.314223 0.307822 0.313069 0.270493 0.325907 0.248255 0.333526 0.284817 0.325907 0.248255 0.348541 0.258809 0.333526 0.284817 0.325907 0.248255 0.33469 0.224126 0.348541 0.258809 0.33469 0.224126 0.358812 0.23059 0.348541 0.258809 0.33469 0.224126 0.339149 0.198839 0.358812 0.23059 0.339149 0.198839 0.364027 0.2010149 0.358812 0.23059 0.339149 0.198839 0.339148 0.173161 0.364027 0.2010149 0.339148 0.173161 0.364027 0.170984 0.364027 0.2010149 0.339148 0.173161 0.33469 0.147873 0.364027 0.170984 0.33469 0.147873 0.358812 0.1414099 0.364027 0.170984 0.33469 0.147873 0.325907 0.123744 0.358812 0.1414099 0.325907 0.123744 0.348541 0.11319 0.358812 0.1414099 0.325907 0.123744 0.313068 0.101507 0.348541 0.11319 0.313068 0.101507 0.333525 0.08718198 0.348541 0.11319 0.313068 0.101507 0.296563 0.08183699 0.333525 0.08718198 0.296563 0.08183699 0.314222 0.06417798 0.333525 0.08718198 0.164038 0.2935 0.163977 0.273412 0.228497 0.293303 0.163977 0.273412 0.228435 0.273214 0.228497 0.293303 0.163977 0.273412 0.16391 0.251614 0.228435 0.273214 0.16391 0.251614 0.2283689 0.251417 0.228435 0.273214 0.16391 0.251614 0.1638399 0.22877 0.2283689 0.251417 0.1638399 0.22877 0.228299 0.228573 0.2283689 0.251417 0.1638399 0.22877 0.163769 0.205574 0.228299 0.228573 0.163769 0.205574 0.228227 0.205376 0.228299 0.228573 0.163769 0.205574 0.163699 0.18273 0.228227 0.205376 0.163699 0.18273 0.228157 0.182532 0.228227 0.205376 0.163699 0.18273 0.163632 0.160932 0.228157 0.182532 0.163632 0.160932 0.22809 0.160735 0.228157 0.182532 0.163632 0.160932 0.16357 0.140844 0.22809 0.160735 0.16357 0.140844 0.228029 0.140646 0.22809 0.160735 0.16357 0.140844 0.163516 0.123074 0.228029 0.140646 0.163516 0.123074 0.2279739 0.122876 0.228029 0.140646 0.291217 0.04487395 0.276893 0.06533199 0.314222 0.06417798 0.276893 0.06533199 0.296563 0.08183699 0.314222 0.06417798 0.254656 0.05249297 0.276893 0.06533199 0.291217 0.04487395 0.26521 0.029859 0.254656 0.05249297 0.291217 0.04487395 0.230526 0.04370999 0.254656 0.05249297 0.26521 0.029859 0.23699 0.01958799 0.230526 0.04370999 0.26521 0.029859 0.2052389 0.03925198 0.230526 0.04370999 0.23699 0.01958799 0.207415 0.014373 0.2052389 0.03925198 0.23699 0.01958799 0.179561 0.03925198 0.2052389 0.03925198 0.207415 0.014373 0.177385 0.014373 0.179561 0.03925198 0.207415 0.014373 0.154274 0.04370999 0.179561 0.03925198 0.177385 0.014373 0.14781 0.01958799 0.154274 0.04370999 0.177385 0.014373 0.130145 0.05249297 0.154274 0.04370999 0.14781 0.01958799 0.11959 0.029859 0.130145 0.05249297 0.14781 0.01958799 0.1079069 0.06533199 0.130145 0.05249297 0.11959 0.029859 0.09358298 0.04487395 0.1079069 0.06533199 0.11959 0.029859 0.08823698 0.08183699 0.1079069 0.06533199 0.09358298 0.04487395 0.07057797 0.06417798 0.08823698 0.08183699 0.09358298 0.04487395 0.07173097 0.101507 0.08823698 0.08183699 0.07057797 0.06417798 0.051274 0.08718299 0.07173097 0.101507 0.07057797 0.06417798 0.05889296 0.123745 0.07173097 0.101507 0.051274 0.08718299 0.03625899 0.11319 0.05889296 0.123745 0.051274 0.08718299 0.05010998 0.1478739 0.05889296 0.123745 0.03625899 0.11319 0.02598798 0.1414099 0.05010998 0.1478739 0.03625899 0.11319 0.04565095 0.173161 0.05010998 0.1478739 0.02598798 0.1414099 0.02077299 0.170985 0.04565095 0.173161 0.02598798 0.1414099 0.04565197 0.198839 0.04565095 0.173161 0.02077299 0.170985 0.02077299 0.201016 0.04565197 0.198839 0.02077299 0.170985 0.05010998 0.2241269 0.04565197 0.198839 0.02077299 0.201016 0.02598798 0.23059 0.05010998 0.2241269 0.02077299 0.201016 0.05889296 0.248256 0.05010998 0.2241269 0.02598798 0.23059 0.03625899 0.25881 0.05889296 0.248256 0.02598798 0.23059 0.07173198 0.270493 0.05889296 0.248256 0.03625899 0.25881 0.051274 0.284818 0.07173198 0.270493 0.03625899 0.25881 0.08823698 0.290163 0.07173198 0.270493 0.051274 0.284818 0.07057797 0.307823 0.08823698 0.290163 0.051274 0.284818 0.1079069 0.306669 0.08823698 0.290163 0.07057797 0.307823 0.09358298 0.327126 0.1079069 0.306669 0.07057797 0.307823 0.130145 0.319507 0.1079069 0.306669 0.09358298 0.327126 0.11959 0.342141 0.130145 0.319507 0.09358298 0.327126 0.154274 0.32829 0.130145 0.319507 0.11959 0.342141 0.14781 0.352413 0.154274 0.32829 0.11959 0.342141 0.179561 0.332749 0.154274 0.32829 0.14781 0.352413 0.177385 0.357627 0.179561 0.332749 0.14781 0.352413 0.2052389 0.332749 0.179561 0.332749 0.177385 0.357627 0.2074159 0.357627 0.2052389 0.332749 0.177385 0.357627 0.230527 0.32829 0.2052389 0.332749 0.2074159 0.357627 0.23699 0.352412 0.230527 0.32829 0.2074159 0.357627 0.254656 0.319507 0.230527 0.32829 0.23699 0.352412 0.26521 0.342141 0.254656 0.319507 0.23699 0.352412 0.276893 0.306668 0.254656 0.319507 0.26521 0.342141 0.291218 0.327126 0.276893 0.306668 0.26521 0.342141 0.296564 0.290163 0.276893 0.306668 0.291218 0.327126 0.314223 0.307822 0.296564 0.290163 0.291218 0.327126 0.313069 0.270493 0.296564 0.290163 0.314223 0.307822 0.333526 0.284817 0.313069 0.270493 0.314223 0.307822 0.325908 0.248255 0.313069 0.270493 0.333526 0.284817 0.348541 0.25881 0.325908 0.248255 0.333526 0.284817 0.33469 0.224126 0.325908 0.248255 0.348541 0.25881 0.358813 0.23059 0.33469 0.224126 0.348541 0.25881 0.339149 0.198839 0.33469 0.224126 0.358813 0.23059 0.364027 0.2010149 0.339149 0.198839 0.358813 0.23059 0.339149 0.173161 0.339149 0.198839 0.364027 0.2010149 0.364027 0.170984 0.339149 0.173161 0.364027 0.2010149 0.33469 0.147873 0.339149 0.173161 0.364027 0.170984 0.358812 0.1414099 0.33469 0.147873 0.364027 0.170984 0.325907 0.123744 0.33469 0.147873 0.358812 0.1414099 0.348541 0.11319 0.325907 0.123744 0.358812 0.1414099 0.313068 0.101507 0.325907 0.123744 0.348541 0.11319 0.333526 0.08718198 0.313068 0.101507 0.348541 0.11319 0.296563 0.08183699 0.313068 0.101507 0.333526 0.08718198 0.314222 0.06417798 0.296563 0.08183699 0.333526 0.08718198 0.991489 0.815687 0.93703 0.815687 0.991489 0.657757 0.93703 0.815687 0.93703 0.657757 0.991489 0.657757 0.93703 0.815687 0.882571 0.815687 0.93703 0.657757 0.882571 0.815687 0.882571 0.657757 0.93703 0.657757 0.882571 0.815687 0.828112 0.815687 0.882571 0.657757 0.828112 0.815687 0.828112 0.657757 0.882571 0.657757 0.828112 0.815687 0.773711 0.815687 0.828112 0.657757 0.773711 0.815687 0.773711 0.657757 0.828112 0.657757 0.773711 0.815687 0.719194 0.815687 0.773711 0.657757 0.719194 0.815687 0.719194 0.657757 0.773711 0.657757 0.719194 0.815687 0.664736 0.815687 0.719194 0.657757 0.664736 0.815687 0.664736 0.657757 0.719194 0.657757 0.664736 0.815687 0.610277 0.815687 0.664736 0.657757 0.610277 0.815687 0.610277 0.657757 0.664736 0.657757 0.610277 0.815687 0.555818 0.815687 0.610277 0.657757 0.555818 0.815687 0.555818 0.657757 0.610277 0.657757 0.555818 0.815687 0.501359 0.815687 0.555818 0.657757 0.501359 0.815687 0.501359 0.657757 0.555818 0.657757 0.501359 0.815687 0.446897 0.815686 0.501359 0.657757 0.446897 0.815686 0.446897 0.657756 0.501359 0.657757 0.446897 0.815686 0.392438 0.815686 0.446897 0.657756 0.392438 0.815686 0.392438 0.657756 0.446897 0.657756 0.392438 0.815686 0.337979 0.815686 0.392438 0.657756 0.337979 0.815686 0.337979 0.657756 0.392438 0.657756 0.337979 0.815686 0.283521 0.815686 0.337979 0.657756 0.283521 0.815686 0.283521 0.657756 0.337979 0.657756 0.283521 0.815686 0.229062 0.815686 0.283521 0.657756 0.229062 0.815686 0.229062 0.657756 0.283521 0.657756 0.229062 0.815686 0.174603 0.815686 0.229062 0.657756 0.174603 0.815686 0.174603 0.657756 0.229062 0.657756 0.174603 0.815686 0.120144 0.815686 0.174603 0.657756 0.120144 0.815686 0.120144 0.657756 0.174603 0.657756 0.120144 0.815686 0.06568497 0.815686 0.120144 0.657756 0.06568497 0.815686 0.06568497 0.657756 0.120144 0.657756 0.06568497 0.815686 0.01122695 0.815686 0.06568497 0.657756 0.01122695 0.815686 0.01122695 0.657756 0.06568497 0.657756 0.163255 0.292417 0.163201 0.274647 0.227714 0.292219 0.163201 0.274647 0.227659 0.27445 0.227714 0.292219 0.163201 0.274647 0.163139 0.254559 0.227659 0.27445 0.163139 0.254559 0.2275969 0.254361 0.227659 0.27445 0.163139 0.254559 0.163072 0.232761 0.2275969 0.254361 0.163072 0.232761 0.22753 0.232563 0.2275969 0.254361 0.163072 0.232761 0.163002 0.209917 0.22753 0.232563 0.163002 0.209917 0.22746 0.209719 0.22753 0.232563 0.163002 0.209917 0.162931 0.186721 0.22746 0.209719 0.162931 0.186721 0.227389 0.186523 0.22746 0.209719 0.162931 0.186721 0.162861 0.163877 0.227389 0.186523 0.162861 0.163877 0.227319 0.163679 0.227389 0.186523 0.162861 0.163877 0.1627939 0.1420789 0.227319 0.163679 0.1627939 0.1420789 0.227252 0.141882 0.227319 0.163679 0.1627939 0.1420789 0.162732 0.12199 0.227252 0.141882 0.162732 0.12199 0.227191 0.121793 0.227252 0.141882 0.162732 0.12199 0.162678 0.104221 0.227191 0.121793 0.162678 0.104221 0.227136 0.104023 0.227191 0.121793 0.163057 0.292219 0.163111 0.27445 0.227515 0.292417 0.163111 0.27445 0.2275699 0.274647 0.227515 0.292417 0.163111 0.27445 0.163173 0.254361 0.2275699 0.274647 0.163173 0.254361 0.227631 0.254559 0.2275699 0.274647 0.163173 0.254361 0.16324 0.232563 0.227631 0.254559 0.16324 0.232563 0.227698 0.232761 0.227631 0.254559 0.16324 0.232563 0.16331 0.209719 0.227698 0.232761 0.16331 0.209719 0.227768 0.209917 0.227698 0.232761 0.16331 0.209719 0.163381 0.186523 0.227768 0.209917 0.163381 0.186523 0.2278389 0.186721 0.227768 0.209917 0.163381 0.186523 0.163451 0.163679 0.2278389 0.186721 0.163451 0.163679 0.227909 0.163877 0.2278389 0.186721 0.163451 0.163679 0.163518 0.141881 0.227909 0.163877 0.163518 0.141881 0.227976 0.1420789 0.227909 0.163877 0.163518 0.141881 0.163579 0.121793 0.227976 0.1420789 0.163579 0.121793 0.228038 0.12199 0.227976 0.1420789 0.163579 0.121793 0.163634 0.104023 0.228038 0.12199 0.163634 0.104023 0.228092 0.104221 0.228038 0.12199 0.163215 0.292219 0.1632699 0.27445 0.227674 0.292417 0.1632699 0.27445 0.227728 0.274647 0.227674 0.292417 0.1632699 0.27445 0.163332 0.254361 0.227728 0.274647 0.163332 0.254361 0.2277899 0.254559 0.227728 0.274647 0.163332 0.254361 0.163398 0.232563 0.2277899 0.254559 0.163398 0.232563 0.2278569 0.232761 0.2277899 0.254559 0.163398 0.232563 0.163469 0.209719 0.2278569 0.232761 0.163469 0.209719 0.227927 0.209917 0.2278569 0.232761 0.163469 0.209719 0.16354 0.186523 0.227927 0.209917 0.16354 0.186523 0.227998 0.186721 0.227927 0.209917 0.16354 0.186523 0.16361 0.163679 0.227998 0.186721 0.16361 0.163679 0.2280679 0.163877 0.227998 0.186721 0.16361 0.163679 0.163677 0.141881 0.2280679 0.163877 0.163677 0.141881 0.228135 0.1420789 0.2280679 0.163877 0.163677 0.141881 0.163738 0.121793 0.228135 0.1420789 0.163738 0.121793 0.228197 0.12199 0.228135 0.1420789 0.163738 0.121793 0.163793 0.104023 0.228197 0.12199 0.163793 0.104023 0.228251 0.104221 0.228197 0.12199 0.186682 0.171459 0.1689119 0.171513 0.186484 0.107 0.1689119 0.171513 0.168714 0.107055 0.186484 0.107 0.501083 0.832038 0.501083 0.989963 0.446618 0.989969 + + + + + + + + + + + + + + + 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 +

0 0 0 2 1 1 1 2 2 0 0 3 1 2 4 3 3 5 1 2 6 4 4 7 3 3 8 4 4 9 5 5 10 3 3 11 4 4 12 6 6 13 5 5 14 6 6 15 7 7 16 5 5 17 6 6 18 8 8 19 7 7 20 8 8 21 9 9 22 7 7 23 8 8 24 10 10 25 9 9 26 10 10 27 11 11 28 9 9 29 10 10 30 12 12 31 11 11 32 12 12 33 13 13 34 11 11 35 12 12 36 14 14 37 13 13 38 14 14 39 15 15 40 13 13 41 14 14 42 16 16 43 15 15 44 16 16 45 17 17 46 15 15 47 0 0 48 18 18 49 2 1 50 20 19 51 18 18 52 19 20 53 21 21 54 20 19 55 19 20 56 21 21 57 19 20 58 22 22 59 23 23 60 21 21 61 22 22 62 23 23 63 22 22 64 24 24 65 25 25 66 23 23 67 24 24 68 25 25 69 24 24 70 26 26 71 27 27 72 25 25 73 26 26 74 27 27 75 26 26 76 28 28 77 29 29 78 27 27 79 28 28 80 29 29 81 28 28 82 30 30 83 31 31 84 29 29 85 30 30 86 31 31 87 30 30 88 32 32 89 33 33 90 31 31 91 32 32 92 33 33 93 32 32 94 34 34 95 35 35 96 33 33 97 34 34 98 35 35 99 34 34 100 36 36 101 37 37 102 35 35 103 36 36 104 40 38 105 39 39 106 38 40 107 39 39 108 41 41 109 38 40 110 39 39 111 42 42 112 41 41 113 42 42 114 43 43 115 41 41 116 42 42 117 44 44 118 43 43 119 44 44 120 45 45 121 43 43 122 44 44 123 46 46 124 45 45 125 46 46 126 47 47 127 45 45 128 46 46 129 48 48 130 47 47 131 48 48 132 49 49 133 47 47 134 48 48 135 50 50 136 49 49 137 50 50 138 51 51 139 49 49 140 50 50 141 52 52 142 51 51 143 52 52 144 53 53 145 51 51 146 52 52 147 54 54 148 53 53 149 54 54 150 55 55 151 53 53 152 54 54 153 56 56 154 55 55 155 56 56 156 57 57 157 55 55 158 56 56 159 58 58 160 57 57 161 58 58 162 59 59 163 57 57 164 58 58 165 60 60 166 59 59 167 60 60 168 61 61 169 59 59 170 60 60 171 62 62 172 61 61 173 62 62 174 63 63 175 61 61 176 62 62 177 64 64 178 63 63 179 64 64 180 65 65 181 63 63 182 64 64 183 66 66 184 65 65 185 66 66 186 67 67 187 65 65 188 66 66 189 68 68 190 67 67 191 68 68 192 69 69 193 67 67 194 68 68 195 70 70 196 69 69 197 70 70 198 71 71 199 69 69 200 70 70 201 72 72 202 71 71 203 72 72 204 73 73 205 71 71 206 72 72 207 74 74 208 73 73 209 74 74 210 75 75 211 73 73 212 74 74 213 76 76 214 75 75 215 76 76 216 77 77 217 75 75 218 76 76 219 78 78 220 77 77 221 78 78 222 79 79 223 77 77 224 78 78 225 80 80 226 79 79 227 80 80 228 81 81 229 79 79 230 80 80 231 82 82 232 81 81 233 82 82 234 83 83 235 81 81 236 82 82 237 84 84 238 83 83 239 84 84 240 85 85 241 83 83 242 84 84 243 86 86 244 85 85 245 86 86 246 87 87 247 85 85 248 86 86 249 88 88 250 87 87 251 88 88 252 89 89 253 87 87 254 88 88 255 90 90 256 89 89 257 90 90 258 91 91 259 89 89 260 90 90 261 92 92 262 91 91 263 92 92 264 93 93 265 91 91 266 92 92 267 94 94 268 93 93 269 94 94 270 95 95 271 93 93 272 94 94 273 96 96 274 95 95 275 96 96 276 97 97 277 95 95 278 96 96 279 98 98 280 97 97 281 98 98 282 99 99 283 97 97 284 98 98 285 100 100 286 99 99 287 100 100 288 101 101 289 99 99 290 100 100 291 102 102 292 101 101 293 102 102 294 103 103 295 101 101 296 102 102 297 104 104 298 103 103 299 104 104 300 105 105 301 103 103 302 104 104 303 106 106 304 105 105 305 106 106 306 107 107 307 105 105 308 106 106 309 108 108 310 107 107 311 108 108 312 109 109 313 107 107 314 108 108 315 40 38 316 109 109 317 40 38 318 38 40 319 109 109 320 112 110 321 111 111 322 110 112 323 111 111 324 113 113 325 110 112 326 111 111 327 114 114 328 113 113 329 114 114 330 115 115 331 113 113 332 114 114 333 116 116 334 115 115 335 116 116 336 117 117 337 115 115 338 116 116 339 118 118 340 117 117 341 118 118 342 119 119 343 117 117 344 118 118 345 120 120 346 119 119 347 120 120 348 121 121 349 119 119 350 120 120 351 122 122 352 121 121 353 122 122 354 123 123 355 121 121 356 122 122 357 124 124 358 123 123 359 124 124 360 125 125 361 123 123 362 124 124 363 126 126 364 125 125 365 126 126 366 127 127 367 125 125 368 130 128 369 129 129 370 128 130 371 129 129 372 131 131 373 128 130 374 132 132 375 129 129 376 130 128 377 133 133 378 132 132 379 130 128 380 134 134 381 132 132 382 133 133 383 135 135 384 134 134 385 133 133 386 136 136 387 134 134 388 135 135 389 137 137 390 136 136 391 135 135 392 138 138 393 136 136 394 137 137 395 139 139 396 138 138 397 137 137 398 140 140 399 138 138 400 139 139 401 141 141 402 140 140 403 139 139 404 142 142 405 140 140 406 141 141 407 143 143 408 142 142 409 141 141 410 144 144 411 142 142 412 143 143 413 145 145 414 144 144 415 143 143 416 146 146 417 144 144 418 145 145 419 147 147 420 146 146 421 145 145 422 148 148 423 146 146 424 147 147 425 149 149 426 148 148 427 147 147 428 150 150 429 148 148 430 149 149 431 151 151 432 150 150 433 149 149 434 152 152 435 150 150 436 151 151 437 153 153 438 152 152 439 151 151 440 154 154 441 152 152 442 153 153 443 155 155 444 154 154 445 153 153 446 156 156 447 154 154 448 155 155 449 157 157 450 156 156 451 155 155 452 158 158 453 156 156 454 157 157 455 159 159 456 158 158 457 157 157 458 160 160 459 158 158 460 159 159 461 161 161 462 160 160 463 159 159 464 162 162 465 160 160 466 161 161 467 163 163 468 162 162 469 161 161 470 164 164 471 162 162 472 163 163 473 165 165 474 164 164 475 163 163 476 166 166 477 164 164 478 165 165 479 167 167 480 166 166 481 165 165 482 168 168 483 166 166 484 167 167 485 169 169 486 168 168 487 167 167 488 170 170 489 168 168 490 169 169 491 171 171 492 170 170 493 169 169 494 172 172 495 170 170 496 171 171 497 173 173 498 172 172 499 171 171 500 174 174 501 172 172 502 173 173 503 175 175 504 174 174 505 173 173 506 176 176 507 174 174 508 175 175 509 177 177 510 176 176 511 175 175 512 178 178 513 176 176 514 177 177 515 179 179 516 178 178 517 177 177 518 180 180 519 178 178 520 179 179 521 181 181 522 180 180 523 179 179 524 182 182 525 180 180 526 181 181 527 183 183 528 182 182 529 181 181 530 184 184 531 182 182 532 183 183 533 185 185 534 184 184 535 183 183 536 186 186 537 184 184 538 185 185 539 187 187 540 186 186 541 185 185 542 188 188 543 186 186 544 187 187 545 189 189 546 188 188 547 187 187 548 190 190 549 188 188 550 189 189 551 191 191 552 190 190 553 189 189 554 192 192 555 190 190 556 191 191 557 193 193 558 192 192 559 191 191 560 194 194 561 192 192 562 193 193 563 195 195 564 194 194 565 193 193 566 196 196 567 194 194 568 195 195 569 197 197 570 196 196 571 195 195 572 198 198 573 196 196 574 197 197 575 199 199 576 198 198 577 197 197 578 131 131 579 198 198 580 199 199 581 128 130 582 131 131 583 199 199 584 202 200 585 201 201 586 200 202 587 201 201 588 203 203 589 200 202 590 201 201 591 204 204 592 203 203 593 204 204 594 205 205 595 203 203 596 204 204 597 206 206 598 205 205 599 206 206 600 207 207 601 205 205 602 206 206 603 208 208 604 207 207 605 208 208 606 209 209 607 207 207 608 208 208 609 210 210 610 209 209 611 210 210 612 211 211 613 209 209 614 210 210 615 212 212 616 211 211 617 212 212 618 213 213 619 211 211 620 212 212 621 214 214 622 213 213 623 214 214 624 215 215 625 213 213 626 214 214 627 216 216 628 215 215 629 216 216 630 217 217 631 215 215 632 216 216 633 218 218 634 217 217 635 218 218 636 219 219 637 217 217 638 218 218 639 220 220 640 219 219 641 220 220 642 221 221 643 219 219 644 220 220 645 222 222 646 221 221 647 222 222 648 223 223 649 221 221 650 222 222 651 224 224 652 223 223 653 224 224 654 225 225 655 223 223 656 224 224 657 226 226 658 225 225 659 226 226 660 227 227 661 225 225 662 226 226 663 228 228 664 227 227 665 228 228 666 229 229 667 227 227 668 228 228 669 230 230 670 229 229 671 230 230 672 231 231 673 229 229 674 230 230 675 232 232 676 231 231 677 232 232 678 233 233 679 231 231 680 232 232 681 234 234 682 233 233 683 234 234 684 235 235 685 233 233 686 234 234 687 236 236 688 235 235 689 236 236 690 237 237 691 235 235 692 240 238 693 239 239 694 238 240 695 239 239 696 241 241 697 238 240 698 239 239 699 242 242 700 241 241 701 242 242 702 243 243 703 241 241 704 242 242 705 244 244 706 243 243 707 244 244 708 245 245 709 243 243 710 244 244 711 246 246 712 245 245 713 246 246 714 247 247 715 245 245 716 246 246 717 248 248 718 247 247 719 248 248 720 249 249 721 247 247 722 248 248 723 250 250 724 249 249 725 250 250 726 251 251 727 249 249 728 250 250 729 252 252 730 251 251 731 252 252 732 253 253 733 251 251 734 252 252 735 254 254 736 253 253 737 254 254 738 255 255 739 253 253 740 254 254 741 256 256 742 255 255 743 256 256 744 257 257 745 255 255 746 260 258 747 259 259 748 258 260 749 259 259 750 261 261 751 258 260 752 259 259 753 262 262 754 261 261 755 262 262 756 263 263 757 261 261 758 262 262 759 264 264 760 263 263 761 264 264 762 265 265 763 263 263 764 264 264 765 266 266 766 265 265 767 266 266 768 267 267 769 265 265 770 266 266 771 268 268 772 267 267 773 268 268 774 269 269 775 267 267 776 268 268 777 270 270 778 269 269 779 270 270 780 271 271 781 269 269 782 270 270 783 272 272 784 271 271 785 272 272 786 273 273 787 271 271 788 272 272 789 274 274 790 273 273 791 274 274 792 275 275 793 273 273 794 274 274 795 276 276 796 275 275 797 276 276 798 277 277 799 275 275 800 280 278 801 279 279 802 278 280 803 279 279 804 281 281 805 278 280 806 279 279 807 282 282 808 281 281 809 282 282 810 283 283 811 281 281 812 282 282 813 284 284 814 283 283 815 284 284 816 285 285 817 283 283 818 284 284 819 286 286 820 285 285 821 286 286 822 287 287 823 285 285 824 286 286 825 288 288 826 287 287 827 288 288 828 289 289 829 287 287 830 288 288 831 290 290 832 289 289 833 290 290 834 291 291 835 289 289 836 290 290 837 292 292 838 291 291 839 292 292 840 293 293 841 291 291 842 292 292 843 294 294 844 293 293 845 294 294 846 295 295 847 293 293 848 294 294 849 296 296 850 295 295 851 296 296 852 297 297 853 295 295 854 300 298 855 299 299 856 298 300 857 299 299 858 301 301 859 298 300 860 18 18 861 20 19 862 2 1 863

+
+
+
+
+ + + + + 0.6858805 -0.3173701 0.6548619 7.481132 0.7276338 0.3124686 -0.6106656 -6.50764 -0.01081678 0.8953432 0.4452454 5.343665 0 0 0 1 + + + + -0.2908646 -0.7711008 0.5663932 4.076245 0.9551712 -0.1998834 0.2183912 1.005454 -0.05518906 0.6045247 0.7946723 5.903862 0 0 0 1 + + + + 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 + + 1.25 0 0 0 0 -1.67949e-7 -1.25 0 0 1.25 -1.67949e-7 0 0 0 0 1 + + 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 + + + + + + + + + + 1 0 0 0 0 1 0 -5.55438e-8 0 0 1 -2e-15 0 0 0 1 + + + + + + + + + + + + 1 0 0 0.3932523 0 1 0 -0.1413886 0 0 1 -1.029667 0 0 0 1 + + + + + + + +
\ No newline at end of file diff --git a/src/parts source/kOS1m dev/Assets/kOSMachine1m.dae.meta b/src/parts source/kOS1m dev/Assets/kOSMachine1m.dae.meta new file mode 100644 index 000000000..ccf794e0c --- /dev/null +++ b/src/parts source/kOS1m dev/Assets/kOSMachine1m.dae.meta @@ -0,0 +1,88 @@ +fileFormatVersion: 2 +guid: d948050f9fcdd4bbba05e8ab0f169530 +timeCreated: 1431174479 +licenseType: Free +ModelImporter: + serializedVersion: 18 + fileIDToRecycleName: + 100000: Area + 100002: Camera + 100004: Cylinder_002 + 100006: GameObject + 100008: //RootNode + 100010: Lamp + 100012: ModuleSmall3 + 100014: Plane + 400000: Area + 400002: Camera + 400004: Cylinder_002 + 400006: GameObject + 400008: //RootNode + 400010: Lamp + 400012: ModuleSmall3 + 400014: Plane + 2300000: Cylinder_002 + 2300002: Plane + 3300000: Cylinder_002 + 3300002: Plane + 4300000: Cylinder_002 + 4300002: Plane + 9500000: //RootNode + materials: + importMaterials: 1 + materialName: 0 + materialSearch: 1 + animations: + legacyGenerateAnimations: 4 + bakeSimulation: 0 + optimizeGameObjects: 0 + motionNodeName: + animationCompression: 1 + animationRotationError: .5 + animationPositionError: .5 + animationScaleError: .5 + animationWrapMode: 0 + extraExposedTransformPaths: [] + clipAnimations: [] + isReadable: 1 + meshes: + lODScreenPercentages: [] + globalScale: 1 + meshCompression: 0 + addColliders: 0 + importBlendShapes: 1 + swapUVChannels: 0 + generateSecondaryUV: 0 + useFileUnits: 1 + optimizeMeshForGPU: 1 + keepQuads: 0 + weldVertices: 1 + secondaryUVAngleDistortion: 8 + secondaryUVAreaDistortion: 15.000001 + secondaryUVHardAngle: 88 + secondaryUVPackMargin: 4 + useFileScale: 1 + tangentSpace: + normalSmoothAngle: 60 + splitTangentsAcrossUV: 1 + normalImportMode: 0 + tangentImportMode: 1 + importAnimation: 1 + copyAvatar: 0 + humanDescription: + human: [] + skeleton: [] + armTwist: .5 + foreArmTwist: .5 + upperLegTwist: .5 + legTwist: .5 + armStretch: .0500000007 + legStretch: .0500000007 + feetSpacing: 0 + rootMotionBoneName: + lastHumanDescriptionAvatarSource: {instanceID: 0} + animationType: 2 + additionalBone: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/parts source/kOS1m dev/Assets/kOSMachine1m.unity b/src/parts source/kOS1m dev/Assets/kOSMachine1m.unity new file mode 100644 index 000000000..262232eae Binary files /dev/null and b/src/parts source/kOS1m dev/Assets/kOSMachine1m.unity differ diff --git a/src/parts source/kOS1m dev/Assets/kOSMachine1m.unity.meta b/src/parts source/kOS1m dev/Assets/kOSMachine1m.unity.meta new file mode 100644 index 000000000..27c0497c7 --- /dev/null +++ b/src/parts source/kOS1m dev/Assets/kOSMachine1m.unity.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 80edfc4c624a64133a1ce2e3fb552c4f +timeCreated: 1431181235 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/parts source/kOS1m dev/kOSMachine1m.blend b/src/parts source/kOS1m dev/kOSMachine1m.blend new file mode 100644 index 000000000..cb8592b4b Binary files /dev/null and b/src/parts source/kOS1m dev/kOSMachine1m.blend differ diff --git a/src/parts source/kOS1m dev/kOSMachine1m.dae b/src/parts source/kOS1m dev/kOSMachine1m.dae new file mode 100644 index 000000000..a49bc321c --- /dev/null +++ b/src/parts source/kOS1m dev/kOSMachine1m.dae @@ -0,0 +1,340 @@ + + + + + Blender User + Blender 2.73.0 commit date:2015-01-20, commit time:18:16, hash:bbf09d9 + + 2015-05-09T08:26:29 + 2015-05-09T08:26:29 + + Z_UP + + + + + + + 49.13434 + 1.777778 + 0.1 + 100 + + + + + + 0 + 0 + 0 + + + + + + + + + 1 1 1 + 1 + 0 + 0.00111109 + + + + + 0.000999987 + 1 + 0.1 + 0.1 + 1 + 1 + 1 + 2 + 0 + 1 + 1 + 1 + 1 + 1 + 0 + 2880 + 2 + 30.002 + 1.000799 + 0.04999995 + 29.99998 + 1 + 2 + 0 + 0 + 1 + 1 + 1 + 1 + 8192 + 1 + 1 + 0 + 1 + 1 + 1 + 3 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 1 + 3 + 0.15 + 75 + 1 + 1 + 0 + 1 + 1 + 0 + + + + + + + 1 1 1 + 1 + 0 + 0.001599967 + + + + + 0.000999987 + 0 + 0.1 + 0.1 + 0.1 + 1 + 1 + 2 + 0 + 1 + 1 + 1 + 1 + 1 + 0 + 512 + 2 + 40 + 0.5 + 0.04999995 + 25 + 1 + 2 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 1 + 3 + 0 + 0 + 0 + 0 + 2 + 1 + 1 + 1 + 3 + 0.15 + 45 + 1 + 1 + 0 + 1 + 1 + 4 + + + + + + + + + + + + 0 0 0 1 + + + 0 0 0 1 + + + 0.64 0.64 0.64 1 + + + 0.5 0.5 0.5 1 + + + 50 + + + 1 + + + + + + + + + + + + + + + + 0 -0.1 0.45 -0.08779096 0.1 0.441353 0 0.1 0.45 -0.08779096 -0.1 0.441353 -0.08779096 -0.1 0.441353 -0.172208 0.1 0.415746 -0.08779096 0.1 0.441353 -0.172208 -0.1 0.415746 -0.172208 -0.1 0.415746 -0.250007 0.1 0.374161 -0.172208 0.1 0.415746 -0.250007 -0.1 0.374161 -0.250007 -0.1 0.374161 -0.318198 0.1 0.318198 -0.250007 0.1 0.374161 -0.318198 -0.1 0.318198 -0.318198 -0.1 0.318198 -0.374161 0.1 0.250007 -0.318198 0.1 0.318198 -0.374161 -0.1 0.250007 -0.374161 -0.1 0.250007 -0.415746 0.1 0.172208 -0.374161 0.1 0.250007 -0.415746 -0.1 0.172208 -0.415746 -0.1 0.172208 -0.441353 0.1 0.08779096 -0.415746 0.1 0.172208 -0.441353 -0.1 0.08779096 -0.441353 -0.1 0.08779096 -0.45 0.1 0 -0.441353 0.1 0.08779096 -0.45 -0.1 0 -0.45 -0.1 0 -0.441353 0.1 -0.08779096 -0.45 0.1 0 -0.441353 -0.1 -0.08779096 -0.441353 -0.1 -0.08779096 -0.415746 0.1 -0.1722069 -0.441353 0.1 -0.08779096 -0.415746 -0.1 -0.1722069 -0.415746 -0.1 -0.1722069 -0.374161 0.1 -0.250007 -0.415746 0.1 -0.1722069 -0.374161 -0.1 -0.250007 -0.374161 -0.1 -0.250007 -0.318198 0.1 -0.318198 -0.374161 0.1 -0.250007 -0.318198 -0.1 -0.318198 -0.318198 -0.1 -0.318198 -0.250007 0.1 -0.374161 -0.318198 0.1 -0.318198 -0.250007 -0.1 -0.374161 -0.250007 -0.1 -0.374161 -0.1722069 0.1 -0.415746 -0.250007 0.1 -0.374161 -0.1722069 -0.1 -0.415746 -0.1722069 -0.1 -0.415746 -0.08779096 0.1 -0.441353 -0.1722069 0.1 -0.415746 -0.08779096 -0.1 -0.441353 -0.08779096 -0.1 -0.441353 0 0.1 -0.45 -0.08779096 0.1 -0.441353 0 -0.1 -0.45 0 -0.1 -0.45 0.08779096 0.1 -0.441353 0 0.1 -0.45 0.08779096 -0.1 -0.441353 0.08779096 -0.1 -0.441353 0.172208 0.1 -0.415746 0.08779096 0.1 -0.441353 0.172208 -0.1 -0.415746 0.172208 -0.1 -0.415746 0.250007 0.1 -0.374161 0.172208 0.1 -0.415746 0.250007 -0.1 -0.374161 0.250007 -0.1 -0.374161 0.318198 0.1 -0.318198 0.250007 0.1 -0.374161 0.318198 -0.1 -0.318198 0.318198 -0.1 -0.318198 0.374161 0.1 -0.250006 0.318198 0.1 -0.318198 0.374161 -0.1 -0.250006 0.374161 -0.1 -0.250006 0.415746 0.1 -0.1722069 0.374161 0.1 -0.250006 0.415746 -0.1 -0.1722069 0.415746 -0.1 -0.1722069 0.441353 0.1 -0.08778995 0.415746 0.1 -0.1722069 0.441353 -0.1 -0.08778995 0.441353 -0.1 -0.08778995 0.45 0.1 0 0.441353 0.1 -0.08778995 0.45 -0.1 0 0.45 -0.1 0 0.441353 0.1 0.08779096 0.45 0.1 0 0.441353 -0.1 0.08779096 0.441353 -0.1 0.08779096 0.415746 0.1 0.172208 0.441353 0.1 0.08779096 0.415746 -0.1 0.172208 0.415746 -0.1 0.172208 0.374161 0.1 0.250007 0.415746 0.1 0.172208 0.374161 -0.1 0.250007 0.374161 -0.1 0.250007 0.318198 0.1 0.318198 0.374161 0.1 0.250007 0.318198 -0.1 0.318198 0.318198 -0.1 0.318198 0.250006 0.1 0.374162 0.318198 0.1 0.318198 0.250006 -0.1 0.374162 0.250006 -0.1 0.374162 0.1722069 0.1 0.415746 0.250006 0.1 0.374162 0.1722069 -0.1 0.415746 -0.08779096 0.1 0.441353 0.08778995 0.1 0.441353 0 0.1 0.45 0.1722069 0.1 0.415746 -0.172208 0.1 0.415746 0.250006 0.1 0.374162 -0.250007 0.1 0.374161 0.318198 0.1 0.318198 -0.318198 0.1 0.318198 0.374161 0.1 0.250007 -0.374161 0.1 0.250007 0.415746 0.1 0.172208 -0.415746 0.1 0.172208 0.441353 0.1 0.08779096 -0.441353 0.1 0.08779096 0.45 0.1 0 -0.45 0.1 0 0.441353 0.1 -0.08778995 -0.441353 0.1 -0.08779096 0.415746 0.1 -0.1722069 -0.415746 0.1 -0.1722069 0.374161 0.1 -0.250006 -0.374161 0.1 -0.250007 0.318198 0.1 -0.318198 -0.318198 0.1 -0.318198 0.250007 0.1 -0.374161 -0.250007 0.1 -0.374161 0.172208 0.1 -0.415746 -0.1722069 0.1 -0.415746 0.08779096 0.1 -0.441353 -0.08779096 0.1 -0.441353 0 0.1 -0.45 0 0.1 0.45 0.08778995 -0.1 0.441353 0 -0.1 0.45 0.08778995 0.1 0.441353 0.1722069 -0.1 0.415746 0.08778995 0.1 0.441353 0.1722069 0.1 0.415746 0.08778995 -0.1 0.441353 0 -0.1 0.45 0.08778995 -0.1 0.441353 -0.08779096 -0.1 0.441353 0.1722069 -0.1 0.415746 -0.172208 -0.1 0.415746 0.250006 -0.1 0.374162 -0.250007 -0.1 0.374161 0.318198 -0.1 0.318198 -0.318198 -0.1 0.318198 0.374161 -0.1 0.250007 -0.374161 -0.1 0.250007 0.415746 -0.1 0.172208 -0.415746 -0.1 0.172208 0.441353 -0.1 0.08779096 -0.441353 -0.1 0.08779096 0.45 -0.1 0 -0.45 -0.1 0 0.441353 -0.1 -0.08778995 -0.441353 -0.1 -0.08779096 0.415746 -0.1 -0.1722069 -0.415746 -0.1 -0.1722069 0.374161 -0.1 -0.250006 -0.374161 -0.1 -0.250007 0.318198 -0.1 -0.318198 -0.318198 -0.1 -0.318198 0.250007 -0.1 -0.374161 -0.250007 -0.1 -0.374161 0.172208 -0.1 -0.415746 -0.1722069 -0.1 -0.415746 0.08779096 -0.1 -0.441353 -0.08779096 -0.1 -0.441353 0 -0.1 -0.45 + + + + + + + + + + -0.09799492 0 0.9951781 -0.09799492 0 0.9951781 -0.09799492 0 0.9951781 -0.09799492 0 0.9951781 -0.2902615 0 0.9569384 -0.2902615 0 0.9569384 -0.2902615 0 0.9569384 -0.2902615 0 0.9569384 -0.4713889 0 0.8818934 -0.4713889 0 0.8818934 -0.4713889 0 0.8818934 -0.4713889 0 0.8818934 -0.6343883 0 0.7730033 -0.6343883 0 0.7730033 -0.6343883 0 0.7730033 -0.6343883 0 0.7730033 -0.7730033 0 0.6343883 -0.7730033 0 0.6343883 -0.7730033 0 0.6343883 -0.7730033 0 0.6343883 -0.8818934 0 0.4713889 -0.8818934 0 0.4713889 -0.8818934 0 0.4713889 -0.8818934 0 0.4713889 -0.9569384 0 0.2902615 -0.9569384 0 0.2902615 -0.9569384 0 0.2902615 -0.9569384 0 0.2902615 -0.9951781 0 0.09799492 -0.9951781 0 0.09799492 -0.9951781 0 0.09799492 -0.9951781 0 0.09799492 -0.9951781 0 -0.09799492 -0.9951781 0 -0.09799492 -0.9951781 0 -0.09799492 -0.9951781 0 -0.09799492 -0.9569384 0 -0.2902615 -0.9569384 0 -0.2902615 -0.9569384 0 -0.2902615 -0.9569384 0 -0.2902615 -0.8818934 0 -0.4713889 -0.8818934 0 -0.4713889 -0.8818934 0 -0.4713889 -0.8818934 0 -0.4713889 -0.7730033 0 -0.6343883 -0.7730033 0 -0.6343883 -0.7730033 0 -0.6343883 -0.7730033 0 -0.6343883 -0.6343883 0 -0.7730033 -0.6343883 0 -0.7730033 -0.6343883 0 -0.7730033 -0.6343883 0 -0.7730033 -0.4713889 0 -0.8818934 -0.4713889 0 -0.8818934 -0.4713889 0 -0.8818934 -0.4713889 0 -0.8818934 -0.2902615 0 -0.9569384 -0.2902615 0 -0.9569384 -0.2902615 0 -0.9569384 -0.2902615 0 -0.9569384 -0.09799492 0 -0.9951781 -0.09799492 0 -0.9951781 -0.09799492 0 -0.9951781 -0.09799492 0 -0.9951781 0.09799492 0 -0.9951781 0.09799492 0 -0.9951781 0.09799492 0 -0.9951781 0.09799492 0 -0.9951781 0.2902615 0 -0.9569384 0.2902615 0 -0.9569384 0.2902615 0 -0.9569384 0.2902615 0 -0.9569384 0.4713889 0 -0.8818934 0.4713889 0 -0.8818934 0.4713889 0 -0.8818934 0.4713889 0 -0.8818934 0.6343883 0 -0.7730033 0.6343883 0 -0.7730033 0.6343883 0 -0.7730033 0.6343883 0 -0.7730033 0.7730033 0 -0.6343883 0.7730033 0 -0.6343883 0.7730033 0 -0.6343883 0.7730033 0 -0.6343883 0.8818934 0 -0.4713889 0.8818934 0 -0.4713889 0.8818934 0 -0.4713889 0.8818934 0 -0.4713889 0.9569384 0 -0.2902615 0.9569384 0 -0.2902615 0.9569384 0 -0.2902615 0.9569384 0 -0.2902615 0.9951781 0 -0.09799492 0.9951781 0 -0.09799492 0.9951781 0 -0.09799492 0.9951781 0 -0.09799492 0.9951781 0 0.09799492 0.9951781 0 0.09799492 0.9951781 0 0.09799492 0.9951781 0 0.09799492 0.9569384 0 0.2902615 0.9569384 0 0.2902615 0.9569384 0 0.2902615 0.9569384 0 0.2902615 0.8818934 0 0.4713889 0.8818934 0 0.4713889 0.8818934 0 0.4713889 0.8818934 0 0.4713889 0.7730033 0 0.6343883 0.7730033 0 0.6343883 0.7730033 0 0.6343883 0.7730033 0 0.6343883 0.6343883 0 0.7730033 0.6343883 0 0.7730033 0.6343883 0 0.7730033 0.6343883 0 0.7730033 0.4713889 0 0.8818934 0.4713889 0 0.8818934 0.4713889 0 0.8818934 0.4713889 0 0.8818934 0 1 0 0 0.9999695 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0.9999695 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0.9999695 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0.09799492 0 0.9951781 0.09799492 0 0.9951781 0.09799492 0 0.9951781 0.09799492 0 0.9951781 0.2902615 0 0.9569384 0.2902615 0 0.9569384 0.2902615 0 0.9569384 0.2902615 0 0.9569384 0 -1 0 0 -0.9999695 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -0.9999695 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -0.9999695 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 + + + + + + + + + + 0.4827008 0.7076991 0.4823486 0.7353461 0.4701541 0.7351908 0.4827008 0.7076991 0.4701541 0.7351908 0.4705063 0.7075438 0.4819946 0.7631602 0.4698001 0.7630048 0.4823468 0.7355132 0.4698001 0.7630048 0.4701524 0.7353578 0.4823468 0.7355132 0.4081793 0.7344012 0.3959848 0.7342458 0.4085315 0.7067542 0.3959848 0.7342458 0.396337 0.7065988 0.4085315 0.7067542 0.4325481 0.7625302 0.4203537 0.7623748 0.4329003 0.7348832 0.4203537 0.7623748 0.4207059 0.7347278 0.4329003 0.7348832 0.3831021 0.7619003 0.3709077 0.7617449 0.3834543 0.7342532 0.3709077 0.7617449 0.3712599 0.7340978 0.3834543 0.7342532 0.3958178 0.7342437 0.3836233 0.7340884 0.39617 0.7065967 0.3836233 0.7340884 0.3839755 0.7064413 0.39617 0.7065967 0.4696331 0.7630027 0.4574387 0.7628473 0.4699854 0.7353557 0.4574387 0.7628473 0.4577909 0.7352003 0.4699854 0.7353557 0.4452639 0.7348737 0.4330694 0.7347183 0.4456162 0.7072266 0.4330694 0.7347183 0.4334216 0.7070713 0.4456162 0.7072266 0.4329024 0.7347162 0.4207079 0.7345608 0.4332547 0.7070692 0.4207079 0.7345608 0.4210601 0.7069138 0.4332547 0.7070692 0.3460178 0.7614278 0.3338235 0.7612724 0.3463701 0.7337808 0.3338235 0.7612724 0.3341757 0.7336254 0.3463701 0.7337808 0.5317951 0.7359761 0.5196005 0.7358208 0.5321473 0.7083291 0.5196005 0.7358208 0.5199527 0.7081737 0.5321473 0.7083291 0.4201865 0.7623727 0.4079921 0.7622174 0.4205387 0.7347257 0.4079921 0.7622174 0.4083443 0.7345703 0.4205387 0.7347257 0.3707407 0.7617428 0.3585463 0.7615874 0.3710929 0.7340957 0.3585463 0.7615874 0.3588985 0.7339404 0.3710929 0.7340957 0.5194334 0.7358186 0.5072388 0.7356632 0.5197857 0.7081716 0.5072388 0.7356632 0.507591 0.7080162 0.5197857 0.7081716 0.3463718 0.7336137 0.3341775 0.7334584 0.346724 0.7059667 0.3341775 0.7334584 0.3345297 0.7058113 0.346724 0.7059667 0.4947102 0.7355036 0.4825156 0.7353482 0.4950624 0.7078566 0.4825156 0.7353482 0.4828678 0.7077012 0.4950624 0.7078566 0.469987 0.7351886 0.4577925 0.7350333 0.4703392 0.7075417 0.4577925 0.7350333 0.4581448 0.7073863 0.4703392 0.7075417 0.5067176 0.7634751 0.4945232 0.7633198 0.5070698 0.7358281 0.4945232 0.7633198 0.4948754 0.7356728 0.5070698 0.7358281 0.3834563 0.7340862 0.3712617 0.7339308 0.3838085 0.7064392 0.3712617 0.7339308 0.371614 0.7062839 0.3838085 0.7064392 0.3954635 0.7620577 0.3832691 0.7619024 0.3958157 0.7344107 0.3832691 0.7619024 0.3836214 0.7342553 0.3958157 0.7344107 0.4205408 0.7345587 0.4083464 0.7344033 0.4208931 0.7069116 0.4083464 0.7344033 0.4086986 0.7067563 0.4208931 0.7069116 0.5314407 0.7637901 0.5192462 0.7636348 0.5317929 0.7361431 0.5192462 0.7636348 0.5195984 0.7359877 0.5317929 0.7361431 0.4943561 0.7633177 0.4821616 0.7631623 0.4947083 0.7356706 0.4821616 0.7631623 0.4825139 0.7355153 0.4947083 0.7356706 0.3587332 0.7337712 0.3465389 0.7336159 0.3590855 0.7061243 0.3465389 0.7336159 0.3468911 0.7059689 0.3590855 0.7061243 0.4576255 0.7350311 0.445431 0.7348757 0.4579777 0.7073841 0.445431 0.7348757 0.4457833 0.7072288 0.4579777 0.7073841 0.4572711 0.7628452 0.4450767 0.7626898 0.4576234 0.7351981 0.4450767 0.7626898 0.4454289 0.7350428 0.4576234 0.7351981 0.3710947 0.7339287 0.3589002 0.7337734 0.371447 0.7062817 0.3589002 0.7337734 0.3592524 0.7061263 0.371447 0.7062817 0.4078249 0.7622152 0.3956305 0.7620599 0.4081771 0.7345682 0.3956305 0.7620599 0.3959828 0.7344129 0.4081771 0.7345682 0.5070718 0.7356612 0.4948772 0.7355058 0.507424 0.7080141 0.4948772 0.7355058 0.4952294 0.7078588 0.507424 0.7080141 0.4449096 0.7626877 0.4327152 0.7625324 0.4452619 0.7350407 0.4327152 0.7625324 0.4330675 0.7348853 0.4452619 0.7350407 0.5189511 0.3171389 0.5350208 0.3064016 0.5052849 0.3308052 0.5350208 0.3064016 0.5528766 0.2990053 0.5052849 0.3308052 0.5528766 0.2990053 0.4945474 0.3468747 0.5052849 0.3308052 0.571832 0.2952348 0.4945474 0.3468747 0.5528766 0.2990053 0.4871514 0.3647305 0.4945474 0.3468747 0.571832 0.2952348 0.5911591 0.2952349 0.4871514 0.3647305 0.571832 0.2952348 0.4833809 0.383686 0.4871514 0.3647305 0.5911591 0.2952349 0.6101145 0.2990053 0.4833809 0.383686 0.5911591 0.2952349 0.4833809 0.4030128 0.4833809 0.383686 0.6101145 0.2990053 0.6279702 0.3064013 0.4833809 0.4030128 0.6101145 0.2990053 0.4871513 0.4219684 0.4833809 0.4030128 0.6279702 0.3064013 0.6440399 0.3171389 0.4871513 0.4219684 0.6279702 0.3064013 0.4945475 0.4398241 0.4871513 0.4219684 0.6440399 0.3171389 0.6577062 0.3308051 0.4945475 0.4398241 0.6440399 0.3171389 0.505285 0.4558939 0.4945475 0.4398241 0.6577062 0.3308051 0.6684435 0.3468747 0.505285 0.4558939 0.6577062 0.3308051 0.5189513 0.4695601 0.505285 0.4558939 0.6684435 0.3468747 0.6758396 0.3647302 0.5189513 0.4695601 0.6684435 0.3468747 0.5350208 0.4802975 0.5189513 0.4695601 0.6758396 0.3647302 0.6796101 0.3836858 0.5350208 0.4802975 0.6758396 0.3647302 0.5528768 0.4876936 0.5350208 0.4802975 0.6796101 0.3836858 0.6796101 0.4030128 0.5528768 0.4876936 0.6796101 0.3836858 0.5718322 0.491464 0.5528768 0.4876936 0.6796101 0.4030128 0.6758398 0.4219682 0.5718322 0.491464 0.6796101 0.4030128 0.5911591 0.491464 0.5718322 0.491464 0.6758398 0.4219682 0.6684438 0.439824 0.5911591 0.491464 0.6758398 0.4219682 0.6101148 0.4876936 0.5911591 0.491464 0.6684438 0.439824 0.6577064 0.4558935 0.6101148 0.4876936 0.6684438 0.439824 0.6279703 0.4802974 0.6101148 0.4876936 0.6577064 0.4558935 0.6440402 0.4695599 0.6279703 0.4802974 0.6577064 0.4558935 0.3465371 0.7337829 0.3587315 0.7339382 0.3461848 0.7614299 0.3587315 0.7339382 0.3583793 0.7615852 0.3461848 0.7614299 0.519079 0.7636327 0.5068846 0.7634773 0.5194313 0.7359856 0.5068846 0.7634773 0.5072368 0.7358303 0.5194313 0.7359856 0.8762223 0.2625701 0.9071549 0.2371844 0.8929389 0.2514006 0.9183247 0.220468 0.9071549 0.2371844 0.8762223 0.2625701 0.857648 0.2702639 0.9183247 0.220468 0.8762223 0.2625701 0.9260185 0.2018937 0.9183247 0.220468 0.857648 0.2702639 0.8379296 0.274186 0.9260185 0.2018937 0.857648 0.2702639 0.9299408 0.1821751 0.9260185 0.2018937 0.8379296 0.274186 0.817825 0.274186 0.9299408 0.1821751 0.8379296 0.274186 0.9299409 0.1620705 0.9299408 0.1821751 0.817825 0.274186 0.7981067 0.2702637 0.9299409 0.1620705 0.817825 0.274186 0.9260187 0.1423519 0.9299409 0.1620705 0.7981067 0.2702637 0.7795322 0.26257 0.9260187 0.1423519 0.7981067 0.2702637 0.9183249 0.1237776 0.9260187 0.1423519 0.7795322 0.26257 0.7628158 0.2514003 0.9183249 0.1237776 0.7795322 0.26257 0.9071553 0.107061 0.9183249 0.1237776 0.7628158 0.2514003 0.7485997 0.2371841 0.9071553 0.107061 0.7628158 0.2514003 0.8929392 0.09284496 0.9071553 0.107061 0.7485997 0.2371841 0.73743 0.2204676 0.8929392 0.09284496 0.7485997 0.2371841 0.8762227 0.08167523 0.8929392 0.09284496 0.73743 0.2204676 0.7297363 0.2018935 0.8762227 0.08167523 0.73743 0.2204676 0.8576483 0.07398158 0.8762227 0.08167523 0.7297363 0.2018935 0.7258141 0.1821749 0.8576483 0.07398158 0.7297363 0.2018935 0.8379297 0.07005918 0.8576483 0.07398158 0.7258141 0.1821749 0.7258141 0.1620703 0.8379297 0.07005918 0.7258141 0.1821749 0.8178251 0.07005918 0.8379297 0.07005918 0.7258141 0.1620703 0.7297363 0.142352 0.8178251 0.07005918 0.7258141 0.1620703 0.7981066 0.07398134 0.8178251 0.07005918 0.7297363 0.142352 0.73743 0.1237774 0.7981066 0.07398134 0.7297363 0.142352 0.7795324 0.08167523 0.7981066 0.07398134 0.73743 0.1237774 0.7485995 0.1070613 0.7795324 0.08167523 0.73743 0.1237774 0.7628157 0.09284496 0.7795324 0.08167523 0.7485995 0.1070613 + + + + + + + + + + + + + + + 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 +

0 0 0 2 1 1 1 2 2 0 0 3 1 2 4 3 3 5 6 4 6 5 5 7 4 6 8 5 5 9 7 7 10 4 6 11 10 8 12 9 9 13 8 10 14 9 9 15 11 11 16 8 10 17 14 12 18 13 13 19 12 14 20 13 13 21 15 15 22 12 14 23 18 16 24 17 17 25 16 18 26 17 17 27 19 19 28 16 18 29 22 20 30 21 21 31 20 22 32 21 21 33 23 23 34 20 22 35 26 24 36 25 25 37 24 26 38 25 25 39 27 27 40 24 26 41 30 28 42 29 29 43 28 30 44 29 29 45 31 31 46 28 30 47 34 32 48 33 33 49 32 34 50 33 33 51 35 35 52 32 34 53 38 36 54 37 37 55 36 38 56 37 37 57 39 39 58 36 38 59 42 40 60 41 41 61 40 42 62 41 41 63 43 43 64 40 42 65 46 44 66 45 45 67 44 46 68 45 45 69 47 47 70 44 46 71 50 48 72 49 49 73 48 50 74 49 49 75 51 51 76 48 50 77 54 52 78 53 53 79 52 54 80 53 53 81 55 55 82 52 54 83 58 56 84 57 57 85 56 58 86 57 57 87 59 59 88 56 58 89 62 60 90 61 61 91 60 62 92 61 61 93 63 63 94 60 62 95 66 64 96 65 65 97 64 66 98 65 65 99 67 67 100 64 66 101 70 68 102 69 69 103 68 70 104 69 69 105 71 71 106 68 70 107 74 72 108 73 73 109 72 74 110 73 73 111 75 75 112 72 74 113 78 76 114 77 77 115 76 78 116 77 77 117 79 79 118 76 78 119 82 80 120 81 81 121 80 82 122 81 81 123 83 83 124 80 82 125 86 84 126 85 85 127 84 86 128 85 85 129 87 87 130 84 86 131 90 88 132 89 89 133 88 90 134 89 89 135 91 91 136 88 90 137 94 92 138 93 93 139 92 94 140 93 93 141 95 95 142 92 94 143 98 96 144 97 97 145 96 98 146 97 97 147 99 99 148 96 98 149 102 100 150 101 101 151 100 102 152 101 101 153 103 103 154 100 102 155 106 104 156 105 105 157 104 106 158 105 105 159 107 107 160 104 106 161 110 108 162 109 109 163 108 110 164 109 109 165 111 111 166 108 110 167 114 112 168 113 113 169 112 114 170 113 113 171 115 115 172 112 114 173 118 116 174 117 117 175 116 118 176 117 117 177 119 119 178 116 118 179 122 120 180 121 121 181 120 122 182 121 121 183 123 123 184 120 122 185 123 123 186 124 124 187 120 122 188 125 125 189 124 124 190 123 123 191 126 126 192 124 124 193 125 125 194 127 127 195 126 126 196 125 125 197 128 128 198 126 126 199 127 127 200 129 129 201 128 128 202 127 127 203 130 130 204 128 128 205 129 129 206 131 131 207 130 130 208 129 129 209 132 132 210 130 130 211 131 131 212 133 133 213 132 132 214 131 131 215 134 134 216 132 132 217 133 133 218 135 135 219 134 134 220 133 133 221 136 136 222 134 134 223 135 135 224 137 137 225 136 136 226 135 135 227 138 138 228 136 136 229 137 137 230 139 139 231 138 138 232 137 137 233 140 140 234 138 138 235 139 139 236 141 141 237 140 140 238 139 139 239 142 142 240 140 140 241 141 141 242 143 143 243 142 142 244 141 141 245 144 144 246 142 142 247 143 143 248 145 145 249 144 144 250 143 143 251 146 146 252 144 144 253 145 145 254 147 147 255 146 146 256 145 145 257 148 148 258 146 146 259 147 147 260 149 149 261 148 148 262 147 147 263 150 150 264 148 148 265 149 149 266 151 151 267 150 150 268 149 149 269 154 152 270 153 153 271 152 154 272 153 153 273 155 155 274 152 154 275 158 156 276 157 157 277 156 158 278 157 157 279 159 159 280 156 158 281 162 160 282 161 161 283 160 162 284 163 163 285 161 161 286 162 160 287 164 164 288 163 163 289 162 160 290 165 165 291 163 163 292 164 164 293 166 166 294 165 165 295 164 164 296 167 167 297 165 165 298 166 166 299 168 168 300 167 167 301 166 166 302 169 169 303 167 167 304 168 168 305 170 170 306 169 169 307 168 168 308 171 171 309 169 169 310 170 170 311 172 172 312 171 171 313 170 170 314 173 173 315 171 171 316 172 172 317 174 174 318 173 173 319 172 172 320 175 175 321 173 173 322 174 174 323 176 176 324 175 175 325 174 174 326 177 177 327 175 175 328 176 176 329 178 178 330 177 177 331 176 176 332 179 179 333 177 177 334 178 178 335 180 180 336 179 179 337 178 178 338 181 181 339 179 179 340 180 180 341 182 182 342 181 181 343 180 180 344 183 183 345 181 181 346 182 182 347 184 184 348 183 183 349 182 182 350 185 185 351 183 183 352 184 184 353 186 186 354 185 185 355 184 184 356 187 187 357 185 185 358 186 186 359 188 188 360 187 187 361 186 186 362 189 189 363 187 187 364 188 188 365 190 190 366 189 189 367 188 188 368 191 191 369 189 189 370 190 190 371

+
+
+
+ + + + 0.4829 -0.14 10e-7 0.475563 0.14 0.08385497 0.4829 0.14 10e-7 0.475564 -0.14 0.08385497 0.453777 0.14 0.165162 0.453777 -0.14 0.165162 0.418203 0.14 0.24145 0.418204 -0.14 0.24145 0.369923 0.14 0.310402 0.369923 -0.14 0.310402 0.310402 0.14 0.369923 0.310402 -0.14 0.369923 0.24145 0.14 0.418204 0.24145 -0.14 0.418204 0.165161 0.14 0.453778 0.165161 -0.14 0.453778 0.08385396 0.14 0.475564 0.08385396 -0.14 0.475564 0.475564 -0.14 -0.083853 0.453778 -0.14 -0.16516 0.475563 0.14 -0.083853 0.453778 0.14 -0.16516 0.418204 -0.14 -0.2414489 0.418204 0.14 -0.2414489 0.369923 -0.14 -0.310401 0.369923 0.14 -0.310401 0.310403 -0.14 -0.369922 0.310403 0.14 -0.369922 0.241451 -0.14 -0.418203 0.241451 0.14 -0.418203 0.165162 -0.14 -0.453777 0.165162 0.14 -0.453777 0.08385598 -0.14 -0.475564 0.08385598 0.14 -0.475563 10e-7 -0.14 -0.4829 10e-7 0.14 -0.4829 -0.08385396 -0.14 -0.475564 -0.08385396 0.14 -0.475564 0.4829 0.14 10e-7 0.406627 0.14 0.07169896 0.4129 0.14 0 0.475563 0.14 0.08385497 0.387999 0.14 0.14122 0.453777 0.14 0.165162 0.357582 0.14 0.20645 0.418203 0.14 0.24145 0.316299 0.14 0.265407 0.369923 0.14 0.310402 0.265407 0.14 0.3163 0.310402 0.14 0.369923 0.20645 0.14 0.357582 0.24145 0.14 0.418204 0.14122 0.14 0.387999 0.165161 0.14 0.453778 0.07169896 0.14 0.406627 0.08385396 0.14 0.475564 0 0.14 0.4129 -10e-7 0.14 0.4829 -0.07169997 0.14 0.406627 -0.08385497 0.14 0.475563 -0.141221 0.14 0.387999 -0.165162 0.14 0.453777 -0.20645 0.14 0.357582 -0.241451 0.14 0.418203 -0.265407 0.14 0.316299 -0.310403 0.14 0.369922 -0.3163 0.14 0.265407 -0.369923 0.14 0.310402 -0.357582 0.14 0.206449 -0.418204 0.14 0.2414489 -0.387999 0.14 0.14122 -0.453778 0.14 0.165161 -0.406627 0.14 0.07169896 -0.475564 0.14 0.08385396 -0.4129 0.14 -10e-7 -0.4829 0.14 -10e-7 -0.406627 0.14 -0.07169997 -0.475564 0.14 -0.08385497 -0.387999 0.14 -0.141221 -0.453777 0.14 -0.165162 -0.357582 0.14 -0.2064509 -0.418203 0.14 -0.241451 -0.316299 0.14 -0.265408 -0.369922 0.14 -0.310403 -0.265407 0.14 -0.3163 -0.310402 0.14 -0.369923 -0.206449 0.14 -0.357582 -0.2414489 0.14 -0.418204 -0.141219 0.14 -0.387999 -0.165161 0.14 -0.453778 -0.07169896 0.14 -0.406627 -0.08385396 0.14 -0.475564 10e-7 0.14 -0.4129 10e-7 0.14 -0.4829 0.07169997 0.14 -0.406627 0.08385598 0.14 -0.475563 0.141221 0.14 -0.387999 0.165162 0.14 -0.453777 0.2064509 0.14 -0.357581 0.241451 0.14 -0.418203 0.265408 0.14 -0.316299 0.310403 0.14 -0.369922 0.3163 0.14 -0.265406 0.369923 0.14 -0.310401 0.357582 0.14 -0.206449 0.418204 0.14 -0.2414489 0.387999 0.14 -0.141219 0.453778 0.14 -0.16516 0.406627 0.14 -0.071698 0.475563 0.14 -0.083853 0.4129 0.14 0 0.406627 -0.14 0.07169896 0.4129 -0.14 10e-7 0.406627 0.14 0.07169896 0.387999 -0.14 0.14122 0.387999 0.14 0.14122 0.357582 -0.14 0.20645 0.357582 0.14 0.20645 0.3163 -0.14 0.265407 0.316299 0.14 0.265407 0.265407 -0.14 0.3163 0.265407 0.14 0.3163 0.20645 -0.14 0.357582 0.20645 0.14 0.357582 0.14122 -0.14 0.387999 0.14122 0.14 0.387999 0.07169896 -0.14 0.406627 0.07169896 0.14 0.406627 0.4829 -0.14 10e-7 0.406627 -0.14 0.07169896 0.475564 -0.14 0.08385497 0.4129 -0.14 10e-7 0.387999 -0.14 0.14122 0.453777 -0.14 0.165162 0.357582 -0.14 0.20645 0.418204 -0.14 0.24145 0.3163 -0.14 0.265407 0.369923 -0.14 0.310402 0.265407 -0.14 0.3163 0.310402 -0.14 0.369923 0.20645 -0.14 0.357582 0.24145 -0.14 0.418204 0.14122 -0.14 0.387999 0.165161 -0.14 0.453778 0.07169896 -0.14 0.406627 0.08385396 -0.14 0.475564 0 -0.14 0.4129 -10e-7 -0.14 0.4829 -0.07169997 -0.14 0.406627 -0.08385497 -0.14 0.475564 -0.141221 -0.14 0.387999 -0.165162 -0.14 0.453777 -0.20645 -0.14 0.357582 -0.241451 -0.14 0.418203 -0.265407 -0.14 0.316299 -0.310403 -0.14 0.369923 -0.3163 -0.14 0.265407 -0.369923 -0.14 0.310402 -0.357582 -0.14 0.20645 -0.418204 -0.14 0.2414489 -0.387999 -0.14 0.14122 -0.453778 -0.14 0.165161 -0.406627 -0.14 0.07169896 -0.475564 -0.14 0.08385396 -0.4129 -0.14 -10e-7 -0.4829 -0.14 -10e-7 -0.406627 -0.14 -0.07169997 -0.475564 -0.14 -0.08385598 -0.387999 -0.14 -0.141221 -0.453778 -0.14 -0.165162 -0.357582 -0.14 -0.2064509 -0.418203 -0.14 -0.241451 -0.316299 -0.14 -0.265408 -0.369923 -0.14 -0.310403 -0.265407 -0.14 -0.3163 -0.310402 -0.14 -0.369924 -0.206449 -0.14 -0.357582 -0.2414489 -0.14 -0.418204 -0.141219 -0.14 -0.387999 -0.165161 -0.14 -0.453778 -0.07169896 -0.14 -0.406627 -0.08385396 -0.14 -0.475564 10e-7 -0.14 -0.4129 10e-7 -0.14 -0.4829 0.07169997 -0.14 -0.406627 0.08385598 -0.14 -0.475564 0.141221 -0.14 -0.387999 0.165162 -0.14 -0.453777 0.2064509 -0.14 -0.357581 0.241451 -0.14 -0.418203 0.265408 -0.14 -0.316299 0.310403 -0.14 -0.369922 0.3163 -0.14 -0.265406 0.369923 -0.14 -0.310401 0.357582 -0.14 -0.206449 0.418204 -0.14 -0.2414489 0.387999 -0.14 -0.141219 0.453778 -0.14 -0.16516 0.406627 -0.14 -0.071698 0.475564 -0.14 -0.083853 0.08385396 -0.14 0.475564 -10e-7 0.14 0.4829 0.08385396 0.14 0.475564 -10e-7 -0.14 0.4829 -0.08385497 0.14 0.475563 -0.08385497 -0.14 0.475564 -0.165162 0.14 0.453777 -0.165162 -0.14 0.453777 -0.241451 0.14 0.418203 -0.241451 -0.14 0.418203 -0.310403 0.14 0.369922 -0.310403 -0.14 0.369923 -0.369923 0.14 0.310402 -0.369923 -0.14 0.310402 -0.418204 0.14 0.2414489 -0.418204 -0.14 0.2414489 -0.453778 0.14 0.165161 -0.453778 -0.14 0.165161 -0.475564 0.14 0.08385396 -0.475564 -0.14 0.08385396 -0.4829 0.14 -10e-7 -0.4829 -0.14 -10e-7 -0.475564 0.14 -0.08385497 -0.475564 -0.14 -0.08385598 -0.453777 0.14 -0.165162 -0.453778 -0.14 -0.165162 -0.418203 0.14 -0.241451 -0.418203 -0.14 -0.241451 -0.369922 0.14 -0.310403 -0.369923 -0.14 -0.310403 -0.310402 0.14 -0.369923 -0.310402 -0.14 -0.369924 -0.2414489 0.14 -0.418204 -0.2414489 -0.14 -0.418204 -0.165161 0.14 -0.453778 -0.165161 -0.14 -0.453778 -0.08385396 0.14 -0.475564 -0.08385396 -0.14 -0.475564 0.07169896 0.14 0.406627 0 -0.14 0.4129 0.07169896 -0.14 0.406627 0 0.14 0.4129 -0.07169997 -0.14 0.406627 -0.07169997 0.14 0.406627 -0.141221 -0.14 0.387999 -0.141221 0.14 0.387999 -0.20645 -0.14 0.357582 -0.20645 0.14 0.357582 -0.265407 -0.14 0.316299 -0.265407 0.14 0.316299 -0.3163 -0.14 0.265407 -0.3163 0.14 0.265407 -0.357582 -0.14 0.20645 -0.357582 0.14 0.206449 -0.387999 -0.14 0.14122 -0.387999 0.14 0.14122 -0.406627 -0.14 0.07169896 -0.406627 0.14 0.07169896 -0.406627 0.14 0.07169896 -0.4129 -0.14 -10e-7 -0.406627 -0.14 0.07169896 -0.4129 0.14 -10e-7 -0.406627 -0.14 -0.07169997 -0.406627 0.14 -0.07169997 -0.387999 -0.14 -0.141221 -0.387999 0.14 -0.141221 -0.357582 -0.14 -0.2064509 -0.357582 0.14 -0.2064509 -0.316299 -0.14 -0.265408 -0.316299 0.14 -0.265408 -0.265407 -0.14 -0.3163 -0.265407 0.14 -0.3163 -0.206449 -0.14 -0.357582 -0.206449 0.14 -0.357582 -0.141219 -0.14 -0.387999 -0.141219 0.14 -0.387999 -0.07169896 -0.14 -0.406627 -0.07169896 0.14 -0.406627 -0.07169896 0.14 -0.406627 10e-7 -0.14 -0.4129 -0.07169896 -0.14 -0.406627 10e-7 0.14 -0.4129 0.07169997 -0.14 -0.406627 0.07169997 0.14 -0.406627 0.141221 -0.14 -0.387999 0.141221 0.14 -0.387999 0.2064509 -0.14 -0.357581 0.2064509 0.14 -0.357581 0.265408 -0.14 -0.316299 0.265408 0.14 -0.316299 0.3163 -0.14 -0.265406 0.3163 0.14 -0.265406 0.357582 -0.14 -0.206449 0.357582 0.14 -0.206449 0.387999 -0.14 -0.141219 0.387999 0.14 -0.141219 0.406627 -0.14 -0.071698 0.406627 0.14 -0.071698 0.406627 0.14 -0.071698 0.4129 -0.14 10e-7 0.406627 -0.14 -0.071698 0.4129 0.14 0 + + + + + + + + + + 1 0 0 1 0 0 0.9848018 0 0.1736503 0.9848018 0 0.1736503 0.9396649 0 0.3420209 0.9396649 0 0.3420209 0.8660237 0 0.4999848 0.8660237 0 0.4999848 0.7660451 0 0.6427809 0.7660146 0 0.6427809 0.6427809 0 0.7660146 0.6427809 0 0.7660146 0.4999848 0 0.8660237 0.4999848 0 0.8660237 0.3419904 0 0.9396649 0.3419904 0 0.9396649 0.2587969 0 0.9659109 0.2587969 0 0.9659109 0.9848018 0 -0.1736198 0.9848018 0 -0.1736198 0.9396649 0 -0.3419904 0.9396649 0 -0.3419904 0.8660237 0 -0.4999848 0.8660237 0 -0.4999848 0.7660451 0 -0.6427809 0.7660451 0 -0.6427809 0.6427809 0 -0.7660146 0.6427809 0 -0.7660146 0.4999848 0 -0.8660237 0.4999848 0 -0.8660237 0.3420209 0 -0.9396649 0.3420209 0 -0.9396649 0.1736503 0 -0.9848018 0.1736503 0 -0.9848018 0 0 -1 0 0 -1 -0.0871303 0 -0.9961852 -0.0871303 0 -0.9961852 0 1 0 0 1 0 0 1 0 0 1 0 0 0.9999695 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0.9999695 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0.9999695 0 0 1 0 0 0.9999695 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0.9999695 0 0 1 0 0 0.9999695 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0.9999695 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0.9999695 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0.9999695 0 0 1 0 -0.9961852 0 -0.0871303 -0.9848018 0 -0.1736198 -0.9961852 0 -0.0871303 -0.9848018 0 -0.1736198 -0.9396649 0 -0.3419904 -0.9396649 0 -0.3419904 -0.8660237 0 -0.4999848 -0.8660237 0 -0.4999848 -0.7660146 0 -0.6427809 -0.7660146 0 -0.6427809 -0.6427809 0 -0.7660146 -0.6427809 0 -0.7660146 -0.4999848 0 -0.8660237 -0.4999848 0 -0.8660237 -0.3419904 0 -0.9396649 -0.3419904 0 -0.9396649 -0.2587969 0 -0.9659109 -0.2587969 0 -0.9659109 0 -0.9999695 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -0.9999695 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -0.9999695 0 0 -1 0 0 -0.9999695 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -0.9999695 0 0 -1 0 0 -1 0 0 -0.9999695 0 0 -1 0 0 -0.9999695 0 0 -1 0 0 -0.9999695 0 0 -1 0 0 -1 0 0 -0.9999695 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -0.9999695 0 0 -1 0 0 -1 0 0 -0.9999695 0 0 -0.9999695 0 0 -0.9999695 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -0.9999695 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -0.9999695 0 0 -0.9999695 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0.0871303 0 0.9961852 0 0 0.9999695 0.0871303 0 0.9961852 0 0 1 -0.1736503 0 0.9848018 -0.1736503 0 0.9848018 -0.3419904 0 0.9396649 -0.3420209 0 0.9396649 -0.4999848 0 0.8660237 -0.4999848 0 0.8660237 -0.6427809 0 0.7660146 -0.6427809 0 0.7660146 -0.7660451 0 0.6427809 -0.7660451 0 0.6427809 -0.8660237 0 0.4999848 -0.8660237 0 0.4999848 -0.9396649 0 0.3420209 -0.9396649 0 0.3419904 -0.9848018 0 0.1736198 -0.9848018 0 0.1736198 -1 0 0 -1 0 0 -0.9848018 0 -0.1736503 -0.9848018 0 -0.1736198 -0.9396649 0 -0.3420209 -0.9396649 0 -0.3420209 -0.8660237 0 -0.4999848 -0.8660237 0 -0.4999848 -0.7660146 0 -0.6427809 -0.7660451 0 -0.6427809 -0.6427809 0 -0.7660451 -0.6427809 0 -0.7660451 -0.4999848 0 -0.8660237 -0.4999848 0 -0.8660237 -0.3420209 0 -0.9396649 -0.3419904 0 -0.9396649 -0.2587969 0 -0.9659109 -0.2587969 0 -0.9659109 -0.0871303 0 -0.9961852 0 0 -1 -0.0871303 0 -0.9961852 0 0 -1 0.1736198 0 -0.9848018 0.1736198 0 -0.9848018 0.3419904 0 -0.9396649 0.3419904 0 -0.9396649 0.4999848 0 -0.8659932 0.4999848 0 -0.8659932 0.6427809 0 -0.7660146 0.6427809 0 -0.7660146 0.7660146 0 -0.6427809 0.7660146 0 -0.6427809 0.8660237 0 -0.4999848 0.8660237 0 -0.4999848 0.9396649 0 -0.3419904 0.9396649 0 -0.3419904 0.9659109 0 -0.2587969 0.9659109 0 -0.2587969 0.9961852 0 -0.0871303 1 0 0 0.9961852 0 -0.0871303 1 0 0 0.9848018 0 0.1736198 0.9848018 0 0.1736198 0.9396649 0 0.3419904 0.9396649 0 0.3419904 0.8660237 0 0.4999848 0.8660237 0 0.4999848 0.7660146 0 0.6427809 0.7660146 0 0.6427809 0.6427809 0 0.7660451 0.6427809 0 0.7660451 0.4999848 0 0.8660237 0.4999848 0 0.8660237 0.3419904 0 0.9396649 0.3419904 0 0.9396649 0.2587969 0 0.9659109 0.2587969 0 0.9659109 0.0871303 0 0.9961852 0 0 1 0.0871303 0 0.9961852 0 0 1 -0.1736198 0 0.9848018 -0.1736198 0 0.9848018 -0.3420209 0 0.9396649 -0.3420209 0 0.9396649 -0.4999848 0 0.8659932 -0.4999848 0 0.8659932 -0.6427809 0 0.7660146 -0.6427809 0 0.7660146 -0.7660451 0 0.6427809 -0.7660451 0 0.6427809 -0.8660237 0 0.4999848 -0.8660237 0 0.4999848 -0.9396649 0 0.3419904 -0.9396649 0 0.3419904 -0.9659109 0 0.2587969 -0.9659109 0 0.2587969 -0.9961852 0 0.0871303 -0.9961852 0 0.0871303 -0.9961852 0 0.0871303 -0.9961852 0 0.0871303 + + + + + + + + + + 0.446618 0.832038 0.446618 0.989969 0.392159 0.989969 0.446618 0.832038 0.392159 0.989969 0.392159 0.832038 0.392159 0.989969 0.3377 0.989969 0.392159 0.832038 0.3377 0.989969 0.3377 0.832038 0.392159 0.832038 0.3377 0.989969 0.283242 0.989969 0.3377 0.832038 0.283242 0.989969 0.283242 0.832038 0.3377 0.832038 0.283242 0.989969 0.228783 0.989969 0.283242 0.832038 0.228783 0.989969 0.228783 0.832038 0.283242 0.832038 0.228783 0.989969 0.174324 0.989969 0.228783 0.832038 0.174324 0.989969 0.174324 0.832038 0.228783 0.832038 0.174324 0.989969 0.119865 0.989969 0.174324 0.832038 0.119865 0.989969 0.119865 0.832038 0.174324 0.832038 0.119865 0.989969 0.06540596 0.989969 0.119865 0.832038 0.06540596 0.989969 0.06540596 0.832038 0.119865 0.832038 0.06540596 0.989969 0.010948 0.989969 0.06540596 0.832038 0.010948 0.989969 0.010948 0.832038 0.06540596 0.832038 0.446618 0.832038 0.501083 0.832038 0.446618 0.989969 0.501083 0.989963 0.501083 0.832038 0.555542 0.832038 0.555542 0.989963 0.501083 0.989963 0.555542 0.832038 0.555542 0.989963 0.555542 0.832038 0.610001 0.832038 0.610001 0.989963 0.555542 0.989963 0.610001 0.832038 0.610001 0.989963 0.610001 0.832038 0.66446 0.832038 0.66446 0.989963 0.610001 0.989963 0.66446 0.832038 0.66446 0.989963 0.66446 0.832038 0.718919 0.832038 0.718919 0.989963 0.66446 0.989963 0.718919 0.832038 0.718919 0.989963 0.718919 0.832038 0.77332 0.832038 0.77332 0.989963 0.718919 0.989963 0.77332 0.832038 0.77332 0.989963 0.77332 0.832038 0.827836 0.832038 0.827836 0.989963 0.77332 0.989963 0.827836 0.832038 0.827836 0.989963 0.827836 0.832038 0.882295 0.832038 0.882295 0.989963 0.827836 0.989963 0.882295 0.832038 0.882295 0.989963 0.882295 0.832038 0.936754 0.832038 0.936754 0.989963 0.882295 0.989963 0.936754 0.832038 0.936754 0.989963 0.936754 0.832038 0.991213 0.832038 0.991213 0.989963 0.936754 0.989963 0.991213 0.832038 0.296563 0.08183699 0.276893 0.06533098 0.314222 0.06417798 0.276893 0.06533098 0.291217 0.04487395 0.314222 0.06417798 0.276893 0.06533098 0.254656 0.05249297 0.291217 0.04487395 0.254656 0.05249297 0.26521 0.029859 0.291217 0.04487395 0.254656 0.05249297 0.230526 0.04370999 0.26521 0.029859 0.230526 0.04370999 0.23699 0.01958799 0.26521 0.029859 0.230526 0.04370999 0.2052389 0.03925096 0.23699 0.01958799 0.2052389 0.03925096 0.207415 0.014373 0.23699 0.01958799 0.2052389 0.03925096 0.179561 0.03925096 0.207415 0.014373 0.179561 0.03925096 0.177384 0.014373 0.207415 0.014373 0.179561 0.03925096 0.154274 0.04370999 0.177384 0.014373 0.154274 0.04370999 0.14781 0.01958799 0.177384 0.014373 0.154274 0.04370999 0.130144 0.05249297 0.14781 0.01958799 0.130144 0.05249297 0.11959 0.029859 0.14781 0.01958799 0.130144 0.05249297 0.1079069 0.06533199 0.11959 0.029859 0.1079069 0.06533199 0.09358298 0.04487395 0.11959 0.029859 0.1079069 0.06533199 0.08823698 0.08183699 0.09358298 0.04487395 0.08823698 0.08183699 0.07057797 0.06417798 0.09358298 0.04487395 0.08823698 0.08183699 0.07173097 0.101507 0.07057797 0.06417798 0.07173097 0.101507 0.051274 0.08718299 0.07057797 0.06417798 0.07173097 0.101507 0.05889296 0.123745 0.051274 0.08718299 0.05889296 0.123745 0.03625899 0.11319 0.051274 0.08718299 0.05889296 0.123745 0.05010998 0.1478739 0.03625899 0.11319 0.05010998 0.1478739 0.02598798 0.1414099 0.03625899 0.11319 0.05010998 0.1478739 0.04565197 0.173161 0.02598798 0.1414099 0.04565197 0.173161 0.02077299 0.170985 0.02598798 0.1414099 0.04565197 0.173161 0.04565197 0.198839 0.02077299 0.170985 0.04565197 0.198839 0.02077299 0.201016 0.02077299 0.170985 0.04565197 0.198839 0.05010998 0.2241269 0.02077299 0.201016 0.05010998 0.2241269 0.02598798 0.23059 0.02077299 0.201016 0.05010998 0.2241269 0.05889296 0.248256 0.02598798 0.23059 0.05889296 0.248256 0.03625899 0.25881 0.02598798 0.23059 0.05889296 0.248256 0.07173198 0.270493 0.03625899 0.25881 0.07173198 0.270493 0.051274 0.284818 0.03625899 0.25881 0.07173198 0.270493 0.08823698 0.290163 0.051274 0.284818 0.08823698 0.290163 0.07057797 0.307822 0.051274 0.284818 0.08823698 0.290163 0.1079069 0.306669 0.07057797 0.307822 0.1079069 0.306669 0.09358298 0.327126 0.07057797 0.307822 0.1079069 0.306669 0.130145 0.319507 0.09358298 0.327126 0.130145 0.319507 0.11959 0.342141 0.09358298 0.327126 0.130145 0.319507 0.154274 0.32829 0.11959 0.342141 0.154274 0.32829 0.14781 0.352412 0.11959 0.342141 0.154274 0.32829 0.179561 0.332749 0.14781 0.352412 0.179561 0.332749 0.177385 0.357627 0.14781 0.352412 0.179561 0.332749 0.2052389 0.332748 0.177385 0.357627 0.2052389 0.332748 0.2074159 0.357627 0.177385 0.357627 0.2052389 0.332748 0.230527 0.32829 0.2074159 0.357627 0.230527 0.32829 0.23699 0.352412 0.2074159 0.357627 0.230527 0.32829 0.254656 0.319507 0.23699 0.352412 0.254656 0.319507 0.26521 0.342141 0.23699 0.352412 0.254656 0.319507 0.276893 0.306668 0.26521 0.342141 0.276893 0.306668 0.291218 0.327126 0.26521 0.342141 0.276893 0.306668 0.296563 0.290163 0.291218 0.327126 0.296563 0.290163 0.314223 0.307822 0.291218 0.327126 0.296563 0.290163 0.313069 0.270493 0.314223 0.307822 0.313069 0.270493 0.333526 0.284817 0.314223 0.307822 0.313069 0.270493 0.325907 0.248255 0.333526 0.284817 0.325907 0.248255 0.348541 0.258809 0.333526 0.284817 0.325907 0.248255 0.33469 0.224126 0.348541 0.258809 0.33469 0.224126 0.358812 0.23059 0.348541 0.258809 0.33469 0.224126 0.339149 0.198839 0.358812 0.23059 0.339149 0.198839 0.364027 0.2010149 0.358812 0.23059 0.339149 0.198839 0.339148 0.173161 0.364027 0.2010149 0.339148 0.173161 0.364027 0.170984 0.364027 0.2010149 0.339148 0.173161 0.33469 0.147873 0.364027 0.170984 0.33469 0.147873 0.358812 0.1414099 0.364027 0.170984 0.33469 0.147873 0.325907 0.123744 0.358812 0.1414099 0.325907 0.123744 0.348541 0.11319 0.358812 0.1414099 0.325907 0.123744 0.313068 0.101507 0.348541 0.11319 0.313068 0.101507 0.333525 0.08718198 0.348541 0.11319 0.313068 0.101507 0.296563 0.08183699 0.333525 0.08718198 0.296563 0.08183699 0.314222 0.06417798 0.333525 0.08718198 0.164038 0.2935 0.163977 0.273412 0.228497 0.293303 0.163977 0.273412 0.228435 0.273214 0.228497 0.293303 0.163977 0.273412 0.16391 0.251614 0.228435 0.273214 0.16391 0.251614 0.2283689 0.251417 0.228435 0.273214 0.16391 0.251614 0.1638399 0.22877 0.2283689 0.251417 0.1638399 0.22877 0.228299 0.228573 0.2283689 0.251417 0.1638399 0.22877 0.163769 0.205574 0.228299 0.228573 0.163769 0.205574 0.228227 0.205376 0.228299 0.228573 0.163769 0.205574 0.163699 0.18273 0.228227 0.205376 0.163699 0.18273 0.228157 0.182532 0.228227 0.205376 0.163699 0.18273 0.163632 0.160932 0.228157 0.182532 0.163632 0.160932 0.22809 0.160735 0.228157 0.182532 0.163632 0.160932 0.16357 0.140844 0.22809 0.160735 0.16357 0.140844 0.228029 0.140646 0.22809 0.160735 0.16357 0.140844 0.163516 0.123074 0.228029 0.140646 0.163516 0.123074 0.2279739 0.122876 0.228029 0.140646 0.291217 0.04487395 0.276893 0.06533199 0.314222 0.06417798 0.276893 0.06533199 0.296563 0.08183699 0.314222 0.06417798 0.254656 0.05249297 0.276893 0.06533199 0.291217 0.04487395 0.26521 0.029859 0.254656 0.05249297 0.291217 0.04487395 0.230526 0.04370999 0.254656 0.05249297 0.26521 0.029859 0.23699 0.01958799 0.230526 0.04370999 0.26521 0.029859 0.2052389 0.03925198 0.230526 0.04370999 0.23699 0.01958799 0.207415 0.014373 0.2052389 0.03925198 0.23699 0.01958799 0.179561 0.03925198 0.2052389 0.03925198 0.207415 0.014373 0.177385 0.014373 0.179561 0.03925198 0.207415 0.014373 0.154274 0.04370999 0.179561 0.03925198 0.177385 0.014373 0.14781 0.01958799 0.154274 0.04370999 0.177385 0.014373 0.130145 0.05249297 0.154274 0.04370999 0.14781 0.01958799 0.11959 0.029859 0.130145 0.05249297 0.14781 0.01958799 0.1079069 0.06533199 0.130145 0.05249297 0.11959 0.029859 0.09358298 0.04487395 0.1079069 0.06533199 0.11959 0.029859 0.08823698 0.08183699 0.1079069 0.06533199 0.09358298 0.04487395 0.07057797 0.06417798 0.08823698 0.08183699 0.09358298 0.04487395 0.07173097 0.101507 0.08823698 0.08183699 0.07057797 0.06417798 0.051274 0.08718299 0.07173097 0.101507 0.07057797 0.06417798 0.05889296 0.123745 0.07173097 0.101507 0.051274 0.08718299 0.03625899 0.11319 0.05889296 0.123745 0.051274 0.08718299 0.05010998 0.1478739 0.05889296 0.123745 0.03625899 0.11319 0.02598798 0.1414099 0.05010998 0.1478739 0.03625899 0.11319 0.04565095 0.173161 0.05010998 0.1478739 0.02598798 0.1414099 0.02077299 0.170985 0.04565095 0.173161 0.02598798 0.1414099 0.04565197 0.198839 0.04565095 0.173161 0.02077299 0.170985 0.02077299 0.201016 0.04565197 0.198839 0.02077299 0.170985 0.05010998 0.2241269 0.04565197 0.198839 0.02077299 0.201016 0.02598798 0.23059 0.05010998 0.2241269 0.02077299 0.201016 0.05889296 0.248256 0.05010998 0.2241269 0.02598798 0.23059 0.03625899 0.25881 0.05889296 0.248256 0.02598798 0.23059 0.07173198 0.270493 0.05889296 0.248256 0.03625899 0.25881 0.051274 0.284818 0.07173198 0.270493 0.03625899 0.25881 0.08823698 0.290163 0.07173198 0.270493 0.051274 0.284818 0.07057797 0.307823 0.08823698 0.290163 0.051274 0.284818 0.1079069 0.306669 0.08823698 0.290163 0.07057797 0.307823 0.09358298 0.327126 0.1079069 0.306669 0.07057797 0.307823 0.130145 0.319507 0.1079069 0.306669 0.09358298 0.327126 0.11959 0.342141 0.130145 0.319507 0.09358298 0.327126 0.154274 0.32829 0.130145 0.319507 0.11959 0.342141 0.14781 0.352413 0.154274 0.32829 0.11959 0.342141 0.179561 0.332749 0.154274 0.32829 0.14781 0.352413 0.177385 0.357627 0.179561 0.332749 0.14781 0.352413 0.2052389 0.332749 0.179561 0.332749 0.177385 0.357627 0.2074159 0.357627 0.2052389 0.332749 0.177385 0.357627 0.230527 0.32829 0.2052389 0.332749 0.2074159 0.357627 0.23699 0.352412 0.230527 0.32829 0.2074159 0.357627 0.254656 0.319507 0.230527 0.32829 0.23699 0.352412 0.26521 0.342141 0.254656 0.319507 0.23699 0.352412 0.276893 0.306668 0.254656 0.319507 0.26521 0.342141 0.291218 0.327126 0.276893 0.306668 0.26521 0.342141 0.296564 0.290163 0.276893 0.306668 0.291218 0.327126 0.314223 0.307822 0.296564 0.290163 0.291218 0.327126 0.313069 0.270493 0.296564 0.290163 0.314223 0.307822 0.333526 0.284817 0.313069 0.270493 0.314223 0.307822 0.325908 0.248255 0.313069 0.270493 0.333526 0.284817 0.348541 0.25881 0.325908 0.248255 0.333526 0.284817 0.33469 0.224126 0.325908 0.248255 0.348541 0.25881 0.358813 0.23059 0.33469 0.224126 0.348541 0.25881 0.339149 0.198839 0.33469 0.224126 0.358813 0.23059 0.364027 0.2010149 0.339149 0.198839 0.358813 0.23059 0.339149 0.173161 0.339149 0.198839 0.364027 0.2010149 0.364027 0.170984 0.339149 0.173161 0.364027 0.2010149 0.33469 0.147873 0.339149 0.173161 0.364027 0.170984 0.358812 0.1414099 0.33469 0.147873 0.364027 0.170984 0.325907 0.123744 0.33469 0.147873 0.358812 0.1414099 0.348541 0.11319 0.325907 0.123744 0.358812 0.1414099 0.313068 0.101507 0.325907 0.123744 0.348541 0.11319 0.333526 0.08718198 0.313068 0.101507 0.348541 0.11319 0.296563 0.08183699 0.313068 0.101507 0.333526 0.08718198 0.314222 0.06417798 0.296563 0.08183699 0.333526 0.08718198 0.991489 0.815687 0.93703 0.815687 0.991489 0.657757 0.93703 0.815687 0.93703 0.657757 0.991489 0.657757 0.93703 0.815687 0.882571 0.815687 0.93703 0.657757 0.882571 0.815687 0.882571 0.657757 0.93703 0.657757 0.882571 0.815687 0.828112 0.815687 0.882571 0.657757 0.828112 0.815687 0.828112 0.657757 0.882571 0.657757 0.828112 0.815687 0.773711 0.815687 0.828112 0.657757 0.773711 0.815687 0.773711 0.657757 0.828112 0.657757 0.773711 0.815687 0.719194 0.815687 0.773711 0.657757 0.719194 0.815687 0.719194 0.657757 0.773711 0.657757 0.719194 0.815687 0.664736 0.815687 0.719194 0.657757 0.664736 0.815687 0.664736 0.657757 0.719194 0.657757 0.664736 0.815687 0.610277 0.815687 0.664736 0.657757 0.610277 0.815687 0.610277 0.657757 0.664736 0.657757 0.610277 0.815687 0.555818 0.815687 0.610277 0.657757 0.555818 0.815687 0.555818 0.657757 0.610277 0.657757 0.555818 0.815687 0.501359 0.815687 0.555818 0.657757 0.501359 0.815687 0.501359 0.657757 0.555818 0.657757 0.501359 0.815687 0.446897 0.815686 0.501359 0.657757 0.446897 0.815686 0.446897 0.657756 0.501359 0.657757 0.446897 0.815686 0.392438 0.815686 0.446897 0.657756 0.392438 0.815686 0.392438 0.657756 0.446897 0.657756 0.392438 0.815686 0.337979 0.815686 0.392438 0.657756 0.337979 0.815686 0.337979 0.657756 0.392438 0.657756 0.337979 0.815686 0.283521 0.815686 0.337979 0.657756 0.283521 0.815686 0.283521 0.657756 0.337979 0.657756 0.283521 0.815686 0.229062 0.815686 0.283521 0.657756 0.229062 0.815686 0.229062 0.657756 0.283521 0.657756 0.229062 0.815686 0.174603 0.815686 0.229062 0.657756 0.174603 0.815686 0.174603 0.657756 0.229062 0.657756 0.174603 0.815686 0.120144 0.815686 0.174603 0.657756 0.120144 0.815686 0.120144 0.657756 0.174603 0.657756 0.120144 0.815686 0.06568497 0.815686 0.120144 0.657756 0.06568497 0.815686 0.06568497 0.657756 0.120144 0.657756 0.06568497 0.815686 0.01122695 0.815686 0.06568497 0.657756 0.01122695 0.815686 0.01122695 0.657756 0.06568497 0.657756 0.163255 0.292417 0.163201 0.274647 0.227714 0.292219 0.163201 0.274647 0.227659 0.27445 0.227714 0.292219 0.163201 0.274647 0.163139 0.254559 0.227659 0.27445 0.163139 0.254559 0.2275969 0.254361 0.227659 0.27445 0.163139 0.254559 0.163072 0.232761 0.2275969 0.254361 0.163072 0.232761 0.22753 0.232563 0.2275969 0.254361 0.163072 0.232761 0.163002 0.209917 0.22753 0.232563 0.163002 0.209917 0.22746 0.209719 0.22753 0.232563 0.163002 0.209917 0.162931 0.186721 0.22746 0.209719 0.162931 0.186721 0.227389 0.186523 0.22746 0.209719 0.162931 0.186721 0.162861 0.163877 0.227389 0.186523 0.162861 0.163877 0.227319 0.163679 0.227389 0.186523 0.162861 0.163877 0.1627939 0.1420789 0.227319 0.163679 0.1627939 0.1420789 0.227252 0.141882 0.227319 0.163679 0.1627939 0.1420789 0.162732 0.12199 0.227252 0.141882 0.162732 0.12199 0.227191 0.121793 0.227252 0.141882 0.162732 0.12199 0.162678 0.104221 0.227191 0.121793 0.162678 0.104221 0.227136 0.104023 0.227191 0.121793 0.163057 0.292219 0.163111 0.27445 0.227515 0.292417 0.163111 0.27445 0.2275699 0.274647 0.227515 0.292417 0.163111 0.27445 0.163173 0.254361 0.2275699 0.274647 0.163173 0.254361 0.227631 0.254559 0.2275699 0.274647 0.163173 0.254361 0.16324 0.232563 0.227631 0.254559 0.16324 0.232563 0.227698 0.232761 0.227631 0.254559 0.16324 0.232563 0.16331 0.209719 0.227698 0.232761 0.16331 0.209719 0.227768 0.209917 0.227698 0.232761 0.16331 0.209719 0.163381 0.186523 0.227768 0.209917 0.163381 0.186523 0.2278389 0.186721 0.227768 0.209917 0.163381 0.186523 0.163451 0.163679 0.2278389 0.186721 0.163451 0.163679 0.227909 0.163877 0.2278389 0.186721 0.163451 0.163679 0.163518 0.141881 0.227909 0.163877 0.163518 0.141881 0.227976 0.1420789 0.227909 0.163877 0.163518 0.141881 0.163579 0.121793 0.227976 0.1420789 0.163579 0.121793 0.228038 0.12199 0.227976 0.1420789 0.163579 0.121793 0.163634 0.104023 0.228038 0.12199 0.163634 0.104023 0.228092 0.104221 0.228038 0.12199 0.163215 0.292219 0.1632699 0.27445 0.227674 0.292417 0.1632699 0.27445 0.227728 0.274647 0.227674 0.292417 0.1632699 0.27445 0.163332 0.254361 0.227728 0.274647 0.163332 0.254361 0.2277899 0.254559 0.227728 0.274647 0.163332 0.254361 0.163398 0.232563 0.2277899 0.254559 0.163398 0.232563 0.2278569 0.232761 0.2277899 0.254559 0.163398 0.232563 0.163469 0.209719 0.2278569 0.232761 0.163469 0.209719 0.227927 0.209917 0.2278569 0.232761 0.163469 0.209719 0.16354 0.186523 0.227927 0.209917 0.16354 0.186523 0.227998 0.186721 0.227927 0.209917 0.16354 0.186523 0.16361 0.163679 0.227998 0.186721 0.16361 0.163679 0.2280679 0.163877 0.227998 0.186721 0.16361 0.163679 0.163677 0.141881 0.2280679 0.163877 0.163677 0.141881 0.228135 0.1420789 0.2280679 0.163877 0.163677 0.141881 0.163738 0.121793 0.228135 0.1420789 0.163738 0.121793 0.228197 0.12199 0.228135 0.1420789 0.163738 0.121793 0.163793 0.104023 0.228197 0.12199 0.163793 0.104023 0.228251 0.104221 0.228197 0.12199 0.186682 0.171459 0.1689119 0.171513 0.186484 0.107 0.1689119 0.171513 0.168714 0.107055 0.186484 0.107 0.501083 0.832038 0.501083 0.989963 0.446618 0.989969 + + + + + + + + + + + + + + + 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 +

0 0 0 2 1 1 1 2 2 0 0 3 1 2 4 3 3 5 1 2 6 4 4 7 3 3 8 4 4 9 5 5 10 3 3 11 4 4 12 6 6 13 5 5 14 6 6 15 7 7 16 5 5 17 6 6 18 8 8 19 7 7 20 8 8 21 9 9 22 7 7 23 8 8 24 10 10 25 9 9 26 10 10 27 11 11 28 9 9 29 10 10 30 12 12 31 11 11 32 12 12 33 13 13 34 11 11 35 12 12 36 14 14 37 13 13 38 14 14 39 15 15 40 13 13 41 14 14 42 16 16 43 15 15 44 16 16 45 17 17 46 15 15 47 0 0 48 18 18 49 2 1 50 20 19 51 18 18 52 19 20 53 21 21 54 20 19 55 19 20 56 21 21 57 19 20 58 22 22 59 23 23 60 21 21 61 22 22 62 23 23 63 22 22 64 24 24 65 25 25 66 23 23 67 24 24 68 25 25 69 24 24 70 26 26 71 27 27 72 25 25 73 26 26 74 27 27 75 26 26 76 28 28 77 29 29 78 27 27 79 28 28 80 29 29 81 28 28 82 30 30 83 31 31 84 29 29 85 30 30 86 31 31 87 30 30 88 32 32 89 33 33 90 31 31 91 32 32 92 33 33 93 32 32 94 34 34 95 35 35 96 33 33 97 34 34 98 35 35 99 34 34 100 36 36 101 37 37 102 35 35 103 36 36 104 40 38 105 39 39 106 38 40 107 39 39 108 41 41 109 38 40 110 39 39 111 42 42 112 41 41 113 42 42 114 43 43 115 41 41 116 42 42 117 44 44 118 43 43 119 44 44 120 45 45 121 43 43 122 44 44 123 46 46 124 45 45 125 46 46 126 47 47 127 45 45 128 46 46 129 48 48 130 47 47 131 48 48 132 49 49 133 47 47 134 48 48 135 50 50 136 49 49 137 50 50 138 51 51 139 49 49 140 50 50 141 52 52 142 51 51 143 52 52 144 53 53 145 51 51 146 52 52 147 54 54 148 53 53 149 54 54 150 55 55 151 53 53 152 54 54 153 56 56 154 55 55 155 56 56 156 57 57 157 55 55 158 56 56 159 58 58 160 57 57 161 58 58 162 59 59 163 57 57 164 58 58 165 60 60 166 59 59 167 60 60 168 61 61 169 59 59 170 60 60 171 62 62 172 61 61 173 62 62 174 63 63 175 61 61 176 62 62 177 64 64 178 63 63 179 64 64 180 65 65 181 63 63 182 64 64 183 66 66 184 65 65 185 66 66 186 67 67 187 65 65 188 66 66 189 68 68 190 67 67 191 68 68 192 69 69 193 67 67 194 68 68 195 70 70 196 69 69 197 70 70 198 71 71 199 69 69 200 70 70 201 72 72 202 71 71 203 72 72 204 73 73 205 71 71 206 72 72 207 74 74 208 73 73 209 74 74 210 75 75 211 73 73 212 74 74 213 76 76 214 75 75 215 76 76 216 77 77 217 75 75 218 76 76 219 78 78 220 77 77 221 78 78 222 79 79 223 77 77 224 78 78 225 80 80 226 79 79 227 80 80 228 81 81 229 79 79 230 80 80 231 82 82 232 81 81 233 82 82 234 83 83 235 81 81 236 82 82 237 84 84 238 83 83 239 84 84 240 85 85 241 83 83 242 84 84 243 86 86 244 85 85 245 86 86 246 87 87 247 85 85 248 86 86 249 88 88 250 87 87 251 88 88 252 89 89 253 87 87 254 88 88 255 90 90 256 89 89 257 90 90 258 91 91 259 89 89 260 90 90 261 92 92 262 91 91 263 92 92 264 93 93 265 91 91 266 92 92 267 94 94 268 93 93 269 94 94 270 95 95 271 93 93 272 94 94 273 96 96 274 95 95 275 96 96 276 97 97 277 95 95 278 96 96 279 98 98 280 97 97 281 98 98 282 99 99 283 97 97 284 98 98 285 100 100 286 99 99 287 100 100 288 101 101 289 99 99 290 100 100 291 102 102 292 101 101 293 102 102 294 103 103 295 101 101 296 102 102 297 104 104 298 103 103 299 104 104 300 105 105 301 103 103 302 104 104 303 106 106 304 105 105 305 106 106 306 107 107 307 105 105 308 106 106 309 108 108 310 107 107 311 108 108 312 109 109 313 107 107 314 108 108 315 40 38 316 109 109 317 40 38 318 38 40 319 109 109 320 112 110 321 111 111 322 110 112 323 111 111 324 113 113 325 110 112 326 111 111 327 114 114 328 113 113 329 114 114 330 115 115 331 113 113 332 114 114 333 116 116 334 115 115 335 116 116 336 117 117 337 115 115 338 116 116 339 118 118 340 117 117 341 118 118 342 119 119 343 117 117 344 118 118 345 120 120 346 119 119 347 120 120 348 121 121 349 119 119 350 120 120 351 122 122 352 121 121 353 122 122 354 123 123 355 121 121 356 122 122 357 124 124 358 123 123 359 124 124 360 125 125 361 123 123 362 124 124 363 126 126 364 125 125 365 126 126 366 127 127 367 125 125 368 130 128 369 129 129 370 128 130 371 129 129 372 131 131 373 128 130 374 132 132 375 129 129 376 130 128 377 133 133 378 132 132 379 130 128 380 134 134 381 132 132 382 133 133 383 135 135 384 134 134 385 133 133 386 136 136 387 134 134 388 135 135 389 137 137 390 136 136 391 135 135 392 138 138 393 136 136 394 137 137 395 139 139 396 138 138 397 137 137 398 140 140 399 138 138 400 139 139 401 141 141 402 140 140 403 139 139 404 142 142 405 140 140 406 141 141 407 143 143 408 142 142 409 141 141 410 144 144 411 142 142 412 143 143 413 145 145 414 144 144 415 143 143 416 146 146 417 144 144 418 145 145 419 147 147 420 146 146 421 145 145 422 148 148 423 146 146 424 147 147 425 149 149 426 148 148 427 147 147 428 150 150 429 148 148 430 149 149 431 151 151 432 150 150 433 149 149 434 152 152 435 150 150 436 151 151 437 153 153 438 152 152 439 151 151 440 154 154 441 152 152 442 153 153 443 155 155 444 154 154 445 153 153 446 156 156 447 154 154 448 155 155 449 157 157 450 156 156 451 155 155 452 158 158 453 156 156 454 157 157 455 159 159 456 158 158 457 157 157 458 160 160 459 158 158 460 159 159 461 161 161 462 160 160 463 159 159 464 162 162 465 160 160 466 161 161 467 163 163 468 162 162 469 161 161 470 164 164 471 162 162 472 163 163 473 165 165 474 164 164 475 163 163 476 166 166 477 164 164 478 165 165 479 167 167 480 166 166 481 165 165 482 168 168 483 166 166 484 167 167 485 169 169 486 168 168 487 167 167 488 170 170 489 168 168 490 169 169 491 171 171 492 170 170 493 169 169 494 172 172 495 170 170 496 171 171 497 173 173 498 172 172 499 171 171 500 174 174 501 172 172 502 173 173 503 175 175 504 174 174 505 173 173 506 176 176 507 174 174 508 175 175 509 177 177 510 176 176 511 175 175 512 178 178 513 176 176 514 177 177 515 179 179 516 178 178 517 177 177 518 180 180 519 178 178 520 179 179 521 181 181 522 180 180 523 179 179 524 182 182 525 180 180 526 181 181 527 183 183 528 182 182 529 181 181 530 184 184 531 182 182 532 183 183 533 185 185 534 184 184 535 183 183 536 186 186 537 184 184 538 185 185 539 187 187 540 186 186 541 185 185 542 188 188 543 186 186 544 187 187 545 189 189 546 188 188 547 187 187 548 190 190 549 188 188 550 189 189 551 191 191 552 190 190 553 189 189 554 192 192 555 190 190 556 191 191 557 193 193 558 192 192 559 191 191 560 194 194 561 192 192 562 193 193 563 195 195 564 194 194 565 193 193 566 196 196 567 194 194 568 195 195 569 197 197 570 196 196 571 195 195 572 198 198 573 196 196 574 197 197 575 199 199 576 198 198 577 197 197 578 131 131 579 198 198 580 199 199 581 128 130 582 131 131 583 199 199 584 202 200 585 201 201 586 200 202 587 201 201 588 203 203 589 200 202 590 201 201 591 204 204 592 203 203 593 204 204 594 205 205 595 203 203 596 204 204 597 206 206 598 205 205 599 206 206 600 207 207 601 205 205 602 206 206 603 208 208 604 207 207 605 208 208 606 209 209 607 207 207 608 208 208 609 210 210 610 209 209 611 210 210 612 211 211 613 209 209 614 210 210 615 212 212 616 211 211 617 212 212 618 213 213 619 211 211 620 212 212 621 214 214 622 213 213 623 214 214 624 215 215 625 213 213 626 214 214 627 216 216 628 215 215 629 216 216 630 217 217 631 215 215 632 216 216 633 218 218 634 217 217 635 218 218 636 219 219 637 217 217 638 218 218 639 220 220 640 219 219 641 220 220 642 221 221 643 219 219 644 220 220 645 222 222 646 221 221 647 222 222 648 223 223 649 221 221 650 222 222 651 224 224 652 223 223 653 224 224 654 225 225 655 223 223 656 224 224 657 226 226 658 225 225 659 226 226 660 227 227 661 225 225 662 226 226 663 228 228 664 227 227 665 228 228 666 229 229 667 227 227 668 228 228 669 230 230 670 229 229 671 230 230 672 231 231 673 229 229 674 230 230 675 232 232 676 231 231 677 232 232 678 233 233 679 231 231 680 232 232 681 234 234 682 233 233 683 234 234 684 235 235 685 233 233 686 234 234 687 236 236 688 235 235 689 236 236 690 237 237 691 235 235 692 240 238 693 239 239 694 238 240 695 239 239 696 241 241 697 238 240 698 239 239 699 242 242 700 241 241 701 242 242 702 243 243 703 241 241 704 242 242 705 244 244 706 243 243 707 244 244 708 245 245 709 243 243 710 244 244 711 246 246 712 245 245 713 246 246 714 247 247 715 245 245 716 246 246 717 248 248 718 247 247 719 248 248 720 249 249 721 247 247 722 248 248 723 250 250 724 249 249 725 250 250 726 251 251 727 249 249 728 250 250 729 252 252 730 251 251 731 252 252 732 253 253 733 251 251 734 252 252 735 254 254 736 253 253 737 254 254 738 255 255 739 253 253 740 254 254 741 256 256 742 255 255 743 256 256 744 257 257 745 255 255 746 260 258 747 259 259 748 258 260 749 259 259 750 261 261 751 258 260 752 259 259 753 262 262 754 261 261 755 262 262 756 263 263 757 261 261 758 262 262 759 264 264 760 263 263 761 264 264 762 265 265 763 263 263 764 264 264 765 266 266 766 265 265 767 266 266 768 267 267 769 265 265 770 266 266 771 268 268 772 267 267 773 268 268 774 269 269 775 267 267 776 268 268 777 270 270 778 269 269 779 270 270 780 271 271 781 269 269 782 270 270 783 272 272 784 271 271 785 272 272 786 273 273 787 271 271 788 272 272 789 274 274 790 273 273 791 274 274 792 275 275 793 273 273 794 274 274 795 276 276 796 275 275 797 276 276 798 277 277 799 275 275 800 280 278 801 279 279 802 278 280 803 279 279 804 281 281 805 278 280 806 279 279 807 282 282 808 281 281 809 282 282 810 283 283 811 281 281 812 282 282 813 284 284 814 283 283 815 284 284 816 285 285 817 283 283 818 284 284 819 286 286 820 285 285 821 286 286 822 287 287 823 285 285 824 286 286 825 288 288 826 287 287 827 288 288 828 289 289 829 287 287 830 288 288 831 290 290 832 289 289 833 290 290 834 291 291 835 289 289 836 290 290 837 292 292 838 291 291 839 292 292 840 293 293 841 291 291 842 292 292 843 294 294 844 293 293 845 294 294 846 295 295 847 293 293 848 294 294 849 296 296 850 295 295 851 296 296 852 297 297 853 295 295 854 300 298 855 299 299 856 298 300 857 299 299 858 301 301 859 298 300 860 18 18 861 20 19 862 2 1 863

+
+
+
+
+ + + + + 0.6858805 -0.3173701 0.6548619 7.481132 0.7276338 0.3124686 -0.6106656 -6.50764 -0.01081678 0.8953432 0.4452454 5.343665 0 0 0 1 + + + + -0.2908646 -0.7711008 0.5663932 4.076245 0.9551712 -0.1998834 0.2183912 1.005454 -0.05518906 0.6045247 0.7946723 5.903862 0 0 0 1 + + + + 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 + + 1.25 0 0 0 0 -1.67949e-7 -1.25 0 0 1.25 -1.67949e-7 0 0 0 0 1 + + 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 + + + + + + + + + + 1 0 0 0 0 1 0 -5.55438e-8 0 0 1 -2e-15 0 0 0 1 + + + + + + + + + + + + 1 0 0 0.3932523 0 1 0 -0.1413886 0 0 1 -1.029667 0 0 0 1 + + + + + + + +
\ No newline at end of file diff --git a/src/parts source/kOS_Models.unitypackage b/src/parts source/kOS_Models.unitypackage new file mode 100644 index 000000000..a1a0dc917 Binary files /dev/null and b/src/parts source/kOS_Models.unitypackage differ diff --git a/src/parts source/kOSkal9000/KAL-9000 meshes/AutoSave_hal9000.skp b/src/parts source/kOSkal9000/KAL-9000 meshes/AutoSave_hal9000.skp new file mode 100644 index 000000000..1ebf8c0d1 Binary files /dev/null and b/src/parts source/kOSkal9000/KAL-9000 meshes/AutoSave_hal9000.skp differ diff --git a/src/parts source/kOSkal9000/KAL-9000 meshes/Jan 7 kal9000.fbx b/src/parts source/kOSkal9000/KAL-9000 meshes/Jan 7 kal9000.fbx new file mode 100644 index 000000000..87bfe619c --- /dev/null +++ b/src/parts source/kOSkal9000/KAL-9000 meshes/Jan 7 kal9000.fbx @@ -0,0 +1,707 @@ +; FBX 7.3.0 project file +; Copyright (C) 1997-2010 Autodesk Inc. and/or its licensors. +; All rights reserved. +; ---------------------------------------------------- + +FBXHeaderExtension: { + FBXHeaderVersion: 1003 + FBXVersion: 7300 + CreationTimeStamp: { + Version: 1000 + Year: 2016 + Month: 1 + Day: 7 + Hour: 11 + Minute: 7 + Second: 54 + Millisecond: 0 + } + Creator: "FBX SDK/FBX Plugins version 2013.3" + SceneInfo: "SceneInfo::GlobalInfo", "UserData" { + Type: "UserData" + Version: 100 + MetaData: { + Version: 100 + Title: "" + Subject: "" + Author: "" + Keywords: "" + Revision: "" + Comment: "" + } + Properties70: { + P: "DocumentUrl", "KString", "Url", "", "/var/folders/16/csq8fhn9279gfgk7gc955t500000gn/T/com.sketchup.SketchUp.2016.petergoddardEHtGaM.fbx" + P: "SrcDocumentUrl", "KString", "Url", "", "/var/folders/16/csq8fhn9279gfgk7gc955t500000gn/T/com.sketchup.SketchUp.2016.petergoddardEHtGaM.fbx" + P: "Original", "Compound", "", "" + P: "Original|ApplicationVendor", "KString", "", "", "" + P: "Original|ApplicationName", "KString", "", "", "" + P: "Original|ApplicationVersion", "KString", "", "", "" + P: "Original|DateTime_GMT", "DateTime", "", "", "" + P: "Original|FileName", "KString", "", "", "" + P: "LastSaved", "Compound", "", "" + P: "LastSaved|ApplicationVendor", "KString", "", "", "" + P: "LastSaved|ApplicationName", "KString", "", "", "" + P: "LastSaved|ApplicationVersion", "KString", "", "", "" + P: "LastSaved|DateTime_GMT", "DateTime", "", "", "" + } + } +} +GlobalSettings: { + Version: 1000 + Properties70: { + P: "UpAxis", "int", "Integer", "",1 + P: "UpAxisSign", "int", "Integer", "",1 + P: "FrontAxis", "int", "Integer", "",2 + P: "FrontAxisSign", "int", "Integer", "",1 + P: "CoordAxis", "int", "Integer", "",0 + P: "CoordAxisSign", "int", "Integer", "",1 + P: "OriginalUpAxis", "int", "Integer", "",-1 + P: "OriginalUpAxisSign", "int", "Integer", "",1 + P: "UnitScaleFactor", "double", "Number", "",1 + P: "OriginalUnitScaleFactor", "double", "Number", "",1 + P: "AmbientColor", "ColorRGB", "Color", "",0,0,0 + P: "DefaultCamera", "KString", "", "", "Producer Perspective" + P: "TimeMode", "enum", "", "",0 + P: "TimeSpanStart", "KTime", "Time", "",0 + P: "TimeSpanStop", "KTime", "Time", "",46186158000 + P: "CustomFrameRate", "double", "Number", "",-1 + } +} + +; Documents Description +;------------------------------------------------------------------ + +Documents: { + Count: 1 + Document: 140569697051760, "", "Scene" { + Properties70: { + P: "SourceObject", "object", "", "" + P: "ActiveAnimStackName", "KString", "", "", "" + } + RootNode: 0 + } +} + +; Document References +;------------------------------------------------------------------ + +References: { +} + +; Object definitions +;------------------------------------------------------------------ + +Definitions: { + Version: 100 + Count: 19 + ObjectType: "GlobalSettings" { + Count: 1 + } + ObjectType: "Model" { + Count: 6 + PropertyTemplate: "FbxNode" { + Properties70: { + P: "QuaternionInterpolate", "enum", "", "",0 + P: "RotationOffset", "Vector3D", "Vector", "",0,0,0 + P: "RotationPivot", "Vector3D", "Vector", "",0,0,0 + P: "ScalingOffset", "Vector3D", "Vector", "",0,0,0 + P: "ScalingPivot", "Vector3D", "Vector", "",0,0,0 + P: "TranslationActive", "bool", "", "",0 + P: "TranslationMin", "Vector3D", "Vector", "",0,0,0 + P: "TranslationMax", "Vector3D", "Vector", "",0,0,0 + P: "TranslationMinX", "bool", "", "",0 + P: "TranslationMinY", "bool", "", "",0 + P: "TranslationMinZ", "bool", "", "",0 + P: "TranslationMaxX", "bool", "", "",0 + P: "TranslationMaxY", "bool", "", "",0 + P: "TranslationMaxZ", "bool", "", "",0 + P: "RotationOrder", "enum", "", "",0 + P: "RotationSpaceForLimitOnly", "bool", "", "",0 + P: "RotationStiffnessX", "double", "Number", "",0 + P: "RotationStiffnessY", "double", "Number", "",0 + P: "RotationStiffnessZ", "double", "Number", "",0 + P: "AxisLen", "double", "Number", "",10 + P: "PreRotation", "Vector3D", "Vector", "",0,0,0 + P: "PostRotation", "Vector3D", "Vector", "",0,0,0 + P: "RotationActive", "bool", "", "",0 + P: "RotationMin", "Vector3D", "Vector", "",0,0,0 + P: "RotationMax", "Vector3D", "Vector", "",0,0,0 + P: "RotationMinX", "bool", "", "",0 + P: "RotationMinY", "bool", "", "",0 + P: "RotationMinZ", "bool", "", "",0 + P: "RotationMaxX", "bool", "", "",0 + P: "RotationMaxY", "bool", "", "",0 + P: "RotationMaxZ", "bool", "", "",0 + P: "InheritType", "enum", "", "",0 + P: "ScalingActive", "bool", "", "",0 + P: "ScalingMin", "Vector3D", "Vector", "",0,0,0 + P: "ScalingMax", "Vector3D", "Vector", "",1,1,1 + P: "ScalingMinX", "bool", "", "",0 + P: "ScalingMinY", "bool", "", "",0 + P: "ScalingMinZ", "bool", "", "",0 + P: "ScalingMaxX", "bool", "", "",0 + P: "ScalingMaxY", "bool", "", "",0 + P: "ScalingMaxZ", "bool", "", "",0 + P: "GeometricTranslation", "Vector3D", "Vector", "",0,0,0 + P: "GeometricRotation", "Vector3D", "Vector", "",0,0,0 + P: "GeometricScaling", "Vector3D", "Vector", "",1,1,1 + P: "MinDampRangeX", "double", "Number", "",0 + P: "MinDampRangeY", "double", "Number", "",0 + P: "MinDampRangeZ", "double", "Number", "",0 + P: "MaxDampRangeX", "double", "Number", "",0 + P: "MaxDampRangeY", "double", "Number", "",0 + P: "MaxDampRangeZ", "double", "Number", "",0 + P: "MinDampStrengthX", "double", "Number", "",0 + P: "MinDampStrengthY", "double", "Number", "",0 + P: "MinDampStrengthZ", "double", "Number", "",0 + P: "MaxDampStrengthX", "double", "Number", "",0 + P: "MaxDampStrengthY", "double", "Number", "",0 + P: "MaxDampStrengthZ", "double", "Number", "",0 + P: "PreferedAngleX", "double", "Number", "",0 + P: "PreferedAngleY", "double", "Number", "",0 + P: "PreferedAngleZ", "double", "Number", "",0 + P: "LookAtProperty", "object", "", "" + P: "UpVectorProperty", "object", "", "" + P: "Show", "bool", "", "",1 + P: "NegativePercentShapeSupport", "bool", "", "",1 + P: "DefaultAttributeIndex", "int", "Integer", "",-1 + P: "Freeze", "bool", "", "",0 + P: "LODBox", "bool", "", "",0 + P: "Lcl Translation", "Lcl Translation", "", "A",0,0,0 + P: "Lcl Rotation", "Lcl Rotation", "", "A",0,0,0 + P: "Lcl Scaling", "Lcl Scaling", "", "A",1,1,1 + P: "Visibility", "Visibility", "", "A",1 + P: "Visibility Inheritance", "Visibility Inheritance", "", "",1 + } + } + } + ObjectType: "Texture" { + Count: 3 + PropertyTemplate: "FbxFileTexture" { + Properties70: { + P: "TextureTypeUse", "enum", "", "",0 + P: "Texture alpha", "Number", "", "A",1 + P: "CurrentMappingType", "enum", "", "",0 + P: "WrapModeU", "enum", "", "",0 + P: "WrapModeV", "enum", "", "",0 + P: "UVSwap", "bool", "", "",0 + P: "PremultiplyAlpha", "bool", "", "",1 + P: "Translation", "Vector", "", "A",0,0,0 + P: "Rotation", "Vector", "", "A",0,0,0 + P: "Scaling", "Vector", "", "A",1,1,1 + P: "TextureRotationPivot", "Vector3D", "Vector", "",0,0,0 + P: "TextureScalingPivot", "Vector3D", "Vector", "",0,0,0 + P: "CurrentTextureBlendMode", "enum", "", "",1 + P: "UVSet", "KString", "", "", "default" + P: "UseMaterial", "bool", "", "",0 + P: "UseMipMap", "bool", "", "",0 + } + } + } + ObjectType: "Geometry" { + Count: 3 + PropertyTemplate: "FbxMesh" { + Properties70: { + P: "Color", "ColorRGB", "Color", "",0.8,0.8,0.8 + P: "BBoxMin", "Vector3D", "Vector", "",0,0,0 + P: "BBoxMax", "Vector3D", "Vector", "",0,0,0 + P: "Primary Visibility", "bool", "", "",1 + P: "Casts Shadows", "bool", "", "",1 + P: "Receive Shadows", "bool", "", "",1 + } + } + } + ObjectType: "Material" { + Count: 3 + PropertyTemplate: "FbxSurfacePhong" { + Properties70: { + P: "ShadingModel", "KString", "", "", "Phong" + P: "MultiLayer", "bool", "", "",0 + P: "EmissiveColor", "Color", "", "A",0,0,0 + P: "EmissiveFactor", "Number", "", "A",1 + P: "AmbientColor", "Color", "", "A",0.2,0.2,0.2 + P: "AmbientFactor", "Number", "", "A",1 + P: "DiffuseColor", "Color", "", "A",0.8,0.8,0.8 + P: "DiffuseFactor", "Number", "", "A",1 + P: "Bump", "Vector3D", "Vector", "",0,0,0 + P: "NormalMap", "Vector3D", "Vector", "",0,0,0 + P: "BumpFactor", "double", "Number", "",1 + P: "TransparentColor", "Color", "", "A",0,0,0 + P: "TransparencyFactor", "Number", "", "A",0 + P: "DisplacementColor", "ColorRGB", "Color", "",0,0,0 + P: "DisplacementFactor", "double", "Number", "",1 + P: "VectorDisplacementColor", "ColorRGB", "Color", "",0,0,0 + P: "VectorDisplacementFactor", "double", "Number", "",1 + P: "SpecularColor", "Color", "", "A",0.2,0.2,0.2 + P: "SpecularFactor", "Number", "", "A",1 + P: "ShininessExponent", "Number", "", "A",20 + P: "ReflectionColor", "Color", "", "A",0,0,0 + P: "ReflectionFactor", "Number", "", "A",1 + } + } + } + ObjectType: "Video" { + Count: 3 + PropertyTemplate: "FbxVideo" { + Properties70: { + P: "ImageSequence", "bool", "", "",0 + P: "ImageSequenceOffset", "int", "Integer", "",0 + P: "FrameRate", "double", "Number", "",0 + P: "LastFrame", "int", "Integer", "",0 + P: "Width", "int", "Integer", "",0 + P: "Height", "int", "Integer", "",0 + P: "Path", "KString", "XRefUrl", "", "" + P: "StartFrame", "int", "Integer", "",0 + P: "StopFrame", "int", "Integer", "",0 + P: "PlaySpeed", "double", "Number", "",0 + P: "Offset", "KTime", "Time", "",0 + P: "InterlaceMode", "enum", "", "",0 + P: "FreeRunning", "bool", "", "",0 + P: "Loop", "bool", "", "",0 + P: "AccessMode", "enum", "", "",0 + } + } + } +} + +; Object properties +;------------------------------------------------------------------ + +Objects: { + Geometry: 140569697341056, "Geometry::", "Mesh" { + Vertices: *408 { + a: 0.750000000000043,1.62201584240891,-3.07856423915753,1.00000000000004,2.27360036299944,-2.39644369470848,1.00000000000005,1.54914084240892,-2.95234103655594,0.750000000000038,2.3766611763574,-2.49950450806644,0.750000000000043,-3.8436091575911,0.0770158258820479,1.00000000000004,-3.57866769795026,0.982364845650661,0.750000000000038,-3.7194513871319,1.02008772147434,1.00000000000005,-3.69785915759112,0.0770158258820327,0.750000000000046,-3.35543922263065,-1.74485917411796,1.00000000000005,-2.67331867818164,-2.39644369470848,1.00000000000005,-3.22921602002908,-1.67198417411796,0.750000000000052,-2.77637949153958,-2.49950450806643,0.750000000000068,-10.8561091575911,-4.07923417411797,0.375000000000069,-11.2311091575911,-4.07923417411798,0.375000000000071,-11.2311091575911,-4.45423417411797,0.750000000000034,-10.8561091575911,4.233265825882,0.375000000000032,-11.2311091575911,4.60826582588201,0.374999999999982,12.8313908424089,4.60826582588203,7.61390950287932e-15,12.8313908424089,-4.45423417411794,-4.37094804794924e-15,12.8313908424089,4.60826582588203,0.375000000000019,12.8313908424089,-4.45423417411795,1.00000000000003,3.2981408424089,0.0770158258820445,0.750000000000023,3.31973307194969,-0.866056069710259,0.750000000000017,3.44389084240889,0.0770158258820541,1.00000000000003,3.17894938276806,-0.828333193886569,1.00000000000005,-3.57866769795025,-0.828333193886578,1.00000000000004,-3.57866769795026,0.982364845650661,1.00000000000005,-3.69785915759112,0.0770158258820327,1.00000000000004,-3.22921602002907,1.82601582588204,1.00000000000005,-3.22921602002908,-1.67198417411796,1.00000000000005,-2.67331867818164,-2.39644369470848,1.00000000000003,-2.67331867818163,2.55047534647257,1.00000000000006,-1.94885915759107,-2.95234103655593,1.00000000000002,-1.94885915759108,3.10637268832,1.00000000000001,-1.10520817735971,3.45582436624119,1.00000000000006,-1.1052081773597,-3.30179271447713,1.00000000000002,-0.199859157591079,3.57501582588203,1.00000000000006,-0.199859157591079,-3.42098417411797,1.00000000000002,0.705489862177526,3.4558243662412, +1.00000000000006,0.705489862177535,-3.30179271447713,1.00000000000002,1.5491408424089,3.10637268831999,1.00000000000005,1.54914084240892,-2.95234103655594,1.00000000000002,2.27360036299946,2.55047534647256,1.00000000000004,2.27360036299944,-2.39644369470848,1.00000000000003,2.82949770484689,-1.67198417411795,1.00000000000002,2.82949770484688,1.82601582588206,1.00000000000002,3.17894938276806,0.982364845650666,1.00000000000003,3.17894938276806,-0.828333193886569,1.00000000000003,3.2981408424089,0.0770158258820445,1.00000000000006,-1.94885915759107,-2.95234103655593,0.750000000000053,-1.14293105318339,-3.44257640365874,1.00000000000006,-1.1052081773597,-3.30179271447713,0.750000000000051,-2.02173415759108,-3.07856423915751,0.750000000000045,-3.71945138713189,-0.866056069710278,1.00000000000005,-3.57866769795025,-0.828333193886578,1.00000000000002,3.17894938276806,0.982364845650666,0.75000000000002,3.31973307194968,1.02008772147436,1.00000000000002,2.27360036299946,2.55047534647256,0.750000000000017,2.95572090744846,1.89889082588204,0.750000000000011,2.37666117635739,2.65353615983051,1.00000000000002,2.82949770484688,1.82601582588206,0.750000000000053,0.743212738001224,-3.44257640365875,1.00000000000006,0.705489862177535,-3.30179271447713,4.07485156728171e-14,-11.2311091575911,4.608265825882,0.375000000000069,-11.2311091575911,-4.07923417411798,0.375000000000032,-11.2311091575911,4.60826582588201,6.51412257468564e-14,-11.2311091575911,-4.45423417411796,0.375000000000071,-11.2311091575911,-4.45423417411797,1.00000000000002,-1.94885915759108,3.10637268832,0.750000000000026,-2.77637949153958,2.65353615983052,1.00000000000003,-2.67331867818163,2.55047534647257,0.750000000000017,-2.02173415759109,3.23259589092158,1.00000000000002,1.5491408424089,3.10637268831999,0.750000000000007,0.743212738001229,3.59660805542283,1.00000000000002,0.705489862177526,3.4558243662412,0.750000000000016,1.62201584240892,3.23259589092157,0.750000000000053,-0.199859157591079,-3.56673417411796,1.00000000000006,-0.199859157591079,-3.42098417411797, +0.75000000000003,-3.35543922263065,1.89889082588204,1.00000000000004,-3.22921602002907,1.82601582588204,1.00000000000001,-1.10520817735971,3.45582436624119,0.750000000000006,-1.14293105318341,3.59660805542282,0.750000000000027,2.95572090744846,-1.74485917411795,1.00000000000003,2.82949770484689,-1.67198417411795,0.750000000000013,-0.19985915759109,3.72076582588203,1.00000000000002,-0.199859157591079,3.57501582588203,0.750000000000068,-10.8561091575911,-4.07923417411797,0.750000000000045,-3.71945138713189,-0.866056069710278,0.750000000000043,-3.8436091575911,0.0770158258820479,0.750000000000046,-3.35543922263065,-1.74485917411796,0.750000000000052,-2.77637949153958,-2.49950450806643,0.750000000000051,-2.02173415759108,-3.07856423915751,0.750000000000053,-1.14293105318339,-3.44257640365874,0.750000000000053,-0.199859157591079,-3.56673417411796,0.750000000000029,12.4563908424089,-4.07923417411793,0.750000000000053,0.743212738001224,-3.44257640365875,0.750000000000043,1.62201584240891,-3.07856423915753,0.750000000000038,2.3766611763574,-2.49950450806644,0.750000000000027,2.95572090744846,-1.74485917411795,0.750000000000023,3.31973307194969,-0.866056069710259,0.750000000000017,3.44389084240889,0.0770158258820541,0.749999999999987,12.4563908424089,4.23326582588204,0.750000000000034,-10.8561091575911,4.233265825882,0.750000000000013,-0.19985915759109,3.72076582588203,0.750000000000006,-1.14293105318341,3.59660805542282,0.750000000000017,-2.02173415759109,3.23259589092158,0.750000000000026,-2.77637949153958,2.65353615983052,0.75000000000003,-3.35543922263065,1.89889082588204,0.750000000000038,-3.7194513871319,1.02008772147434,0.750000000000007,0.743212738001229,3.59660805542283,0.750000000000016,1.62201584240892,3.23259589092157,0.750000000000011,2.37666117635739,2.65353615983051,0.750000000000017,2.95572090744846,1.89889082588204,0.75000000000002,3.31973307194968,1.02008772147436,0.750000000000029,12.4563908424089,-4.07923417411793,0.374999999999982,12.8313908424089,4.60826582588203,0.749999999999987,12.4563908424089,4.23326582588204, +0.375000000000019,12.8313908424089,-4.45423417411795,0.375000000000071,-11.2311091575911,-4.45423417411797,0.375000000000024,12.4563908424089,-4.45423417411794,0.750000000000068,-10.8561091575911,-4.07923417411797,0.375000000000019,12.8313908424089,-4.45423417411795,0.750000000000029,12.4563908424089,-4.07923417411793,0.374999999999982,12.8313908424089,4.60826582588203,0.750000000000034,-10.8561091575911,4.233265825882,0.749999999999987,12.4563908424089,4.23326582588204,0.375000000000032,-11.2311091575911,4.60826582588201,0.375000000000071,-11.2311091575911,-4.45423417411797,0.375000000000019,12.8313908424089,-4.45423417411795,0.375000000000024,12.4563908424089,-4.45423417411794,7.61390950287932e-15,12.8313908424089,-4.45423417411794,6.51412257468564e-14,-11.2311091575911,-4.45423417411796,-4.37094804794924e-15,12.8313908424089,4.60826582588203,0.375000000000032,-11.2311091575911,4.60826582588201,0.374999999999982,12.8313908424089,4.60826582588203,4.07485156728171e-14,-11.2311091575911,4.608265825882 + } + PolygonVertexIndex: *354 { + a: 0,1,-3,1,0,-4,4,5,-7,5,4,-8,8,9,-11,9,8,-12,12,13,-15,13,12,-16,15,16,-14,17,18,-20,18,17,-21,21,22,-24,22,21,-25,25,26,-28,26,25,-29,28,25,-30,28,29,-31,28,30,-32,31,30,-33,31,32,-34,33,32,-35,34,32,-36,34,35,-37,36,35,-38,36,37,-39,38,37,-40,38,39,-41,40,39,-42,40,41,-43,42,41,-44,42,43,-45,42,44,-46,45,44,-47,46,44,-48,46,47,-49,49,50,-52,50,49,-53,53,7,-5,7,53,-55,55,23,-57,23,55,-22,57,58,-60,58,57,-61,61,2,-63,2,61,-1,9,52,-50,52,9,-12,63,64,-66,64,63,-67,64,66,-68,68,69,-71,69,68,-72,72,73,-75,73,72,-76,51,76,-78,76,51,-51,78,70,-70,70,78,-80,80,71,-69,71,80,-82,60,56,-59,56,60,-56,53,10,-55,10,53,-9,76,62,-78,62,76,-62,1,82,-84,82,1,-4,84,80,-86,80,84,-82,6,79,-79,79,6,-6,73,85,-75,85,73,-85,83,22,-25,22,83,-83,59,72,-58,72,59,-76,86,87,-89,87,86,-90,89,86,-91,90,86,-92,91,86,-93,92,86,-94,93,86,-95,93,94,-96,95,94,-97,96,94,-98,97,94,-99,98,94,-100,99,94,-101,100,94,-102,102,103,-102,103,102,-105,104,102,-106,105,102,-107,106,102,-87,106,86,-108,107,86,-109,108,86,-89,101,103,-110,101,109,-111,101,110,-112,101,111,-113,101,112,-114,101,113,-101,114,115,-117,115,114,-118,118,119,-121,120,121,-123,121,120,-120,123,124,-126,124,123,-127,127,128,-130,128,127,-131,130,127,-132,132,133,-135,133,132,-136 + } + GeometryVersion: 124 + LayerElementNormal: 0 { + Version: 101 + Name: "" + MappingInformationType: "ByVertice" + ReferenceInformationType: "Direct" + Normals: *408 { + a: 0.503656152931393,0.431952103714742,-0.748162990070184,0.503656152931392,0.610872523368976,-0.610872523368968,0.503656152931393,0.431952103714742,-0.748162990070184,0.503656152931392,0.610872523368976,-0.610872523368968,0.503656152931372,-0.863904207429487,2.04351193968313e-15,0.503656152931381,-0.834467385395924,0.223594862026953,0.503656152931381,-0.834467385395924,0.223594862026953,0.503656152931372,-0.863904207429487,2.04351193968313e-15,0.503656152931386,-0.748162990070191,-0.431952103714738,0.503656152931394,-0.61087252336897,-0.610872523368972,0.503656152931386,-0.748162990070191,-0.431952103714738,0.503656152931394,-0.61087252336897,-0.610872523368972,0.70710678118656,-0.707106781186534,2.22655551514828e-15,0.70710678118656,-0.707106781186534,2.22655551514828e-15,0.70710678118656,-0.707106781186534,2.22655551514828e-15,0.70710678118656,-0.707106781186534,2.22655551514828e-15,0.70710678118656,-0.707106781186534,2.22655551514828e-15,-1.35308431126193e-15,1,8.46545056276679e-16,-1.35308431126193e-15,1,8.46545056276679e-16,-1.35308431126193e-15,1,8.46545056276679e-16,-1.35308431126193e-15,1,8.46545056276679e-16,0.50365615293138,0.863904207429483,3.74526838842259e-15,0.503656152931381,0.834467385395927,-0.223594862026942,0.50365615293138,0.863904207429483,3.74526838842259e-15,0.503656152931381,0.834467385395927,-0.223594862026942,1,1.35308431126193e-15,5.24580379135387e-15,1,1.35308431126193e-15,5.24580379135387e-15,1,1.35308431126193e-15,5.24580379135387e-15,1,1.35308431126193e-15,5.24580379135387e-15,1,1.35308431126193e-15,5.24580379135387e-15,1,1.35308431126193e-15,5.24580379135387e-15,1,1.35308431126193e-15,5.24580379135387e-15,1,1.35308431126193e-15,5.24580379135387e-15,1,1.35308431126193e-15,5.24580379135387e-15,1,1.35308431126193e-15,5.24580379135387e-15,1,1.35308431126193e-15,5.24580379135387e-15,1,1.35308431126193e-15,5.24580379135387e-15,1,1.35308431126193e-15,5.24580379135387e-15,1,1.35308431126193e-15,5.24580379135387e-15,1,1.35308431126193e-15,5.24580379135387e-15,1,1.35308431126193e-15,5.24580379135387e-15, +1,1.35308431126193e-15,5.24580379135387e-15,1,1.35308431126193e-15,5.24580379135387e-15,1,1.35308431126193e-15,5.24580379135387e-15,1,1.35308431126193e-15,5.24580379135387e-15,1,1.35308431126193e-15,5.24580379135387e-15,1,1.35308431126193e-15,5.24580379135387e-15,1,1.35308431126193e-15,5.24580379135387e-15,1,1.35308431126193e-15,5.24580379135387e-15,0.50365615293139,-0.431952103714737,-0.748162990070188,0.503656152931381,-0.223594862026949,-0.834467385395925,0.503656152931381,-0.223594862026949,-0.834467385395925,0.50365615293139,-0.431952103714737,-0.748162990070188,0.503656152931377,-0.834467385395928,-0.223594862026946,0.503656152931377,-0.834467385395928,-0.223594862026946,0.503656152931362,0.834467385395935,0.223594862026953,0.503656152931362,0.834467385395935,0.223594862026953,0.50365615293137,0.610872523368981,0.610872523368982,0.503656152931353,0.748162990070206,0.431952103714749,0.50365615293137,0.610872523368981,0.610872523368982,0.503656152931353,0.748162990070206,0.431952103714749,0.503656152931387,0.223594862026948,-0.834467385395921,0.503656152931387,0.223594862026948,-0.834467385395921,-1.45716771982029e-16,-1,-7.35522753814165e-16,-1.45716771982029e-16,-1,-7.35522753814165e-16,-1.45716771982029e-16,-1,-7.35522753814165e-16,-1.45716771982029e-16,-1,-7.35522753814165e-16,-1.45716771982029e-16,-1,-7.35522753814165e-16,0.503656152931383,-0.431952103714741,0.748162990070191,0.503656152931381,-0.610872523368974,0.610872523368979,0.503656152931381,-0.610872523368974,0.610872523368979,0.503656152931383,-0.431952103714741,0.748162990070191,0.503656152931391,0.431952103714742,0.748162990070185,0.503656152931387,0.223594862026946,0.834467385395922,0.503656152931387,0.223594862026946,0.834467385395922,0.503656152931391,0.431952103714742,0.748162990070185,0.503656152931386,2.63265532329339e-15,-0.863904207429479,0.503656152931386,2.63265532329339e-15,-0.863904207429479,0.503656152931383,-0.748162990070189,0.431952103714745,0.503656152931383,-0.748162990070189,0.431952103714745,0.503656152931377,-0.223594862026951,0.834467385395927, +0.503656152931377,-0.223594862026951,0.834467385395927,0.503656152931382,0.748162990070194,-0.431952103714738,0.503656152931382,0.748162990070194,-0.431952103714738,0.503656152931372,-6.55555180552323e-15,0.863904207429487,0.503656152931372,-6.55555180552323e-15,0.863904207429487,1,1.35308431126193e-15,5.24580379135387e-15,1,1.35308431126193e-15,5.24580379135387e-15,1,1.35308431126193e-15,5.24580379135387e-15,1,1.35308431126193e-15,5.24580379135387e-15,1,1.35308431126193e-15,5.24580379135387e-15,1,1.35308431126193e-15,5.24580379135387e-15,1,1.35308431126193e-15,5.24580379135387e-15,1,1.35308431126193e-15,5.24580379135387e-15,1,1.35308431126193e-15,5.24580379135387e-15,1,1.35308431126193e-15,5.24580379135387e-15,1,1.35308431126193e-15,5.24580379135387e-15,1,1.35308431126193e-15,5.24580379135387e-15,1,1.35308431126193e-15,5.24580379135387e-15,1,1.35308431126193e-15,5.24580379135387e-15,1,1.35308431126193e-15,5.24580379135387e-15,1,1.35308431126193e-15,5.24580379135387e-15,1,1.35308431126193e-15,5.24580379135387e-15,1,1.35308431126193e-15,5.24580379135387e-15,1,1.35308431126193e-15,5.24580379135387e-15,1,1.35308431126193e-15,5.24580379135387e-15,1,1.35308431126193e-15,5.24580379135387e-15,1,1.35308431126193e-15,5.24580379135387e-15,1,1.35308431126193e-15,5.24580379135387e-15,1,1.35308431126193e-15,5.24580379135387e-15,1,1.35308431126193e-15,5.24580379135387e-15,1,1.35308431126193e-15,5.24580379135387e-15,1,1.35308431126193e-15,5.24580379135387e-15,1,1.35308431126193e-15,5.24580379135387e-15,0.707106781186552,0.707106781186543,4.90152688185069e-15,0.707106781186552,0.707106781186543,4.90152688185069e-15,0.707106781186552,0.707106781186543,4.90152688185069e-15,0.707106781186552,0.707106781186543,4.90152688185069e-15,0.707106781186536,1.66210139130811e-15,-0.707106781186559,0.707106781186536,1.66210139130811e-15,-0.707106781186559,0.707106781186536,1.66210139130811e-15,-0.707106781186559,0.707106781186536,1.66210139130811e-15,-0.707106781186559,0.707106781186536,1.66210139130811e-15,-0.707106781186559,0.707106781186538,1.28904973266922e-15,0.707106781186557, +0.707106781186538,1.28904973266922e-15,0.707106781186557,0.707106781186538,1.28904973266922e-15,0.707106781186557,0.707106781186538,1.28904973266922e-15,0.707106781186557,2.83106871279415e-15,1.11022302462512e-15,-1,2.83106871279415e-15,1.11022302462512e-15,-1,2.83106871279415e-15,1.11022302462512e-15,-1,2.83106871279415e-15,1.11022302462512e-15,-1,2.83106871279415e-15,1.11022302462512e-15,-1,-5.24580379135386e-15,-9.9920072216262e-16,1,-5.24580379135386e-15,-9.9920072216262e-16,1,-5.24580379135386e-15,-9.9920072216262e-16,1,-5.24580379135386e-15,-9.9920072216262e-16,1 + } + } + LayerElementUV: 0 { + Version: 101 + Name: "" + MappingInformationType: "ByPolygonVertex" + ReferenceInformationType: "IndexToDirect" + UV: *116 { + a: -0.406851599704662,-0.457754036523888,-0.426915634094131,-0.433796727275882,-0.410564356728596,-0.460433486457433,-0.423884180250086,-0.430007412391066,-0.49967056104745,-0.658712826620155,-0.526300691166398,-0.648971518046782,-0.527410281291384,-0.654147819389495,-0.499670559743455,-0.653353925040627,-0.446081531795738,-0.64076391705765,-0.426915678353167,-0.615683873281153,-0.448225091619884,-0.636122971951398,-0.423884226353249,-0.619473189261517,-0.377417791479357,-0.916546774419919,-0.377417794834402,-0.930334685218653,-0.36638746465886,-0.930334685510815,-0.621923467459207,-0.916546766661881,-0.632953803133133,-0.930334678450213,-0.632953587851005,-0.0456103162416248,-0.366387249376787,-0.0456104129693277,-0.499670497151723,-0.396126649223243,-0.471930776188928,-0.395332757604052,-0.499670495847728,-0.390767747643714,-0.47304036626804,-0.400509058732758,-0.47304042672701,-0.648971525155079,-0.551116021493864,-0.636122957716591,-0.572425426826126,-0.615683852019327,-0.41056438802446,-0.589047120008854,-0.588776706204198,-0.5890470921637,-0.599055546759175,-0.558027929381887,-0.400285533846829,-0.558027962783353,-0.602561462346642,-0.524740268539852,-0.396779602598687,-0.52474030572401,-0.599055530559241,-0.491452608964837,-0.400285517646898,-0.491452647397647,-0.588776674908328,-0.460433449897737,-0.572425382567084,-0.433796695951368,-0.448225037413855,-0.413357620904547,-0.55111596728783,-0.413357597955197,-0.526300630707425,-0.400509046593118,-0.396144492568128,-0.559414949214236,-0.406851632304521,-0.591726571284167,-0.471930839167021,-0.654147826684783,-0.527410218313287,-0.395332744849407,-0.553259527283181,-0.408716652478274,-0.575456834909413,-0.43000737954299,-0.396144475693199,-0.490065662463312,-0.575456881012582,-0.619473167332155,-0.592489463741748,-0.591726542467916,-0.603196572476889,-0.490065622319947,-0.592489431141883,-0.457753998251753,-0.392492480863015,-0.524740306498679,-0.5532595837478,-0.640763902418843,-0.603196589351821,-0.559414914530228,-0.446081475331125,-0.408716676572965, +-0.606848584767135,-0.524740267765181,-0.377417582907373,-0.0593983197655319,-0.621923258887174,-0.0593982323246414,-0.366387252731833,-0.059398323710233 + } + UVIndex: *354 { + a: 0,1,2,1,0,3,4,5,6,5,4,7,8,9,10,9,8,11,12,13,14,13,12,15,15,16,13,17,18,17,18,17,18,19,20,21,20,19,22,23,5,7,5,23,24,24,23,10,24,10,9,24,9,25,25,9,26,25,26,27,27,26,28,28,26,29,28,29,30,30,29,31,30,31,32,32,31,33,32,33,34,34,33,2,34,2,35,35,2,1,35,1,36,35,36,37,37,36,38,38,36,22,38,22,19,26,39,29,39,26,40,41,7,4,7,41,23,38,21,42,21,38,19,35,43,44,43,35,37,45,2,33,2,45,0,9,40,26,40,9,11,16,13,16,13,16,14,13,14,14,27,46,25,46,27,47,34,48,32,48,34,49,29,50,31,50,29,39,51,25,46,25,51,24,28,47,27,47,28,52,37,42,43,42,37,38,41,10,23,10,41,8,50,33,31,33,50,45,1,53,36,53,1,3,54,28,30,28,54,52,6,24,51,24,6,5,48,30,32,30,48,54,36,20,22,20,36,53,44,34,35,34,44,49,12,41,4,41,12,8,8,12,11,11,12,40,40,12,39,39,12,50,50,12,55,50,55,45,45,55,0,0,55,3,3,55,53,53,55,20,20,55,21,21,55,56,15,54,56,54,15,52,52,15,47,47,15,46,46,15,12,46,12,51,51,12,6,6,12,4,56,54,48,56,48,49,56,49,44,56,44,43,56,43,42,56,42,21,55,17,56,17,55,18,14,57,12,12,18,55,18,12,57,17,15,56,15,17,16,14,18,57,18,14,18,18,14,14,17,16,17,16,17,16 + } + } + LayerElementMaterial: 0 { + Version: 101 + Name: "" + MappingInformationType: "ByPolygon" + ReferenceInformationType: "IndexToDirect" + Materials: *118 { + a: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + } + } + Layer: 0 { + Version: 100 + LayerElement: { + Type: "LayerElementNormal" + TypedIndex: 0 + } + LayerElement: { + Type: "LayerElementMaterial" + TypedIndex: 0 + } + LayerElement: { + Type: "LayerElementTexture" + TypedIndex: 0 + } + LayerElement: { + Type: "LayerElementUV" + TypedIndex: 0 + } + } + } + Geometry: 140569697652432, "Geometry::", "Mesh" { + Vertices: *402 { + a: 1.01000000000002,-1.13735915759108,-2.88819703742752,1.24545450725805,-1.15713437596647,-2.48113807294223,1.10860634196866,-1.77746864326619,-2.44892774412596,1.35277725488452,-1.81311999008032,-1.85972406157786,1.01000000000002,-2.03125284966598,-2.42298417411797,1.24073711475834,0.7593049389036,-2.47852540875875,1.3106058157655,0.123006751699209,-2.49512021891339,1.01000000000002,0.737640842408918,-2.88819703742752,1.01000000000002,0.608950358354292,-2.9415023812713,1.01000000000002,-2.38735915759108,-2.14973419345749,1.13941736162009,-3.05066256562907,0.710604786886332,1.01000000000002,-3.24257634659897,0.702015825882028,1.01000000000002,-3.32485915759109,0.0770158258820287,1.01000000000002,-1.00866867353646,-2.9415023812713,1.13816742813127,2.64966677983311,0.709493966937714,1.42604375667922,2.07510685316067,0.726264662991372,1.46395955379011,2.08333473700174,0.0763485126676824,1.01000000000002,-0.512359157591081,-3.0068427686219,1.31284259980565,-0.519701075977921,-2.49628732629024,1.57244449903031,-0.527940549952788,-1.89891749754302,1.01000000000002,-1.76235915759108,-2.62931356094434,1.01000000000002,1.36264084240891,-2.62931356094433,1.91685435264554,-0.539418642227518,0.0767185439769543,1.84017645416,-1.21140262303216,0.0769759309927592,1.80153305815406,-1.20763335936163,-0.59491104348912,1.01000000000002,0.112640842408919,-3.0068427686219,1.01000000000002,-0.199859157591081,-3.04798417411796,1.10585969419728,1.37848612095248,-2.44729987169911,1.01000000000002,2.92514084240891,0.0770158258820422,1.17618983954099,2.65970139223203,0.0764913760898178,1.13936926976446,2.65077656567347,-0.556597337054683,1.42828678031292,-2.47693027551933,0.7277367244047,1.17615487368084,-3.05965752776328,0.0774464439653273,1.01000000000002,-3.24257634659897,-0.547984174117971,1.24662355057374,0.75755419991751,2.63536531794631,1.01000000000002,0.737640842408905,3.04222868919159,1.01000000000002,0.608950358354279,3.09553403303538,1.65069763494539,-1.85865475095621,0.740444850501438,1.46452756029124,-2.48376850201163,0.0773667267984183, +1.64866604538675,1.45703438246767,0.739205868830993,1.80035612017221,0.806986349408132,0.748043706263837,1.8390772193333,0.810882339847085,0.0764525746984386,1.87817307581289,0.138413866867284,-0.599675645841,1.8783296764432,-0.537877400631121,-0.599496553342923,1.76255555481268,-0.534021951819915,-1.26248400129472,1.13729641509454,-3.04892239196676,-0.555213536192521,1.64928246862387,-1.8576467537734,-0.585853445388776,1.68804013188748,-1.86371218077538,0.0771978572302552,1.42581422170174,-2.47521762921137,-0.572548033331086,1.11427716713354,1.3797212430062,2.60545530870542,1.49933524208152,0.779943820341958,2.03933446182546,1.01000000000002,-2.38735915759109,2.30376584522155,1.01000000000002,-2.40956784879906,2.28672451708999,1.14256345528451,-2.41773475504217,1.97767733473688,1.14753386752115,2.0191883329134,1.9789733003066,1.01000000000001,1.98764084240891,2.30376584522156,1.01000000000002,1.6315345344838,2.57701582588204,1.53615869974548,1.44012114512584,1.38892193606491,1.68586569826774,0.796627009331924,1.40655248922217,1.42761852150863,2.07652223130155,-0.573835024673912,1.57227940676395,0.130425041291102,-1.89892217875485,1.13562757384631,-2.41381321868139,-1.8203556848156,1.01000000000002,-2.40956784879905,-2.13269286532593,1.49969555507586,-1.18018295754278,-1.88614276771897,1.3145812099688,-2.45130054127974,-1.20901389434623,1.01000000000002,-2.66639886067403,-1.79798417411797,1.14247500809543,2.01790388458737,-1.82365810983757,1.01000000000002,1.98764084240892,-2.14973419345747,1.01000000000002,-3.01235915759108,-1.22916563986874,1.03490215555889,-3.02227251855286,-1.17680038682331,1.01000000000002,-3.03563028265905,-1.17298417411797,1.01000000000002,1.63153453448381,-2.42298417411796,1.91636415817454,0.139034263910758,0.0765681064998937,1.24008395674133,-1.15895007304208,2.63207946071119,1.10562091082463,-1.77816640619096,2.60113373239585,1.3552439301795,-1.81549556857492,2.01494933955744,1.01000000000002,-3.03563028265905,1.32701582588203,1.03468121299743,-3.02255798482681,1.33174029598251,1.01000000000002,-3.01235915759109,1.38319729163279, +1.31025446097989,-0.522831540742542,2.64862908880467,1.4983654291615,-1.18214117306898,2.03952556967069,1.01000000000002,2.50647022923528,-1.48548417411796,1.01000000000002,2.26668054549186,-1.79798417411796,1.01000000000002,2.84285803141679,-0.547984174117958,1.03463471974321,2.62274600018102,-1.17764754859993,1.01000000000002,2.81865904956225,-0.731793690063338,1.01000000000002,2.00984953361688,-2.13269286532592,1.68680880243582,-1.19858356816115,1.4074275535804,1.5388363490205,-1.8425690383973,1.39070475134357,1.31262349436778,0.119852377923598,2.64985563688214,1.57173410971694,0.127771654179258,2.05201972514242,1.76257453496256,0.135559038150519,-1.26256643868851,1.3192730313385,2.05460834381924,-1.21138301490761,1.53858625954812,1.4424305824886,-1.2369588698042,1.35526611343445,1.41566595512152,-1.86112762581456,1.53609181598908,-1.84057176866671,-1.23563151227436,1.87697237267877,0.137478361067544,0.752638708931821,1.68652431296577,-1.19713150310831,-1.25344547884554,1.80168816278407,-1.20838485245113,0.748809830416991,1.01000000000002,2.84285803141678,0.702015825882041,1.01000000000001,2.00984953361687,2.28672451709,1.64996916651083,1.45826482877273,-0.586692108776385,1.8015633019206,0.808067557908566,-0.595406643346915,1.68717502714831,0.798602597189077,-1.25396440727238,1.68722634442755,1.46309321197531,0.0763063776652513,1.01000000000001,2.63591196747687,1.32701582588204,1.01000000000001,2.61264084240891,1.38319729163279,1.040520441661,2.62536968060381,1.33288190967785,1.01000000000002,-1.13735915759109,3.04222868919158,1.01000000000002,-1.7623591575911,2.7833452127084,1.01000000000002,-3.21837736474443,-0.731793690063355,1.57098610463903,-0.530354542158138,2.0519408116637,1.01000000000002,2.61264084240891,-1.22916563986871,1.01000000000001,2.50647022923528,1.63951582588204,1.01000000000001,2.26668054549185,1.95201582588204,1.49929746967605,0.782377103667377,-1.88623706377319,1.7614874329961,-0.53564607774176,1.41569296033336,1.87741191518276,-0.538652982048277,0.75290566458556,1.31976037322881,-2.45476049827524,1.365445691508, +1.01000000000002,-3.21837736474443,0.885825341827402,1.76128004680998,0.13368385362886,1.41544114833018,1.01000000000002,-0.512359157591095,3.16087442038597,1.01000000000002,-2.90618854441746,1.63951582588202,1.01000000000002,-2.90618854441746,-1.48548417411798,1.01000000000002,0.112640842408905,3.16087442038597,1.01000000000002,-0.199859157591099,3.20201582588203,1.01000000000002,-2.03125284966599,2.57701582588203,1.01000000000002,-1.00866867353648,3.09553403303537,1.31583596075064,2.0517295469934,1.36323402435216,1.35291294586493,1.41291365137219,2.0130630816316,1.01000000000002,-2.66639886067404,1.95201582588203,1.01000000000002,2.63591196747687,-1.17298417411796,1.01000000000002,1.3626408424089,2.7833452127084,1.01000000000002,2.81865904956224,0.88582534182742 + } + PolygonVertexIndex: *630 { + a: 0,1,-3,2,3,-5,5,6,-8,7,6,-9,3,9,-5,10,11,-13,13,1,-1,14,15,-17,17,1,-14,18,19,-2,20,2,-5,21,5,-8,22,23,-25,25,18,-27,27,5,-22,28,29,-31,31,10,-33,32,12,-34,34,35,-37,37,31,-39,39,40,-42,42,43,-45,38,32,-46,46,47,-49,49,34,-51,51,52,-54,54,55,-57,57,58,-41,29,59,-31,60,18,-7,9,61,-63,1,63,-3,61,64,-66,24,23,-47,66,27,-68,68,69,-71,71,27,-22,49,35,-35,72,43,-43,73,74,-76,43,22,-25,31,32,-39,10,12,-33,76,77,-79,79,73,-81,81,66,-83,83,84,-86,82,66,-87,87,88,-38,34,89,-91,91,19,-61,92,93,-95,24,46,-96,40,58,-97,92,94,-67,43,24,-98,98,37,-48,28,99,-30,72,22,-44,54,100,-56,48,45,-70,101,102,-104,15,39,-105,29,16,-60,104,41,-103,8,6,-26,105,106,-108,84,92,-67,3,95,-62,44,43,-98,97,95,-4,16,104,-102,28,30,-84,26,18,-18,59,101,-94,108,109,-74,45,33,-111,39,57,-41,72,96,-23,98,47,-24,99,14,-30,59,93,-93,79,80,-112,94,5,-28,101,103,-94,95,46,-65,64,48,-70,70,45,-111,69,45,-71,84,66,-113,19,44,-64,53,78,-78,107,113,-115,115,6,-6,14,105,-108,77,11,-11,83,30,-85,104,39,-42,41,40,-73,116,98,-118,87,37,-99,88,31,-38,118,10,-32,16,15,-105,77,119,-12,37,38,-48,104,102,-102,41,42,-103,48,38,-46,96,120,-118,117,23,-23,102,42,-92,50,34,-91,45,32,-34,103,60,-116,54,56,-50,6,18,-26,79,108,-74,89,121,-80,53,122,-79,112,66,-82,64,69,-124,34,124,-90,107,114,-55,17,18,-2,74,51,-54,30,92,-85,120,116,-118,89,124,-126,34,36,-125,0,2,-21,111,87,-117,74,126,-52,79,127,-109,16,101,-60,121,127,-80,58,50,-121,107,128,-16,74,53,-76,89,125,-122,42,44,-92,89,79,-112,93,103,-116,46,48,-65,15,128,-40,64,123,-66,114,100,-55,66,94,-28,73,75,-81,95,64,-62,63,97,-4,57,129,-59,53,130,-123,75,53,-119,111,80,-88,80,75,-89,90,111,-117,50,90,-121,129,50,-59,107,106,-114,54,129,-58,102,91,-104,67,27,-72,73,109,-75,52,130,-54,54,49,-130,84,131,-86,47,38,-49,40,96,-73,23,47,-47,109,126,-75,29,14,-17,56,132,-50,41,72,-43,96,117,-23,93,115,-95,129,49,-51,117,98,-24,30,59,-93,99,133,-15,118,77,-11,112,131,-85,103,91,-61,58,120,-97,116,87,-99,123,69,-69,107,54,-129,88,118,-32,97,24,-96,128,57,-40,91,44,-20,128,54,-58,120,90,-117,119,77,-77,44,97,-64,66, +67,-87,94,115,-6,115,60,-7,60,19,-19,19,63,-2,49,132,-36,63,3,-3,3,61,-10,62,61,-66,90,89,-112,80,88,-88,75,118,-89,53,77,-119,133,105,-15,14,107,-16 + } + GeometryVersion: 124 + LayerElementNormal: 0 { + Version: 101 + Name: "" + MappingInformationType: "ByVertice" + ReferenceInformationType: "Direct" + Normals: *402 { + a: 0.84564554824681,-0.205840127134581,-0.492456545079434,0.879886927675133,-0.145472033480632,-0.452368082407927,0.860417501565838,-0.264948255614617,-0.435297765725914,0.894257100096969,-0.29202061620846,-0.339158073227501,0.840069872009417,-0.347042211160103,-0.416946415999932,0.879423124674302,0.177732591758268,-0.441617587529047,0.890435541361485,0.0822407474967148,-0.447617030653953,0.870059246556305,0.160888695868569,-0.465952502969547,0.878916237330527,0.119537407078922,-0.461754324360473,0.87409763406212,-0.308671198720238,-0.375067216919336,0.858066588322191,-0.500632948517176,0.114404461731675,0.893410335127745,-0.440461285346631,0.0883845529361542,0.840756465437114,-0.541034769267722,0.0202470805084032,0.8640028544267,-0.134361997313517,-0.485227700384506,0.815059831616476,0.570529903824182,0.100861785269209,0.913211613588609,0.391713848137053,0.112271144932935,0.919132745837031,0.393943190275402,0.00193865048888704,0.864670534523004,-0.0771903573638924,-0.496373362961529,0.889848648831424,-0.0297566631479714,-0.455284442048252,0.9379232569265,-0.0546208719620048,-0.342514998886906,0.831862896843552,-0.281471616314216,-0.478307275780452,0.842488839935606,0.255918979902002,-0.474044333696624,0.99839788841502,-0.0565808711378248,0.000511301979149448,0.985321673618307,-0.170707693110644,-0.000288116055243545,0.978457653229242,-0.171384993747336,-0.115099108403797,0.871080793455644,0.04346605228154,-0.489212585254861,0.875697164060631,-0.00370955468739328,-0.482846472556432,0.853920563198148,0.297889247541508,-0.426710285728516,0.84097142908217,0.540700097205305,-0.0202598210669805,0.869526152767471,0.493876031762997,0.00327641624874075,0.858462994400944,0.499962016804745,-0.114364631756052,0.912048406305437,-0.39445257283486,0.112137738249321,0.869529232823823,-0.493865922389146,-0.00391968972384808,0.836952342397332,-0.543092836886415,-0.0675347842099586,0.880356330802403,0.142528908277278,0.452391689934085,0.839245506956666,0.206995927308257,0.502811759141374,0.862794126397818,0.134906066462026,0.48722340736583, +0.952504174426127,-0.282711681845509,0.113180840467306,0.918811413346916,-0.394687792649041,-0.00267077465748629,0.951986386483155,0.283753518402522,0.114916755718803,0.978544208940055,0.170995260954988,0.114942820049,0.985277101535627,0.170961439746929,0.00110422335172127,0.991808795537877,0.0570783239158889,-0.114268884796597,0.991755841711501,-0.0570093747699082,-0.114761847403465,0.971704537558402,-0.0567314077000198,-0.229285496856619,0.826524503057579,-0.552964830410468,-0.105295499308111,0.9515452749989,-0.284949563078078,-0.115608546954282,0.958839593185058,-0.283944656938319,-0.00143747587527904,0.91193713972301,-0.393956737469013,-0.114755140175011,0.853392802713984,0.277147232671204,0.441486280306267,0.927472716402776,0.166013290421762,0.335013354557392,0.853568378889442,-0.32326363792975,0.40856045201717,0.845394408916785,-0.38259144211301,0.372735941108618,0.849792268881948,-0.404415361297955,0.338084775307488,0.859772674602891,0.375991861210056,0.345573535314829,0.866256621937082,0.304136786474158,0.396358776947513,0.821924511840929,0.357277800956927,0.443613198381691,0.933391539471931,0.280459582104302,0.223880898801349,0.95871171743936,0.170346345284721,0.227714658053913,0.912283958928869,0.393960503924668,-0.111951327051051,0.937158406949225,0.0565311976691845,-0.344293978998294,0.875038579803808,-0.365455975930326,-0.317410481099392,0.863273176577272,-0.361604267189768,-0.352138859758955,0.926115486728485,-0.167869403105737,-0.337831272594153,0.890098831889757,-0.392808387981628,-0.231139870640624,0.849601204577227,-0.42898791783602,-0.306834091214848,0.850136777808742,0.404133473664469,-0.337555320622946,0.853325654171827,0.32362380341752,-0.408782291438612,0.400382380425752,-0.846595309229326,-0.350671258924238,0.684239683468627,-0.687329847250849,-0.243708302371662,0.603440028045889,-0.764068033337397,-0.228166984868315,0.814858804823922,0.352874341494546,-0.459874795260319,0.998346416281073,0.0574788761009211,0.000782240955999146,0.879928513584551,-0.177274480412824,0.440794248573238,0.854376870074264,-0.297233109800839,0.426254199181929, +0.899689130816336,-0.275856899224298,0.338322980362406,0.384150395212355,-0.852990746784457,0.353320335896882,0.755701518425688,-0.596727369911314,0.269873416712049,0.699398979497609,-0.633249377166631,0.331415590755438,0.890949222128615,-0.0822952030277493,0.446583679893296,0.924555303446925,-0.165840153199561,0.343066370335114,0.874384256840548,0.413189350312047,-0.254414488931175,0.808097786642103,0.467323481847798,-0.35858991973811,0.893648072314271,0.439988117451044,-0.0883378704230192,0.757028677807666,0.595358128315162,-0.2691770421597,0.781752031472108,0.585663924858145,-0.214153049030327,0.845638464309166,0.382313890686304,-0.372467014202783,0.958753347985184,-0.168253271983725,0.229091366476284,0.932745788884378,-0.280464334706112,0.226550326144805,0.890308052753974,0.0288816955389532,0.454441876222055,0.938328152781035,0.0538207933439414,0.341531257577339,0.971644592317742,0.0566277547461412,-0.22956498777492,0.892256411702988,0.392610286047029,-0.223014930139168,0.932681416916238,0.281204625065643,-0.22589673167359,0.899571445050289,0.276662782706618,-0.337977691445996,0.931144484672526,-0.285065252668823,-0.227393382456034,0.991670918641271,0.057319416356404,0.115339818058375,0.958456115924878,-0.171171093313061,-0.228171713102673,0.97881090453973,-0.169699198215527,0.114592300261071,0.835483244367123,0.545406884407468,0.0670751729235549,0.834288620701586,0.394807793290082,0.384823730720002,0.952441228190992,0.283102401875828,-0.112733033730897,0.978758700330954,0.170588441077833,-0.113714512253697,0.958761220002684,0.169246690424556,-0.228325383607036,0.958945183689275,0.283587823262075,0.00144262837245005,0.509478931485624,0.82837564497835,0.232862640152877,0.238485757892418,0.897221907707616,0.371641482630755,0.708661073286876,0.654554115267096,0.263359817350336,0.870732078315782,-0.160747516114452,0.46474281474264,0.843443267957115,-0.255191222401467,0.472737658482024,0.853403632786483,-0.504501867643533,-0.13107289991078,0.937311897842126,-0.0564596255702131,0.343887651485282,0.701197332254195,0.631777261615939,-0.330423656756997, +0.681158559877181,0.657212546340123,0.322637079764828,0.861958718400082,0.410436383348153,0.297605683746422,0.924395968021638,0.166671731140445,-0.343092740150511,0.971614805038675,-0.0560562825401509,0.229831163721188,0.991745113745743,-0.0561220371821349,0.115290703458562,0.892039005194586,-0.392850359237236,0.22346142499015,0.780216050541226,-0.587472954864481,0.214798607492335,0.971787154888441,0.0565984700141611,0.228967986377756,0.871486789292394,-0.0434817830680938,0.488487574693619,0.874172747593701,-0.413515408129842,0.254611497391004,0.746753072267983,-0.587892606792246,-0.311033972320302,0.864592226014213,0.0764526131653918,0.496623882486507,0.876017620041014,0.00370319665492413,0.48226488127606,0.815905304320697,-0.351977063836265,0.45870544024957,0.879323187559733,-0.119351624347099,0.461027029126818,0.903021534193032,0.376215495959513,0.2073981904058,0.91058033742172,0.263509891983342,0.31844306544165,0.807784351166701,-0.467664427490083,0.358851536530868,0.388268548272367,0.851397740459343,-0.352660491072071,0.811232842133415,0.296453582007838,0.504000545196991,0.851246097122103,0.507901305683755,0.131971003705833 + } + } + LayerElementUV: 0 { + Version: 101 + Name: "" + MappingInformationType: "ByPolygonVertex" + ReferenceInformationType: "IndexToDirect" + UV: *268 { + a: -0.0460105264588013,-0.643198117267299,-0.108830379850367,-0.646249944786925,-0.113801303365397,-0.741983757220909,-0.204730859011916,-0.74748568672318,-0.117805086236018,-0.78114930210189,-0.109233500101505,-0.35049320151043,-0.106672513799962,-0.44869066535242,-0.0460104460136341,-0.353836549948543,-0.0377840419333149,-0.373696860802272,-0.159974726990919,-0.836105823620476,-0.601400000793821,-0.938470893316988,-0.600074507152402,-0.968088216542574,-0.503620626547876,-0.980786610028217,-0.0377841113357861,-0.623337808707369,-0.601228327583781,-0.0587607662591158,-0.603816510346117,-0.147430411812581,-0.503517410594599,-0.146160657630067,-0.0277003583112275,-0.546744263801626,-0.106492426155829,-0.547877304031636,-0.198682230439736,-0.549148858952944,-0.0859630494329842,-0.739651970148495,-0.0859629153577016,-0.257382685927258,-0.503574628651196,-0.550920190973734,-0.50361437904484,-0.65462491770788,-0.3999246112316,-0.654043231583557,-0.0277003314961718,-0.450290408519694,-0.0213511493911123,-0.498517337045844,-0.114052391290366,-0.254937338943689,-0.503620358397233,-0.0162479295906368,-0.503539433436657,-0.0572121883333961,-0.40583725448217,-0.0585895483731591,-0.60404388331938,-0.849928973035488,-0.503687070826598,-0.93985905321366,-0.407166744055643,-0.968088218254007,-0.89844087691957,-0.35076324390924,-0.961230574920394,-0.353836385538967,-0.96945699426729,-0.373696698581212,-0.606005053846177,-0.754512864860315,-0.503674743670316,-0.850984294656204,-0.605813704232573,-0.242815182896669,-0.607177642160145,-0.343134621022263,-0.503533524686888,-0.342533386592888,-0.399189250497803,-0.446312899222316,-0.39921691817842,-0.550682350067821,-0.296900586426396,-0.550087366161384,-0.40605105575414,-0.938202342296567,-0.401322463830642,-0.754357318470235,-0.503648656066835,-0.755293365715378,-0.403375864033046,-0.849664675237358,-0.89382495083716,-0.254746565726053,-0.806457674765619,-0.347307955430374,-0.847266511321232,-0.836105792304654,-0.844636588181444,-0.839533175423335,-0.796942499609629, +-0.840793545169165,-0.797142310735299,-0.156060058811293,-0.847266323615737,-0.160928651494149,-0.889435981474388,-0.215885176886559,-0.706081931993101,-0.245425317397109,-0.708802816367375,-0.344733320028389,-0.403177052258969,-0.147212029460383,-0.198681479759597,-0.447545814986695,-0.210806456183054,-0.840188375400235,-0.162604651035223,-0.839533205849627,-0.200653733734038,-0.649806935210422,-0.305152506735148,-0.845973646516863,-0.214258976929844,-0.879168951603058,-0.210296615388268,-0.156258420497593,-0.159974539285515,-0.160928811818356,-0.302042588631744,-0.932559679785725,-0.310123919232653,-0.934089570768033,-0.310712861387679,-0.936151023473019,-0.117804929087454,-0.215885345095242,-0.503551383097034,-0.446217139646539,-0.897933865138974,-0.646530076822477,-0.893158153683814,-0.742091384421526,-0.802694521979258,-0.747852258751269,-0.696528387581197,-0.936151016624561,-0.697257496665814,-0.934133618598793,-0.705198660242026,-0.93255967222694,-0.900487879797124,-0.54836031698078,-0.806487251901646,-0.650109080192945,-0.262485688654116,-0.0808598313305901,-0.21425876528054,-0.117865668699514,-0.407166482965558,-0.0289463482594252,-0.309992937785652,-0.0629154235690636,-0.378799859703272,-0.0326808924318828,-0.162604461424131,-0.157501428855895,-0.708937947351849,-0.652646581997156,-0.70635720799093,-0.752030411157123,-0.900677140781882,-0.449177346192873,-0.808415371693804,-0.447955208494557,-0.296887835449506,-0.446753489779995,-0.304786696055178,-0.15059393933858,-0.300839697994897,-0.245068995761747,-0.204514113769978,-0.249199498572964,-0.301044684883593,-0.751722208090174,-0.607886800274641,-0.446457240146408,-0.298295495634622,-0.652422529999037,-0.607295961671968,-0.654159186706563,-0.600074246062283,-0.0289462961816965,-0.844636398570262,-0.15750126910878,-0.40119289382933,-0.24262533588677,-0.399848040706211,-0.342967800101241,-0.298215325760974,-0.344428509897803,-0.503510934670252,-0.241880168364944,-0.696528144248732,-0.0608834692051191,-0.705198418906412,-0.0644748111851742,-0.697433435280919, +-0.0625104200115184,-0.961230655365611,-0.643198026482768,-0.921278166578077,-0.739651909689102,-0.37880011871688,-0.964353681991116,-0.808403221509934,-0.549521324778632,-0.302042347296202,-0.0644749160398415,-0.744755096395935,-0.0808597080965775,-0.792982054570726,-0.117865526772581,-0.200639097181917,-0.346932546048369,-0.710213487957416,-0.550337959642432,-0.607928027540248,-0.550802016524531,-0.70245909883662,-0.846507591510186,-0.628441133904713,-0.964353679517173,-0.710174598043744,-0.447042816310621,-0.97954077938712,-0.546744143860917,-0.744755328621241,-0.916174764285806,-0.262485920879346,-0.9161747755247,-0.979540752572047,-0.450290263055329,-0.985889964874839,-0.498517202572939,-0.889436138623036,-0.781149255153924,-0.969457063669804,-0.623337711146723,-0.702117587240977,-0.151038119278979,-0.802403284381166,-0.249624126359424,-0.792982266220115,-0.879168932162503,-0.31071261805528,-0.0608835699349863,-0.921278032502717,-0.257382513472746,-0.62844087489106,-0.0326808252975284 + } + UVIndex: *630 { + a: 0,1,2,2,3,4,5,6,7,7,6,8,3,9,4,10,11,12,13,1,0,14,15,16,17,1,13,18,19,1,20,2,4,21,5,7,22,23,24,25,18,26,27,5,21,28,29,30,31,10,32,32,12,33,34,35,36,37,31,38,39,40,41,42,43,44,38,32,45,46,47,48,49,34,50,51,52,53,54,55,56,57,58,40,29,59,30,60,18,6,9,61,62,1,63,2,61,64,65,24,23,46,66,27,67,68,69,70,71,27,21,49,35,34,72,43,42,73,74,75,43,22,24,31,32,38,10,12,32,76,77,78,79,73,80,81,66,82,83,84,85,82,66,86,87,88,37,34,89,90,91,19,60,92,93,94,24,46,95,40,58,96,92,94,66,43,24,97,98,37,47,28,99,29,72,22,43,54,100,55,48,45,69,101,102,103,15,39,104,29,16,59,104,41,102,8,6,25,105,106,107,84,92,66,3,95,61,44,43,97,97,95,3,16,104,101,28,30,83,26,18,17,59,101,93,108,109,73,45,33,110,39,57,40,72,96,22,98,47,23,99,14,29,59,93,92,79,80,111,94,5,27,101,103,93,95,46,64,64,48,69,70,45,110,69,45,70,84,66,112,19,44,63,53,78,77,107,113,114,115,6,5,14,105,107,77,11,10,83,30,84,104,39,41,41,40,72,116,98,117,87,37,98,88,31,37,118,10,31,16,15,104,77,119,11,37,38,47,104,102,101,41,42,102,48,38,45,96,120,117,117,23,22,102,42,91,50,34,90,45,32,33,103,60,115,54,56,49,6,18,25,79,108,73,89,121,79,53,122,78,112,66,81,64,69,123,34,124,89,107,114,54,17,18,1,74,51,53,30,92,84,120,116,117,89,124,125,34,36,124,0,2,20,111,87,116,74,126,51,79,127,108,16,101,59,121,127,79,58,50,120,107,128,15,74,53,75,89,125,121,42,44,91,89,79,111,93,103,115,46,48,64,15,128,39,64,123,65,114,100,54,66,94,27,73,75,80,95,64,61,63,97,3,57,129,58,53,130,122,75,53,118,111,80,87,80,75,88,90,111,116,50,90,120,129,50,58,107,106,113,54,129,57,102,91,103,67,27,71,73,109,74,52,130,53,54,49,129,84,131,85,47,38,48,40,96,72,23,47,46,109,126,74,29,14,16,56,132,49,41,72,42,96,117,22,93,115,94,129,49,50,117,98,23,30,59,92,99,133,14,118,77,10,112,131,84,103,91,60,58,120,96,116,87,98,123,69,68,107,54,128,88,118,31,97,24,95,128,57,39,91,44,19,128,54,57,120,90,116,119,77,76,44,97,63,66,67,86,94,115,5,115,60,6,60,19,18,19,63,1,49,132,35,63,3,2,3,61,9,62,61,65,90,89,111,80,88,87,75,118,88,53,77,118,133,105,14,14,107,15 + } + } + LayerElementMaterial: 0 { + Version: 101 + Name: "" + MappingInformationType: "ByPolygon" + ReferenceInformationType: "IndexToDirect" + Materials: *210 { + a: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + } + } + Layer: 0 { + Version: 100 + LayerElement: { + Type: "LayerElementNormal" + TypedIndex: 0 + } + LayerElement: { + Type: "LayerElementMaterial" + TypedIndex: 0 + } + LayerElement: { + Type: "LayerElementTexture" + TypedIndex: 0 + } + LayerElement: { + Type: "LayerElementUV" + TypedIndex: 0 + } + } + } + Geometry: 140569681203216, "Geometry::", "Mesh" { + Vertices: *12 { + a: 7.65163388306112e-18,12.8313908424089,-4.45423417411793,3.32790356661296e-14,-11.2311091575911,4.60826582588201,-3.7288039554929e-15,12.8313908424089,4.60826582588204,4.59688848375951e-14,-11.2311091575911,-4.45423417411796 + } + PolygonVertexIndex: *6 { + a: 0,1,-3,1,0,-4 + } + GeometryVersion: 124 + LayerElementNormal: 0 { + Version: 101 + Name: "" + MappingInformationType: "ByVertice" + ReferenceInformationType: "Direct" + Normals: *12 { + a: -1,-1.35308431126193e-15,-3.42781358853017e-15,-1,-1.35308431126193e-15,-3.42781358853017e-15,-1,-1.35308431126193e-15,-3.42781358853017e-15,-1,-1.35308431126193e-15,-3.42781358853017e-15 + } + } + LayerElementUV: 0 { + Version: 101 + Name: "" + MappingInformationType: "ByPolygonVertex" + ReferenceInformationType: "IndexToDirect" + UV: *8 { + a: -0.999999999999995,0.999999999999994,-0.00156738631786177,0.0051975231806893,-0.0112955752098978,0.999998465489192,-0.990271707686745,0.00519753115635761 + } + UVIndex: *6 { + a: 0,1,2,1,0,3 + } + } + LayerElementMaterial: 0 { + Version: 101 + Name: "" + MappingInformationType: "ByPolygon" + ReferenceInformationType: "IndexToDirect" + Materials: *2 { + a: 0,0 + } + } + Layer: 0 { + Version: 100 + LayerElement: { + Type: "LayerElementNormal" + TypedIndex: 0 + } + LayerElement: { + Type: "LayerElementMaterial" + TypedIndex: 0 + } + LayerElement: { + Type: "LayerElementTexture" + TypedIndex: 0 + } + LayerElement: { + Type: "LayerElementUV" + TypedIndex: 0 + } + } + } + Model: 140569683031040, "Model::Model", "Null" { + Version: 232 + Properties70: { + P: "ScalingMax", "Vector3D", "Vector", "",0,0,0 + } + Shading: Y + Culling: "CullingOff" + } + Model: 140569684590080, "Model::Group1", "Null" { + Version: 232 + Properties70: { + P: "ScalingMax", "Vector3D", "Vector", "",0,0,0 + } + Shading: Y + Culling: "CullingOff" + } + Model: 140569622889472, "Model::Mesh1", "Mesh" { + Version: 232 + Properties70: { + P: "ScalingMax", "Vector3D", "Vector", "",0,0,0 + P: "DefaultAttributeIndex", "int", "Integer", "",0 + } + Shading: T + Culling: "CullingOff" + } + Model: 140569622883328, "Model::Group2", "Null" { + Version: 232 + Properties70: { + P: "ScalingMax", "Vector3D", "Vector", "",0,0,0 + } + Shading: Y + Culling: "CullingOff" + } + Model: 140569684765696, "Model::Mesh2", "Mesh" { + Version: 232 + Properties70: { + P: "ScalingMax", "Vector3D", "Vector", "",0,0,0 + P: "DefaultAttributeIndex", "int", "Integer", "",0 + } + Shading: T + Culling: "CullingOff" + } + Model: 140569632555008, "Model::Mesh3", "Mesh" { + Version: 232 + Properties70: { + P: "ScalingMax", "Vector3D", "Vector", "",0,0,0 + P: "DefaultAttributeIndex", "int", "Integer", "",0 + } + Shading: T + Culling: "CullingOff" + } + Material: 140569697179264, "Material::hal9000", "" { + Version: 102 + ShadingModel: "phong" + MultiLayer: 0 + Properties70: { + P: "AmbientColor", "Color", "", "A",0,0,0 + P: "DiffuseColor", "Color", "", "A",0.270588235294118,0.258823529411765,0.258823529411765 + P: "TransparentColor", "Color", "", "A",1,1,1 + P: "SpecularColor", "Color", "", "A",0.33,0.33,0.33 + P: "ReflectionFactor", "Number", "", "A",0 + P: "Emissive", "Vector3D", "Vector", "",0,0,0 + P: "Ambient", "Vector3D", "Vector", "",0,0,0 + P: "Diffuse", "Vector3D", "Vector", "",0.270588235294118,0.258823529411765,0.258823529411765 + P: "Specular", "Vector3D", "Vector", "",0.33,0.33,0.33 + P: "Shininess", "double", "Number", "",20 + P: "Opacity", "double", "Number", "",1 + P: "Reflectivity", "double", "Number", "",0 + } + } + Material: 140569692045024, "Material::hal9000eye", "" { + Version: 102 + ShadingModel: "phong" + MultiLayer: 0 + Properties70: { + P: "AmbientColor", "Color", "", "A",0,0,0 + P: "DiffuseColor", "Color", "", "A",0.352941176470588,0.0352941176470588,0.0235294117647059 + P: "TransparentColor", "Color", "", "A",1,1,1 + P: "SpecularColor", "Color", "", "A",0.33,0.33,0.33 + P: "ReflectionFactor", "Number", "", "A",0 + P: "Emissive", "Vector3D", "Vector", "",0,0,0 + P: "Ambient", "Vector3D", "Vector", "",0,0,0 + P: "Diffuse", "Vector3D", "Vector", "",0.352941176470588,0.0352941176470588,0.0235294117647059 + P: "Specular", "Vector3D", "Vector", "",0.33,0.33,0.33 + P: "Shininess", "double", "Number", "",20 + P: "Opacity", "double", "Number", "",1 + P: "Reflectivity", "double", "Number", "",0 + } + } + Material: 140569681196576, "Material::kal9000back", "" { + Version: 102 + ShadingModel: "phong" + MultiLayer: 0 + Properties70: { + P: "AmbientColor", "Color", "", "A",0,0,0 + P: "DiffuseColor", "Color", "", "A",0.552941176470588,0.494117647058824,0.419607843137255 + P: "TransparentColor", "Color", "", "A",1,1,1 + P: "SpecularColor", "Color", "", "A",0.33,0.33,0.33 + P: "ReflectionFactor", "Number", "", "A",0 + P: "Emissive", "Vector3D", "Vector", "",0,0,0 + P: "Ambient", "Vector3D", "Vector", "",0,0,0 + P: "Diffuse", "Vector3D", "Vector", "",0.552941176470588,0.494117647058824,0.419607843137255 + P: "Specular", "Vector3D", "Vector", "",0.33,0.33,0.33 + P: "Shininess", "double", "Number", "",20 + P: "Opacity", "double", "Number", "",1 + P: "Reflectivity", "double", "Number", "",0 + } + } + Video: 140569697223136, "Video::hal9000_texture", "Clip" { + Type: "Clip" + Properties70: { + P: "Path", "KString", "XRefUrl", "", "Jan 7 kal9000/hal9000.jpg" + } + UseMipMap: 0 + Filename: "Jan 7 kal9000/hal9000.jpg" + RelativeFilename: "../../../../../hal9000.jpg" + } + Video: 140569697262960, "Video::hal9000eye_texture", "Clip" { + Type: "Clip" + Properties70: { + P: "Path", "KString", "XRefUrl", "", "Jan 7 kal9000/hal9000eye.tif" + } + UseMipMap: 0 + Filename: "Jan 7 kal9000/hal9000eye.tif" + RelativeFilename: "../../../../../hal9000eye.tif" + } + Video: 140569697264208, "Video::kal9000back_texture", "Clip" { + Type: "Clip" + Properties70: { + P: "Path", "KString", "XRefUrl", "", "Jan 7 kal9000/kal9000back.jpg" + } + UseMipMap: 0 + Filename: "Jan 7 kal9000/kal9000back.jpg" + RelativeFilename: "../../../../../kal9000back.jpg" + } + Texture: 140569694849776, "Texture::hal9000_texture", "" { + Type: "TextureVideoClip" + Version: 202 + TextureName: "Texture::hal9000_texture" + Media: "Video::hal9000_texture" + FileName: "Jan 7 kal9000/hal9000.jpg" + RelativeFilename: "../../../../../hal9000.jpg" + ModelUVTranslation: 0,0 + ModelUVScaling: 1,1 + Texture_Alpha_Source: "None" + Cropping: 0,0,0,0 + } + Texture: 140569694848000, "Texture::hal9000eye_texture", "" { + Type: "TextureVideoClip" + Version: 202 + TextureName: "Texture::hal9000eye_texture" + Media: "Video::hal9000eye_texture" + FileName: "Jan 7 kal9000/hal9000eye.tif" + RelativeFilename: "../../../../../hal9000eye.tif" + ModelUVTranslation: 0,0 + ModelUVScaling: 1,1 + Texture_Alpha_Source: "None" + Cropping: 0,0,0,0 + } + Texture: 140569681199040, "Texture::kal9000back_texture", "" { + Type: "TextureVideoClip" + Version: 202 + TextureName: "Texture::kal9000back_texture" + Media: "Video::kal9000back_texture" + FileName: "Jan 7 kal9000/kal9000back.jpg" + RelativeFilename: "../../../../../kal9000back.jpg" + ModelUVTranslation: 0,0 + ModelUVScaling: 1,1 + Texture_Alpha_Source: "None" + Cropping: 0,0,0,0 + } +} + +; Object connections +;------------------------------------------------------------------ + +Connections: { + + ;Model::Model, Model::RootNode + C: "OO",140569683031040,0 + + ;Model::Group1, Model::Model + C: "OO",140569684590080,140569683031040 + + ;Model::Group2, Model::Model + C: "OO",140569622883328,140569683031040 + + ;Model::Mesh3, Model::Model + C: "OO",140569632555008,140569683031040 + + ;Model::Mesh1, Model::Group1 + C: "OO",140569622889472,140569684590080 + + ;Geometry::, Model::Mesh1 + C: "OO",140569697341056,140569622889472 + + ;Material::hal9000, Model::Mesh1 + C: "OO",140569697179264,140569622889472 + + ;Texture::hal9000_texture, Model::Mesh1 + C: "OO",140569694849776,140569622889472 + + ;Video::hal9000_texture, Texture::hal9000_texture + C: "OO",140569697223136,140569694849776 + + ;Texture::hal9000_texture, Material::hal9000 + C: "OP",140569694849776,140569697179264, "DiffuseColor" + + ;Model::Mesh2, Model::Group2 + C: "OO",140569684765696,140569622883328 + + ;Geometry::, Model::Mesh2 + C: "OO",140569697652432,140569684765696 + + ;Material::hal9000eye, Model::Mesh2 + C: "OO",140569692045024,140569684765696 + + ;Texture::hal9000eye_texture, Model::Mesh2 + C: "OO",140569694848000,140569684765696 + + ;Video::hal9000eye_texture, Texture::hal9000eye_texture + C: "OO",140569697262960,140569694848000 + + ;Texture::hal9000eye_texture, Material::hal9000eye + C: "OP",140569694848000,140569692045024, "DiffuseColor" + + ;Geometry::, Model::Mesh3 + C: "OO",140569681203216,140569632555008 + + ;Material::kal9000back, Model::Mesh3 + C: "OO",140569681196576,140569632555008 + + ;Texture::kal9000back_texture, Model::Mesh3 + C: "OO",140569681199040,140569632555008 + + ;Video::kal9000back_texture, Texture::kal9000back_texture + C: "OO",140569697264208,140569681199040 + + ;Texture::kal9000back_texture, Material::kal9000back + C: "OP",140569681199040,140569681196576, "DiffuseColor" +} +;Takes section +;---------------------------------------------------- + +Takes: { + Current: "" +} diff --git a/src/parts source/kOSkal9000/KAL-9000 meshes/final kal9000.skp b/src/parts source/kOSkal9000/KAL-9000 meshes/final kal9000.skp new file mode 100644 index 000000000..8123aefff Binary files /dev/null and b/src/parts source/kOSkal9000/KAL-9000 meshes/final kal9000.skp differ diff --git a/src/parts source/kOSkal9000/KAL-9000 meshes/final kal9000~.skp b/src/parts source/kOSkal9000/KAL-9000 meshes/final kal9000~.skp new file mode 100644 index 000000000..a68eb0b39 Binary files /dev/null and b/src/parts source/kOSkal9000/KAL-9000 meshes/final kal9000~.skp differ diff --git a/src/parts source/kOSkal9000/KAL-9000 meshes/hal9000.fbx b/src/parts source/kOSkal9000/KAL-9000 meshes/hal9000.fbx new file mode 100644 index 000000000..ee568c84a --- /dev/null +++ b/src/parts source/kOSkal9000/KAL-9000 meshes/hal9000.fbx @@ -0,0 +1,666 @@ +; FBX 7.3.0 project file +; Copyright (C) 1997-2010 Autodesk Inc. and/or its licensors. +; All rights reserved. +; ---------------------------------------------------- + +FBXHeaderExtension: { + FBXHeaderVersion: 1003 + FBXVersion: 7300 + CreationTimeStamp: { + Version: 1000 + Year: 2015 + Month: 12 + Day: 20 + Hour: 9 + Minute: 22 + Second: 3 + Millisecond: 0 + } + Creator: "FBX SDK/FBX Plugins version 2013.3" + SceneInfo: "SceneInfo::GlobalInfo", "UserData" { + Type: "UserData" + Version: 100 + MetaData: { + Version: 100 + Title: "" + Subject: "" + Author: "" + Keywords: "" + Revision: "" + Comment: "" + } + Properties70: { + P: "DocumentUrl", "KString", "Url", "", "/var/folders/16/csq8fhn9279gfgk7gc955t500000gn/T/com.sketchup.SketchUp.2016.petergoddardE8Amop.fbx" + P: "SrcDocumentUrl", "KString", "Url", "", "/var/folders/16/csq8fhn9279gfgk7gc955t500000gn/T/com.sketchup.SketchUp.2016.petergoddardE8Amop.fbx" + P: "Original", "Compound", "", "" + P: "Original|ApplicationVendor", "KString", "", "", "" + P: "Original|ApplicationName", "KString", "", "", "" + P: "Original|ApplicationVersion", "KString", "", "", "" + P: "Original|DateTime_GMT", "DateTime", "", "", "" + P: "Original|FileName", "KString", "", "", "" + P: "LastSaved", "Compound", "", "" + P: "LastSaved|ApplicationVendor", "KString", "", "", "" + P: "LastSaved|ApplicationName", "KString", "", "", "" + P: "LastSaved|ApplicationVersion", "KString", "", "", "" + P: "LastSaved|DateTime_GMT", "DateTime", "", "", "" + } + } +} +GlobalSettings: { + Version: 1000 + Properties70: { + P: "UpAxis", "int", "Integer", "",1 + P: "UpAxisSign", "int", "Integer", "",1 + P: "FrontAxis", "int", "Integer", "",2 + P: "FrontAxisSign", "int", "Integer", "",1 + P: "CoordAxis", "int", "Integer", "",0 + P: "CoordAxisSign", "int", "Integer", "",1 + P: "OriginalUpAxis", "int", "Integer", "",-1 + P: "OriginalUpAxisSign", "int", "Integer", "",1 + P: "UnitScaleFactor", "double", "Number", "",1 + P: "OriginalUnitScaleFactor", "double", "Number", "",1 + P: "AmbientColor", "ColorRGB", "Color", "",0,0,0 + P: "DefaultCamera", "KString", "", "", "Producer Perspective" + P: "TimeMode", "enum", "", "",0 + P: "TimeSpanStart", "KTime", "Time", "",0 + P: "TimeSpanStop", "KTime", "Time", "",46186158000 + P: "CustomFrameRate", "double", "Number", "",-1 + } +} + +; Documents Description +;------------------------------------------------------------------ + +Documents: { + Count: 1 + Document: 140224766734272, "", "Scene" { + Properties70: { + P: "SourceObject", "object", "", "" + P: "ActiveAnimStackName", "KString", "", "", "" + } + RootNode: 0 + } +} + +; Document References +;------------------------------------------------------------------ + +References: { +} + +; Object definitions +;------------------------------------------------------------------ + +Definitions: { + Version: 100 + Count: 17 + ObjectType: "GlobalSettings" { + Count: 1 + } + ObjectType: "Model" { + Count: 4 + PropertyTemplate: "FbxNode" { + Properties70: { + P: "QuaternionInterpolate", "enum", "", "",0 + P: "RotationOffset", "Vector3D", "Vector", "",0,0,0 + P: "RotationPivot", "Vector3D", "Vector", "",0,0,0 + P: "ScalingOffset", "Vector3D", "Vector", "",0,0,0 + P: "ScalingPivot", "Vector3D", "Vector", "",0,0,0 + P: "TranslationActive", "bool", "", "",0 + P: "TranslationMin", "Vector3D", "Vector", "",0,0,0 + P: "TranslationMax", "Vector3D", "Vector", "",0,0,0 + P: "TranslationMinX", "bool", "", "",0 + P: "TranslationMinY", "bool", "", "",0 + P: "TranslationMinZ", "bool", "", "",0 + P: "TranslationMaxX", "bool", "", "",0 + P: "TranslationMaxY", "bool", "", "",0 + P: "TranslationMaxZ", "bool", "", "",0 + P: "RotationOrder", "enum", "", "",0 + P: "RotationSpaceForLimitOnly", "bool", "", "",0 + P: "RotationStiffnessX", "double", "Number", "",0 + P: "RotationStiffnessY", "double", "Number", "",0 + P: "RotationStiffnessZ", "double", "Number", "",0 + P: "AxisLen", "double", "Number", "",10 + P: "PreRotation", "Vector3D", "Vector", "",0,0,0 + P: "PostRotation", "Vector3D", "Vector", "",0,0,0 + P: "RotationActive", "bool", "", "",0 + P: "RotationMin", "Vector3D", "Vector", "",0,0,0 + P: "RotationMax", "Vector3D", "Vector", "",0,0,0 + P: "RotationMinX", "bool", "", "",0 + P: "RotationMinY", "bool", "", "",0 + P: "RotationMinZ", "bool", "", "",0 + P: "RotationMaxX", "bool", "", "",0 + P: "RotationMaxY", "bool", "", "",0 + P: "RotationMaxZ", "bool", "", "",0 + P: "InheritType", "enum", "", "",0 + P: "ScalingActive", "bool", "", "",0 + P: "ScalingMin", "Vector3D", "Vector", "",0,0,0 + P: "ScalingMax", "Vector3D", "Vector", "",1,1,1 + P: "ScalingMinX", "bool", "", "",0 + P: "ScalingMinY", "bool", "", "",0 + P: "ScalingMinZ", "bool", "", "",0 + P: "ScalingMaxX", "bool", "", "",0 + P: "ScalingMaxY", "bool", "", "",0 + P: "ScalingMaxZ", "bool", "", "",0 + P: "GeometricTranslation", "Vector3D", "Vector", "",0,0,0 + P: "GeometricRotation", "Vector3D", "Vector", "",0,0,0 + P: "GeometricScaling", "Vector3D", "Vector", "",1,1,1 + P: "MinDampRangeX", "double", "Number", "",0 + P: "MinDampRangeY", "double", "Number", "",0 + P: "MinDampRangeZ", "double", "Number", "",0 + P: "MaxDampRangeX", "double", "Number", "",0 + P: "MaxDampRangeY", "double", "Number", "",0 + P: "MaxDampRangeZ", "double", "Number", "",0 + P: "MinDampStrengthX", "double", "Number", "",0 + P: "MinDampStrengthY", "double", "Number", "",0 + P: "MinDampStrengthZ", "double", "Number", "",0 + P: "MaxDampStrengthX", "double", "Number", "",0 + P: "MaxDampStrengthY", "double", "Number", "",0 + P: "MaxDampStrengthZ", "double", "Number", "",0 + P: "PreferedAngleX", "double", "Number", "",0 + P: "PreferedAngleY", "double", "Number", "",0 + P: "PreferedAngleZ", "double", "Number", "",0 + P: "LookAtProperty", "object", "", "" + P: "UpVectorProperty", "object", "", "" + P: "Show", "bool", "", "",1 + P: "NegativePercentShapeSupport", "bool", "", "",1 + P: "DefaultAttributeIndex", "int", "Integer", "",-1 + P: "Freeze", "bool", "", "",0 + P: "LODBox", "bool", "", "",0 + P: "Lcl Translation", "Lcl Translation", "", "A",0,0,0 + P: "Lcl Rotation", "Lcl Rotation", "", "A",0,0,0 + P: "Lcl Scaling", "Lcl Scaling", "", "A",1,1,1 + P: "Visibility", "Visibility", "", "A",1 + P: "Visibility Inheritance", "Visibility Inheritance", "", "",1 + } + } + } + ObjectType: "Texture" { + Count: 3 + PropertyTemplate: "FbxFileTexture" { + Properties70: { + P: "TextureTypeUse", "enum", "", "",0 + P: "Texture alpha", "Number", "", "A",1 + P: "CurrentMappingType", "enum", "", "",0 + P: "WrapModeU", "enum", "", "",0 + P: "WrapModeV", "enum", "", "",0 + P: "UVSwap", "bool", "", "",0 + P: "PremultiplyAlpha", "bool", "", "",1 + P: "Translation", "Vector", "", "A",0,0,0 + P: "Rotation", "Vector", "", "A",0,0,0 + P: "Scaling", "Vector", "", "A",1,1,1 + P: "TextureRotationPivot", "Vector3D", "Vector", "",0,0,0 + P: "TextureScalingPivot", "Vector3D", "Vector", "",0,0,0 + P: "CurrentTextureBlendMode", "enum", "", "",1 + P: "UVSet", "KString", "", "", "default" + P: "UseMaterial", "bool", "", "",0 + P: "UseMipMap", "bool", "", "",0 + } + } + } + ObjectType: "Geometry" { + Count: 2 + PropertyTemplate: "FbxMesh" { + Properties70: { + P: "Color", "ColorRGB", "Color", "",0.8,0.8,0.8 + P: "BBoxMin", "Vector3D", "Vector", "",0,0,0 + P: "BBoxMax", "Vector3D", "Vector", "",0,0,0 + P: "Primary Visibility", "bool", "", "",1 + P: "Casts Shadows", "bool", "", "",1 + P: "Receive Shadows", "bool", "", "",1 + } + } + } + ObjectType: "Material" { + Count: 4 + PropertyTemplate: "FbxSurfacePhong" { + Properties70: { + P: "ShadingModel", "KString", "", "", "Phong" + P: "MultiLayer", "bool", "", "",0 + P: "EmissiveColor", "Color", "", "A",0,0,0 + P: "EmissiveFactor", "Number", "", "A",1 + P: "AmbientColor", "Color", "", "A",0.2,0.2,0.2 + P: "AmbientFactor", "Number", "", "A",1 + P: "DiffuseColor", "Color", "", "A",0.8,0.8,0.8 + P: "DiffuseFactor", "Number", "", "A",1 + P: "Bump", "Vector3D", "Vector", "",0,0,0 + P: "NormalMap", "Vector3D", "Vector", "",0,0,0 + P: "BumpFactor", "double", "Number", "",1 + P: "TransparentColor", "Color", "", "A",0,0,0 + P: "TransparencyFactor", "Number", "", "A",0 + P: "DisplacementColor", "ColorRGB", "Color", "",0,0,0 + P: "DisplacementFactor", "double", "Number", "",1 + P: "VectorDisplacementColor", "ColorRGB", "Color", "",0,0,0 + P: "VectorDisplacementFactor", "double", "Number", "",1 + P: "SpecularColor", "Color", "", "A",0.2,0.2,0.2 + P: "SpecularFactor", "Number", "", "A",1 + P: "ShininessExponent", "Number", "", "A",20 + P: "ReflectionColor", "Color", "", "A",0,0,0 + P: "ReflectionFactor", "Number", "", "A",1 + } + } + } + ObjectType: "Video" { + Count: 3 + PropertyTemplate: "FbxVideo" { + Properties70: { + P: "ImageSequence", "bool", "", "",0 + P: "ImageSequenceOffset", "int", "Integer", "",0 + P: "FrameRate", "double", "Number", "",0 + P: "LastFrame", "int", "Integer", "",0 + P: "Width", "int", "Integer", "",0 + P: "Height", "int", "Integer", "",0 + P: "Path", "KString", "XRefUrl", "", "" + P: "StartFrame", "int", "Integer", "",0 + P: "StopFrame", "int", "Integer", "",0 + P: "PlaySpeed", "double", "Number", "",0 + P: "Offset", "KTime", "Time", "",0 + P: "InterlaceMode", "enum", "", "",0 + P: "FreeRunning", "bool", "", "",0 + P: "Loop", "bool", "", "",0 + P: "AccessMode", "enum", "", "",0 + } + } + } +} + +; Object properties +;------------------------------------------------------------------ + +Objects: { + Geometry: 140224778099776, "Geometry::", "Mesh" { + Vertices: *804 { + a: -1.21138301490755,2.05460834381926,-1.31927303133853,-0.556597337054623,2.65077656567349,-1.13936926976448,-1.17764754859987,2.62274600018105,-1.03463471974324,-1.17764754859987,2.62274600018105,-1.03463471974324,-0.556597337054623,2.65077656567349,-1.13936926976448,-1.21138301490755,2.05460834381926,-1.31927303133853,0.752905664585613,-0.538652982048258,-1.87741191518278,1.41569296033341,-0.535646077741744,-1.76148743299612,1.41544114833023,0.133683853628876,-1.76128004680999,1.41544114833023,0.133683853628876,-1.76128004680999,1.41569296033341,-0.535646077741744,-1.76148743299612,0.752905664585613,-0.538652982048258,-1.87741191518278,2.64985563688219,0.11985237792361,-1.31262349436779,3.20201582588208,-0.199859157591088,-1.01000000000003,3.16087442038603,0.112640842408916,-1.01000000000003,3.16087442038603,0.112640842408916,-1.01000000000003,3.20201582588208,-0.199859157591088,-1.01000000000003,2.64985563688219,0.11985237792361,-1.31262349436779,2.63536531794637,0.757554199917523,-1.24662355057375,3.09553403303543,0.608950358354291,-1.01000000000003,3.09553403303543,0.608950358354291,-1.01000000000003,2.63536531794637,0.757554199917523,-1.24662355057375,-2.88819703742748,-1.13735915759105,-1.01000000000005,-2.62931356094429,-1.76235915759105,-1.01000000000005,-2.44892774412591,-1.77746864326616,-1.1086063419687,-2.44892774412591,-1.77746864326616,-1.1086063419687,-2.62931356094429,-1.76235915759105,-1.01000000000005,-2.88819703742748,-1.13735915759105,-1.01000000000005,1.40742755358045,-1.19858356816113,-1.68680880243584,2.05194081166375,-0.530354542158123,-1.57098610463904,2.05194081166375,-0.530354542158123,-1.57098610463904,1.40742755358045,-1.19858356816113,-1.68680880243584,2.30376584522159,-2.38735915759108,-1.01000000000003,2.57701582588207,-2.03125284966597,-1.01000000000003,2.60113373239589,-1.77816640619095,-1.10562091082465,2.60113373239589,-1.77816640619095,-1.10562091082465,2.57701582588207,-2.03125284966597,-1.01000000000003,2.30376584522159,-2.38735915759108,-1.01000000000003,2.64862908880472,-0.52283154074253,-1.31025446097991, +3.04222868919163,-1.13735915759108,-1.01000000000003,3.09553403303542,-1.00866867353647,-1.01000000000003,3.09553403303542,-1.00866867353647,-1.01000000000003,3.04222868919163,-1.13735915759108,-1.01000000000003,2.64862908880472,-0.52283154074253,-1.31025446097991,-0.586692108776326,1.45826482877275,-1.64996916651085,0.0763485126677422,2.08333473700176,-1.46395955379013,-0.573835024673853,2.07652223130158,-1.42761852150866,-0.573835024673853,2.07652223130158,-1.42761852150866,0.0763485126677422,2.08333473700176,-1.46395955379013,-0.586692108776326,1.45826482877275,-1.64996916651085,3.16087442038602,-0.512359157591084,-1.01000000000003,3.16087442038602,-0.512359157591084,-1.01000000000003,1.40655248922223,0.796627009331941,-1.68586569826776,2.03933446182551,0.779943820341973,-1.49933524208154,2.03933446182551,0.779943820341973,-1.49933524208154,1.40655248922223,0.796627009331941,-1.68586569826776,0.726264662991432,2.07510685316068,-1.42604375667924,1.36323402435222,2.05172954699342,-1.31583596075066,1.33288190967791,2.62536968060383,-1.04052044166102,1.33288190967791,2.62536968060383,-1.04052044166102,1.36323402435222,2.05172954699342,-1.31583596075066,0.726264662991432,2.07510685316068,-1.42604375667924,1.97767733473692,-2.41773475504215,-1.14256345528452,2.01494933955749,-1.8154955685749,-1.35524393017951,2.01494933955749,-1.8154955685749,-1.35524393017951,1.97767733473692,-2.41773475504215,-1.14256345528452,-1.26256643868845,0.135559038150545,-1.76257453496259,-1.26248400129467,-0.534021951819889,-1.7625555548127,-0.599675645840945,0.138413866867308,-1.87817307581291,-0.599675645840945,0.138413866867308,-1.87817307581291,-1.26248400129467,-0.534021951819889,-1.7625555548127,-1.26256643868845,0.135559038150545,-1.76257453496259,2.78334521270844,-1.76235915759108,-1.01000000000003,2.63207946071124,-1.15895007304207,-1.24008395674134,2.63207946071124,-1.15895007304207,-1.24008395674134,2.78334521270844,-1.76235915759108,-1.01000000000003,1.95201582588207,-2.66639886067402,-1.01000000000003,2.28672451709003,-2.40956784879904,-1.01000000000003, +2.28672451709003,-2.40956784879904,-1.01000000000003,1.95201582588207,-2.66639886067402,-1.01000000000003,1.97897330030666,2.01918833291342,-1.14753386752116,2.01306308163166,1.4129136513722,-1.35291294586494,2.60545530870548,1.37972124300621,-1.11427716713355,2.60545530870548,1.37972124300621,-1.11427716713355,2.01306308163166,1.4129136513722,-1.35291294586494,1.97897330030666,2.01918833291342,-1.14753386752116,-0.731793690063276,2.81865904956227,-1.01000000000004,-1.1729841741179,2.6359119674769,-1.01000000000004,-1.1729841741179,2.6359119674769,-1.01000000000004,-0.731793690063276,2.81865904956227,-1.01000000000004,-0.572548033331041,-2.47521762921135,-1.42581422170177,0.0773667267984634,-2.48376850201161,-1.46452756029126,0.0771978572303037,-1.86371218077536,-1.6880401318875,0.0771978572303037,-1.86371218077536,-1.6880401318875,0.0773667267984634,-2.48376850201161,-1.46452756029126,-0.572548033331041,-2.47521762921135,-1.42581422170177,0.076568106499949,0.139034263910779,-1.91636415817457,0.752638708931877,0.137478361067562,-1.87697237267879,0.748043706263894,0.80698634940815,-1.80035612017223,0.748043706263894,0.80698634940815,-1.80035612017223,0.752638708931877,0.137478361067562,-1.87697237267879,0.076568106499949,0.139034263910779,-1.91636415817457,-0.585853445388727,-1.85764675377337,-1.6492824686239,0.0769759309928099,-1.21140262303214,-1.84017645416002,0.0769759309928099,-1.21140262303214,-1.84017645416002,-0.585853445388727,-1.85764675377337,-1.6492824686239,0.709493966937774,2.64966677983313,-1.13816742813129,0.0764913760898782,2.65970139223205,-1.17618983954101,0.0764913760898782,2.65970139223205,-1.17618983954101,0.709493966937774,2.64966677983313,-1.13816742813129,2.57701582588209,1.63153453448381,-1.01000000000003,2.78334521270846,1.36264084240892,-1.01000000000003,2.78334521270846,1.36264084240892,-1.01000000000003,2.57701582588209,1.63153453448381,-1.01000000000003,0.0764525746984961,0.810882339847106,-1.83907721933332,0.0764525746984961,0.810882339847106,-1.83907721933332,0.0767185439770084,-0.539418642227496,-1.91685435264556, +0.0767185439770084,-0.539418642227496,-1.91685435264556,-1.88623706377314,0.782377103667404,-1.49929746967609,-1.23695886980414,1.44243058248863,-1.53858625954814,-1.8611276258145,1.41566595512155,-1.35526611343448,-1.8611276258145,1.41566595512155,-1.35526611343448,-1.23695886980414,1.44243058248863,-1.53858625954814,-1.88623706377314,0.782377103667404,-1.49929746967609,0.748809830417043,-1.20838485245112,-1.80168816278409,0.748809830417043,-1.20838485245112,-1.80168816278409,0.702015825882102,2.8428580314168,-1.01000000000003,0.885825341827481,2.81865904956226,-1.01000000000003,0.885825341827481,2.81865904956226,-1.01000000000003,0.702015825882102,2.8428580314168,-1.01000000000003,0.710604786886374,-3.05066256562905,-1.13941736162011,1.33174029598255,-3.0225579848268,-1.03468121299745,1.36544569150805,-2.45476049827522,-1.31976037322883,1.36544569150805,-2.45476049827522,-1.31976037322883,1.33174029598255,-3.0225579848268,-1.03468121299745,0.710604786886374,-3.05066256562905,-1.13941736162011,-1.22916563986865,2.61264084240894,-1.01000000000004,-1.22916563986865,2.61264084240894,-1.01000000000004,-1.8989221787548,0.130425041291131,-1.57227940676398,-1.25396440727233,0.798602597189103,-1.68717502714834,-1.25396440727233,0.798602597189103,-1.68717502714834,-1.8989221787548,0.130425041291131,-1.57227940676398,-1.17680038682326,-3.02227251855283,-1.03490215555892,-1.48548417411793,-2.90618854441743,-1.01000000000005,-1.2291656398687,-3.01235915759106,-1.01000000000005,-1.2291656398687,-3.01235915759106,-1.01000000000005,-1.48548417411793,-2.90618854441743,-1.01000000000005,-1.17680038682326,-3.02227251855283,-1.03490215555892,0.727736724404746,-2.47693027551931,-1.42828678031294,1.39070475134362,-1.84256903839729,-1.53883634902052,1.39070475134362,-1.84256903839729,-1.53883634902052,0.727736724404746,-2.47693027551931,-1.42828678031294,-1.25344547884549,-1.19713150310828,-1.6865243129658,-1.23563151227431,-1.84057176866669,-1.5360918159891,-0.59491104348907,-1.20763335936161,-1.80153305815408,-0.59491104348907,-1.20763335936161,-1.80153305815408, +-1.23563151227431,-1.84057176866669,-1.5360918159891,-1.25344547884549,-1.19713150310828,-1.6865243129658,0.739205868831052,1.45703438246769,-1.64866604538677,1.38892193606497,1.44012114512586,-1.5361586997455,1.38892193606497,1.44012114512586,-1.5361586997455,0.739205868831052,1.45703438246769,-1.64866604538677,-1.89891749754297,-0.52794054995276,-1.57244449903035,-1.89891749754297,-0.52794054995276,-1.57244449903035,2.05201972514247,0.127771654179273,-1.57173410971695,2.05201972514247,0.127771654179273,-1.57173410971695,0.885825341827444,-3.21837736474441,-1.01000000000004,1.32701582588207,-3.03563028265904,-1.01000000000004,1.32701582588207,-3.03563028265904,-1.01000000000004,0.885825341827444,-3.21837736474441,-1.01000000000004,-1.88614276771893,-1.18018295754275,-1.49969555507589,-1.88614276771893,-1.18018295754275,-1.49969555507589,-2.44729987169906,1.37848612095251,-1.10585969419731,-2.14973419345742,1.98764084240894,-1.01000000000005,-2.4229841741179,1.63153453448384,-1.01000000000005,-2.4229841741179,1.63153453448384,-1.01000000000005,-2.14973419345742,1.98764084240894,-1.01000000000005,-2.44729987169906,1.37848612095251,-1.10585969419731,-0.595406643346858,0.808067557908589,-1.80156330192063,-0.595406643346858,0.808067557908589,-1.80156330192063,1.9520158258821,2.26668054549187,-1.01000000000003,2.28672451709006,2.00984953361688,-1.01000000000003,2.28672451709006,2.00984953361688,-1.01000000000003,1.9520158258821,2.26668054549187,-1.01000000000003,1.6395158258821,2.50647022923529,-1.01000000000003,1.38319729163285,2.61264084240893,-1.01000000000003,1.38319729163285,2.61264084240893,-1.01000000000003,1.6395158258821,2.50647022923529,-1.01000000000003,2.03952556967074,-1.18214117306896,-1.49836542916152,2.03952556967074,-1.18214117306896,-1.49836542916152,1.63951582588207,-2.90618854441745,-1.01000000000004,1.63951582588207,-2.90618854441745,-1.01000000000004,-1.82365810983751,2.01790388458739,-1.14247500809546,-2.13269286532586,2.0098495336169,-1.01000000000005,-2.13269286532586,2.0098495336169,-1.01000000000005, +-1.82365810983751,2.01790388458739,-1.14247500809546,-2.47852540875869,0.759304938903629,-1.24073711475837,-2.47852540875869,0.759304938903629,-1.24073711475837,-2.49512021891333,0.123006751699238,-1.31060581576554,-2.49512021891333,0.123006751699238,-1.31060581576554,-2.49628732629019,-0.519701075977892,-1.31284259980568,-2.49628732629019,-0.519701075977892,-1.31284259980568,-2.48113807294219,-1.15713437596644,-1.24545450725808,-2.48113807294219,-1.15713437596644,-1.24545450725808,3.04222868919165,0.737640842408917,-1.01000000000003,3.04222868919165,0.737640842408917,-1.01000000000003,-1.85972406157781,-1.81311999008029,-1.35277725488455,-1.85972406157781,-1.81311999008029,-1.35277725488455,-2.14973419345745,-2.38735915759105,-1.01000000000005,-1.82035568481556,-2.41381321868136,-1.13562757384634,-1.82035568481556,-2.41381321868136,-1.13562757384634,-2.14973419345745,-2.38735915759105,-1.01000000000005,-2.13269286532588,-2.40956784879902,-1.01000000000005,-1.79798417411793,-2.66639886067401,-1.01000000000005,-1.79798417411793,-2.66639886067401,-1.01000000000005,-2.13269286532588,-2.40956784879902,-1.01000000000005,1.3270158258821,2.63591196747688,-1.01000000000003,1.3270158258821,2.63591196747688,-1.01000000000003,0.0774464439653702,-3.05965752776325,-1.17615487368086,0.0774464439653702,-3.05965752776325,-1.17615487368086,0.0770158258820699,-3.32485915759106,-1.01000000000004,0.0770158258820699,-3.32485915759106,-1.01000000000004,0.0770158258821037,2.92514084240893,-1.01000000000004,0.0770158258821037,2.92514084240893,-1.01000000000004,-2.94150238127125,0.608950358354324,-1.01000000000005,-2.88819703742746,0.737640842408949,-1.01000000000005,-2.88819703742746,0.737640842408949,-1.01000000000005,-2.94150238127125,0.608950358354324,-1.01000000000005,-2.42298417411792,-2.03125284966595,-1.01000000000005,-2.42298417411792,-2.03125284966595,-1.01000000000005,-2.62931356094428,1.36264084240894,-1.01000000000005,-2.62931356094428,1.36264084240894,-1.01000000000005,-3.04798417411791,-0.19985915759105,-1.01000000000005,-3.00684276862185,0.11264084240895,-1.01000000000005, +-3.00684276862185,0.11264084240895,-1.01000000000005,-3.04798417411791,-0.19985915759105,-1.01000000000005,-3.00684276862185,-0.51235915759105,-1.01000000000005,-2.94150238127126,-1.00866867353643,-1.01000000000005,-2.94150238127126,-1.00866867353643,-1.01000000000005,-3.00684276862185,-0.51235915759105,-1.01000000000005,0.702015825882069,-3.24257634659895,-1.01000000000004,0.702015825882069,-3.24257634659895,-1.01000000000004,0.740444850501487,-1.85865475095619,-1.65069763494541,0.740444850501487,-1.85865475095619,-1.65069763494541,-0.599496553342869,-0.537877400631098,-1.87832967644323,-0.599496553342869,-0.537877400631098,-1.87832967644323,-0.54798417411793,-3.24257634659894,-1.01000000000005,-0.54798417411793,-3.24257634659894,-1.01000000000005,-1.20901389434619,-2.45130054127972,-1.31458120996883,-1.20901389434619,-2.45130054127972,-1.31458120996883,-0.555213536192478,-3.04892239196673,-1.13729641509457,-0.555213536192478,-3.04892239196673,-1.13729641509457,1.38319729163283,-3.01235915759107,-1.01000000000004,1.38319729163283,-3.01235915759107,-1.01000000000004,2.30376584522161,1.98764084240892,-1.01000000000003,2.30376584522161,1.98764084240892,-1.01000000000003,-1.17298417411793,-3.03563028265903,-1.01000000000005,-1.17298417411793,-3.03563028265903,-1.01000000000005,-1.4854841741179,2.50647022923531,-1.01000000000004,-1.7979841741179,2.26668054549189,-1.01000000000005,-1.7979841741179,2.26668054549189,-1.01000000000005,-1.4854841741179,2.50647022923531,-1.01000000000004,-0.547984174117897,2.84285803141681,-1.01000000000004,-0.547984174117897,2.84285803141681,-1.01000000000004,0.0763063776653105,1.46309321197533,-1.68722634442758,0.0763063776653105,1.46309321197533,-1.68722634442758,-0.731793690063314,-3.2183773647444,-1.01000000000005,-0.731793690063314,-3.2183773647444,-1.01000000000005 + } + PolygonVertexIndex: *1260 { + a: 0,1,-3,3,4,-6,6,7,-9,9,10,-12,12,13,-15,15,16,-18,18,14,-20,20,15,-22,22,23,-25,25,26,-28,28,29,-8,10,30,-32,32,33,-35,35,36,-38,38,39,-41,41,42,-44,44,45,-47,47,48,-50,38,40,-51,51,41,-44,52,8,-54,54,9,-56,56,57,-59,59,60,-62,62,34,-64,64,35,-66,12,50,-14,16,51,-18,66,67,-69,69,70,-72,29,38,-13,17,43,-31,34,72,-74,74,75,-36,76,77,-63,65,78,-80,80,81,-83,83,84,-86,2,86,-88,88,89,-4,90,91,-93,93,94,-96,96,97,-99,99,100,-102,102,92,-104,104,93,-106,33,72,-35,35,75,-37,45,106,-108,108,109,-49,110,82,-112,112,83,-114,68,96,-115,115,101,-70,116,6,-98,100,11,-118,118,119,-121,121,122,-124,81,53,-83,83,54,-85,103,124,-7,11,125,-105,0,46,-2,4,47,-6,126,106,-128,128,109,-130,130,131,-133,133,134,-136,2,87,-137,137,88,-4,138,66,-140,140,71,-142,97,8,-53,55,9,-101,124,28,-8,10,31,-126,142,143,-145,145,146,-148,58,57,-81,85,60,-60,148,132,-150,150,133,-152,152,153,-155,155,156,-158,158,159,-58,60,160,-162,162,67,-67,71,70,-164,57,159,-81,85,160,-61,8,7,-165,165,10,-10,131,166,-168,168,169,-135,170,152,-68,70,157,-172,118,139,-120,122,140,-124,98,52,-160,160,55,-100,172,173,-175,175,176,-178,66,178,-140,140,179,-72,180,80,-182,182,85,-184,159,81,-81,85,84,-161,58,184,-186,186,187,-60,52,53,-82,84,54,-56,8,164,-54,54,165,-10,7,29,-165,165,30,-11,28,188,-30,30,189,-32,149,63,-189,189,64,-151,132,62,-64,64,65,-134,190,76,-63,65,79,-192,173,192,-194,194,195,-177,196,118,-121,121,123,-198,198,138,-119,123,141,-200,200,162,-139,141,163,-202,202,170,-163,163,171,-204,82,204,-112,112,205,-84,24,206,-171,171,207,-26,208,209,-207,207,210,-212,212,213,-210,210,214,-216,29,12,-165,165,17,-31,149,188,-29,31,189,-151,132,63,-150,150,64,-134,131,62,-133,133,65,-135,106,216,-128,128,217,-110,106,56,-59,59,61,-110,91,218,-149,151,219,-95,220,130,-219,219,135,-222,200,138,-199,199,141,-202,200,202,-163,163,203,-202,1,107,-223,223,108,-5,202,24,-171,171,25,-204,224,198,-226,226,199,-228,228,208,-207,207,211,-230,208,212,-210,210,215,-212,230,196,-173,177,197,-232,232,200,-234,234,201,-236,236,237,-203,203,238,-240,22,24,-203,203, +25,-28,24,228,-207,207,229,-26,225,198,-197,197,199,-227,220,240,-131,135,241,-222,237,22,-203,203,27,-239,218,130,-149,151,135,-220,18,19,-205,205,20,-22,91,148,-243,243,151,-95,114,98,-159,161,99,-116,67,244,-69,69,245,-71,56,158,-58,60,161,-62,23,228,-25,25,229,-27,246,220,-219,219,221,-248,248,90,-103,105,95,-250,250,218,-92,94,219,-252,225,196,-231,231,197,-227,154,103,-117,117,104,-156,45,56,-107,109,61,-49,230,172,-175,175,177,-232,82,18,-205,205,21,-84,68,244,-97,101,245,-70,46,107,-2,4,108,-48,164,12,-19,21,17,-166,131,167,-253,253,168,-135,188,73,-39,43,74,-190,63,34,-74,74,35,-65,244,154,-117,117,155,-246,102,90,-93,93,95,-106,53,18,-83,83,21,-55,62,77,-33,37,78,-66,80,110,-255,255,113,-86,154,102,-104,104,105,-156,209,213,-249,249,214,-211,172,192,-174,176,195,-178,142,144,-257,257,145,-148,192,258,-260,260,261,-196,2,262,-87,89,263,-4,193,192,-260,260,195,-195,242,149,-29,31,150,-244,138,162,-67,71,163,-142,120,119,-1,5,122,-122,153,102,-155,155,105,-157,98,97,-53,55,100,-100,120,0,-193,195,5,-122,152,154,-245,245,155,-158,92,242,-125,125,243,-94,107,126,-223,223,129,-109,244,116,-97,101,117,-246,80,254,-182,182,255,-86,142,250,-91,95,251,-148,139,178,-45,49,179,-141,264,158,-57,61,161,-266,46,45,-108,108,48,-48,178,114,-265,265,115,-180,233,198,-225,227,199,-235,58,185,-217,217,186,-60,192,0,-3,3,5,-196,206,209,-154,156,210,-208,159,52,-82,84,55,-161,170,206,-153,157,207,-172,209,248,-154,156,249,-211,63,73,-189,189,74,-65,213,143,-249,249,146,-215,172,120,-193,195,121,-178,67,152,-245,245,157,-71,206,153,-153,157,156,-208,44,264,-46,48,265,-50,1,222,-263,263,223,-5,232,236,-201,201,239,-236,119,44,-47,47,49,-123,73,72,-40,42,75,-75,266,246,-251,251,247,-268,158,98,-160,160,99,-162,96,116,-98,100,117,-102,103,92,-125,125,93,-105,107,106,-127,129,109,-109,119,46,-1,5,47,-123,188,38,-30,30,43,-190,196,120,-173,177,121,-198,139,44,-120,122,49,-141,153,248,-103,105,249,-157,248,142,-91,95,147,-250,256,266,-251,251,267,-258,250,142,-257,257,147,-252,192,2,-137,137,3,-196,162,170,-68,70,171,-164,131,252,-63, +65,253,-135,58,180,-185,187,183,-60,198,118,-197,197,123,-200,106,58,-217,217,59,-110,240,131,-131,135,134,-242,2,1,-263,263,4,-4,264,114,-159,161,115,-266,114,96,-99,99,101,-116,124,7,-7,11,10,-126,242,28,-125,125,31,-244,148,149,-243,243,150,-152,130,132,-149,151,133,-136,264,56,-46,48,61,-266,240,166,-132,134,169,-242,92,91,-243,243,94,-94,178,264,-45,49,265,-180,68,114,-179,179,115,-70,90,250,-92,94,251,-96,97,6,-9,9,11,-101,116,103,-7,11,104,-118,66,68,-179,179,69,-72,53,164,-19,21,165,-55,250,246,-219,219,247,-252,138,139,-119,123,140,-142,80,82,-111,113,83,-86,233,200,-199,199,201,-235,73,39,-39,43,42,-75,38,50,-13,17,51,-44,252,190,-63,65,191,-254,192,136,-259,261,137,-196,143,142,-249,249,147,-147,18,12,-15,15,17,-22,58,80,-181,183,85,-60,236,202,-201,201,203,-240,62,32,-35,35,37,-66 + } + GeometryVersion: 124 + LayerElementNormal: 0 { + Version: 101 + Name: "" + MappingInformationType: "ByVertice" + ReferenceInformationType: "Direct" + Normals: *804 { + a: 0.223014930139163,-0.392610286047031,0.892256411702988,0.114364631756048,-0.499962016804746,0.858462994400944,0.269177042159695,-0.595358128315163,0.757028677807666,-0.269177042159695,0.595358128315163,-0.757028677807666,-0.114364631756048,0.499962016804746,-0.858462994400944,-0.223014930139163,0.392610286047031,-0.892256411702988,-0.115290703458566,0.056122037182135,0.991745113745743,-0.229831163721192,0.0560562825401513,0.971614805038674,-0.22896798637776,-0.0565984700141607,0.971787154888441,0.22896798637776,0.0565984700141607,-0.971787154888441,0.229831163721192,-0.0560562825401513,-0.971614805038674,0.115290703458566,-0.056122037182135,-0.991745113745743,-0.454441876222059,-0.0288816955389521,0.890308052753973,-0.482264881276064,-0.00370319665492289,0.876017620041012,-0.496623882486511,-0.0764526131653905,0.864592226014211,0.496623882486511,0.0764526131653905,-0.864592226014211,0.482264881276064,0.00370319665492289,-0.876017620041012,0.454441876222059,0.0288816955389521,-0.890308052753973,-0.452391689934089,-0.142528908277277,0.880356330802401,-0.487223407365834,-0.134906066462025,0.862794126397816,0.487223407365834,0.134906066462025,-0.862794126397816,0.452391689934089,0.142528908277277,-0.880356330802401,0.492456545079431,0.20584012713458,0.845645548246812,0.47830727578045,0.281471616314215,0.831862896843553,0.435297765725912,0.264948255614615,0.86041750156584,-0.435297765725912,-0.264948255614615,-0.86041750156584,-0.47830727578045,-0.281471616314215,-0.831862896843553,-0.492456545079431,-0.20584012713458,-0.845645548246812,-0.229091366476287,0.168253271983725,0.958753347985183,-0.343887651485285,0.0564596255702139,0.937311897842125,0.343887651485285,-0.0564596255702139,-0.937311897842125,0.229091366476287,-0.168253271983725,-0.958753347985183,-0.408560452017172,0.323263637929751,0.85356837888944,-0.458705440249572,0.351977063836267,0.815905304320695,-0.426254199181931,0.29723310980084,0.854376870074262,0.426254199181931,-0.29723310980084,-0.854376870074262,0.458705440249572,-0.351977063836267,-0.815905304320695, +0.408560452017172,-0.323263637929751,-0.85356837888944,-0.446583679893299,0.0822952030277505,0.890949222128613,-0.464742814742643,0.160747516114453,0.87073207831578,-0.461027029126821,0.119351624347101,0.879323187559731,0.461027029126821,-0.119351624347101,-0.879323187559731,0.464742814742643,-0.160747516114453,-0.87073207831578,0.446583679893299,-0.0822952030277505,-0.890949222128613,0.112733033730892,-0.283102401875829,0.952441228190992,-0.00193865048889188,-0.393943190275402,0.919132745837031,0.111951327051046,-0.393960503924669,0.912283958928869,-0.111951327051046,0.393960503924669,-0.912283958928869,0.00193865048889188,0.393943190275402,-0.919132745837031,-0.112733033730892,0.283102401875829,-0.952441228190992,-0.488487574693622,0.043481783068095,0.871486789292392,0.488487574693622,-0.043481783068095,-0.871486789292392,-0.227714658053918,-0.17034634528472,0.958711717439359,-0.335013354557396,-0.166013290421761,0.927472716402774,0.335013354557396,0.166013290421761,-0.927472716402774,0.227714658053918,0.17034634528472,-0.958711717439359,-0.11227114493294,-0.391713848137053,0.913211613588608,-0.207398190405805,-0.376215495959512,0.903021534193031,-0.263359817350341,-0.654554115267095,0.708661073286875,0.263359817350341,0.654554115267095,-0.708661073286875,0.207398190405805,0.376215495959512,-0.903021534193031,0.11227114493294,0.391713848137053,-0.913211613588608,-0.33808477530749,0.404415361297956,0.849792268881947,-0.338322980362409,0.275856899224299,0.899689130816335,0.338322980362409,-0.275856899224299,-0.899689130816335,0.33808477530749,-0.404415361297956,-0.849792268881947,0.229564987774916,-0.0566277547461423,0.971644592317743,0.229285496856615,0.0567314077000188,0.971704537558403,0.114268884796593,-0.0570783239158896,0.991808795537878,-0.114268884796593,0.0570783239158896,-0.991808795537878,-0.229285496856615,-0.0567314077000188,-0.971704537558403,-0.229564987774916,0.0566277547461423,-0.971644592317743,-0.472737658482027,0.255191222401468,0.843443267957113,-0.440794248573241,0.177274480412825,0.87992851358455, +0.440794248573241,-0.177274480412825,-0.87992851358455,0.472737658482027,-0.255191222401468,-0.843443267957113,-0.358851536530869,0.467664427490084,0.8077843511667,-0.37273594110862,0.382591442113011,0.845394408916784,0.37273594110862,-0.382591442113011,-0.845394408916784,0.358851536530869,-0.467664427490084,-0.8077843511667,-0.345573535314833,-0.375991861210056,0.85977267460289,-0.318443065441654,-0.263509891983342,0.910580337421718,-0.441486280306271,-0.277147232671203,0.853392802713983,0.441486280306271,0.277147232671203,-0.853392802713983,0.318443065441654,0.263509891983342,-0.910580337421718,0.345573535314833,0.375991861210056,-0.85977267460289,0.214153049030322,-0.585663924858146,0.781752031472109,0.352660491072067,-0.851397740459344,0.388268548272368,-0.352660491072067,0.851397740459344,-0.388268548272368,-0.214153049030322,0.585663924858146,-0.781752031472109,0.114755140175009,0.393956737469013,0.911937139723011,0.00267077465748396,0.394687792649041,0.918811413346916,0.0014374758752762,0.283944656938319,0.958839593185058,-0.0014374758752762,-0.283944656938319,-0.958839593185058,-0.00267077465748396,-0.394687792649041,-0.918811413346916,-0.114755140175009,-0.393956737469013,-0.911937139723011,-0.000782240956003238,-0.0574788761009215,0.998346416281073,-0.115339818058379,-0.057319416356404,0.99167091864127,-0.114942820049004,-0.170995260954988,0.978544208940055,0.114942820049004,0.170995260954988,-0.978544208940055,0.115339818058379,0.057319416356404,-0.99167091864127,0.000782240956003238,0.0574788761009215,-0.998346416281073,0.115608546954279,0.284949563078078,0.9515452749989,0.000288116055240238,0.170707693110644,0.985321673618307,-0.000288116055240238,-0.170707693110644,-0.985321673618307,-0.115608546954279,-0.284949563078078,-0.9515452749989,-0.100861785269214,-0.570529903824182,0.815059831616475,-0.00327641624874573,-0.493876031762998,0.869526152767471,0.00327641624874573,0.493876031762998,-0.869526152767471,0.100861785269214,0.570529903824182,-0.815059831616475,-0.443613198381695,-0.357277800956926,0.821924511840927, +-0.504000545196995,-0.296453582007837,0.811232842133413,0.504000545196995,0.296453582007837,-0.811232842133413,0.443613198381695,0.357277800956926,-0.821924511840927,-0.00110422335172568,-0.170961439746929,0.985277101535627,0.00110422335172568,0.170961439746929,-0.985277101535627,-0.000511301979153173,0.0565808711378245,0.99839788841502,0.000511301979153173,-0.0565808711378245,-0.99839788841502,0.343092740150507,-0.166671731140446,0.924395968021639,0.225896731673585,-0.281204625065644,0.932681416916239,0.337977691445992,-0.276662782706619,0.899571445050291,-0.337977691445992,0.276662782706619,-0.899571445050291,-0.225896731673585,0.281204625065644,-0.932681416916239,-0.343092740150507,0.166671731140446,-0.924395968021639,-0.114592300261075,0.169699198215527,0.978810904539729,0.114592300261075,-0.169699198215527,-0.978810904539729,-0.0670751729235599,-0.545406884407469,0.835483244367122,-0.131971003705838,-0.507901305683755,0.851246097122102,0.131971003705838,0.507901305683755,-0.851246097122102,0.0670751729235599,0.545406884407469,-0.835483244367122,-0.114404461731677,0.500632948517176,0.858066588322191,-0.26987341671205,0.596727369911315,0.755701518425687,-0.223461424990152,0.392850359237237,0.892039005194585,0.223461424990152,-0.392850359237237,-0.892039005194585,0.26987341671205,-0.596727369911315,-0.755701518425687,0.114404461731677,-0.500632948517176,-0.858066588322191,0.330423656756992,-0.63177726161594,0.701197332254196,-0.330423656756992,0.63177726161594,-0.701197332254196,0.34429397899829,-0.0565311976691859,0.937158406949227,0.228325383607032,-0.169246690424557,0.958761220002684,-0.228325383607032,0.169246690424557,-0.958761220002684,-0.34429397899829,0.0565311976691859,-0.937158406949227,0.243708302371662,0.687329847250849,0.684239683468628,0.311033972320301,0.587892606792245,0.746753072267984,0.350671258924239,0.846595309229325,0.400382380425754,-0.350671258924239,-0.846595309229325,-0.400382380425754,-0.311033972320301,-0.587892606792245,-0.746753072267984,-0.243708302371662,-0.687329847250849,-0.684239683468628, +-0.112137738249323,0.39445257283486,0.912048406305436,-0.226550326144808,0.280464334706112,0.932745788884377,0.226550326144808,-0.280464334706112,-0.932745788884377,0.112137738249323,-0.39445257283486,-0.912048406305436,0.22817171310267,0.17117109331306,0.958456115924879,0.227393382456032,0.285065252668822,0.931144484672527,0.115099108403794,0.171384993747335,0.978457653229243,-0.115099108403794,-0.171384993747335,-0.978457653229243,-0.227393382456032,-0.285065252668822,-0.931144484672527,-0.22817171310267,-0.17117109331306,-0.958456115924879,-0.114916755718807,-0.283753518402522,0.951986386483154,-0.223880898801354,-0.280459582104302,0.93339153947193,0.223880898801354,0.280459582104302,-0.93339153947193,0.114916755718807,0.283753518402522,-0.951986386483154,0.342514998886902,0.0546208719620034,0.937923256926501,-0.342514998886902,-0.0546208719620034,-0.937923256926501,-0.341531257577343,-0.0538207933439407,0.938328152781034,0.341531257577343,0.0538207933439407,-0.938328152781034,-0.214798607492336,0.587472954864481,0.780216050541226,-0.35332033589688,0.852990746784458,0.384150395212354,0.35332033589688,-0.852990746784458,-0.384150395212354,0.214798607492336,-0.587472954864481,-0.780216050541226,0.33783127259415,0.167869403105736,0.926115486728486,-0.33783127259415,-0.167869403105736,-0.926115486728486,0.426710285728511,-0.29788924754151,0.85392056319815,0.408782291438607,-0.323623803417521,0.853325654171828,0.459874795260314,-0.352874341494548,0.814858804823924,-0.459874795260314,0.352874341494548,-0.814858804823924,-0.408782291438607,0.323623803417521,-0.853325654171828,-0.426710285728511,0.29788924754151,-0.85392056319815,0.113714512253693,-0.170588441077834,0.978758700330955,-0.113714512253693,0.170588441077834,-0.978758700330955,-0.297605683746427,-0.410436383348152,0.861958718400081,-0.384823730720007,-0.394807793290081,0.834288620701585,0.384823730720007,0.394807793290081,-0.834288620701585,0.297605683746427,0.410436383348152,-0.861958718400081,-0.322637079764833,-0.657212546340122,0.681158559877179,-0.371641482630758,-0.897221907707615,0.238485757892416, +0.371641482630758,0.897221907707615,-0.238485757892416,0.322637079764833,0.657212546340122,-0.681158559877179,-0.343066370335117,0.165840153199562,0.924555303446924,0.343066370335117,-0.165840153199562,-0.924555303446924,-0.254611497391006,0.413515408129843,0.8741727475937,0.254611497391006,-0.413515408129843,-0.8741727475937,0.337555320622941,-0.404133473664471,0.850136777808743,0.372467014202779,-0.382313890686306,0.845638464309167,-0.372467014202779,0.382313890686306,-0.845638464309167,-0.337555320622941,0.404133473664471,-0.850136777808743,0.441617587529043,-0.177732591758269,0.879423124674304,-0.441617587529043,0.177732591758269,-0.879423124674304,0.447617030653949,-0.0822407474967166,0.890435541361486,-0.447617030653949,0.0822407474967166,-0.890435541361486,0.455284442048248,0.0297566631479696,0.889848648831425,-0.455284442048248,-0.0297566631479696,-0.889848648831425,0.452368082407924,0.145472033480631,0.879886927675135,-0.452368082407924,-0.145472033480631,-0.879886927675135,-0.502811759141378,-0.206995927308256,0.839245506956664,0.502811759141378,0.206995927308256,-0.839245506956664,0.339158073227499,0.292020616208459,0.89425710009697,-0.339158073227499,-0.292020616208459,-0.89425710009697,0.375067216919333,0.308671198720236,0.874097634062121,0.31741048109939,0.365455975930325,0.87503857980381,-0.31741048109939,-0.365455975930325,-0.87503857980381,-0.375067216919333,-0.308671198720236,-0.874097634062121,0.352138859758953,0.361604267189767,0.863273176577273,0.306834091214846,0.428987917836019,0.849601204577228,-0.306834091214846,-0.428987917836019,-0.849601204577228,-0.352138859758953,-0.361604267189767,-0.863273176577273,-0.232862640152882,-0.82837564497835,0.509478931485623,0.232862640152882,0.82837564497835,-0.509478931485623,0.00391968972384626,0.493865922389146,0.869529232823823,-0.00391968972384626,-0.493865922389146,-0.869529232823823,-0.0202470805084047,0.541034769267722,0.840756465437114,0.0202470805084047,-0.541034769267722,-0.840756465437114,0.0202598210669755,-0.540700097205306,0.84097142908217, +-0.0202598210669755,0.540700097205306,-0.84097142908217,0.461754324360469,-0.119537407078924,0.878916237330529,0.465952502969543,-0.160888695868571,0.870059246556307,-0.465952502969543,0.160888695868571,-0.870059246556307,-0.461754324360469,0.119537407078924,-0.878916237330529,0.41694641599993,0.347042211160102,0.840069872009419,-0.41694641599993,-0.347042211160102,-0.840069872009419,0.474044333696619,-0.255918979902004,0.842488839935608,-0.474044333696619,0.255918979902004,-0.842488839935608,0.482846472556428,0.00370955468739143,0.875697164060633,0.489212585254858,-0.0434660522815419,0.871080793455645,-0.489212585254858,0.0434660522815419,-0.871080793455645,-0.482846472556428,-0.00370955468739143,-0.875697164060633,0.496373362961526,0.0771903573638905,0.864670534523006,0.485227700384503,0.134361997313515,0.864002854426702,-0.485227700384503,-0.134361997313515,-0.864002854426702,-0.496373362961526,-0.0771903573638905,-0.864670534523006,-0.0883845529361563,0.440461285346631,0.893410335127745,0.0883845529361563,-0.440461285346631,-0.893410335127745,-0.113180840467309,0.282711681845509,0.952504174426127,0.113180840467309,-0.282711681845509,-0.952504174426127,0.114761847403461,0.0570093747699076,0.991755841711502,-0.114761847403461,-0.0570093747699076,-0.991755841711502,0.0675347842099571,0.543092836886414,0.836952342397332,-0.0675347842099571,-0.543092836886414,-0.836952342397332,0.231139870640622,0.392808387981627,0.890098831889758,-0.231139870640622,-0.392808387981627,-0.890098831889758,0.10529549930811,0.552964830410468,0.82652450305758,-0.10529549930811,-0.552964830410468,-0.82652450305758,-0.331415590755439,0.633249377166632,0.699398979497608,0.331415590755439,-0.633249377166632,-0.699398979497608,-0.396358776947517,-0.304136786474157,0.86625662193708,0.396358776947517,0.304136786474157,-0.86625662193708,0.228166984868315,0.764068033337397,0.60344002804589,-0.228166984868315,-0.764068033337397,-0.60344002804589,0.25441448893117,-0.413189350312049,0.874384256840549,0.358589919738106,-0.4673234818478,0.808097786642104, +-0.358589919738106,0.4673234818478,-0.808097786642104,-0.25441448893117,0.413189350312049,-0.874384256840549,0.0883378704230143,-0.439988117451044,0.893648072314271,-0.0883378704230143,0.439988117451044,-0.893648072314271,-0.00144262837245471,-0.283587823262075,0.958945183689275,0.00144262837245471,0.283587823262075,-0.958945183689275,0.131072899910778,0.504501867643532,0.853403632786483,-0.131072899910778,-0.504501867643532,-0.853403632786483 + } + } + LayerElementUV: 0 { + Version: 101 + Name: "" + MappingInformationType: "ByPolygonVertex" + ReferenceInformationType: "IndexToDirect" + UV: *268 { + a: -0.304786696055178,-0.15059393933858,-0.40583725448217,-0.0585895483731594,-0.309992937785652,-0.062915423569064,-0.607928027540249,-0.550802016524532,-0.710213487957416,-0.550337959642432,-0.710174598043744,-0.447042816310621,-0.900677140781882,-0.449177346192873,-0.985889964874839,-0.498517202572939,-0.979540752572047,-0.450290263055329,-0.89844087691957,-0.35076324390924,-0.96945699426729,-0.373696698581212,-0.0460105264588016,-0.6431981172673,-0.0859630494329846,-0.739651970148495,-0.113801303365397,-0.741983757220909,-0.708937947351849,-0.652646581997156,-0.808403221509935,-0.549521324778632,-0.847266511321232,-0.836105792304654,-0.889436138623037,-0.781149255153924,-0.893158153683815,-0.742091384421526,-0.900487879797124,-0.54836031698078,-0.961230655365611,-0.643198026482768,-0.969457063669805,-0.623337711146723,-0.401192893829331,-0.24262533588677,-0.503517410594599,-0.146160657630067,-0.403177052258969,-0.147212029460383,-0.97954077938712,-0.546744143860917,-0.708802816367376,-0.344733320028389,-0.806457674765619,-0.347307955430374,-0.603816510346117,-0.147430411812581,-0.702117587240977,-0.15103811927898,-0.697433435280919,-0.0625104200115185,-0.796942499609629,-0.840793545169165,-0.802694521979258,-0.747852258751269,-0.296887835449506,-0.446753489779995,-0.296900586426397,-0.550087366161385,-0.399189250497804,-0.446312899222316,-0.921278166578078,-0.739651909689102,-0.897933865138975,-0.646530076822477,-0.792982266220115,-0.879168932162503,-0.844636588181445,-0.839533175423335,-0.797142310735299,-0.156060058811294,-0.802403284381166,-0.249624126359424,-0.893824950837161,-0.254746565726054,-0.378799859703272,-0.032680892431883,-0.31071261805528,-0.0608835699349864,-0.403375864033046,-0.849664675237358,-0.503674743670316,-0.850984294656204,-0.503648656066836,-0.755293365715378,-0.503551383097035,-0.44621713964654,-0.607886800274642,-0.446457240146408,-0.607177642160145,-0.343134621022264,-0.401322463830643,-0.754357318470235,-0.503614379044841,-0.65462491770788,-0.601228327583781,-0.058760766259116, +-0.503539433436657,-0.0572121883333963,-0.889435981474388,-0.215885176886559,-0.921278032502718,-0.257382513472746,-0.503533524686888,-0.342533386592888,-0.503574628651196,-0.550920190973734,-0.200639097181918,-0.34693254604837,-0.300839697994897,-0.245068995761747,-0.204514113769979,-0.249199498572964,-0.607295961671969,-0.654159186706564,-0.600074246062283,-0.0289462961816965,-0.62844087489106,-0.0326808252975285,-0.601400000793821,-0.938470893316988,-0.697257496665814,-0.934133618598793,-0.70245909883662,-0.846507591510186,-0.302042347296202,-0.0644749160398417,-0.198681479759598,-0.447545814986695,-0.298215325760975,-0.344428509897803,-0.310123919232653,-0.934089570768033,-0.262485920879346,-0.9161747755247,-0.302042588631745,-0.932559679785725,-0.60404388331938,-0.849928973035488,-0.70635720799093,-0.752030411157123,-0.298295495634623,-0.652422529999037,-0.301044684883593,-0.751722208090174,-0.399924611231601,-0.654043231583557,-0.605813704232573,-0.242815182896669,-0.706081931993101,-0.245425317397109,-0.198682230439736,-0.549148858952944,-0.808415371693804,-0.447955208494557,-0.628441133904713,-0.964353679517173,-0.696528387581197,-0.936151016624561,-0.200653733734038,-0.649806935210422,-0.114052391290366,-0.254937338943689,-0.159974539285515,-0.160928811818357,-0.117804929087454,-0.215885345095242,-0.399848040706211,-0.342967800101241,-0.792982054570727,-0.117865526772581,-0.844636398570262,-0.15750126910878,-0.744755096395935,-0.0808597080965777,-0.705198418906412,-0.0644748111851743,-0.806487251901647,-0.650109080192945,-0.744755328621242,-0.916174764285806,-0.210296615388269,-0.156258420497593,-0.162604461424131,-0.157501428855896,-0.109233500101505,-0.35049320151043,-0.106672513799963,-0.44869066535242,-0.10649242615583,-0.547877304031636,-0.108830379850367,-0.646249944786925,-0.961230574920394,-0.353836385538967,-0.204730859011916,-0.74748568672318,-0.15997472699092,-0.836105823620476,-0.210806456183054,-0.840188375400235,-0.162604651035224,-0.839533205849627,-0.214258976929844,-0.879168951603058,-0.696528144248732, +-0.0608834692051191,-0.503687070826598,-0.93985905321366,-0.503620626547877,-0.980786610028217,-0.503620358397234,-0.0162479295906371,-0.0377840419333153,-0.373696860802272,-0.0460104460136347,-0.353836549948543,-0.117805086236019,-0.78114930210189,-0.085962915357702,-0.257382685927258,-0.0213511493911129,-0.498517337045844,-0.0277003314961725,-0.450290408519694,-0.0277003583112279,-0.546744263801626,-0.0377841113357863,-0.62333780870737,-0.600074507152403,-0.968088216542574,-0.606005053846177,-0.754512864860315,-0.399216918178421,-0.550682350067821,-0.407166744055643,-0.968088218254007,-0.305152506735148,-0.845973646516863,-0.40605105575414,-0.938202342296567,-0.705198660242026,-0.93255967222694,-0.847266323615737,-0.160928651494149,-0.31071286138768,-0.936151023473019,-0.262485688654117,-0.0808598313305904,-0.21425876528054,-0.117865668699514,-0.407166482965558,-0.0289463482594255,-0.503510934670252,-0.241880168364944,-0.37880011871688,-0.964353681991116 + } + UVIndex: *1260 { + a: 0,1,2,2,1,0,3,4,5,5,4,3,6,7,8,8,7,6,9,8,10,10,8,9,11,12,13,13,12,11,14,15,4,4,15,14,16,17,18,18,17,16,19,20,21,21,20,19,22,23,24,24,23,22,19,21,25,25,21,19,26,5,27,27,5,26,28,29,30,30,29,28,31,18,32,32,18,31,6,25,7,7,25,6,33,34,35,35,34,33,15,19,6,6,19,15,18,36,37,37,36,18,38,39,31,31,39,38,40,41,42,42,41,40,2,43,44,44,43,2,45,46,47,47,46,45,48,49,50,50,49,48,51,47,52,52,47,51,17,36,18,18,36,17,23,53,54,54,53,23,55,42,56,56,42,55,35,48,57,57,48,35,58,3,49,49,3,58,59,60,61,61,60,59,41,27,42,42,27,41,52,62,3,3,62,52,0,24,1,1,24,0,63,53,64,64,53,63,65,66,67,67,66,65,2,44,68,68,44,2,69,33,70,70,33,69,49,5,26,26,5,49,62,14,4,4,14,62,71,72,73,73,72,71,30,29,40,40,29,30,74,67,75,75,67,74,76,77,78,78,77,76,79,80,29,29,80,79,81,34,33,33,34,81,29,80,40,40,80,29,5,4,82,82,4,5,66,83,84,84,83,66,85,76,34,34,76,85,59,70,60,60,70,59,50,26,80,80,26,50,86,87,88,88,87,86,33,89,70,70,89,33,90,40,91,91,40,90,80,41,40,40,41,80,30,92,93,93,92,30,26,27,41,41,27,26,5,82,27,27,82,5,4,15,82,82,15,4,14,94,15,15,94,14,75,32,94,94,32,75,67,31,32,32,31,67,95,38,31,31,38,95,87,96,97,97,96,87,98,59,61,61,59,98,99,69,59,59,69,99,100,81,69,69,81,100,101,85,81,81,85,101,42,102,56,56,102,42,13,103,85,85,103,13,104,105,103,103,105,104,106,107,105,105,107,106,15,6,82,82,6,15,75,94,14,14,94,75,67,32,75,75,32,67,66,31,67,67,31,66,53,108,64,64,108,53,53,28,30,30,28,53,46,109,74,74,109,46,110,65,109,109,65,110,100,69,99,99,69,100,100,101,81,81,101,100,1,54,111,111,54,1,101,13,85,85,13,101,112,99,113,113,99,112,114,104,103,103,104,114,104,106,105,105,106,104,115,98,86,86,98,115,116,100,117,117,100,116,118,119,101,101,119,118,11,13,101,101,13,11,13,114,103,103,114,13,113,99,98,98,99,113,110,120,65,65,120,110,119,11,101,101,11,119,109,65,74,74,65,109,9,10,102,102,10,9,46,74,121,121,74,46,57,50,79,79,50,57,34,122,35,35,122,34,28,79,29,29,79,28,12,114,13,13,114,12,123,110,109,109,110,123,124,45,51,51,45,124,125,109,46,46,109,125,113,98,115,115,98,113,78,52,58,58,52,78,23,28,53,53,28,23,115,86,88,88,86,115,42,9,102,102,9,42,35,122,48,48, +122,35,24,54,1,1,54,24,82,6,9,9,6,82,66,84,126,126,84,66,94,37,19,19,37,94,32,18,37,37,18,32,122,78,58,58,78,122,51,45,47,47,45,51,27,9,42,42,9,27,31,39,16,16,39,31,40,55,127,127,55,40,78,51,52,52,51,78,105,107,124,124,107,105,86,96,87,87,96,86,71,73,128,128,73,71,96,129,130,130,129,96,2,131,43,43,131,2,97,96,130,130,96,97,121,75,14,14,75,121,69,81,33,33,81,69,61,60,0,0,60,61,77,51,78,78,51,77,50,49,26,26,49,50,61,0,96,96,0,61,76,78,122,122,78,76,47,121,62,62,121,47,54,63,111,111,63,54,122,58,48,48,58,122,40,127,91,91,127,40,71,125,45,45,125,71,70,89,22,22,89,70,132,79,28,28,79,132,24,23,54,54,23,24,89,57,132,132,57,89,117,99,112,112,99,117,30,93,108,108,93,30,96,0,2,2,0,96,103,105,77,77,105,103,80,26,41,41,26,80,85,103,76,76,103,85,105,124,77,77,124,105,32,37,94,94,37,32,107,72,124,124,72,107,86,61,96,96,61,86,34,76,122,122,76,34,103,77,76,76,77,103,22,132,23,23,132,22,1,111,131,131,111,1,116,118,100,100,118,116,60,22,24,24,22,60,37,36,20,20,36,37,133,123,125,125,123,133,79,50,80,80,50,79,48,58,49,49,58,48,52,47,62,62,47,52,54,53,63,63,53,54,60,24,0,0,24,60,94,19,15,15,19,94,98,61,86,86,61,98,70,22,60,60,22,70,77,124,51,51,124,77,124,71,45,45,71,124,128,133,125,125,133,128,125,71,128,128,71,125,96,2,68,68,2,96,81,85,34,34,85,81,66,126,31,31,126,66,30,90,92,92,90,30,99,59,98,98,59,99,53,30,108,108,30,53,120,66,65,65,66,120,2,1,131,131,1,2,132,57,79,79,57,132,57,48,50,50,48,57,62,4,3,3,4,62,121,14,62,62,14,121,74,75,121,121,75,74,65,67,74,74,67,65,132,28,23,23,28,132,120,83,66,66,83,120,47,46,121,121,46,47,89,132,22,22,132,89,35,57,89,89,57,35,45,125,46,46,125,45,49,3,5,5,3,49,58,52,3,3,52,58,33,35,89,89,35,33,27,82,9,9,82,27,125,123,109,109,123,125,69,70,59,59,70,69,40,42,55,55,42,40,117,100,99,99,100,117,37,20,19,19,20,37,19,25,6,6,25,19,126,95,31,31,95,126,96,68,129,129,68,96,72,71,124,124,71,72,9,6,8,8,6,9,30,40,90,90,40,30,118,101,100,100,101,118,31,16,18,18,16,31 + } + } + LayerElementMaterial: 0 { + Version: 101 + Name: "" + MappingInformationType: "ByPolygon" + ReferenceInformationType: "IndexToDirect" + Materials: *420 { + a: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + } + } + Layer: 0 { + Version: 100 + LayerElement: { + Type: "LayerElementNormal" + TypedIndex: 0 + } + LayerElement: { + Type: "LayerElementMaterial" + TypedIndex: 0 + } + LayerElement: { + Type: "LayerElementTexture" + TypedIndex: 0 + } + LayerElement: { + Type: "LayerElementUV" + TypedIndex: 0 + } + } + } + Geometry: 140224764960032, "Geometry::", "Mesh" { + Vertices: *840 { + a: -2.39644369470844,-2.67331867818164,-1.00000000000006,-1.74485917411792,-3.35543922263065,-0.750000000000055,-2.49950450806639,-2.77637949153958,-0.75000000000006,-1.67198417411792,-3.22921602002907,-1.00000000000006,-2.49950450806639,-2.77637949153958,-0.75000000000006,-1.74485917411792,-3.35543922263065,-0.750000000000055,-2.39644369470844,-2.67331867818164,-1.00000000000006,-1.67198417411792,-3.22921602002907,-1.00000000000006,-2.39644369470846,2.27360036299944,-1.00000000000005,-3.07856423915749,1.62201584240891,-0.750000000000052,-2.49950450806641,2.37666117635739,-0.750000000000049,-2.95234103655591,1.54914084240892,-1.00000000000006,-2.49950450806641,2.37666117635739,-0.750000000000049,-3.07856423915749,1.62201584240891,-0.750000000000052,-2.39644369470846,2.27360036299944,-1.00000000000005,-2.95234103655591,1.54914084240892,-1.00000000000006,0.982364845650703,-3.57866769795025,-1.00000000000005,0.0770158258820914,-3.84360915759109,-0.750000000000052,0.0770158258820757,-3.69785915759111,-1.00000000000006,1.02008772147439,-3.71945138713189,-0.750000000000048,0.0770158258820757,-3.69785915759111,-1.00000000000006,0.0770158258820914,-3.84360915759109,-0.750000000000052,0.982364845650703,-3.57866769795025,-1.00000000000005,1.02008772147439,-3.71945138713189,-0.750000000000048,-4.07923417411792,-10.8561091575911,-0.750000000000071,-4.07923417411792,-11.2311091575911,-0.375000000000071,-4.45423417411791,-11.2311091575911,-0.375000000000072,4.23326582588205,-10.8561091575911,-0.750000000000042,4.60826582588207,-11.2311091575911,-0.37500000000004,-4.45423417411791,-11.2311091575911,-0.375000000000072,-4.07923417411792,-11.2311091575911,-0.375000000000071,-4.07923417411792,-10.8561091575911,-0.750000000000071,4.23326582588205,-10.8561091575911,-0.750000000000042,4.60826582588207,-11.2311091575911,-0.37500000000004,-4.45423417411793,12.8313908424089,-2.4997460698617e-14,4.60826582588203,12.8313908424089,-0.375000000000004,-4.45423417411794,12.8313908424089,-0.375000000000034,4.60826582588204,12.8313908424089,-1.6608060413037e-14, +-4.45423417411794,12.8313908424089,-0.375000000000034,4.60826582588203,12.8313908424089,-0.375000000000004,-4.45423417411793,12.8313908424089,-2.4997460698617e-14,4.60826582588204,12.8313908424089,-1.6608060413037e-14,0.0770158258820812,3.44389084240889,-0.75000000000003,-0.828333193886543,3.17894938276807,-1.00000000000004,-0.866056069710232,3.3197330719497,-0.750000000000036,0.0770158258820712,3.2981408424089,-1.00000000000004,-0.866056069710232,3.3197330719497,-0.750000000000036,-0.828333193886543,3.17894938276807,-1.00000000000004,0.0770158258820812,3.44389084240889,-0.75000000000003,0.0770158258820712,3.2981408424089,-1.00000000000004,-3.44257640365871,-1.14293105318339,-0.750000000000062,-2.95234103655589,-1.94885915759108,-1.00000000000006,-3.07856423915747,-2.02173415759108,-0.750000000000061,-3.30179271447709,-1.1052081773597,-1.00000000000006,-3.07856423915747,-2.02173415759108,-0.750000000000061,-2.95234103655589,-1.94885915759108,-1.00000000000006,-3.44257640365871,-1.14293105318339,-0.750000000000062,-3.30179271447709,-1.1052081773597,-1.00000000000006,-0.828333193886537,-3.57866769795025,-1.00000000000006,0.982364845650703,-3.57866769795025,-1.00000000000005,0.0770158258820757,-3.69785915759111,-1.00000000000006,1.82601582588208,-3.22921602002906,-1.00000000000005,-1.67198417411792,-3.22921602002907,-1.00000000000006,-2.39644369470844,-2.67331867818164,-1.00000000000006,2.55047534647261,-2.67331867818162,-1.00000000000004,-2.95234103655589,-1.94885915759108,-1.00000000000006,3.10637268832004,-1.94885915759107,-1.00000000000003,-3.30179271447709,-1.1052081773597,-1.00000000000006,3.45582436624123,-1.1052081773597,-1.00000000000003,3.57501582588207,-0.199859157591068,-1.00000000000003,-3.42098417411793,-0.199859157591082,-1.00000000000007,-3.3017927144771,0.705489862177533,-1.00000000000006,3.45582436624123,0.705489862177538,-1.00000000000003,-2.95234103655591,1.54914084240892,-1.00000000000006,3.10637268832002,1.54914084240891,-1.00000000000003,2.55047534647259,2.27360036299947,-1.00000000000004,-2.39644369470846,2.27360036299944,-1.00000000000005, +-1.67198417411792,2.82949770484689,-1.00000000000005,1.82601582588209,2.82949770484689,-1.00000000000004,0.982364845650693,3.17894938276807,-1.00000000000004,-0.828333193886543,3.17894938276807,-1.00000000000004,0.0770158258820712,3.2981408424089,-1.00000000000004,0.0770158258820757,-3.69785915759111,-1.00000000000006,0.982364845650703,-3.57866769795025,-1.00000000000005,-0.828333193886537,-3.57866769795025,-1.00000000000006,1.82601582588208,-3.22921602002906,-1.00000000000005,-1.67198417411792,-3.22921602002907,-1.00000000000006,-2.39644369470844,-2.67331867818164,-1.00000000000006,2.55047534647261,-2.67331867818162,-1.00000000000004,-2.95234103655589,-1.94885915759108,-1.00000000000006,3.10637268832004,-1.94885915759107,-1.00000000000003,-3.30179271447709,-1.1052081773597,-1.00000000000006,3.45582436624123,-1.1052081773597,-1.00000000000003,3.57501582588207,-0.199859157591068,-1.00000000000003,-3.42098417411793,-0.199859157591082,-1.00000000000007,-3.3017927144771,0.705489862177533,-1.00000000000006,3.45582436624123,0.705489862177538,-1.00000000000003,-2.95234103655591,1.54914084240892,-1.00000000000006,3.10637268832002,1.54914084240891,-1.00000000000003,2.55047534647259,2.27360036299947,-1.00000000000004,-2.39644369470846,2.27360036299944,-1.00000000000005,-1.67198417411792,2.82949770484689,-1.00000000000005,1.82601582588209,2.82949770484689,-1.00000000000004,0.982364845650693,3.17894938276807,-1.00000000000004,-0.828333193886543,3.17894938276807,-1.00000000000004,0.0770158258820712,3.2981408424089,-1.00000000000004,-0.828333193886537,-3.57866769795025,-1.00000000000006,-0.866056069710236,-3.71945138713189,-0.750000000000054,-0.866056069710236,-3.71945138713189,-0.750000000000054,-0.828333193886537,-3.57866769795025,-1.00000000000006,0.982364845650693,3.17894938276807,-1.00000000000004,1.02008772147439,3.31973307194969,-0.750000000000034,0.982364845650693,3.17894938276807,-1.00000000000004,1.02008772147439,3.31973307194969,-0.750000000000034,1.89889082588207,2.95572090744846,-0.750000000000031,2.55047534647259,2.27360036299947,-1.00000000000004, +1.82601582588209,2.82949770484689,-1.00000000000004,2.65353615983054,2.3766611763574,-0.750000000000026,1.82601582588209,2.82949770484689,-1.00000000000004,2.55047534647259,2.27360036299947,-1.00000000000004,1.89889082588207,2.95572090744846,-0.750000000000031,2.65353615983054,2.3766611763574,-0.750000000000026,-3.44257640365872,0.743212738001221,-0.750000000000063,-3.3017927144771,0.705489862177533,-1.00000000000006,-3.44257640365872,0.743212738001221,-0.750000000000063,-3.3017927144771,0.705489862177533,-1.00000000000006,-4.07923417411792,-11.2311091575911,-0.375000000000071,-4.4542341741179,-11.2311091575911,-6.58164755334978e-14,-4.45423417411791,-11.2311091575911,-0.375000000000072,4.60826582588207,-11.2311091575911,-4.76276917210638e-14,4.60826582588207,-11.2311091575911,-0.37500000000004,-4.45423417411791,-11.2311091575911,-0.375000000000072,-4.4542341741179,-11.2311091575911,-6.58164755334978e-14,-4.07923417411792,-11.2311091575911,-0.375000000000071,4.60826582588207,-11.2311091575911,-4.76276917210638e-14,4.60826582588207,-11.2311091575911,-0.37500000000004,2.65353615983056,-2.77637949153957,-0.750000000000037,3.10637268832004,-1.94885915759107,-1.00000000000003,3.23259589092162,-2.02173415759108,-0.750000000000028,2.55047534647261,-2.67331867818162,-1.00000000000004,3.23259589092162,-2.02173415759108,-0.750000000000028,3.10637268832004,-1.94885915759107,-1.00000000000003,2.65353615983056,-2.77637949153957,-0.750000000000037,2.55047534647261,-2.67331867818162,-1.00000000000004,3.45582436624123,0.705489862177538,-1.00000000000003,3.2325958909216,1.62201584240893,-0.75000000000003,3.59660805542286,0.743212738001241,-0.75000000000002,3.10637268832002,1.54914084240891,-1.00000000000003,3.59660805542286,0.743212738001241,-0.75000000000002,3.2325958909216,1.62201584240893,-0.75000000000003,3.45582436624123,0.705489862177538,-1.00000000000003,3.10637268832002,1.54914084240891,-1.00000000000003,-3.56673417411793,-0.199859157591085,-0.750000000000062,-3.42098417411793,-0.199859157591082,-1.00000000000007,-3.56673417411793,-0.199859157591085,-0.750000000000062, +-3.42098417411793,-0.199859157591082,-1.00000000000007,1.89889082588208,-3.35543922263064,-0.75000000000004,1.82601582588208,-3.22921602002906,-1.00000000000005,1.82601582588208,-3.22921602002906,-1.00000000000005,1.89889082588208,-3.35543922263064,-0.75000000000004,3.45582436624123,-1.1052081773597,-1.00000000000003,3.59660805542286,-1.14293105318339,-0.750000000000019,3.59660805542286,-1.14293105318339,-0.750000000000019,3.45582436624123,-1.1052081773597,-1.00000000000003,-1.74485917411792,2.95572090744846,-0.750000000000039,-1.67198417411792,2.82949770484689,-1.00000000000005,-1.74485917411792,2.95572090744846,-0.750000000000039,-1.67198417411792,2.82949770484689,-1.00000000000005,3.72076582588206,-0.19985915759108,-0.750000000000028,3.57501582588207,-0.199859157591068,-1.00000000000003,3.72076582588206,-0.19985915759108,-0.750000000000028,3.57501582588207,-0.199859157591068,-1.00000000000003,-4.07923417411792,-10.8561091575911,-0.750000000000071,-0.866056069710236,-3.71945138713189,-0.750000000000054,0.0770158258820914,-3.84360915759109,-0.750000000000052,-1.74485917411792,-3.35543922263065,-0.750000000000055,-2.49950450806639,-2.77637949153958,-0.75000000000006,-3.07856423915747,-2.02173415759108,-0.750000000000061,-3.44257640365871,-1.14293105318339,-0.750000000000062,-3.56673417411793,-0.199859157591085,-0.750000000000062,-4.07923417411792,12.4563908424089,-0.750000000000045,-3.44257640365872,0.743212738001221,-0.750000000000063,-3.07856423915749,1.62201584240891,-0.750000000000052,-2.49950450806641,2.37666117635739,-0.750000000000049,-1.74485917411792,2.95572090744846,-0.750000000000039,-0.866056069710232,3.3197330719497,-0.750000000000036,0.0770158258820812,3.44389084240889,-0.75000000000003,4.23326582588204,12.4563908424089,-0.750000000000008,4.23326582588205,-10.8561091575911,-0.750000000000042,3.72076582588206,-0.19985915759108,-0.750000000000028,3.59660805542286,-1.14293105318339,-0.750000000000019,3.23259589092162,-2.02173415759108,-0.750000000000028,2.65353615983056,-2.77637949153957,-0.750000000000037, +1.89889082588208,-3.35543922263064,-0.75000000000004,1.02008772147439,-3.71945138713189,-0.750000000000048,3.59660805542286,0.743212738001241,-0.75000000000002,3.2325958909216,1.62201584240893,-0.75000000000003,2.65353615983054,2.3766611763574,-0.750000000000026,1.89889082588207,2.95572090744846,-0.750000000000031,1.02008772147439,3.31973307194969,-0.750000000000034,0.0770158258820914,-3.84360915759109,-0.750000000000052,-0.866056069710236,-3.71945138713189,-0.750000000000054,-4.07923417411792,-10.8561091575911,-0.750000000000071,-1.74485917411792,-3.35543922263065,-0.750000000000055,-2.49950450806639,-2.77637949153958,-0.75000000000006,-3.07856423915747,-2.02173415759108,-0.750000000000061,-3.44257640365871,-1.14293105318339,-0.750000000000062,-3.56673417411793,-0.199859157591085,-0.750000000000062,-4.07923417411792,12.4563908424089,-0.750000000000045,-3.44257640365872,0.743212738001221,-0.750000000000063,-3.07856423915749,1.62201584240891,-0.750000000000052,-2.49950450806641,2.37666117635739,-0.750000000000049,-1.74485917411792,2.95572090744846,-0.750000000000039,-0.866056069710232,3.3197330719497,-0.750000000000036,0.0770158258820812,3.44389084240889,-0.75000000000003,4.23326582588204,12.4563908424089,-0.750000000000008,3.72076582588206,-0.19985915759108,-0.750000000000028,4.23326582588205,-10.8561091575911,-0.750000000000042,3.59660805542286,-1.14293105318339,-0.750000000000019,3.23259589092162,-2.02173415759108,-0.750000000000028,2.65353615983056,-2.77637949153957,-0.750000000000037,1.89889082588208,-3.35543922263064,-0.75000000000004,1.02008772147439,-3.71945138713189,-0.750000000000048,3.59660805542286,0.743212738001241,-0.75000000000002,3.2325958909216,1.62201584240893,-0.75000000000003,2.65353615983054,2.3766611763574,-0.750000000000026,1.89889082588207,2.95572090744846,-0.750000000000031,1.02008772147439,3.31973307194969,-0.750000000000034,4.60826582588204,12.8313908424089,-1.6608060413037e-14,-4.4542341741179,-11.2311091575911,-6.58164755334978e-14,4.60826582588207,-11.2311091575911,-4.76276917210638e-14, +-4.45423417411793,12.8313908424089,-2.4997460698617e-14,4.60826582588207,-11.2311091575911,-4.76276917210638e-14,-4.4542341741179,-11.2311091575911,-6.58164755334978e-14,4.60826582588204,12.8313908424089,-1.6608060413037e-14,-4.45423417411793,12.8313908424089,-2.4997460698617e-14,-4.07923417411792,12.4563908424089,-0.750000000000045,4.60826582588203,12.8313908424089,-0.375000000000004,4.23326582588204,12.4563908424089,-0.750000000000008,-4.45423417411794,12.8313908424089,-0.375000000000034,4.23326582588204,12.4563908424089,-0.750000000000008,4.60826582588203,12.8313908424089,-0.375000000000004,-4.07923417411792,12.4563908424089,-0.750000000000045,-4.45423417411794,12.8313908424089,-0.375000000000034,-4.07923417411792,12.4563908424089,-0.750000000000045,-4.45423417411794,12.4563908424089,-0.375000000000038,-4.45423417411794,12.8313908424089,-0.375000000000034,-4.45423417411791,-11.2311091575911,-0.375000000000072,-4.07923417411792,-10.8561091575911,-0.750000000000071,-4.45423417411794,12.8313908424089,-0.375000000000034,-4.45423417411794,12.4563908424089,-0.375000000000038,-4.07923417411792,12.4563908424089,-0.750000000000045,-4.45423417411791,-11.2311091575911,-0.375000000000072,-4.07923417411792,-10.8561091575911,-0.750000000000071,4.60826582588207,-11.2311091575911,-0.37500000000004,4.23326582588204,12.4563908424089,-0.750000000000008,4.60826582588203,12.8313908424089,-0.375000000000004,4.23326582588205,-10.8561091575911,-0.750000000000042,4.60826582588203,12.8313908424089,-0.375000000000004,4.23326582588204,12.4563908424089,-0.750000000000008,4.60826582588207,-11.2311091575911,-0.37500000000004,4.23326582588205,-10.8561091575911,-0.750000000000042,-4.45423417411794,12.8313908424089,-0.375000000000034,-4.4542341741179,-11.2311091575911,-6.58164755334978e-14,-4.45423417411793,12.8313908424089,-2.4997460698617e-14,-4.45423417411791,-11.2311091575911,-0.375000000000072,-4.45423417411794,12.4563908424089,-0.375000000000038,-4.45423417411793,12.8313908424089,-2.4997460698617e-14,-4.4542341741179,-11.2311091575911,-6.58164755334978e-14, +-4.45423417411794,12.8313908424089,-0.375000000000034,-4.45423417411791,-11.2311091575911,-0.375000000000072,-4.45423417411794,12.4563908424089,-0.375000000000038,4.60826582588207,-11.2311091575911,-4.76276917210638e-14,4.60826582588203,12.8313908424089,-0.375000000000004,4.60826582588204,12.8313908424089,-1.6608060413037e-14,4.60826582588207,-11.2311091575911,-0.37500000000004,4.60826582588204,12.8313908424089,-1.6608060413037e-14,4.60826582588203,12.8313908424089,-0.375000000000004,4.60826582588207,-11.2311091575911,-4.76276917210638e-14,4.60826582588207,-11.2311091575911,-0.37500000000004 + } + PolygonVertexIndex: *720 { + a: 0,1,-3,1,0,-4,4,5,-7,7,6,-6,8,9,-11,9,8,-12,12,13,-15,15,14,-14,16,17,-19,17,16,-20,20,21,-23,23,22,-22,24,25,-27,25,24,-28,27,28,-26,29,30,-32,32,31,-31,30,33,-33,34,35,-37,35,34,-38,38,39,-41,41,40,-40,42,43,-45,43,42,-46,46,47,-49,49,48,-48,50,51,-53,51,50,-54,54,55,-57,57,56,-56,58,59,-61,59,58,-62,61,58,-63,61,62,-64,61,63,-65,64,63,-66,64,65,-67,66,65,-68,66,67,-69,68,67,-70,69,67,-71,69,70,-72,69,71,-73,72,71,-74,72,73,-75,74,73,-76,75,73,-77,75,76,-78,75,77,-79,78,77,-80,79,77,-81,79,80,-82,82,83,-85,85,84,-84,86,84,-86,87,86,-86,88,87,-86,89,87,-89,90,89,-89,91,89,-91,92,91,-91,93,91,-93,94,91,-94,95,94,-94,96,95,-94,97,95,-97,98,97,-97,99,97,-99,100,97,-100,101,100,-100,102,101,-100,103,101,-103,104,101,-104,105,104,-104,106,17,-108,17,106,-19,108,21,-110,20,109,-22,42,110,-46,110,42,-112,49,112,-49,113,48,-113,114,115,-117,115,114,-118,118,119,-121,121,120,-120,11,122,-10,122,11,-124,13,124,-16,125,15,-125,52,0,-3,0,52,-52,4,6,-55,55,54,-7,126,127,-129,127,126,-130,129,126,-131,131,132,-134,134,133,-133,135,133,-135,136,137,-139,137,136,-140,140,141,-143,143,142,-142,144,145,-147,145,144,-148,148,149,-151,151,150,-150,152,53,-51,53,152,-154,56,57,-155,155,154,-58,139,156,-158,156,139,-137,158,159,-144,142,143,-160,138,160,-162,160,138,-138,162,163,-141,141,140,-164,111,116,-111,116,111,-115,112,118,-114,120,113,-119,3,107,-2,107,3,-107,5,108,-8,109,7,-109,122,153,-153,153,122,-124,154,155,-125,125,124,-156,164,8,-11,8,164,-166,12,14,-167,167,166,-15,160,168,-162,168,160,-170,162,170,-164,171,163,-171,157,19,-17,19,157,-157,22,23,-159,159,158,-24,168,144,-147,144,168,-170,148,150,-171,171,170,-151,44,165,-165,165,44,-44,166,167,-47,47,46,-168,145,115,-118,115,145,-148,121,119,-150,151,149,-120,172,173,-175,173,172,-176,175,172,-177,176,172,-178,177,172,-179,178,172,-180,179,172,-181,179,180,-182,181,180,-183,182,180,-184,183,180,-185,184,180,-186,185,180,-187,186,180,-188,188,189,-188,189,188,-191,190,188,-192,191,188,-193,192,188,-173,192,172,-194,193,172,-195,194,172,-175,187,189,-196, +187,195,-197,187,196,-198,187,197,-199,187,198,-200,187,199,-187,200,201,-203,203,202,-202,204,202,-204,205,202,-205,206,202,-206,207,202,-207,208,202,-208,209,208,-208,210,208,-210,211,208,-211,212,208,-212,213,208,-213,214,208,-214,215,208,-215,215,216,-218,218,217,-217,219,217,-219,220,217,-220,202,217,-221,221,202,-221,222,202,-222,200,202,-223,223,216,-216,224,223,-216,225,224,-216,226,225,-216,227,226,-216,214,227,-216,228,229,-231,229,228,-232,232,233,-235,235,234,-234,236,237,-239,237,236,-240,240,241,-243,243,242,-242,244,245,-247,245,244,-248,247,244,-249,249,250,-252,252,251,-251,253,251,-253,254,255,-257,255,254,-258,258,259,-261,261,260,-260,262,263,-265,263,262,-266,265,262,-267,267,268,-270,270,269,-269,271,269,-271,272,273,-275,273,272,-276,276,277,-279,279,278,-278 + } + GeometryVersion: 124 + LayerElementNormal: 0 { + Version: 101 + Name: "" + MappingInformationType: "ByVertice" + ReferenceInformationType: "Direct" + Normals: *840 { + a: -0.610872523368971,-0.610872523368972,-0.503656152931394,-0.431952103714737,-0.748162990070192,-0.503656152931386,-0.610872523368971,-0.610872523368972,-0.503656152931394,-0.431952103714737,-0.748162990070192,-0.503656152931386,0.610872523368971,0.610872523368972,0.503656152931394,0.431952103714737,0.748162990070192,0.503656152931386,0.610872523368971,0.610872523368972,0.503656152931394,0.431952103714737,0.748162990070192,0.503656152931386,-0.61087252336897,0.610872523368974,-0.503656152931392,-0.748162990070185,0.43195210371474,-0.503656152931393,-0.61087252336897,0.610872523368974,-0.503656152931392,-0.748162990070185,0.43195210371474,-0.503656152931393,0.61087252336897,-0.610872523368974,0.503656152931392,0.748162990070185,-0.43195210371474,0.503656152931393,0.61087252336897,-0.610872523368974,0.503656152931392,0.748162990070185,-0.43195210371474,0.503656152931393,0.223594862026954,-0.834467385395924,-0.503656152931381,3.79909437496452e-15,-0.863904207429487,-0.503656152931372,3.79909437496452e-15,-0.863904207429487,-0.503656152931372,0.223594862026954,-0.834467385395924,-0.503656152931381,-3.79909437496452e-15,0.863904207429487,0.503656152931372,-3.79909437496452e-15,0.863904207429487,0.503656152931372,-0.223594862026954,0.834467385395924,0.503656152931381,-0.223594862026954,0.834467385395924,0.503656152931381,3.2612801348364e-15,-0.707106781186535,-0.70710678118656,3.2612801348364e-15,-0.707106781186535,-0.70710678118656,3.2612801348364e-15,-0.707106781186535,-0.70710678118656,3.2612801348364e-15,-0.707106781186535,-0.70710678118656,3.2612801348364e-15,-0.707106781186535,-0.70710678118656,-3.2612801348364e-15,0.707106781186535,0.70710678118656,-3.2612801348364e-15,0.707106781186535,0.70710678118656,-3.2612801348364e-15,0.707106781186535,0.70710678118656,-3.2612801348364e-15,0.707106781186535,0.70710678118656,-3.2612801348364e-15,0.707106781186535,0.70710678118656,-1.35308431126194e-15,1,8.46545056276681e-16,-1.35308431126194e-15,1,8.46545056276681e-16,-1.35308431126194e-15,1,8.46545056276681e-16, +-1.35308431126194e-15,1,8.46545056276681e-16,1.35308431126194e-15,-1,-8.46545056276681e-16,1.35308431126194e-15,-1,-8.46545056276681e-16,1.35308431126194e-15,-1,-8.46545056276681e-16,1.35308431126194e-15,-1,-8.46545056276681e-16,1.59226749538954e-15,0.863904207429483,-0.50365615293138,-0.223594862026944,0.834467385395926,-0.503656152931381,-0.223594862026944,0.834467385395926,-0.503656152931381,1.59226749538954e-15,0.863904207429483,-0.50365615293138,0.223594862026944,-0.834467385395926,0.503656152931381,0.223594862026944,-0.834467385395926,0.503656152931381,-1.59226749538954e-15,-0.863904207429483,0.50365615293138,-1.59226749538954e-15,-0.863904207429483,0.50365615293138,-0.834467385395924,-0.223594862026951,-0.503656152931381,-0.748162990070188,-0.431952103714739,-0.50365615293139,-0.748162990070188,-0.431952103714739,-0.50365615293139,-0.834467385395924,-0.223594862026951,-0.503656152931381,0.748162990070188,0.431952103714739,0.50365615293139,0.748162990070188,0.431952103714739,0.50365615293139,0.834467385395924,0.223594862026951,0.503656152931381,0.834467385395924,0.223594862026951,0.503656152931381,4.64905891561784e-15,8.46545056276682e-16,-1,4.64905891561784e-15,8.46545056276682e-16,-1,4.64905891561784e-15,8.46545056276682e-16,-1,4.64905891561784e-15,8.46545056276682e-16,-1,4.64905891561784e-15,8.46545056276682e-16,-1,4.64905891561784e-15,8.46545056276682e-16,-1,4.64905891561784e-15,8.46545056276682e-16,-1,4.64905891561784e-15,8.46545056276682e-16,-1,4.64905891561784e-15,8.46545056276682e-16,-1,4.64905891561784e-15,8.46545056276682e-16,-1,4.64905891561784e-15,8.46545056276682e-16,-1,4.64905891561784e-15,8.46545056276682e-16,-1,4.64905891561784e-15,8.46545056276682e-16,-1,4.64905891561784e-15,8.46545056276682e-16,-1,4.64905891561784e-15,8.46545056276682e-16,-1,4.64905891561784e-15,8.46545056276682e-16,-1,4.64905891561784e-15,8.46545056276682e-16,-1,4.64905891561784e-15,8.46545056276682e-16,-1,4.64905891561784e-15,8.46545056276682e-16,-1,4.64905891561784e-15,8.46545056276682e-16,-1,4.64905891561784e-15,8.46545056276682e-16,-1, +4.64905891561784e-15,8.46545056276682e-16,-1,4.64905891561784e-15,8.46545056276682e-16,-1,4.64905891561784e-15,8.46545056276682e-16,-1,-4.64905891561784e-15,-8.46545056276682e-16,1,-4.64905891561784e-15,-8.46545056276682e-16,1,-4.64905891561784e-15,-8.46545056276682e-16,1,-4.64905891561784e-15,-8.46545056276682e-16,1,-4.64905891561784e-15,-8.46545056276682e-16,1,-4.64905891561784e-15,-8.46545056276682e-16,1,-4.64905891561784e-15,-8.46545056276682e-16,1,-4.64905891561784e-15,-8.46545056276682e-16,1,-4.64905891561784e-15,-8.46545056276682e-16,1,-4.64905891561784e-15,-8.46545056276682e-16,1,-4.64905891561784e-15,-8.46545056276682e-16,1,-4.64905891561784e-15,-8.46545056276682e-16,1,-4.64905891561784e-15,-8.46545056276682e-16,1,-4.64905891561784e-15,-8.46545056276682e-16,1,-4.64905891561784e-15,-8.46545056276682e-16,1,-4.64905891561784e-15,-8.46545056276682e-16,1,-4.64905891561784e-15,-8.46545056276682e-16,1,-4.64905891561784e-15,-8.46545056276682e-16,1,-4.64905891561784e-15,-8.46545056276682e-16,1,-4.64905891561784e-15,-8.46545056276682e-16,1,-4.64905891561784e-15,-8.46545056276682e-16,1,-4.64905891561784e-15,-8.46545056276682e-16,1,-4.64905891561784e-15,-8.46545056276682e-16,1,-4.64905891561784e-15,-8.46545056276682e-16,1,-0.223594862026944,-0.834467385395929,-0.503656152931376,-0.223594862026944,-0.834467385395929,-0.503656152931376,0.223594862026944,0.834467385395929,0.503656152931376,0.223594862026944,0.834467385395929,0.503656152931376,0.223594862026951,0.834467385395935,-0.503656152931363,0.223594862026951,0.834467385395935,-0.503656152931363,-0.223594862026951,-0.834467385395935,0.503656152931363,-0.223594862026951,-0.834467385395935,0.503656152931363,0.431952103714748,0.748162990070207,-0.503656152931354,0.61087252336898,0.610872523368982,-0.50365615293137,0.431952103714748,0.748162990070207,-0.503656152931354,0.61087252336898,0.610872523368982,-0.50365615293137,-0.431952103714748,-0.748162990070207,0.503656152931354,-0.61087252336898,-0.610872523368982,0.50365615293137,-0.431952103714748,-0.748162990070207,0.503656152931354, +-0.61087252336898,-0.610872523368982,0.50365615293137,-0.834467385395922,0.223594862026946,-0.503656152931387,-0.834467385395922,0.223594862026946,-0.503656152931387,0.834467385395922,-0.223594862026946,0.503656152931387,0.834467385395922,-0.223594862026946,0.503656152931387,1.46410661372445e-15,-1,6.52256026967282e-16,1.46410661372445e-15,-1,6.52256026967282e-16,1.46410661372445e-15,-1,6.52256026967282e-16,1.46410661372445e-15,-1,6.52256026967282e-16,1.46410661372445e-15,-1,6.52256026967282e-16,-1.46410661372445e-15,1,-6.52256026967282e-16,-1.46410661372445e-15,1,-6.52256026967282e-16,-1.46410661372445e-15,1,-6.52256026967282e-16,-1.46410661372445e-15,1,-6.52256026967282e-16,-1.46410661372445e-15,1,-6.52256026967282e-16,0.61087252336898,-0.610872523368973,-0.503656152931381,0.748162990070191,-0.431952103714739,-0.503656152931384,0.748162990070191,-0.431952103714739,-0.503656152931384,0.61087252336898,-0.610872523368973,-0.503656152931381,-0.748162990070191,0.431952103714739,0.503656152931384,-0.748162990070191,0.431952103714739,0.503656152931384,-0.61087252336898,0.610872523368973,0.503656152931381,-0.61087252336898,0.610872523368973,0.503656152931381,0.834467385395921,0.223594862026947,-0.503656152931388,0.748162990070184,0.431952103714743,-0.503656152931391,0.834467385395921,0.223594862026947,-0.503656152931388,0.748162990070184,0.431952103714743,-0.503656152931391,-0.834467385395921,-0.223594862026947,0.503656152931388,-0.748162990070184,-0.431952103714743,0.503656152931391,-0.834467385395921,-0.223594862026947,0.503656152931388,-0.748162990070184,-0.431952103714743,0.503656152931391,-0.863904207429479,5.09804943699282e-16,-0.503656152931385,-0.863904207429479,5.09804943699282e-16,-0.503656152931385,0.863904207429479,-5.09804943699282e-16,0.503656152931385,0.863904207429479,-5.09804943699282e-16,0.503656152931385,0.431952103714746,-0.748162990070188,-0.503656152931382,0.431952103714746,-0.748162990070188,-0.503656152931382,-0.431952103714746,0.748162990070188,0.503656152931382,-0.431952103714746,0.748162990070188,0.503656152931382, +0.834467385395927,-0.223594862026949,-0.503656152931377,0.834467385395927,-0.223594862026949,-0.503656152931377,-0.834467385395927,0.223594862026949,0.503656152931377,-0.834467385395927,0.223594862026949,0.503656152931377,-0.43195210371474,0.748162990070192,-0.503656152931382,-0.43195210371474,0.748162990070192,-0.503656152931382,0.43195210371474,-0.748162990070192,0.503656152931382,0.43195210371474,-0.748162990070192,0.503656152931382,0.863904207429487,-4.91647507348349e-15,-0.503656152931373,0.863904207429487,-4.91647507348349e-15,-0.503656152931373,-0.863904207429487,4.91647507348349e-15,0.503656152931373,-0.863904207429487,4.91647507348349e-15,0.503656152931373,4.64905891561784e-15,8.46545056276682e-16,-1,4.64905891561784e-15,8.46545056276682e-16,-1,4.64905891561784e-15,8.46545056276682e-16,-1,4.64905891561784e-15,8.46545056276682e-16,-1,4.64905891561784e-15,8.46545056276682e-16,-1,4.64905891561784e-15,8.46545056276682e-16,-1,4.64905891561784e-15,8.46545056276682e-16,-1,4.64905891561784e-15,8.46545056276682e-16,-1,4.64905891561784e-15,8.46545056276682e-16,-1,4.64905891561784e-15,8.46545056276682e-16,-1,4.64905891561784e-15,8.46545056276682e-16,-1,4.64905891561784e-15,8.46545056276682e-16,-1,4.64905891561784e-15,8.46545056276682e-16,-1,4.64905891561784e-15,8.46545056276682e-16,-1,4.64905891561784e-15,8.46545056276682e-16,-1,4.64905891561784e-15,8.46545056276682e-16,-1,4.64905891561784e-15,8.46545056276682e-16,-1,4.64905891561784e-15,8.46545056276682e-16,-1,4.64905891561784e-15,8.46545056276682e-16,-1,4.64905891561784e-15,8.46545056276682e-16,-1,4.64905891561784e-15,8.46545056276682e-16,-1,4.64905891561784e-15,8.46545056276682e-16,-1,4.64905891561784e-15,8.46545056276682e-16,-1,4.64905891561784e-15,8.46545056276682e-16,-1,4.64905891561784e-15,8.46545056276682e-16,-1,4.64905891561784e-15,8.46545056276682e-16,-1,4.64905891561784e-15,8.46545056276682e-16,-1,4.64905891561784e-15,8.46545056276682e-16,-1,-4.64905891561784e-15,-8.46545056276682e-16,1,-4.64905891561784e-15,-8.46545056276682e-16,1,-4.64905891561784e-15,-8.46545056276682e-16,1, +-4.64905891561784e-15,-8.46545056276682e-16,1,-4.64905891561784e-15,-8.46545056276682e-16,1,-4.64905891561784e-15,-8.46545056276682e-16,1,-4.64905891561784e-15,-8.46545056276682e-16,1,-4.64905891561784e-15,-8.46545056276682e-16,1,-4.64905891561784e-15,-8.46545056276682e-16,1,-4.64905891561784e-15,-8.46545056276682e-16,1,-4.64905891561784e-15,-8.46545056276682e-16,1,-4.64905891561784e-15,-8.46545056276682e-16,1,-4.64905891561784e-15,-8.46545056276682e-16,1,-4.64905891561784e-15,-8.46545056276682e-16,1,-4.64905891561784e-15,-8.46545056276682e-16,1,-4.64905891561784e-15,-8.46545056276682e-16,1,-4.64905891561784e-15,-8.46545056276682e-16,1,-4.64905891561784e-15,-8.46545056276682e-16,1,-4.64905891561784e-15,-8.46545056276682e-16,1,-4.64905891561784e-15,-8.46545056276682e-16,1,-4.64905891561784e-15,-8.46545056276682e-16,1,-4.64905891561784e-15,-8.46545056276682e-16,1,-4.64905891561784e-15,-8.46545056276682e-16,1,-4.64905891561784e-15,-8.46545056276682e-16,1,-4.64905891561784e-15,-8.46545056276682e-16,1,-4.64905891561784e-15,-8.46545056276682e-16,1,-4.64905891561784e-15,-8.46545056276682e-16,1,-4.64905891561784e-15,-8.46545056276682e-16,1,-4.64905891561784e-15,-8.46545056276682e-16,1,-4.64905891561784e-15,-8.46545056276682e-16,1,-4.64905891561784e-15,-8.46545056276682e-16,1,-4.64905891561784e-15,-8.46545056276682e-16,1,4.64905891561784e-15,8.46545056276682e-16,-1,4.64905891561784e-15,8.46545056276682e-16,-1,4.64905891561784e-15,8.46545056276682e-16,-1,4.64905891561784e-15,8.46545056276682e-16,-1,3.01147995429574e-15,0.707106781186543,-0.707106781186552,3.01147995429574e-15,0.707106781186543,-0.707106781186552,3.01147995429574e-15,0.707106781186543,-0.707106781186552,3.01147995429574e-15,0.707106781186543,-0.707106781186552,-3.01147995429574e-15,-0.707106781186543,0.707106781186552,-3.01147995429574e-15,-0.707106781186543,0.707106781186552,-3.01147995429574e-15,-0.707106781186543,0.707106781186552,-3.01147995429574e-15,-0.707106781186543,0.707106781186552,-0.707106781186559,-2.51448792712793e-16,-0.707106781186536,-0.707106781186559,-2.51448792712793e-16,-0.707106781186536, +-0.707106781186559,-2.51448792712793e-16,-0.707106781186536,-0.707106781186559,-2.51448792712793e-16,-0.707106781186536,-0.707106781186559,-2.51448792712793e-16,-0.707106781186536,0.707106781186559,2.51448792712793e-16,0.707106781186536,0.707106781186559,2.51448792712793e-16,0.707106781186536,0.707106781186559,2.51448792712793e-16,0.707106781186536,0.707106781186559,2.51448792712793e-16,0.707106781186536,0.707106781186559,2.51448792712793e-16,0.707106781186536,0.707106781186557,2.48624523241562e-15,-0.707106781186538,0.707106781186557,2.48624523241562e-15,-0.707106781186538,0.707106781186557,2.48624523241562e-15,-0.707106781186538,0.707106781186557,2.48624523241562e-15,-0.707106781186538,-0.707106781186557,-2.48624523241562e-15,0.707106781186538,-0.707106781186557,-2.48624523241562e-15,0.707106781186538,-0.707106781186557,-2.48624523241562e-15,0.707106781186538,-0.707106781186557,-2.48624523241562e-15,0.707106781186538,-1,-1.0894063429135e-15,-2.41473507855972e-15,-1,-1.0894063429135e-15,-2.41473507855972e-15,-1,-1.0894063429135e-15,-2.41473507855972e-15,-1,-1.0894063429135e-15,-2.41473507855972e-15,-1,-1.0894063429135e-15,-2.41473507855972e-15,1,1.0894063429135e-15,2.41473507855972e-15,1,1.0894063429135e-15,2.41473507855972e-15,1,1.0894063429135e-15,2.41473507855972e-15,1,1.0894063429135e-15,2.41473507855972e-15,1,1.0894063429135e-15,2.41473507855972e-15,1,1.200428645376e-15,4.64905891561784e-15,1,1.200428645376e-15,4.64905891561784e-15,1,1.200428645376e-15,4.64905891561784e-15,1,1.200428645376e-15,4.64905891561784e-15,-1,-1.200428645376e-15,-4.64905891561784e-15,-1,-1.200428645376e-15,-4.64905891561784e-15,-1,-1.200428645376e-15,-4.64905891561784e-15,-1,-1.200428645376e-15,-4.64905891561784e-15 + } + } + LayerElementUV: 0 { + Version: 101 + Name: "" + MappingInformationType: "ByPolygonVertex" + ReferenceInformationType: "IndexToDirect" + UV: *500 { + a: -0.426915678353167,-0.615683873281153,-0.446081531795738,-0.64076391705765,-0.423884226353249,-0.619473189261517,-0.448225091619884,-0.636122971951398,0.463447748362503,-0.164606168041751,0.25887507362019,-0.478284766023168,0.364133138549815,-0.108777779871796,0.167743370797195,-0.409909233933955,-0.426915634094131,-0.433796727275882,-0.406851599704663,-0.457754036523888,-0.423884180250086,-0.430007412391067,-0.410564356728596,-0.460433486457433,0.340815509972121,0.284350733390694,0.475060828690047,-0.0652525224367327,0.237371640927589,0.236605926290862,0.366247146896801,-0.0990131993034645,-0.526300691166398,-0.648971518046783,-0.49967056104745,-0.658712826620156,-0.499670559743455,-0.653353925040627,-0.527410281291384,-0.654147819389496,0.0571450233388621,-0.411522165863231,0.0354646541911162,-0.523371002430799,-0.290536932328561,-0.320054405385567,-0.326704049629107,-0.428092085266572,-0.377417791479357,-0.916546774419919,-0.377417794834403,-0.930334685218653,-0.36638746465886,-0.930334685510815,-0.621923467459207,-0.916546766661881,-0.632953803133133,-0.930334678450214,1.75363550162122,-3.02221590654888,1.60599770634564,-3.02221590654888,1.60599770634564,-2.81342453415127,-1.66664008892994,-2.81342453415127,-1.81427788420554,-3.02221590654888,-0.366387249376787,-0.0456104129693274,-0.632953587851005,-0.0456103162416247,-1.75363550162123,0.147637795275608,1.81427788420553,0.147637795275596,-1.75363550162123,1.41180358981938e-14,1.81427788420553,1.08151223999339e-14,-0.499670495847728,-0.390767747643714,-0.47304036626804,-0.400509058732758,-0.471930776188928,-0.395332757604053,-0.499670497151723,-0.396126649223243,0.267551143124914,0.358822722823876,0.231384025824369,0.250785042942873,-0.0946175606953169,0.4541016399881,-0.116297929843051,0.342252803420526,-0.396144492568128,-0.559414949214236,-0.41056438802446,-0.589047120008855,-0.406851632304521,-0.591726571284168,-0.400285533846829,-0.558027962783353,0.392524587840632,-0.35868136624556,0.282726923558491,-0.328272920608075,0.468535292574503, +0.0080155315442505,0.35569720010301,0.0237561012701422,-0.47304042672701,-0.648971525155079,-0.551116021493864,-0.636122957716591,-0.572425426826127,-0.615683852019327,-0.588776706204198,-0.589047092163701,-0.599055546759175,-0.558027929381887,-0.602561462346642,-0.524740268539852,-0.396779602598687,-0.52474030572401,-0.400285517646898,-0.491452647397647,-0.599055530559241,-0.491452608964837,-0.588776674908328,-0.460433449897738,-0.572425382567084,-0.433796695951368,-0.448225037413856,-0.413357620904547,-0.55111596728783,-0.413357597955197,-0.526300630707425,-0.400509046593118,-0.030321191292154,-1.45585006204375,-0.386757813248307,-1.4089242905316,0.326115430663993,-1.40892429053159,-0.718903868457512,-1.27134488977522,0.658261485873197,-1.27134488977523,0.943481769570254,-1.05248766857545,-1.00412415215457,-1.05248766857544,1.16233899077004,-0.767267384878377,-1.22298137335434,-0.767267384878374,1.29991839152641,-0.435121329669174,-1.36056077411072,-0.435121329669174,-1.40748654562286,-0.0786847077130194,1.34684416303856,-0.0786847077130246,1.29991839152642,0.277751914243123,-1.36056077411072,0.277751914243125,1.16233899077004,0.609897969452331,-1.22298137335434,0.609897969452327,-1.00412415215456,0.895118253149398,0.94348176957026,0.895118253149387,0.658261485873198,1.11397547434917,-0.718903868457512,1.11397547434917,-0.386757813248303,1.25155487510554,0.326115430663995,1.25155487510554,-0.0303211912921522,1.29848064661768,-0.471930839167021,-0.654147826684783,0.26755114312491,-0.439558068181796,-0.0946175606953259,-0.534836985346024,0.23138402582436,-0.331520388300793,-0.116297929843059,-0.422988148778454,-0.527410218313287,-0.395332744849407,0.0571450233388582,0.330786820505271,-0.290536932328564,0.239319060027615,0.0354646541911151,0.442635657072843,-0.326704049629112,0.347356739908615,-0.553259527283181,-0.408716652478274,-0.575456834909413,-0.43000737954299,-0.209498968531409,0.265329523651123,-0.405888736284015,-0.0358019304110329,-0.3006306713544,0.333705055740337,-0.505203346096707,0.0200264577589196,-0.3961444756932, +-0.490065662463312,0.392524587840647,0.210200339694235,0.468535292574514,-0.156496558095575,0.282726923558503,0.179791894056756,0.35569720010302,-0.172237127821465,0.34081550997211,-0.418088491134936,0.237371640927581,-0.370343684035105,0.475060828690037,-0.0684852353075025,0.366247146896793,-0.0347245584407644,1.75363550162123,0.147637795275622,1.75363550162123,2.87960764453008e-14,1.60599770634564,0.147637795275621,-1.81427788420553,2.16351379364685e-14,-1.81427788420553,0.147637795275609,-0.575456881012582,-0.619473167332155,-0.592489463741748,-0.591726542467916,-0.510770492259207,-0.0426526122008331,-0.401956810465963,-0.00889193533409549,-0.376525173541287,-0.39225586802826,-0.273081304496757,-0.344511060928428,-0.592489431141883,-0.457753998251754,-0.603196572476889,-0.490065622319947,-0.500699202310804,-0.173529623256488,-0.424688497576919,0.193167274533323,-0.387861109839305,-0.189270192982385,-0.31489083329478,0.162758828895834,-0.392492480863015,-0.524740306498679,0.42753804412084,-0.297966306895264,0.314592129496402,-0.283019032309242,0.452157266572034,0.0757155577552859,0.338226583049545,0.0757155577552871,-0.5532595837478,-0.640763902418843,-0.209498968531425,-0.379702939305264,-0.30063067135442,-0.448078471394478,-0.405888736284044,-0.0785714852431028,-0.505203346096732,-0.134399873413059,-0.603196589351821,-0.559414914530228,-0.500699202310778,0.025048596705151,-0.387861109839281,0.0407891664310426,-0.4246884975769,-0.341648301084658,-0.31489083329476,-0.311239855447172,-0.10514513993176,0.317787376147238,-0.382093780437747,0.0885526841274505,-0.171863489726562,0.410139216673345,-0.460351656920293,0.171353079152738,0.40978707802387,-0.292578738312773,0.121298910830132,-0.531364875833373,0.33152920154132,-0.209778343287486,0.0545805610353308,-0.439013035307261,0.452157266572042,-0.232076902290214,0.338226583049552,-0.232076902290213,0.427538044120849,0.141604962360334,0.314592129496411,0.126657687774313,-0.446081475331125,-0.408716676572965,0.463447748362508,0.0502327523876388,0.364133138549816,-0.00559563578231725, +0.258875073620193,0.36391135036906,0.167743370797197,0.29553581827985,-0.606848584767135,-0.524740267765182,-0.458080953237842,-0.29204598116973,-0.482700175689028,0.0816358834808216,-0.3451350386134,-0.277098706583707,-0.368769492166538,0.0816358834808261,-0.105145139931775,-0.412235514345447,-0.171863489726573,-0.504587354871563,-0.382093780437765,-0.183000822325668,-0.460351656920315,-0.265801217350955,-0.458080953237851,0.135684636634823,-0.345135038613407,0.120737362048796,-0.482700175689038,-0.237997228015731,-0.368769492166548,-0.237997228015727,0.40978707802387,0.198130600114595,0.331529201541318,0.115330205089311,0.12129891083013,0.4369167376352,0.0545805610353312,0.344564897109089,-0.376525173541291,0.258518110284049,-0.273081304496759,0.210773303184219,-0.510770492259207,-0.0910851455433752,-0.401956810465964,-0.124845822410115,-0.377417582907374,-0.0593983197655316,-0.621923258887174,-0.0593982323246412,-0.0303211912921606,-1.51323195180752,0.340966956578835,-1.4643509398157,1.60599770634564,-4.27405872346105,0.686952430755086,-1.32103906402782,0.984056892939525,-1.09306279194472,1.21203316502263,-0.795958329760269,1.35534504081052,-0.449972855584014,1.40422605280234,-0.0786847077130257,1.60599770634564,4.90409088283815,1.35534504081052,0.292603440157961,1.21203316502264,0.638588914334216,0.984056892939535,0.935693376518658,0.686952430755089,1.16366964860176,0.340966956578833,1.30698152438964,-0.0303211912921566,1.35586253638145,-1.66664008892994,4.90409088283815,-1.46486843538664,-0.0786847077130239,-1.66664008892994,-4.27405872346105,-1.41598742339483,-0.449972855584014,-1.27267554760693,-0.795958329760266,-1.04469927552384,-1.09306279194471,-0.747594813339401,-1.32103906402781,-0.401609339163143,-1.46435093981571,-1.41598742339483,0.292603440157969,-1.27267554760693,0.638588914334223,-1.04469927552383,0.935693376518663,-0.747594813339395,1.16366964860176,-0.401609339163143,1.30698152438964,-0.0112955752098976,0.999998465489192,-0.990271707686746,0.00519753115635761,-0.00156738631786099,0.00519752318068924, +-0.999999999999997,0.999999999999994,1.81427788420554,-4.42169651873665,-1.75363550162122,-4.42169651873665,1.81427788420553,5.05172867811375,-1.75363550162123,5.05172867811375,-1.66664008892994,3.25892454641239,-1.81427788420552,3.46771591881,1.60599770634564,3.25892454641239,1.75363550162124,3.46771591881001,-0.366387252731832,-0.0593983237102328,1.13561186872702,5.05172867811375,1.13561186872701,4.90409088283816,0.926820496329405,4.90409088283815,1.135611868727,-4.42169651873665,0.926820496329396,-4.27405872346105,-1.17849250867969,5.05172867811374,-0.969701136282088,4.90409088283815,-1.17849250867969,-4.42169651873667,-0.96970113628208,-4.27405872346106,-5.60695479931297e-15,5.05172867811376,-2.16774330807621e-14,-4.42169651873664,-0.1476377952756,5.05172867811375,-0.147637795275615,-4.42169651873665,-0.147637795275601,4.90409088283816,1.49732912347996e-14,5.05172867811375,0.147637795275601,5.05172867811374,2.71857445056763e-14,-4.42169651873665,0.147637795275615,-4.42169651873667 + } + UVIndex: *720 { + a: 0,1,2,1,0,3,4,5,6,7,6,5,8,9,10,9,8,11,12,13,14,15,14,13,16,17,18,17,16,19,20,21,22,23,22,21,24,25,26,25,24,27,27,28,25,29,30,31,32,31,30,30,33,32,34,35,34,35,34,35,36,37,38,39,38,37,40,41,42,41,40,43,44,45,46,47,46,45,48,49,50,49,48,51,52,53,54,55,54,53,56,16,18,16,56,57,57,56,3,57,3,0,57,0,58,58,0,49,58,49,59,59,49,51,59,51,60,60,51,61,61,51,62,61,62,63,61,63,64,64,63,11,64,11,65,65,11,66,66,11,8,66,8,67,66,67,68,68,67,69,69,67,41,69,41,43,70,71,72,73,72,71,74,72,73,75,74,73,76,75,73,77,75,76,78,77,76,79,77,78,80,79,78,81,79,80,82,79,81,83,82,81,84,83,81,85,83,84,86,85,84,87,85,86,88,85,87,89,88,87,90,89,87,91,89,90,92,89,91,93,92,91,56,17,94,17,56,18,95,96,97,98,97,96,40,69,43,69,40,99,100,101,102,103,102,101,104,66,68,66,104,105,106,107,108,109,108,107,11,110,9,110,11,63,111,112,113,114,113,112,50,0,2,0,50,49,115,116,117,118,117,116,25,26,26,26,25,28,28,25,28,119,120,121,122,121,120,123,121,122,124,59,125,59,124,58,126,127,128,129,128,127,64,130,131,130,64,65,132,133,134,135,134,133,136,51,48,51,136,62,137,138,139,140,139,138,58,141,57,141,58,124,142,143,144,145,144,143,125,60,146,60,125,59,147,148,149,150,149,148,99,68,69,68,99,104,151,152,153,154,153,152,3,94,1,94,3,56,155,156,157,158,157,156,110,62,136,62,110,63,159,160,161,162,161,160,163,8,10,8,163,67,164,165,166,167,166,165,60,168,146,168,60,61,169,170,171,172,171,170,57,19,16,19,57,141,173,174,175,176,175,174,168,64,131,64,168,61,177,178,179,180,179,178,42,67,163,67,42,41,181,182,183,184,183,182,130,66,105,66,130,65,185,186,187,188,187,186,24,94,17,94,24,1,1,24,2,2,24,50,50,24,48,48,24,136,136,24,189,136,189,110,110,189,9,9,189,10,10,189,163,163,189,42,42,189,40,40,189,190,27,168,190,168,27,146,146,27,125,125,27,124,124,27,24,124,24,141,141,24,19,19,24,17,190,168,131,190,131,130,190,130,105,190,105,104,190,104,99,190,99,40,191,192,193,194,193,192,195,193,194,196,193,195,197,193,196,198,193,197,199,193,198,200,199,198,201,199,200,202,199,201,203,199,202,204,199,203,205,199,204,206,199,205,206,207,208,209,208,207,210,208,209,211,208, +210,193,208,211,212,193,211,213,193,212,191,193,213,214,207,206,215,214,206,216,215,206,217,216,206,218,217,206,205,218,206,219,220,221,220,219,222,223,224,225,226,225,224,189,35,190,35,189,34,227,228,229,230,229,228,189,231,34,231,189,26,26,189,24,232,233,234,235,234,233,236,234,235,28,190,35,190,28,27,237,238,239,240,239,238,34,26,34,26,34,26,26,34,231,241,242,243,244,243,242,245,243,244,28,35,35,35,28,28,246,247,248,249,248,247 + } + } + LayerElementMaterial: 0 { + Version: 101 + Name: "" + MappingInformationType: "ByPolygon" + ReferenceInformationType: "IndexToDirect" + Materials: *240 { + a: 0,0,1,1,0,0,1,1,0,0,1,1,0,0,0,1,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,0,1,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,1,1,0,0,1,1,0,0,0,1,1,1,0,0,1,1,0,0,0,1,1,1,0,0,1,1 + } + } + Layer: 0 { + Version: 100 + LayerElement: { + Type: "LayerElementNormal" + TypedIndex: 0 + } + LayerElement: { + Type: "LayerElementMaterial" + TypedIndex: 0 + } + LayerElement: { + Type: "LayerElementTexture" + TypedIndex: 0 + } + LayerElement: { + Type: "LayerElementUV" + TypedIndex: 0 + } + } + } + Model: 140224670541824, "Model::Model", "Null" { + Version: 232 + Properties70: { + P: "ScalingMax", "Vector3D", "Vector", "",0,0,0 + } + Shading: Y + Culling: "CullingOff" + } + Model: 140224668186624, "Model::Group1", "Null" { + Version: 232 + Properties70: { + P: "ScalingMax", "Vector3D", "Vector", "",0,0,0 + } + Shading: Y + Culling: "CullingOff" + } + Model: 140224679474176, "Model::Mesh1", "Mesh" { + Version: 232 + Properties70: { + P: "ScalingMax", "Vector3D", "Vector", "",0,0,0 + P: "DefaultAttributeIndex", "int", "Integer", "",0 + } + Shading: T + Culling: "CullingOff" + } + Model: 140224677109760, "Model::Mesh2", "Mesh" { + Version: 232 + Properties70: { + P: "ScalingMax", "Vector3D", "Vector", "",0,0,0 + P: "DefaultAttributeIndex", "int", "Integer", "",0 + } + Shading: T + Culling: "CullingOff" + } + Material: 140224776891456, "Material::hal9000eye", "" { + Version: 102 + ShadingModel: "phong" + MultiLayer: 0 + Properties70: { + P: "AmbientColor", "Color", "", "A",0,0,0 + P: "DiffuseColor", "Color", "", "A",0.352941176470588,0.0352941176470588,0.0235294117647059 + P: "TransparentColor", "Color", "", "A",1,1,1 + P: "SpecularColor", "Color", "", "A",0.33,0.33,0.33 + P: "ReflectionFactor", "Number", "", "A",0 + P: "Emissive", "Vector3D", "Vector", "",0,0,0 + P: "Ambient", "Vector3D", "Vector", "",0,0,0 + P: "Diffuse", "Vector3D", "Vector", "",0.352941176470588,0.0352941176470588,0.0235294117647059 + P: "Specular", "Vector3D", "Vector", "",0.33,0.33,0.33 + P: "Shininess", "double", "Number", "",20 + P: "Opacity", "double", "Number", "",1 + P: "Reflectivity", "double", "Number", "",0 + } + } + Material: 140224777082480, "Material::hal9000", "" { + Version: 102 + ShadingModel: "phong" + MultiLayer: 0 + Properties70: { + P: "AmbientColor", "Color", "", "A",0,0,0 + P: "DiffuseColor", "Color", "", "A",0.270588235294118,0.258823529411765,0.258823529411765 + P: "TransparentColor", "Color", "", "A",1,1,1 + P: "SpecularColor", "Color", "", "A",0.33,0.33,0.33 + P: "ReflectionFactor", "Number", "", "A",0 + P: "Emissive", "Vector3D", "Vector", "",0,0,0 + P: "Ambient", "Vector3D", "Vector", "",0,0,0 + P: "Diffuse", "Vector3D", "Vector", "",0.270588235294118,0.258823529411765,0.258823529411765 + P: "Specular", "Vector3D", "Vector", "",0.33,0.33,0.33 + P: "Shininess", "double", "Number", "",20 + P: "Opacity", "double", "Number", "",1 + P: "Reflectivity", "double", "Number", "",0 + } + } + Material: 140224767238928, "Material::BackColor", "" { + Version: 102 + ShadingModel: "phong" + MultiLayer: 0 + Properties70: { + P: "AmbientColor", "Color", "", "A",0,0,0 + P: "DiffuseColor", "Color", "", "A",0.643137254901961,0.698039215686274,0.733333333333333 + P: "TransparentColor", "Color", "", "A",1,1,1 + P: "SpecularColor", "Color", "", "A",0.33,0.33,0.33 + P: "ReflectionFactor", "Number", "", "A",0 + P: "Emissive", "Vector3D", "Vector", "",0,0,0 + P: "Ambient", "Vector3D", "Vector", "",0,0,0 + P: "Diffuse", "Vector3D", "Vector", "",0.643137254901961,0.698039215686274,0.733333333333333 + P: "Specular", "Vector3D", "Vector", "",0.33,0.33,0.33 + P: "Shininess", "double", "Number", "",20 + P: "Opacity", "double", "Number", "",1 + P: "Reflectivity", "double", "Number", "",0 + } + } + Material: 140224778006800, "Material::kal9000back", "" { + Version: 102 + ShadingModel: "phong" + MultiLayer: 0 + Properties70: { + P: "AmbientColor", "Color", "", "A",0,0,0 + P: "DiffuseColor", "Color", "", "A",0.552941176470588,0.494117647058824,0.419607843137255 + P: "TransparentColor", "Color", "", "A",1,1,1 + P: "SpecularColor", "Color", "", "A",0.33,0.33,0.33 + P: "ReflectionFactor", "Number", "", "A",0 + P: "Emissive", "Vector3D", "Vector", "",0,0,0 + P: "Ambient", "Vector3D", "Vector", "",0,0,0 + P: "Diffuse", "Vector3D", "Vector", "",0.552941176470588,0.494117647058824,0.419607843137255 + P: "Specular", "Vector3D", "Vector", "",0.33,0.33,0.33 + P: "Shininess", "double", "Number", "",20 + P: "Opacity", "double", "Number", "",1 + P: "Reflectivity", "double", "Number", "",0 + } + } + Video: 140224776855024, "Video::hal9000eye_texture", "Clip" { + Type: "Clip" + Properties70: { + P: "Path", "KString", "XRefUrl", "", "hal9000/hal9000eye.tif" + } + UseMipMap: 0 + Filename: "hal9000/hal9000eye.tif" + RelativeFilename: "../../../../../hal9000eye.tif" + } + Video: 140224767508192, "Video::hal9000_texture", "Clip" { + Type: "Clip" + Properties70: { + P: "Path", "KString", "XRefUrl", "", "hal9000/hal9000.jpg" + } + UseMipMap: 0 + Filename: "hal9000/hal9000.jpg" + RelativeFilename: "../../../../../hal9000.jpg" + } + Video: 140224767509568, "Video::kal9000back_texture", "Clip" { + Type: "Clip" + Properties70: { + P: "Path", "KString", "XRefUrl", "", "hal9000/kal9000back.jpg" + } + UseMipMap: 0 + Filename: "hal9000/kal9000back.jpg" + RelativeFilename: "../../../../../kal9000back.jpg" + } + Texture: 140224777059744, "Texture::hal9000eye_texture", "" { + Type: "TextureVideoClip" + Version: 202 + TextureName: "Texture::hal9000eye_texture" + Media: "Video::hal9000eye_texture" + FileName: "hal9000/hal9000eye.tif" + RelativeFilename: "../../../../../hal9000eye.tif" + ModelUVTranslation: 0,0 + ModelUVScaling: 1,1 + Texture_Alpha_Source: "None" + Cropping: 0,0,0,0 + } + Texture: 140224768121392, "Texture::hal9000_texture", "" { + Type: "TextureVideoClip" + Version: 202 + TextureName: "Texture::hal9000_texture" + Media: "Video::hal9000_texture" + FileName: "hal9000/hal9000.jpg" + RelativeFilename: "../../../../../hal9000.jpg" + ModelUVTranslation: 0,0 + ModelUVScaling: 1,1 + Texture_Alpha_Source: "None" + Cropping: 0,0,0,0 + } + Texture: 140224777846736, "Texture::kal9000back_texture", "" { + Type: "TextureVideoClip" + Version: 202 + TextureName: "Texture::kal9000back_texture" + Media: "Video::kal9000back_texture" + FileName: "hal9000/kal9000back.jpg" + RelativeFilename: "../../../../../kal9000back.jpg" + ModelUVTranslation: 0,0 + ModelUVScaling: 1,1 + Texture_Alpha_Source: "None" + Cropping: 0,0,0,0 + } +} + +; Object connections +;------------------------------------------------------------------ + +Connections: { + + ;Model::Model, Model::RootNode + C: "OO",140224670541824,0 + + ;Model::Group1, Model::Model + C: "OO",140224668186624,140224670541824 + + ;Model::Mesh2, Model::Model + C: "OO",140224677109760,140224670541824 + + ;Model::Mesh1, Model::Group1 + C: "OO",140224679474176,140224668186624 + + ;Geometry::, Model::Mesh1 + C: "OO",140224778099776,140224679474176 + + ;Material::hal9000eye, Model::Mesh1 + C: "OO",140224776891456,140224679474176 + + ;Texture::hal9000eye_texture, Model::Mesh1 + C: "OO",140224777059744,140224679474176 + + ;Video::hal9000eye_texture, Texture::hal9000eye_texture + C: "OO",140224776855024,140224777059744 + + ;Texture::hal9000eye_texture, Material::hal9000eye + C: "OP",140224777059744,140224776891456, "DiffuseColor" + + ;Geometry::, Model::Mesh2 + C: "OO",140224764960032,140224677109760 + + ;Material::hal9000, Model::Mesh2 + C: "OO",140224777082480,140224677109760 + + ;Material::BackColor, Model::Mesh2 + C: "OO",140224767238928,140224677109760 + + ;Material::kal9000back, Model::Mesh2 + C: "OO",140224778006800,140224677109760 + + ;Texture::hal9000_texture, Model::Mesh2 + C: "OO",140224768121392,140224677109760 + + ;Texture::kal9000back_texture, Model::Mesh2 + C: "OO",140224777846736,140224677109760 + + ;Video::hal9000_texture, Texture::hal9000_texture + C: "OO",140224767508192,140224768121392 + + ;Video::kal9000back_texture, Texture::kal9000back_texture + C: "OO",140224767509568,140224777846736 + + ;Texture::hal9000_texture, Material::hal9000 + C: "OP",140224768121392,140224777082480, "DiffuseColor" + + ;Texture::kal9000back_texture, Material::kal9000back + C: "OP",140224777846736,140224778006800, "DiffuseColor" +} +;Takes section +;---------------------------------------------------- + +Takes: { + Current: "" +} diff --git a/src/parts source/kOSkal9000/KAL-9000 meshes/hal9000/hal9000.jpg b/src/parts source/kOSkal9000/KAL-9000 meshes/hal9000/hal9000.jpg new file mode 100644 index 000000000..1f21e21b5 Binary files /dev/null and b/src/parts source/kOSkal9000/KAL-9000 meshes/hal9000/hal9000.jpg differ diff --git a/src/parts source/kOSkal9000/KAL-9000 meshes/hal9000/hal9000eye.tif b/src/parts source/kOSkal9000/KAL-9000 meshes/hal9000/hal9000eye.tif new file mode 100644 index 000000000..ba7d442fa Binary files /dev/null and b/src/parts source/kOSkal9000/KAL-9000 meshes/hal9000/hal9000eye.tif differ diff --git a/src/parts source/kOSkal9000/KAL-9000 meshes/hal9000/kal9000back.jpg b/src/parts source/kOSkal9000/KAL-9000 meshes/hal9000/kal9000back.jpg new file mode 100644 index 000000000..966f59831 Binary files /dev/null and b/src/parts source/kOSkal9000/KAL-9000 meshes/hal9000/kal9000back.jpg differ diff --git a/src/parts source/kOSkal9000/KAL-9000 meshes/hal9000/kal9000backTEXTURE.jpg b/src/parts source/kOSkal9000/KAL-9000 meshes/hal9000/kal9000backTEXTURE.jpg new file mode 100644 index 000000000..dd78ce8cf Binary files /dev/null and b/src/parts source/kOSkal9000/KAL-9000 meshes/hal9000/kal9000backTEXTURE.jpg differ diff --git a/src/parts source/kOSkal9000/KAL-9000 meshes/materials/hal9000.jpg b/src/parts source/kOSkal9000/KAL-9000 meshes/materials/hal9000.jpg new file mode 100644 index 000000000..1f21e21b5 Binary files /dev/null and b/src/parts source/kOSkal9000/KAL-9000 meshes/materials/hal9000.jpg differ diff --git a/src/parts source/kOSkal9000/KAL-9000 meshes/materials/hal9000eye.tif b/src/parts source/kOSkal9000/KAL-9000 meshes/materials/hal9000eye.tif new file mode 100644 index 000000000..ba7d442fa Binary files /dev/null and b/src/parts source/kOSkal9000/KAL-9000 meshes/materials/hal9000eye.tif differ diff --git a/src/parts source/kOSkal9000/KAL-9000 meshes/materials/kal9000back.jpg b/src/parts source/kOSkal9000/KAL-9000 meshes/materials/kal9000back.jpg new file mode 100644 index 000000000..966f59831 Binary files /dev/null and b/src/parts source/kOSkal9000/KAL-9000 meshes/materials/kal9000back.jpg differ diff --git a/src/sound_sources/README.md b/src/sound_sources/README.md new file mode 100644 index 000000000..5a616ce81 --- /dev/null +++ b/src/sound_sources/README.md @@ -0,0 +1,34 @@ +Sound Sources +------------- + +These files are the sound effects in the terminal window +(and perhaps more later?). + +In keeping with the idea that every *source* from which the final +product is made should be in github, these are the configurations +in the Audacity editor that were used to export the WAV files used. + +The program *Audacity* is free and can be downloaded for Windows, +Mac, or Linux. + +They are not part of the automated build system, so you will have +to manually export new WAV files if you change them. To export +a WAV file, run Audacity, open one of the ``*.aup`` files here, +and choose File|Export. + +Files so far: + +*terminal-click*: A very short "pop" sound that only lasts 1/100th of +a second, so it can be used with fast typing for the keyclick feature. + +*terminal-beep*: The sound for the BEL character in the GUI terminal. +It's a single-tone basic simple square waveform to simulate primitive +sound output on early comptuers. + +*error*: The sound warning the user that a KOSException happens. It is +NOT part of the GUI terminal because it can fire off even when the +terminal is closed. It just fires for any KOSException. If you hear it +when you weren't expecting it, you might want to go have a look at the +log file. The error sound is just a square waveform that starts high +pitched and then drops to a lower, near-raspberry pitch halfway through. + diff --git a/src/sound_sources/error.aup b/src/sound_sources/error.aup new file mode 100644 index 000000000..58a3cdeed --- /dev/null +++ b/src/sound_sources/error.aup @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/sound_sources/error_data/e00/d00/e0000929.au b/src/sound_sources/error_data/e00/d00/e0000929.au new file mode 100644 index 000000000..3eb2667d5 Binary files /dev/null and b/src/sound_sources/error_data/e00/d00/e0000929.au differ diff --git a/src/sound_sources/error_data/e00/d00/e0000c1f.au b/src/sound_sources/error_data/e00/d00/e0000c1f.au new file mode 100644 index 000000000..1ec76d734 Binary files /dev/null and b/src/sound_sources/error_data/e00/d00/e0000c1f.au differ diff --git a/src/sound_sources/error_data/e00/d00/e0000c97.au b/src/sound_sources/error_data/e00/d00/e0000c97.au new file mode 100644 index 000000000..d80ffcc52 Binary files /dev/null and b/src/sound_sources/error_data/e00/d00/e0000c97.au differ diff --git a/src/sound_sources/terminal-beep.aup b/src/sound_sources/terminal-beep.aup new file mode 100644 index 000000000..457535ac1 --- /dev/null +++ b/src/sound_sources/terminal-beep.aup @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/src/sound_sources/terminal-beep_data/e00/d00/e0000ec1.au b/src/sound_sources/terminal-beep_data/e00/d00/e0000ec1.au new file mode 100644 index 000000000..62dc9825f Binary files /dev/null and b/src/sound_sources/terminal-beep_data/e00/d00/e0000ec1.au differ diff --git a/src/sound_sources/terminal-click.aup b/src/sound_sources/terminal-click.aup new file mode 100644 index 000000000..9efad847f --- /dev/null +++ b/src/sound_sources/terminal-click.aup @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/src/sound_sources/terminal-click_data/e00/d00/e00008b2.au b/src/sound_sources/terminal-click_data/e00/d00/e00008b2.au new file mode 100644 index 000000000..d43602c27 Binary files /dev/null and b/src/sound_sources/terminal-click_data/e00/d00/e00008b2.au differ