diff --git a/.docker/default.conf b/.docker/default.conf
new file mode 100644
index 00000000..9d3a7b22
--- /dev/null
+++ b/.docker/default.conf
@@ -0,0 +1,21 @@
+server {
+ listen 80;
+ listen [::]:80;
+ server_name localhost;
+
+ location / {
+ root /usr/share/nginx/html;
+ index index.html;
+ add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; font-src data: 'self'";
+ add_header X-XSS-Protection "1; mode=block";
+ add_header X-Frame-Options "DENY";
+ add_header X-Content-Type-Options nosniff;
+ add_header Referrer-Policy "strict-origin";
+ }
+
+ error_page 500 502 503 504 /50x.html;
+ location = /50x.html {
+ root /usr/share/nginx/html;
+ }
+
+}
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
index b027f814..f01a2390 100644
--- a/.github/FUNDING.yml
+++ b/.github/FUNDING.yml
@@ -1,3 +1,3 @@
# These are supported funding model platforms
-
+github: Azgaar
patreon: Azgaar
diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
new file mode 100644
index 00000000..d4407a32
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -0,0 +1,33 @@
+---
+name: Bug report
+about: Report a problem
+title: ''
+labels: pending review
+assignees: Azgaar
+
+---
+
+
+**Describe the bug**
+
+
+**Steps to reproduce**
+
+1. Click on ...
+2. Type ...
+3. See the ...
+
+**Expected behavior**
+
+
+**.map file**
+
+
+**Screenshots**
+
+
+**System**
+
+ - Version: ...
+ - Browser: ...
+ - OS: ...
diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md
new file mode 100644
index 00000000..29ab55e2
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/feature_request.md
@@ -0,0 +1,19 @@
+---
+name: Feature request
+about: Suggest an idea
+title: ''
+labels: pending review
+assignees: Azgaar
+
+---
+
+<-- BEFORE CREATING PLEASE CHECK THE TO-DO LIST-->
+<-- https://trello.com/b/7x832DG4/fantasy-map-generator ->>
+**Problem**
+<-- Is your feature request related to a problem? Please describe. Ex.: I'm always frustrated when ... -->
+
+**Solution**
+<-- A clear and concise description of what you want to happen and ideas on how it can be implemented. Screenshots are welcomed -->
+
+**Alternatives**
+<-- A clear and concise description of any alternative solutions or features you've considered -->
diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md
new file mode 100644
index 00000000..698d23ae
--- /dev/null
+++ b/.github/copilot-instructions.md
@@ -0,0 +1,89 @@
+# Fantasy Map Generator
+
+Azgaar's Fantasy Map Generator is a client-side JavaScript web application for creating fantasy maps. It generates detailed fantasy worlds with countries, cities, rivers, biomes, and cultural elements.
+
+Always reference these instructions first and fallback to search or bash commands only when you encounter unexpected information that does not match the info here.
+
+## Working Effectively
+
+- **CRITICAL**: This is a static web application - NO build process needed. No npm install, no compilation, no bundling.
+- Run the application using HTTP server (required - cannot run with file:// protocol):
+ - `python3 -m http.server 8000` - takes 2-3 seconds to start
+- Access at: `http://localhost:8000`
+
+## Validation
+
+- Always manually validate any changes by:
+ 1. Starting the HTTP server (NEVER CANCEL - wait for full startup)
+ 2. Navigate to the application in browser
+ 3. Click the "►" button to open the menu and generate a new map
+ 4. **CRITICAL VALIDATION**: Verify the map generates with countries, cities, roads, and geographic features
+ 5. Test UI interaction: click "Layers" button, verify layer controls work
+ 6. Test regeneration: click "New Map!" button, verify new map generates correctly
+- **Known Issues**: Google Analytics and font loading errors are normal (blocked external resources)
+
+## Repository Structure
+
+### Core Files
+
+- `index.html` - Main application entry point
+- `main.js` - Core application logic
+- `versioning.js` - Version management and update handling
+
+### Key Directories
+
+- `modules/` - core functionality modules:
+ - `modules/ui/` - UI components (editors, tools, style management)
+ - `modules/dynamic/` - runtime modules (export, installation)
+ - `modules/renderers/` - drawing and rendering logic
+- `utils/` - utility libraries (math, arrays, strings, etc.)
+- `styles/` - visual style presets (JSON files)
+- `libs/` - Third-party libraries (D3.js, TinyMCE, etc.)
+- `images/` - backgrounds, UI elements
+- `charges/` - heraldic symbols and coat of arms elements
+- `config/` - Heightmap templates and configurations
+- `heightmaps/` - Terrain generation data
+
+## Common Tasks
+
+### Making Code Changes
+
+1. Edit JavaScript files directly (no compilation needed)
+2. Refresh browser to see changes immediately
+3. **ALWAYS test map generation** after making changes
+4. Update version in `versioning.js` for all changes
+5. Update file hashes in `index.html` for changed files (format: `file.js?v=1.108.1`)
+
+### Debugging Map Generation
+
+- Open browser developer tools console
+- Look for timing logs, e.g. "TOTAL: ~0.76s"
+- Map generation logs show each step (heightmap, rivers, states, etc.)
+- Error messages will indicate specific generation failures
+
+### Testing Different Map Types
+
+- Use "New Map!" button for quick regeneration
+- Access "Layers" menu to change map visualization
+- Available presets: Political, Cultural, Religions, Biomes, Heightmap, Physical, Military
+
+## Troubleshooting
+
+### Application Won't Load
+
+- Ensure using HTTP server (not file://)
+- Check console for JavaScript errors
+- Verify all files are present in repository
+
+### Map Generation Fails
+
+- Check browser console for error messages
+- Look for specific module failures in generation logs
+- Try refreshing page and generating new map
+
+### Performance Issues
+
+- Map generation should complete in ~1 second for standard configurations
+- If slower, check browser console for errors
+
+Remember: This is a sophisticated client-side application that generates complete fantasy worlds with political systems, geography, cultures, and detailed cartographic elements. Always validate that your changes preserve the core map generation functionality.
diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
new file mode 100644
index 00000000..acedeb18
--- /dev/null
+++ b/.github/pull_request_template.md
@@ -0,0 +1,23 @@
+# Description
+
+
+
+# Type of change
+
+
+
+- [ ] Bug fix
+- [ ] New feature
+- [ ] Refactoring / style
+- [ ] Documentation update / chore
+- [ ] Other (please describe)
+
+# Versioning
+
+
+
+- [ ] Version is updated
+- [ ] Changed files hash is updated
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 00000000..b0a273f0
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,5 @@
+.vscode
+.idea
+/node_modules
+/dist
+/coverage
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
new file mode 100644
index 00000000..23cfdd81
--- /dev/null
+++ b/CODE_OF_CONDUCT.md
@@ -0,0 +1,108 @@
+# Contributor Code of Conduct
+
+We as members, contributors, and leaders agree to make participation in our
+community a harassment-free experience for everyone, regardless of age, body
+size, visible or invisible disability, ethnicity, sex characteristics, gender
+identity and expression, level of experience, education, socio-economic status,
+nationality, personal appearance, race, religion, or sexual identity
+and orientation.
+
+## Our Standards
+
+Examples of behavior that contributes to a positive environment for our
+community include:
+
+* Demonstrating empathy and kindness toward other people
+* Being respectful of differing opinions, viewpoints, and experiences
+* Giving and gracefully accepting constructive feedback
+* Accepting responsibility and apologizing to those affected by our mistakes,
+ and learning from the experience
+* Focusing on what is best not just for us as individuals, but for the
+ overall community
+
+Examples of unacceptable behavior include:
+
+* Vocal support of agressive behaviour, agressive communities or countries
+* The use of sexualized language or imagery, and sexual attention or
+ advances of any kind
+* Trolling, insulting or derogatory comments, and personal or political attacks
+* Public or private harassment
+* Publishing others' private information, such as a physical or email
+ address, without their explicit permission
+* Other conduct which could reasonably be considered inappropriate in a
+ professional setting
+
+## Enforcement Responsibilities
+
+Community leaders are responsible for clarifying and enforcing our standards of
+acceptable behavior and will take appropriate and fair corrective action in
+response to any behavior that they deem inappropriate, threatening, offensive,
+or harmful.
+
+Community leaders have the right and responsibility to remove, edit, or reject
+comments, commits, code, wiki edits, issues, and other contributions that are
+not aligned to this Code of Conduct, and will communicate reasons for moderation
+decisions when appropriate.
+
+## Scope
+
+This Code of Conduct applies within all community spaces, and also applies when
+an individual is officially representing the community in public spaces.
+Examples of representing our community include using an official e-mail address,
+posting via an official social media account, or acting as an appointed
+representative at an online or offline event.
+
+## Enforcement
+
+Instances of abusive, harassing, or otherwise unacceptable behavior may be
+reported to the community leaders responsible for enforcement at
+azgaar.fmg@yandex.com.
+All complaints will be reviewed and investigated promptly and fairly.
+
+All community leaders are obligated to respect the privacy and security of the
+reporter of any incident.
+
+## Enforcement Guidelines
+
+Community leaders will follow these Community Impact Guidelines in determining
+the consequences for any action they deem in violation of this Code of Conduct:
+
+### 1. Warning
+
+**Community Impact**: A violation through a single incident or series
+of actions.
+
+**Consequence**: A warning with consequences for continued behavior. No
+interaction with the people involved, including unsolicited interaction with
+those enforcing the Code of Conduct, for a specified period of time. This
+includes avoiding interactions in community spaces as well as external channels
+like social media. Violating these terms may lead to a temporary or
+permanent ban.
+
+### 2. Temporary Ban
+
+**Community Impact**: A serious violation of community standards, including
+sustained inappropriate behavior.
+
+**Consequence**: A temporary ban from any sort of interaction or public
+communication with the community for a specified period of time. No public or
+private interaction with the people involved, including unsolicited interaction
+with those enforcing the Code of Conduct, is allowed during this period.
+Violating these terms may lead to a permanent ban.
+
+### 3. Permanent Ban
+
+**Community Impact**: Demonstrating a pattern of violation of community
+standards, including sustained inappropriate behavior, harassment of an
+individual, or aggression toward or disparagement of classes of individuals.
+
+**Consequence**: A permanent ban from any sort of public interaction within
+the community.
+
+## Attribution
+
+This Code of Conduct is based on [Contributor Covenant](https://www.contributor-covenant.org/version/2/0/code_of_conduct.html),
+version 2.0.
+
+Community Impact Guidelines were inspired by [Mozilla's code of conduct
+enforcement ladder](https://github.com/mozilla/diversity).
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 00000000..fbf5a425
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,7 @@
+FROM nginx:stable-alpine
+
+# Copy the contents of the repo to the container
+COPY . /usr/share/nginx/html
+
+# Move the customized nginx config file to the nginx folder
+RUN mv /usr/share/nginx/html/.docker/default.conf /etc/nginx/conf.d/default.conf
diff --git a/Fantasy Map Generator.lnk b/Fantasy Map Generator.lnk
deleted file mode 100644
index 1e1f2012..00000000
Binary files a/Fantasy Map Generator.lnk and /dev/null differ
diff --git a/LICENSE b/LICENSE
index 19e4e777..4b0e677e 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
MIT License
-Copyright 2018-2019 Max Ganiev (Azgaar), azgaar.fmg@yandex.by
+Copyright 2017-2024 Max Haniyeu (Azgaar), azgaar.fmg@yandex.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@@ -12,8 +12,9 @@ furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
-You can produce, without restrictions, any derivative works from the original
+You can produce, without restrictions, any derivative works from the original
software and even reap commercial benefits from the sale of the secondary product.
+The derivates include created maps, map images, screenshots, videos, and other materials.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
@@ -21,4 +22,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
\ No newline at end of file
+SOFTWARE.
diff --git a/README.md b/README.md
index d5fe4479..3ab245b2 100644
--- a/README.md
+++ b/README.md
@@ -1,25 +1,29 @@
# Fantasy Map Generator
-Azgaar's _Fantasy Map Generator_. Online tool generating interactive and highly customizable svg maps based on voronoi diagram.
+Azgaar's _Fantasy Map Generator_ is a free web application that helps fantasy writers, game masters, and cartographers create and edit fantasy maps.
-Project is under development, check out the current version [here](https://azgaar.github.io/Fantasy-Map-Generator). You can also try an Electron desktop application - download [an archive](https://github.com/Azgaar/Fantasy-Map-Generator/releases) for your architecture, unzip and run the _Azgaar's Fantasy Map Generator.exe_.
+Link: [azgaar.github.io/Fantasy-Map-Generator](https://azgaar.github.io/Fantasy-Map-Generator).
-Refer to the [project wiki](https://github.com/Azgaar/Fantasy-Map-Generator/wiki) for a guidance. Some details are covered in my blog [_Fantasy Maps for fun and glory_](https://azgaar.wordpress.com), you may also keep an eye on my [Trello devboard](https://trello.com/b/7x832DG4/fantasy-map-generator).
+Refer to the [project wiki](https://github.com/Azgaar/Fantasy-Map-Generator/wiki) for guidance. The current progress is tracked in [Trello](https://trello.com/b/7x832DG4/fantasy-map-generator). Some details are covered in my old blog [_Fantasy Maps for fun and glory_](https://azgaar.wordpress.com).
-[](https://i.redd.it/8bf81ir2cy631.png)
+[](https://github.com/Azgaar/Fantasy-Map-Generator/assets/26469650/11a42446-4bd5-4526-9cb1-3ef97c868992)
-[](https://cdn.discordapp.com/attachments/515359185664344071/593888810782162964/The_Wichin_Island_sepia.png)
+[](https://github.com/Azgaar/Fantasy-Map-Generator/assets/26469650/e751a9e5-7986-4638-b8a9-362395ef7583)
-[](https://cdn.discordapp.com/attachments/515359096925454350/593891237984206848/The_Wichin_Island_-_diplomacy.png)
+[](https://github.com/Azgaar/Fantasy-Map-Generator/assets/26469650/b0d0efde-a0d1-4e80-8818-ea3dd83c2323)
-Join our [Reddit community](https://www.reddit.com/r/FantasyMapGenerator) and [Discord server](https://discordapp.com/invite/X7E84HU) to share the created maps, discuss the Generator, suggest ideas and get a most recent updates. You may also contact me directly via [email](mailto:azgaar.fmg@yandex.by). For bug reports please use the project [issues page](https://github.com/Azgaar/Fantasy-Map-Generator/issues) or Discord "Bugs" channel. If you are facing performance issues, please read [the tips](https://github.com/Azgaar/Fantasy-Map-Generator/wiki/Tips#performance-tips).
+Join our [Discord server](https://discordapp.com/invite/X7E84HU) and [Reddit community](https://www.reddit.com/r/FantasyMapGenerator) to share your creations, discuss the Generator, suggest ideas and get the most recent updates.
-You can support the project [on Patreon](https://www.patreon.com/azgaar).
+Contact me via [email](mailto:azgaar.fmg@yandex.com) if you have non-public suggestions. For bug reports please use [GitHub issues](https://github.com/Azgaar/Fantasy-Map-Generator/issues) or _#fmg-bugs_ channel on Discord. If you are facing performance issues, please read [the tips](https://github.com/Azgaar/Fantasy-Map-Generator/wiki/Tips#performance-tips).
+
+Pull requests are highly welcomed. The codebase is messy and requires re-design. I will appreciate if you start with minor changes. Check out the [data model](https://github.com/Azgaar/Fantasy-Map-Generator/wiki/Data-model) before contributing.
+
+You can support the project on [Patreon](https://www.patreon.com/azgaar).
_Inspiration:_
-* Martin O'Leary's [_Generating fantasy maps_](https://mewo2.com/notes/terrain)
+- Martin O'Leary's [_Generating fantasy maps_](https://mewo2.com/notes/terrain)
-* Amit Patel's [_Polygonal Map Generation for Games_](http://www-cs-students.stanford.edu/~amitp/game-programming/polygon-map-generation)
+- Amit Patel's [_Polygonal Map Generation for Games_](http://www-cs-students.stanford.edu/~amitp/game-programming/polygon-map-generation)
-* Scott Turner's [_Here Dragons Abound_](https://heredragonsabound.blogspot.com)
+- Scott Turner's [_Here Dragons Abound_](https://heredragonsabound.blogspot.com)
diff --git a/Readme.txt b/Readme.txt
deleted file mode 100644
index 6760d7eb..00000000
--- a/Readme.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-Azgaar's Fantasy Map Generator
-This is an open-source software available under MIT license
-https://github.com/Azgaar/Fantasy-Map-Generator
-
-To run the tool unzip ALL files and open index.html in browser
\ No newline at end of file
diff --git a/_config.yml b/_config.yml
deleted file mode 100644
index c7418817..00000000
--- a/_config.yml
+++ /dev/null
@@ -1 +0,0 @@
-theme: jekyll-theme-slate
\ No newline at end of file
diff --git a/charges/agnusDei.svg b/charges/agnusDei.svg
new file mode 100644
index 00000000..60ea9d87
--- /dev/null
+++ b/charges/agnusDei.svg
@@ -0,0 +1,132 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/anchor.svg b/charges/anchor.svg
new file mode 100644
index 00000000..59678314
--- /dev/null
+++ b/charges/anchor.svg
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/charges/angel.svg b/charges/angel.svg
new file mode 100644
index 00000000..e6f3ba3e
--- /dev/null
+++ b/charges/angel.svg
@@ -0,0 +1,227 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/annulet.svg b/charges/annulet.svg
new file mode 100644
index 00000000..b3dad13d
--- /dev/null
+++ b/charges/annulet.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/charges/anvil.svg b/charges/anvil.svg
new file mode 100644
index 00000000..2b6b0868
--- /dev/null
+++ b/charges/anvil.svg
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/charges/apple.svg b/charges/apple.svg
new file mode 100644
index 00000000..6679428d
--- /dev/null
+++ b/charges/apple.svg
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/charges/arbalest.svg b/charges/arbalest.svg
new file mode 100644
index 00000000..38adac50
--- /dev/null
+++ b/charges/arbalest.svg
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/arbalest2.svg b/charges/arbalest2.svg
new file mode 100644
index 00000000..be9b1a6a
--- /dev/null
+++ b/charges/arbalest2.svg
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/archer.svg b/charges/archer.svg
new file mode 100644
index 00000000..00891c1b
--- /dev/null
+++ b/charges/archer.svg
@@ -0,0 +1,68 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/armEmbowedHoldingSabre.svg b/charges/armEmbowedHoldingSabre.svg
new file mode 100644
index 00000000..2fbae9f6
--- /dev/null
+++ b/charges/armEmbowedHoldingSabre.svg
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/armEmbowedVambraced.svg b/charges/armEmbowedVambraced.svg
new file mode 100644
index 00000000..ac1422b5
--- /dev/null
+++ b/charges/armEmbowedVambraced.svg
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/armEmbowedVambracedHoldingSword.svg b/charges/armEmbowedVambracedHoldingSword.svg
new file mode 100644
index 00000000..d00d8bab
--- /dev/null
+++ b/charges/armEmbowedVambracedHoldingSword.svg
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/armillarySphere.svg b/charges/armillarySphere.svg
new file mode 100644
index 00000000..45d09b8d
--- /dev/null
+++ b/charges/armillarySphere.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/charges/arrow.svg b/charges/arrow.svg
new file mode 100644
index 00000000..2135169f
--- /dev/null
+++ b/charges/arrow.svg
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/arrowsSheaf.svg b/charges/arrowsSheaf.svg
new file mode 100644
index 00000000..4b879e10
--- /dev/null
+++ b/charges/arrowsSheaf.svg
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/attire.svg b/charges/attire.svg
new file mode 100644
index 00000000..99427a60
--- /dev/null
+++ b/charges/attire.svg
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/axe.svg b/charges/axe.svg
new file mode 100644
index 00000000..e1608145
--- /dev/null
+++ b/charges/axe.svg
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/badgerStatant.svg b/charges/badgerStatant.svg
new file mode 100644
index 00000000..29cd5f39
--- /dev/null
+++ b/charges/badgerStatant.svg
@@ -0,0 +1,62 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/banner.svg b/charges/banner.svg
new file mode 100644
index 00000000..8ca47b97
--- /dev/null
+++ b/charges/banner.svg
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/basilisk.svg b/charges/basilisk.svg
new file mode 100644
index 00000000..b2755dff
--- /dev/null
+++ b/charges/basilisk.svg
@@ -0,0 +1,220 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/bearPassant.svg b/charges/bearPassant.svg
new file mode 100644
index 00000000..847ea7bd
--- /dev/null
+++ b/charges/bearPassant.svg
@@ -0,0 +1,142 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/bearRampant.svg b/charges/bearRampant.svg
new file mode 100644
index 00000000..418d6fb3
--- /dev/null
+++ b/charges/bearRampant.svg
@@ -0,0 +1,129 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/bee.svg b/charges/bee.svg
new file mode 100644
index 00000000..7f3a0069
--- /dev/null
+++ b/charges/bee.svg
@@ -0,0 +1,116 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/bell.svg b/charges/bell.svg
new file mode 100644
index 00000000..307b6493
--- /dev/null
+++ b/charges/bell.svg
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/billet.svg b/charges/billet.svg
new file mode 100644
index 00000000..9482f5a7
--- /dev/null
+++ b/charges/billet.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/charges/boarHeadErased.svg b/charges/boarHeadErased.svg
new file mode 100644
index 00000000..08348586
--- /dev/null
+++ b/charges/boarHeadErased.svg
@@ -0,0 +1,44 @@
+
+
+
+
diff --git a/charges/boarRampant.svg b/charges/boarRampant.svg
new file mode 100644
index 00000000..436fb439
--- /dev/null
+++ b/charges/boarRampant.svg
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/boat.svg b/charges/boat.svg
new file mode 100644
index 00000000..b50f6194
--- /dev/null
+++ b/charges/boat.svg
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/boat2.svg b/charges/boat2.svg
new file mode 100644
index 00000000..f3e37a5b
--- /dev/null
+++ b/charges/boat2.svg
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/bone.svg b/charges/bone.svg
new file mode 100644
index 00000000..27a9e410
--- /dev/null
+++ b/charges/bone.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/charges/bookClosed.svg b/charges/bookClosed.svg
new file mode 100644
index 00000000..0cd74341
--- /dev/null
+++ b/charges/bookClosed.svg
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/bookClosed2.svg b/charges/bookClosed2.svg
new file mode 100644
index 00000000..bf8d2519
--- /dev/null
+++ b/charges/bookClosed2.svg
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/bookOpen.svg b/charges/bookOpen.svg
new file mode 100644
index 00000000..62f1c6fc
--- /dev/null
+++ b/charges/bookOpen.svg
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/bow.svg b/charges/bow.svg
new file mode 100644
index 00000000..b1f2c8ec
--- /dev/null
+++ b/charges/bow.svg
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/charges/bowWithArrow.svg b/charges/bowWithArrow.svg
new file mode 100644
index 00000000..12d7f9ff
--- /dev/null
+++ b/charges/bowWithArrow.svg
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/bowWithThreeArrows.svg b/charges/bowWithThreeArrows.svg
new file mode 100644
index 00000000..0efc30f2
--- /dev/null
+++ b/charges/bowWithThreeArrows.svg
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/bridge.svg b/charges/bridge.svg
new file mode 100644
index 00000000..f5ce588e
--- /dev/null
+++ b/charges/bridge.svg
@@ -0,0 +1,92 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/bridge2.svg b/charges/bridge2.svg
new file mode 100644
index 00000000..6d3dfab5
--- /dev/null
+++ b/charges/bridge2.svg
@@ -0,0 +1,52 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/bucket.svg b/charges/bucket.svg
new file mode 100644
index 00000000..56c7e83c
--- /dev/null
+++ b/charges/bucket.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/charges/buckle.svg b/charges/buckle.svg
new file mode 100644
index 00000000..b83ba97d
--- /dev/null
+++ b/charges/buckle.svg
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/charges/bugleHorn.svg b/charges/bugleHorn.svg
new file mode 100644
index 00000000..a7985ca6
--- /dev/null
+++ b/charges/bugleHorn.svg
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/bugleHorn2.svg b/charges/bugleHorn2.svg
new file mode 100644
index 00000000..cf5bcaa7
--- /dev/null
+++ b/charges/bugleHorn2.svg
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/bullHeadCaboshed.svg b/charges/bullHeadCaboshed.svg
new file mode 100644
index 00000000..d3ddeccc
--- /dev/null
+++ b/charges/bullHeadCaboshed.svg
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/bullPassant.svg b/charges/bullPassant.svg
new file mode 100644
index 00000000..0314b64e
--- /dev/null
+++ b/charges/bullPassant.svg
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/butterfly.svg b/charges/butterfly.svg
new file mode 100644
index 00000000..2c301fcf
--- /dev/null
+++ b/charges/butterfly.svg
@@ -0,0 +1,64 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/camel.svg b/charges/camel.svg
new file mode 100644
index 00000000..e2dd8bb9
--- /dev/null
+++ b/charges/camel.svg
@@ -0,0 +1,125 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/cancer.svg b/charges/cancer.svg
new file mode 100644
index 00000000..a8bf102c
--- /dev/null
+++ b/charges/cancer.svg
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/cannon.svg b/charges/cannon.svg
new file mode 100644
index 00000000..05e88b25
--- /dev/null
+++ b/charges/cannon.svg
@@ -0,0 +1,68 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/caravel.svg b/charges/caravel.svg
new file mode 100644
index 00000000..9eb57671
--- /dev/null
+++ b/charges/caravel.svg
@@ -0,0 +1,70 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/carreau.svg b/charges/carreau.svg
new file mode 100644
index 00000000..bfeeb049
--- /dev/null
+++ b/charges/carreau.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/charges/castle.svg b/charges/castle.svg
new file mode 100644
index 00000000..43a2fa38
--- /dev/null
+++ b/charges/castle.svg
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/castle2.svg b/charges/castle2.svg
new file mode 100644
index 00000000..5f12a8aa
--- /dev/null
+++ b/charges/castle2.svg
@@ -0,0 +1,60 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/catPassantGuardant.svg b/charges/catPassantGuardant.svg
new file mode 100644
index 00000000..b49dc820
--- /dev/null
+++ b/charges/catPassantGuardant.svg
@@ -0,0 +1,67 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/cavalier.svg b/charges/cavalier.svg
new file mode 100644
index 00000000..7bfad7ac
--- /dev/null
+++ b/charges/cavalier.svg
@@ -0,0 +1,75 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/centaur.svg b/charges/centaur.svg
new file mode 100644
index 00000000..f4ddeb22
--- /dev/null
+++ b/charges/centaur.svg
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/chain.svg b/charges/chain.svg
new file mode 100644
index 00000000..cfe4a3bb
--- /dev/null
+++ b/charges/chain.svg
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/chalice.svg b/charges/chalice.svg
new file mode 100644
index 00000000..0f4f95f6
--- /dev/null
+++ b/charges/chalice.svg
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/cinquefoil.svg b/charges/cinquefoil.svg
new file mode 100644
index 00000000..49db293e
--- /dev/null
+++ b/charges/cinquefoil.svg
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/cock.svg b/charges/cock.svg
new file mode 100644
index 00000000..4b100034
--- /dev/null
+++ b/charges/cock.svg
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/column.svg b/charges/column.svg
new file mode 100644
index 00000000..38d8b2a0
--- /dev/null
+++ b/charges/column.svg
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/comet.svg b/charges/comet.svg
new file mode 100644
index 00000000..096ddb67
--- /dev/null
+++ b/charges/comet.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/charges/compassRose.svg b/charges/compassRose.svg
new file mode 100644
index 00000000..dec495cc
--- /dev/null
+++ b/charges/compassRose.svg
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/charges/cossack.svg b/charges/cossack.svg
new file mode 100644
index 00000000..f5cf75ed
--- /dev/null
+++ b/charges/cossack.svg
@@ -0,0 +1,201 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/cowHorns.svg b/charges/cowHorns.svg
new file mode 100644
index 00000000..74378210
--- /dev/null
+++ b/charges/cowHorns.svg
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/cowStatant.svg b/charges/cowStatant.svg
new file mode 100644
index 00000000..66b46823
--- /dev/null
+++ b/charges/cowStatant.svg
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/crescent.svg b/charges/crescent.svg
new file mode 100644
index 00000000..9181995b
--- /dev/null
+++ b/charges/crescent.svg
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/charges/crocodile.svg b/charges/crocodile.svg
new file mode 100644
index 00000000..442e456d
--- /dev/null
+++ b/charges/crocodile.svg
@@ -0,0 +1,66 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/crosier.svg b/charges/crosier.svg
new file mode 100644
index 00000000..631ef998
--- /dev/null
+++ b/charges/crosier.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/charges/crossAnkh.svg b/charges/crossAnkh.svg
new file mode 100644
index 00000000..6bbac70e
--- /dev/null
+++ b/charges/crossAnkh.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/charges/crossArrowed.svg b/charges/crossArrowed.svg
new file mode 100644
index 00000000..ff4b6c02
--- /dev/null
+++ b/charges/crossArrowed.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/charges/crossAvellane.svg b/charges/crossAvellane.svg
new file mode 100644
index 00000000..303e7f72
--- /dev/null
+++ b/charges/crossAvellane.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/charges/crossBiparted.svg b/charges/crossBiparted.svg
new file mode 100644
index 00000000..0e6ac5f8
--- /dev/null
+++ b/charges/crossBiparted.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/charges/crossBottony.svg b/charges/crossBottony.svg
new file mode 100644
index 00000000..2d246b29
--- /dev/null
+++ b/charges/crossBottony.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/charges/crossBurgundy.svg b/charges/crossBurgundy.svg
new file mode 100644
index 00000000..cb681714
--- /dev/null
+++ b/charges/crossBurgundy.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/charges/crossCalvary.svg b/charges/crossCalvary.svg
new file mode 100644
index 00000000..dd0447b5
--- /dev/null
+++ b/charges/crossCalvary.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/charges/crossCarolingian.svg b/charges/crossCarolingian.svg
new file mode 100644
index 00000000..761464a7
--- /dev/null
+++ b/charges/crossCarolingian.svg
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/crossCeltic.svg b/charges/crossCeltic.svg
new file mode 100644
index 00000000..6abe10fe
--- /dev/null
+++ b/charges/crossCeltic.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/charges/crossCeltic2.svg b/charges/crossCeltic2.svg
new file mode 100644
index 00000000..84628911
--- /dev/null
+++ b/charges/crossCeltic2.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/charges/crossCercelee.svg b/charges/crossCercelee.svg
new file mode 100644
index 00000000..2b8bff16
--- /dev/null
+++ b/charges/crossCercelee.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/charges/crossClechy.svg b/charges/crossClechy.svg
new file mode 100644
index 00000000..c246534e
--- /dev/null
+++ b/charges/crossClechy.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/charges/crossDouble.svg b/charges/crossDouble.svg
new file mode 100644
index 00000000..1a0e4bc8
--- /dev/null
+++ b/charges/crossDouble.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/charges/crossErminee.svg b/charges/crossErminee.svg
new file mode 100644
index 00000000..1def3830
--- /dev/null
+++ b/charges/crossErminee.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/charges/crossFitchy.svg b/charges/crossFitchy.svg
new file mode 100644
index 00000000..954b8e70
--- /dev/null
+++ b/charges/crossFitchy.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/charges/crossFleury.svg b/charges/crossFleury.svg
new file mode 100644
index 00000000..d617a15d
--- /dev/null
+++ b/charges/crossFleury.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/charges/crossFormee.svg b/charges/crossFormee.svg
new file mode 100644
index 00000000..efef99d4
--- /dev/null
+++ b/charges/crossFormee.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/charges/crossFormee2.svg b/charges/crossFormee2.svg
new file mode 100644
index 00000000..2309e494
--- /dev/null
+++ b/charges/crossFormee2.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/charges/crossFourchy.svg b/charges/crossFourchy.svg
new file mode 100644
index 00000000..9308a143
--- /dev/null
+++ b/charges/crossFourchy.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/charges/crossGamma.svg b/charges/crossGamma.svg
new file mode 100644
index 00000000..d2da6490
--- /dev/null
+++ b/charges/crossGamma.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/charges/crossHummetty.svg b/charges/crossHummetty.svg
new file mode 100644
index 00000000..e2676ab2
--- /dev/null
+++ b/charges/crossHummetty.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/charges/crossJerusalem.svg b/charges/crossJerusalem.svg
new file mode 100644
index 00000000..54ba95dc
--- /dev/null
+++ b/charges/crossJerusalem.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/charges/crossLatin.svg b/charges/crossLatin.svg
new file mode 100644
index 00000000..16f60138
--- /dev/null
+++ b/charges/crossLatin.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/charges/crossMaltese.svg b/charges/crossMaltese.svg
new file mode 100644
index 00000000..5718dacf
--- /dev/null
+++ b/charges/crossMaltese.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/charges/crossMoline.svg b/charges/crossMoline.svg
new file mode 100644
index 00000000..97f3b918
--- /dev/null
+++ b/charges/crossMoline.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/charges/crossOccitan.svg b/charges/crossOccitan.svg
new file mode 100644
index 00000000..15fe7587
--- /dev/null
+++ b/charges/crossOccitan.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/charges/crossOrthodox.svg b/charges/crossOrthodox.svg
new file mode 100644
index 00000000..9519f84d
--- /dev/null
+++ b/charges/crossOrthodox.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/charges/crossPatonce.svg b/charges/crossPatonce.svg
new file mode 100644
index 00000000..aaaec339
--- /dev/null
+++ b/charges/crossPatonce.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/charges/crossPatriarchal.svg b/charges/crossPatriarchal.svg
new file mode 100644
index 00000000..12338bc2
--- /dev/null
+++ b/charges/crossPatriarchal.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/charges/crossPattee.svg b/charges/crossPattee.svg
new file mode 100644
index 00000000..1c3bf761
--- /dev/null
+++ b/charges/crossPattee.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/charges/crossPatteeAlisee.svg b/charges/crossPatteeAlisee.svg
new file mode 100644
index 00000000..801e7113
--- /dev/null
+++ b/charges/crossPatteeAlisee.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/charges/crossPommy.svg b/charges/crossPommy.svg
new file mode 100644
index 00000000..da002347
--- /dev/null
+++ b/charges/crossPommy.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/charges/crossPotent.svg b/charges/crossPotent.svg
new file mode 100644
index 00000000..cc3bb92f
--- /dev/null
+++ b/charges/crossPotent.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/charges/crossSaltire.svg b/charges/crossSaltire.svg
new file mode 100644
index 00000000..8798ba45
--- /dev/null
+++ b/charges/crossSaltire.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/charges/crossSantiago.svg b/charges/crossSantiago.svg
new file mode 100644
index 00000000..7e510a90
--- /dev/null
+++ b/charges/crossSantiago.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/charges/crossTau.svg b/charges/crossTau.svg
new file mode 100644
index 00000000..0789faf5
--- /dev/null
+++ b/charges/crossTau.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/charges/crossTemplar.svg b/charges/crossTemplar.svg
new file mode 100644
index 00000000..9c33613c
--- /dev/null
+++ b/charges/crossTemplar.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/charges/crossTriquetra.svg b/charges/crossTriquetra.svg
new file mode 100644
index 00000000..024225c1
--- /dev/null
+++ b/charges/crossTriquetra.svg
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/charges/crossVoided.svg b/charges/crossVoided.svg
new file mode 100644
index 00000000..0fa95bd7
--- /dev/null
+++ b/charges/crossVoided.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/charges/crossedBones.svg b/charges/crossedBones.svg
new file mode 100644
index 00000000..3b06442f
--- /dev/null
+++ b/charges/crossedBones.svg
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/charges/crosslet.svg b/charges/crosslet.svg
new file mode 100644
index 00000000..645b68a3
--- /dev/null
+++ b/charges/crosslet.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/charges/crown.svg b/charges/crown.svg
new file mode 100644
index 00000000..00dbbacf
--- /dev/null
+++ b/charges/crown.svg
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/crown2.svg b/charges/crown2.svg
new file mode 100644
index 00000000..f06a106e
--- /dev/null
+++ b/charges/crown2.svg
@@ -0,0 +1,70 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/deerHeadCaboshed.svg b/charges/deerHeadCaboshed.svg
new file mode 100644
index 00000000..aca87f99
--- /dev/null
+++ b/charges/deerHeadCaboshed.svg
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/delf.svg b/charges/delf.svg
new file mode 100644
index 00000000..227bd04f
--- /dev/null
+++ b/charges/delf.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/charges/dolphin.svg b/charges/dolphin.svg
new file mode 100644
index 00000000..be5b00bd
--- /dev/null
+++ b/charges/dolphin.svg
@@ -0,0 +1,60 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/donkeyHeadCaboshed.svg b/charges/donkeyHeadCaboshed.svg
new file mode 100644
index 00000000..da5aee0a
--- /dev/null
+++ b/charges/donkeyHeadCaboshed.svg
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/dove.svg b/charges/dove.svg
new file mode 100644
index 00000000..7406a6ec
--- /dev/null
+++ b/charges/dove.svg
@@ -0,0 +1,67 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/doveDisplayed.svg b/charges/doveDisplayed.svg
new file mode 100644
index 00000000..35bd14d6
--- /dev/null
+++ b/charges/doveDisplayed.svg
@@ -0,0 +1,112 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/dragonPassant.svg b/charges/dragonPassant.svg
new file mode 100644
index 00000000..b8fbc58e
--- /dev/null
+++ b/charges/dragonPassant.svg
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/dragonRampant.svg b/charges/dragonRampant.svg
new file mode 100644
index 00000000..6ff64c2a
--- /dev/null
+++ b/charges/dragonRampant.svg
@@ -0,0 +1,61 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/dragonfly.svg b/charges/dragonfly.svg
new file mode 100644
index 00000000..c8b501ca
--- /dev/null
+++ b/charges/dragonfly.svg
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/drakkar.svg b/charges/drakkar.svg
new file mode 100644
index 00000000..f36c3c4d
--- /dev/null
+++ b/charges/drakkar.svg
@@ -0,0 +1,53 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/drawingCompass.svg b/charges/drawingCompass.svg
new file mode 100644
index 00000000..65a252d3
--- /dev/null
+++ b/charges/drawingCompass.svg
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/drum.svg b/charges/drum.svg
new file mode 100644
index 00000000..bd8fd638
--- /dev/null
+++ b/charges/drum.svg
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/duck.svg b/charges/duck.svg
new file mode 100644
index 00000000..940c3e4d
--- /dev/null
+++ b/charges/duck.svg
@@ -0,0 +1,85 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/eagle.svg b/charges/eagle.svg
new file mode 100644
index 00000000..c52fd495
--- /dev/null
+++ b/charges/eagle.svg
@@ -0,0 +1,91 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/eagleTwoHeads.svg b/charges/eagleTwoHeads.svg
new file mode 100644
index 00000000..cc8ac124
--- /dev/null
+++ b/charges/eagleTwoHeads.svg
@@ -0,0 +1,103 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/earOfWheat.svg b/charges/earOfWheat.svg
new file mode 100644
index 00000000..a1b3072c
--- /dev/null
+++ b/charges/earOfWheat.svg
@@ -0,0 +1,99 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/elephant.svg b/charges/elephant.svg
new file mode 100644
index 00000000..fed4c13f
--- /dev/null
+++ b/charges/elephant.svg
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/elephantHeadErased.svg b/charges/elephantHeadErased.svg
new file mode 100644
index 00000000..f521413b
--- /dev/null
+++ b/charges/elephantHeadErased.svg
@@ -0,0 +1,22 @@
+
+
+
+
diff --git a/charges/escallop.svg b/charges/escallop.svg
new file mode 100644
index 00000000..4fda9dda
--- /dev/null
+++ b/charges/escallop.svg
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/estoile.svg b/charges/estoile.svg
new file mode 100644
index 00000000..6966ccbc
--- /dev/null
+++ b/charges/estoile.svg
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/falchion.svg b/charges/falchion.svg
new file mode 100644
index 00000000..ccb71d3d
--- /dev/null
+++ b/charges/falchion.svg
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/falcon.svg b/charges/falcon.svg
new file mode 100644
index 00000000..5e4cebd5
--- /dev/null
+++ b/charges/falcon.svg
@@ -0,0 +1,223 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/fan.svg b/charges/fan.svg
new file mode 100644
index 00000000..d7504ac6
--- /dev/null
+++ b/charges/fan.svg
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/fasces.svg b/charges/fasces.svg
new file mode 100644
index 00000000..71e27285
--- /dev/null
+++ b/charges/fasces.svg
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/feather.svg b/charges/feather.svg
new file mode 100644
index 00000000..0be55bf5
--- /dev/null
+++ b/charges/feather.svg
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/charges/flamberge.svg b/charges/flamberge.svg
new file mode 100644
index 00000000..ab9d2277
--- /dev/null
+++ b/charges/flamberge.svg
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/flangedMace.svg b/charges/flangedMace.svg
new file mode 100644
index 00000000..901d942f
--- /dev/null
+++ b/charges/flangedMace.svg
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/fleurDeLis.svg b/charges/fleurDeLis.svg
new file mode 100644
index 00000000..2583e48f
--- /dev/null
+++ b/charges/fleurDeLis.svg
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/fly.svg b/charges/fly.svg
new file mode 100644
index 00000000..9c880f72
--- /dev/null
+++ b/charges/fly.svg
@@ -0,0 +1,61 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/foot.svg b/charges/foot.svg
new file mode 100644
index 00000000..22963e5b
--- /dev/null
+++ b/charges/foot.svg
@@ -0,0 +1,14 @@
+
+
+
+
diff --git a/charges/fountain.svg b/charges/fountain.svg
new file mode 100644
index 00000000..1ed8ac67
--- /dev/null
+++ b/charges/fountain.svg
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/frog.svg b/charges/frog.svg
new file mode 100644
index 00000000..392d3d05
--- /dev/null
+++ b/charges/frog.svg
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/fusil.svg b/charges/fusil.svg
new file mode 100644
index 00000000..eac10ed4
--- /dev/null
+++ b/charges/fusil.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/charges/garb.svg b/charges/garb.svg
new file mode 100644
index 00000000..fbefacd8
--- /dev/null
+++ b/charges/garb.svg
@@ -0,0 +1,150 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/gauntlet.svg b/charges/gauntlet.svg
new file mode 100644
index 00000000..f00a03eb
--- /dev/null
+++ b/charges/gauntlet.svg
@@ -0,0 +1,54 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/gear.svg b/charges/gear.svg
new file mode 100644
index 00000000..2d128dfb
--- /dev/null
+++ b/charges/gear.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/charges/goat.svg b/charges/goat.svg
new file mode 100644
index 00000000..721c3f15
--- /dev/null
+++ b/charges/goat.svg
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/goutte.svg b/charges/goutte.svg
new file mode 100644
index 00000000..40f23183
--- /dev/null
+++ b/charges/goutte.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/charges/grapeBunch.svg b/charges/grapeBunch.svg
new file mode 100644
index 00000000..38d4693f
--- /dev/null
+++ b/charges/grapeBunch.svg
@@ -0,0 +1,73 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/grapeBunch2.svg b/charges/grapeBunch2.svg
new file mode 100644
index 00000000..0af7b6a6
--- /dev/null
+++ b/charges/grapeBunch2.svg
@@ -0,0 +1,52 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/grenade.svg b/charges/grenade.svg
new file mode 100644
index 00000000..07436784
--- /dev/null
+++ b/charges/grenade.svg
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/greyhoundCourant.svg b/charges/greyhoundCourant.svg
new file mode 100644
index 00000000..916d70cf
--- /dev/null
+++ b/charges/greyhoundCourant.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/charges/greyhoundRampant.svg b/charges/greyhoundRampant.svg
new file mode 100644
index 00000000..cf607df5
--- /dev/null
+++ b/charges/greyhoundRampant.svg
@@ -0,0 +1,89 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/greyhoundSejant.svg b/charges/greyhoundSejant.svg
new file mode 100644
index 00000000..09efa81c
--- /dev/null
+++ b/charges/greyhoundSejant.svg
@@ -0,0 +1,108 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/griffinPassant.svg b/charges/griffinPassant.svg
new file mode 100644
index 00000000..871b3591
--- /dev/null
+++ b/charges/griffinPassant.svg
@@ -0,0 +1,61 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/griffinRampant.svg b/charges/griffinRampant.svg
new file mode 100644
index 00000000..da2cfebe
--- /dev/null
+++ b/charges/griffinRampant.svg
@@ -0,0 +1,115 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/hand.svg b/charges/hand.svg
new file mode 100644
index 00000000..91c279ae
--- /dev/null
+++ b/charges/hand.svg
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/harp.svg b/charges/harp.svg
new file mode 100644
index 00000000..91e5ee08
--- /dev/null
+++ b/charges/harp.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/charges/hatchet.svg b/charges/hatchet.svg
new file mode 100644
index 00000000..37052556
--- /dev/null
+++ b/charges/hatchet.svg
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/charges/head.svg b/charges/head.svg
new file mode 100644
index 00000000..08e36060
--- /dev/null
+++ b/charges/head.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/charges/headWreathed.svg b/charges/headWreathed.svg
new file mode 100644
index 00000000..b6dafc64
--- /dev/null
+++ b/charges/headWreathed.svg
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/heart.svg b/charges/heart.svg
new file mode 100644
index 00000000..56d0940c
--- /dev/null
+++ b/charges/heart.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/charges/hedgehog.svg b/charges/hedgehog.svg
new file mode 100644
index 00000000..c7a84caa
--- /dev/null
+++ b/charges/hedgehog.svg
@@ -0,0 +1,52 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/helmet.svg b/charges/helmet.svg
new file mode 100644
index 00000000..9099c7c3
--- /dev/null
+++ b/charges/helmet.svg
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/helmetCorinthian.svg b/charges/helmetCorinthian.svg
new file mode 100644
index 00000000..3ccd9cdd
--- /dev/null
+++ b/charges/helmetCorinthian.svg
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/helmetGreat.svg b/charges/helmetGreat.svg
new file mode 100644
index 00000000..b7a7bf49
--- /dev/null
+++ b/charges/helmetGreat.svg
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/helmetZischagge.svg b/charges/helmetZischagge.svg
new file mode 100644
index 00000000..8985d197
--- /dev/null
+++ b/charges/helmetZischagge.svg
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/heron.svg b/charges/heron.svg
new file mode 100644
index 00000000..4893b082
--- /dev/null
+++ b/charges/heron.svg
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/hindStatant.svg b/charges/hindStatant.svg
new file mode 100644
index 00000000..3f9cc429
--- /dev/null
+++ b/charges/hindStatant.svg
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/hook.svg b/charges/hook.svg
new file mode 100644
index 00000000..d5679f64
--- /dev/null
+++ b/charges/hook.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/charges/horseHeadCouped.svg b/charges/horseHeadCouped.svg
new file mode 100644
index 00000000..8c455c23
--- /dev/null
+++ b/charges/horseHeadCouped.svg
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/horsePassant.svg b/charges/horsePassant.svg
new file mode 100644
index 00000000..b2361b84
--- /dev/null
+++ b/charges/horsePassant.svg
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/horseRampant.svg b/charges/horseRampant.svg
new file mode 100644
index 00000000..be7fee6c
--- /dev/null
+++ b/charges/horseRampant.svg
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/horseSalient.svg b/charges/horseSalient.svg
new file mode 100644
index 00000000..21b5db48
--- /dev/null
+++ b/charges/horseSalient.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/charges/horseshoe.svg b/charges/horseshoe.svg
new file mode 100644
index 00000000..3bd51f7a
--- /dev/null
+++ b/charges/horseshoe.svg
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/charges/hourglass.svg b/charges/hourglass.svg
new file mode 100644
index 00000000..87e7930b
--- /dev/null
+++ b/charges/hourglass.svg
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/key.svg b/charges/key.svg
new file mode 100644
index 00000000..6fb883ea
--- /dev/null
+++ b/charges/key.svg
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/ladder.svg b/charges/ladder.svg
new file mode 100644
index 00000000..fc72f130
--- /dev/null
+++ b/charges/ladder.svg
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/ladder2.svg b/charges/ladder2.svg
new file mode 100644
index 00000000..5596e045
--- /dev/null
+++ b/charges/ladder2.svg
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/ladybird.svg b/charges/ladybird.svg
new file mode 100644
index 00000000..3cc1587e
--- /dev/null
+++ b/charges/ladybird.svg
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/lamb.svg b/charges/lamb.svg
new file mode 100644
index 00000000..1d574b53
--- /dev/null
+++ b/charges/lamb.svg
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/lambPassantReguardant.svg b/charges/lambPassantReguardant.svg
new file mode 100644
index 00000000..90884eb7
--- /dev/null
+++ b/charges/lambPassantReguardant.svg
@@ -0,0 +1,118 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/lanceHead.svg b/charges/lanceHead.svg
new file mode 100644
index 00000000..255492db
--- /dev/null
+++ b/charges/lanceHead.svg
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/charges/lanceWithBanner.svg b/charges/lanceWithBanner.svg
new file mode 100644
index 00000000..556e5ade
--- /dev/null
+++ b/charges/lanceWithBanner.svg
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/charges/laurelWreath.svg b/charges/laurelWreath.svg
new file mode 100644
index 00000000..989e00c4
--- /dev/null
+++ b/charges/laurelWreath.svg
@@ -0,0 +1,263 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/laurelWreath2.svg b/charges/laurelWreath2.svg
new file mode 100644
index 00000000..6dfb373e
--- /dev/null
+++ b/charges/laurelWreath2.svg
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/lighthouse.svg b/charges/lighthouse.svg
new file mode 100644
index 00000000..b66938f5
--- /dev/null
+++ b/charges/lighthouse.svg
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/lionHeadCaboshed.svg b/charges/lionHeadCaboshed.svg
new file mode 100644
index 00000000..63022fc0
--- /dev/null
+++ b/charges/lionHeadCaboshed.svg
@@ -0,0 +1,107 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/lionHeadErased.svg b/charges/lionHeadErased.svg
new file mode 100644
index 00000000..7ed39c67
--- /dev/null
+++ b/charges/lionHeadErased.svg
@@ -0,0 +1,28 @@
+
+
+
+
diff --git a/charges/lionPassant.svg b/charges/lionPassant.svg
new file mode 100644
index 00000000..7dd6b396
--- /dev/null
+++ b/charges/lionPassant.svg
@@ -0,0 +1,185 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/lionPassantGuardant.svg b/charges/lionPassantGuardant.svg
new file mode 100644
index 00000000..584e8835
--- /dev/null
+++ b/charges/lionPassantGuardant.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/charges/lionRampant.svg b/charges/lionRampant.svg
new file mode 100644
index 00000000..8aab2b09
--- /dev/null
+++ b/charges/lionRampant.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/charges/lionSejant.svg b/charges/lionSejant.svg
new file mode 100644
index 00000000..23ca98db
--- /dev/null
+++ b/charges/lionSejant.svg
@@ -0,0 +1,125 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/lizard.svg b/charges/lizard.svg
new file mode 100644
index 00000000..dc8dbf9d
--- /dev/null
+++ b/charges/lizard.svg
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/lochaberAxe.svg b/charges/lochaberAxe.svg
new file mode 100644
index 00000000..cf09c61e
--- /dev/null
+++ b/charges/lochaberAxe.svg
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/charges/log.svg b/charges/log.svg
new file mode 100644
index 00000000..387fad44
--- /dev/null
+++ b/charges/log.svg
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/charges/lozenge.svg b/charges/lozenge.svg
new file mode 100644
index 00000000..4cfb22c9
--- /dev/null
+++ b/charges/lozenge.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/charges/lozengeFaceted.svg b/charges/lozengeFaceted.svg
new file mode 100644
index 00000000..63a575e3
--- /dev/null
+++ b/charges/lozengeFaceted.svg
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/lozengePloye.svg b/charges/lozengePloye.svg
new file mode 100644
index 00000000..0187c681
--- /dev/null
+++ b/charges/lozengePloye.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/charges/lute.svg b/charges/lute.svg
new file mode 100644
index 00000000..c88cc397
--- /dev/null
+++ b/charges/lute.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/charges/lymphad.svg b/charges/lymphad.svg
new file mode 100644
index 00000000..457f10d7
--- /dev/null
+++ b/charges/lymphad.svg
@@ -0,0 +1,77 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/lyre.svg b/charges/lyre.svg
new file mode 100644
index 00000000..d89b8550
--- /dev/null
+++ b/charges/lyre.svg
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/mace.svg b/charges/mace.svg
new file mode 100644
index 00000000..a3f0e074
--- /dev/null
+++ b/charges/mace.svg
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/maces.svg b/charges/maces.svg
new file mode 100644
index 00000000..93988b80
--- /dev/null
+++ b/charges/maces.svg
@@ -0,0 +1,65 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/mallet.svg b/charges/mallet.svg
new file mode 100644
index 00000000..ecb418f9
--- /dev/null
+++ b/charges/mallet.svg
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/mantle.svg b/charges/mantle.svg
new file mode 100644
index 00000000..5493c30b
--- /dev/null
+++ b/charges/mantle.svg
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/mapleLeaf.svg b/charges/mapleLeaf.svg
new file mode 100644
index 00000000..93e63767
--- /dev/null
+++ b/charges/mapleLeaf.svg
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/martenCourant.svg b/charges/martenCourant.svg
new file mode 100644
index 00000000..1760d038
--- /dev/null
+++ b/charges/martenCourant.svg
@@ -0,0 +1,68 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/mascle.svg b/charges/mascle.svg
new file mode 100644
index 00000000..b867e47a
--- /dev/null
+++ b/charges/mascle.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/charges/mastiffStatant.svg b/charges/mastiffStatant.svg
new file mode 100644
index 00000000..14feb266
--- /dev/null
+++ b/charges/mastiffStatant.svg
@@ -0,0 +1,156 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/millstone.svg b/charges/millstone.svg
new file mode 100644
index 00000000..f8d523ca
--- /dev/null
+++ b/charges/millstone.svg
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/mitre.svg b/charges/mitre.svg
new file mode 100644
index 00000000..1a20e002
--- /dev/null
+++ b/charges/mitre.svg
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/monk.svg b/charges/monk.svg
new file mode 100644
index 00000000..8ede0359
--- /dev/null
+++ b/charges/monk.svg
@@ -0,0 +1,139 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/moonInCrescent.svg b/charges/moonInCrescent.svg
new file mode 100644
index 00000000..27fdb512
--- /dev/null
+++ b/charges/moonInCrescent.svg
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/mullet.svg b/charges/mullet.svg
new file mode 100644
index 00000000..2658e971
--- /dev/null
+++ b/charges/mullet.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/charges/mullet10.svg b/charges/mullet10.svg
new file mode 100644
index 00000000..60ed608a
--- /dev/null
+++ b/charges/mullet10.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/charges/mullet4.svg b/charges/mullet4.svg
new file mode 100644
index 00000000..37242f99
--- /dev/null
+++ b/charges/mullet4.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/charges/mullet6.svg b/charges/mullet6.svg
new file mode 100644
index 00000000..1a1972aa
--- /dev/null
+++ b/charges/mullet6.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/charges/mullet6Faceted.svg b/charges/mullet6Faceted.svg
new file mode 100644
index 00000000..1ca0c335
--- /dev/null
+++ b/charges/mullet6Faceted.svg
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/charges/mullet6Pierced.svg b/charges/mullet6Pierced.svg
new file mode 100644
index 00000000..96d6f279
--- /dev/null
+++ b/charges/mullet6Pierced.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/charges/mullet7.svg b/charges/mullet7.svg
new file mode 100644
index 00000000..53321978
--- /dev/null
+++ b/charges/mullet7.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/charges/mullet8.svg b/charges/mullet8.svg
new file mode 100644
index 00000000..0239a883
--- /dev/null
+++ b/charges/mullet8.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/charges/mulletFaceted.svg b/charges/mulletFaceted.svg
new file mode 100644
index 00000000..a43fe26e
--- /dev/null
+++ b/charges/mulletFaceted.svg
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/charges/mulletPierced.svg b/charges/mulletPierced.svg
new file mode 100644
index 00000000..b469bf0c
--- /dev/null
+++ b/charges/mulletPierced.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/charges/oak.svg b/charges/oak.svg
new file mode 100644
index 00000000..b01da9b4
--- /dev/null
+++ b/charges/oak.svg
@@ -0,0 +1,347 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/orb.svg b/charges/orb.svg
new file mode 100644
index 00000000..2d7354f5
--- /dev/null
+++ b/charges/orb.svg
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/ouroboros.svg b/charges/ouroboros.svg
new file mode 100644
index 00000000..f0f39146
--- /dev/null
+++ b/charges/ouroboros.svg
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/charges/owl.svg b/charges/owl.svg
new file mode 100644
index 00000000..015a7f81
--- /dev/null
+++ b/charges/owl.svg
@@ -0,0 +1,139 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/owlDisplayed.svg b/charges/owlDisplayed.svg
new file mode 100644
index 00000000..353fe5e7
--- /dev/null
+++ b/charges/owlDisplayed.svg
@@ -0,0 +1,75 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/palace.svg b/charges/palace.svg
new file mode 100644
index 00000000..9e03dd4b
--- /dev/null
+++ b/charges/palace.svg
@@ -0,0 +1,170 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/palmTree.svg b/charges/palmTree.svg
new file mode 100644
index 00000000..590d14a3
--- /dev/null
+++ b/charges/palmTree.svg
@@ -0,0 +1,156 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/parrot.svg b/charges/parrot.svg
new file mode 100644
index 00000000..92d7dd10
--- /dev/null
+++ b/charges/parrot.svg
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/peacock.svg b/charges/peacock.svg
new file mode 100644
index 00000000..064831f4
--- /dev/null
+++ b/charges/peacock.svg
@@ -0,0 +1,167 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/peacockInPride.svg b/charges/peacockInPride.svg
new file mode 100644
index 00000000..b8b4f8c7
--- /dev/null
+++ b/charges/peacockInPride.svg
@@ -0,0 +1,216 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/pear.svg b/charges/pear.svg
new file mode 100644
index 00000000..d421e208
--- /dev/null
+++ b/charges/pear.svg
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/pegasus.svg b/charges/pegasus.svg
new file mode 100644
index 00000000..5335022d
--- /dev/null
+++ b/charges/pegasus.svg
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/pike.svg b/charges/pike.svg
new file mode 100644
index 00000000..812002b7
--- /dev/null
+++ b/charges/pike.svg
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/pillar.svg b/charges/pillar.svg
new file mode 100644
index 00000000..d9aa943f
--- /dev/null
+++ b/charges/pillar.svg
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/pincers.svg b/charges/pincers.svg
new file mode 100644
index 00000000..2e91f728
--- /dev/null
+++ b/charges/pincers.svg
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/charges/pineCone.svg b/charges/pineCone.svg
new file mode 100644
index 00000000..c326f2a2
--- /dev/null
+++ b/charges/pineCone.svg
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/pineTree.svg b/charges/pineTree.svg
new file mode 100644
index 00000000..2abebe11
--- /dev/null
+++ b/charges/pineTree.svg
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/pique.svg b/charges/pique.svg
new file mode 100644
index 00000000..06c5836e
--- /dev/null
+++ b/charges/pique.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/charges/plaice.svg b/charges/plaice.svg
new file mode 100644
index 00000000..8325d1ca
--- /dev/null
+++ b/charges/plaice.svg
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/plough.svg b/charges/plough.svg
new file mode 100644
index 00000000..7c1f42fc
--- /dev/null
+++ b/charges/plough.svg
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/ploughshare.svg b/charges/ploughshare.svg
new file mode 100644
index 00000000..45928f03
--- /dev/null
+++ b/charges/ploughshare.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/charges/porcupine.svg b/charges/porcupine.svg
new file mode 100644
index 00000000..bdc53081
--- /dev/null
+++ b/charges/porcupine.svg
@@ -0,0 +1,137 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/portcullis.svg b/charges/portcullis.svg
new file mode 100644
index 00000000..de154326
--- /dev/null
+++ b/charges/portcullis.svg
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/pot.svg b/charges/pot.svg
new file mode 100644
index 00000000..64cc0ff6
--- /dev/null
+++ b/charges/pot.svg
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/quatrefoil.svg b/charges/quatrefoil.svg
new file mode 100644
index 00000000..ff33f762
--- /dev/null
+++ b/charges/quatrefoil.svg
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/rabbitSejant.svg b/charges/rabbitSejant.svg
new file mode 100644
index 00000000..c61e0a9b
--- /dev/null
+++ b/charges/rabbitSejant.svg
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/raft.svg b/charges/raft.svg
new file mode 100644
index 00000000..d5b728b4
--- /dev/null
+++ b/charges/raft.svg
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/rake.svg b/charges/rake.svg
new file mode 100644
index 00000000..6feed725
--- /dev/null
+++ b/charges/rake.svg
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/ramHeadErased.svg b/charges/ramHeadErased.svg
new file mode 100644
index 00000000..c971f7b4
--- /dev/null
+++ b/charges/ramHeadErased.svg
@@ -0,0 +1,75 @@
+
+
+
+
diff --git a/charges/ramPassant.svg b/charges/ramPassant.svg
new file mode 100644
index 00000000..421e416c
--- /dev/null
+++ b/charges/ramPassant.svg
@@ -0,0 +1,80 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/ramsHorn.svg b/charges/ramsHorn.svg
new file mode 100644
index 00000000..26585cc9
--- /dev/null
+++ b/charges/ramsHorn.svg
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/rapier.svg b/charges/rapier.svg
new file mode 100644
index 00000000..fed83920
--- /dev/null
+++ b/charges/rapier.svg
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/ratRampant.svg b/charges/ratRampant.svg
new file mode 100644
index 00000000..13c6746a
--- /dev/null
+++ b/charges/ratRampant.svg
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/raven.svg b/charges/raven.svg
new file mode 100644
index 00000000..6e3c4eca
--- /dev/null
+++ b/charges/raven.svg
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/rhinoceros.svg b/charges/rhinoceros.svg
new file mode 100644
index 00000000..1d43c4f4
--- /dev/null
+++ b/charges/rhinoceros.svg
@@ -0,0 +1,61 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/ribbon1.svg b/charges/ribbon1.svg
new file mode 100644
index 00000000..03bf3515
--- /dev/null
+++ b/charges/ribbon1.svg
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/ribbon2.svg b/charges/ribbon2.svg
new file mode 100644
index 00000000..0f15bb04
--- /dev/null
+++ b/charges/ribbon2.svg
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/charges/ribbon3.svg b/charges/ribbon3.svg
new file mode 100644
index 00000000..dd168991
--- /dev/null
+++ b/charges/ribbon3.svg
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/ribbon4.svg b/charges/ribbon4.svg
new file mode 100644
index 00000000..bab35959
--- /dev/null
+++ b/charges/ribbon4.svg
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/ribbon5.svg b/charges/ribbon5.svg
new file mode 100644
index 00000000..3c718bce
--- /dev/null
+++ b/charges/ribbon5.svg
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/ribbon6.svg b/charges/ribbon6.svg
new file mode 100644
index 00000000..a32eede7
--- /dev/null
+++ b/charges/ribbon6.svg
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/charges/ribbon7.svg b/charges/ribbon7.svg
new file mode 100644
index 00000000..2d9a1e21
--- /dev/null
+++ b/charges/ribbon7.svg
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/ribbon8.svg b/charges/ribbon8.svg
new file mode 100644
index 00000000..f7c672a7
--- /dev/null
+++ b/charges/ribbon8.svg
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/charges/rose.svg b/charges/rose.svg
new file mode 100644
index 00000000..7ce11665
--- /dev/null
+++ b/charges/rose.svg
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/roundel.svg b/charges/roundel.svg
new file mode 100644
index 00000000..344991ed
--- /dev/null
+++ b/charges/roundel.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/charges/roundel2.svg b/charges/roundel2.svg
new file mode 100644
index 00000000..fffa7ad4
--- /dev/null
+++ b/charges/roundel2.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/charges/rustre.svg b/charges/rustre.svg
new file mode 100644
index 00000000..60c253a1
--- /dev/null
+++ b/charges/rustre.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/charges/sabre.svg b/charges/sabre.svg
new file mode 100644
index 00000000..0f1f002d
--- /dev/null
+++ b/charges/sabre.svg
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/sabre2.svg b/charges/sabre2.svg
new file mode 100644
index 00000000..2466a761
--- /dev/null
+++ b/charges/sabre2.svg
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/sabresCrossed.svg b/charges/sabresCrossed.svg
new file mode 100644
index 00000000..e9cec5f4
--- /dev/null
+++ b/charges/sabresCrossed.svg
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/sagittarius.svg b/charges/sagittarius.svg
new file mode 100644
index 00000000..ac5eaeeb
--- /dev/null
+++ b/charges/sagittarius.svg
@@ -0,0 +1,136 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/salmon.svg b/charges/salmon.svg
new file mode 100644
index 00000000..bda9bf49
--- /dev/null
+++ b/charges/salmon.svg
@@ -0,0 +1,127 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/saw.svg b/charges/saw.svg
new file mode 100644
index 00000000..c356263f
--- /dev/null
+++ b/charges/saw.svg
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/scale.svg b/charges/scale.svg
new file mode 100644
index 00000000..b2da96ea
--- /dev/null
+++ b/charges/scale.svg
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/scaleImbalanced.svg b/charges/scaleImbalanced.svg
new file mode 100644
index 00000000..ea151649
--- /dev/null
+++ b/charges/scaleImbalanced.svg
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/scalesHanging.svg b/charges/scalesHanging.svg
new file mode 100644
index 00000000..1065211b
--- /dev/null
+++ b/charges/scalesHanging.svg
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/sceptre.svg b/charges/sceptre.svg
new file mode 100644
index 00000000..57869cbf
--- /dev/null
+++ b/charges/sceptre.svg
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/scissors.svg b/charges/scissors.svg
new file mode 100644
index 00000000..a7437f1e
--- /dev/null
+++ b/charges/scissors.svg
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/charges/scissors2.svg b/charges/scissors2.svg
new file mode 100644
index 00000000..109d8238
--- /dev/null
+++ b/charges/scissors2.svg
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/scorpion.svg b/charges/scorpion.svg
new file mode 100644
index 00000000..c132511d
--- /dev/null
+++ b/charges/scorpion.svg
@@ -0,0 +1,60 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/scrollClosed.svg b/charges/scrollClosed.svg
new file mode 100644
index 00000000..1f7d8034
--- /dev/null
+++ b/charges/scrollClosed.svg
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/scythe.svg b/charges/scythe.svg
new file mode 100644
index 00000000..b8d0a04d
--- /dev/null
+++ b/charges/scythe.svg
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/scythe2.svg b/charges/scythe2.svg
new file mode 100644
index 00000000..7fa9de5d
--- /dev/null
+++ b/charges/scythe2.svg
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/charges/serpent.svg b/charges/serpent.svg
new file mode 100644
index 00000000..e12c9570
--- /dev/null
+++ b/charges/serpent.svg
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/sextifoil.svg b/charges/sextifoil.svg
new file mode 100644
index 00000000..ad6e3303
--- /dev/null
+++ b/charges/sextifoil.svg
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/shears.svg b/charges/shears.svg
new file mode 100644
index 00000000..3b3daeb4
--- /dev/null
+++ b/charges/shears.svg
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/charges/shield.svg b/charges/shield.svg
new file mode 100644
index 00000000..89ad41de
--- /dev/null
+++ b/charges/shield.svg
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/shipWheel.svg b/charges/shipWheel.svg
new file mode 100644
index 00000000..fa23136c
--- /dev/null
+++ b/charges/shipWheel.svg
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/sickle.svg b/charges/sickle.svg
new file mode 100644
index 00000000..753eeeaa
--- /dev/null
+++ b/charges/sickle.svg
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/skeleton.svg b/charges/skeleton.svg
new file mode 100644
index 00000000..cde28dae
--- /dev/null
+++ b/charges/skeleton.svg
@@ -0,0 +1,105 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/skull.svg b/charges/skull.svg
new file mode 100644
index 00000000..c7dc7044
--- /dev/null
+++ b/charges/skull.svg
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/skull2.svg b/charges/skull2.svg
new file mode 100644
index 00000000..a580afd7
--- /dev/null
+++ b/charges/skull2.svg
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/snail.svg b/charges/snail.svg
new file mode 100644
index 00000000..387dc48a
--- /dev/null
+++ b/charges/snail.svg
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/snake.svg b/charges/snake.svg
new file mode 100644
index 00000000..532f2c0c
--- /dev/null
+++ b/charges/snake.svg
@@ -0,0 +1,74 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/snowflake.svg b/charges/snowflake.svg
new file mode 100644
index 00000000..d85d067b
--- /dev/null
+++ b/charges/snowflake.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/charges/spear.svg b/charges/spear.svg
new file mode 100644
index 00000000..9944f9d5
--- /dev/null
+++ b/charges/spear.svg
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/spiral.svg b/charges/spiral.svg
new file mode 100644
index 00000000..05736127
--- /dev/null
+++ b/charges/spiral.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/charges/squirrel.svg b/charges/squirrel.svg
new file mode 100644
index 00000000..bf2cc68b
--- /dev/null
+++ b/charges/squirrel.svg
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/stagLodgedRegardant.svg b/charges/stagLodgedRegardant.svg
new file mode 100644
index 00000000..024f648c
--- /dev/null
+++ b/charges/stagLodgedRegardant.svg
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/stagPassant.svg b/charges/stagPassant.svg
new file mode 100644
index 00000000..745ed25e
--- /dev/null
+++ b/charges/stagPassant.svg
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/stagsAttires.svg b/charges/stagsAttires.svg
new file mode 100644
index 00000000..c8b3692b
--- /dev/null
+++ b/charges/stagsAttires.svg
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/stirrup.svg b/charges/stirrup.svg
new file mode 100644
index 00000000..4350ad26
--- /dev/null
+++ b/charges/stirrup.svg
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/sun.svg b/charges/sun.svg
new file mode 100644
index 00000000..6d58a55c
--- /dev/null
+++ b/charges/sun.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/charges/sunInSplendour.svg b/charges/sunInSplendour.svg
new file mode 100644
index 00000000..4de9c571
--- /dev/null
+++ b/charges/sunInSplendour.svg
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/sunInSplendour2.svg b/charges/sunInSplendour2.svg
new file mode 100644
index 00000000..d56c221d
--- /dev/null
+++ b/charges/sunInSplendour2.svg
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/swallow.svg b/charges/swallow.svg
new file mode 100644
index 00000000..bf363a15
--- /dev/null
+++ b/charges/swallow.svg
@@ -0,0 +1,62 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/swan.svg b/charges/swan.svg
new file mode 100644
index 00000000..26a345f7
--- /dev/null
+++ b/charges/swan.svg
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/swanErased.svg b/charges/swanErased.svg
new file mode 100644
index 00000000..510c380a
--- /dev/null
+++ b/charges/swanErased.svg
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/sword.svg b/charges/sword.svg
new file mode 100644
index 00000000..cdf8853b
--- /dev/null
+++ b/charges/sword.svg
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/talbotPassant.svg b/charges/talbotPassant.svg
new file mode 100644
index 00000000..121e6ba4
--- /dev/null
+++ b/charges/talbotPassant.svg
@@ -0,0 +1,58 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/talbotSejant.svg b/charges/talbotSejant.svg
new file mode 100644
index 00000000..e89d4b90
--- /dev/null
+++ b/charges/talbotSejant.svg
@@ -0,0 +1,75 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/template.svg b/charges/template.svg
new file mode 100644
index 00000000..cad51295
--- /dev/null
+++ b/charges/template.svg
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/thistle.svg b/charges/thistle.svg
new file mode 100644
index 00000000..09cff52a
--- /dev/null
+++ b/charges/thistle.svg
@@ -0,0 +1,70 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/tower.svg b/charges/tower.svg
new file mode 100644
index 00000000..9754803a
--- /dev/null
+++ b/charges/tower.svg
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/tree.svg b/charges/tree.svg
new file mode 100644
index 00000000..0e2854fc
--- /dev/null
+++ b/charges/tree.svg
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/charges/trefle.svg b/charges/trefle.svg
new file mode 100644
index 00000000..8180526b
--- /dev/null
+++ b/charges/trefle.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/charges/trefoil.svg b/charges/trefoil.svg
new file mode 100644
index 00000000..438c993e
--- /dev/null
+++ b/charges/trefoil.svg
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/triangle.svg b/charges/triangle.svg
new file mode 100644
index 00000000..0a06d67c
--- /dev/null
+++ b/charges/triangle.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/charges/trianglePierced.svg b/charges/trianglePierced.svg
new file mode 100644
index 00000000..6bbe2fc2
--- /dev/null
+++ b/charges/trianglePierced.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/charges/trowel.svg b/charges/trowel.svg
new file mode 100644
index 00000000..b9533474
--- /dev/null
+++ b/charges/trowel.svg
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/unicornRampant.svg b/charges/unicornRampant.svg
new file mode 100644
index 00000000..a3102dbc
--- /dev/null
+++ b/charges/unicornRampant.svg
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/wasp.svg b/charges/wasp.svg
new file mode 100644
index 00000000..9d54306c
--- /dev/null
+++ b/charges/wasp.svg
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/wheatStalk.svg b/charges/wheatStalk.svg
new file mode 100644
index 00000000..c6113ccd
--- /dev/null
+++ b/charges/wheatStalk.svg
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/wheel.svg b/charges/wheel.svg
new file mode 100644
index 00000000..6133eee9
--- /dev/null
+++ b/charges/wheel.svg
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/windmill.svg b/charges/windmill.svg
new file mode 100644
index 00000000..b814ef1e
--- /dev/null
+++ b/charges/windmill.svg
@@ -0,0 +1,64 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/wing.svg b/charges/wing.svg
new file mode 100644
index 00000000..d38622f2
--- /dev/null
+++ b/charges/wing.svg
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/wingSword.svg b/charges/wingSword.svg
new file mode 100644
index 00000000..75c2f80e
--- /dev/null
+++ b/charges/wingSword.svg
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/wolfHeadErased.svg b/charges/wolfHeadErased.svg
new file mode 100644
index 00000000..518ea83f
--- /dev/null
+++ b/charges/wolfHeadErased.svg
@@ -0,0 +1,20 @@
+
+
+
+
diff --git a/charges/wolfPassant.svg b/charges/wolfPassant.svg
new file mode 100644
index 00000000..06f8761a
--- /dev/null
+++ b/charges/wolfPassant.svg
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/wolfRampant.svg b/charges/wolfRampant.svg
new file mode 100644
index 00000000..f5c7f57c
--- /dev/null
+++ b/charges/wolfRampant.svg
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/wolfStatant.svg b/charges/wolfStatant.svg
new file mode 100644
index 00000000..d592b9ef
--- /dev/null
+++ b/charges/wolfStatant.svg
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/wyvern.svg b/charges/wyvern.svg
new file mode 100644
index 00000000..f09b821e
--- /dev/null
+++ b/charges/wyvern.svg
@@ -0,0 +1,69 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/charges/wyvernWithWingsDisplayed.svg b/charges/wyvernWithWingsDisplayed.svg
new file mode 100644
index 00000000..d3aef9b4
--- /dev/null
+++ b/charges/wyvernWithWingsDisplayed.svg
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/components/fill-box.js b/components/fill-box.js
new file mode 100644
index 00000000..b4d075c3
--- /dev/null
+++ b/components/fill-box.js
@@ -0,0 +1,74 @@
+{
+ const style = /* css */ `
+ fill-box:not([disabled]) {
+ cursor: pointer;
+ }
+
+ fill-box > svg {
+ vertical-align: middle;
+ pointer-events: none;
+ }
+
+ fill-box > svg > rect {
+ stroke: #666666;
+ stroke-width: 2;
+ }
+ `;
+
+ const styleElement = document.createElement("style");
+ styleElement.setAttribute("type", "text/css");
+ styleElement.innerHTML = style;
+ document.head.appendChild(styleElement);
+}
+
+{
+ const template = document.createElement("template");
+ template.innerHTML = /* html */ `
+
+
+
+ `;
+
+ class FillBox extends HTMLElement {
+ constructor() {
+ super();
+
+ this.appendChild(template.content.cloneNode(true));
+ this.querySelector("rect")?.setAttribute("fill", this.fill);
+ this.querySelector("svg")?.setAttribute("width", this.size);
+ this.querySelector("svg")?.setAttribute("height", this.size);
+ }
+
+ static showTip() {
+ tip(this.tip);
+ }
+
+ connectedCallback() {
+ this.addEventListener("mousemove", this.constructor.showTip);
+ }
+
+ disconnectedCallback() {
+ this.removeEventListener("mousemove", this.constructor.showTip);
+ }
+
+ get fill() {
+ return this.getAttribute("fill") || "#333";
+ }
+
+ set fill(newFill) {
+ this.setAttribute("fill", newFill);
+ this.querySelector("rect")?.setAttribute("fill", newFill);
+ }
+
+ get size() {
+ return this.getAttribute("size") || "1em";
+ }
+
+ get tip() {
+ return this.dataset.tip || "Fill style. Click to change";
+ }
+ }
+
+ // cannot use Shadow DOM here as need an access to svg hatches
+ customElements.define("fill-box", FillBox);
+}
diff --git a/components/slider-input.js b/components/slider-input.js
new file mode 100644
index 00000000..f1732027
--- /dev/null
+++ b/components/slider-input.js
@@ -0,0 +1,78 @@
+{
+ const style = /* css */ `
+ slider-input {
+ display: flex;
+ align-items: center;
+ gap: .4em;
+ }
+ `;
+
+ const styleElement = document.createElement("style");
+ styleElement.setAttribute("type", "text/css");
+ styleElement.innerHTML = style;
+ document.head.appendChild(styleElement);
+}
+
+{
+ const template = document.createElement("template");
+ template.innerHTML = /* html */ `
+
+
+ `;
+
+ class SliderInput extends HTMLElement {
+ constructor() {
+ super();
+ this.appendChild(template.content.cloneNode(true));
+
+ const range = this.querySelector("input[type=range]");
+ const number = this.querySelector("input[type=number]");
+
+ range.value = number.value = this.value || this.getAttribute("value") || 50;
+ range.min = number.min = this.getAttribute("min") || 0;
+ range.max = number.max = this.getAttribute("max") || 100;
+ range.step = number.step = this.getAttribute("step") || 1;
+
+ range.addEventListener("input", this.handleEvent.bind(this));
+ number.addEventListener("input", this.handleEvent.bind(this));
+ range.addEventListener("change", this.handleEvent.bind(this));
+ number.addEventListener("change", this.handleEvent.bind(this));
+ }
+
+ handleEvent(e) {
+ const value = e.target.value;
+ const isNaN = Number.isNaN(Number(value));
+ if (isNaN || value === "") return e.stopPropagation();
+
+ const range = this.querySelector("input[type=range]");
+ const number = this.querySelector("input[type=number]");
+ this.value = range.value = number.value = value;
+
+ this.dispatchEvent(
+ new CustomEvent(e.type, {
+ detail: {value},
+ bubbles: true,
+ composed: true
+ })
+ );
+ }
+
+ set value(value) {
+ const range = this.querySelector("input[type=range]");
+ const number = this.querySelector("input[type=number]");
+ range.value = number.value = value;
+ }
+
+ get value() {
+ const number = this.querySelector("input[type=number]");
+ return number.value;
+ }
+
+ get valueAsNumber() {
+ const number = this.querySelector("input[type=number]");
+ return number.valueAsNumber;
+ }
+ }
+
+ customElements.define("slider-input", SliderInput);
+}
diff --git a/config/heightmap-templates.js b/config/heightmap-templates.js
new file mode 100644
index 00000000..29738609
--- /dev/null
+++ b/config/heightmap-templates.js
@@ -0,0 +1,166 @@
+"use strict";
+
+const heightmapTemplates = (function () {
+ const volcano = `Hill 1 90-100 44-56 40-60
+ Multiply 0.8 50-100 0 0
+ Range 1.5 30-55 45-55 40-60
+ Smooth 3 0 0 0
+ Hill 1.5 35-45 25-30 20-75
+ Hill 1 35-55 75-80 25-75
+ Hill 0.5 20-25 10-15 20-25
+ Mask 3 0 0 0`;
+
+ const highIsland = `Hill 1 90-100 65-75 47-53
+ Add 7 all 0 0
+ Hill 5-6 20-30 25-55 45-55
+ Range 1 40-50 45-55 45-55
+ Multiply 0.8 land 0 0
+ Mask 3 0 0 0
+ Smooth 2 0 0 0
+ Trough 2-3 20-30 20-30 20-30
+ Trough 2-3 20-30 60-80 70-80
+ Hill 1 10-15 60-60 50-50
+ Hill 1.5 13-16 15-20 20-75
+ Range 1.5 30-40 15-85 30-40
+ Range 1.5 30-40 15-85 60-70
+ Pit 3-5 10-30 15-85 20-80`;
+
+ const lowIsland = `Hill 1 90-99 60-80 45-55
+ Hill 1-2 20-30 10-30 10-90
+ Smooth 2 0 0 0
+ Hill 6-7 25-35 20-70 30-70
+ Range 1 40-50 45-55 45-55
+ Trough 2-3 20-30 15-85 20-30
+ Trough 2-3 20-30 15-85 70-80
+ Hill 1.5 10-15 5-15 20-80
+ Hill 1 10-15 85-95 70-80
+ Pit 5-7 15-25 15-85 20-80
+ Multiply 0.4 20-100 0 0
+ Mask 4 0 0 0`;
+
+ const continents = `Hill 1 80-85 60-80 40-60
+ Hill 1 80-85 20-30 40-60
+ Hill 6-7 15-30 25-75 15-85
+ Multiply 0.6 land 0 0
+ Hill 8-10 5-10 15-85 20-80
+ Range 1-2 30-60 5-15 25-75
+ Range 1-2 30-60 80-95 25-75
+ Range 0-3 30-60 80-90 20-80
+ Strait 2 vertical 0 0
+ Strait 1 vertical 0 0
+ Smooth 3 0 0 0
+ Trough 3-4 15-20 15-85 20-80
+ Trough 3-4 5-10 45-55 45-55
+ Pit 3-4 10-20 15-85 20-80
+ Mask 4 0 0 0`;
+
+ const archipelago = `Add 11 all 0 0
+ Range 2-3 40-60 20-80 20-80
+ Hill 5 15-20 10-90 30-70
+ Hill 2 10-15 10-30 20-80
+ Hill 2 10-15 60-90 20-80
+ Smooth 3 0 0 0
+ Trough 10 20-30 5-95 5-95
+ Strait 2 vertical 0 0
+ Strait 2 horizontal 0 0`;
+
+ const atoll = `Hill 1 75-80 50-60 45-55
+ Hill 1.5 30-50 25-75 30-70
+ Hill .5 30-50 25-35 30-70
+ Smooth 1 0 0 0
+ Multiply 0.2 25-100 0 0
+ Hill 0.5 10-20 50-55 48-52`;
+
+ const mediterranean = `Range 4-6 30-80 0-100 0-10
+ Range 4-6 30-80 0-100 90-100
+ Hill 6-8 30-50 10-90 0-5
+ Hill 6-8 30-50 10-90 95-100
+ Multiply 0.9 land 0 0
+ Mask -2 0 0 0
+ Smooth 1 0 0 0
+ Hill 2-3 30-70 0-5 20-80
+ Hill 2-3 30-70 95-100 20-80
+ Trough 3-6 40-50 0-100 0-10
+ Trough 3-6 40-50 0-100 90-100`;
+
+ const peninsula = `Range 2-3 20-35 40-50 0-15
+ Add 5 all 0 0
+ Hill 1 90-100 10-90 0-5
+ Add 13 all 0 0
+ Hill 3-4 3-5 5-95 80-100
+ Hill 1-2 3-5 5-95 40-60
+ Trough 5-6 10-25 5-95 5-95
+ Smooth 3 0 0 0
+ Invert 0.4 both 0 0`;
+
+ const pangea = `Hill 1-2 25-40 15-50 0-10
+ Hill 1-2 5-40 50-85 0-10
+ Hill 1-2 25-40 50-85 90-100
+ Hill 1-2 5-40 15-50 90-100
+ Hill 8-12 20-40 20-80 48-52
+ Smooth 2 0 0 0
+ Multiply 0.7 land 0 0
+ Trough 3-4 25-35 5-95 10-20
+ Trough 3-4 25-35 5-95 80-90
+ Range 5-6 30-40 10-90 35-65`;
+
+ const isthmus = `Hill 5-10 15-30 0-30 0-20
+ Hill 5-10 15-30 10-50 20-40
+ Hill 5-10 15-30 30-70 40-60
+ Hill 5-10 15-30 50-90 60-80
+ Hill 5-10 15-30 70-100 80-100
+ Smooth 2 0 0 0
+ Trough 4-8 15-30 0-30 0-20
+ Trough 4-8 15-30 10-50 20-40
+ Trough 4-8 15-30 30-70 40-60
+ Trough 4-8 15-30 50-90 60-80
+ Trough 4-8 15-30 70-100 80-100
+ Invert 0.25 x 0 0`;
+
+ const shattered = `Hill 8 35-40 15-85 30-70
+ Trough 10-20 40-50 5-95 5-95
+ Range 5-7 30-40 10-90 20-80
+ Pit 12-20 30-40 15-85 20-80`;
+
+ const taklamakan = `Hill 1-3 20-30 30-70 30-70
+ Hill 2-4 60-85 0-5 0-100
+ Hill 2-4 60-85 95-100 0-100
+ Hill 3-4 60-85 20-80 0-5
+ Hill 3-4 60-85 20-80 95-100
+ Smooth 3 0 0 0`;
+
+ const oldWorld = `Range 3 70 15-85 20-80
+ Hill 2-3 50-70 15-45 20-80
+ Hill 2-3 50-70 65-85 20-80
+ Hill 4-6 20-25 15-85 20-80
+ Multiply 0.5 land 0 0
+ Smooth 2 0 0 0
+ Range 3-4 20-50 15-35 20-45
+ Range 2-4 20-50 65-85 45-80
+ Strait 3-7 vertical 0 0
+ Trough 6-8 20-50 15-85 45-65
+ Pit 5-6 20-30 10-90 10-90`;
+
+ const fractious = `Hill 12-15 50-80 5-95 5-95
+ Mask -1.5 0 0 0
+ Mask 3 0 0 0
+ Add -20 30-100 0 0
+ Range 6-8 40-50 5-95 10-90`;
+
+ return {
+ volcano: {id: 0, name: "Volcano", template: volcano, probability: 3},
+ highIsland: {id: 1, name: "High Island", template: highIsland, probability: 19},
+ lowIsland: {id: 2, name: "Low Island", template: lowIsland, probability: 9},
+ continents: {id: 3, name: "Continents", template: continents, probability: 16},
+ archipelago: {id: 4, name: "Archipelago", template: archipelago, probability: 18},
+ atoll: {id: 5, name: "Atoll", template: atoll, probability: 1},
+ mediterranean: {id: 6, name: "Mediterranean", template: mediterranean, probability: 5},
+ peninsula: {id: 7, name: "Peninsula", template: peninsula, probability: 3},
+ pangea: {id: 8, name: "Pangea", template: pangea, probability: 5},
+ isthmus: {id: 9, name: "Isthmus", template: isthmus, probability: 2},
+ shattered: {id: 10, name: "Shattered", template: shattered, probability: 7},
+ taklamakan: {id: 11, name: "Taklamakan", template: taklamakan, probability: 1},
+ oldWorld: {id: 12, name: "Old World", template: oldWorld, probability: 8},
+ fractious: {id: 13, name: "Fractious", template: fractious, probability: 3}
+ };
+})();
diff --git a/config/precreated-heightmaps.js b/config/precreated-heightmaps.js
new file mode 100644
index 00000000..22f45abd
--- /dev/null
+++ b/config/precreated-heightmaps.js
@@ -0,0 +1,27 @@
+"use strict";
+
+const precreatedHeightmaps = {
+ "africa-centric": {id: 0, name: "Africa Centric"},
+ arabia: {id: 1, name: "Arabia"},
+ atlantics: {id: 2, name: "Atlantics"},
+ britain: {id: 3, name: "Britain"},
+ caribbean: {id: 4, name: "Caribbean"},
+ "east-asia": {id: 5, name: "East Asia"},
+ eurasia: {id: 6, name: "Eurasia"},
+ europe: {id: 7, name: "Europe"},
+ "europe-accented": {id: 8, name: "Europe Accented"},
+ "europe-and-central-asia": {id: 9, name: "Europe and Central Asia"},
+ "europe-central": {id: 10, name: "Europe Central"},
+ "europe-north": {id: 11, name: "Europe North"},
+ greenland: {id: 12, name: "Greenland"},
+ hellenica: {id: 13, name: "Hellenica"},
+ iceland: {id: 14, name: "Iceland"},
+ "indian-ocean": {id: 15, name: "Indian Ocean"},
+ "mediterranean-sea": {id: 16, name: "Mediterranean Sea"},
+ "middle-east": {id: 17, name: "Middle East"},
+ "north-america": {id: 18, name: "North America"},
+ "us-centric": {id: 19, name: "US-centric"},
+ "us-mainland": {id: 20, name: "US Mainland"},
+ world: {id: 21, name: "World"},
+ "world-from-pacific": {id: 22, name: "World from Pacific"}
+};
diff --git a/dropbox.html b/dropbox.html
new file mode 100644
index 00000000..cd1921da
--- /dev/null
+++ b/dropbox.html
@@ -0,0 +1,48 @@
+
+
+
+
+
+ FMG Dropbox Auth
+
+
+
+
+
diff --git a/fonts.css b/fonts.css
deleted file mode 100644
index c1cd22bc..00000000
--- a/fonts.css
+++ /dev/null
@@ -1,175 +0,0 @@
-@font-face {
- font-family: 'Amatic SC';
- font-style: normal;
- font-weight: 700;
- src: local('Amatic SC Bold'), local('AmaticSC-Bold'), url(https://fonts.gstatic.com/s/amaticsc/v11/TUZ3zwprpvBS1izr_vOMscGKfrUC.woff2) format('woff2');
- unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
-}
-
-@font-face {
- font-family: 'Architects Daughter';
- font-style: normal;
- font-weight: 400;
- src: local('Architects Daughter Regular'), local('ArchitectsDaughter-Regular'), url(https://fonts.gstatic.com/s/architectsdaughter/v8/RXTgOOQ9AAtaVOHxx0IUBM3t7GjCYufj5TXV5VnA2p8.woff2) format('woff2');
- unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215;
-}
-
-@font-face {
- font-family: 'Bitter';
- font-style: normal;
- font-weight: 400;
- src: local('Bitter Regular'), local('Bitter-Regular'), url(https://fonts.gstatic.com/s/bitter/v12/zfs6I-5mjWQ3nxqccMoL2A.woff2) format('woff2');
- unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215;
-}
-
-@font-face {
- font-family: 'Caesar Dressing';
- font-style: normal;
- font-weight: 400;
- src: local('Caesar Dressing'), local('CaesarDressing-Regular'), url(https://fonts.gstatic.com/s/caesardressing/v6/yYLx0hLa3vawqtwdswbotmK4vrRHdrz7.woff2) format('woff2');
- unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
-}
-
-@font-face {
- font-family: 'Cinzel';
- font-style: normal;
- font-weight: 400;
- src: local('Cinzel Regular'), local('Cinzel-Regular'), url(https://fonts.gstatic.com/s/cinzel/v7/zOdksD_UUTk1LJF9z4tURA.woff2) format('woff2');
- unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215;
-}
-
-@font-face {
- font-family: 'Comfortaa';
- font-style: normal;
- font-weight: 700;
- src: local('Comfortaa Bold'), local('Comfortaa-Bold'), url(https://fonts.gstatic.com/s/comfortaa/v12/fND5XPYKrF2tQDwwfWZJI-gdm0LZdjqr5-oayXSOefg.woff2) format('woff2');
- unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215;
-}
-
-@font-face {
- font-family: 'Dancing Script';
- font-style: normal;
- font-weight: 700;
- src: local('Dancing Script Bold'), local('DancingScript-Bold'), url(https://fonts.gstatic.com/s/dancingscript/v9/KGBfwabt0ZRLA5W1ywjowUHdOuSHeh0r6jGTOGdAKHA.woff2) format('woff2');
- unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215;
-}
-
-@font-face {
- font-family: 'Fredericka the Great';
- font-style: normal;
- font-weight: 400;
- src: local('Fredericka the Great'), local('FrederickatheGreat'), url(https://fonts.gstatic.com/s/frederickathegreat/v6/9Bt33CxNwt7aOctW2xjbCstzwVKsIBVV--Sjxbc.woff2) format('woff2');
- unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
-}
-
-@font-face {
- font-family: 'Gloria Hallelujah';
- font-style: normal;
- font-weight: 400;
- src: local('Gloria Hallelujah'), local('GloriaHallelujah'), url(https://fonts.gstatic.com/s/gloriahallelujah/v9/CA1k7SlXcY5kvI81M_R28cNDay8z-hHR7F16xrcXsJw.woff2) format('woff2');
- unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215;
-}
-
-@font-face {
- font-family: 'Great Vibes';
- font-style: normal;
- font-weight: 400;
- src: local('Great Vibes'), local('GreatVibes-Regular'), url(https://fonts.gstatic.com/s/greatvibes/v5/6q1c0ofG6NKsEhAc2eh-3Y4P5ICox8Kq3LLUNMylGO4.woff2) format('woff2');
- unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215;
-}
-
-@font-face {
- font-family: 'IM Fell English';
- font-style: normal;
- font-weight: 400;
- src: local('IM FELL English Roman'), local('IM_FELL_English_Roman'), url(https://fonts.gstatic.com/s/imfellenglish/v7/xwIisCqGFi8pff-oa9uSVAkYLEKE0CJQa8tfZYc_plY.woff2) format('woff2');
- unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215;
-}
-
-@font-face {
- font-family: 'Kaushan Script';
- font-style: normal;
- font-weight: 400;
- src: local('Kaushan Script'), local('KaushanScript-Regular'), url(https://fonts.gstatic.com/s/kaushanscript/v6/qx1LSqts-NtiKcLw4N03IEd0sm1ffa_JvZxsF_BEwQk.woff2) format('woff2');
- unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215;
-}
-
-@font-face {
- font-family: 'MedievalSharp';
- font-style: normal;
- font-weight: 400;
- src: local('MedievalSharp'), url(https://fonts.gstatic.com/s/medievalsharp/v9/EvOJzAlL3oU5AQl2mP5KdgptMqhwMg.woff2) format('woff2');
- unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
-}
-
-@font-face {
- font-family: 'Metamorphous';
- font-style: normal;
- font-weight: 400;
- src: local('Metamorphous'), url(https://fonts.gstatic.com/s/metamorphous/v7/Wnz8HA03aAXcC39ZEX5y133EOyqs.woff2) format('woff2');
- unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
-}
-
-@font-face {
- font-family: 'Montez';
- font-style: normal;
- font-weight: 400;
- src: local('Montez Regular'), local('Montez-Regular'), url(https://fonts.gstatic.com/s/montez/v8/aq8el3-0osHIcFK6bXAPkw.woff2) format('woff2');
- unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215;
-}
-
-@font-face {
- font-family: 'Nova Script';
- font-style: normal;
- font-weight: 400;
- src: local('Nova Script Regular'), local('NovaScript-Regular'), url(https://fonts.gstatic.com/s/novascript/v10/7Au7p_IpkSWSTWaFWkumvlQKGFw.woff2) format('woff2');
- unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
-}
-
-@font-face {
- font-family: 'Orbitron';
- font-style: normal;
- font-weight: 400;
- src: local('Orbitron Regular'), local('Orbitron-Regular'), url(https://fonts.gstatic.com/s/orbitron/v9/HmnHiRzvcnQr8CjBje6GQvesZW2xOQ-xsNqO47m55DA.woff2) format('woff2');
- unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215;
-}
-
-@font-face {
- font-family: 'Satisfy';
- font-style: normal;
- font-weight: 400;
- src: local('Satisfy Regular'), local('Satisfy-Regular'), url(https://fonts.gstatic.com/s/satisfy/v8/2OzALGYfHwQjkPYWELy-cw.woff2) format('woff2');
- unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215;
-}
-
-@font-face {
- font-family: 'Shadows Into Light';
- font-style: normal;
- font-weight: 400;
- src: local('Shadows Into Light'), local('ShadowsIntoLight'), url(https://fonts.gstatic.com/s/shadowsintolight/v7/clhLqOv7MXn459PTh0gXYFK2TSYBz0eNcHnp4YqE4Ts.woff2) format('woff2');
- unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215;
-}
-
-@font-face {
- font-family: 'Uncial Antiqua';
- font-style: normal;
- font-weight: 400;
- src: local('Uncial Antiqua'), local('UncialAntiqua-Regular'), url(https://fonts.gstatic.com/s/uncialantiqua/v5/N0bM2S5WOex4OUbESzoESK-i-MfWQZQ.woff2) format('woff2');
- unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
-}
-
-@font-face {
- font-family: 'Underdog';
- font-style: normal;
- font-weight: 400;
- src: local('Underdog'), local('Underdog-Regular'), url(https://fonts.gstatic.com/s/underdog/v6/CHygV-jCElj7diMroWSlWV8.woff2) format('woff2');
- unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
-}
-
-@font-face {
- font-family: 'Yellowtail';
- font-style: normal;
- font-weight: 400;
- src: local('Yellowtail Regular'), local('Yellowtail-Regular'), url(https://fonts.gstatic.com/s/yellowtail/v8/GcIHC9QEwVkrA19LJU1qlPk_vArhqVIZ0nv9q090hN8.woff2) format('woff2');
- unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215;
-}
diff --git a/heightmaps/africa-centric.png b/heightmaps/africa-centric.png
new file mode 100644
index 00000000..02e4a311
Binary files /dev/null and b/heightmaps/africa-centric.png differ
diff --git a/heightmaps/arabia.png b/heightmaps/arabia.png
new file mode 100644
index 00000000..27946711
Binary files /dev/null and b/heightmaps/arabia.png differ
diff --git a/heightmaps/atlantics.png b/heightmaps/atlantics.png
new file mode 100644
index 00000000..be123705
Binary files /dev/null and b/heightmaps/atlantics.png differ
diff --git a/heightmaps/britain.png b/heightmaps/britain.png
new file mode 100644
index 00000000..60e08da4
Binary files /dev/null and b/heightmaps/britain.png differ
diff --git a/heightmaps/caribbean.png b/heightmaps/caribbean.png
new file mode 100644
index 00000000..e4a8ed05
Binary files /dev/null and b/heightmaps/caribbean.png differ
diff --git a/heightmaps/east-asia.png b/heightmaps/east-asia.png
new file mode 100644
index 00000000..41144db5
Binary files /dev/null and b/heightmaps/east-asia.png differ
diff --git a/heightmaps/eurasia.png b/heightmaps/eurasia.png
new file mode 100644
index 00000000..bdbdb4d7
Binary files /dev/null and b/heightmaps/eurasia.png differ
diff --git a/heightmaps/europe-accented.png b/heightmaps/europe-accented.png
new file mode 100644
index 00000000..9be9480e
Binary files /dev/null and b/heightmaps/europe-accented.png differ
diff --git a/heightmaps/europe-and-central-asia.png b/heightmaps/europe-and-central-asia.png
new file mode 100644
index 00000000..c23e97ed
Binary files /dev/null and b/heightmaps/europe-and-central-asia.png differ
diff --git a/heightmaps/europe-central.png b/heightmaps/europe-central.png
new file mode 100644
index 00000000..b220f546
Binary files /dev/null and b/heightmaps/europe-central.png differ
diff --git a/heightmaps/europe-north.png b/heightmaps/europe-north.png
new file mode 100644
index 00000000..1bb49184
Binary files /dev/null and b/heightmaps/europe-north.png differ
diff --git a/heightmaps/europe.png b/heightmaps/europe.png
new file mode 100644
index 00000000..59dfdfea
Binary files /dev/null and b/heightmaps/europe.png differ
diff --git a/heightmaps/greenland.png b/heightmaps/greenland.png
new file mode 100644
index 00000000..3136c539
Binary files /dev/null and b/heightmaps/greenland.png differ
diff --git a/heightmaps/hellenica.png b/heightmaps/hellenica.png
new file mode 100644
index 00000000..2681d6ec
Binary files /dev/null and b/heightmaps/hellenica.png differ
diff --git a/heightmaps/iceland.png b/heightmaps/iceland.png
new file mode 100644
index 00000000..88463158
Binary files /dev/null and b/heightmaps/iceland.png differ
diff --git a/heightmaps/import-rules.txt b/heightmaps/import-rules.txt
new file mode 100644
index 00000000..69499114
--- /dev/null
+++ b/heightmaps/import-rules.txt
@@ -0,0 +1,8 @@
+To get heightmap with correct height scale:
+1. Open https://tangrams.github.io/heightmapper
+2. Toggle off auto-exposure
+3. Set max elevation to 2000
+4. Set min elevation to -500
+5. Find region you like
+6. Render image
+7. Optionally rescale image to a smaller size (e.g. 500x300px) as high resolution is not used
diff --git a/heightmaps/indian-ocean.png b/heightmaps/indian-ocean.png
new file mode 100644
index 00000000..860ca952
Binary files /dev/null and b/heightmaps/indian-ocean.png differ
diff --git a/heightmaps/mediterranean-sea.png b/heightmaps/mediterranean-sea.png
new file mode 100644
index 00000000..6a7c8bb3
Binary files /dev/null and b/heightmaps/mediterranean-sea.png differ
diff --git a/heightmaps/middle-east.png b/heightmaps/middle-east.png
new file mode 100644
index 00000000..bfcc55bb
Binary files /dev/null and b/heightmaps/middle-east.png differ
diff --git a/heightmaps/north-america.png b/heightmaps/north-america.png
new file mode 100644
index 00000000..1c1f1ad5
Binary files /dev/null and b/heightmaps/north-america.png differ
diff --git a/heightmaps/us-centric.png b/heightmaps/us-centric.png
new file mode 100644
index 00000000..7094df6a
Binary files /dev/null and b/heightmaps/us-centric.png differ
diff --git a/heightmaps/us-mainland.png b/heightmaps/us-mainland.png
new file mode 100644
index 00000000..3b1984e7
Binary files /dev/null and b/heightmaps/us-mainland.png differ
diff --git a/heightmaps/world-from-pacific.png b/heightmaps/world-from-pacific.png
new file mode 100644
index 00000000..02043165
Binary files /dev/null and b/heightmaps/world-from-pacific.png differ
diff --git a/heightmaps/world.png b/heightmaps/world.png
new file mode 100644
index 00000000..22a79298
Binary files /dev/null and b/heightmaps/world.png differ
diff --git a/icons.css b/icons.css
index eab23067..4740f091 100644
--- a/icons.css
+++ b/icons.css
@@ -252,17 +252,8 @@
.icon-if:before {font-style: italic; font-weight: bold;content:'if';}
.icon-coa:before {content:'\f3ed'; font-size: .9em; color: #999;} /* '' */
.icon-half:before {font-weight: bold;content:'½';}
-.icon-curve:before {content: 'C';}
-.icon-area:before {content: 'O';}
-.icon-curve:before,
-.icon-area:before {
- font-size: 1.5em;
- padding: 0;
- writing-mode: tb-rl;
- margin-left: 1px;
- width: .6em;
- font-family: monospace;
-}
+.icon-voice:before {content:'🔊';}
+.icon-robot:before {content:'🤖';}
.icon-die:before {content:'🎲';}
.icon-button-die:before {content:'🎲'; padding-right: .4em;}
.icon-button-power:before {content:'💪'; padding-right: .6em;}
@@ -295,4 +286,5 @@
.icon-button-siege:before {content:'🏰'; padding-right: .4em;}
.icon-button-ambush:before {content:'🌳'; padding-right: .4em;}
.icon-button-landing:before {content:'⚓'; padding-right: .4em;}
-.icon-button-air:before {content:'💨'; padding-right: .4em;}
\ No newline at end of file
+.icon-button-air:before {content:'💨'; padding-right: .4em;}
+.icon-button-screenshot:before {content:'🖥️'; padding-right: .4em;}
diff --git a/images/Discord.png b/images/Discord.png
new file mode 100644
index 00000000..78dab317
Binary files /dev/null and b/images/Discord.png differ
diff --git a/images/Tumblr.png b/images/Tumblr.png
deleted file mode 100644
index 2b65ddad..00000000
Binary files a/images/Tumblr.png and /dev/null differ
diff --git a/images/favicon-32x32.png b/images/favicon-32x32.png
deleted file mode 100644
index e1815ea8..00000000
Binary files a/images/favicon-32x32.png and /dev/null differ
diff --git a/images/icon.ico b/images/icon.ico
deleted file mode 100644
index 78e496d0..00000000
Binary files a/images/icon.ico and /dev/null differ
diff --git a/images/favicon-16x16.png b/images/icons/favicon-16x16.png
similarity index 100%
rename from images/favicon-16x16.png
rename to images/icons/favicon-16x16.png
diff --git a/images/icons/favicon-32x32.png b/images/icons/favicon-32x32.png
new file mode 100644
index 00000000..13e5179d
Binary files /dev/null and b/images/icons/favicon-32x32.png differ
diff --git a/images/icons/icon_x512.png b/images/icons/icon_x512.png
new file mode 100644
index 00000000..f1f8c9aa
Binary files /dev/null and b/images/icons/icon_x512.png differ
diff --git a/images/icons/maskable_icon_x128.png b/images/icons/maskable_icon_x128.png
new file mode 100644
index 00000000..fa877d1b
Binary files /dev/null and b/images/icons/maskable_icon_x128.png differ
diff --git a/images/icons/maskable_icon_x192.png b/images/icons/maskable_icon_x192.png
new file mode 100644
index 00000000..3322eab3
Binary files /dev/null and b/images/icons/maskable_icon_x192.png differ
diff --git a/images/icons/maskable_icon_x384.png b/images/icons/maskable_icon_x384.png
new file mode 100644
index 00000000..c7e7e705
Binary files /dev/null and b/images/icons/maskable_icon_x384.png differ
diff --git a/images/icons/maskable_icon_x512.png b/images/icons/maskable_icon_x512.png
new file mode 100644
index 00000000..5b2361fd
Binary files /dev/null and b/images/icons/maskable_icon_x512.png differ
diff --git a/images/kiwiroo.png b/images/kiwiroo.png
new file mode 100644
index 00000000..4f34ae7e
Binary files /dev/null and b/images/kiwiroo.png differ
diff --git a/images/pattern1.png b/images/pattern1.png
new file mode 100644
index 00000000..59375796
Binary files /dev/null and b/images/pattern1.png differ
diff --git a/images/pattern2.png b/images/pattern2.png
new file mode 100644
index 00000000..e96f68fa
Binary files /dev/null and b/images/pattern2.png differ
diff --git a/images/pattern3.png b/images/pattern3.png
new file mode 100644
index 00000000..636fde6f
Binary files /dev/null and b/images/pattern3.png differ
diff --git a/images/pattern4.png b/images/pattern4.png
new file mode 100644
index 00000000..d96aa18a
Binary files /dev/null and b/images/pattern4.png differ
diff --git a/images/pattern5.png b/images/pattern5.png
new file mode 100644
index 00000000..82a2af7c
Binary files /dev/null and b/images/pattern5.png differ
diff --git a/images/pattern6.png b/images/pattern6.png
new file mode 100644
index 00000000..dc9271ef
Binary files /dev/null and b/images/pattern6.png differ
diff --git a/images/preview.png b/images/preview.png
index aaa8459c..2b150732 100644
Binary files a/images/preview.png and b/images/preview.png differ
diff --git a/images/textures/antique-big.jpg b/images/textures/antique-big.jpg
new file mode 100644
index 00000000..711b1681
Binary files /dev/null and b/images/textures/antique-big.jpg differ
diff --git a/images/textures/antique-small.jpg b/images/textures/antique-small.jpg
new file mode 100644
index 00000000..851b5d07
Binary files /dev/null and b/images/textures/antique-small.jpg differ
diff --git a/images/textures/folded-paper-big.jpg b/images/textures/folded-paper-big.jpg
new file mode 100644
index 00000000..c2c4d761
Binary files /dev/null and b/images/textures/folded-paper-big.jpg differ
diff --git a/images/textures/folded-paper-small.jpg b/images/textures/folded-paper-small.jpg
new file mode 100644
index 00000000..88418a13
Binary files /dev/null and b/images/textures/folded-paper-small.jpg differ
diff --git a/images/textures/gray-paper.jpg b/images/textures/gray-paper.jpg
new file mode 100644
index 00000000..238d6e4c
Binary files /dev/null and b/images/textures/gray-paper.jpg differ
diff --git a/images/textures/iran-small.jpg b/images/textures/iran-small.jpg
new file mode 100644
index 00000000..39f34512
Binary files /dev/null and b/images/textures/iran-small.jpg differ
diff --git a/images/textures/marble-big.jpg b/images/textures/marble-big.jpg
new file mode 100644
index 00000000..c1d2a6d4
Binary files /dev/null and b/images/textures/marble-big.jpg differ
diff --git a/images/textures/marble-blue-big.jpg b/images/textures/marble-blue-big.jpg
new file mode 100644
index 00000000..dbfc0975
Binary files /dev/null and b/images/textures/marble-blue-big.jpg differ
diff --git a/images/textures/marble-blue-small.jpg b/images/textures/marble-blue-small.jpg
new file mode 100644
index 00000000..2e95fdcb
Binary files /dev/null and b/images/textures/marble-blue-small.jpg differ
diff --git a/images/textures/marble-small.jpg b/images/textures/marble-small.jpg
new file mode 100644
index 00000000..10d1a9ab
Binary files /dev/null and b/images/textures/marble-small.jpg differ
diff --git a/images/textures/mars-big.jpg b/images/textures/mars-big.jpg
new file mode 100644
index 00000000..3fd39dae
Binary files /dev/null and b/images/textures/mars-big.jpg differ
diff --git a/images/textures/mars-small.jpg b/images/textures/mars-small.jpg
new file mode 100644
index 00000000..75de8dd3
Binary files /dev/null and b/images/textures/mars-small.jpg differ
diff --git a/images/textures/mauritania-small.jpg b/images/textures/mauritania-small.jpg
new file mode 100644
index 00000000..22d9cecf
Binary files /dev/null and b/images/textures/mauritania-small.jpg differ
diff --git a/images/textures/mercury-big.jpg b/images/textures/mercury-big.jpg
new file mode 100644
index 00000000..7e06f0ee
Binary files /dev/null and b/images/textures/mercury-big.jpg differ
diff --git a/images/textures/mercury-small.jpg b/images/textures/mercury-small.jpg
new file mode 100644
index 00000000..53f31ee3
Binary files /dev/null and b/images/textures/mercury-small.jpg differ
diff --git a/images/textures/ocean.jpg b/images/textures/ocean.jpg
new file mode 100644
index 00000000..981366ca
Binary files /dev/null and b/images/textures/ocean.jpg differ
diff --git a/images/textures/pergamena-small.jpg b/images/textures/pergamena-small.jpg
new file mode 100644
index 00000000..951f9eda
Binary files /dev/null and b/images/textures/pergamena-small.jpg differ
diff --git a/images/textures/plaster.jpg b/images/textures/plaster.jpg
new file mode 100644
index 00000000..8ec85c81
Binary files /dev/null and b/images/textures/plaster.jpg differ
diff --git a/images/textures/soiled-paper-vertical.png b/images/textures/soiled-paper-vertical.png
new file mode 100644
index 00000000..f8bb720e
Binary files /dev/null and b/images/textures/soiled-paper-vertical.png differ
diff --git a/images/textures/soiled-paper.jpg b/images/textures/soiled-paper.jpg
new file mode 100644
index 00000000..00333992
Binary files /dev/null and b/images/textures/soiled-paper.jpg differ
diff --git a/images/textures/spain-small.jpg b/images/textures/spain-small.jpg
new file mode 100644
index 00000000..a413f508
Binary files /dev/null and b/images/textures/spain-small.jpg differ
diff --git a/images/textures/timbercut-big.jpg b/images/textures/timbercut-big.jpg
new file mode 100644
index 00000000..7dc9b656
Binary files /dev/null and b/images/textures/timbercut-big.jpg differ
diff --git a/images/textures/timbercut-small.jpg b/images/textures/timbercut-small.jpg
new file mode 100644
index 00000000..a73e47be
Binary files /dev/null and b/images/textures/timbercut-small.jpg differ
diff --git a/index.css b/index.css
index 57d0df7f..373bf63c 100644
--- a/index.css
+++ b/index.css
@@ -1,856 +1,988 @@
-@font-face {
- font-family: 'Almendra SC';
- font-style: normal;
- font-weight: 400;
- src: url(data:application/font-woff2;charset=utf-8;base64,d09GMgABAAAAAC5cAA4AAAAAdigAAC3+AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP0ZGVE0cGh4GYACDKhEICoHQKIGbKAuDJgABNgIkA4ZIBCAFhwQHg0sMBxsLWRNuLDxsHDAWEA8WUTUaS/ZfJfAEJtXwF2CTqKhq1GldrigpJuuZzpbfwBe3GHB3cREO4XjwXN7Hx0/8dYQMuT0E2+yoMBGdGMMADEoUGyVaEAkDCQVRDKza5lxYsdS5vUtdZLnI+KrFp/zz/cXOf7sgURpYIlEzESceYJxgpFHAYXP5f+rg987dPz+xJoo4zKyKKORUdmFudWLp5ri1ToiVgzC5h5J686RIImzq1flJr8Yrh2sqbnTZMpg+Bqe0mSOBV7qkhXheHI7ccDdcL7vk6u7lz42YtAk2ECcHKZBSX4G08na1r5f5t81q/ydZIXtCTn1WyrPXi3hRbnnV8FlmmPkZZIgBq+QEWAVWI+8mk0FDBD8TXREhZ65kT1SaYstc2Z2XWpS1LsPpEijUN6dmtBPj7nzXv7F9nbHeRrRFq5SgfODNzgsAgAwY3J+wAAAArhJUSytL9LXzPy6KB4CvCQoCjtsAAt6gC6d1dC2CsHt+Tx8ABp56gnxw9vfv9PWqwzbUmp+6esAf+W372RYCgGm+f3iYF5yBeGDyBw52hwOLbAAmMOR/NlyPKXievK7u5m47mIbELP1cnCfz7ORDJpGDyaHkZPL2O43JtA7srGukW5RAnkEOlCWdVt975p6+UIer/m8wqu//++7Vvle7X+16tf3VyCsKTamFAYK0qDfVgoj+2jsAMDgCifKqlH+lDrR+7kNCw8IpVFpEZFQ0ncFksWM4sXHc+ITEpOSUVF5aOl8gFIklUplcocxQqTM1WVqd3pCdk5tnzDeZLdaCQhvo6OzuXTzyzbq16yc2TG7asnnrth3bd+7as2/v/oMHjh45dhzUFDlKbzStIasqBw0Fug7UAiUNAACgYsDGb7dXAgCAawGYZ3fh8jNnL05dvXbp8iHpFAC3b94CADT/XwcL+ub39wwODQ8sXQaWrFw1dvrchWrgfMv0OkOa5lFm3IEvcGlK/pRHfsBFgQ3/MfSm9WHgoCDBoE8Y9gahHLShLzy6kdBD8lj6RymFOBcc7EsjWIV0OPg0OdjNjsObHu0PLfxhlQyGnnDXRnBMGIoBQ78ILlhYD3SHXqhWMe6WH0p/+Vn+EiSE+Hi087FHBwBop/hEvvq3VokRVR1tjY911zVpq5XG73dRAK38m3xdPut7DbX+no2pp0PNT8ee7bc6N63vTWxOPenb1N6j1qi+Vbz0BbXa79a0dLZuCAVSDVs2gNVjcHVnq9WdWOfrtVqbQNN3/aBflbRAPwBdk99frFpVrPahAGxXAUpWtbYoHXF/IAL8iF1N5LGaqrWhpeYxqXxdvltQo/eL4RhQ+nw9zaJ+/9UXWqpfCvN7Nf0+S19jJQtX6uqQ3VySHtnvp72jtTXmU5YypD1AQB+lNqC0tPiUYpR7UKvZAFbzqd6AMRo6X7p9ltJh1XTq/lbXt+SVhYXuNlLylCzx+Z4we0HNX9IL543c2R2F01TJtbAhM/PSTWO2CWvDGKedIq69TEEDASoxAXuWXb2Z98LaQC3J3EWn0ttl4zrgprF4ChYMbSpCt0oXbIBDS302b8lJiNk2qOjNxJUvQwUFz/bCc+cuOdi1T9/djhzIMpTTTuM0ljOyC1RCojMtoD5LXPWiwxjxXCE+E5RfDcnDXt80Qzx6+qOmpfFzZENWKq5QqBUj6tI2cmefeDIWijx78msCUqeQiDIb4GHsAsIQp+sL016Ev71bwJ8mCXFH/YBPvGnrQsjYNTKWdtS+26nkJqUZqqF4TlMJIIPXFapoWTWnzUlZEkNFFZx4lrersSk1X2fq8/BWF8jvlaeJjhN53aAKfeoGIEAvGHn9iFygUVwylGPPeB1G9ICRG0VOUpdB0sy3yimNSdIiTWkRiNgavSrCR0KqOp40hVrE1uvVN6ZnQKVVwLSAM5a2YL+zNOMpEH/ipsDek9egjJuAjg3xUkHBmjJqLEcDK6Q/dNoSkFKnVB+dQkHVAwQU1di8EPjLBhAzizR1Op7fK2MxQLnEbK0AUXCO00RJxh7QoZ5ViVuMxA7gOoMrM0b0gs2lBTZIvHXyZTjOUC2dCWtTkroEyD2q1GEZJELA05bN7GUHonsRSVwXOGRNagJqUyho7g8xEFPt8ymOk2ysZBkHHKpcTdDvcb96HTDI2AiBzjOWEJA1uE1WauoU9MzGUovRMWTz9klcqWDoyfMiRflQCe89V7mhnzmKON2OnOq8+LZ4dgx7UzxlTMUMaTZOPPnkTCCd2l5ICBn4p98EChP/fnijntt8U8B2dac0okGu3ny//vS4jTK7wxiVf6B3cv5EBl9afpLv13RlMYRtwsY4hcHpJJNQtyaEvNtPbMa4tTyl3dL8Tu/APQ/Z55F+QsbyEjEZWhuokGRoJpVeiTllauGmCjG/YRPO8taApx6nAQFXSFIGqOj9djNkDRNn4CnulMLRXYs0hV19BWQ4XV7WziI2KM2Kg7izgdiaqc3iI8Z/hK6/jD1isgnnOl1/UsagXnAqOjXrBB6yy3kCxFy4T/bLN8gGJiHHEbvHW9ZzZRIIO5dBo9ncgPNsPl+JrOajEuvGTCI3ufIN41QgMopp4j7SRYV2Rouo1tzftESSfAl4WXYRIhNPnY/Sp2Rct7QtXFYoDM4GmL3AAKnI1YQxR43X5AUP2D0V2TnrxO8fQlgzV/YO9IhN5WxRTq3gqX5mcwo996RQaFmaDah5oh7NKIoaN8CVvvAyhcHX0xJyNBN9IwHXgNKSECdxq1GmA6ifXwzztfSmYcz15tAZQLxNnufe28AXYiJ8UZlvx6DnFgM7hIAhzTgt6RilND6iG8sEtymitxpx1yv8tqu/abM2vSTj7arNJHQsanQ0xaJfY6+PcZ6ZnizbWe4tTGKvWyQJcSxSy3Klz0iT3DG+4RNmkQs1S2E3G+swLgFyJoCOa9psIAtIRWVQ/5pSToJDDytUOCB/Uw72PyLGQN51Q6wqUjSKzvh/T5PHU6Hnw/iErlfDBYVKyCYeFpAyoL/OM0fBSdmgVo6QsiEentzxmnpVxm4FEEXfdrRDVw1CMlbb77bMkzPq9oemgjf5xOLUkW7ZANedsw0j5yu0P5679wNOrcsJ7Q2hkSxrJtOqp+Bx+pzYrU4wkNO/7HgrV3mF5lUWAYcGuZc5tbQzI+1Hqirj7ftDynRM9/O3nB2He9Ic2X3c7cXl3pGlIYxyvkO9dgRF+LC5ytEA74L3gxQC3yGD/C1nHMf0T8fmFBZqM8nxVb7dzMeROwLK27115JqqHunL4/MK5Rt5iU7GFzBkesUzREKaeipemf8eOFdoZ4tl2HVdnpI2lnQFeNfj1jfgWNb0Rki/Lv7pGssKVSTW/9iyI5ERsMNzZwyFO8PcyWbogMb+4agrgAD5P/D4iivT8aGYgAPcMR2+J6VFavRMgWrH+NqAW5jPbAzISFzKWwNLJLn3MlDUYtIGYF7qG/bjyO3ZMpCunXPhGlSbvFgWBrDbXQIOTVRlbG76xrMxmHfzQP0ofclzc7gxHm3wc+yaYgfLGTje+JE3FFwHYqe4gtcFV2xX3HRvSN8/ll+veVBySyJnsTewy+OUoZqXYmEh+3PBBvtH6Xq30ueWrc8Fs6p/37HQvUH+LIiPq4tPHgyGBKgYKOiPAtRUPyVhPLIX0gcnnHYUaOUs2Uez6aTLAhtsvSscrhnr4Vo+ncSL+smGzG4vzT7Pa4l1GvGIXbI8h0c50Vim6w/Iyq99FHuuassSHczx6ZVlsKaC05K/BZhM4sXgALlbNQXb6ZTnAnur6VsB/VBJRVFe6WOtUYW8nXMyp/GoyqKwGTDKFgduYq/Dc1UJdS/2cv8FUM52iQ/gIk0I7GUglbwjqJ/9DfxAOFNIDwSjHrNFHp2xghdsD5A1sctPpZEgN6VZ01Jty5Tro4xQiBA0mQS9W8mf8+wVRR3I2y2xRG5JyHmQbMuasTfs/daOnSOq9NqU45cnyWIDwB1hvgcGZxciYP+YhMjKVqz192zi2nhdVgDaQtiGMGM3mwV2FV3OVylL3BZpKvi66dby8LpF7DiJWBcst2ys9NE73FNqDjXwjqJ+TM+6KPDcL5F+zh1nLfdmVUXCrRDC+zyR2sAsRRbnXX3WB4soy71jLbVsJDw4nDd3IFCcMnn/xuj66OyWIU2hVpXKC2Ze9wBpa73cmdYBSU4FYiUcysfClMuxk4zd0EQZppDSpq8EEJembInXIiZNvhJVnWlT/6cb0Zk/4EixTIAoyfmV1GdeC2NPPgBlrw4Lee+rMWOMvhQ9ypLEA2RLbF6kzvJ0gIu1YHcgL2dPEZBvFWnL7bjYIK9Dz4xUsaasQdYw7NiQOxdNn4ovIOjKSb1euWlJp6EOEmfS1RTKyrZohZhMEP2c97Px2OXvl8bgoqbZFyX0PN+oZpPuLZs8a4MjoepLl2T80oNNpYTi3IWUeyQeK1gS8ztUz5uHZt6sG+WdYmCmLQlrUpNspD21O9RYXuhBWQcgYEm9ZMDmQuVNiqZN3Vsg3WMvbqNV7Hnr4hNaLAuJZ435dGuLLG7XSmdpoiBLOHt1JZHQZktNa7mkPBRf77ZZwZkowd956+ULTjdrVzzveG8NTKtTEbBXrhBzge0We/gE+9/biIcYPEm3jvCJUjjKUG1OkU7Z+mEZyIeFAQYvwiHFYOMLacf0XFnAqPNsHfXrzSmNK3LUvnewWOlagnBiuiA9i5JOVKoQVS/gnjwwVrRVLSLtsK8/plwwDuBQHmSGLxKx9Xc8duDofu8Xr5L4LHqFJqpj8TK3M5Iypws0RcFFqbLZlJaujVJ2Q7ak6P3TkmmknaVGCb/aoIgRBkAIKAZtFopNsSR5Uq42b6rFcsc0O3RejG2n/SrS67YuZP1C3fB05KinTF2kMa4zrqYOKFuK5hQqOsmUOTMi7be8xFKERfRq2Mi1FTJ2Oa7qQdSuZkHoFJCWFVkNChMIdGh1afS2VLxlknWlsDGXlnFdIt9oM6hF2zry4P7veGNDfOG4IW0wPxgIXYs7ErPd59H8WqJhrYgktQJQMDeULSXlJO2a0qZ+oWdejtJyVDtq76R2zPkpsxcV6PTdB35YoFsV4hF/1fIzhQUOM4YdZst5lP0OoYvUSl1QJoGkJD6NWI7Ext38AWPG4g6Pjc1/tkNUd5XcPjaaH3ePdh2FO0WxP1+niei9NQRcSVLsDTGkOBLf8MRmtjx8LzlGSXJgOQa3Sqj7OISnjtF2UoWYGK3DZWoFVkc8T0zHexgn3aTJnUUSrgfsiFPsi1Zw9TpZBFq21WsPo1Xq5UKSEryMRZsROzQbTKDFk/g7LYYkpiQOC74D2qHBI+71jdHIhnM8qnjXIonUjiqizzX9YzBAYOdeyAsIrNoLfenl8UYhZrFeGCBp6b1Bb6LHNtoXudYGXBt0iM3uZu2iAx2Q16HlfcLQjs5OkzYoH0IG9PLW4C4c2t8vew3uLCTN7YywS8Tq+xG0sH1IJRBqJyXB1ApLUH8xMaqej3p5E1ioGReSCAUuuTdR9FfcwW+kqITuJcWRMLPoGDUK+0+jC4FTsAMq1AAF6Wc061owqkBzfGDHsaqjJGYP05vzdC2qVQ53zihhDzCGuCKgfs8+hPMbDySr5V0YxDsZEy5t6v6BcDU0B66QCGToXBySnLq0YSLZn1x52pHnNEFA2oOJEZULChz3dDPYy4CEUPOktPrBeZI0vjyDZb9As+QIrtK3njg36mjjLDNhCO9iEUo+kW9JOQbv5iRoCXoa+cOkX5qxnZIuItkeULIYuapkebyBOxTXjFZceid/w2mQmLvxWI1g3jZ/I/HOjQRfFf10qQosRtcwaoX3sKyOEOma17jjHHOowiod1mZmr9IPnEd5jdCmE081DPuYpLFYr82ywFwwe0bNn8v8KaiBya0G9Teaa7F+QWAZZHxYyDaWQOfDuIxJzAaeKxcuF6pGIawcm8sN6WSdjg3zBA+1WXed2lOF8LQpggzAJrkL9qptKxWV59QOtP/EOn3a+km6zrta9/xPF3sL/e0B3aJmbnTnLAZpPR+O43iwxr3vduujZirB7DohYKOL18yFui/4lYVyLGqBkt4iGjy87HhXBW30MVV4NbRpqRyxx2NeBbRxmRxh879F6OD4VOMckAyI/4Pie6QG59y297cMiMeCCigwZ0frCk5AVb9t4OiA6hd3NULoG0G1sBFLipMLVnvG5ZQJycCIgI+pNTJ/NzVC4Esjdt5B7yi5PvD9iQBDDHJ1kXRnDCmDCV+QhQZ7knwPBXUUG7WbQkWFqmb2c8Sqc44e/k4vloyRyW4pbQwL/cFd75abbTZqDW6qwJZrZmbmOlBD//Codl03U3S4f2j6fJr+H9z21WdfnaCX+0/HfDe8UqW3DtTMFK+JDLs/f4RXVyciVgw6CyX1JiVcBMsXpaY3FYu8ZGLvL11qgca9ipTgvrjCrUipKUntL1AtkFXO8tiCVV0VgFD2bUHWWP/Jr+2yzyLzGBhq7PdAqAAWzRiSjr79a+lHfQxcWbPc6waSH78GRjBAJjwAbHiaAIHDYg63xMHhEMK07IQigccExECAraUg+Te8lp8TCs4v9zqJ4lPW9m8teGzLYTZs8TXxaP7O8w9EPW9HWx+NvDratKAV8erqtxL4QiWE32LPHgRrGByR88WYPESOHX2sP/ceaGbm6TENxkfunRagWecEuIQog9GLQvJqo2hOSsOeSc7KxBWA0bZgbGHzQECzf++C0QD0lSwoWMvv7+jg9ze/EcC9pwnOaJWXG0Xt1bzXM8ZNuyehy3HxWSjF0exNP4BWgDU5HoVF+OXnpBv5rkPbyL1w+O+rE5n5NTq9oJxpsIb9VBGxArkmd/ctHLPK3J6v0Bdkte1f6vsROJfRiDWZfvKE6wyhUiridq0mfNibnIfs3Ch1piza3ExaO7zVvah3aHTGOlF5kS7SSWS75cPFIIeAV32EUn8+/vsAKyaUzZqlfBDbYXkaFnyllP0bL9tWPc4pHvs5q4xTbWj8nAGgP4E6KvIb9LekkPbqMG5nSoJIkNgOcxA37xWrDR1dEqS+LA67oNjPCikpMBP7VZo4J+ToShPeU3hiXprHG9Tn/vxivUHXWJppMFoMjauv1saeyU1zTYIkxPJipegvElKRNiAsSy8Ku3+uLa6rw6AW7d1c7HMU0dcfJXJEm7RbQcvXf8GifTyXys5RLw+QVpj2SYql7Q0aa7LeUaNbmZzFyRw/xLiGHbZsRN/QSDjWeU28opjLW4P5OXRpJuCKudmwIl66iPJrI1vfiZqNeNtZfxh/t/Qm72XNfwW2mDZFSR+8pFcBeFe2oJ/aswe3NqGvvRSC357LkHKa1fWgt7BP0dYnmx9HDfiZRflTeULtz1a5uVqrVGvTjFYrMg+Wtdinj9DcHLKC2q05+vdc7KlcbFKfFFti3GLUCcKEk9aZjBIlQy7JeV4+MrxuUVqn64jCc/eWzbsvvyadJllYyxfdbfC0/1SBdxNbJzwlWWFsx0K/pMfclo3yJtUf9y3LN9eG0heDF1bMUjm+QDxIU6B2yBKvU1EC6BJu26SfrWkz7+3STbmb0TiryaMydSVyqG/3a3xMY3fIiOdK3O1+Cbf54uyuPfDq0Dg1iFtiQE1BV/0zq1qd3wSXG4WCrOVLc3zT9BSMTuzn+s6IOlQF+QnD1y9maRvkXyU8YbYwtEKHcojhuSnNtELeypNicA7Op+bmce4/l9fOicypzKX3XuHsb1tkIRWXeiNIeX0orf9QtKq9k1Oy/gBTCYo9/Vxj6ELEZ/6LAbXJC9O/+PWcMHkeBaObrGW+Q1tU8FxTn5Zj9jYs9o/F3dZuE+M1JWkDvo4e7LGbvMiAq0PzIjJKjXT69wlHM40olGJsU2SmMnbYmF/0XijMagBXcSqfE3N6grDa3SlFuGHoPN46JNCjXoAtYEXr/FIiW8PtxDw5e77tjPcOMHK+w5bgke5+IbUwK3myq61c6NvSMoJb8m52SGmpN8K/dCdC7d8T913PfE5OlxcQ9DuO4RXiQdqXXVOJ16kYBziuQC5RIMF9XGaJkIPNW4ithLydoNvxiveJVQFIJWRpBmZEhAZ7UWb6kuEEPBO/+dvCLakP/gSPnVjlSnwBHs36jI16PVG2g9cX2iC4YU85glILu/Zl7rfyM/uqLo+ijUTk8k/DxVWAG5aEHJO1XZIAeG/rdez9GLShZ8GORqr+nneSWbsOQyFCg9O3SuDEQu5wfFXdPugoRiLEfYY2gcdOfG47yugV/PvosqFF/rf7JT4O6HvOLqyO9TqdAOK8dPXvM4ts8FldWN1eBmFngvx/hGw2ufYZSdn2VAuIas8m8lA/MptP/fMQEde4YJgd/IQwVE/xGOe9XS5ClGoGP29u2afEYYClbQtavZr3dmATVeq5F2/bkHIMr6BcTZRVQEPmv92Kjdn8KVzpsPhNbocGcUX1PLurcPKvxfM8lc7ta77GgL1jcxZ79DxqZTYOrmy7trTzkLRkrNKxPT+lLsY0dzJN5R9LOtHt4/PAN3+HJzKc76q2g0YKTluHqXBZy9k4UFgo2b240uZRmI7P0GQMC7kK6h1U3nxc3py/TQL2osyZzpTmYMq1YUf6Ho/D5rgM1MQpx8XGCI1cxajRRimqv28m98otrWr9fuhmA3nWnMXoWVcbYhd8Oy+ceMY/PuSvw2BBKL7AyYltXUlZao70i8fqp1GvJ27qfcsDEVmWnR0hFLxcLe2WMDLC7Ki8AaxS977eb8tTtUfhNlIvUfQxvpuOVXqz5gpTZg9wHZrFix2aFGlbiyYgR+Xpk44o8ufKNhRLooTJQn2ajp+sDHNUrrJS5+CViSng7MheLxXlKfWfODFWaSdpEUhXEb7AipePdCbB+XC3tvMY8U/XNwbB58OxtdTr3KldX8IHxXjFyRS7TKMOT0ZfShI/N6Q2b0FbktuX4DAM9bVQiUvbx7sENqI2LX7L25eFVXSsPnC8UcPH4x81xmBIZXXpjySelloDeW97De8JLPTLy7k8+z31OmiA/VE+/BmlNj4qxCSeSBQmzaJs0f6sOMo8LUFRxqB77HqCngpvUk6R/gJntpgPo6fgPzNP985YtQ6tNQjY3eBcoW8Sj1C9TnqJ0/fsP8eV1bAS3AV1x+c9CBcP0jSoDd1VR0WKdfjMWrzDWu9zFN+0onIf+O5P0pYK+9+2j5EzL76y6lECmR04l7zJDV04YJadL3SL9EOv8yVyRook3oVhfKS38pM2KEKGuUJ1aWPys+kal+Omv98OmZ0t1trN2uX8Ms8zX3yGgoHbadcNB0b8L0bsuOFycyOqIVaqVQ0hugF/OmIPltEzM+vvv+D+1qh5Lt5MM83+EiTs7v3/BFS0j3zDNJ73XGH9KW/0BoB3bkEP27ObrE1gxv3FfotapXr5uuMuDBpUECzY02Zs0tNPWG04VssxJX4ZaU4iTRihJe+s4QQtOSaM7ZgnS2oZmT91EC1BFRcQjzR6hXgBCvJnpB31ycSXv4anKjj17S1C7xk6wtj2brF3ngSdFTjz/JG03UPs3IKQo0gRKaGzaAmELVRzlRyAT5Jcey40WGbaKmfdnn/IEagwuSMISLrFvzZcVxpAlRaPC2k3QRjyPbJuVsXDriNFgSSd91as029JBJ+iPorkB8X7ln1PkZXZyXzQOZ5StOj4bAXBs0fYeqhwMLmsfoemXuMDrHfI5vrGhVRyyg+fLiKW9aDV+69EoPpoSY/haFkHy4ypjj8aocT8xMeKWuE6/0KAT4peAS8/3BRei5M0LD66yq0blkts+LJkPc2LhyafSq4BJZ60+fERxvPjQ6xFq84bI+Ln05IOU1A1oOaT6/3kwBdErqcOjIxyOKlv362tzfN9gQFlxaMKTH1szEQLu/UBGmatHW1skWE+haFlDSZLO3Q7owmcIkUWV6Raud/zDfpDSc5DaFG5Y2HASEuSrLmB/zxQlDnCfgttLWDiWtkIVmD52JdKTMTR+FWLWHMwGvjjJFofKuLK/kZtc30e+TbTH6ZqB4yENN5nSj17xhGPOnNiKPuebTSJdM88ldgVKcPO9vXc6OnL+0hU2kj50V7xedImxUZuHKVZ/GdOiksj4ttpSRgD9IfAW7ASFtIobXh9CAQgmWn5r/1o9VxWl229ObKvrRXJ73R4pkovKDWuCJnVFdBF8lxWWh45sBejmctasXykJ5KUV++b6uzOWqDuiumaenp+C9iAa51zp/1Qib+zouFRww4nxfMtAx0hKZ8l4nPsj2mSK7I5IAr5EXlgoWKeUYfnszFpFxqQ8SFXkIJUNH/ZE3MYNEYSic6iB4MxeHXrDVT173bpZktE1gZZ9j+79rymSEcqi9hmj1WXwBvkF9d7ZL4xTspOVvxW/Y74MHmk7F76tWCepEsUGIhtcjmKQ7ciBfyB/TK8Tih5Ay4S+CYx30iLqEmelKbN5FZXrFee9B6Dy/0DFawsYYiflKuPlPJmppY1fUmv+uwROAdh9A8jg9o7ZP6GxnisTqKgO4uL/pKQYts2pAatjiXptvNVGF8DVtfvE+hfCK4FsHoxovsPI5DO0NReJlc0Y/t1htuF0ALISHfyqPUem6PFFVxhGuY3wDRPUFpy3mGEoBAxOf8caz5AJZXKni6FVSQ1j3xJNHGQAjGEVilcRh+b18m+ZzGBR8SLcRdvC1Xkb405CaQIbuOICROeSMpFm9SopJOvgzUXQzq4y1KW0U5AzgjmQHl4hWDStC1ik4Rbe3o5UdgTvKHpiE1eR6hjrtrGPqRAPL2qBD+gvow2J31TR5+7qWr5q7PmpOaNXxJT7H5ZHfq+IO+NuljXwyP3m1a2r/lj5HDSqOMeu8GNZRotWOOASv2A5oPnZHupFY2Tfy3AKPcv2gAo6M5KYv137/eSxPr76Pd/hDhT6/K2A/X03k1zmPeoKaSFkcYPJyHyW3jcQ7Xe60W7+dduvqn1csUwdS/rgjhzvxKIXs98wK5LOXozaYIVLsJzZB5UFmnSlKP/j7fjjz4W/VjEbRUdrqLfjqAfY/X9sYMHhi/6l9j3ID8HBfIhg2D24Ry9iTTJoso8OCJ8OIs0YR5X56UQCYbEzRVuCxkThAgppDyrdP/2sggg2FcePPUg2BTd5WVZslqKb9wZ1xuULGFiLFahDAU2xJ9bEKosmMp11Lo6cybM9vocRxDBO+VenehLIxo98S6xP+jElWs7rz0Gzm54KcTeaWG6ZVf36YiSXeBUCpHU8bzHwXzj/BxMg3EpFlk4HvphLxptsfrkI4DgWjHG6H51zV0cZgA7PqiyxtcR7GZMunHIkKUlrBt3lFIFeF1Rfh4iXNGx3D/FkGp7qAhHlDrnZLqpGH0Zho7L/w5lZE/PNeDtecBxVPQX6YpmffamOMI16kX9PmJYxPAniBNeG6tE9EBC3Uvh2vCMdEFA0wG6d7ODEvrsYgyUj5NBHoTpcW0w4PZvAhph2Xvogq//gmV6/xI7OIB4tOgBtKv+g/xhP1ESX5s6bFcJ4ACOvyDpVqEpqfANy9QUpuZm2Vri1JIfWvzht3K+CfJsoFku8DnaLQAVy5Lt2qew7841QIFT9c5/jh9Uh2RkGMcL+2Uz0gcAxPG7xrvS76S4+sA/r0gXp0hToyVfJK288Xn7zs877jy7PgPKuMEyoCYlnj5XAvfK/q/gg7/3a76brkMJm1JlBLHibVILjaQnBWoybzbrRQbRN6CKVDHOM5cbOD7WWJ2NLh6wDfHyC1RMn6J4kYYOTv7U0bRgM/qZPZsPXyj5Fvism6it/XfNVqN6zJaufEtPvqlLaoSG64SZUblxOGHUb76G0KV1KCycRgsNwdRBuxgGrJ1dh9t7JsEVvg8L0OuMiFnnGganoZ1gTr8muV6X/XeyLKU+Q/csa/eDLE+66aOGW0EUVge0Ze6Dq2fKVRTsvgV2/OwPTd6S8dFLViEG4/JHhoPsz0+hfJwuVVGYUBpYnjGzAXnwiM2Xkqe8LnwpzLDX2r0ngPpqgPvf8lVdqnfMMEOT90Qtw2dxLiKDWdyZ7dX4sPeK0Fbn9G4+nyFrk23BV9vBwgeL/BY70ZjjrnVyqR6cfUkQxyKlzcHE36UeNqzYyJ5ZZj/hf6LMxxh66J8uvAVzGqc3cjojDKFDk1maFV5UZyHphJviQB64tDgE7c+ZBpYTU9icljEVPhiX6L4EAeJsBPLSRbRlfcCSlrs5QYUetsWVxgmwJkAn/qmRu8e7YcCboddTys+0cZi9UU9Ul+n7l+hjvoKOv0V0ZqoXjigj5O5xD8FmGUVaS3ciuTG/xLOvAyUGbVBLwcqCHjVBrcldae6WBbrZQjkTC5JtHLJ+9SDXBM7MqRgvHcLrbNZYHwPHXH4k2DZkbceLNEXxPipmfgF4hKxI2HVXTsPE1DIZ8otfQxrtKM9tE6roEyk9a7hlsXTtsGCQ73bE3Pj3f9ZkrbzK8JrzxTm8RsfVQ7N7GFkisx3gQ3aAkcihB3In4JXsq+zXVLjA4ykkrs/POKLkT/JcULVXpIB23xsv9VMm7mkf1D65rsRslcdrlUZtmGMYLHvaDyEEXVfWa8OURm28fCtnCmHHf6+sVQ57WGJKEpt9DHKWfNpclMMg1Et2liWQ5vxJLAkmRnsN4JdbZzEVhTnc5KNvYJ/s01t6gz3nY2PjkKX+fcKJ2v0w1KkPTGNyju7M5ftEFzSuypFnqJ/pKotCqrO7W5BA9N7cGbu1JpvG6txMH7+s6GJDF6ISLmOz7lCg4CfsuQBYOyRHgZPOmf7d3G8XboBHfSk7jhur1aqf6crqKG5ZpzwEF+46wkCmbiUz9nBWMizorlYlU/8rqmA39SmZmk0XsXlukHgyY77gDXi3iHF5d4GVYYR98xSX7WTfYJnLsNMAun4acVkvYIp5BjdfPTliv4rvzt4P0+NKoGAAVVIFufx/5jqN6pnv0DmrqmHQWCViDLoC+Cy1zQaGQeUZA5s0tHoNkGN4sN7XVe/A4GCvZz6xiaKLSF53ZynBz5efhbZP3on1X4rptLdu1o2NSOqKjxzEja8cpoA7OL8esmJEV7PLVjIwAsZzEF9Xs8op9v7qPyUPWds7Tpov+oBuqTWUK5cByrCQDfJsKNkQtMFgkm4o8sMXsRHuyq+hRKJpBAZ74aTAYmDNw7qDt0BvTBhh+ZN6CU8qijBD/GJ9S+LFnIwFf8e7/8ZVm7zcNxnM5Gf8CYPGNGOfKn2D7mIOUzVmbN1sUtKk29m1v7BWrI37lbF5F+ghWLD4VpyoFa7xL2SRCwhnUKPUUF7uMhX6smANXTeveYsoVxOw5RICvV8spvbpbrEdc/F/ihuf+rhJdDucz/VDWqiBewPPAnxS1E0hbbyYKg0o1YXX+lvoSALC5K5wBM4/dLtyls0yU2h4fs35Q5wRmB8LJfS4ewbW25Dto+8Z6DSe1kvjCn3iCvXS0+A5+Zgh5zOknsCnEfQjaAPmJ+TL2ROz5RCOimHrwZp3vfoQpscpoKBjLnxtdS3Qw/ISu6kD87kwdgTCoT3iu6HZkv8MO/6fPXjcO8zv/7n3uIiQ/1K0/gLe4tDj5GuhV8kB9OfuIdfIb2el89rOHWhm6187T/NEgj8c9BnErmBB9QKbvsqJhu9+oUnxAxOsONMTWHhEwJzuxdOzPb6a2gGdDw1c7JW1rs5QYjHNfezBPLGYPsG65Ubs7voER143MetnRlOdsUub+lOvun4TzWEUwOWKOqLds2boqvHA+hY7NtwgrbhfZL9oze/Rss/7YaXbcM/AzqduLN3KwtWwlVbvLLfieu3s7Rda8QQFesSE9oGrSvVOE/6d9pwhjWp1hrRUGMm709ON2QGWLJRG9ASGgw3W7pzzxgCgtNnoT/bsppEmAKc9iRY57tXru6KscWbLMDh8C24lWc0qahN5MZbGmehsID7fSGuwy3k5Rsx0V6WHin3CpKpU938OtECk/Q99DM4WneHAo3yRQMCDPdMC1nbHZraK08ZScgqoprxmSNFEmB5X6FFwWiSmXuCrKW1SEGWn3DUIvm8EbTzv+1GM9BByb6wS8RLu5QGx4Jthq/fzHXi+g/ABzxdwHvxhiZUhbtHAA4B1nwPjs18Ay6B8N08g+mJZZb8Zp7NErxm6VZ1rzir7xnkL2Y1oHQAVZesTHTSFW7TmD8idxvSV+7WsrbHfxYK+zKNGb5d9GOP+6cg8Mk0JLmMC0zCq3bt5iwgVfxamhvScAgEAxMILpLlDGU/9AQ72rd6/fqbzL+Vs3xqRQQMG0hzQ1cc8aoBWXDPeHHfAfjnkhuJpfQPipEiPKsJZCX0rtHyc7QfpIrHHdop60XXjlrz7IFywwN0Dcew8PeUDsAOGQxp0gxyoglaYxpJllbBoeFRxkHtpxNHwOmYJ5XYlft/4XVSuvgkCOL5tSQxRnW8ZLSJto1ljcKmlU9idzhrKRxOYXidu79wq2uU23KCm7zfWonIzn77MdbazkPJd7SkpqwJEUsEhASdn/+0SANBjv4cHVHsxChDuNIbDov2IUTk6LroI+HEDdKOiu9f0VIvKHUS5Jjp3JHHYk4h29W9Cwf7rQx/H54bH9F9u95vD4IuOvp+BEZm8TJy9AQxnqXo2UgnIeDn1wz6xussbBYD+RVmJahwxqlh7EXkDkDtGVBwNyDIFb777gSQw/Y+KJ+UwAJAzsX5k4wJPGjFxBNMAqq4YwLcq9c8GAbEUINWrAcJY4vFDoyhaqLQCqV+ICIqFAMQjQFS1OELoFmvtVwsxnM7mCoZ06N7VtwBBqhcHdLpCAqm/KKlQQGP34P4zhQ6AazjR9Zrt2BIqAM7IIVfLs39OD6b7gAuK8N2aVxVudriyVi3i9gXRPdAlQYOck+yOwamBgQKG5Dm+Fs7uAHju4nmvnXO3YgICt7IIKNRyETBBdhNwBJ8JBLehEkje5dvdkdrQoWXIjgEA3FADAeErkYByX2YCJlkDAUd1g0AghSWQwos799zFNT8riVSr0apOGadSDcgiFIlExsEWI4Yx9lpnMoEqNmbSs6G9RDFXh8Vr1KjGNtTVMzufU2VqyWVcmIpUM5GhiUyHTP3YVKcJ7Q5kUsRVK+6cyabScycLJeBK2as41GHloSVocxiR5wf+SzlzUST5pwgPRVBlI+ttVSXFrrKammpLY0uz9ZTnO3XSIr2x+ZHMb2OEPqdGdSiXwlCBa7afKkedLTQ6KGS9KBSs3B80wGAHnZ0audhsDnwXvXQHIAYTGxtHimwZcmVKWRhiQRndBxeTbDYnJTsjNzNlOSTlGAuVtEFByQsQbqCOjDjnuLDUKzsW/MmEA5ryVSuuBrCRFa4bOmkNuEGNZCws9YpOckwN61qPqf5EMqpqdZxYNKRUwIeUq3+2uaW+zPVxw1tppCpwjWgG0ws3sKKB9s7HalP6tf+aAhBhQhkXvHgj8EHky88M/kgCBAoSbCayEKHChKOgookQKUo0OgYmFrYYHLHicMVLkChJshSpeNKk4xMQEhGTkJKRU1DKoKKWSSOLlo6eQbYcufIY5TMxs7AqUMhmgw6dThjxrS5D+o3bYkKfJxZa6nd/GDSqxzkv/Ga1rT7502fr7XDZlJ3siizicFWxS6646ZrrbvhOibtuuW0Xp18t9sA995X6wU96lStToZJLlbWq1apRp16jBk2afa/FLK1mazPHYeu0m2ue+X70s6Me2m2PR557bK99DjrkvP0OuKDbSacC+ji4v+thyHTnAnwQAAAA) format('woff2');
+:root {
+ --monospace: Consolas, monospace;
+ --serif: Georgia, serif;
+ --sans-serif: Helvetica, Arial, sans-serif;
}
-body {
- border: 0;
- height: 100%;
+/* hide Google translate header */
+body > .skiptranslate {
+ display: none;
}
-t {
- pointer-events: none;
+/* hide Google translate in-progress widget */
+body > .skiptranslate + div {
+ display: none;
}
-input, select, button {
- font-size: 1em;
+/* make translated text wrapper non-blocking */
+font {
+ pointer-events: none;
}
-input, select, textarea {
- border: 0.5px solid #DBDFE6;
- border-radius: .5px;
- box-sizing: border-box;
+input,
+select,
+button {
+ font-size: 1em;
+}
+
+input,
+select,
+textarea {
+ border: 0.5px solid #dbdfe6;
+ border-radius: 0.5px;
+ box-sizing: border-box;
}
select {
- height: 1.6em;
- border-top-color: #abadb3;
- padding: 0;
- text-indent: 0px;
+ height: 1.6em;
+ border-top-color: #abadb3;
+ padding: 0;
+ text-indent: 0px;
}
input {
- border-top-color: #abadb3;
- padding: 2px;
- text-indent: 1px;
+ border-top-color: #abadb3;
+ padding: 2px;
+ text-indent: 1px;
}
input:read-only {
- cursor: default;
+ cursor: default;
+}
+
+input[type="radio"] {
+ vertical-align: bottom;
+ cursor: pointer;
}
textarea {
- padding: 2px;
- text-indent: 1px;
- box-sizing: border-box;
- width: 100%;
+ padding: 3px;
+ box-sizing: border-box;
+ width: 100%;
+}
+
+iframe {
+ border: 0;
+ width: 100%;
}
#map {
- background-color: #000000;
- mask-mode: alpha;
- mask-clip: no-clip;
- fill-rule: evenodd;
+ background-color: #000000;
+ mask-mode: alpha;
+ mask-clip: no-clip;
+ fill-rule: evenodd;
+ user-select: none;
}
#canvas {
- position: absolute;
- pointer-events: none;
+ position: absolute;
+ pointer-events: none;
}
#preview {
- position: absolute;
- bottom: 1em;
- left: 1em;
- cursor: pointer;
+ position: absolute;
+ bottom: 1em;
+ left: 1em;
+ cursor: pointer;
}
#pickerContainer {
- position: absolute;
- z-index: 100;
+ position: absolute;
+ z-index: 100;
}
-input, button, select, a, textarea {
- outline: none;
+input,
+button,
+select,
+a,
+textarea {
+ outline: none;
}
-button, select, a, .pointer {
- cursor: pointer;
+button,
+select,
+a {
+ cursor: pointer;
+}
+
+.pointer {
+ cursor: pointer !important;
}
#prec text {
- font-size: 32px;
- stroke: none;
- text-shadow: 1px 1px 1px #9daac9;
- user-select: none;
+ font-size: 32px;
+ stroke: none;
+ text-shadow: 1px 1px 1px #9daac9;
+ user-select: none;
}
-#population, #cells, #compass {
- fill: none;
-}
-
-#biomes {
- stroke-width: .7;
- fill-rule: evenodd;
+#population,
+#cells,
+#compass {
+ fill: none;
}
#landmass {
- mask: url(#land);
- fill-rule: evenodd;
+ mask: url(#land);
+ fill-rule: evenodd;
}
-#lakes, #coastline, #armies, #ice {
- cursor: pointer;
+#lakes,
+#coastline,
+#armies,
+#ice,
+#emblems {
+ cursor: pointer;
}
#temperature {
- font-family: sans-serif;
- font-weight: 700;
- text-anchor: middle;
- dominant-baseline: central;
- text-shadow: 0px 0px 10px white;
- fill-rule: evenodd;
+ font-family: var(--sans-serif);
+ font-weight: 700;
+ text-anchor: middle;
+ dominant-baseline: central;
+ text-shadow: 0px 0px 10px white;
+ fill-rule: evenodd;
}
-#oceanLayers, #terrs {
- fill-rule: evenodd;
+#oceanLayers,
+#terrs {
+ fill-rule: evenodd;
}
#coastline {
- fill: none;
- stroke-linejoin: round;
+ fill: none;
+ stroke-linejoin: round;
}
-#regions, #cults, #relig, #biomes, #provs, #terrs, #biomes, #tooltip, #temperature, #texture, #landmass, #fogging {
- pointer-events: none;
+t,
+#regions,
+#cults,
+#relig,
+#biomes,
+#provincesBody,
+#terrs,
+#tooltip,
+#temperature,
+#texture,
+#landmass,
+#vignette,
+#gridOverlay,
+#fogging {
+ pointer-events: none;
}
#armies text {
- pointer-events: none;
- user-select: none;
+ pointer-events: none;
+ user-select: none;
+ stroke: none;
+ fill: #fff;
+ text-shadow: 0 0 4px #000;
+ dominant-baseline: central;
+ text-anchor: middle;
+ font-family: var(--sans-serif);
+ fill-opacity: 1;
}
-#statesBody, #provincesBody, #relig, #biomes, #cults {
- stroke-width: .6;
- fill-rule: evenodd;
- mask: url(#land);
+#armies text.regimentIcon {
+ font-size: 0.8em;
}
#statesHalo {
- fill: none;
- filter: url(#blur5);
- /*animation: hideshow 3s infinite;*/
+ fill: none;
+ stroke-linecap: round;
+ stroke-linejoin: round;
+}
+
+#statesBody,
+#provincesBody,
+#relig,
+#biomes,
+#cults {
+ stroke-linejoin: round;
+ fill-rule: evenodd;
+}
+
+#statesBody,
+#provincesBody,
+#relig,
+#cults {
+ mask: url(#land);
}
#borders {
- stroke-linejoin: round;
- fill: none;
-}
-
-#provinceLabels {
- text-anchor: middle;
- fill: "#18181a";
- font-family: "Georgia";
- font-size: 9px;
-}
-
-@keyframes hideshow {
- 0% {stroke-width: 1;}
- 50% {stroke-width: 10;}
+ stroke-linejoin: round;
+ fill: none;
}
#rivers {
- stroke: none;
- mask: url(#land);
- cursor: pointer;
+ stroke: none;
+ mask: url(#land);
+ cursor: pointer;
+ fill-rule: nonzero;
}
#anchors {
- pointer-events: none;
+ pointer-events: none;
}
-#terrain, #burgIcons {
- cursor: pointer;
+#terrain,
+#burgIcons {
+ cursor: pointer;
}
.strokes {
- stroke-width: .08px;
- width: 2px;
- stroke: #5c5c70;
- stroke-dasharray: 0.5, 0.7;
- stroke-linecap: round;
+ stroke-width: 0.08px;
+ width: 2px;
+ stroke: #5c5c70;
+ stroke-dasharray: 0.5, 0.7;
+ stroke-linecap: round;
}
#routes {
- fill: none;
- cursor: pointer;
-}
-
-#options .pressed {
- background-color: #896c77 !important;
- font-style: italic;
+ fill: none;
+ cursor: pointer;
}
i.icon-lock {
- cursor: pointer;
+ cursor: pointer;
}
-#riverAngle, #riverWidthInput, #riverIncrement {
- width: 7em;
-}
-
-.editButtonS {
- display: none;
- cursor: pointer;
-}
-
-#riverEditor > *,
-#routeEditor > *,
-#labelEditor div,
-#markerEditor div {
- display: inline-block;
+#labelEditor div {
+ display: inline-block;
}
#labels {
- text-anchor: start;
- dominant-baseline: central;
- text-shadow: 0 0 4px white;
- cursor: pointer;
+ text-anchor: middle;
+ dominant-baseline: central;
+ cursor: pointer;
}
.chartInfo {
- text-align: center;
- font-family: sans-serif;
- font-style: italic;
- font-size: 12px;
+ text-align: center;
+ font-family: var(--sans-serif);
+ font-style: italic;
+ font-size: 12px;
}
-#hierarchy .selected {
- stroke: #c13119;
- stroke-width: 1;
- cursor: move;
-}
-
-#hierarchy text,
#statesTree text,
#provincesTree text {
- pointer-events: none;
- user-select: none;
- stroke: none;
- font-size: 11px;
+ pointer-events: none;
+ user-select: none;
+ stroke: none;
+ font-size: 11px;
}
#statesTree circle {
- filter: url(#dropShadow05);
- stroke: #666666;
- stroke-width: 1;
+ filter: url(#dropShadow05);
+ stroke: #666666;
+ stroke-width: 1;
}
#statesTree circle.selected,
#provincesTree .selected {
- stroke: #c13119;
- stroke-width: 2;
+ stroke: #c13119;
+ stroke-width: 2;
}
-.dragLine {
- marker-end: url(#end-arrow);
- stroke: #333333;
- stroke-dasharray: 5;
- stroke-dashoffset: 1000;
- animation: dash 80s linear backwards;
+.regimentDragLine {
+ marker-end: url(#end-arrow);
+ stroke: #333333;
+ stroke-dasharray: 5;
+ stroke-dashoffset: 1000;
+ animation: dash 80s linear backwards;
+}
+
+.arrow {
+ marker-end: url(#end-arrow-small);
+ stroke: #555;
+ stroke-width: 0.5;
}
@keyframes dash {
- to {stroke-dashoffset: 0}
+ to {
+ stroke-dashoffset: 0;
+ }
}
+#provinceLabels,
#burgLabels {
- dominant-baseline: alphabetic;
- text-anchor: middle;
+ dominant-baseline: alphabetic;
+ text-anchor: middle;
}
-#routeLength,
-#riverLength,
-#lakeArea,
+#routeLength,
#coastlineArea {
- background-color: #eeeeee;
- border: 1px solid #a5a5a5;
- line-height: 1.3em;
- cursor: default;
+ background-color: #eeeeee;
+ border: 1px solid #a5a5a5;
+ line-height: 1.3em;
+ cursor: default;
}
#brushCircle {
- stroke: #373737;
- stroke-width: 1.5px;
- stroke-dasharray: 7;
- stroke-linecap: butt;
- fill: none;
+ stroke: #373737;
+ stroke-width: 1.5px;
+ stroke-dasharray: 7;
+ stroke-linecap: butt;
+ fill: none;
}
text.drag {
- text-shadow: 0 0 1px red;
+ text-shadow: 0 0 1px red;
+}
+
+#dialogs {
+ background-color: var(--bg-dialogs);
}
.draggable {
- cursor: move;
+ cursor: move;
}
-.ui-dialog, #optionsContainer {
- user-select: none;
+.ui-widget-header {
+ border-bottom: 1px solid var(--dark-solid);
+ background: var(--header);
+ color: #ffffff;
+ font-weight: bold;
}
-#collapsible {
- margin: 11px;
- border: 0;
- position: absolute;
- z-index: 2;
+button.ui-button:disabled {
+ filter: brightness(0.95);
}
-div.tab > button#optionsHide {
- width: 7%;
- height: 100%;
- font-family: Times New Roman, Arial;
- padding: 7px 0px;
+button.ui-button:disabled:hover {
+ cursor: default;
+}
+
+.ui-dialog,
+#optionsContainer {
+ user-select: none;
+}
+
+#optionsTrigger {
+ padding: 0.6em 0.45em;
+}
+
+@media (max-width: 600px) {
+ #optionsTrigger {
+ font-size: 2em;
+ padding: 0;
+ width: 1.3em;
+ height: 1.6em;
+ border: solid 1px #5e4fa2;
+ }
}
#options {
- margin: 10px;
- font-family: Consolas, monospace;
- position: absolute;
- border: solid 1px #5e4fa2;
- width: 300px;
- background-position: center;
- background-size: cover;
- background-blend-mode: color-dodge;
+ position: absolute;
+ font-family: var(--monospace);
+ border: solid 1px #5e4fa2;
+ margin: 10px;
+ padding-bottom: 0.3em;
+ background: var(--bg-light);
}
-#options input, #options select, #options button {
- font-family: Consolas, monospace;
+#options input,
+#options select,
+#options button {
+ font-family: var(--monospace);
+}
+
+#collapsible {
+ margin: 11px;
+ border: 0;
+ position: absolute;
+ z-index: 2;
+ display: grid;
+ grid-template-columns: 2fr 7fr;
}
.tab {
- overflow: hidden;
- border-bottom: 1px solid #5d4651;
- height: 2.2em;
+ border-bottom: 1px solid var(--dark-solid);
+ height: 2.2em;
+ display: flex;
+ justify-content: space-between;
+}
+
+div.tab > button#optionsHide {
+ width: auto;
+ font-family: var(--sans-serif);
+ padding: 0.6em 0.45em;
+}
+
+button.options {
+ width: 100%;
+ background-color: var(--bg-main);
+ font-weight: bold;
+ border: none;
+ transition: 0.2s;
+}
+
+button.active {
+ background-color: var(--header);
+ color: white;
+}
+
+button.options:hover {
+ background-color: var(--header-active);
+ color: white;
}
#options p {
- font-style: italic;
- font-weight: bold;
- margin: .8em 0 0 0;
+ font-style: italic;
+ font-weight: bold;
+ margin: 0.8em 0 0 0;
+}
+
+#options .tip {
+ color: #444;
+ font-size: 0.9em;
+ font-family: sans-serif;
+ font-style: italic;
+ margin-left: 0.5em;
}
#aboutContent {
- text-align: justify;
+ text-align: justify;
}
#aboutContent p {
- font-weight: normal;
+ font-weight: normal;
+ font-style: normal;
}
#aboutContent a {
- color: #1d1b1c;
- font-weight: bold;
- text-decoration: underline;
+ color: #1d1b1c;
+ font-weight: bold;
+ text-decoration: underline;
}
#optionsContent span {
- font-size: .9em;
+ font-size: 0.9em;
}
#options i {
- color: #31272c;
- font-size: .8em;
- cursor: pointer;
+ color: #31272c;
+ font-size: 0.85em;
+ cursor: pointer;
+}
+
+#options button i.icon-cog {
+ position: absolute;
+ padding: 0.1em 0.3em;
+ background-color: var(--bg-lighter);
+ border-radius: 50%;
+ visibility: hidden;
+ opacity: 0;
+ transition: 0.4s ease-in-out;
+}
+
+#options button i.icon-cog:hover {
+ color: #111;
+ background-color: var(--bg-light);
+ transform: rotateZ(180deg);
+}
+
+#options button i.icon-cog:active {
+ transform: translateY(1px);
+}
+
+#options button:hover i.icon-cog {
+ visibility: visible;
+ opacity: 1;
}
input[type="color"] {
- -webkit-appearance: none;
- cursor: pointer;
- border: 1px solid #a9a9a9;
+ -webkit-appearance: none;
+ cursor: pointer;
+ border: 1px solid #a9a9a9;
}
input[type="color"]::-webkit-color-swatch-wrapper {
- padding: 0;
+ padding: 0;
}
#options input[type="color"] {
- width: 4.5em;
- height: 1em;
- border: 0;
+ width: 4.5em;
+ height: 1em;
+ border: 0;
}
#convertImageDialog input[type="color"] {
- width: 38px;
- padding: 0;
- border: 0;
- background: none;
- cursor: pointer;
+ width: 38px;
+ padding: 0;
+ border: 0;
+ background: none;
+ cursor: pointer;
}
#options select {
- height: 1.5em;
- border: 0;
- cursor: pointer;
- font-size: smaller;
-}
-
-#options input[type="range"] {
- height: 8px;
- background: 0;
- -moz-appearance: none;
- -webkit-appearance: none;
- margin-left: 0;
- border: 0;
- padding: 0;
-}
-
-#options input[type="range"]::-webkit-slider-thumb {
- -webkit-appearance: none;
- border-radius: 15%;
- width: .91em;
- height: .91em;
- background: #a58394;
- border: 1px solid #5d4651;
- cursor: pointer;
- margin-top: -.4em;
- box-shadow: .5px .5px 0px #5d4651;
-}
-
-#options input[type="range"]::-moz-range-thumb {
- -moz-appearance: none;
- border-radius: 15%;
- width: .73em;
- height: .73em;
- background: #a58394;
- border: 1px solid #5d4651;
- cursor: pointer;
- box-shadow: .5px .5px 0px #5d4651;
-}
-
-#options input[type=range]::-webkit-slider-runnable-track {
- height: 2px;
- background: #ffffff;
-}
-
-#options input[type=range]::-moz-range-track {
- -moz-appearance: none;
- background-color: #ffffff;
- height: 2px;
-}
-
-#options input[type="number"] {
- font-size: .8em;
+ height: 1.5em;
+ border: 0;
+ cursor: pointer;
+ font-size: smaller;
}
#options input[type="text"] {
- border: 0px;
- width: 62%;
- font-size: smaller;
+ border: 0px;
+ width: 62%;
+ font-size: smaller;
}
-#optionsContent output {
- text-align: right;
- font-size: smaller;
+#options output {
+ text-align: right;
+ font-size: smaller;
}
-#optionsContent input[type="number"] {
- border: 0;
- text-align: right;
- background-color: transparent;
- width: 3.3em;
- -moz-appearance: textfield;
+#options input[type="number"] {
+ font-size: 0.8em;
+ border: 0;
+ text-align: right;
+ background-color: transparent;
+ width: 3.3em;
}
-#optionsContent input[type=number]::-webkit-inner-spin-button,
-#optionsContent input[type=number]::-webkit-outer-spin-button {
- -webkit-appearance: none;
- margin: 0;
+#options input[type="number"]::-webkit-inner-spin-button,
+#options input[type="number"]::-webkit-outer-spin-button {
+ -webkit-appearance: none;
+ margin: 0;
}
-#optionsContent input[type="number"]:hover {
- outline: 1px solid #5d4651;
+#options input[type="number"] {
+ appearance: textfield;
+ -moz-appearance: textfield;
}
-#optionsContent input.paired {
- text-align: center;
- background-color: white;
+#options input[type="number"]:hover {
+ outline: 1px solid var(--dark-solid);
}
-#optionsContent input.long {
- width: 100%;
+#options input.paired {
+ text-align: center;
+ background-color: white;
+}
+
+#options input.long {
+ width: 100%;
background-color: white;
text-align: left;
}
-#optionsContent input[type="range"] {
- width: 100%;
+#options input[type="range"] {
+ width: 100%;
+ height: 8px;
+ background: 0;
+ appearance: none;
+ margin-left: 0;
+ border: 0;
+ padding: 0;
}
-#optionsContent select {
- width: 100%;
-}
-
-#optionsSeedGenerate:before {
- content: '✓';
- margin-left: -2px;
- font-weight: bold;
-}
-
-#layersContent button.presetButton {
- position: absolute;
- height: 2em;
+#options input[type="range"]::-webkit-slider-thumb {
+ -webkit-appearance: none;
border-radius: 15%;
- margin: 1.3em 0 0 .6em;
- font-size: .7em;
+ width: 0.91em;
+ height: 0.91em;
+ background: var(--light-solid);
+ border: 1px solid var(--dark-solid);
+ cursor: pointer;
+ margin-top: -0.4em;
+ box-shadow: 0.5px 0.5px 0px var(--dark-solid);
}
-#styleContent button.styleButton {
- font-size: 70%;
- border-radius: 15%;
- margin: 0;
+#options input[type="range"]::-moz-range-thumb {
+ -moz-appearance: none;
+ border-radius: 15%;
+ width: 0.73em;
+ height: 0.73em;
+ background: var(--light-solid);
+ border: 1px solid var(--dark-solid);
+ cursor: pointer;
+ box-shadow: 0.5px 0.5px 0px var(--dark-solid);
+}
+
+#options input[type="range"]::-webkit-slider-runnable-track {
+ height: 2px;
+ background: #ffffff;
+}
+
+#options input[type="range"]::-moz-range-track {
+ -moz-appearance: none;
+ background-color: #ffffff;
+ height: 2px;
+}
+
+#options select {
+ width: 100%;
+}
+
+#loadGoogleTranslateButton {
+ font-size: smaller;
+ padding: 0.4em 0.5em;
+}
+
+#options input[type="color"] {
+ width: 2em;
+ padding: 1px;
+}
+
+.tabcontent button.sideButton {
+ border-radius: 15%;
+ font-size: 0.8em;
+ margin-block: -1em;
}
#layersContent button.active,
#styleContent button:active {
- transform: translate(0px, 1px);
+ transform: translate(0px, 1px);
}
-#styleElements input[type="range"] {
- width: 64%;
+#styleSelectFont > option {
+ font-size: 2em;
}
-#styleElements select {
- width: 64%;
-}
-
-#styleElements input[type="number"] {
- width: 52px;
- border: 0;
- padding-left: 2.5px;
+#sticked {
+ display: flex;
+ justify-content: space-evenly;
+ width: 100%;
}
#sticked button {
- background-color: #997c8900;
- padding: 0;
- margin-bottom: 2px;
- width: 22%;
- font-size: 1em;
- border: 0;
- font-weight: bold;
+ background-color: transparent;
+ font-weight: bold;
+ border: 0;
}
#sticked button:hover {
- color: white;
+ color: white;
}
#exitCustomization {
- right: 10px;
- bottom: 10px;
- position: absolute;
- display: none;
+ right: 10px;
+ bottom: 10px;
+ position: absolute;
+ display: none;
}
#exitCustomization > div {
- width: 12em;
- background: #5d4651;
- cursor: move;
+ width: 12em;
+ background: var(--dark-solid);
+ cursor: move;
}
#finalizeHeightmap {
- width: 100%;
- border: none;
- padding: .45em .75em;
- margin: .4em 0;
- font-family: Consolas, monospace;
- animation: glowing 2s infinite;
+ width: 100%;
+ border: none;
+ padding: 0.45em 0.75em;
+ margin: 0.4em 0;
+ white-space: nowrap;
+ font-family: var(--monospace);
+ animation: glowing 2s infinite;
}
.glow {
- animation: glowing 3s infinite;
+ animation: glowing 3s infinite ease-in-out;
}
@keyframes glowing {
- 0% {box-shadow: 0 0 -4px #ded2d8;}
- 50% {box-shadow: 0 0 8px #F44336;}
- 100% {box-shadow: 0 0 -4px #ded2d8;}
-}
-
-.tab > button.options {
- width: 18.6%;
- height: 100%;
- padding: 6px 0px;
-}
-
-button.options {
- background-color: #997b89;
- font-weight: bold;
- float: left;
- border: none;
- border-radius: 0;
- padding: 8px 10px;
- transition: 0.2s;
-}
-
-button.options:hover {
- background-color: #806070 !important;
- color: white !important;
-}
-
-button.active {
- background-color: #916e7f;
- color: white;
+ 0% {
+ box-shadow: 0 0 1px #f44336;
+ }
+ 50% {
+ box-shadow: 0 0 10px #f44336;
+ }
+ 100% {
+ box-shadow: 0 0 1px #f44336;
+ }
}
.tabcontent {
- display: none;
- padding: 0 12px 2px 12px;
- opacity: 0.9;
+ display: none;
+ padding: 0 12px 2px 12px;
+ opacity: 0.9;
}
.tabcontent button {
- background-color: #916e7f;
- border: none;
- padding: .45em .75em;
- margin: .35em 0;
- transition: 0.1s;
- font-size: 1em;
+ background-color: var(--bg-lighter);
+ border: none;
+ padding: 0.45em 0.75em;
+ margin: 0.35em 0;
+ transition: 0.1s;
+ overflow: hidden;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+}
+
+.tabcontent button.pressed {
+ background-color: var(--header);
+ font-style: italic;
}
.tabcontent button:hover {
- background-color: #a8879d !important;
+ background-color: var(--header-active);
+}
+
+#toolsContent > .grid {
+ display: grid;
+ grid-template-columns: repeat(3, 1fr);
+ margin: 0.2em 0;
+}
+
+#toolsContent button {
+ padding: 0.35em 0;
+ margin: 0.16em 0.12em;
}
#mapLayers {
- display: inline-block;
- padding: 0;
- margin: 0;
+ display: inline-block;
+ padding: 0;
+ margin: 0;
}
#mapFilters > button {
- width: 23%;
- padding: 4px 0;
+ width: 23%;
+ padding: 4px 0;
}
#viewMode > button {
- padding: .35em;
- margin: .2em .3em .6em .3em;
- float: left;
- width: 30.7%;
+ padding: 0.35em;
+ margin: 0.3em 0.3em 0.6em 0.3em;
+ float: left;
+ width: 30.7%;
}
fieldset {
- border: 1px solid #5d4651;
+ border: 1px solid var(--dark-solid);
}
.tabcontent li {
- list-style-type: none;
- background-color: #997b89;
- cursor: pointer;
- padding: .35em;
- margin: .2em .3em;
- float: left;
- width: 28%;
- text-align: center;
+ list-style-type: none;
+ background-color: var(--bg-main);
+ cursor: pointer;
+ padding: 0.35em;
+ margin: 0.2em 0.3em;
+ float: left;
+ width: 28%;
+ text-align: center;
+ text-transform: capitalize;
+
+ overflow: hidden;
+ white-space: nowrap;
+ text-overflow: ellipsis;
}
-#options .buttonoff {
- background-color: #b6b4b440 !important;
- color: grey;
+.tabcontent li.buttonoff {
+ background-color: var(--bg-disabled);
+ color: #444444aa;
+}
+
+.tabcontent li:hover {
+ box-shadow: 0 0 2px 2px var(--dark-solid) 17;
}
-.tabcontent li:hover,
.tabcontent button:hover {
- box-shadow: 0 0 2px 2px #5d465117;
+ background-color: var(--header);
}
#optionsContainer span {
- cursor: default;
+ cursor: default;
}
#cellInfo {
- user-select: text;
+ user-select: text;
}
#tooltip {
- position: fixed;
- text-align: center;
- bottom: 0.5vw;
- width: 70%;
- left: 15%;
- cursor: default;
- text-shadow: 1px 1px 2px #1d0e0f;
- color: #ffffff;
- font-size: calc(12px + 0.5vw);
- white-space: pre-line;
- z-index: 99999;
- background: linear-gradient(0.1turn, #ffffff00, #c71d1d66, #ffffff00);
+ position: fixed;
+ text-align: center;
+ bottom: 0.5vw;
+ width: 70%;
+ left: 15%;
+ cursor: default;
+ text-shadow: 1px 1px 2px #1d0e0f;
+ color: #ffffff;
+ font-size: calc(12px + 0.5vw);
+ white-space: pre-line;
+ z-index: 99999;
+ background: linear-gradient(0.1turn, #ffffff00, #c71d1d66, #ffffff00);
}
#optionsContent table {
- border-spacing: 0;
- line-height: 1.2em;
+ border-spacing: 0;
+ line-height: 1.2em;
}
#optionsContent table td:nth-of-type(1) {
- width: 3%;
+ width: 3%;
}
#optionsContent table td:nth-of-type(2) {
- width: 40%;
+ width: 40%;
}
#optionsContent table td:nth-of-type(4) {
- text-align: right;
- width: 6%;
+ text-align: right;
+ width: 6%;
+}
+
+.emblemShapePreview {
+ width: 1.5em;
+ height: 1.5em;
+ margin: -0.4em 0.1em;
+ fill: #fff;
+ stroke: #000;
+ stroke-width: 5px;
}
#styleContent table {
- border-spacing: 0;
- margin-left: .2em;
- width: 100%;
+ border-spacing: 0;
+ margin-left: 0.2em;
+ width: 100%;
}
#styleContent table tr {
- width: 100%;
- display: table;
+ width: 100%;
+ display: table;
}
#styleContent table td:nth-of-type(1) {
- width: 34.2%;
+ width: 34.2%;
}
-#styleElements tbody, #styleElements caption {
- display: none;
+#styleElements tbody,
+#styleElements caption {
+ display: none;
}
#styleIsOff {
- color: darkred;
- font-weight: 700;
- text-align: left;
+ color: darkred;
+ font-weight: 700;
+ text-align: left;
}
#styleElements .whiteButton {
- padding: 0 .8em;
- border: 0;
- background-color: #ffffff !important;
+ padding: 0 0.8em;
+ border: 0;
+ background-color: #ffffff !important;
}
.overflow-table {
- width: 100%;
- text-align: center;
+ width: 100%;
+ text-align: center;
}
.matrix-table {
- width: 100%;
- font-size: smaller;
- text-align: center;
- border-collapse: collapse;
+ max-height: 80vh;
+ max-width: 85vw;
+ scrollbar-width: thin;
+ overflow: auto;
}
-table.matrix-table th, table.matrix-table td {
- border: 1px solid #5d4651;
- height: 2em;
- padding: .2em;
- position: relative;
+.matrix-table > table {
+ text-align: center;
+ border-collapse: collapse;
+ font-size: smaller;
}
-table.matrix-table th {
- background-color: #302a2a;
- color: #ffffff;
+.matrix-table > table th,
+.matrix-table > table td {
+ border: 1px solid var(--dark-solid);
+ height: 2em;
+ padding: 0.2em;
+ position: relative;
}
-table.matrix-table tr:hover th {
- background: #3e3636;
+.matrix-table > table th {
+ background-color: #302a2a;
+ color: #ffffff;
}
-table.matrix-table td:hover {
- outline: 2px solid #5d4651;
- outline-offset: -1px;
- z-index: 1;
+.matrix-table > table td:hover {
+ outline: 2px solid var(--dark-solid);
+ outline-offset: -1px;
+ z-index: 1;
+ cursor: pointer;
}
-table.matrix-table td.Ally {
- background-color: #73ec73;
- color: #000000;
+.matrix-table > table td.Ally {
+ background-color: #73ec73;
+ color: #000000;
}
-table.matrix-table td.Friendly {
- background-color:#d4f8aa;
+.matrix-table > table td.Friendly {
+ background-color: #d4f8aa;
}
-table.matrix-table td.Neutral {
- background-color:#d8d9d3;
+.matrix-table > table td.Neutral {
+ background-color: #d8d9d3;
}
-table.matrix-table td.Suspicion {
- background-color:#eeafaa;
+.matrix-table > table td.Suspicion {
+ background-color: #eeafaa;
}
-table.matrix-table td.Enemy {
- background-color:#ffa39c;
- color: #af0d23;
+.matrix-table > table td.Enemy {
+ background-color: #ffa39c;
+ color: #af0d23;
}
-table.matrix-table td.Unknown {
- background-color:#c1bfbf;
+.matrix-table > table td.Unknown {
+ background-color: #c1bfbf;
}
-table.matrix-table td.Rival {
- background-color:#bd845c;
+.matrix-table > table td.Rival {
+ background-color: #bd845c;
}
-table.matrix-table td.Vassal {
- background-color:#87CEFA;
+.matrix-table > table td.Vassal {
+ background-color: #87cefa;
}
-table.matrix-table td.Suzerain {
- background-color:#8f8fe1;
+.matrix-table > table td.Suzerain {
+ background-color: #8f8fe1;
}
-table.matrix-table td.x {
- background-color:#d4ca94;
+.matrix-table > table td.x {
+ background-color: #d4ca94;
+ cursor: initial;
}
#sizeOutput {
- color: green;
+ color: green;
}
.setColors {
- display: inline-block;
+ display: inline-block;
}
-body button.noicon {
- width: 1.8em;
+#templateTools > button {
+ width: 1.8em;
height: 1.6em;
margin: 1px;
- padding: .1em .5em;
+ padding: 0.1em 0.5em;
float: left;
font-size: 1.2em;
- font-family: Copperplate, monospace;
+ font-family: var(--monospace);
}
#brushesButtons > button {
- padding: 0;
+ padding: 0.3em;
}
#brushesButtons svg {
- pointer-events: none;
+ pointer-events: none;
}
#brushesPanel > div {
- margin: 2px 0;
+ margin: 2px 0;
}
#templateEditor > div {
- margin: 1px 0;
+ margin: 1px 0;
}
#templateEditor #templateTools {
- display: inline-block;
- margin-bottom: -.3em;
+ display: inline-block;
+ margin-bottom: -0.3em;
}
#templateBody > div {
@@ -858,631 +990,660 @@ body button.noicon {
border-radius: 1px;
background-image: linear-gradient(to right, #ffffff 0%, #fafafa 51%, #ebebeb 100%);
margin: 1px 1px;
- padding: .1em .2em;
+ padding: 0.1em 0.2em;
height: 1.2em;
}
#templateBody > div:hover {
- border-color: #808080;
- background-image: linear-gradient(to right, #fcfcfc 0%, #ededed 51%, #dedede 100%);
+ border-color: #808080;
+ background-image: linear-gradient(to right, #fcfcfc 0%, #ededed 51%, #dedede 100%);
}
#templateBody > div > div {
- display: inline-block;
+ display: inline-block;
}
#templateBody > div > span {
- float: right;
- margin: 0 1px 0 .5px;
+ float: right;
+ margin-inline: 1px;
}
#templateBody > div > i {
- float: right;
+ float: right;
}
#templateBody input,
#templateBody select {
- width: 4em;
- height: 1em;
- border: 0;
- font-size: .95em;
- background-color: #ffffff95;
- color: #05044d;
- font-style: italic;
- font-family: monospace;
+ width: 4.5em;
+ height: 1em;
+ border: 0;
+ background-color: #ffffff95;
+ color: #05044d;
+ font-style: italic;
+ font-family: var(--monospace);
}
#templateBody select {
- width: 8em;
- height: 1.4em;
- cursor: pointer;
- font-size: .9em;
+ width: 8em;
+ height: 1.4em;
+ cursor: pointer;
+ font-size: 0.9em;
}
#templateBody .icon-resize-vertical {
- cursor: row-resize;
- font-size: .9em;
- color: #555555;
- margin: 1px 1px;
+ cursor: row-resize;
+ font-size: 0.9em;
+ color: #555555;
+ margin: 1px 1px;
}
#templateBody .icon-check-empty,
#templateBody .icon-check {
- width: 1.1em;
- cursor: pointer;
- color: #575957;
- font-size: .9em;
+ width: 1.1em;
+ cursor: pointer;
+ color: #575957;
+ font-size: 0.9em;
}
#controlPoints {
- fill: #ff0000;
- stroke: #841f1f;
- stroke-width: .25;
- cursor: move;
- opacity: .8;
+ fill: #ff0000;
+ stroke: #841f1f;
+ stroke-width: 0.25;
+ cursor: move;
+ opacity: 0.8;
}
#controlPoints > path {
- fill: none;
- stroke: #000000;
- stroke-width: 2;
- opacity: .4;
- cursor: pointer;
+ fill: none;
+ stroke: #0a0909;
+ stroke-width: 2;
+ opacity: 0.4;
+ cursor: pointer;
+}
+
+#controlCells {
+ pointer-events: none;
+ fill: #82c8ff80;
+ stroke: none;
}
#vertices > circle {
- fill: #ff0000;
- stroke: #841f1f;
- stroke-width: .1;
- cursor: move;
- opacity: .8;
+ fill: #ff0000;
+ stroke: #841f1f;
+ stroke-width: 0.1;
+ cursor: move;
+ opacity: 0.8;
}
#vertices > polygon {
- fill: none;
- stroke: #808080;
- stroke-width: .1;
+ fill: none;
+ stroke: #808080;
+ stroke-width: 0.1;
}
#controlPoints > circle:hover,
-#vertices> circle:hover {
- stroke: #2c0808;
+#vertices > circle:hover {
+ stroke: #2c0808;
}
#battleBody > table {
- padding: .2em .6em .2em .6em;
- border: 1px solid #ccc;
- margin: .2em 0 .4em 0;
- display: block;
- overflow: auto;
- max-height: 34vh;
- width: 100%;
+ padding: 0.2em 0.6em 0.2em 0.6em;
+ border: 1px solid #ccc;
+ margin: 0.2em 0 0.4em 0;
+ display: block;
+ overflow: auto;
+ max-height: 34vh;
+ width: 100%;
}
#battleBody > table .regiment {
- width: 13em;
- font-weight: bold;
+ width: 13em;
+ font-weight: bold;
}
-tr.battleCasualties, tr.battleSurvivors {
- font-style: italic;
- font-size: .9em;
+tr.battleCasualties,
+tr.battleSurvivors {
+ font-style: italic;
+ font-size: 0.9em;
}
-#battleBody div.battlePhases,
#battleBottom div.battleTypes {
- position: fixed;
- background-color: #ffffff30;
+ position: fixed;
+ background-color: #ffffff30;
+}
+
+#battleBody div.battlePhases {
+ position: absolute;
+ background-color: #ffffff30;
}
#battleBody div.battlePhases > button,
#battleBottom div.battleTypes > button {
- width: 3.2em;
- display: block;
- margin: .2em 0;
+ width: 3.2em;
+ display: block;
+ margin: 0.2em 0;
}
div#regimentSelectorBody {
- max-height: 50vh;
- font-size: .9em;
+ max-height: 50vh;
+ font-size: 0.9em;
}
div#regimentSelectorBody > div {
- padding: .1em;
- border: 1px solid #fff;
+ padding: 0.1em;
+ border: 1px solid #fff;
}
div#regimentSelectorBody > div:hover {
- border: 1px solid #ccc;
+ border: 1px solid #ccc;
}
div#regimentSelectorBody > div.selected {
- border: 1px solid #b28585;
+ border: 1px solid #b28585;
}
div#regimentSelectorBody > div.inactive {
- background-color: #eee;
- color: #aaa;
+ background-color: #eee;
+ color: #aaa;
}
div#regimentSelectorBody > div > div {
- display: inline-block;
- pointer-events: none;
+ display: inline-block;
+ pointer-events: none;
}
.drag-trigger {
- border-left: 1em solid transparent;
- border-right: 1em solid #000;
- border-top: 1em solid transparent;
- position: absolute;
- right: -1px;
- bottom: -1px;
- opacity: .3;
+ border-left: 1em solid transparent;
+ border-right: 1em solid #000;
+ border-top: 1em solid transparent;
+ position: absolute;
+ right: -1px;
+ bottom: -1px;
+ opacity: 0.3;
}
.drag-trigger:hover {
- cursor: move;
- opacity: .6;
+ cursor: move;
+ opacity: 0.6;
}
.tint {
- filter: sepia(1) hue-rotate(200deg);
+ filter: sepia(1) hue-rotate(200deg);
+}
+
+.colorsContainer {
+ display: grid;
+ grid-template-columns: repeat(5, 1fr);
+ grid-column-gap: 0.3em;
+ grid-row-gap: 0.2em;
}
.color-div {
- width: 3em;
- height: 1em;
- display: inline-block;
- margin: 0 .16em;
- border: 1px #c5c5c5 groove;
- cursor: pointer;
+ width: 3em;
+ height: 1.5em;
+ border: 1px #999 solid;
+ cursor: pointer;
}
#colorsSelect div {
- height: 1.7em;
- display: inline-block;
- cursor: pointer;
+ height: 1.7em;
+ display: inline-block;
+ cursor: pointer;
}
.color-div:hover {
- border-color: red;
+ border-color: red;
}
.hoveredColor {
- box-shadow: 0 0 1px 1px #717171;
+ box-shadow: 0 0 1px 1px #717171;
}
.selectedColor {
- outline: 2px solid #f87b66;
+ outline: 2px solid #f87b66;
}
#colorScheme {
- margin: 6px 1px 4px 1px;
+ margin: 6px 1px 4px 1px;
}
#debug path.selected {
- stroke-width: .8;
- stroke: #da3126;
- fill: none;
+ stroke-width: 0.8;
+ stroke: #da3126;
+ fill: none;
+}
+
+#debug > text {
+ font-size: 2px;
+ text-anchor: middle;
+ dominant-baseline: central;
}
.selectedCell {
- stroke-width: 1;
- stroke: #da3126;
+ stroke-width: 1;
+ stroke: #da3126;
}
i.resetButton {
- float: left;
- padding-right: .4em;
- font-size: .8em;
- margin-top: .25em;
- color: #ffffff;
- cursor: pointer;
+ float: left;
+ padding-right: 0.4em;
+ font-size: 0.8em;
+ margin-top: 0.25em;
+ color: #ffffff;
+ cursor: pointer;
}
i.resetButton:active {
- color: #5d4651;
+ color: var(--dark-solid);
}
.ui-dialog button.pressed {
- box-shadow: inset 1px 1px 0 0 #ccc;
- border-color: #a6a6da;
- background-color: #ecd8d8;
+ box-shadow: inset 1px 1px 0 0 #ccc;
+ border-color: #a6a6da;
+ background-color: #ecd8d8;
+ border-radius: 10%;
}
.ui-dialog input[type="range"] {
- padding: 0;
- height: 2px;
- background: #d4d4d4;
- top: -.35em;
- position: relative;
- appearance: none;
- -webkit-appearance: none;
+ padding: 0;
+ height: 2px;
+ background: #d4d4d4;
+ position: relative;
+ appearance: none;
+ -webkit-appearance: none;
}
.ui-dialog input[type="range"]::-webkit-slider-thumb {
- -webkit-appearance: none;
- border-radius: 15%;
+ -webkit-appearance: none;
+ border-radius: 15%;
width: 1em;
height: 1em;
- background: #e9e9e9;
- border: 1px solid #9b9b9b;
- cursor: pointer;
+ background: #e9e9e9;
+ border: 1px solid #9b9b9b;
+ cursor: pointer;
}
.ui-dialog input[type="range"]::-moz-range-thumb {
- appearance: none;
- border-radius: 15%;
+ appearance: none;
+ border-radius: 15%;
width: 1em;
height: 1em;
- background: #e9e9e9;
- border: 1px solid #9b9b9b;
- cursor: pointer;
+ background: #e9e9e9;
+ border: 1px solid #9b9b9b;
+ cursor: pointer;
}
.ui-dialog input[type="number"] {
- width: 3.5em;
+ width: 4.5em;
}
.ui-dialog .disabled {
- opacity: 0.2;
-}
-
-.ui-dialog .disabled::slider-thumb {
- opacity: 0.2;
-}
-
-.ui-dialog .disabled::-moz-range-thumb {
- opacity: 0.2;
+ opacity: 0.2;
}
.ui-dialog:disabled {
- cursor: default;
+ cursor: default;
}
div.slider {
- width: 40em;
- margin-top: 0.2em;
+ width: 40em;
+ margin-top: 0.2em;
}
div.slider .ui-slider-handle {
- width: 3em;
- height: 1.6em;
- top: 50%;
- margin-top: -.8em;
- text-align: center;
- line-height: 1.6em;
+ width: 3em;
+ height: 1.6em;
+ top: 50%;
+ margin-top: -0.8em;
+ text-align: center;
+ line-height: 1.6em;
}
#saveDropdown {
- display: none;
- position: absolute;
- left: 29%;
- top: 100%;
- border: 1px solid #5e4fa2;
- background-color: #a4879b;
- width: 5em;
+ display: none;
+ position: absolute;
+ left: 29%;
+ top: 100%;
+ border: 1px solid #5e4fa2;
+ background-color: #a4879b;
+ width: 5em;
}
#loadDropdown {
- display: none;
- position: absolute;
- left: 53%;
- top: 100%;
- border: 1px solid #5e4fa2;
- background-color: #a4879b;
- width: 9em;
+ display: none;
+ position: absolute;
+ left: 53%;
+ top: 100%;
+ border: 1px solid #5e4fa2;
+ background-color: #a4879b;
+ width: 9em;
}
-#loadDropdown>div,
-#saveDropdown>div {
- padding: 2px 4px;
- cursor: pointer;
+#loadDropdown > div,
+#saveDropdown > div {
+ padding: 2px 4px;
+ cursor: pointer;
}
-#loadDropdown>div:hover,
-#saveDropdown>div:hover {
- color: white;
-}
-
-#brushPower,
-#brushRadius {
- width: 8em;
+#loadDropdown > div:hover,
+#saveDropdown > div:hover {
+ color: white;
}
#rescaleHigher,
#rescaleLower,
#rescaleModifier {
- width: 3.7em;
+ width: 3.7em;
}
.italic {
- font-style: italic;
+ font-style: italic;
}
.hidden {
- display: none !important;
-}
-
-.burgs-table {
- max-height: 75vh;
- overflow-x: hidden;
- overflow-y: scroll;
+ display: none !important;
}
.table {
- max-height: 75vh;
- max-width: 75vw;
- overflow-x: hidden;
- overflow-y: auto;
+ max-height: 75vh;
+ max-width: 75vw;
+ overflow-x: hidden;
+ overflow-y: auto;
+ scrollbar-width: thin;
}
-.overflow {
- max-width: 93vw;
- overflow: auto;
- max-height: 75vh;
+@media screen and (max-width: 600px) {
+ .table {
+ max-width: unset;
+ }
}
-.overflow > div {
- width: max-content;
+.dialog::-webkit-scrollbar,
+#alertMessage::-webkit-scrollbar,
+.table::-webkit-scrollbar,
+.matrix-table::-webkit-scrollbar {
+ width: 6px;
+ height: 6px;
+ background-color: transparent;
}
-div.header > div {
- font-weight: bold;
- font-size: .9em;
- display: inline-block;
- position: sticky;
- white-space: nowrap;
- overflow-x: hidden;
- vertical-align: bottom;
+.dialog::-webkit-scrollbar-thumb,
+#alertMessage::-webkit-scrollbar-thumb,
+.table::-webkit-scrollbar-thumb,
+.matrix-table::-webkit-scrollbar-thumb {
+ background-color: #aaa;
+ border-radius: 6px;
+}
+
+.dialog::-webkit-scrollbar-thumb:hover,
+#alertMessage::-webkit-scrollbar-thumb:hover,
+.table::-webkit-scrollbar-thumb:hover,
+.matrix-table::-webkit-scrollbar-thumb:hover {
+ background: #666;
+}
+
+.dialog {
+ max-width: 93vw;
+}
+
+.dialog > div {
+ width: max-content;
+}
+
+div.header {
+ display: grid;
+ width: 0;
+ font-weight: bold;
+ font-size: 0.9em;
+}
+
+div.header > div:first-child {
+ margin-left: 1.8em;
}
.sortable {
- cursor: pointer;
+ cursor: pointer;
}
.totalLine {
- color: #666666;
- font-style: italic;
- font-size: .9em;
- margin-bottom: 3px;
+ color: #666666;
+ font-style: italic;
+ font-size: 0.9em;
+ margin-bottom: 3px;
}
-.totalLine>div {
- display: inline-block;
+.totalLine > div {
+ display: inline-block;
}
div.states {
- border: 1px solid #d4d4d4;
- background-image: linear-gradient(to right, #fafafa80 0%, #f0f0f080 50%, #c8c8c880 100%);
- margin: .1em 0;
- padding: 0 .2em;
- font-size: .9em;
- line-height: 1.5em;
+ border: 1px solid #d4d4d4;
+ background-image: linear-gradient(to right, #fafafa80 0%, #f0f0f080 50%, #c8c8c880 100%);
+ margin: 0.1em 0;
+ padding: 0 0.2em;
+ font-size: 0.9em;
+ line-height: 1.5em;
}
-div.states:hover {
- border: 1px solid #c4c4c4;
- background-image: linear-gradient(to right, #dedede 100%, #f2f2f2 50%, #fcfcfc 0%);
+div.states:hover,
+div.states.hovered {
+ border: 1px solid #c4c4c4;
+ background-image: linear-gradient(to right, #dedede 100%, #f2f2f2 50%, #fcfcfc 0%);
}
div.states > *,
div.states sup,
div.totalLine > div {
- display: inline-block;
+ display: inline-block;
}
-div.states>input {
- width: 6em;
- background: none;
- border: 0;
+div.states > input {
+ width: 7em;
+ background: none;
+ border: 0;
}
div.states div {
- width: 3.2em;
+ width: 3.2em;
}
-div.states .statePower, div.states .biomeHabitability {
- width: 4em;
- -moz-appearance: textfield;
+div.states .biomeHabitability {
+ width: 4em;
+ -moz-appearance: textfield;
}
-div.states .stateBurgs {
- width: 2.4em;
+div.states > .statePopulation {
+ width: 3em;
}
-div.states>.stateArea {
- width: 5em;
-}
-
-div.states>.statePopulation {
- width: 3em;
+div.states:hover > .hiddenIcon {
+ visibility: visible !important;
}
div.states .icon-pencil,
div.states .icon-trash-empty,
div.states .icon-eye,
div.states .icon-pin,
-div.states .icon-flag-empty {
- cursor: pointer;
+div.states .icon-flag-empty,
+div.states .icon-cw,
+div.states .icon-lock,
+div.states .icon-lock-open {
+ cursor: pointer;
}
div.states .icon-resize-vertical {
- cursor: row-resize;
- font-size: .9em;
+ cursor: row-resize;
+ font-size: 0.9em;
}
-div.states>[class^="icon-"] {
- color: #6e5e66;
- padding: 0;
+div.states > [class^="icon-"] {
+ color: #6e5e66;
+ padding: 0;
}
div.states > .icon-arrows-cw {
- color: #67575c;
- font-size: .9em;
- cursor: pointer;
+ color: #67575c;
+ font-size: 0.9em;
+ cursor: pointer;
}
-div.states>.before {
- color: #6e5e66;
- padding: 0 1px 0 0;
+div.states > .before {
+ color: #6e5e66;
+ padding: 0 1px 0 0;
}
-div.states>.small {
- font-size: .9em;
+div.states > .small {
+ font-size: 0.9em;
}
-div.states>.cultureName {
- width: 5em;
-}
-
-div.states>.culturePopulation {
- width: 4em;
- cursor: pointer;
-}
-
-div.states > .cultureBase,
-div.states > .cultureType,
-div.states > .stateCulture,
-div.states > .diplomacyRelations {
- width: 4.6em;
- cursor: pointer;
- border: 0;
- background-color: transparent;
- -webkit-appearance: none;
- -moz-appearance: none;
- appearance: none;
-}
-
-div.states > .cultureBase {
- width: 6em;
+div.states > select {
+ width: 7em;
+ cursor: pointer;
+ border: 0;
+ background-color: transparent;
+ -webkit-appearance: none;
+ -moz-appearance: none;
+ appearance: none;
}
div.states > .burgName,
div.states > .burgState,
div.states > .burgCulture {
- width: 6em;
-}
-
-div.states .burgPopulation {
- width: 4.8em;
-}
-
-div.states .burgType {
- width: 3em;
-}
-
-div.states .burgType > span {
- padding: 0 1px;
- color: #6e5e66;
- transition: 0.2s;
+ width: 6em;
}
div.states span.inactive {
- color: #c6c2c2;
+ color: #c6c2c2;
}
div.states span.inactive:hover {
- color: #abaaaa;
+ color: #abaaaa;
}
-div.states>input.riverType {
- width: 5em;
+div.states > .riverName {
+ width: 7em;
+}
+
+div.states > .riverType {
+ width: 5em;
+}
+
+.coaIcon {
+ stroke-width: 3;
+ width: 1.4em;
+ height: 1.4em;
+ margin: -0.3em 0;
+}
+
+.coaIcon > use {
+ pointer-events: none;
}
#diplomacyBodySection > div {
- cursor: pointer;
+ cursor: pointer;
+}
+
+.changeRelations > * {
+ pointer-events: none;
+ cursor: pointer;
}
#diplomacySelect {
- width: 5em;
- margin: .1em 0 0 -.3em;
- position: fixed;
- background-color: #ffffff;
- border: 1px solid #1891ff;
+ width: 5em;
+ margin: 0.1em 0 0 -0.3em;
+ position: fixed;
+ background-color: #ffffff;
+ border: 1px solid #1891ff;
}
#diplomacySelect > div {
- width: 100%;
- padding-left: .3em;
+ width: 100%;
+ padding-left: 0.3em;
}
#diplomacySelect > div:hover {
- background-color: #1891ff;
- color: #ffffff;
- width: calc(100% - .3em);
+ background-color: #1891ff;
+ color: #ffffff;
+ width: calc(100% - 0.3em);
}
#burgsFooterPopulation {
- border: 0;
- width: 50px;
- color: #666666;
- font-style: italic;
- line-height: 1.4em;
+ border: 0;
+ width: 50px;
+ color: #666666;
+ font-style: italic;
+ line-height: 1.4em;
+}
+
+#burgBody div.label {
+ display: inline-block;
+ width: 6em;
+}
+
+#burgBody > div > div,
+#riverBody > div,
+#routeBody > div,
+#lakeBody > div {
+ padding: 0.1em;
+}
+
+#riverBody div.label,
+#riverBody input,
+#riverBody select,
+#routeBody div.label,
+#lakeBody div.label,
+#lakeBody input,
+#lakeBody select {
+ display: inline-block;
+ width: 7em;
+}
+
+#routeBody input,
+#routeBody select {
+ display: inline-block;
+ width: 10em;
}
#stateNameEditor div.label,
#provinceNameEditor div.label,
-#burgBody div.label,
-#regimentBody div.label {
- display: inline-block;
+#regimentBody div.label,
+#markerEditor div.label {
+ display: inline-block;
width: 5.5em;
+ padding: 0.3em 0;
}
-#regimentBody div {
- margin: .1em 0;
+#exportToPngTilesScreen div.label {
+ display: inline-block;
+ width: 5em;
}
#regimentBody input[type="number"] {
- width: 5em;
+ width: 5em;
}
.burgFeature {
- font-size: 1.2em;
- padding: 1px 2px;
- color: #555;
- cursor: pointer;
+ padding: 1px;
+ cursor: pointer;
}
.burgFeature.inactive {
- color: #ddd;
+ color: #ddd;
}
.burgFeature.inactive:hover {
color: #abaaaa;
}
-div.states>.religionName {
- width: 11em;
-}
-
-div.states>.religionType {
- width: 5em;
- cursor: pointer;
- border: 0;
- background-color: transparent;
- -webkit-appearance: none;
- -moz-appearance: none;
- appearance: none;
-}
-
-div.states>.religionForm {
- width: 6em;
-}
-
-div.states>.religionDeity {
- width: 15em;
-}
-
.placeholder {
- opacity: 0;
- cursor: default;
- pointer-events: none;
+ opacity: 0;
+ cursor: default;
+ pointer-events: none;
}
div.states.selected {
- border-color: #b28585;
- background-image: linear-gradient(to right, #f2f2f2 0%, #ebe7e7 50%, #E5DADB 100%);
+ border-color: #b28585;
+ background-image: linear-gradient(to right, #f2f2f2 0%, #ebe7e7 50%, #e5dadb 100%);
}
div.states.active {
@@ -1491,633 +1652,651 @@ div.states.active {
}
div.states.Self {
- border-color: #858b8e;
- background-image: linear-gradient(to right, #f2f2f2 0%, #b0c6d9 100%);
- font-style: italic;
- font-weight: bold;
- margin-bottom: .2em;
- cursor: default !important;
+ margin-bottom: 0.2em;
+ cursor: default !important;
+ padding: 0.2em 0 0 0.5em;
+ font-weight: bold;
}
div.states button.selectCapital {
- margin: -1px 21px 0 7px;
- padding: 0px 3px;
+ margin: -1px 21px 0 7px;
+ padding: 0px 3px;
}
div.states > input.biomeName {
- width: 12em;
+ width: 12em;
}
div.states > div.biomeArea {
- width: 5em;
-}
-
-rect.fillRect {
- stroke: #666666;
- stroke-width: 2;
-}
-
-#militaryHeader > div,
-#regimentsHeader > div {
- width: 5.2em;
+ width: 5em;
}
#militaryBody div.states > input {
- -moz-appearance: textfield;
+ -moz-appearance: textfield;
}
#militaryBody div.states > input,
#militaryBody div.states > div,
#regimentsBody div.states > div {
- width: 5em;
+ width: 5em;
+}
+
+#emblemBody > div {
+ padding: 1px 3px;
+ transition: all 0.3s ease-out;
+}
+
+#emblemBody > div.active {
+ background-color: #54ca7728;
+}
+
+#emblemArmiger {
+ text-align: center;
+ display: block;
+}
+
+#emblemBody .label {
+ width: 6em;
+ display: inline-block;
+}
+
+#emblemBody select {
+ width: 9em;
+}
+
+#emblemsBottom {
+ margin-top: 4px;
+ text-align: center;
+}
+
+#emblemUploadControl,
+#emblemDownloadControl {
+ margin-top: 0.3em;
+ width: 100%;
+}
+
+div.editorLine {
+ margin: 0.2em 0;
+ padding: 0 0.2em;
+ font-size: 0.9em;
+}
+
+#emblemDownloadControl > input {
+ width: 4.1em;
}
#picker text {
- cursor: default;
+ cursor: default;
}
#pickerHeader {
- fill: #916e7f;
- stroke: #5d4651;
- cursor: move;
+ fill: var(--header);
+ stroke: var(--dark-solid);
+ cursor: move;
}
#pickerLabel {
- fill: #f8ffff;
- font-size: 12px;
- font-weight: bold;
- font-family: Arial, Helvetica, sans-serif;
- cursor: move !important;
+ fill: #f8ffff;
+ font-size: 12px;
+ font-weight: bold;
+ font-family: var(--sans-serif);
+ cursor: move !important;
}
#pickerCloseRect {
- cursor: pointer;
- fill: #916e7f;
- stroke: #f8ffff;
+ cursor: pointer;
+ fill: var(--header);
+ stroke: #f8ffff;
}
#pickerCloseText {
- fill: #f8ffff;
- font-size: 10px;
- font-family: Arial, Helvetica, sans-serif;
- pointer-events: none;
+ fill: #f8ffff;
+ font-size: 10px;
+ font-family: var(--sans-serif);
+ pointer-events: none;
}
#pickerControls line {
- stroke: #999999;
- stroke-width: 2;
+ stroke: #999999;
+ stroke-width: 2;
}
#pickerControls circle {
- fill: #ffeb3b;
- stroke: #666666;
- cursor: ew-resize;
+ fill: #ffeb3b;
+ stroke: #666666;
+ cursor: ew-resize;
}
#pickerControls circle:hover {
- fill: #eca116;
- stroke: #000000;
+ fill: #eca116;
+ stroke: #000000;
}
#pickerControls,
#pickerSpaces {
- font-size: 11px;
+ font-size: 11px;
}
#pickerSpaces input {
- width: 22px;
- font-size: 9px;
- -moz-appearance: textfield;
+ width: 22px;
+ font-size: 9px;
+ -moz-appearance: textfield;
}
#pickerSpaces input::-webkit-inner-spin-button,
#pickerSpaces input::-webkit-outer-spin-button {
- -webkit-appearance: none;
- margin: 0;
+ -webkit-appearance: none;
+ margin: 0;
}
-#pickerColors rect, #pickerHatches rect {
- cursor: pointer;
+#pickerColors rect,
+#pickerHatches rect {
+ cursor: pointer;
}
#picker rect.selected {
- outline: 2px dashed #b90c0c;
- stroke-width: 0;
+ outline: 2px dashed #b90c0c;
+ stroke-width: 0;
}
.hoverButton {
- position: sticky;
- margin-left: -1.8em;
- margin-top: 1px;
- background-color: #dedede;
- font-size: 8px;
- cursor: pointer;
- padding: 0px 3px !important;
-}
-
-#unitsBody>div>* {
- display: inline-block;
- margin-bottom: .2em;
+ position: sticky;
+ margin-left: -1.8em;
+ margin-top: 1px;
+ background-color: #dedede;
+ font-size: 8px;
+ cursor: pointer;
+ padding: 0px 3px !important;
}
.unitsHeader {
- margin: .8em 0 0 -1.1em;
- font-weight: bold;
- font-style: italic;
+ margin: 0.8em 0 0 -1.1em;
+ font-weight: bold;
+ font-style: italic;
}
-#unitsBottom, #reliefBottom {
- margin: 6px 0 0 6px;
+#unitsBottom,
+#reliefBottom {
+ margin: 6px 0 0 6px;
}
-#unitsBody>div>div {
- width: 9em;
+#unitsBody label {
+ display: inline-block;
+ width: 9em;
}
-#unitsBody>div>input[type="range"] {
- width: 7em;
+#unitsBody > div > select,
+#unitsBody > div > input[type="text"] {
+ width: 14.4em;
+ border: 1px solid #e9e9e9;
}
-#unitsBody>div>input[type="text"] {
- width: 11.2em;
-}
-
-#unitsBody>div>select {
- width: 11.32em;
-}
-
-#unitsBody>div>input[type="number"] {
- width: 3.4em;
-}
-
-#unitsBody>div>input,
-#unitsBody>div>select {
- border: 1px solid #e9e9e9;
+#unitsBody input[type="range"] {
+ width: 9em;
}
#unitsEditor i.icon-lock-open,
#unitsEditor i.icon-lock {
- color: #626573;
- font-size: .8em;
- cursor: pointer;
- position: fixed;
- margin: .4em 0 0 -.9em;
-}
-
-#barBackColor {
- width: 3.5em;
- padding: 0px;
- height: 1.2em;
+ color: #626573;
+ font-size: 0.8em;
+ cursor: pointer;
+ position: fixed;
+ margin: 0.4em 0 0 -0.9em;
}
#ruler {
- cursor: move;
- fill: none;
+ cursor: move;
+ fill: none;
}
-#ruler circle {
- stroke: #4e5a69;
- fill: yellow;
- cursor: grab;
+#ruler .rulerPoints {
+ stroke: #4e5a69;
+ fill: yellow;
+ cursor: grab;
}
-#ruler rect {
- stroke: #3d3d3d;
- fill: yellow;
- cursor: col-resize;
+#ruler .rulerPoints .control {
+ fill: #999999;
}
#ruler .white {
- stroke: white;
+ stroke: white;
}
#ruler .gray {
- stroke: #3d3d3d;
+ stroke: #3d3d3d;
+ pointer-events: none;
}
#ruler text {
- font-family: 'Times New Roman';
- fill: #3d3d3d;
- stroke: none;
- text-anchor: middle;
- text-shadow: 0 0 4px white;
- cursor: pointer;
+ font-family: var(--serif);
+ fill: #3d3d3d;
+ text-anchor: middle;
+ text-shadow: 0 0 4px white;
+ cursor: pointer;
}
-#ruler .planimeter {
- fill: lightblue;
- fill-rule: evenodd;
- fill-opacity: 0.5;
- stroke: #737373;
-}
-
-#scaleBar {
- stroke: none;
- fill: none;
- cursor: pointer;
-}
-
-#scaleBar text {
- fill: #353540;
- text-anchor: middle;
- font-family: Georgia;
+#ruler path.planimeter {
+ fill: lightblue;
+ fill-rule: evenodd;
+ fill-opacity: 0.5;
+ stroke: #737373;
}
#militaryOptionsTable select {
- border: 1px solid #d4d4d4;
+ border: 1px solid #d4d4d4;
}
#militaryOptionsTable input {
- width: 9em;
- border: 1px solid #d4d4d4;
+ width: 9em;
+ border: 1px solid #d4d4d4;
}
#militaryOptionsTable input[type="number"] {
- width: 4em;
+ width: 4em;
}
#militaryOptionsTable button {
- width: 100%;
+ width: 100%;
}
#gridOverlay {
- fill: none;
+ fill: none;
}
#coordinateLabels {
- fill: #333333;
- font-family: monospace;
- text-shadow: 0 0 4px white;
- stroke-width: 0;
- dominant-baseline: central;
- text-anchor: middle;
+ fill: #333333;
+ font-family: var(--monospace);
+ text-shadow: 0 0 4px white;
+ stroke-width: 0;
+ dominant-baseline: central;
+ text-anchor: middle;
}
ul.share-buttons {
- margin: 4px 0 0 0;
- padding-left: 8%;
+ margin: 4px 0 0 0;
+ padding-left: 8%;
}
ul.share-buttons li {
- padding: 0;
- background: none !important;
- width: 16%;
- margin: 0;
+ padding: 0;
+ background: none !important;
+ width: 16%;
+ margin: 0;
}
ul.share-buttons img {
- width: 2em;
+ width: 2em;
}
input[type="checkbox"] {
- display: none;
+ display: none;
}
.checkbox,
.checkbox-label {
- margin: 3px;
- cursor: pointer;
+ cursor: pointer;
}
-.checkbox+.checkbox-label:before {
- content: '';
- display: inline-block;
- vertical-align: text-top;
- width: .6em;
- height: .6em;
- padding: .2em;
- margin-right: .2em;
- border: 1px solid darkgrey;
- border-radius: 15%;
- background: white;
+.checkbox + .checkbox-label:before {
+ content: "";
+ display: inline-block;
+ vertical-align: bottom;
+ width: 0.6em;
+ height: 0.6em;
+ padding: 0.2em;
+ margin-right: 0.2em;
+ border: 1px solid darkgrey;
+ border-radius: 15%;
+ background: white;
+ font-family: var(--monospace);
}
-.checkbox:checked+.checkbox-label:before {
- line-height: .8em;
- font-weight: bold;
- content: '✓';
- color: #333333;
+.checkbox:checked + .checkbox-label:before {
+ line-height: 0.8em;
+ font-weight: bold;
+ content: "✓";
+ color: #333333;
}
div.textual select,
-div.textual textarea {
- font-family: Copperplate, monospace;
-}
-
+div.textual textarea,
div.textual input {
- font-family: Copperplate, monospace;
+ font-family: var(--monospace);
}
div.textual fieldset {
- margin: 3px 3px 5px 0;
- border-style: dashed;
+ margin: 3px 3px 5px 0;
+ border-style: dashed;
}
-div.textual span, .textual legend {
- font-size: .8em;
- font-weight: bold;
+div.textual span,
+.textual legend {
+ font-size: 0.9em;
+ font-weight: bold;
}
#namesbaseExamples {
- font-family: Copperplate, monospace;
- cursor: pointer;
+ font-family: var(--monospace);
+ cursor: pointer;
}
#markers {
- cursor: pointer;
- font-family: monospace;
- -moz-user-select: none;
- user-select: none;
- text-anchor: middle;
-}
-
-#markerEditor > button {
- vertical-align: top;
+ cursor: pointer;
+ font-family: var(--monospace);
+ user-select: none;
+ text-anchor: middle;
+ dominant-baseline: central;
}
.highlighted {
- outline-width: 2px;
- outline-style: dashed;
- outline-color: #0da6ff;
- outline-offset: 100px;
- fill: none;
+ outline-width: 2px;
+ outline-style: dashed;
+ outline-color: #0da6ff;
+ outline-offset: 100px;
+ fill: none;
}
-div#notes {
- display: none;
- position: fixed;
- width: 28vw;
- right: 1vw;
- top: 1vw;
- font-size: 1.2em;
- border: 1px solid #5e4fa2;
- background: rgba(255, 250, 228, 0.7);
- box-shadow: 2px 2px 5px -3px #3a2804;
- white-space: pre-line;
- pointer-events: none;
+#notes {
+ display: none;
+ position: fixed;
+ width: 28vw;
+ right: 1vw;
+ top: 1vw;
+ font-size: 1.2em;
+ border: 1px solid #5e4fa2;
+ background: rgba(255, 250, 228, 0.7);
+ box-shadow: 2px 2px 5px -3px #3a2804;
}
-div#notesHeader {
- font-weight: bold;
- font-size: 1.3em;
- padding: 0 0 4px 14px;
- border-bottom: 1px solid #5e4fa2;
+@media screen and (max-width: 600px) {
+ #notes {
+ width: 50vw;
+ }
}
-div#notesBody {
- padding: 0 1em;
- max-height: 80vh;
- overflow: auto;
+#notesHeader {
+ font-weight: bold;
+ font-size: 1.3em;
+ padding: 16px 0 4px 12px;
+ border-bottom: 1px solid #5e4fa2;
+}
+
+#notesBody {
+ padding: 14px 12px;
+ max-height: 80vh;
+ overflow: auto;
+}
+
+#notesBody > iframe {
+ user-select: none;
+}
+
+#notesBody p {
+ margin: 4px;
+}
+
+#notesLegend {
+ width: auto;
+ height: 87%;
+ outline: 0;
+ overflow-y: auto;
+ padding: 0.6em;
+ font-family: var(--monospace);
+ background-color: #fff;
+ border: 1px solid #dedede;
+ color: #000;
}
svg.button {
- position: relative;
- background-color: transparent;
- margin: -5px;
- padding: 0;
+ position: relative;
+ background-color: transparent;
+ margin: -5px;
+ padding: 0;
}
#reliefEditor > div > div {
- font-style: italic;
- display: inline-block;
+ font-style: italic;
+ display: inline-block;
}
#reliefEditor div.reliefEditorLabel {
- width: 4em;
+ width: 4em;
}
#reliefEditor input[type="range"] {
- width: 16em;
-}
-
-#reliefEditor input[type="number"] {
- width: 3em;
+ width: 16em;
}
#reliefIconsDiv {
- margin-top: 2px;
- padding: 2px;
+ margin-top: 2px;
+ padding: 2px;
+ width: 100%;
}
#reliefIconsDiv svg {
- width: 40px;
- height: 40px;
- background-color: #e7e6e4;
- border: 1px solid #a9a9a9;
- cursor: pointer;
+ width: 40px;
+ height: 40px;
+ background-color: #e7e6e4;
+ border: 1px solid #a9a9a9;
+ cursor: pointer;
}
#reliefIconsDiv svg:hover {
- border-color: #5c5c5c;
- background-color: #eef6fb;
- transition: all .3s ease-out 3s;
- transform: scale(2);
+ border-color: #5c5c5c;
+ background-color: #eef6fb;
+ transition: all 0.3s ease-out 3s;
+ transform: scale(2);
}
#reliefIconsDiv svg.pressed {
- border: 1px solid #b3352c;
- background-color: #f2f2f2;
+ border: 1px solid #b3352c;
+ background-color: #f2f2f2;
}
#reliefIconsSeletionAny {
- display: none;
- text-anchor: middle;
- dominant-baseline: central;
+ display: none;
+ text-anchor: middle;
+ dominant-baseline: central;
}
#alertMessage {
- -moz-user-select: text;
- user-select: text;
- max-height: 70vh;
- max-width: 75vw;
- overflow: auto;
+ user-select: text;
+ max-height: 70vh;
+ max-width: 75vw;
+ overflow: auto;
}
#alertMessage ul {
- padding-left: 15px;
- margin: 10px 0;
+ padding-left: 1.2em;
+ margin: 1em 0;
}
.pseudoLink {
- cursor: pointer;
+ cursor: pointer;
text-decoration: underline;
}
-#info-line {
- font-size: .9em;
- color: gray;
- user-select: none;
+.info-line {
+ font-size: 0.9em;
+ font-style: italic;
+ color: gray;
+ user-select: none;
}
.optionsSeedRestore {
- font-size: 12px;
- cursor: pointer;
- margin-right: 2px;
+ font-size: 12px;
+ cursor: pointer;
+ margin-right: 2px;
}
.optionsSeedRestore:hover {
- color: blue;
+ color: blue;
}
#worldControls {
- width: 16em;
- display: inline-block;
- vertical-align: top;
+ width: 16em;
+ display: inline-block;
+ vertical-align: top;
}
#worldControls > div {
- display: block;
- margin: 1px 0;
- padding: 2px 0;
+ display: block;
+ margin: 1px 0;
+ padding: 2px 0;
}
#worldControls input[type="number"] {
- border: 1px solid #e5e5e5;
- padding: 0px;
- width: 3.2em;
+ border: 1px solid #e5e5e5;
+ padding: 0px;
+ width: 4em;
}
#worldControls i.icon-lock-open,
#worldControls i.icon-lock {
- color: #626573;
- font-size: .8em;
- cursor: pointer;
+ color: #626573;
+ font-size: 0.8em;
+ cursor: pointer;
}
#globe {
- stroke: black;
- stroke-width: 1;
+ stroke: black;
+ stroke-width: 1;
}
#globeNoteLines {
- stroke-dasharray: 5;
- stroke: #bbb;
+ stroke-dasharray: 5;
+ stroke: #bbb;
}
#globaAxisLabels {
- font-style: italic;
- font-size: 9px;
- font-family: monospace;
- stroke: none;
- fill: #001754;
+ font-style: italic;
+ font-size: 9px;
+ font-family: var(--monospace);
+ stroke: none;
+ fill: #001754;
}
#globeLatLabels {
- font-size: 12px;
- font-family: monospace;
- stroke: none;
- fill: #001754;
+ font-size: 12px;
+ font-family: var(--monospace);
+ stroke: none;
+ fill: #001754;
}
#globeWindArrows {
- fill: none;
- stroke: #6072a3;
- cursor: pointer;
+ fill: none;
+ stroke: #6072a3;
+ cursor: pointer;
}
#globeWindArrows path {
- stroke-width: 1.7px;
- fill: none;
- stroke: #6072a3;
- pointer-events: none;
+ stroke-width: 1.7px;
+ fill: none;
+ stroke: #6072a3;
+ pointer-events: none;
}
#globeWindArrows circle {
- fill: #fff;
- fill-opacity: 0;
- stroke-opacity: .05;
+ fill: #fff;
+ fill-opacity: 0;
+ stroke-opacity: 0.05;
}
#globaAxisLabels #restoreWind:hover {
- cursor: pointer;
- fill: blue;
-}
-
-#globeOutline {
- fill: url(#temperatureGradient);
+ cursor: pointer;
+ fill: blue;
}
#globeArea {
- fill: white;
- fill-opacity: .3;
+ fill: white;
+ fill-opacity: 0.3;
}
#globeGraticule {
- fill: none;
- stroke-width: .2;
+ fill: none;
+ stroke-width: 0.2;
+}
+
+#globePrimeMeridian {
+ stroke: blue;
+ stroke-width: 1.4;
}
#globeEquator {
- stroke: red;
- stroke-width: 1.4;
+ stroke: red;
+ stroke-width: 1.4;
}
#legend {
- cursor: move;
- -moz-user-select: none;
- user-select: none;
+ cursor: move;
+ user-select: none;
}
.dontAsk {
- display: inline-block;
- margin: .9em 0 0 .6em;
+ margin: 0.9em 0 0 0.6em;
+ display: inline-flex;
+ align-items: center;
}
#errorBox {
- font-size: .9em;
- font-family: Consolas, monospace;
- color: #920303;
- background-color: #dabdbd91;
- padding: 2px;
- border: 1px solid #916e7f;
+ font-size: 0.9em;
+ font-family: var(--monospace);
+ color: #920303;
+ background-color: #dabdbd91;
+ padding: 2px;
+ border: 1px solid var(--header);
}
.announcement {
- background-color: #a18888;
- color: white;
- padding: .4em .5em;
- border: dashed 1px #5d4651;
+ background-color: #a18888;
+ color: white;
+ padding: 0.4em 0.5em;
+ border: dashed 1px var(--dark-solid);
+}
+
+.speaker {
+ font-size: 0.9em;
+ cursor: pointer;
}
#prompt {
- position: absolute;
- left: 50%;
- top: 50%;
- transform: translate(-50%, -50%);
- max-width: 22em;
- background-color: #fff;
- padding: 1.2em;
- border: solid 1px #000;
- font-size: 1.2em;
+ position: absolute;
+ left: 50%;
+ top: 50%;
+ transform: translate(-50%, -50%);
+ max-width: 23em;
+ padding: 1.2em;
+ background-color: var(--bg-dialogs);
+ border: solid 1px var(--dark-solid);
+ font-size: 1.2em;
+ z-index: 1000;
}
-#promptTest {
- padding: 0 0 .6em 0;
- font-weight: bold;
- font-family: sans-serif;
+#promptText {
+ padding: 0 0 0.6em 0;
+ font-weight: bold;
+ font-family: var(--sans-serif);
}
#mapOverlay {
- position: absolute;
- display: flex;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- align-items: center;
- justify-content: center;
- z-index: 10;
- pointer-events: none;
- text-align: center;
- background: rgba(0, 0, 0, .5);
- font-size: 2.4em;
- color: #fff5da;
- text-shadow: 0px 1px 4px #4c3a35;
+ position: absolute;
+ inset: 0;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ z-index: 10;
+ pointer-events: none;
+ text-align: center;
+ background: rgba(0, 0, 0, 0.5);
+ font-size: 2.4em;
+ color: #fff5da;
+ text-shadow: 0px 1px 4px #4c3a35;
}
.epgrid line {
stroke: lightgrey;
- stroke-opacity: .7;
+ stroke-opacity: 0.5;
shape-rendering: crispEdges;
}
@@ -2126,34 +2305,119 @@ svg.button {
}
#debug {
- font-size: 1px;
- opacity: .8;
+ font-size: 1px;
+ opacity: 0.8;
+}
+
+#markerTypeSelector {
+ font-size: 0.85em;
+}
+
+#markerTypeSelectorWrapper {
+ position: relative;
+}
+
+#markerTypeSelectMenu {
+ display: none;
+}
+
+#markerTypeSelectMenu.visible {
+ display: block;
+ position: absolute;
+ height: 250px;
+ width: 170px;
+ overflow-y: scroll;
+ background: inherit;
+ bottom: 100%;
+ left: 0;
+ background: white;
+}
+
+#markerTypeSelectMenu > button {
+ display: block;
+ width: 100%;
+ border: 1px solid #ddd;
+ margin-bottom: 1px;
+}
+
+#markerTypeSelectMenu > button:hover {
+ background: #ccc;
+}
+
+.separator {
+ display: flex;
+ align-items: center;
+ text-align: center;
+
+ font-style: italic;
+ font-weight: bold;
+ color: #222;
+ margin: 0.8em 0 0 0;
+}
+.separator::before,
+.separator::after {
+ content: "";
+ flex: 1;
+ border-bottom: 1px solid #333;
+}
+.separator:not(:empty)::before {
+ margin-right: 0.25em;
+}
+.separator:not(:empty)::after {
+ margin-left: 0.25em;
+}
+
+@keyframes clockwiseBorderPulse {
+ 0% {
+ transform: rotate(0deg);
+ }
+ 100% {
+ transform: rotate(360deg);
+ }
+}
+
+#chat-widget-container {
+ user-select: none;
+}
+
+#chat-widget-minimized {
+ animation: fadeIn 1s ease-in;
+ transform: scale(0.65);
+ opacity: var(--bg-opacity);
+}
+
+@keyframes fadeIn {
+ from {
+ opacity: 0;
+ }
+ to {
+ opacity: var(--bg-opacity);
+ }
}
@media print {
- div, canvas {display: none;}
+ div,
+ canvas {
+ display: none;
+ }
}
@media only screen and (max-width: 420px) {
- #collapsible, #options {
- margin: 0;
- border: 0;
- }
-
- #options {
- height: 100vh;
- width: 100vw;
- }
+ table {
+ width: 100%;
+ }
- table {
- width: 100%;
- }
-
- .tabcontent {
- max-width: 100%;
- }
+ .tabcontent {
+ max-width: 100%;
+ }
- .drag-trigger {
- display: none;
- }
+ .drag-trigger {
+ display: none;
+ }
+}
+
+@media (prefers-color-scheme: dark) {
+ body {
+ background: #25252a;
+ }
}
diff --git a/index.html b/index.html
index eaf4bf58..5a18e579 100644
--- a/index.html
+++ b/index.html
@@ -1,3766 +1,8184 @@
-
-
-
- Azgaar's Fantasy Map Generator
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
-
-
-
-
-
-
-
+ Azgaar's Fantasy Map Generator
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
-
-
-
-
-
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Azgaar's
+
Fantasy Map Generator
+
+
LOADING. . .
+
+
+
+
+
+
+ ►
+
+
+ New Map!
+
+
+
+
+
+
+
+
+ ◄
+
+ Layers
+ Style
+ Options
+ Tools
+ About
+
+
+
+
Layers preset:
+
+ Political map
+ Cultural map
+ Religions map
+ Provinces map
+ Biomes map
+ Heightmap
+ Physical map
+ Places of interest
+ Military map
+ Emblems
+ Pure landmass
+ Custom (not saved)
+
+
+
+
+
Displayed layers and layers order:
+
+
+ Tex ture
+
+
+ H eightmap
+
+
+ B iomes
+
+
+ Ce lls
+
+
+ G rid
+
+
+ Co ordinates
+
+
+ W ind Rose
+
+
+ Riv ers
+
+
+ Relief
+
+
+ R eligions
+
+
+ C ultures
+
+
+ S tates
+
+
+ P rovinces
+
+
+ Z ones
+
+
+ Bord ers
+
+
+ Rou tes
+
+
+ T emperature
+
+
+ Population
+
+
+ Ice
+
+
+ Precipita tion
+
+
+ Emblems
+
+
+ L abels
+
+
+ I cons
+
+
+ M ilitary
+
+
+ Mark ers
+
+
+ Rulers
+
+
+ Scale Bar
+
+
+ Vignette
+
+
+
Click to toggle, drag to raise or lower the layer
+
Ctrl + click to edit layer style
+
+
+
View mode:
+
+ Standard
+
+
+ 3D scene
+
+
Globe
+
+
+
+
+
+ Style preset:
+
+
+
+
+
+
Select element:
+
+ Anchor Icons
+ Biomes
+ Borders
+ Burg Icons
+ Cells
+ Coastline
+ Coordinates
+ Cultures
+ Emblems
+ Fogging
+ Grid
+ Heightmap
+ Ice
+ Labels
+ Lakes
+ Landmass
+ Legend
+ Markers
+ Military
+ Ocean
+ Population
+ Precipitation
+ Provinces
+ Relief Icons
+ Religions
+ Rivers
+ Routes
+ Rulers
+ Scale Bar
+ States
+ Temperature
+ Texture
+ Vignette
+ Wind Rose
+ Zones
+
+
+
+
+
+
Toggle global filters:
+
Grayscale
+
Sepia
+
Dingy
+
Tint
+
+
+
+
+
+ Map settings (new map to apply):
+
+
+
+
+ Generator settings:
+
+
+
+
+
+ Configure World
+
+
+ Reset to defaults
+
+
+
+
+
+
Edit
+
+
+ Biomes
+
+
+ Burgs
+
+
+ Cultures
+
+
+ Diplomacy
+
+
+ Emblems
+
+
+ Heightmap
+
+
+ Markers
+
+
+ Military
+
+
+ Namesbase
+
+ Notes
+
+ Provinces
+
+
+ Religions
+
+
+ Rivers
+
+
+ Routes
+
+
+ States
+
+ Units
+ Zones
+
+
+
Regenerate
+
+
+ Burgs
+
+ Cultures
+ Emblems
+ Ice
+
+ State Labels
+
+
+ Markers
+
+
+ Military
+
+
+ Population
+
+
+ Provinces
+
+
+ Relief
+
+ Religions
+
+ Rivers
+
+ Routes
+
+ States
+
+
+ Zones
+
+
+
+
Add
+
+
+ Burg
+
+
+ Label
+
+
+ Marker
+
+
+ River
+
+ Route
+
+
+
Show
+
+
+ Cells
+
+
+ Charts
+
+
+
+
Create
+
+ Submap
+ Transform
+
+
+
+
+
+
+
+ Fantasy Map Generator is an
+ open source
+ tool by Azgaar. You may use auto-generated maps as they are, edit them or even create a new map from
+ scratch. Check out the
+ Quick start , Q&A ,
+ Video tutorial , and
+ hotkeys for
+ guidance.
+
+
+
+ Join our Discord server and
+ Reddit community to ask
+ questions, get help and share maps. The created maps can be used for free, even for commercial purposes.
+
+
+
+ The project is under active development. Creator and main maintainer: Azgaar. To track the development
+ progress see the
+ devboard . For older
+ versions see the
+ changelog .
+ Please report bugs
+ here . You can also
+ contact me directly via email .
+
+
+
+
+
+ Special thanks to
+ all supporters on Patreon!
+
+
+
+
+
+
Check out our other projects:
+
+ •
Armoria : a tool for creating heraldic
+ coats of arms
+
+
+ •
Deorum : a vast gallery of customizable fantasy
+ characters
+
+
+
+
+
+
+
+
+
+ New Map
+ Export
+ Save
+ Load
+ Reset Zoom
+
+
+
+
+
+
+
+ Exit Customization
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ wind
+ latitude
+
+
+ 90°
+ 60°
+ 30°
+ 0°
+ 30°
+ 60°
+ 90°
+
+
+
+
+
+
+
+
+
+
+ Restore winds
+
+
+
+
+
+ Presets:
+ Whole world
+ Northern
+ Tropical
+ Southern
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 🔊
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Height scale:
+ Curve:
+
+ Linear
+ Basis spline
+ Bundle
+ Cubic Catmull-Rom
+ Monotone X
+ Natural
+
+
+
+
+
+
+
+
+
+
+
Click on map to add/remove route points
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Any
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Type:
+
+ Generic
+ River
+ Lake
+ Naval
+ Nomadic
+ Hunting
+ Highland
+
+
+
+
+
+
+
+
+
+
+
Elevation:
+
above sea level
+
+
+
+
Features:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Burg preview:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Pin shape:
+
+ Bubble
+ Pin
+ Square
+ Squarish
+ Diamond
+ Hex
+ Hexy
+ Shieldy
+ Shield
+ Pentagon
+ Heptagon
+ Circle
+ No
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Select template:
+
+ Custom
+ Volcano
+ High Island
+ Low Island
+ Continents
+ Archipelago
+ Atoll
+ Mediterranean
+ Peninsula
+ Pangea
+ Isthmus
+ Shattered
+ Taklamakan
+ Old World
+ Fractious
+
+
+
+ H
+ P
+ R
+ T
+ S
+ M
+ I
+ +
+ *
+
+ ~
+
+
+
+
+
+
+
+
+
+
+
+
+ Seed:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Overlay opacity:
+
+
+
+
+
+
+
+
Assigned colors ( ):
+
+
+
+
+
Unassigned colors ( ):
+
+
+
+
+ Complete the conversion
+
+
+
+
+
+
+
+
Short name:
+
+
🔊
+
+
+
+
+
+
Form name:
+
+ blank
+
+ Beylik
+ Despotate
+ Dominion
+ Duchy
+ Emirate
+ Empire
+ Horde
+ Grand Duchy
+ Heptarchy
+ Khaganate
+ Khanate
+ Kingdom
+ Marches
+ Principality
+ Satrapy
+ Shogunate
+ Sultanate
+ Tsardom
+ Ulus
+ Viceroyalty
+
+
+ Chancellery
+ City-state
+ Diarchy
+ Federation
+ Free City
+ Most Serene Republic
+ Oligarchy
+ Protectorate
+ Republic
+ Tetrarchy
+ Trade Company
+ Triumvirate
+
+
+ Confederacy
+ Confederation
+ Conglomerate
+ Commonwealth
+ League
+ Union
+ United Hordes
+ United Kingdom
+ United Provinces
+ United Republic
+ United States
+ United Tribes
+
+
+ Bishopric
+ Brotherhood
+ Caliphate
+ Diocese
+ Divine Duchy
+ Divine Grand Duchy
+ Divine Principality
+ Divine Kingdom
+ Divine Empire
+ Eparchy
+ Exarchate
+ Holy State
+ Imamah
+ Patriarchate
+ Theocracy
+
+
+ Commune
+ Community
+ Council
+ Free Territory
+ Tribes
+
+
+
+
+
+
+
+
+
+
+ Update label on Apply
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
State:
+
+
+
+
+
+
+
+
+
Click on state name to see relations. Click on relations name to change it
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Short name:
+
+
🔊
+
+
+
+
+
+
Form name:
+
+ blank
+ Area
+ Autonomy
+ Barony
+ Canton
+ Captaincy
+ Chiefdom
+ Clan
+ Colony
+ Council
+ County
+ Deanery
+ Department
+ Dependency
+ Diaconate
+ District
+ Earldom
+ Governorate
+ Island
+ Islands
+ Land
+ Landgrave
+ Mandate
+ Margrave
+ Municipality
+ Occupation zone
+ Parish
+ Prefecture
+ Province
+ Region
+ Republic
+ Reservation
+ Seneschalty
+ Shire
+ State
+ Territory
+ Tribe
+
+
+
+
+
+
+
+
+ Dominant culture:
+
+
+
+
+
+ Select base:
+
+ Names data:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Type:
+
+
+
+
+
+
+
+ Element:
+
+ Element name:
+
+ 🔊
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Shape:
+
+
+ Heater
+ Spanish
+ French
+
+
+ Horsehead
+ Horsehead Edgy
+ Polish
+ Hessen
+ Swiss
+
+
+ Boeotian
+ Roman
+ Kite
+ Old French
+ Renaissance
+ Baroque
+
+
+ Targe
+ Targe2
+ Pavise
+ Wedged
+
+
+ Flag
+ Pennon
+ Guidon
+ Banner
+ Dovetail
+ Gonfalon
+ Pennant
+
+
+ Round
+ Oval
+ Vesica Piscis
+ Square
+ Diamond
+
+
+ Fantasy1
+ Fantasy2
+ Fantasy3
+ Fantasy4
+ Fantasy5
+
+
+ Noldor
+ Gondor
+ Easterling
+ Erebor
+ Iron Hills
+ UrukHai
+ Moria Orc
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ SVG
+
+
+ PNG
+
+
+ JPG
+
+
+
+
+
+
+
+
+
+ Distance unit:
+
+ Mile (mi)
+ Kilometer (km)
+ League (lg)
+ Versta (vr)
+ Nautical mile (nmi)
+ Nautical league (nlg)
+ Custom name
+
+
+
+
+
+
+ 1 map pixel:
+
+
+
+
+ Area unit:
+
+
+
+
+
+
+ Height unit:
+
+ Feet (ft)
+ Meters (m)
+ Fathoms (f)
+ Custom name
+
+
+
+
+
+ Exponent:
+
+
+
+
+
+
+ Temperature scale:
+
+ degree Celsius (°C)
+ degree Fahrenheit (°F)
+ Kelvin (K)
+ degree Rankine (°R)
+ degree Delisle (°De)
+ degree Newton (°N)
+ degree Réaumur (°Ré)
+ degree Rømer (°Rø)
+
+
+
+
+
+
+
+ 1 population point:
+
+
+
+
+
+ Urbanization rate:
+
+
+
+
+
+ Urban density:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ State:
+
+
+ Culture:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Icon
+ Unit name
+ Biomes
+ States
+ Cultures
+ Religions
+ Rural
+ Urban
+ Crew
+ Power
+ Type
+
+ Separate
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ❓
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Style JSON:
+
+
+
+
+
+
+
+
+
+
+
+
+
There are 3 ways to add a custom font:
+
+ Google font . Open Google Fonts , find
+ a font you like and enter its name to the field below.
+
+
+ Local font . If you have a font
+ installed on your computer , just provide the font name. Make sure the browser is reloaded after the installation. The font won't work
+ on machines not having it installed. Good source of fonts are
+ Fontdesk and
+ DaFont .
+
+
+ Font URL . Provide font name and link to the font file hosted online. The best free font
+ hostings are Google Fonts and
+ CDN Fonts . To get font file open the link to css
+ provided by these services and manually copy the link to woff2 of desired variant. To add another
+ variant (e.g. Cyrillic), add the font one more time under the same name, but with another URL
+
+
+
+
+
+
+ Cell: X: Y:
+
+
Latitude:
+
Longitude:
+
Geozone:
+
Area: 0
+
Type: n/a
+
Precipitation: 0
+
River: no
+
Population: 0
+
Elevation: 0
+
Depth: 0
+
Temperature: 0
+
Biome: n/a
+
State: n/a
+
Province: n/a
+
Culture: n/a
+
Religion: n/a
+
Burg: n/a
+
+
+
+
+
Unicode emojis
+
+
Select from the list or paste a Unicode character here:
+
+
. See EmojiDB to search for emojis
+
+
+
+
+
+
External images
+
+ Paste link to the image here:
+
+ Add
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Texture resolution:
+
+ 512x512px
+ 1024x1024px
+ 2048x2048px
+ 4096x4096px
+ 8192x8192px
+
+
+
+
+
+
+
+ Show 3D labels
+
+
+
+
+ Show sky and extend water
+
+
+
+
+ Smooth geometry [slow]
+
+
+
+ Sky:
+ Water:
+
+
+
+
+
+
+
+
Texture resolution:
+
+ 0.5x
+ 1x
+ 2x
+ 4x
+ 8x
+
+
+
+
+ Equirectangular projection is used
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Download image
+
+
+ .svg
+
+
+ .png
+
+
+ .jpeg
+
+
+ tiles
+
+
+
+ Show all labels
+
+
+
+
+ PNG / JPEG scale:
+
+
+
+
+
Generator uses pop-up window to download files. Please ensure your browser does not block popups.
+
+
Export to GeoJSON
+
+ cells
+ routes
+ rivers
+ markers
+
+
+ GeoJSON format is used in GIS tools such as QGIS. Check out
+ wiki-page
+ for guidance.
+
+
+
Export To JSON
+
+ full
+ minimal
+
+ pack cells
+
+
+ grid cells
+
+
+
Export in JSON format can be used as an API replacement.
+
+
+ It's also possible to export map to Foundry VTT , see
+ the module.
+
+
+
+
+
+ Save map to
+
+ machine
+
+
+ dropbox
+
+
+ browser
+
+
+
+ Maps are saved in .map format, that can be loaded back via the Load in menu. There is no way to
+ restore the progress if file is lost. Please keep old save files on your machine or cloud storage as backups.
+
+
+
+
+
+ Load map from
+
+ machine
+
+
+ URL
+
+ storage
+
+
+
Click on storage to open the last saved map.
+
+
+
+ Or load from your Dropbox account
+
+ Connect
+
+
+
+
+
+ Load
+
+ Share
+
+
+
+
+
+
+
+
+
Map will be split into tiles and downloaded as a single zip file. Avoid saving too large images
+
+
+
+
+
Total size:
+
1000 x 1000 px
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Drop a map file to open
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Port
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ?
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Azgaar's
-
Fantasy Map Generator
-
v. 1.4
-
LOADING . . .
-
-
-
-
-
- ►
- New Map!
-
-
-
-
-
-
- ◄
- Layers
- Style
- Options
- Tools
- About
-
-
-
-
Layers preset:
-
- Political map
- Cultural map
- Religions map
- Provinces map
- Biomes map
- Heightmap
- Physical map
- Places of interest
- Military map
- Pure landmass
- Custom (not saved)
-
-
-
-
-
Displayed layers and layers order:
-
- Tex ture
- H eightmap
- B iomes
- Ce lls
- G rid
- Co ordinates
- W ind Rose
- Riv ers
- Relief
- R eligions
- C ultures
- S tates
- P rovinces
- Z ones
- Bord ers
- Rou tes
- T emperature
- Population
- Ice
- Precipita tion
- L abels
- I cons
- M ilitary
- Mark ers
- Rulers
- Scale Bar
-
-
-
-
View mode:
-
Standard
-
3D scene
-
Globe
-
-
-
-
-
Style preset:
-
- Default
- Ancient
- Gloom
- Clean
- Monochrome (for heightmap)
-
-
-
-
-
Select element:
-
- Anchor Icons
- Biomes
- Borders
- Burg Icons
- Cells
- Coastline
- Coordinates
- Cultures
- Fogging
- Grid
- Heightmap
- Ice
- Labels
- Lakes
- Landmass
- Legend
- Markers
- Military
- Ocean
- Population
- Precipitation
- Provinces
- Relief Icons
- Religions
- Rivers
- Routes
- Rulers
- States
- Temperature
- Texture
- Wind Rose
- Zones
-
-
-
-
-
-
-
Toggle global filters:
-
Grayscale
-
Sepia
-
Dingy
-
Tint
-
-
-
-
-
-
Map settings (new map to apply):
-
-
-
Generator settings:
-
-
-
Configure World
-
Reset to defaults
-
-
-
-
-
-
Click to configure:
-
Heightmap
-
Biomes
-
States
-
Provinces
-
Diplomacy
-
Cultures
-
Namesbase
-
Zones
-
Religions
-
Units
-
Notes
-
-
-
-
Click to overview:
-
Burgs
-
Rivers
-
Military
-
Cells
-
-
-
-
-
-
-
Click to regenerate:
-
State labels
-
Relief icons
-
Routes
-
Rivers
-
Population
-
Burgs
-
States
-
Provinces
-
Religions
-
Military
-
Ice
-
Markers
-
Zones
-
-
-
-
Click to add:
-
Burg
-
Label
-
River
-
Route
-
Marker
-
-
-
-
-
-
-
Fantasy Map Generator is a free open source tool which procedurally generates fantasy maps. You may use auto-generated maps as they are, edit them or even create a new map from scratch. Check out the quick start tutorial , Q&A and hotkeys for guidance.
-
Join our Discord server and Reddit community to ask questions, get help and share maps.
-
The project is under active development. Creator and main maintainer: Azgaar. To track the development progress see the devboard . For older versions see the changelog . Please report bugs here . You can also contact me directly via email .
-
-
Special thanks to all supporters on Patreon!
-
-
-
-
-
- New Map
- Save
- Load
- Reset Zoom
-
-
-
-
-
-
-
-
- Exit Customization
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
- wind
- latitude
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
- 90°
- 60°
- 30°
- 0°
- 30°
- 60°
- 90°
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
0
-
-
-
-
-
-
-
-
-
-
- Height scale:
- Curve:
-
- Linear
- Basis spline
- Bundle
- Cubic Catmull-Rom
- Monotone X
- Natural
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
0
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
0
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
0
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Any
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Features:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Select template:
- Custom
- Volcano
- High Island
- Low Island
- Two Continents
- Archipelago
- Atoll
- Mediterranean
- Peninsula
- Pangea
- Isthmus
- Shattered
-
-
-
- H
- P
- R
- T
- S
- +
- *
- ~
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Overlay opacity:
-
-
-
-
-
-
-
- Assigned colors ( ):
-
-
-
- Unassigned colors ( ):
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Brush radius:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Form name:
-
- blank
- Beylik
- Caliphate
- City-state
- Commonwealth
- Confederacy
- Confederation
- Conglomerate
- Despotate
- Diarchy
- Diocese
- Duchy
- Emirate
- Empire
- Eparchy
- Federation
- Free City
- Grand Duchy
- Heptarchy
- Horde
- Imamah
- Khaganate
- Khanate
- Kingdom
- League
- Marches
- Oligarchy
- Principality
- Protectorate
- Republic
- Satrapy
- Shogunate
- Sultanate
- Tetrarchy
- Theocracy
- Trade Company
- Tribes
- Triumvirate
- Tsardom
- Ulus
- Union
- United Hordes
- United Kingdom
- United Provinces
- United Republic
- United States
- United Tribes
-
-
-
-
-
-
-
-
-
- Update label
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Brush size:
-
-
-
-
-
-
-
-
-
-
-
State:
-
-
-
-
-
-
-
-
-
-
-
Ally
-
Friendly
-
Neutral
-
Suspicion
-
Enemy
-
Unknown
-
Rival
-
Vassal
-
Suzerain
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Form name:
-
- blank
- Barony
- Canton
- Council
- County
- Deanery
- Department
- District
- Earldom
- Governorate
- Land
- Landgrave
- Margrave
- Parish
- Prefecture
- Province
- Region
- Republic
- Reservation
- Shire
- State
- Territory
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Brush size:
-
-
-
-
-
-
-
-
-
-
-
-
- auto-apply changes
-
-
-
-
-
-
- Select base:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Brush:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Select object:
-
- Object name:
-
-
-
- Legend:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Brush size:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Distance unit:
-
- Mile (mi)
- Kilometer (km)
- League (lg)
- Versta (vr)
- Custom name
-
-
-
-
-
-
-
-
-
-
-
-
Height unit:
-
- Feet (ft)
- Meters (m)
- Fathoms (f)
- Custom name
-
-
-
-
-
-
-
-
-
Temperature scale:
-
- degree Celsius (°C)
- degree Fahrenheit (°F)
- Kelvin (K)
- degree Rankine (°R)
- degree Delisle (°De)
- degree Newton (°N)
- degree Réaumur (°Ré)
- degree Rømer (°Rø)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- State:
-
- Culture:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Icon
- Unit name
- Rural
- Urban
- Crew
- Power
- Type
- Sep.
-
-
-
-
-
-
-
-
-
-
-
-
- Style JSON:
-
-
-
-
-
-
-
-
-
-
-
-
-
Cell: X: Y:
-
Latitude:
-
Longitude:
-
Area: 0
-
Type: n/a
-
Precipitation: 0
-
River: no
-
Population: 0
-
Elevation: 0
-
Depth: 0
-
Temperature: 0
-
Biome: n/a
-
State: n/a
-
Province: n/a
-
Culture: n/a
-
Religion: n/a
-
Burg: n/a
-
-
-
-
-
-
Select from the list or paste a Unicode character here:
-
-
. See Emojipedia for reference
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Show sky and extend water
-
-
-
- Sky:
- Water:
-
-
-
-
-
-
-
-
Texture resolution:
-
- 0.5x
- 1x
- 2x
- 4x
-
-
-
-
Equirectangular projection is used
-
-
-
-
-
-
-
-
-
-
-
-
-
Please select saving variant:
-
- .map
- .svg
- .png
- .jpeg
- .json
- storage
-
-
Generator uses pop-up window to download files. Please ensure your browser does not block popups
-
- PNG / JPEG scale:
-
-
-
-
-
-
-
Load map from:
-
- local disk
- URL
- storage
-
-
-
-
-
-
-
-
-
-
-
- Сlick the arrow button for options. Zoom in to see the map in details
-
- Drop a .map file to open
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/lang/lang-en.js b/lang/lang-en.js
deleted file mode 100644
index 2ef89bbd..00000000
--- a/lang/lang-en.js
+++ /dev/null
@@ -1,511 +0,0 @@
-// Source translation file for FMG. This file is only used as a reference for tranlation. Version 0.01a
-window.translation = {
- titleFull: "Azgaar's Fantasy Map Generator",
- titleName: "Azgaar's",
- title: "Fantasy Map Generator",
- version: "v. ",
- loading: "Loading",
- newMap: "New Map!",
- layers: "Layers",
- style: "Style",
- options: "Options",
- tools: "Tools",
- about: "About",
- tipOptionsTrigger: "Click to show options pane. Shortcut: Tab",
- tipRegenerate: "Click to generate a new map. Shortcut: F2",
- optionsDragTrigger: "Drag to move options pane",
- optionsHide: "Click to hide options pane. Shortcut: Tab to close this or Esc to close all dialogs",
- layersTab: "Click to change map layers",
- styleTab: "Click to open style editor",
- optionsTab: "Click to change generation and UI options",
- toolsTab: "Click to open tools menu",
- aboutTab: "Click to see Generator info"
-};
-
-return;
-// list of tooltips from init DOM (dynamically added elements are not icluded)
-const sourceDataForReference = {
- optionsTrigger: "Click to show options pane. Shortcut: Tab",
- NeedToAdd!: "Drag to move options pane",
- optionsHide: "Click to hide options pane. Shortcut: Tab to close this or Esc to close all dialogs",
- NeedToAdd!: "Select a map layers preset",
- savePresetButton: "Click to save displayed layers as a new preset",
- removePresetButton: "Click to remove current custom preset",
- NeedToAdd!: "Click to toggle a layer, drag to raise or lower a layer. Ctrl + click to edit layer style",
- toggleRulers: "Rulers: click to toggle, drag to move, click on label to delete. Ctrl + click to edit layer style. Shortcut: = (equal)",
- toggleScaleBar: "Scale Bar: click to toggle. Ctrl + click to edit style. Shortcut: - (minus)",
- viewStandard: "Standard view mode that allows to edit the map",
- viewMesh: "Map presentation in 3D scene. Works best for heightmap. Cannot be used for editing",
- viewGlobe: "Project map on globe. Cannot be used for editing",
- NeedToAdd!: "Select a style preset",
- addStyleButton: "Click to save current style as a new preset",
- removeStyleButton: "Click to remove current custom style preset",
- NeedToAdd!: "Select an element to edit its style",
- styleIsOff: "The selected layer is not visible. See the buttons above to toggle it on",
- NeedToAdd!: "Click and provide a URL to image to be set as a texture",
- styleTextureShiftX: "Shift texture by x axis in pixels",
- styleTextureShiftY: "Shift texture by y axis in pixels",
- styleGridSizeFriendly: "Distance between two adjacent cells in map scale",
- styleShiftX: "Shift by x axis in pixels",
- styleShiftY: "Shift by y axis in pixels",
- styleCompassShiftX: "Shift by x axis in pixels",
- styleCompassShiftY: "Shift by y axis in pixels",
- styleInputFont: "Provide a link to @font-face declaration or type Google font name",
- styleFontAdd: "Add custom font from the web",
- styleFontPlus: "Multiply font size by 1.1",
- styleFontMinus: "Multiply font size by 0.9",
- styleRadiusPlus: "Multiply radius by 1.1",
- styleRadiusMinus: "Multiply radius by 1.1",
- styleIconSizePlus: "Multiply size by 1.1",
- styleIconSizeMinus: "Multiply size by 1.1",
- NeedToAdd!: "Allow system to hide labels if their size in too small or too big on that scale",
- NeedToAdd!: "Map generation settings. Generate a new map to apply the settings",
- toggleFullscreen: "Toggle between screen size and initial canvas size",
- optionsSeedGenerate: "Click to generate a map for this seed",
- optionsMapHistory: "Show seed history to apply a previous seed",
- optionsCopySeed: "Copy map seed as URL. It will produce the same map only if options are default or the same",
- NeedToAdd!: "Regenerate map name",
- NeedToAdd!: "Tool settings that don't affect maps. Changes are getting applied immediately",
- NeedToAdd!: "Mimimal possible zoom level (should be > 0)",
- zoomExtentMin: "Mimimal possible zoom level (should be > 0)",
- NeedToAdd!: "Maximal possible zoom level (should be > 1)",
- zoomExtentMax: "Maximal possible zoom level (should be > 1)",
- zoomExtentDefault: "Restore default [1, 20] zoom extent",
- configureWorld: "Click to open world configurator to setup map position on Globe and World climate",
- optionsReset: "Click to restore default options (page will be reloaded)",
- editHeightmapButton: "Click to open Heightmap customization menu. Shortcut: Shift + H",
- editBiomesButton: "Click to open Biomes Editor. Shortcut: Shift + B",
- editStatesButton: "Click to open States Editor. Shortcut: Shift + S",
- editProvincesButton: "Click to open Provinces Editor. Shortcut: Shift + P",
- editDiplomacyButton: "Click to open Diplomatical relationships Editor. Shortcut: Shift + D",
- editCulturesButton: "Click to open Cultures Editor. Shortcut: Shift + C",
- editNamesBaseButton: "Click to open Namesbase Editor. Shortcut: Shift + N",
- editZonesButton: "Click to open Zones Editor. Shortcut: Shift + Z",
- editReligions: "Click to open Religions Editor. Shortcut: Shift + R",
- editUnitsButton: "Click to open Units Editor. Shortcut: Shift + Q",
- editNotesButton: "Click to open Notes Editor. Shortcut: Shift + O",
- overviewBurgsButton: "Click to open Burgs Overview. Shortcut: Shift + T",
- overviewRiversButton: "Click to open Rivers Overview. Shortcut: Shift + V",
- overviewMilitaryButton: "Click to open Military Forces Overview. Shortcut: Shift + M",
- overviewCellsButton: "Click to open Cell details view. Shortcut: Shift + E",
- regenerateStateLabels: "Click to update state labels placement based on current borders",
- regenerateReliefIcons: "Click to regenerate all relief icons based on current cell biome and elevation",
- regenerateRoutes: "Click to regenerate all routes",
- regenerateRivers: "Click to regenerate all rivers (restore default state)",
- regeneratePopulation: "Click to recalculate rural and urban population",
- regenerateBurgs: "Click to regenerate all burgs and routes. States will remain as they are",
- regenerateStates: "Click to select new capitals and regenerate states. Burgs will remain as they are",
- regenerateProvinces: "Click to regenerate provinces. States will remain as they are",
- regenerateReligions: "Click to regenerate religions",
- regenerateMarkers: "Click to regenerate markers. Hold Ctrl and click to set markers number multiplier",
- regenerateZones: "Click to regenerate zones. Hold Ctrl and click to set zones number multiplier",
- addBurgTool: "Click on map to place a burg. Hold Shift to add multiple. Shortcut: Shift + 1",
- addLabel: "Click on map to place label. Hold Shift to add multiple. Shortcut: Shift + 2",
- addRiver: "Click on map to place a river. Hold Shift to add multiple. Shortcut: Shift + 3",
- addRoute: "Click on map to place a route. Shortcut: Shift + 4",
- addMarker: "Click on map to place a marker. Hold Shift to add multiple. Shortcut: Shift + 5",
- paintBrushes: "Display brushes panel",
- applyTemplate: "Open template editor",
- convertImage: "Open Image Converter",
- heightmapPreview: "Render heightmap data as a small monochrome image",
- heightmap3DView: "Preview heightmap in 3D scene",
- NeedToAdd!: "Click to see supporters names",
- newMapButton: "Generate a new map based on options. Shortcut: F2",
- saveButton: "Select format to save map",
- loadButton: "Load fully functional map in a .map format",
- zoomReset: "Reset map zoom. Shortcut: 0",
- finalizeHeightmap: "Finalize the heightmap and exit the edit mode",
- NeedToAdd!: "Length of Meridian. Almost half of the equator length",
- meridianLength: "Length of Meridian in pixels",
- meridianLengthFriendly: "Length of Meridian is friendly units (depends on user configuration)",
- meridianLengthEarth: "Fantasy world Meridian length relative to real-world Earth (20k km)",
- labelGroupShow: "Show the group selection",
- labelGroupHide: "Hide the group selection",
- labelGroupSelect: "Select a group for this label",
- labelGroupInput: "Provide a name for the new group",
- labelGroupNew: "Create new group for this label",
- labelGroupRemove: "Remove the Group with all labels",
- labelTextShow: "Show the edit label text section",
- labelTextHide: "Hide the edit label text section",
- labelText: "Type to change the label. Enter "|" to move to a new line",
- labelTextRandom: "Generate random name",
- labelEditStyle: "Edit label group style in Style Editor",
- labelSizeShow: "Show the font size section",
- labelSizeHide: "Hide the font size section",
- labelStartOffset: "Set starting offset for the particular label",
- labelRelativeSize: "Set relative size for the particular label",
- labelAlign: "Turn text path into a straight line",
- labelLegend: "Edit free text notes (legend) for this label",
- labelRemoveSingle: "Remove the label. Shortcut: Delete",
- riverNameShow: "Show river name section",
- riverNameHide: "Hide the river name section",
- riverName: "Change river proper name",
- riverType: "Change river type name",
- riverNameCulture: "Generate culture-specific name for the river",
- riverNameRandom: "Generate random name for the river",
- riverWidthShow: "Show river width and widening change section",
- riverWidthHide: "Hide the river width and widening change section",
- riverWidthInput: "Change river width",
- riverIncrement: "Change river bed increment (widening speed)",
- riverEditStyle: "Edit style for all rivers in Style Editor",
- riverLength: "River length in selected units",
- riverNew: "Create new river clicking on map",
- riverLegend: "Edit free text notes (legend) for the river",
- riverRemove: "Remove river. Shortcut: Delete",
- routeGroupsShow: "Show the group selection",
- routeGroupsHide: "Hide the group section",
- routeGroup: "Select a group for this route",
- routeGroupName: "Provide a name for the new group",
- routeGroupAdd: "Create new group for this route",
- routeGroupRemove: "Remove all routes of this group",
- routeEditStyle: "Edit route group style in Style Editor",
- routeLength: "Route length in selected units",
- routeSplit: "Click on a control point to split the route",
- routeLegend: "Edit free text notes (legend) for the route",
- routeNew: "Create new route clicking on map",
- routeRemove: "Remove route. Shortcut: Delete",
- lakeGroupsShow: "Show the group selection",
- lakeGroupsHide: "Hide the group section",
- lakeGroup: "Select a group for this lake",
- lakeGroupName: "Provide a name for the new group",
- lakeGroupAdd: "Create new group for this lake",
- lakeGroupRemove: "Remove the group",
- lakeEditStyle: "Edit lake group style in Style Editor",
- lakeArea: "Lake area in selected units",
- lakeLegend: "Edit free text notes (legend) for the lake",
- coastlineGroupsShow: "Show the group selection",
- coastlineGroupsHide: "Hide the group section",
- coastlineGroup: "Select a group for this coastline",
- coastlineGroupName: "Provide a name for the new group",
- coastlineGroupAdd: "Create new group for this coastline",
- coastlineGroupRemove: "Remove the group",
- coastlineEditStyle: "Edit coastline group style in Style Editor",
- coastlineArea: "Lake area in selected units",
- reliefIndividual: "Edit individual selected icon",
- reliefBulkAdd: "Place icons in a bulk",
- reliefBulkRemove: "Remove icons in a bulk",
- reliefEditStyle: "Edit Relief Icons style in Style Editor",
- reliefCopy: "Copy selected relief icon",
- reliefMoveFront: "Move selected relief icon to front",
- reliefMoveBack: "Move selected relief icon back",
- reliefRemove: "Remove selected relief icon. Shortcut: Delete",
- burgName: "Type to rename the burg",
- burgNameReCulture: "Generate culture-specific name for the burg",
- burgNameReRandom: "Generate random name for the burg",
- burgPopulation: "Set burg population",
- burgCapital: "Shows whether the burg is a state capital. Click to toggle",
- burgPort: "Shows whether the burg is a port. Click to toggle",
- burgCitadel: "Shows whether the burg has a citadel (castle). Click to toggle",
- burgWalls: "Shows whether the burg is walled. Click to toggle",
- burgPlaza: "Shows whether the burg is a trade center (has big marketplace). Click to toggle",
- burgTemple: "Shows whether the burg is a religious center. Click to toggle",
- burgShanty: "Shows whether the burg has a shanty town. Click to toggle",
- burgGroupShow: "Show group change section",
- burgGroupHide: "Hide group change section",
- burgSelectGroup: "Select a group for this burg",
- burgInputGroup: "Create new Group for the Burg",
- burgAddGroup: "Create new group for the burg",
- burgRemoveGroup: "Remove selected burg group",
- burgStyleShow: "Show style edit section",
- burgStyleHide: "Hide style edit section",
- burgEditLabelStyle: "Edit label style for burg group in Style Editor",
- burgEditIconStyle: "Edit icon style for burg group in Style Editor",
- burgEditAnchorStyle: "Edit port icon (anchor) style for burg group in Style Editor",
- burgSeeInMFCG: "Open burg in the Medieval Fantasy City Generator by Watabou. Ctrl + click to change the seed",
- burgOpenCOA: "Open burg's COA in the Iron Arachne Heraldry Generator. Ctrl + click to change the seed",
- burgRelocate: "Relocate burg",
- burglLegend: "Edit free text notes (legend) for this burg",
- burgRemove: "Remove non-capital burg. Shortcut: Delete",
- markerGroup: "Change marker type",
- markerSelectGroup: "Select type for the selected marker",
- markerInputGroup: "Create new type for selected marker",
- markerAddGroup: "Create new markers type",
- markerRemoveGroup: "Remove all markers of that type",
- markerIcon: "Change marker icon and edit positioning",
- NeedToAdd!: "Change marker icon size",
- markerIconSize: "Change marker icon size",
- NeedToAdd!: "Change marker horizontal shift",
- markerIconShiftX: "Change icon horizontal shift",
- NeedToAdd!: "Change marker vertical shift",
- markerIconShiftY: "Change vertical shift",
- NeedToAdd!: "Paste custom unicode symbol to use as icon",
- markerIconCustom: "Paste custom unicode symbol to use as icon",
- markerStyle: "Change marker size and colors",
- NeedToAdd!: "Change marker base (pin) style",
- markerSize: "Change marker size",
- markerBaseStroke: "Change pin stroke color",
- markerBaseFill: "Change pin fill color",
- NeedToAdd!: "Change marker icon style",
- markerIconStrokeWidth: "Change icon stroke width",
- markerIconStroke: "Change icon stroke color. Ensure icon stroke width is non-zero",
- markerIconFill: "Change icon fill color",
- markerToggleBubble: "Toggle pin (bubble) display",
- markerLegendButton: "Edit place legend (free text notes)",
- markerAdd: "Add additional marker of that type",
- markerRemove: "Remove the marker. Shortcut: Delete",
- undo: "Undo the latest action (Ctrl + Z)",
- redo: "Redo the action (Ctrl + Y)",
- rescaleShow: "Show rescaler slider",
- rescaleCondShow: "Rescaler: change height if condition is fulfilled",
- smoothHeights: "Smooth all heights a bit",
- disruptHeights: "Disrupt (randomize) heights a bit",
- brushClear: "Set height for all cells to 0 (erase the map)",
- rescaleHide: "Hide rescaler slider",
- rescaler: "Change height for all cells",
- rescaleCondHide: "Hide rescaler",
- rescaleExecute: "Click to perform an operation",
- templateHill: "Hill: small blob",
- templatePit: "Pit: round depression",
- templateRange: "Range: elongated elevation",
- templateTrough: "Trough: elongated depression",
- templateStrait: "Strait: centered vertical or horizontal depression",
- templateAdd: "Add or subtract value from all heights in range",
- templateMultiply: "Multiply all heights in range by factor",
- templateSmooth: "Smooth the map replacing cell heights by an average values of its neighbors",
- NeedToAdd!: "Click to skip the step",
- NeedToAdd!: "Remove the step",
- NeedToAdd!: "Drag to reorder",
- NeedToAdd!: "Placement range percentage along Y axis (minY-maxY)",
- NeedToAdd!: "Placement range percentage along X axis (minX-maxX)",
- NeedToAdd!: "Blob maximum height, use hyphen to get a random number in range",
- NeedToAdd!: "Blobs to add, use hyphen to get a random number in range",
- templateRun: "Apply current template",
- templateUndo: "Undo the latest action",
- templateRedo: "Redo the action",
- templateSave: "Download the template as a text file",
- templateLoad: "Open previously downloaded template",
- templateCA: "Find or share custom template on Cartography Assets portal",
- templateTutorial: "Open Template Editor Tutorial",
- convertImageLoad: "Load image to convert",
- convertAutoLum: "Auto-assign colors based on liminosity (good to monochrome images)",
- convertAutoHue: "Auto-assign colors based on hue (good to colored images)",
- convertColorsButton: "Set number of colors",
- convertComplete: "Complete the assignment. All unassigned colors will be considered as ocean",
- NeedToAdd!: "Click to sort by biome name",
- NeedToAdd!: "Click to sort by biome habitability",
- NeedToAdd!: "Click to sort by biome cells number",
- NeedToAdd!: "Click to sort by biome area",
- NeedToAdd!: "Click to sort by biome population",
- biomesEditorRefresh: "Refresh the Editor",
- biomesEditStyle: "Edit biomes style in Style Editor",
- biomesLegend: "Toggle Legend box",
- biomesPercentage: "Toggle percentage / absolute values views",
- biomesManually: "Manually re-assign biomes to not follow the default moisture/temperature pattern",
- biomesManuallyApply: "Apply current assignment",
- biomesManuallyCancel: "Cancel assignment",
- biomesAdd: "Add a custom biome",
- biomesRestore: "Restore the defaults and re-define biomes based on current moisture and temperature",
- biomesRegenerateReliefIcons: "Regenerate relief icons based on current biomes and elevation",
- biomesExport: "Save biomes-related data as a text file (.csv)",
- NeedToAdd!: "Click to sort by state name",
- NeedToAdd!: "Click to sort by state form name",
- NeedToAdd!: "Click to sort by capital name",
- NeedToAdd!: "Click to sort by state dominant culture",
- NeedToAdd!: "Click to sort by state burgs count",
- NeedToAdd!: "Click to sort by state area",
- NeedToAdd!: "Click to sort by state population",
- NeedToAdd!: "Click to sort by state type",
- NeedToAdd!: "Click to sort by state expansion value",
- NeedToAdd!: "Click to sort by state cells count",
- statesEditorRefresh: "Refresh the Editor",
- statesEditStyle: "Edit states style in Style Editor",
- statesLegend: "Toggle Legend box",
- statesPercentage: "Toggle percentage / absolute values views",
- statesChart: "Show states bubble chart",
- statesRegenerate: "Show the regeneration menu and more data",
- statesRegenerateBack: "Hide the regeneration menu",
- statesRandomize: "Randomize states Expansion value and re-calculate states and provinces",
- statesRecalculate: "Recalculate states based on current values of growth-related attributes",
- statesManually: "Manually re-assign states",
- statesManuallyApply: "Apply assignment",
- statesManuallyCancel: "Cancel assignment",
- statesAdd: "Add a new state. Hold Shift to add multiple",
- statesExport: "Save state-related data as a text file (.csv)",
- NeedToAdd!: "State short name",
- stateNameEditorShort: "Type to change the short name",
- stateNameEditorShortCulture: "Generate culture-specific name",
- stateNameEditorShortRandom: "Generate random name",
- NeedToAdd!: "State form name",
- stateNameEditorCustomForm: "Create custom state form name",
- stateNameEditorAddForm: "Click to add custom state form name to the list",
- NeedToAdd!: "State full name",
- stateNameEditorFull: "Type to change the full name",
- stateNameEditorFullRegenerate: "Click to re-generate full name",
- NeedToAdd!: "Click to sort by province name",
- NeedToAdd!: "Click to sort by province form name",
- NeedToAdd!: "Click to sort by province capital",
- NeedToAdd!: "Click to sort by province owner",
- NeedToAdd!: "Click to sort by province area",
- NeedToAdd!: "Click to sort by province population",
- provincesEditorRefresh: "Refresh the Editor",
- provincesEditStyle: "Edit provinces style in Style Editor",
- provincesPercentage: "Toggle percentage / absolute values views",
- provincesChart: "Show provinces chart",
- provincesToggleLabels: "Toggle province labels",
- provincesExport: "Save provinces-related data as a text file (.csv)",
- provincesManually: "Manually re-assign provinces",
- provincesManuallyApply: "Apply assignment",
- provincesManuallyCancel: "Cancel assignment",
- provincesAdd: "Add a new province. Hold Shift to add multiple",
- provincesRemoveAll: "Remove all provinces. States will remain as they are",
- NeedToAdd!: "Click to sort by state name",
- NeedToAdd!: "Click to sort by diplomatical relations",
- NeedToAdd!: "Ally means states formed a defensive pact and will protect each other in case of third party aggression",
- NeedToAdd!: "State is friendly to anouther state when they share some common interests",
- NeedToAdd!: "Neutral means states relations are neither positive nor negative",
- NeedToAdd!: "Suspicion means shate has a cautious distrust of another state",
- NeedToAdd!: "Enemies are states at war with each other",
- NeedToAdd!: "Relations are unknown if states do not have enought information about each other",
- NeedToAdd!: "Rivalry is a state of competing for dominance in the region",
- NeedToAdd!: "Vassal is a state having obligation to its suzerain",
- NeedToAdd!: "Suzerain is a state having some control over its vassals",
- diplomacyEditorRefresh: "Refresh the Editor",
- diplomacyEditStyle: "Edit states (including diplomacy view) style in Style Editor",
- diplomacyRegenerate: "Regenerate diplomatical relations",
- diplomacyHistory: "Show relations history",
- diplomacyMatrix: "Show relations matrix",
- diplomacyExport: "Save state relations matrix as a text file (.csv)",
- NeedToAdd!: "Province short name",
- provinceNameEditorShort: "Type to change the short name",
- provinceNameEditorShortCulture: "Generate culture-specific name",
- provinceNameEditorShortRandom: "Generate random name",
- NeedToAdd!: "Province form name",
- provinceNameEditorCustomForm: "Create custom province form name",
- provinceNameEditorAddForm: "Click to add custom province form name to the list",
- NeedToAdd!: "Province full name",
- provinceNameEditorFull: "Type to change the full name",
- provinceNameEditorFullRegenerate: "Click to re-generate full name",
- NeedToAdd!: "Click to sort by culture name",
- NeedToAdd!: "Click to sort by culture cells count",
- NeedToAdd!: "Click to sort by expansionism",
- NeedToAdd!: "Click to sort by type",
- NeedToAdd!: "Click to sort by culture area",
- NeedToAdd!: "Click to sort by culture population",
- NeedToAdd!: "Click to sort by culture namesbase",
- culturesEditorRefresh: "Refresh the Editor",
- culturesEditStyle: "Edit cultures style in Style Editor",
- culturesLegend: "Toggle Legend box",
- culturesPercentage: "Toggle percentage / absolute values display mode",
- culturesHeirarchy: "Show cultures hierarchy tree",
- culturesManually: "Manually re-assign cultures",
- culturesManuallyApply: "Apply assignment",
- culturesManuallyCancel: "Cancel assignment",
- culturesEditNamesBase: "Edit a database used for names generation",
- culturesAdd: "Add a new culture. Hold Shift to add multiple",
- culturesExport: "Download cultures-related data",
- culturesRecalculate: "Recalculate cultures based on current values of growth-related attributes",
- namesbaseSelect: "Select base to edit",
- namesbaseTextarea: "Names data: a comma separated list of source names used for names generation",
- namesbaseName: "Type to change a base name",
- namesbaseMin: "Recommended minimum name length",
- namesbaseMax: "Recommended maximum name length",
- namesbaseDouble: "Populate with letters that can used twice in a row",
- namesbaseMulti: "Multi-word names rate. 1 - allow all multi-word names, 0 - all names should spelled as a single word",
- namesbaseExamples: "Examples. Click to re-generate",
- namesbaseUpdateExamples: "Re-generate examples based on provided data",
- namesbaseAdd: "Add new namesbase",
- namesbaseDefault: "Restore default namesbase",
- namesbaseDownload: "Download namesbase to PC",
- namesbaseUpload: "Upload a namesbase from PC",
- namesbaseCA: "Find or share custom namesbase on Cartography Assets portal",
- NeedToAdd!: "Zone description",
- NeedToAdd!: "Zone cells count",
- NeedToAdd!: "Zone area",
- NeedToAdd!: "Zone population",
- zonesEditorRefresh: "Refresh the Editor",
- zonesEditStyle: "Edit zones style in Style Editor",
- zonesLegend: "Toggle Legend box",
- zonesPercentage: "Toggle percentage / absolute values views",
- zonesManually: "Re-assign zones",
- zonesManuallyApply: "Apply assignment",
- zonesManuallyCancel: "Cancel assignment",
- zonesRemove: "Click to toggle the removal mode on brush dragging. Shortcut: ctrl",
- zonesAdd: "Add a new zone layer",
- zonesExport: "Download zones-related data",
- notesSelect: "Select object",
- notesName: "Type to change object name",
- notesText: "Type object description",
- notesFocus: "Focus on selected object",
- notesDownload: "Download notes to PC",
- notesUpload: "Upload notes from PC",
- notesRemove: "Remove this note",
- NeedToAdd!: "Click to sort by religion name",
- NeedToAdd!: "Click to sort by religion type",
- NeedToAdd!: "Click to sort by religion form",
- NeedToAdd!: "Click to sort by supreme deity",
- NeedToAdd!: "Click to sort by religion area",
- NeedToAdd!: "Click to sort by number of believers (religion area population)",
- religionsEditorRefresh: "Refresh the Editor",
- religionsEditStyle: "Edit religions style in Style Editor",
- religionsLegend: "Toggle Legend box",
- religionsPercentage: "Toggle percentage / absolute values display mode",
- religionsHeirarchy: "Show religions hierarchy tree",
- religionsExtinct: "Show/hide extinct religions (religions without cells)",
- religionsManually: "Manually re-assign religions",
- religionsManuallyApply: "Apply assignment",
- religionsManuallyCancel: "Cancel assignment",
- religionsAdd: "Add a new religion. Hold Shift to add multiple",
- religionsExport: "Download religions-related data",
- addLinearRuler: "Click to place a linear measurer (ruler)",
- addOpisometer: "Drag to measure a curve length (opisometer)",
- addPlanimeter: "Drag to measure a polygon area (planimeter)",
- removeRulers: "Remove all rulers from the map. Click on ruler label to remove a ruler separately",
- unitsRestore: "Restore default units settings",
- NeedToAdd!: "Click to sort by burg name",
- NeedToAdd!: "Click to sort by province name",
- NeedToAdd!: "Click to sort by state name",
- NeedToAdd!: "Click to sort by culture name",
- NeedToAdd!: "Click to sort by burg population",
- NeedToAdd!: "Click to sort by burg type",
- burgsOverviewRefresh: "Refresh the Editor",
- burgsChart: "Show burgs bubble chart",
- regenerateBurgNames: "Regenerate burg names based on assigned culture",
- addNewBurg: "Add a new burg. Hold Shift to add multiple",
- burgsExport: "Save burgs-related data as a text file (.csv)",
- burgNamesImport: "Rename burgs in bulk",
- burgsRemoveAll: "Remove all burgs except for capitals. To remove a capital remove its state first",
- NeedToAdd!: "Click to sort by river name",
- NeedToAdd!: "Click to sort by river type name",
- NeedToAdd!: "Click to sort by river length",
- NeedToAdd!: "Click to sort by river basin",
- riversOverviewRefresh: "Refresh the Editor",
- addNewRiver: "Add a new river. Hold Shift to add multiple",
- riversBasinHighlight: "Toggle basin highlight mode",
- riversExport: "Save rivers-related data as a text file (.csv)",
- riversRemoveAll: "Remove all rivers",
- NeedToAdd!: "State name. Click to sort",
- militaryTotal: "Total military personnel (considering crew). Click to sort",
- NeedToAdd!: "State population. Click to sort",
- NeedToAdd!: "Military personnel rate (% of state population). Depends on war alert. Click to sort",
- NeedToAdd!: "War Alert. Modifier to military forces number, depends of political situation. Click to sort",
- militaryOverviewRefresh: "Refresh the Editor",
- militaryOptionsButton: "Military options. Click to customize units",
- militaryOverviewRecalculate: "Recalculate military forces based on current options",
- militaryExport: "Save military-related data as a text file (.csv)",
- militaryVisualize: "Show armies on the map",
- NeedToAdd!: "Unit name. If name is changed for existing unit, old unit will be replaced",
- NeedToAdd!: "Conscription percentage for rural population",
- NeedToAdd!: "Conscription percentage for urban population",
- NeedToAdd!: "Average number of people in crew",
- NeedToAdd!: "Unit type to apply special rules on forces recalculation",
- styleSaverName: "Enter style preset name",
- styleSaverTip: "Shows whether there is already a preset with this name",
- styleSaverJSON: "Style JSON is getting formed based the current settings, but can be entered manually",
- styleSaverSave: "Save current JSON as a new style preset",
- styleSaverDownload: "Download the style as a .json file (can be opened in any text editor)",
- styleSaverLoad: "Open previously downloaded style file",
- styleSaverCA: "Find or share custom style preset on Cartography Assets portal",
- NeedToAdd!: "Equirectangular projection is used: distortion is maximum on poles. Use map with aspect ratio 2:1 for best result",
- options3dUpdate: "Update the scene",
- NeedToAdd!: "Configure world and map size and climate settings",
- options3dSave: "Save screenshot of the 3d scene",
- NeedToAdd!: "Download the map as fully-functional .map file to your machine",
- NeedToAdd!: "Download the map as vector image (open in browser or Inkscape)",
- NeedToAdd!: "Download visible part of the map as .png (lossless compressed)",
- NeedToAdd!: "Download visible part of the map as .jpeg (lossy compressed) image",
- NeedToAdd!: "Download map data in GeoJSON format",
- NeedToAdd!: "Save fully-functional map to browser storage. Shortcut: F6",
- NeedToAdd!: "Load .map file from local disk",
- NeedToAdd!: "Load .map file from URL (server should allow CORS)",
- NeedToAdd!: "Load map from browser storage (if saved before)"
-};
\ No newline at end of file
diff --git a/lang/lang-ru.js b/lang/lang-ru.js
deleted file mode 100644
index d6b32483..00000000
--- a/lang/lang-ru.js
+++ /dev/null
@@ -1,23 +0,0 @@
-// Файл перевода FMG на русский язык. Источник: lang-en.js. Версия 0.01a
-window.translation = {
- titleFull: "Генератор фэнтези карт",
- titleName: " ",
- title: "Генератор фэнтези карт",
- version: "в. ",
- loading: "ЗАГРУЗКА",
- newMap: "Новая карта!",
- layers: "Слои",
- style: "Стиль",
- options: "Опции",
- tools: "Редактор",
- about: "Справка",
- tipOptionsTrigger: "Нажмите для открытия панели меню. Клавиша Tab",
- tipRegenerate: "Нажмите, чтобы сгенерировать новую карту. Клавиша F2",
- optionsDragTrigger: "Зажмите и тяните, чтобы переместить меню",
- optionsHide: "Нажмите, чтобы скрыть меню. Клавиша: Tab (скрыть меню) Esc (скрыть меню и закрыть все окна)",
- layersTab: "Нажмите, чтобы изменить слои карты, их видимость и порядок",
- styleTab: "Нажмите, чтобы окрыть вкладку для работы над стилем",
- optionsTab: "Нажмите, чтобы изменить настройки генерации карты и пользовательского интерейса",
- toolsTab: "Нажмите, чтобы открыть вкладку инструментов",
- aboutTab: "Нажмите, чтобы посмотреть информацию о Генераторе"
-};
\ No newline at end of file
diff --git a/libs/alea.min.js b/libs/alea.min.js
new file mode 100644
index 00000000..f4ecef67
--- /dev/null
+++ b/libs/alea.min.js
@@ -0,0 +1,3 @@
+/*https://github.com/macmcmeans/aleaPRNG/blob/master/aleaPRNG-1.1.js
+©2010 Johannes Baagøe, MIT license; Derivative ©2017-2020 W. Mac" McMeans, BSD license.*/
+const aleaPRNG=function(){return function(n){"use strict";var r,t,e,o,a,u=new Uint32Array(3),i="";function c(n){var a=function(){var n=4022871197,r=function(r){r=r.toString();for(var t=0,e=r.length;t>>0,n=(o*=n)>>>0,n+=4294967296*(o-=n)}return 2.3283064365386963e-10*(n>>>0)};return r.version="Mash 0.9",r}();r=a(" "),t=a(" "),e=a(" "),o=1;for(var u=0;uarguments[1]&&(n=arguments[1],r=arguments[0]),f(n)&&f(r)?Math.floor(l()*(r-n+1))+n:l()*(r-n)+n},l.restart=function(){c(a)},l.seed=function(){c(Array.prototype.slice.call(arguments))},l.version=function(){return"aleaPRNG 1.1.0"},l.versions=function(){return"aleaPRNG 1.1.0, "+i},0===n.length&&(window.crypto.getRandomValues(u),n=[u[0],u[1],u[2]]),a=n,c(n),l}(Array.prototype.slice.call(arguments))};
\ No newline at end of file
diff --git a/libs/delaunator.min.js b/libs/delaunator.min.js
index 6c8af070..1f63da53 100644
--- a/libs/delaunator.min.js
+++ b/libs/delaunator.min.js
@@ -1 +1 @@
-!function(t,i){"object"==typeof exports&&"undefined"!=typeof module?module.exports=i():"function"==typeof define&&define.amd?define(i):t.Delaunator=i()}(this,function(){"use strict";var t=Math.pow(2,-52),i=function(i){var n=i.length>>1;if(n>0&&"number"!=typeof i[0])throw new Error("Expected coords to contain numbers.");this.coords=i;var s=2*n-5,l=this.triangles=new Uint32Array(3*s),o=this.halfedges=new Int32Array(3*s);this._hashSize=Math.ceil(Math.sqrt(n));for(var f=this.hullPrev=new Uint32Array(n),u=this.hullNext=new Uint32Array(n),v=this.hullTri=new Uint32Array(n),d=new Int32Array(this._hashSize).fill(-1),_=new Uint32Array(n),y=1/0,g=1/0,c=-1/0,w=-1/0,p=0;pc&&(c=b),x>w&&(w=x),_[p]=p}for(var z,S,k,A=(y+c)/2,T=(g+w)/2,M=1/0,K=0;K0&&(S=N,M=E)}for(var D=i[2*S],F=i[2*S+1],I=1/0,P=0;P=a&&r[i[o]]>l;)i[o+1]=i[o--];i[o+1]=s}else{var f=a+h>>1,u=a+1,v=h;e(i,f,u),r[i[a]]>r[i[h]]&&e(i,a,h),r[i[u]]>r[i[h]]&&e(i,u,h),r[i[a]]>r[i[u]]&&e(i,a,u);for(var d=i[u],_=r[d];;){do{u++}while(r[i[u]]<_);do{v--}while(r[i[v]]>_);if(v=v-a?(t(i,r,u,h),t(i,r,a,v-1)):(t(i,r,a,v-1),t(i,r,u,h))}}(_,O,0,n-1),this.hullStart=z;var R=3;u[z]=f[k]=S,u[S]=f[z]=k,u[k]=f[S]=z,v[z]=0,v[S]=1,v[k]=2,d[this._hashKey(U,L)]=z,d[this._hashKey(D,F)]=S,d[this._hashKey(q,B)]=k,this.trianglesLen=0,this._addTriangle(z,S,k,-1,-1,-1);for(var V=0,W=void 0,X=void 0;V<_.length;V++){var Y=_[V],Z=i[2*Y],$=i[2*Y+1];if(!(V>0&&Math.abs(Z-W)<=t&&Math.abs($-X)<=t)&&(W=Z,X=$,Y!==z&&Y!==S&&Y!==k)){for(var tt=0,it=0,rt=this._hashKey(Z,$);it0?3-h:1+h)/4*this._hashSize))%this._hashSize;var r,a,h},i.prototype._legalize=function(t){var i=this.triangles,r=this.coords,a=this.halfedges,h=a[t],e=t-t%3,n=h-h%3,s=e+(t+1)%3,l=e+(t+2)%3,o=n+(h+2)%3;if(-1===h)return l;var f,u,v,d,_,y,g,c,w,p,b,x,z,S,k,A,T=i[l],M=i[t],K=i[s],m=i[o];if(f=r[2*T],u=r[2*T+1],v=r[2*M],d=r[2*M+1],_=r[2*K],y=r[2*K+1],g=r[2*m],c=r[2*m+1],(w=f-g)*((x=d-c)*(A=(z=_-g)*z+(S=y-c)*S)-(k=(b=v-g)*b+x*x)*S)-(p=u-c)*(b*A-k*z)+(w*w+p*p)*(b*S-x*z)<0){i[t]=m,i[h]=T;var U=a[o];if(-1===U){var L=this.hullStart;do{if(this.hullTri[L]===o){this.hullTri[L]=t;break}L=this.hullNext[L]}while(L!==this.hullStart)}this._link(t,U),this._link(h,a[l]),this._link(l,o);var N=n+(h+1)%3;return this._legalize(t),this._legalize(N)}return l},i.prototype._link=function(t,i){this.halfedges[t]=i,-1!==i&&(this.halfedges[i]=t)},i.prototype._addTriangle=function(t,i,r,a,h,e){var n=this.trianglesLen;return this.triangles[n]=t,this.triangles[n+1]=i,this.triangles[n+2]=r,this._link(n,a),this._link(n+1,h),this._link(n+2,e),this.trianglesLen+=3,n},i});
+!function(t,i){"object"==typeof exports&&"undefined"!=typeof module?module.exports=i():"function"==typeof define&&define.amd?define(i):(t="undefined"!=typeof globalThis?globalThis:t||self).Delaunator=i()}(this,(function(){"use strict";const t=134217729;function i(t,i,s,e,n){let h,r,l,o,a=i[0],f=e[0],c=0,u=0;f>a==f>-a?(h=a,a=i[++c]):(h=f,f=e[++u]);let _=0;if(ca==f>-a?(r=a+h,l=h-(r-a),a=i[++c]):(r=f+h,l=h-(r-f),f=e[++u]),h=r,0!==l&&(n[_++]=l);ca==f>-a?(r=h+a,o=r-h,l=h-(r-o)+(a-o),a=i[++c]):(r=h+f,o=r-h,l=h-(r-o)+(f-o),f=e[++u]),h=r,0!==l&&(n[_++]=l);for(;c0!=d>0)return g;const y=Math.abs(_+d);return Math.abs(g)>=33306690738754716e-32*y?g:-function(s,o,a,f,c,u,_){let d,g,y,w,b,A,k,M,p,x,S,T,z,U,m,K,L,v;const F=s-c,P=a-c,E=o-u,H=f-u;U=F*H,A=t*F,k=A-(A-F),M=F-k,A=t*H,p=A-(A-H),x=H-p,m=M*x-(U-k*p-M*p-k*x),K=E*P,A=t*E,k=A-(A-E),M=E-k,A=t*P,p=A-(A-P),x=P-p,L=M*x-(K-k*p-M*p-k*x),S=m-L,b=m-S,e[0]=m-(S+b)+(b-L),T=U+S,b=T-U,z=U-(T-b)+(S-b),S=z-K,b=z-S,e[1]=z-(S+b)+(b-K),v=T+S,b=v-T,e[2]=T-(v-b)+(S-b),e[3]=v;let I=function(t,i){let s=i[0];for(let e=1;e=N||-I>=N)return I;if(b=s-F,d=s-(F+b)+(b-c),b=a-P,y=a-(P+b)+(b-c),b=o-E,g=o-(E+b)+(b-u),b=f-H,w=f-(H+b)+(b-u),0===d&&0===g&&0===y&&0===w)return I;if(N=11093356479670487e-47*_+33306690738754706e-32*Math.abs(I),I+=F*w+H*d-(E*y+P*g),I>=N||-I>=N)return I;U=d*H,A=t*d,k=A-(A-d),M=d-k,A=t*H,p=A-(A-H),x=H-p,m=M*x-(U-k*p-M*p-k*x),K=g*P,A=t*g,k=A-(A-g),M=g-k,A=t*P,p=A-(A-P),x=P-p,L=M*x-(K-k*p-M*p-k*x),S=m-L,b=m-S,l[0]=m-(S+b)+(b-L),T=U+S,b=T-U,z=U-(T-b)+(S-b),S=z-K,b=z-S,l[1]=z-(S+b)+(b-K),v=T+S,b=v-T,l[2]=T-(v-b)+(S-b),l[3]=v;const j=i(4,e,4,l,n);U=F*w,A=t*F,k=A-(A-F),M=F-k,A=t*w,p=A-(A-w),x=w-p,m=M*x-(U-k*p-M*p-k*x),K=E*y,A=t*E,k=A-(A-E),M=E-k,A=t*y,p=A-(A-y),x=y-p,L=M*x-(K-k*p-M*p-k*x),S=m-L,b=m-S,l[0]=m-(S+b)+(b-L),T=U+S,b=T-U,z=U-(T-b)+(S-b),S=z-K,b=z-S,l[1]=z-(S+b)+(b-K),v=T+S,b=v-T,l[2]=T-(v-b)+(S-b),l[3]=v;const q=i(j,n,4,l,h);U=d*w,A=t*d,k=A-(A-d),M=d-k,A=t*w,p=A-(A-w),x=w-p,m=M*x-(U-k*p-M*p-k*x),K=g*y,A=t*g,k=A-(A-g),M=g-k,A=t*y,p=A-(A-y),x=y-p,L=M*x-(K-k*p-M*p-k*x),S=m-L,b=m-S,l[0]=m-(S+b)+(b-L),T=U+S,b=T-U,z=U-(T-b)+(S-b),S=z-K,b=z-S,l[1]=z-(S+b)+(b-K),v=T+S,b=v-T,l[2]=T-(v-b)+(S-b),l[3]=v;const D=i(q,h,4,l,r);return r[D-1]}(s,o,a,f,c,u,y)}const a=Math.pow(2,-52),f=new Uint32Array(512);class c{static from(t,i=w,s=b){const e=t.length,n=new Float64Array(2*e);for(let h=0;h>1;if(i>0&&"number"!=typeof t[0])throw new Error("Expected coords to contain numbers.");this.coords=t;const s=Math.max(2*i-5,0);this._triangles=new Uint32Array(3*s),this._halfedges=new Int32Array(3*s),this._hashSize=Math.ceil(Math.sqrt(i)),this._hullPrev=new Uint32Array(i),this._hullNext=new Uint32Array(i),this._hullTri=new Uint32Array(i),this._hullHash=new Int32Array(this._hashSize).fill(-1),this._ids=new Uint32Array(i),this._dists=new Float64Array(i),this.update()}update(){const{coords:t,_hullPrev:i,_hullNext:s,_hullTri:e,_hullHash:n}=this,h=t.length>>1;let r=1/0,l=1/0,f=-1/0,c=-1/0;for(let i=0;if&&(f=s),e>c&&(c=e),this._ids[i]=i}const _=(r+f)/2,y=(l+c)/2;let w,b,A,k=1/0;for(let i=0;i0&&(b=i,k=s)}let x=t[2*b],S=t[2*b+1],T=1/0;for(let i=0;ie&&(i[s++]=n,e=this._dists[n])}return this.hull=i.subarray(0,s),this.triangles=new Uint32Array(0),void(this.halfedges=new Uint32Array(0))}if(o(M,p,x,S,z,U)<0){const t=b,i=x,s=S;b=A,x=z,S=U,A=t,z=i,U=s}const m=function(t,i,s,e,n,h){const r=s-t,l=e-i,o=n-t,a=h-i,f=r*r+l*l,c=o*o+a*a,u=.5/(r*a-l*o);return{x:t+(a*f-l*c)*u,y:i+(r*c-o*f)*u}}(M,p,x,S,z,U);this._cx=m.x,this._cy=m.y;for(let i=0;i0&&Math.abs(c-h)<=a&&Math.abs(u-r)<=a)continue;if(h=c,r=u,f===w||f===b||f===A)continue;let _=0;for(let t=0,i=this._hashKey(c,u);t=0;)if(g=d,g===_){g=-1;break}if(-1===g)continue;let y=this._addTriangle(g,f,s[g],-1,-1,e[g]);e[f]=this._legalize(y+2),e[g]=y,K++;let k=s[g];for(;d=s[k],o(c,u,t[2*k],t[2*k+1],t[2*d],t[2*d+1])<0;)y=this._addTriangle(k,f,d,e[f],-1,e[k]),e[f]=this._legalize(y+2),s[k]=k,K--,k=d;if(g===_)for(;d=i[g],o(c,u,t[2*d],t[2*d+1],t[2*g],t[2*g+1])<0;)y=this._addTriangle(d,f,g,-1,e[g],e[d]),this._legalize(y+2),e[d]=y,s[g]=g,K--,g=d;this._hullStart=i[f]=g,s[g]=i[k]=f,s[f]=k,n[this._hashKey(c,u)]=f,n[this._hashKey(t[2*g],t[2*g+1])]=g}this.hull=new Uint32Array(K);for(let t=0,i=this._hullStart;t0?3-s:1+s)/4}(t-this._cx,i-this._cy)*this._hashSize)%this._hashSize}_legalize(t){const{_triangles:i,_halfedges:s,coords:e}=this;let n=0,h=0;for(;;){const r=s[t],l=t-t%3;if(h=l+(t+2)%3,-1===r){if(0===n)break;t=f[--n];continue}const o=r-r%3,a=l+(t+1)%3,c=o+(r+2)%3,u=i[h],d=i[t],g=i[a],y=i[c];if(_(e[2*u],e[2*u+1],e[2*d],e[2*d+1],e[2*g],e[2*g+1],e[2*y],e[2*y+1])){i[t]=y,i[r]=u;const e=s[c];if(-1===e){let i=this._hullStart;do{if(this._hullTri[i]===c){this._hullTri[i]=t;break}i=this._hullPrev[i]}while(i!==this._hullStart)}this._link(t,e),this._link(r,s[h]),this._link(h,c);const l=o+(r+1)%3;n=s&&i[t[r]]>h;)t[r+1]=t[r--];t[r+1]=e}else{let n=s+1,h=e;y(t,s+e>>1,n),i[t[s]]>i[t[e]]&&y(t,s,e),i[t[n]]>i[t[e]]&&y(t,n,e),i[t[s]]>i[t[n]]&&y(t,s,n);const r=t[n],l=i[r];for(;;){do{n++}while(i[t[n]]l);if(h=h-s?(g(t,i,n,e),g(t,i,s,h-1)):(g(t,i,s,h-1),g(t,i,n,e))}}function y(t,i,s){const e=t[i];t[i]=t[s],t[s]=e}function w(t){return t[0]}function b(t){return t[1]}return c}));
diff --git a/libs/dropbox-sdk.min.js b/libs/dropbox-sdk.min.js
new file mode 100644
index 00000000..c5e32fc2
--- /dev/null
+++ b/libs/dropbox-sdk.min.js
@@ -0,0 +1 @@
+!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).Dropbox={})}(this,(function(e){"use strict";function t(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function r(e,t){for(var r=0;t.length>r;r++){var s=t[r];s.enumerable=s.enumerable||!1,s.configurable=!0,"value"in s&&(s.writable=!0),Object.defineProperty(e,s.key,s)}}function s(e,t,s){return t&&r(e.prototype,t),s&&r(e,s),e}function i(e){return(i=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}function n(e,t){return(n=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e})(e,t)}function u(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}function a(e,t,r){return(a=u()?Reflect.construct:function(e,t,r){var s=[null];s.push.apply(s,t);var i=new(Function.bind.apply(e,s));return r&&n(i,r.prototype),i}).apply(null,arguments)}function o(e){var t="function"==typeof Map?new Map:void 0;return(o=function(e){if(null===e||-1===Function.toString.call(e).indexOf("[native code]"))return e;if("function"!=typeof e)throw new TypeError("Super expression must either be null or a function");if(void 0!==t){if(t.has(e))return t.get(e);t.set(e,r)}function r(){return a(e,arguments,i(this).constructor)}return r.prototype=Object.create(e.prototype,{constructor:{value:r,enumerable:!1,writable:!0,configurable:!0}}),n(r,e)})(e)}function c(e,t){return!t||"object"!=typeof t&&"function"!=typeof t?function(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}(e):t}var p="app",l="user",f="team",h="dropboxapi.com",m="dropbox.com",d={api:"api",notify:"bolt",content:"api-content"},_={};function q(e){var t="000".concat(e.charCodeAt(0).toString(16)).slice(-4);return"\\u".concat(t)}_.accountSetProfilePhoto=function(e){return this.request("account/set_profile_photo",e,"user","api","rpc")},_.authTokenFromOauth1=function(e){return this.request("auth/token/from_oauth1",e,"app","api","rpc")},_.authTokenRevoke=function(){return this.request("auth/token/revoke",null,"user","api","rpc")},_.checkApp=function(e){return this.request("check/app",e,"app","api","rpc")},_.checkUser=function(e){return this.request("check/user",e,"user","api","rpc")},_.contactsDeleteManualContacts=function(){return this.request("contacts/delete_manual_contacts",null,"user","api","rpc")},_.contactsDeleteManualContactsBatch=function(e){return this.request("contacts/delete_manual_contacts_batch",e,"user","api","rpc")},_.filePropertiesPropertiesAdd=function(e){return this.request("file_properties/properties/add",e,"user","api","rpc")},_.filePropertiesPropertiesOverwrite=function(e){return this.request("file_properties/properties/overwrite",e,"user","api","rpc")},_.filePropertiesPropertiesRemove=function(e){return this.request("file_properties/properties/remove",e,"user","api","rpc")},_.filePropertiesPropertiesSearch=function(e){return this.request("file_properties/properties/search",e,"user","api","rpc")},_.filePropertiesPropertiesSearchContinue=function(e){return this.request("file_properties/properties/search/continue",e,"user","api","rpc")},_.filePropertiesPropertiesUpdate=function(e){return this.request("file_properties/properties/update",e,"user","api","rpc")},_.filePropertiesTemplatesAddForTeam=function(e){return this.request("file_properties/templates/add_for_team",e,"team","api","rpc")},_.filePropertiesTemplatesAddForUser=function(e){return this.request("file_properties/templates/add_for_user",e,"user","api","rpc")},_.filePropertiesTemplatesGetForTeam=function(e){return this.request("file_properties/templates/get_for_team",e,"team","api","rpc")},_.filePropertiesTemplatesGetForUser=function(e){return this.request("file_properties/templates/get_for_user",e,"user","api","rpc")},_.filePropertiesTemplatesListForTeam=function(){return this.request("file_properties/templates/list_for_team",null,"team","api","rpc")},_.filePropertiesTemplatesListForUser=function(){return this.request("file_properties/templates/list_for_user",null,"user","api","rpc")},_.filePropertiesTemplatesRemoveForTeam=function(e){return this.request("file_properties/templates/remove_for_team",e,"team","api","rpc")},_.filePropertiesTemplatesRemoveForUser=function(e){return this.request("file_properties/templates/remove_for_user",e,"user","api","rpc")},_.filePropertiesTemplatesUpdateForTeam=function(e){return this.request("file_properties/templates/update_for_team",e,"team","api","rpc")},_.filePropertiesTemplatesUpdateForUser=function(e){return this.request("file_properties/templates/update_for_user",e,"user","api","rpc")},_.fileRequestsCount=function(){return this.request("file_requests/count",null,"user","api","rpc")},_.fileRequestsCreate=function(e){return this.request("file_requests/create",e,"user","api","rpc")},_.fileRequestsDelete=function(e){return this.request("file_requests/delete",e,"user","api","rpc")},_.fileRequestsDeleteAllClosed=function(){return this.request("file_requests/delete_all_closed",null,"user","api","rpc")},_.fileRequestsGet=function(e){return this.request("file_requests/get",e,"user","api","rpc")},_.fileRequestsListV2=function(e){return this.request("file_requests/list_v2",e,"user","api","rpc")},_.fileRequestsList=function(){return this.request("file_requests/list",null,"user","api","rpc")},_.fileRequestsListContinue=function(e){return this.request("file_requests/list/continue",e,"user","api","rpc")},_.fileRequestsUpdate=function(e){return this.request("file_requests/update",e,"user","api","rpc")},_.filesAlphaGetMetadata=function(e){return this.request("files/alpha/get_metadata",e,"user","api","rpc")},_.filesAlphaUpload=function(e){return this.request("files/alpha/upload",e,"user","content","upload")},_.filesCopyV2=function(e){return this.request("files/copy_v2",e,"user","api","rpc")},_.filesCopy=function(e){return this.request("files/copy",e,"user","api","rpc")},_.filesCopyBatchV2=function(e){return this.request("files/copy_batch_v2",e,"user","api","rpc")},_.filesCopyBatch=function(e){return this.request("files/copy_batch",e,"user","api","rpc")},_.filesCopyBatchCheckV2=function(e){return this.request("files/copy_batch/check_v2",e,"user","api","rpc")},_.filesCopyBatchCheck=function(e){return this.request("files/copy_batch/check",e,"user","api","rpc")},_.filesCopyReferenceGet=function(e){return this.request("files/copy_reference/get",e,"user","api","rpc")},_.filesCopyReferenceSave=function(e){return this.request("files/copy_reference/save",e,"user","api","rpc")},_.filesCreateFolderV2=function(e){return this.request("files/create_folder_v2",e,"user","api","rpc")},_.filesCreateFolder=function(e){return this.request("files/create_folder",e,"user","api","rpc")},_.filesCreateFolderBatch=function(e){return this.request("files/create_folder_batch",e,"user","api","rpc")},_.filesCreateFolderBatchCheck=function(e){return this.request("files/create_folder_batch/check",e,"user","api","rpc")},_.filesDeleteV2=function(e){return this.request("files/delete_v2",e,"user","api","rpc")},_.filesDelete=function(e){return this.request("files/delete",e,"user","api","rpc")},_.filesDeleteBatch=function(e){return this.request("files/delete_batch",e,"user","api","rpc")},_.filesDeleteBatchCheck=function(e){return this.request("files/delete_batch/check",e,"user","api","rpc")},_.filesDownload=function(e){return this.request("files/download",e,"user","content","download")},_.filesDownloadZip=function(e){return this.request("files/download_zip",e,"user","content","download")},_.filesExport=function(e){return this.request("files/export",e,"user","content","download")},_.filesGetFileLockBatch=function(e){return this.request("files/get_file_lock_batch",e,"user","api","rpc")},_.filesGetMetadata=function(e){return this.request("files/get_metadata",e,"user","api","rpc")},_.filesGetPreview=function(e){return this.request("files/get_preview",e,"user","content","download")},_.filesGetTemporaryLink=function(e){return this.request("files/get_temporary_link",e,"user","api","rpc")},_.filesGetTemporaryUploadLink=function(e){return this.request("files/get_temporary_upload_link",e,"user","api","rpc")},_.filesGetThumbnail=function(e){return this.request("files/get_thumbnail",e,"user","content","download")},_.filesGetThumbnailV2=function(e){return this.request("files/get_thumbnail_v2",e,"app, user","content","download")},_.filesGetThumbnailBatch=function(e){return this.request("files/get_thumbnail_batch",e,"user","content","rpc")},_.filesListFolder=function(e){return this.request("files/list_folder",e,"user","api","rpc")},_.filesListFolderContinue=function(e){return this.request("files/list_folder/continue",e,"user","api","rpc")},_.filesListFolderGetLatestCursor=function(e){return this.request("files/list_folder/get_latest_cursor",e,"user","api","rpc")},_.filesListFolderLongpoll=function(e){return this.request("files/list_folder/longpoll",e,"noauth","notify","rpc")},_.filesListRevisions=function(e){return this.request("files/list_revisions",e,"user","api","rpc")},_.filesLockFileBatch=function(e){return this.request("files/lock_file_batch",e,"user","api","rpc")},_.filesMoveV2=function(e){return this.request("files/move_v2",e,"user","api","rpc")},_.filesMove=function(e){return this.request("files/move",e,"user","api","rpc")},_.filesMoveBatchV2=function(e){return this.request("files/move_batch_v2",e,"user","api","rpc")},_.filesMoveBatch=function(e){return this.request("files/move_batch",e,"user","api","rpc")},_.filesMoveBatchCheckV2=function(e){return this.request("files/move_batch/check_v2",e,"user","api","rpc")},_.filesMoveBatchCheck=function(e){return this.request("files/move_batch/check",e,"user","api","rpc")},_.filesPaperCreate=function(e){return this.request("files/paper/create",e,"user","api","upload")},_.filesPaperUpdate=function(e){return this.request("files/paper/update",e,"user","api","upload")},_.filesPermanentlyDelete=function(e){return this.request("files/permanently_delete",e,"user","api","rpc")},_.filesPropertiesAdd=function(e){return this.request("files/properties/add",e,"user","api","rpc")},_.filesPropertiesOverwrite=function(e){return this.request("files/properties/overwrite",e,"user","api","rpc")},_.filesPropertiesRemove=function(e){return this.request("files/properties/remove",e,"user","api","rpc")},_.filesPropertiesTemplateGet=function(e){return this.request("files/properties/template/get",e,"user","api","rpc")},_.filesPropertiesTemplateList=function(){return this.request("files/properties/template/list",null,"user","api","rpc")},_.filesPropertiesUpdate=function(e){return this.request("files/properties/update",e,"user","api","rpc")},_.filesRestore=function(e){return this.request("files/restore",e,"user","api","rpc")},_.filesSaveUrl=function(e){return this.request("files/save_url",e,"user","api","rpc")},_.filesSaveUrlCheckJobStatus=function(e){return this.request("files/save_url/check_job_status",e,"user","api","rpc")},_.filesSearch=function(e){return this.request("files/search",e,"user","api","rpc")},_.filesSearchV2=function(e){return this.request("files/search_v2",e,"user","api","rpc")},_.filesSearchContinueV2=function(e){return this.request("files/search/continue_v2",e,"user","api","rpc")},_.filesUnlockFileBatch=function(e){return this.request("files/unlock_file_batch",e,"user","api","rpc")},_.filesUpload=function(e){return this.request("files/upload",e,"user","content","upload")},_.filesUploadSessionAppendV2=function(e){return this.request("files/upload_session/append_v2",e,"user","content","upload")},_.filesUploadSessionAppend=function(e){return this.request("files/upload_session/append",e,"user","content","upload")},_.filesUploadSessionFinish=function(e){return this.request("files/upload_session/finish",e,"user","content","upload")},_.filesUploadSessionFinishBatch=function(e){return this.request("files/upload_session/finish_batch",e,"user","api","rpc")},_.filesUploadSessionFinishBatchCheck=function(e){return this.request("files/upload_session/finish_batch/check",e,"user","api","rpc")},_.filesUploadSessionStart=function(e){return this.request("files/upload_session/start",e,"user","content","upload")},_.paperDocsArchive=function(e){return this.request("paper/docs/archive",e,"user","api","rpc")},_.paperDocsCreate=function(e){return this.request("paper/docs/create",e,"user","api","upload")},_.paperDocsDownload=function(e){return this.request("paper/docs/download",e,"user","api","download")},_.paperDocsFolderUsersList=function(e){return this.request("paper/docs/folder_users/list",e,"user","api","rpc")},_.paperDocsFolderUsersListContinue=function(e){return this.request("paper/docs/folder_users/list/continue",e,"user","api","rpc")},_.paperDocsGetFolderInfo=function(e){return this.request("paper/docs/get_folder_info",e,"user","api","rpc")},_.paperDocsList=function(e){return this.request("paper/docs/list",e,"user","api","rpc")},_.paperDocsListContinue=function(e){return this.request("paper/docs/list/continue",e,"user","api","rpc")},_.paperDocsPermanentlyDelete=function(e){return this.request("paper/docs/permanently_delete",e,"user","api","rpc")},_.paperDocsSharingPolicyGet=function(e){return this.request("paper/docs/sharing_policy/get",e,"user","api","rpc")},_.paperDocsSharingPolicySet=function(e){return this.request("paper/docs/sharing_policy/set",e,"user","api","rpc")},_.paperDocsUpdate=function(e){return this.request("paper/docs/update",e,"user","api","upload")},_.paperDocsUsersAdd=function(e){return this.request("paper/docs/users/add",e,"user","api","rpc")},_.paperDocsUsersList=function(e){return this.request("paper/docs/users/list",e,"user","api","rpc")},_.paperDocsUsersListContinue=function(e){return this.request("paper/docs/users/list/continue",e,"user","api","rpc")},_.paperDocsUsersRemove=function(e){return this.request("paper/docs/users/remove",e,"user","api","rpc")},_.paperFoldersCreate=function(e){return this.request("paper/folders/create",e,"user","api","rpc")},_.sharingAddFileMember=function(e){return this.request("sharing/add_file_member",e,"user","api","rpc")},_.sharingAddFolderMember=function(e){return this.request("sharing/add_folder_member",e,"user","api","rpc")},_.sharingCheckJobStatus=function(e){return this.request("sharing/check_job_status",e,"user","api","rpc")},_.sharingCheckRemoveMemberJobStatus=function(e){return this.request("sharing/check_remove_member_job_status",e,"user","api","rpc")},_.sharingCheckShareJobStatus=function(e){return this.request("sharing/check_share_job_status",e,"user","api","rpc")},_.sharingCreateSharedLink=function(e){return this.request("sharing/create_shared_link",e,"user","api","rpc")},_.sharingCreateSharedLinkWithSettings=function(e){return this.request("sharing/create_shared_link_with_settings",e,"user","api","rpc")},_.sharingGetFileMetadata=function(e){return this.request("sharing/get_file_metadata",e,"user","api","rpc")},_.sharingGetFileMetadataBatch=function(e){return this.request("sharing/get_file_metadata/batch",e,"user","api","rpc")},_.sharingGetFolderMetadata=function(e){return this.request("sharing/get_folder_metadata",e,"user","api","rpc")},_.sharingGetSharedLinkFile=function(e){return this.request("sharing/get_shared_link_file",e,"user","content","download")},_.sharingGetSharedLinkMetadata=function(e){return this.request("sharing/get_shared_link_metadata",e,"user","api","rpc")},_.sharingGetSharedLinks=function(e){return this.request("sharing/get_shared_links",e,"user","api","rpc")},_.sharingListFileMembers=function(e){return this.request("sharing/list_file_members",e,"user","api","rpc")},_.sharingListFileMembersBatch=function(e){return this.request("sharing/list_file_members/batch",e,"user","api","rpc")},_.sharingListFileMembersContinue=function(e){return this.request("sharing/list_file_members/continue",e,"user","api","rpc")},_.sharingListFolderMembers=function(e){return this.request("sharing/list_folder_members",e,"user","api","rpc")},_.sharingListFolderMembersContinue=function(e){return this.request("sharing/list_folder_members/continue",e,"user","api","rpc")},_.sharingListFolders=function(e){return this.request("sharing/list_folders",e,"user","api","rpc")},_.sharingListFoldersContinue=function(e){return this.request("sharing/list_folders/continue",e,"user","api","rpc")},_.sharingListMountableFolders=function(e){return this.request("sharing/list_mountable_folders",e,"user","api","rpc")},_.sharingListMountableFoldersContinue=function(e){return this.request("sharing/list_mountable_folders/continue",e,"user","api","rpc")},_.sharingListReceivedFiles=function(e){return this.request("sharing/list_received_files",e,"user","api","rpc")},_.sharingListReceivedFilesContinue=function(e){return this.request("sharing/list_received_files/continue",e,"user","api","rpc")},_.sharingListSharedLinks=function(e){return this.request("sharing/list_shared_links",e,"user","api","rpc")},_.sharingModifySharedLinkSettings=function(e){return this.request("sharing/modify_shared_link_settings",e,"user","api","rpc")},_.sharingMountFolder=function(e){return this.request("sharing/mount_folder",e,"user","api","rpc")},_.sharingRelinquishFileMembership=function(e){return this.request("sharing/relinquish_file_membership",e,"user","api","rpc")},_.sharingRelinquishFolderMembership=function(e){return this.request("sharing/relinquish_folder_membership",e,"user","api","rpc")},_.sharingRemoveFileMember=function(e){return this.request("sharing/remove_file_member",e,"user","api","rpc")},_.sharingRemoveFileMember2=function(e){return this.request("sharing/remove_file_member_2",e,"user","api","rpc")},_.sharingRemoveFolderMember=function(e){return this.request("sharing/remove_folder_member",e,"user","api","rpc")},_.sharingRevokeSharedLink=function(e){return this.request("sharing/revoke_shared_link",e,"user","api","rpc")},_.sharingSetAccessInheritance=function(e){return this.request("sharing/set_access_inheritance",e,"user","api","rpc")},_.sharingShareFolder=function(e){return this.request("sharing/share_folder",e,"user","api","rpc")},_.sharingTransferFolder=function(e){return this.request("sharing/transfer_folder",e,"user","api","rpc")},_.sharingUnmountFolder=function(e){return this.request("sharing/unmount_folder",e,"user","api","rpc")},_.sharingUnshareFile=function(e){return this.request("sharing/unshare_file",e,"user","api","rpc")},_.sharingUnshareFolder=function(e){return this.request("sharing/unshare_folder",e,"user","api","rpc")},_.sharingUpdateFileMember=function(e){return this.request("sharing/update_file_member",e,"user","api","rpc")},_.sharingUpdateFolderMember=function(e){return this.request("sharing/update_folder_member",e,"user","api","rpc")},_.sharingUpdateFolderPolicy=function(e){return this.request("sharing/update_folder_policy",e,"user","api","rpc")},_.teamDevicesListMemberDevices=function(e){return this.request("team/devices/list_member_devices",e,"team","api","rpc")},_.teamDevicesListMembersDevices=function(e){return this.request("team/devices/list_members_devices",e,"team","api","rpc")},_.teamDevicesListTeamDevices=function(e){return this.request("team/devices/list_team_devices",e,"team","api","rpc")},_.teamDevicesRevokeDeviceSession=function(e){return this.request("team/devices/revoke_device_session",e,"team","api","rpc")},_.teamDevicesRevokeDeviceSessionBatch=function(e){return this.request("team/devices/revoke_device_session_batch",e,"team","api","rpc")},_.teamFeaturesGetValues=function(e){return this.request("team/features/get_values",e,"team","api","rpc")},_.teamGetInfo=function(){return this.request("team/get_info",null,"team","api","rpc")},_.teamGroupsCreate=function(e){return this.request("team/groups/create",e,"team","api","rpc")},_.teamGroupsDelete=function(e){return this.request("team/groups/delete",e,"team","api","rpc")},_.teamGroupsGetInfo=function(e){return this.request("team/groups/get_info",e,"team","api","rpc")},_.teamGroupsJobStatusGet=function(e){return this.request("team/groups/job_status/get",e,"team","api","rpc")},_.teamGroupsList=function(e){return this.request("team/groups/list",e,"team","api","rpc")},_.teamGroupsListContinue=function(e){return this.request("team/groups/list/continue",e,"team","api","rpc")},_.teamGroupsMembersAdd=function(e){return this.request("team/groups/members/add",e,"team","api","rpc")},_.teamGroupsMembersList=function(e){return this.request("team/groups/members/list",e,"team","api","rpc")},_.teamGroupsMembersListContinue=function(e){return this.request("team/groups/members/list/continue",e,"team","api","rpc")},_.teamGroupsMembersRemove=function(e){return this.request("team/groups/members/remove",e,"team","api","rpc")},_.teamGroupsMembersSetAccessType=function(e){return this.request("team/groups/members/set_access_type",e,"team","api","rpc")},_.teamGroupsUpdate=function(e){return this.request("team/groups/update",e,"team","api","rpc")},_.teamLegalHoldsCreatePolicy=function(e){return this.request("team/legal_holds/create_policy",e,"team","api","rpc")},_.teamLegalHoldsGetPolicy=function(e){return this.request("team/legal_holds/get_policy",e,"team","api","rpc")},_.teamLegalHoldsListHeldRevisions=function(e){return this.request("team/legal_holds/list_held_revisions",e,"team","api","rpc")},_.teamLegalHoldsListHeldRevisionsContinue=function(e){return this.request("team/legal_holds/list_held_revisions_continue",e,"team","api","rpc")},_.teamLegalHoldsListPolicies=function(e){return this.request("team/legal_holds/list_policies",e,"team","api","rpc")},_.teamLegalHoldsReleasePolicy=function(e){return this.request("team/legal_holds/release_policy",e,"team","api","rpc")},_.teamLegalHoldsUpdatePolicy=function(e){return this.request("team/legal_holds/update_policy",e,"team","api","rpc")},_.teamLinkedAppsListMemberLinkedApps=function(e){return this.request("team/linked_apps/list_member_linked_apps",e,"team","api","rpc")},_.teamLinkedAppsListMembersLinkedApps=function(e){return this.request("team/linked_apps/list_members_linked_apps",e,"team","api","rpc")},_.teamLinkedAppsListTeamLinkedApps=function(e){return this.request("team/linked_apps/list_team_linked_apps",e,"team","api","rpc")},_.teamLinkedAppsRevokeLinkedApp=function(e){return this.request("team/linked_apps/revoke_linked_app",e,"team","api","rpc")},_.teamLinkedAppsRevokeLinkedAppBatch=function(e){return this.request("team/linked_apps/revoke_linked_app_batch",e,"team","api","rpc")},_.teamMemberSpaceLimitsExcludedUsersAdd=function(e){return this.request("team/member_space_limits/excluded_users/add",e,"team","api","rpc")},_.teamMemberSpaceLimitsExcludedUsersList=function(e){return this.request("team/member_space_limits/excluded_users/list",e,"team","api","rpc")},_.teamMemberSpaceLimitsExcludedUsersListContinue=function(e){return this.request("team/member_space_limits/excluded_users/list/continue",e,"team","api","rpc")},_.teamMemberSpaceLimitsExcludedUsersRemove=function(e){return this.request("team/member_space_limits/excluded_users/remove",e,"team","api","rpc")},_.teamMemberSpaceLimitsGetCustomQuota=function(e){return this.request("team/member_space_limits/get_custom_quota",e,"team","api","rpc")},_.teamMemberSpaceLimitsRemoveCustomQuota=function(e){return this.request("team/member_space_limits/remove_custom_quota",e,"team","api","rpc")},_.teamMemberSpaceLimitsSetCustomQuota=function(e){return this.request("team/member_space_limits/set_custom_quota",e,"team","api","rpc")},_.teamMembersAddV2=function(e){return this.request("team/members/add_v2",e,"team","api","rpc")},_.teamMembersAdd=function(e){return this.request("team/members/add",e,"team","api","rpc")},_.teamMembersAddJobStatusGetV2=function(e){return this.request("team/members/add/job_status/get_v2",e,"team","api","rpc")},_.teamMembersAddJobStatusGet=function(e){return this.request("team/members/add/job_status/get",e,"team","api","rpc")},_.teamMembersDeleteProfilePhotoV2=function(e){return this.request("team/members/delete_profile_photo_v2",e,"team","api","rpc")},_.teamMembersDeleteProfilePhoto=function(e){return this.request("team/members/delete_profile_photo",e,"team","api","rpc")},_.teamMembersGetAvailableTeamMemberRoles=function(){return this.request("team/members/get_available_team_member_roles",null,"team","api","rpc")},_.teamMembersGetInfoV2=function(e){return this.request("team/members/get_info_v2",e,"team","api","rpc")},_.teamMembersGetInfo=function(e){return this.request("team/members/get_info",e,"team","api","rpc")},_.teamMembersListV2=function(e){return this.request("team/members/list_v2",e,"team","api","rpc")},_.teamMembersList=function(e){return this.request("team/members/list",e,"team","api","rpc")},_.teamMembersListContinueV2=function(e){return this.request("team/members/list/continue_v2",e,"team","api","rpc")},_.teamMembersListContinue=function(e){return this.request("team/members/list/continue",e,"team","api","rpc")},_.teamMembersMoveFormerMemberFiles=function(e){return this.request("team/members/move_former_member_files",e,"team","api","rpc")},_.teamMembersMoveFormerMemberFilesJobStatusCheck=function(e){return this.request("team/members/move_former_member_files/job_status/check",e,"team","api","rpc")},_.teamMembersRecover=function(e){return this.request("team/members/recover",e,"team","api","rpc")},_.teamMembersRemove=function(e){return this.request("team/members/remove",e,"team","api","rpc")},_.teamMembersRemoveJobStatusGet=function(e){return this.request("team/members/remove/job_status/get",e,"team","api","rpc")},_.teamMembersSecondaryEmailsAdd=function(e){return this.request("team/members/secondary_emails/add",e,"team","api","rpc")},_.teamMembersSecondaryEmailsDelete=function(e){return this.request("team/members/secondary_emails/delete",e,"team","api","rpc")},_.teamMembersSecondaryEmailsResendVerificationEmails=function(e){return this.request("team/members/secondary_emails/resend_verification_emails",e,"team","api","rpc")},_.teamMembersSendWelcomeEmail=function(e){return this.request("team/members/send_welcome_email",e,"team","api","rpc")},_.teamMembersSetAdminPermissionsV2=function(e){return this.request("team/members/set_admin_permissions_v2",e,"team","api","rpc")},_.teamMembersSetAdminPermissions=function(e){return this.request("team/members/set_admin_permissions",e,"team","api","rpc")},_.teamMembersSetProfileV2=function(e){return this.request("team/members/set_profile_v2",e,"team","api","rpc")},_.teamMembersSetProfile=function(e){return this.request("team/members/set_profile",e,"team","api","rpc")},_.teamMembersSetProfilePhotoV2=function(e){return this.request("team/members/set_profile_photo_v2",e,"team","api","rpc")},_.teamMembersSetProfilePhoto=function(e){return this.request("team/members/set_profile_photo",e,"team","api","rpc")},_.teamMembersSuspend=function(e){return this.request("team/members/suspend",e,"team","api","rpc")},_.teamMembersUnsuspend=function(e){return this.request("team/members/unsuspend",e,"team","api","rpc")},_.teamNamespacesList=function(e){return this.request("team/namespaces/list",e,"team","api","rpc")},_.teamNamespacesListContinue=function(e){return this.request("team/namespaces/list/continue",e,"team","api","rpc")},_.teamPropertiesTemplateAdd=function(e){return this.request("team/properties/template/add",e,"team","api","rpc")},_.teamPropertiesTemplateGet=function(e){return this.request("team/properties/template/get",e,"team","api","rpc")},_.teamPropertiesTemplateList=function(){return this.request("team/properties/template/list",null,"team","api","rpc")},_.teamPropertiesTemplateUpdate=function(e){return this.request("team/properties/template/update",e,"team","api","rpc")},_.teamReportsGetActivity=function(e){return this.request("team/reports/get_activity",e,"team","api","rpc")},_.teamReportsGetDevices=function(e){return this.request("team/reports/get_devices",e,"team","api","rpc")},_.teamReportsGetMembership=function(e){return this.request("team/reports/get_membership",e,"team","api","rpc")},_.teamReportsGetStorage=function(e){return this.request("team/reports/get_storage",e,"team","api","rpc")},_.teamTeamFolderActivate=function(e){return this.request("team/team_folder/activate",e,"team","api","rpc")},_.teamTeamFolderArchive=function(e){return this.request("team/team_folder/archive",e,"team","api","rpc")},_.teamTeamFolderArchiveCheck=function(e){return this.request("team/team_folder/archive/check",e,"team","api","rpc")},_.teamTeamFolderCreate=function(e){return this.request("team/team_folder/create",e,"team","api","rpc")},_.teamTeamFolderGetInfo=function(e){return this.request("team/team_folder/get_info",e,"team","api","rpc")},_.teamTeamFolderList=function(e){return this.request("team/team_folder/list",e,"team","api","rpc")},_.teamTeamFolderListContinue=function(e){return this.request("team/team_folder/list/continue",e,"team","api","rpc")},_.teamTeamFolderPermanentlyDelete=function(e){return this.request("team/team_folder/permanently_delete",e,"team","api","rpc")},_.teamTeamFolderRename=function(e){return this.request("team/team_folder/rename",e,"team","api","rpc")},_.teamTeamFolderUpdateSyncSettings=function(e){return this.request("team/team_folder/update_sync_settings",e,"team","api","rpc")},_.teamTokenGetAuthenticatedAdmin=function(){return this.request("team/token/get_authenticated_admin",null,"team","api","rpc")},_.teamLogGetEvents=function(e){return this.request("team_log/get_events",e,"team","api","rpc")},_.teamLogGetEventsContinue=function(e){return this.request("team_log/get_events/continue",e,"team","api","rpc")},_.usersFeaturesGetValues=function(e){return this.request("users/features/get_values",e,"user","api","rpc")},_.usersGetAccount=function(e){return this.request("users/get_account",e,"user","api","rpc")},_.usersGetAccountBatch=function(e){return this.request("users/get_account_batch",e,"user","api","rpc")},_.usersGetCurrentAccount=function(){return this.request("users/get_current_account",null,"user","api","rpc")},_.usersGetSpaceUsage=function(){return this.request("users/get_space_usage",null,"user","api","rpc")};var g=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:h,r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:".";return t!==h&&void 0!==d[e]&&(e=d[e],r="-"),"https://".concat(e).concat(r).concat(t,"/2/")},b=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:m;return e!==m&&(e="meta-".concat(e)),"https://".concat(e,"/oauth2/authorize")},v=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:h,t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:".",r="api";return e!==h&&(r=d[r],t="-"),"https://".concat(r).concat(t).concat(e,"/oauth2/token")};function k(e){return JSON.stringify(e).replace(/[\u007f-\uffff]/g,q)}function y(e){return new Date(Date.now()+1e3*e)}function A(){return"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope||"undefined"==typeof module||"undefined"!=typeof window}function C(){return"undefined"!=typeof window}function S(e){return e.toString("base64").replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"")}var T,L,w,M=function(e){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&n(e,t)}(o,e);var r,s,a=(r=o,s=u(),function(){var e,t=i(r);if(s){var n=i(this).constructor;e=Reflect.construct(t,arguments,n)}else e=t.apply(this,arguments);return c(this,e)});function o(e,r,s){var i;return t(this,o),(i=a.call(this,"Response failed with a ".concat(e," code"))).name="DropboxResponseError",i.status=e,i.headers=r,i.error=s,i}return o}(o(Error)),P=function e(r,s,i){t(this,e),this.status=r,this.headers=s,this.result=i};function R(e){return e.text().then((function(t){var r;try{r=JSON.parse(t)}catch(e){r=t}throw new M(e.status,e.headers,r)}))}function F(e){return e.ok?e.text().then((function(t){var r;try{r=JSON.parse(t)}catch(e){r=t}return new P(e.status,e.headers,r)})):R(e)}T=C()?window.fetch.bind(window):require("node-fetch"),L=C()?window.crypto||window.msCrypto:require("crypto"),w="undefined"==typeof TextEncoder?require("util").TextEncoder:TextEncoder;var D,G=["legacy","offline","online"],U=["code","token"],x=["none","user","team"],E=function(){function e(r){t(this,e),this.fetch=(r=r||{}).fetch||T,this.accessToken=r.accessToken,this.accessTokenExpiresAt=r.accessTokenExpiresAt,this.refreshToken=r.refreshToken,this.clientId=r.clientId,this.clientSecret=r.clientSecret,this.domain=r.domain,this.domainDelimiter=r.domainDelimiter}return s(e,[{key:"setAccessToken",value:function(e){this.accessToken=e}},{key:"getAccessToken",value:function(){return this.accessToken}},{key:"setClientId",value:function(e){this.clientId=e}},{key:"getClientId",value:function(){return this.clientId}},{key:"setClientSecret",value:function(e){this.clientSecret=e}},{key:"getClientSecret",value:function(){return this.clientSecret}},{key:"getRefreshToken",value:function(){return this.refreshToken}},{key:"setRefreshToken",value:function(e){this.refreshToken=e}},{key:"getAccessTokenExpiresAt",value:function(){return this.accessTokenExpiresAt}},{key:"setAccessTokenExpiresAt",value:function(e){this.accessTokenExpiresAt=e}},{key:"setCodeVerifier",value:function(e){this.codeVerifier=e}},{key:"getCodeVerifier",value:function(){return this.codeVerifier}},{key:"generateCodeChallenge",value:function(){var e,t=this,r=(new w).encode(this.codeVerifier);if(C())return L.subtle.digest("SHA-256",r).then((function(r){var s=btoa(String.fromCharCode.apply(null,new Uint8Array(r)));e=S(s).substr(0,128),t.codeChallenge=e}));var s=L.createHash("sha256").update(r).digest();return e=S(s),this.codeChallenge=e,Promise.resolve()}},{key:"generatePKCECodes",value:function(){var e;if(C()){var t=new Uint8Array(128),r=L.getRandomValues(t);e=S(btoa(r)).substr(0,128)}else{e=S(L.randomBytes(128)).substr(0,128)}return this.codeVerifier=e,this.generateCodeChallenge()}},{key:"getAuthenticationUrl",value:function(e,t){var r,s=this,i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"token",n=arguments.length>3&&void 0!==arguments[3]?arguments[3]:null,u=arguments.length>4&&void 0!==arguments[4]?arguments[4]:null,a=arguments.length>5&&void 0!==arguments[5]?arguments[5]:"none",o=arguments.length>6&&void 0!==arguments[6]&&arguments[6],c=this.getClientId(),p=b(this.domain);if(!c)throw Error("A client id is required. You can set the client id using .setClientId().");if("code"!==i&&!e)throw Error("A redirect uri is required.");if(!U.includes(i))throw Error("Authorization type must be code or token");if(n&&!G.includes(n))throw Error("Token Access Type must be legacy, offline, or online");if(u&&!(u instanceof Array))throw Error("Scope must be an array of strings");if(!x.includes(a))throw Error("includeGrantedScopes must be none, user, or team");return r="code"===i?"".concat(p,"?response_type=code&client_id=").concat(c):"".concat(p,"?response_type=token&client_id=").concat(c),e&&(r+="&redirect_uri=".concat(e)),t&&(r+="&state=".concat(t)),n&&(r+="&token_access_type=".concat(n)),u&&(r+="&scope=".concat(u.join(" "))),"none"!==a&&(r+="&include_granted_scopes=".concat(a)),o?this.generatePKCECodes().then((function(){return r+="&code_challenge_method=S256",r+="&code_challenge=".concat(s.codeChallenge)})):Promise.resolve(r)}},{key:"getAccessTokenFromCode",value:function(e,t){var r=this.getClientId(),s=this.getClientSecret();if(!r)throw Error("A client id is required. You can set the client id using .setClientId().");var i=v(this.domain,this.domainDelimiter);if(i+="?grant_type=authorization_code",i+="&code=".concat(t),i+="&client_id=".concat(r),s)i+="&client_secret=".concat(s);else{if(!this.codeVerifier)throw Error("You must use PKCE when generating the authorization URL to not include a client secret");i+="&code_verifier=".concat(this.codeVerifier)}e&&(i+="&redirect_uri=".concat(e));return this.fetch(i,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"}}).then((function(e){return F(e)}))}},{key:"checkAndRefreshAccessToken",value:function(){var e=this.getRefreshToken()&&this.getClientId(),t=!this.getAccessTokenExpiresAt()||new Date(Date.now()+3e5)>=this.getAccessTokenExpiresAt(),r=!this.getAccessToken();return(t||r)&&e?this.refreshAccessToken():Promise.resolve()}},{key:"refreshAccessToken",value:function(){var e=this,t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,r=v(this.domain,this.domainDelimiter),s=this.getClientId(),i=this.getClientSecret();if(!s)throw Error("A client id is required. You can set the client id using .setClientId().");if(t&&!(t instanceof Array))throw Error("Scope must be an array of strings");var n={"Content-Type":"application/json"};r+="?grant_type=refresh_token&refresh_token=".concat(this.getRefreshToken()),r+="&client_id=".concat(s),i&&(r+="&client_secret=".concat(i)),t&&(r+="&scope=".concat(t.join(" ")));var u={method:"POST"};return u.headers=n,this.fetch(r,u).then((function(e){return F(e)})).then((function(t){e.setAccessToken(t.result.access_token),e.setAccessTokenExpiresAt(y(t.result.expires_in))}))}}]),e}();D="undefined"!=typeof window?window.fetch.bind(window):require("node-fetch");var V="undefined"==typeof btoa?function(e){return Buffer.from(e).toString("base64")}:btoa;e.Dropbox=function(){function e(r){t(this,e),this.auth=(r=r||{}).auth?r.auth:new E(r),this.fetch=r.fetch||D,this.selectUser=r.selectUser,this.selectAdmin=r.selectAdmin,this.pathRoot=r.pathRoot,this.domain=r.domain,this.domainDelimiter=r.domainDelimiter,Object.assign(this,_)}return s(e,[{key:"request",value:function(e,t,r,s,i){if(r.split(",").length>1){var n=r.replace(" ","").split(",");n.includes(l)&&this.auth.getAccessToken()?r=l:n.includes(f)&&this.auth.getAccessToken()?r=f:n.includes(p)&&(r=p)}switch(i){case"rpc":return this.rpcRequest(e,t,r,s);case"download":return this.downloadRequest(e,t,r,s);case"upload":return this.uploadRequest(e,t,r,s);default:throw Error("Invalid request style: ".concat(i))}}},{key:"rpcRequest",value:function(e,t,r,s){var i=this;return this.auth.checkAndRefreshAccessToken().then((function(){var e,s={method:"POST",body:t?JSON.stringify(t):null,headers:{}};switch(t&&(s.headers["Content-Type"]="application/json"),r){case p:if(!i.auth.clientId||!i.auth.clientSecret)throw Error("A client id and secret is required for this function");e=V("".concat(i.auth.clientId,":").concat(i.auth.clientSecret)),s.headers.Authorization="Basic ".concat(e);break;case f:case l:s.headers.Authorization="Bearer ".concat(i.auth.getAccessToken());break;case"noauth":break;default:throw Error("Unhandled auth type: ".concat(r))}return i.setCommonHeaders(s),s})).then((function(t){return i.fetch(g(s,i.domain,i.domainDelimiter)+e,t)})).then((function(e){return F(e)}))}},{key:"downloadRequest",value:function(e,t,r,s){var i=this;return this.auth.checkAndRefreshAccessToken().then((function(){if(r!==l)throw Error("Unexpected auth type: ".concat(r));var e={method:"POST",headers:{Authorization:"Bearer ".concat(i.auth.getAccessToken()),"Dropbox-API-Arg":k(t)}};return i.setCommonHeaders(e),e})).then((function(t){return i.fetch(g(s,i.domain,i.domainDelimiter)+e,t)})).then((function(e){return function(e){return e.ok?new Promise((function(t){A()?e.blob().then((function(e){return t(e)})):e.buffer().then((function(e){return t(e)}))})).then((function(t){var r=JSON.parse(e.headers.get("dropbox-api-result"));return A()?r.fileBlob=t:r.fileBinary=t,new P(e.status,e.headers,r)})):R(e)}(e)}))}},{key:"uploadRequest",value:function(e,t,r,s){var i=this;return this.auth.checkAndRefreshAccessToken().then((function(){if(r!==l)throw Error("Unexpected auth type: ".concat(r));var e=t.contents;delete t.contents;var s={body:e,method:"POST",headers:{Authorization:"Bearer ".concat(i.auth.getAccessToken()),"Content-Type":"application/octet-stream","Dropbox-API-Arg":k(t)}};return i.setCommonHeaders(s),s})).then((function(t){return i.fetch(g(s,i.domain,i.domainDelimiter)+e,t)})).then((function(e){return F(e)}))}},{key:"setCommonHeaders",value:function(e){this.selectUser&&(e.headers["Dropbox-API-Select-User"]=this.selectUser),this.selectAdmin&&(e.headers["Dropbox-API-Select-Admin"]=this.selectAdmin),this.pathRoot&&(e.headers["Dropbox-API-Path-Root"]=this.pathRoot)}}]),e}(),e.DropboxAuth=E,e.DropboxResponse=P,e.DropboxResponseError=M,Object.defineProperty(e,"__esModule",{value:!0})}));
diff --git a/libs/flatqueue.js b/libs/flatqueue.js
new file mode 100644
index 00000000..271aaf32
--- /dev/null
+++ b/libs/flatqueue.js
@@ -0,0 +1,57 @@
+!(function (t, s) {
+ "object" == typeof exports && "undefined" != typeof module
+ ? (module.exports = s())
+ : "function" == typeof define && define.amd
+ ? define(s)
+ : ((t = "undefined" != typeof globalThis ? globalThis : t || self).FlatQueue = s());
+})(this, function () {
+ "use strict";
+ return class {
+ constructor() {
+ (this.ids = []), (this.values = []), (this.length = 0);
+ }
+ clear() {
+ this.length = 0;
+ }
+ push(t, s) {
+ let i = this.length++;
+ for (; i > 0; ) {
+ const t = (i - 1) >> 1,
+ e = this.values[t];
+ if (s >= e) break;
+ (this.ids[i] = this.ids[t]), (this.values[i] = e), (i = t);
+ }
+ (this.ids[i] = t), (this.values[i] = s);
+ }
+ pop() {
+ if (0 === this.length) return;
+ const t = this.ids[0];
+ if ((this.length--, this.length > 0)) {
+ const t = (this.ids[0] = this.ids[this.length]),
+ s = (this.values[0] = this.values[this.length]),
+ i = this.length >> 1;
+ let e = 0;
+ for (; e < i; ) {
+ let t = 1 + (e << 1);
+ const i = t + 1;
+ let h = this.ids[t],
+ l = this.values[t];
+ const n = this.values[i];
+ if ((i < this.length && n < l && ((t = i), (h = this.ids[i]), (l = n)), l >= s)) break;
+ (this.ids[e] = h), (this.values[e] = l), (e = t);
+ }
+ (this.ids[e] = t), (this.values[e] = s);
+ }
+ return t;
+ }
+ peek() {
+ if (0 !== this.length) return this.ids[0];
+ }
+ peekValue() {
+ if (0 !== this.length) return this.values[0];
+ }
+ shrink() {
+ this.ids.length = this.values.length = this.length;
+ }
+ };
+});
diff --git a/libs/indexedDB.js b/libs/indexedDB.js
new file mode 100644
index 00000000..37e89c13
--- /dev/null
+++ b/libs/indexedDB.js
@@ -0,0 +1,65 @@
+let db;
+
+const DATABASE_NAME = "d2";
+const STORE_NAME = "s";
+
+const openDatabase = () => {
+ return new Promise((resolve, reject) => {
+ if (db) resolve();
+
+ if (!window.indexedDB) return reject("IndexedDB is not supported");
+ const request = window.indexedDB.open(DATABASE_NAME);
+
+ request.onsuccess = event => {
+ db = event.target.result;
+ resolve();
+ };
+
+ request.onerror = event => {
+ console.error("IndexedDB request error");
+ reject();
+ };
+
+ request.onupgradeneeded = event => {
+ db = event.target.result;
+ const objectStore = db.createObjectStore(STORE_NAME, {keyPath: "key"});
+ objectStore.transaction.oncomplete = () => {
+ db = event.target.result;
+ };
+ };
+ });
+};
+
+const ldb = {
+ get: key => {
+ return new Promise((resolve, reject) => {
+ openDatabase().then(() => {
+ const hasStore = Array.from(db.objectStoreNames).includes(STORE_NAME);
+ if (!hasStore) return reject("IndexedDB: no store found");
+
+ const transaction = db.transaction(STORE_NAME, "readonly");
+ const objectStore = transaction.objectStore(STORE_NAME);
+ const getRequest = objectStore.get(key);
+
+ getRequest.onsuccess = event => {
+ const result = event.target.result?.value || null;
+ resolve(result);
+ };
+ });
+ });
+ },
+
+ set: (keyName, value) => {
+ return new Promise(resolve => {
+ openDatabase().then(() => {
+ const transaction = db.transaction(STORE_NAME, "readwrite");
+ const objectStore = transaction.objectStore([STORE_NAME]);
+ const putRequest = objectStore.put({key: keyName, value});
+
+ putRequest.onsuccess = () => {
+ resolve();
+ };
+ });
+ });
+ }
+};
diff --git a/libs/jquery-ui.css b/libs/jquery-ui.css
index 927bfc9b..ad11d1a6 100644
--- a/libs/jquery-ui.css
+++ b/libs/jquery-ui.css
@@ -3,81 +3,79 @@
* Copyright jQuery Foundation and other contributors; Licensed MIT */
.ui-draggable-handle {
- -ms-touch-action: none;
- touch-action: none;
+ -ms-touch-action: none;
+ touch-action: none;
}
.ui-helper-hidden {
- display: none;
+ display: none;
}
.ui-helper-hidden-accessible {
- border: 0;
- clip: rect(0 0 0 0);
- height: 1px;
- margin: -1px;
- overflow: hidden;
- padding: 0;
- position: absolute;
- width: 1px;
+ border: 0;
+ clip: rect(0 0 0 0);
+ height: 1px;
+ margin: -1px;
+ overflow: hidden;
+ padding: 0;
+ position: absolute;
+ width: 1px;
}
.ui-helper-reset {
- margin: 0;
- padding: 0;
- border: 0;
- outline: 0;
- line-height: 1.3;
- text-decoration: none;
- font-size: 100%;
- list-style: none;
+ margin: 0;
+ padding: 0;
+ border: 0;
+ outline: 0;
+ line-height: 1.3;
+ text-decoration: none;
+ font-size: 100%;
+ list-style: none;
}
.ui-helper-clearfix:before,
.ui-helper-clearfix:after {
- content: "";
- display: table;
- border-collapse: collapse;
+ content: "";
+ display: table;
+ border-collapse: collapse;
}
.ui-helper-clearfix:after {
- clear: both;
+ clear: both;
}
.ui-helper-zfix {
- width: 100%;
- height: 100%;
- top: 0;
- left: 0;
- position: absolute;
- opacity: 0;
- filter:Alpha(Opacity=0); /* support: IE8 */
+ width: 100%;
+ height: 100%;
+ top: 0;
+ left: 0;
+ position: absolute;
+ opacity: 0;
+ filter: Alpha(Opacity=0); /* support: IE8 */
}
.ui-front {
- z-index: 100;
+ z-index: 100;
}
-
/* Interaction Cues
----------------------------------*/
.ui-state-disabled {
- cursor: default !important;
- pointer-events: none;
+ cursor: default !important;
+ pointer-events: none;
}
-
/* Icons
----------------------------------*/
.ui-icon {
- display: inline-block;
- vertical-align: middle;
- margin-top: -.25em;
- position: relative;
- text-indent: -99999px;
- overflow: hidden;
- background-repeat: no-repeat;
+ display: inline-block;
+ vertical-align: middle;
+ margin-top: -0.25em;
+ position: relative;
+ text-indent: -99999px;
+ overflow: hidden;
+ background-repeat: no-repeat;
}
.ui-widget-icon-block {
- left: 50%;
- margin-left: -8px;
- display: block;
+ left: 50%;
+ margin-left: -8px;
+ display: block;
}
/* Misc visuals
@@ -85,102 +83,102 @@
/* Overlays */
.ui-widget-overlay {
- position: fixed;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
}
.ui-resizable {
- position: relative;
+ position: relative;
}
.ui-resizable-handle {
- position: absolute;
- font-size: 0.1px;
- display: block;
- -ms-touch-action: none;
- touch-action: none;
+ position: absolute;
+ font-size: 0.1px;
+ display: block;
+ -ms-touch-action: none;
+ touch-action: none;
}
.ui-resizable-disabled .ui-resizable-handle,
.ui-resizable-autohide .ui-resizable-handle {
- display: none;
+ display: none;
}
.ui-resizable-n {
- cursor: n-resize;
- height: 7px;
- width: 100%;
- top: -5px;
- left: 0;
+ cursor: n-resize;
+ height: 7px;
+ width: 100%;
+ top: -5px;
+ left: 0;
}
.ui-resizable-s {
- cursor: s-resize;
- height: 7px;
- width: 100%;
- bottom: -5px;
- left: 0;
+ cursor: s-resize;
+ height: 7px;
+ width: 100%;
+ bottom: -5px;
+ left: 0;
}
.ui-resizable-e {
- cursor: e-resize;
- width: 7px;
- right: -5px;
- top: 0;
- height: 100%;
+ cursor: e-resize;
+ width: 7px;
+ right: -5px;
+ top: 0;
+ height: 100%;
}
.ui-resizable-w {
- cursor: w-resize;
- width: 7px;
- left: -5px;
- top: 0;
- height: 100%;
+ cursor: w-resize;
+ width: 7px;
+ left: -5px;
+ top: 0;
+ height: 100%;
}
.ui-resizable-se {
- cursor: se-resize;
- width: 12px;
- height: 12px;
- right: 1px;
- bottom: 1px;
+ cursor: se-resize;
+ width: 12px;
+ height: 12px;
+ right: 1px;
+ bottom: 1px;
}
.ui-resizable-sw {
- cursor: sw-resize;
- width: 9px;
- height: 9px;
- left: -5px;
- bottom: -5px;
+ cursor: sw-resize;
+ width: 9px;
+ height: 9px;
+ left: -5px;
+ bottom: -5px;
}
.ui-resizable-nw {
- cursor: nw-resize;
- width: 9px;
- height: 9px;
- left: -5px;
- top: -5px;
+ cursor: nw-resize;
+ width: 9px;
+ height: 9px;
+ left: -5px;
+ top: -5px;
}
.ui-resizable-ne {
- cursor: ne-resize;
- width: 9px;
- height: 9px;
- right: -5px;
- top: -5px;
+ cursor: ne-resize;
+ width: 9px;
+ height: 9px;
+ right: -5px;
+ top: -5px;
}
.ui-sortable-handle {
- -ms-touch-action: none;
- touch-action: none;
+ -ms-touch-action: none;
+ touch-action: none;
}
.ui-button {
- padding: .4em 1em;
- display: inline-block;
- position: relative;
- line-height: normal;
- margin-right: .1em;
- cursor: pointer;
- vertical-align: middle;
- text-align: center;
- -webkit-user-select: none;
- -moz-user-select: none;
- -ms-user-select: none;
- user-select: none;
+ padding: 0.4em 1em;
+ display: inline-block;
+ position: relative;
+ line-height: normal;
+ margin-right: 0.1em;
+ cursor: pointer;
+ vertical-align: middle;
+ text-align: center;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
- /* Support: IE <= 11 */
- overflow: visible;
+ /* Support: IE <= 11 */
+ overflow: visible;
}
.ui-button,
@@ -188,128 +186,126 @@
.ui-button:visited,
.ui-button:hover,
.ui-button:active {
- text-decoration: none;
+ text-decoration: none;
}
/* to make room for the icon, a width needs to be set here */
.ui-button-icon-only {
- width: 2em;
- box-sizing: border-box;
- white-space: nowrap;
+ width: 2em;
+ box-sizing: border-box;
+ white-space: nowrap;
}
/* button icon element(s) */
.ui-button-icon-only .ui-icon {
- position: absolute;
- top: 50%;
- left: 50%;
- margin-top: -8px;
- margin-left: -8px;
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ margin-top: -8px;
+ margin-left: -8px;
}
.ui-button.ui-icon-notext .ui-icon {
- padding: 0;
- width: 2.1em;
- height: 2.1em;
- text-indent: -9999px;
- white-space: nowrap;
-
+ padding: 0;
+ width: 2.1em;
+ height: 2.1em;
+ text-indent: -9999px;
+ white-space: nowrap;
}
input.ui-button.ui-icon-notext .ui-icon {
- width: auto;
- height: auto;
- text-indent: 0;
- white-space: normal;
- padding: .4em 1em;
+ width: auto;
+ height: auto;
+ text-indent: 0;
+ white-space: normal;
+ padding: 0.4em 1em;
}
/* workarounds */
/* Support: Firefox 5 - 40 */
input.ui-button::-moz-focus-inner,
button.ui-button::-moz-focus-inner {
- border: 0;
- padding: 0;
+ border: 0;
+ padding: 0;
}
.ui-controlgroup {
- vertical-align: middle;
- display: inline-block;
+ vertical-align: middle;
+ display: inline-block;
}
.ui-controlgroup > .ui-controlgroup-item {
- float: left;
- margin-left: 0;
- margin-right: 0;
+ float: left;
+ margin-left: 0;
+ margin-right: 0;
}
.ui-controlgroup > .ui-controlgroup-item:focus,
.ui-controlgroup > .ui-controlgroup-item.ui-visual-focus {
- z-index: 9999;
+ z-index: 9999;
}
.ui-controlgroup-vertical > .ui-controlgroup-item {
- display: block;
- float: none;
- width: 100%;
- margin-top: 0;
- margin-bottom: 0;
- text-align: left;
+ display: block;
+ float: none;
+ width: 100%;
+ margin-top: 0;
+ margin-bottom: 0;
+ text-align: left;
}
.ui-controlgroup-vertical .ui-controlgroup-item {
- box-sizing: border-box;
+ box-sizing: border-box;
}
.ui-controlgroup .ui-controlgroup-label {
- padding: .4em 1em;
+ padding: 0.4em 1em;
}
.ui-controlgroup .ui-controlgroup-label span {
- font-size: 80%;
+ font-size: 80%;
}
.ui-controlgroup-horizontal .ui-controlgroup-label + .ui-controlgroup-item {
- border-left: none;
+ border-left: none;
}
.ui-controlgroup-vertical .ui-controlgroup-label + .ui-controlgroup-item {
- border-top: none;
+ border-top: none;
}
.ui-controlgroup-horizontal .ui-controlgroup-label.ui-widget-content {
- border-right: none;
+ border-right: none;
}
.ui-controlgroup-vertical .ui-controlgroup-label.ui-widget-content {
- border-bottom: none;
+ border-bottom: none;
}
/* Spinner specific style fixes */
.ui-controlgroup-vertical .ui-spinner-input {
-
- /* Support: IE8 only, Android < 4.4 only */
- width: 75%;
- width: calc( 100% - 2.4em );
+ /* Support: IE8 only, Android < 4.4 only */
+ width: 75%;
+ width: calc(100% - 2.4em);
}
.ui-controlgroup-vertical .ui-spinner .ui-spinner-up {
- border-top-style: solid;
+ border-top-style: solid;
}
.ui-checkboxradio-label .ui-icon-background {
- box-shadow: inset 1px 1px 1px #ccc;
- border-radius: .12em;
- border: none;
+ box-shadow: inset 1px 1px 1px #ccc;
+ border-radius: 0.12em;
+ border: none;
}
.ui-checkboxradio-radio-label .ui-icon-background {
- width: 16px;
- height: 16px;
- border-radius: 1em;
- overflow: visible;
- border: none;
+ width: 16px;
+ height: 16px;
+ border-radius: 1em;
+ overflow: visible;
+ border: none;
}
.ui-checkboxradio-radio-label.ui-checkboxradio-checked .ui-icon,
.ui-checkboxradio-radio-label.ui-checkboxradio-checked:hover .ui-icon {
- background-image: none;
- width: 8px;
- height: 8px;
- border-width: 4px;
- border-style: solid;
+ background-image: none;
+ width: 8px;
+ height: 8px;
+ border-width: 4px;
+ border-style: solid;
}
.ui-checkboxradio-disabled {
- pointer-events: none;
+ pointer-events: none;
}
body .ui-dialog {
- position: absolute;
+ position: absolute;
top: 0;
left: 0;
outline: 0;
@@ -317,142 +313,143 @@ body .ui-dialog {
background-color: inherit;
}
.ui-dialog .ui-dialog-titlebar {
- padding: .4em 1em;
- position: relative;
- font-size: 1.2em;
+ display: flex;
+ padding: 0.3em 0.8em;
+ justify-content: space-between;
+ align-items: center;
+ font-size: 1.2em;
min-width: 150px;
}
.ui-dialog .ui-dialog-title {
- float: left;
- margin: .1em 0;
- white-space: nowrap;
- width: 90%;
- overflow: hidden;
- text-overflow: ellipsis;
+ white-space: nowrap;
+ width: 100%;
+ overflow: hidden;
+ text-overflow: ellipsis;
}
-.ui-dialog .ui-dialog-titlebar button {
- position: absolute;
- right: .5em;
- top: 53%;
- padding: 0;
- width: 1.8em;
- height: 1.8em;
+.ui-dialog .ui-dialog-titlebar button {
+ padding: 3px;
+ margin-left: 5px;
+ width: 19px;
+ height: 18px;
color: #ffffff;
background: none;
- font-size: .75em;
+ font-size: 0.8em;
border: 1px solid #c5c5c5;
}
-.ui-dialog .ui-dialog-titlebar button.ui-dialog-titlebar-collapse {
- margin: -1em 2.2em 0 0;
+@media (max-width: 600px) {
+ .ui-dialog .ui-dialog-title {
+ font-size: 1.6em;
+ }
+
+ .ui-dialog .ui-dialog-titlebar button {
+ padding: 3px;
+ margin-left: 10px;
+ width: 40px;
+ height: 32px;
+ font-size: 1.6em;
+ }
}
-.ui-dialog .ui-dialog-titlebar button.ui-dialog-titlebar-close {
- margin: -1em 0 0;
-}
-
-.ui-dialog .ui-dialog-titlebar button:active {
+.ui-dialog .ui-dialog-titlebar button:active {
border: 1px solid #5d4651;
color: #5d4651;
}
.ui-dialog .ui-dialog-content {
- position: relative;
- border: 0;
- padding: .5em 1em;
- background: none;
- overflow-y: auto;
- overflow-x: hidden;
+ position: relative;
+ border: 0;
+ padding: 0.5em 1em;
+ background: none;
+ overflow-y: auto;
+ overflow-x: auto;
}
.ui-dialog .ui-dialog-buttonpane {
- text-align: left;
- border-width: 1px 0 0 0;
- background-image: none;
- margin-top: .5em;
- padding: .3em 1em .5em .4em;
+ text-align: left;
+ border-width: 1px 0 0 0;
+ background-image: none;
+ margin-top: 0.5em;
+ padding: 0.3em 1em 0.5em 0.4em;
}
.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset {
- float: right;
+ float: right;
}
.ui-dialog .ui-dialog-buttonpane button {
- margin: .5em .4em .5em 0;
- cursor: pointer;
+ margin: 0.5em 0.4em 0.5em 0;
+ cursor: pointer;
}
.ui-dialog .ui-resizable-n {
- height: 2px;
- top: 0;
+ height: 2px;
+ top: 0;
}
.ui-dialog .ui-resizable-e {
- width: 2px;
- right: 0;
+ width: 2px;
+ right: 0;
}
.ui-dialog .ui-resizable-s {
- height: 2px;
- bottom: 0;
+ height: 2px;
+ bottom: 0;
}
.ui-dialog .ui-resizable-w {
- width: 2px;
- left: 0;
+ width: 2px;
+ left: 0;
}
.ui-dialog .ui-resizable-se,
.ui-dialog .ui-resizable-sw,
.ui-dialog .ui-resizable-ne,
.ui-dialog .ui-resizable-nw {
- width: 7px;
- height: 7px;
+ width: 7px;
+ height: 7px;
}
.ui-dialog .ui-resizable-se {
- right: 0;
- bottom: 0;
+ right: 0;
+ bottom: 0;
}
.ui-dialog .ui-resizable-sw {
- left: 0;
- bottom: 0;
+ left: 0;
+ bottom: 0;
}
.ui-dialog .ui-resizable-ne {
- right: 0;
- top: 0;
+ right: 0;
+ top: 0;
}
.ui-dialog .ui-resizable-nw {
- left: 0;
- top: 0;
+ left: 0;
+ top: 0;
}
.ui-draggable .ui-dialog-titlebar {
- cursor: move;
+ cursor: move;
}
/* Component containers
----------------------------------*/
.ui-widget {
- font-family: Arial,Helvetica,sans-serif;
+ font-family: var(--sans-serif);
}
.ui-widget input,
.ui-widget select,
.ui-widget textarea,
.ui-widget button {
- font-family: Arial,Helvetica,sans-serif;
- font-size: 1em;
+ font-family: var(--sans-serif);
+ font-size: 1em;
+}
+.ui-widget button[class^="icon-"] {
+ padding: 1px 6px;
}
.ui-widget.ui-widget-content {
- border: 1px solid #5e4fa2;
+ border: 1px solid #5e4fa2;
color: #333333;
}
.ui-widget-content {
- border: 1px solid #dddddd;
- color: #333333;
+ border: 1px solid #dddddd;
+ color: #333333;
}
.ui-widget-content a {
- color: #333333;
-}
-.ui-widget-header {
- border-bottom: 1px solid #5d4651;
- background: #916e7f;
- color: #ffffff;
- font-weight: bold;
+ color: #333333;
}
.ui-widget-header a {
- color: #333333;
+ color: #333333;
}
/* Interaction states
@@ -466,10 +463,10 @@ body .ui-dialog {
works properly when clicked or hovered */
html .ui-button.ui-state-disabled:hover,
html .ui-button.ui-state-disabled:active {
- border: 1px solid #c5c5c5;
- background: #f6f6f6;
- font-weight: normal;
- color: #454545;
+ border: 1px solid #c5c5c5;
+ background: #f6f6f6;
+ font-weight: normal;
+ color: #454545;
}
.ui-state-default a,
.ui-state-default a:link,
@@ -478,10 +475,10 @@ a.ui-button,
a:link.ui-button,
a:visited.ui-button,
.ui-button {
- color: #454545;
+ color: #454545;
}
.ui-button:active {
- color: #5d4651;
+ color: #5d4651;
border-color: #5d4651;
}
.ui-state-hover a,
@@ -494,12 +491,12 @@ a:visited.ui-button,
.ui-state-focus a:visited,
a.ui-button:hover,
a.ui-button:focus {
- color: #2b2b2b;
- text-decoration: none;
+ color: #2b2b2b;
+ text-decoration: none;
}
.ui-visual-focus {
- box-shadow: 0 0 3px 1px rgb(94, 158, 214);
+ box-shadow: 0 0 3px 1px rgb(94, 158, 214);
}
/* Interaction Cues
@@ -507,68 +504,68 @@ a.ui-button:focus {
.ui-state-highlight,
.ui-widget-content .ui-state-highlight,
.ui-widget-header .ui-state-highlight {
- border: 1px solid #dad55e;
- background: #fffa90;
- color: #777620;
+ border: 1px solid #dad55e;
+ background: #fffa90;
+ color: #777620;
}
.ui-state-checked {
- border: 1px solid #dad55e;
- background: #fffa90;
+ border: 1px solid #dad55e;
+ background: #fffa90;
}
.ui-state-highlight a,
.ui-widget-content .ui-state-highlight a,
.ui-widget-header .ui-state-highlight a {
- color: #777620;
+ color: #777620;
}
.ui-state-error,
.ui-widget-content .ui-state-error,
.ui-widget-header .ui-state-error {
- border: 1px solid #f1a899;
- background: #fddfdf;
- color: #5f3f3f;
+ border: 1px solid #f1a899;
+ background: #fddfdf;
+ color: #5f3f3f;
}
.ui-state-error a,
.ui-widget-content .ui-state-error a,
.ui-widget-header .ui-state-error a {
- color: #5f3f3f;
+ color: #5f3f3f;
}
.ui-state-error-text,
.ui-widget-content .ui-state-error-text,
.ui-widget-header .ui-state-error-text {
- color: #5f3f3f;
+ color: #5f3f3f;
}
.ui-priority-primary,
.ui-widget-content .ui-priority-primary,
.ui-widget-header .ui-priority-primary {
- font-weight: bold;
+ font-weight: bold;
}
.ui-priority-secondary,
.ui-widget-content .ui-priority-secondary,
.ui-widget-header .ui-priority-secondary {
- opacity: .7;
- filter:Alpha(Opacity=70); /* support: IE8 */
- font-weight: normal;
+ opacity: 0.7;
+ filter: Alpha(Opacity=70); /* support: IE8 */
+ font-weight: normal;
}
.ui-state-disabled,
.ui-widget-content .ui-state-disabled,
.ui-widget-header .ui-state-disabled {
- opacity: .35;
- filter:Alpha(Opacity=35); /* support: IE8 */
- background-image: none;
+ opacity: 0.35;
+ filter: Alpha(Opacity=35); /* support: IE8 */
+ background-image: none;
}
.ui-state-disabled .ui-icon {
- filter:Alpha(Opacity=35); /* support: IE8 - See #6059 */
+ filter: Alpha(Opacity=35); /* support: IE8 - See #6059 */
}
/* Misc visuals
----------------------------------*/
/* Overlays */
.ui-widget-overlay {
- background: #aaaaaa;
- opacity: .3;
- filter: Alpha(Opacity=30); /* support: IE8 */
+ background: #aaaaaa;
+ opacity: 0.3;
+ filter: Alpha(Opacity=30); /* support: IE8 */
}
.ui-widget-shadow {
- -webkit-box-shadow: 0px 0px 5px #666666;
- box-shadow: 0px 0px 5px #666666;
+ -webkit-box-shadow: 0px 0px 5px #666666;
+ box-shadow: 0px 0px 5px #666666;
}
diff --git a/libs/jszip.min.js b/libs/jszip.min.js
new file mode 100644
index 00000000..131b697d
--- /dev/null
+++ b/libs/jszip.min.js
@@ -0,0 +1,13 @@
+/*!
+
+JSZip v3.6.0 - A JavaScript class for generating and reading zip files
+
+
+(c) 2009-2016 Stuart Knightley
+Dual licenced under the MIT license or GPLv3. See https://raw.github.com/Stuk/jszip/master/LICENSE.markdown.
+
+JSZip uses the library pako released under the MIT license :
+https://github.com/nodeca/pako/blob/master/LICENSE
+*/
+
+!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).JSZip=e()}}(function(){return function s(a,o,u){function h(r,e){if(!o[r]){if(!a[r]){var t="function"==typeof require&&require;if(!e&&t)return t(r,!0);if(f)return f(r,!0);var n=new Error("Cannot find module '"+r+"'");throw n.code="MODULE_NOT_FOUND",n}var i=o[r]={exports:{}};a[r][0].call(i.exports,function(e){var t=a[r][1][e];return h(t||e)},i,i.exports,s,a,o,u)}return o[r].exports}for(var f="function"==typeof require&&require,e=0;e>2,s=(3&t)<<4|r>>4,a=1>6:64,o=2>4,r=(15&i)<<4|(s=p.indexOf(e.charAt(o++)))>>2,n=(3&s)<<6|(a=p.indexOf(e.charAt(o++))),h[u++]=t,64!==s&&(h[u++]=r),64!==a&&(h[u++]=n);return h}},{"./support":30,"./utils":32}],2:[function(e,t,r){"use strict";var n=e("./external"),i=e("./stream/DataWorker"),s=e("./stream/Crc32Probe"),a=e("./stream/DataLengthProbe");function o(e,t,r,n,i){this.compressedSize=e,this.uncompressedSize=t,this.crc32=r,this.compression=n,this.compressedContent=i}o.prototype={getContentWorker:function(){var e=new i(n.Promise.resolve(this.compressedContent)).pipe(this.compression.uncompressWorker()).pipe(new a("data_length")),t=this;return e.on("end",function(){if(this.streamInfo.data_length!==t.uncompressedSize)throw new Error("Bug : uncompressed data size mismatch")}),e},getCompressedWorker:function(){return new i(n.Promise.resolve(this.compressedContent)).withStreamInfo("compressedSize",this.compressedSize).withStreamInfo("uncompressedSize",this.uncompressedSize).withStreamInfo("crc32",this.crc32).withStreamInfo("compression",this.compression)}},o.createWorkerFrom=function(e,t,r){return e.pipe(new s).pipe(new a("uncompressedSize")).pipe(t.compressWorker(r)).pipe(new a("compressedSize")).withStreamInfo("compression",t)},t.exports=o},{"./external":6,"./stream/Crc32Probe":25,"./stream/DataLengthProbe":26,"./stream/DataWorker":27}],3:[function(e,t,r){"use strict";var n=e("./stream/GenericWorker");r.STORE={magic:"\0\0",compressWorker:function(e){return new n("STORE compression")},uncompressWorker:function(){return new n("STORE decompression")}},r.DEFLATE=e("./flate")},{"./flate":7,"./stream/GenericWorker":28}],4:[function(e,t,r){"use strict";var n=e("./utils"),a=function(){for(var e,t=[],r=0;r<256;r++){e=r;for(var n=0;n<8;n++)e=1&e?3988292384^e>>>1:e>>>1;t[r]=e}return t}();t.exports=function(e,t){return void 0!==e&&e.length?"string"!==n.getTypeOf(e)?function(e,t,r){var n=a,i=0+r;e^=-1;for(var s=0;s>>8^n[255&(e^t[s])];return-1^e}(0|t,e,e.length):function(e,t,r){var n=a,i=0+r;e^=-1;for(var s=0;s>>8^n[255&(e^t.charCodeAt(s))];return-1^e}(0|t,e,e.length):0}},{"./utils":32}],5:[function(e,t,r){"use strict";r.base64=!1,r.binary=!1,r.dir=!1,r.createFolders=!0,r.date=null,r.compression=null,r.compressionOptions=null,r.comment=null,r.unixPermissions=null,r.dosPermissions=null},{}],6:[function(e,t,r){"use strict";var n;n="undefined"!=typeof Promise?Promise:e("lie"),t.exports={Promise:n}},{lie:37}],7:[function(e,t,r){"use strict";var n="undefined"!=typeof Uint8Array&&"undefined"!=typeof Uint16Array&&"undefined"!=typeof Uint32Array,i=e("pako"),s=e("./utils"),a=e("./stream/GenericWorker"),o=n?"uint8array":"array";function u(e,t){a.call(this,"FlateWorker/"+e),this._pako=null,this._pakoAction=e,this._pakoOptions=t,this.meta={}}r.magic="\b\0",s.inherits(u,a),u.prototype.processChunk=function(e){this.meta=e.meta,null===this._pako&&this._createPako(),this._pako.push(s.transformTo(o,e.data),!1)},u.prototype.flush=function(){a.prototype.flush.call(this),null===this._pako&&this._createPako(),this._pako.push([],!0)},u.prototype.cleanUp=function(){a.prototype.cleanUp.call(this),this._pako=null},u.prototype._createPako=function(){this._pako=new i[this._pakoAction]({raw:!0,level:this._pakoOptions.level||-1});var t=this;this._pako.onData=function(e){t.push({data:e,meta:t.meta})}},r.compressWorker=function(e){return new u("Deflate",e)},r.uncompressWorker=function(){return new u("Inflate",{})}},{"./stream/GenericWorker":28,"./utils":32,pako:38}],8:[function(e,t,r){"use strict";function I(e,t){var r,n="";for(r=0;r>>=8;return n}function i(e,t,r,n,i,s){var a,o,u=e.file,h=e.compression,f=s!==B.utf8encode,l=O.transformTo("string",s(u.name)),d=O.transformTo("string",B.utf8encode(u.name)),c=u.comment,p=O.transformTo("string",s(c)),m=O.transformTo("string",B.utf8encode(c)),_=d.length!==u.name.length,g=m.length!==c.length,v="",b="",w="",y=u.dir,k=u.date,x={crc32:0,compressedSize:0,uncompressedSize:0};t&&!r||(x.crc32=e.crc32,x.compressedSize=e.compressedSize,x.uncompressedSize=e.uncompressedSize);var S=0;t&&(S|=8),f||!_&&!g||(S|=2048);var z,E=0,C=0;y&&(E|=16),"UNIX"===i?(C=798,E|=((z=u.unixPermissions)||(z=y?16893:33204),(65535&z)<<16)):(C=20,E|=63&(u.dosPermissions||0)),a=k.getUTCHours(),a<<=6,a|=k.getUTCMinutes(),a<<=5,a|=k.getUTCSeconds()/2,o=k.getUTCFullYear()-1980,o<<=4,o|=k.getUTCMonth()+1,o<<=5,o|=k.getUTCDate(),_&&(v+="up"+I((b=I(1,1)+I(T(l),4)+d).length,2)+b),g&&(v+="uc"+I((w=I(1,1)+I(T(p),4)+m).length,2)+w);var A="";return A+="\n\0",A+=I(S,2),A+=h.magic,A+=I(a,2),A+=I(o,2),A+=I(x.crc32,4),A+=I(x.compressedSize,4),A+=I(x.uncompressedSize,4),A+=I(l.length,2),A+=I(v.length,2),{fileRecord:R.LOCAL_FILE_HEADER+A+l+v,dirRecord:R.CENTRAL_FILE_HEADER+I(C,2)+A+I(p.length,2)+"\0\0\0\0"+I(E,4)+I(n,4)+l+v+p}}var O=e("../utils"),s=e("../stream/GenericWorker"),B=e("../utf8"),T=e("../crc32"),R=e("../signature");function n(e,t,r,n){s.call(this,"ZipFileWorker"),this.bytesWritten=0,this.zipComment=t,this.zipPlatform=r,this.encodeFileName=n,this.streamFiles=e,this.accumulate=!1,this.contentBuffer=[],this.dirRecords=[],this.currentSourceOffset=0,this.entriesCount=0,this.currentFile=null,this._sources=[]}O.inherits(n,s),n.prototype.push=function(e){var t=e.meta.percent||0,r=this.entriesCount,n=this._sources.length;this.accumulate?this.contentBuffer.push(e):(this.bytesWritten+=e.data.length,s.prototype.push.call(this,{data:e.data,meta:{currentFile:this.currentFile,percent:r?(t+100*(r-n-1))/r:100}}))},n.prototype.openedSource=function(e){this.currentSourceOffset=this.bytesWritten,this.currentFile=e.file.name;var t=this.streamFiles&&!e.file.dir;if(t){var r=i(e,t,!1,this.currentSourceOffset,this.zipPlatform,this.encodeFileName);this.push({data:r.fileRecord,meta:{percent:0}})}else this.accumulate=!0},n.prototype.closedSource=function(e){this.accumulate=!1;var t,r=this.streamFiles&&!e.file.dir,n=i(e,r,!0,this.currentSourceOffset,this.zipPlatform,this.encodeFileName);if(this.dirRecords.push(n.dirRecord),r)this.push({data:(t=e,R.DATA_DESCRIPTOR+I(t.crc32,4)+I(t.compressedSize,4)+I(t.uncompressedSize,4)),meta:{percent:100}});else for(this.push({data:n.fileRecord,meta:{percent:0}});this.contentBuffer.length;)this.push(this.contentBuffer.shift());this.currentFile=null},n.prototype.flush=function(){for(var e=this.bytesWritten,t=0;t=this.index;t--)r=(r<<8)+this.byteAt(t);return this.index+=e,r},readString:function(e){return n.transformTo("string",this.readData(e))},readData:function(e){},lastIndexOfSignature:function(e){},readAndCheckSignature:function(e){},readDate:function(){var e=this.readInt(4);return new Date(Date.UTC(1980+(e>>25&127),(e>>21&15)-1,e>>16&31,e>>11&31,e>>5&63,(31&e)<<1))}},t.exports=i},{"../utils":32}],19:[function(e,t,r){"use strict";var n=e("./Uint8ArrayReader");function i(e){n.call(this,e)}e("../utils").inherits(i,n),i.prototype.readData=function(e){this.checkOffset(e);var t=this.data.slice(this.zero+this.index,this.zero+this.index+e);return this.index+=e,t},t.exports=i},{"../utils":32,"./Uint8ArrayReader":21}],20:[function(e,t,r){"use strict";var n=e("./DataReader");function i(e){n.call(this,e)}e("../utils").inherits(i,n),i.prototype.byteAt=function(e){return this.data.charCodeAt(this.zero+e)},i.prototype.lastIndexOfSignature=function(e){return this.data.lastIndexOf(e)-this.zero},i.prototype.readAndCheckSignature=function(e){return e===this.readData(4)},i.prototype.readData=function(e){this.checkOffset(e);var t=this.data.slice(this.zero+this.index,this.zero+this.index+e);return this.index+=e,t},t.exports=i},{"../utils":32,"./DataReader":18}],21:[function(e,t,r){"use strict";var n=e("./ArrayReader");function i(e){n.call(this,e)}e("../utils").inherits(i,n),i.prototype.readData=function(e){if(this.checkOffset(e),0===e)return new Uint8Array(0);var t=this.data.subarray(this.zero+this.index,this.zero+this.index+e);return this.index+=e,t},t.exports=i},{"../utils":32,"./ArrayReader":17}],22:[function(e,t,r){"use strict";var n=e("../utils"),i=e("../support"),s=e("./ArrayReader"),a=e("./StringReader"),o=e("./NodeBufferReader"),u=e("./Uint8ArrayReader");t.exports=function(e){var t=n.getTypeOf(e);return n.checkSupport(t),"string"!==t||i.uint8array?"nodebuffer"===t?new o(e):i.uint8array?new u(n.transformTo("uint8array",e)):new s(n.transformTo("array",e)):new a(e)}},{"../support":30,"../utils":32,"./ArrayReader":17,"./NodeBufferReader":19,"./StringReader":20,"./Uint8ArrayReader":21}],23:[function(e,t,r){"use strict";r.LOCAL_FILE_HEADER="PK",r.CENTRAL_FILE_HEADER="PK",r.CENTRAL_DIRECTORY_END="PK",r.ZIP64_CENTRAL_DIRECTORY_LOCATOR="PK",r.ZIP64_CENTRAL_DIRECTORY_END="PK",r.DATA_DESCRIPTOR="PK\b"},{}],24:[function(e,t,r){"use strict";var n=e("./GenericWorker"),i=e("../utils");function s(e){n.call(this,"ConvertWorker to "+e),this.destType=e}i.inherits(s,n),s.prototype.processChunk=function(e){this.push({data:i.transformTo(this.destType,e.data),meta:e.meta})},t.exports=s},{"../utils":32,"./GenericWorker":28}],25:[function(e,t,r){"use strict";var n=e("./GenericWorker"),i=e("../crc32");function s(){n.call(this,"Crc32Probe"),this.withStreamInfo("crc32",0)}e("../utils").inherits(s,n),s.prototype.processChunk=function(e){this.streamInfo.crc32=i(e.data,this.streamInfo.crc32||0),this.push(e)},t.exports=s},{"../crc32":4,"../utils":32,"./GenericWorker":28}],26:[function(e,t,r){"use strict";var n=e("../utils"),i=e("./GenericWorker");function s(e){i.call(this,"DataLengthProbe for "+e),this.propName=e,this.withStreamInfo(e,0)}n.inherits(s,i),s.prototype.processChunk=function(e){if(e){var t=this.streamInfo[this.propName]||0;this.streamInfo[this.propName]=t+e.data.length}i.prototype.processChunk.call(this,e)},t.exports=s},{"../utils":32,"./GenericWorker":28}],27:[function(e,t,r){"use strict";var n=e("../utils"),i=e("./GenericWorker");function s(e){i.call(this,"DataWorker");var t=this;this.dataIsReady=!1,this.index=0,this.max=0,this.data=null,this.type="",this._tickScheduled=!1,e.then(function(e){t.dataIsReady=!0,t.data=e,t.max=e&&e.length||0,t.type=n.getTypeOf(e),t.isPaused||t._tickAndRepeat()},function(e){t.error(e)})}n.inherits(s,i),s.prototype.cleanUp=function(){i.prototype.cleanUp.call(this),this.data=null},s.prototype.resume=function(){return!!i.prototype.resume.call(this)&&(!this._tickScheduled&&this.dataIsReady&&(this._tickScheduled=!0,n.delay(this._tickAndRepeat,[],this)),!0)},s.prototype._tickAndRepeat=function(){this._tickScheduled=!1,this.isPaused||this.isFinished||(this._tick(),this.isFinished||(n.delay(this._tickAndRepeat,[],this),this._tickScheduled=!0))},s.prototype._tick=function(){if(this.isPaused||this.isFinished)return!1;var e=null,t=Math.min(this.max,this.index+16384);if(this.index>=this.max)return this.end();switch(this.type){case"string":e=this.data.substring(this.index,t);break;case"uint8array":e=this.data.subarray(this.index,t);break;case"array":case"nodebuffer":e=this.data.slice(this.index,t)}return this.index=t,this.push({data:e,meta:{percent:this.max?this.index/this.max*100:0}})},t.exports=s},{"../utils":32,"./GenericWorker":28}],28:[function(e,t,r){"use strict";function n(e){this.name=e||"default",this.streamInfo={},this.generatedError=null,this.extraStreamInfo={},this.isPaused=!0,this.isFinished=!1,this.isLocked=!1,this._listeners={data:[],end:[],error:[]},this.previous=null}n.prototype={push:function(e){this.emit("data",e)},end:function(){if(this.isFinished)return!1;this.flush();try{this.emit("end"),this.cleanUp(),this.isFinished=!0}catch(e){this.emit("error",e)}return!0},error:function(e){return!this.isFinished&&(this.isPaused?this.generatedError=e:(this.isFinished=!0,this.emit("error",e),this.previous&&this.previous.error(e),this.cleanUp()),!0)},on:function(e,t){return this._listeners[e].push(t),this},cleanUp:function(){this.streamInfo=this.generatedError=this.extraStreamInfo=null,this._listeners=[]},emit:function(e,t){if(this._listeners[e])for(var r=0;r "+e:e}},t.exports=n},{}],29:[function(e,t,r){"use strict";var h=e("../utils"),i=e("./ConvertWorker"),s=e("./GenericWorker"),f=e("../base64"),n=e("../support"),a=e("../external"),o=null;if(n.nodestream)try{o=e("../nodejs/NodejsStreamOutputAdapter")}catch(e){}function u(e,t,r){var n=t;switch(t){case"blob":case"arraybuffer":n="uint8array";break;case"base64":n="string"}try{this._internalType=n,this._outputType=t,this._mimeType=r,h.checkSupport(n),this._worker=e.pipe(new i(n)),e.lock()}catch(e){this._worker=new s("error"),this._worker.error(e)}}u.prototype={accumulate:function(e){return o=this,u=e,new a.Promise(function(t,r){var n=[],i=o._internalType,s=o._outputType,a=o._mimeType;o.on("data",function(e,t){n.push(e),u&&u(t)}).on("error",function(e){n=[],r(e)}).on("end",function(){try{var e=function(e,t,r){switch(e){case"blob":return h.newBlob(h.transformTo("arraybuffer",t),r);case"base64":return f.encode(t);default:return h.transformTo(e,t)}}(s,function(e,t){var r,n=0,i=null,s=0;for(r=0;r>>6:(r<65536?t[s++]=224|r>>>12:(t[s++]=240|r>>>18,t[s++]=128|r>>>12&63),t[s++]=128|r>>>6&63),t[s++]=128|63&r);return t}(e)},s.utf8decode=function(e){return u.nodebuffer?o.transformTo("nodebuffer",e).toString("utf-8"):function(e){var t,r,n,i,s=e.length,a=new Array(2*s);for(t=r=0;t>10&1023,a[r++]=56320|1023&n)}return a.length!==r&&(a.subarray?a=a.subarray(0,r):a.length=r),o.applyFromCharCode(a)}(e=o.transformTo(u.uint8array?"uint8array":"array",e))},o.inherits(a,n),a.prototype.processChunk=function(e){var t=o.transformTo(u.uint8array?"uint8array":"array",e.data);if(this.leftOver&&this.leftOver.length){if(u.uint8array){var r=t;(t=new Uint8Array(r.length+this.leftOver.length)).set(this.leftOver,0),t.set(r,this.leftOver.length)}else t=this.leftOver.concat(t);this.leftOver=null}var n=function(e,t){var r;for((t=t||e.length)>e.length&&(t=e.length),r=t-1;0<=r&&128==(192&e[r]);)r--;return r<0?t:0===r?t:r+h[e[r]]>t?r:t}(t),i=t;n!==t.length&&(u.uint8array?(i=t.subarray(0,n),this.leftOver=t.subarray(n,t.length)):(i=t.slice(0,n),this.leftOver=t.slice(n,t.length))),this.push({data:s.utf8decode(i),meta:e.meta})},a.prototype.flush=function(){this.leftOver&&this.leftOver.length&&(this.push({data:s.utf8decode(this.leftOver),meta:{}}),this.leftOver=null)},s.Utf8DecodeWorker=a,o.inherits(f,n),f.prototype.processChunk=function(e){this.push({data:s.utf8encode(e.data),meta:e.meta})},s.Utf8EncodeWorker=f},{"./nodejsUtils":14,"./stream/GenericWorker":28,"./support":30,"./utils":32}],32:[function(e,t,o){"use strict";var u=e("./support"),h=e("./base64"),r=e("./nodejsUtils"),n=e("set-immediate-shim"),f=e("./external");function i(e){return e}function l(e,t){for(var r=0;r>8;this.dir=!!(16&this.externalFileAttributes),0==e&&(this.dosPermissions=63&this.externalFileAttributes),3==e&&(this.unixPermissions=this.externalFileAttributes>>16&65535),this.dir||"/"!==this.fileNameStr.slice(-1)||(this.dir=!0)},parseZIP64ExtraField:function(e){if(this.extraFields[1]){var t=n(this.extraFields[1].value);this.uncompressedSize===s.MAX_VALUE_32BITS&&(this.uncompressedSize=t.readInt(8)),this.compressedSize===s.MAX_VALUE_32BITS&&(this.compressedSize=t.readInt(8)),this.localHeaderOffset===s.MAX_VALUE_32BITS&&(this.localHeaderOffset=t.readInt(8)),this.diskNumberStart===s.MAX_VALUE_32BITS&&(this.diskNumberStart=t.readInt(4))}},readExtraFields:function(e){var t,r,n,i=e.index+this.extraFieldsLength;for(this.extraFields||(this.extraFields={});e.index+4>>6:(r<65536?t[s++]=224|r>>>12:(t[s++]=240|r>>>18,t[s++]=128|r>>>12&63),t[s++]=128|r>>>6&63),t[s++]=128|63&r);return t},r.buf2binstring=function(e){return f(e,e.length)},r.binstring2buf=function(e){for(var t=new u.Buf8(e.length),r=0,n=t.length;r>10&1023,o[n++]=56320|1023&i)}return f(o,n)},r.utf8border=function(e,t){var r;for((t=t||e.length)>e.length&&(t=e.length),r=t-1;0<=r&&128==(192&e[r]);)r--;return r<0?t:0===r?t:r+h[e[r]]>t?r:t}},{"./common":41}],43:[function(e,t,r){"use strict";t.exports=function(e,t,r,n){for(var i=65535&e|0,s=e>>>16&65535|0,a=0;0!==r;){for(r-=a=2e3>>1:e>>>1;t[r]=e}return t}();t.exports=function(e,t,r,n){var i=o,s=n+r;e^=-1;for(var a=n;a>>8^i[255&(e^t[a])];return-1^e}},{}],46:[function(e,t,r){"use strict";var u,d=e("../utils/common"),h=e("./trees"),c=e("./adler32"),p=e("./crc32"),n=e("./messages"),f=0,l=0,m=-2,i=2,_=8,s=286,a=30,o=19,g=2*s+1,v=15,b=3,w=258,y=w+b+1,k=42,x=113;function S(e,t){return e.msg=n[t],t}function z(e){return(e<<1)-(4e.avail_out&&(r=e.avail_out),0!==r&&(d.arraySet(e.output,t.pending_buf,t.pending_out,r,e.next_out),e.next_out+=r,t.pending_out+=r,e.total_out+=r,e.avail_out-=r,t.pending-=r,0===t.pending&&(t.pending_out=0))}function A(e,t){h._tr_flush_block(e,0<=e.block_start?e.block_start:-1,e.strstart-e.block_start,t),e.block_start=e.strstart,C(e.strm)}function I(e,t){e.pending_buf[e.pending++]=t}function O(e,t){e.pending_buf[e.pending++]=t>>>8&255,e.pending_buf[e.pending++]=255&t}function B(e,t){var r,n,i=e.max_chain_length,s=e.strstart,a=e.prev_length,o=e.nice_match,u=e.strstart>e.w_size-y?e.strstart-(e.w_size-y):0,h=e.window,f=e.w_mask,l=e.prev,d=e.strstart+w,c=h[s+a-1],p=h[s+a];e.prev_length>=e.good_match&&(i>>=2),o>e.lookahead&&(o=e.lookahead);do{if(h[(r=t)+a]===p&&h[r+a-1]===c&&h[r]===h[s]&&h[++r]===h[s+1]){s+=2,r++;do{}while(h[++s]===h[++r]&&h[++s]===h[++r]&&h[++s]===h[++r]&&h[++s]===h[++r]&&h[++s]===h[++r]&&h[++s]===h[++r]&&h[++s]===h[++r]&&h[++s]===h[++r]&&su&&0!=--i);return a<=e.lookahead?a:e.lookahead}function T(e){var t,r,n,i,s,a,o,u,h,f,l=e.w_size;do{if(i=e.window_size-e.lookahead-e.strstart,e.strstart>=l+(l-y)){for(d.arraySet(e.window,e.window,l,l,0),e.match_start-=l,e.strstart-=l,e.block_start-=l,t=r=e.hash_size;n=e.head[--t],e.head[t]=l<=n?n-l:0,--r;);for(t=r=l;n=e.prev[--t],e.prev[t]=l<=n?n-l:0,--r;);i+=l}if(0===e.strm.avail_in)break;if(a=e.strm,o=e.window,u=e.strstart+e.lookahead,f=void 0,(h=i)<(f=a.avail_in)&&(f=h),r=0===f?0:(a.avail_in-=f,d.arraySet(o,a.input,a.next_in,f,u),1===a.state.wrap?a.adler=c(a.adler,o,f,u):2===a.state.wrap&&(a.adler=p(a.adler,o,f,u)),a.next_in+=f,a.total_in+=f,f),e.lookahead+=r,e.lookahead+e.insert>=b)for(s=e.strstart-e.insert,e.ins_h=e.window[s],e.ins_h=(e.ins_h<=b&&(e.ins_h=(e.ins_h<=b)if(n=h._tr_tally(e,e.strstart-e.match_start,e.match_length-b),e.lookahead-=e.match_length,e.match_length<=e.max_lazy_match&&e.lookahead>=b){for(e.match_length--;e.strstart++,e.ins_h=(e.ins_h<=b&&(e.ins_h=(e.ins_h<=b&&e.match_length<=e.prev_length){for(i=e.strstart+e.lookahead-b,n=h._tr_tally(e,e.strstart-1-e.prev_match,e.prev_length-b),e.lookahead-=e.prev_length-1,e.prev_length-=2;++e.strstart<=i&&(e.ins_h=(e.ins_h<e.pending_buf_size-5&&(r=e.pending_buf_size-5);;){if(e.lookahead<=1){if(T(e),0===e.lookahead&&t===f)return 1;if(0===e.lookahead)break}e.strstart+=e.lookahead,e.lookahead=0;var n=e.block_start+r;if((0===e.strstart||e.strstart>=n)&&(e.lookahead=e.strstart-n,e.strstart=n,A(e,!1),0===e.strm.avail_out))return 1;if(e.strstart-e.block_start>=e.w_size-y&&(A(e,!1),0===e.strm.avail_out))return 1}return e.insert=0,4===t?(A(e,!0),0===e.strm.avail_out?3:4):(e.strstart>e.block_start&&(A(e,!1),e.strm.avail_out),1)}),new F(4,4,8,4,R),new F(4,5,16,8,R),new F(4,6,32,32,R),new F(4,4,16,16,D),new F(8,16,32,32,D),new F(8,16,128,128,D),new F(8,32,128,256,D),new F(32,128,258,1024,D),new F(32,258,258,4096,D)],r.deflateInit=function(e,t){return L(e,t,_,15,8,0)},r.deflateInit2=L,r.deflateReset=P,r.deflateResetKeep=U,r.deflateSetHeader=function(e,t){return e&&e.state?2!==e.state.wrap?m:(e.state.gzhead=t,l):m},r.deflate=function(e,t){var r,n,i,s;if(!e||!e.state||5>8&255),I(n,n.gzhead.time>>16&255),I(n,n.gzhead.time>>24&255),I(n,9===n.level?2:2<=n.strategy||n.level<2?4:0),I(n,255&n.gzhead.os),n.gzhead.extra&&n.gzhead.extra.length&&(I(n,255&n.gzhead.extra.length),I(n,n.gzhead.extra.length>>8&255)),n.gzhead.hcrc&&(e.adler=p(e.adler,n.pending_buf,n.pending,0)),n.gzindex=0,n.status=69):(I(n,0),I(n,0),I(n,0),I(n,0),I(n,0),I(n,9===n.level?2:2<=n.strategy||n.level<2?4:0),I(n,3),n.status=x);else{var a=_+(n.w_bits-8<<4)<<8;a|=(2<=n.strategy||n.level<2?0:n.level<6?1:6===n.level?2:3)<<6,0!==n.strstart&&(a|=32),a+=31-a%31,n.status=x,O(n,a),0!==n.strstart&&(O(n,e.adler>>>16),O(n,65535&e.adler)),e.adler=1}if(69===n.status)if(n.gzhead.extra){for(i=n.pending;n.gzindex<(65535&n.gzhead.extra.length)&&(n.pending!==n.pending_buf_size||(n.gzhead.hcrc&&n.pending>i&&(e.adler=p(e.adler,n.pending_buf,n.pending-i,i)),C(e),i=n.pending,n.pending!==n.pending_buf_size));)I(n,255&n.gzhead.extra[n.gzindex]),n.gzindex++;n.gzhead.hcrc&&n.pending>i&&(e.adler=p(e.adler,n.pending_buf,n.pending-i,i)),n.gzindex===n.gzhead.extra.length&&(n.gzindex=0,n.status=73)}else n.status=73;if(73===n.status)if(n.gzhead.name){i=n.pending;do{if(n.pending===n.pending_buf_size&&(n.gzhead.hcrc&&n.pending>i&&(e.adler=p(e.adler,n.pending_buf,n.pending-i,i)),C(e),i=n.pending,n.pending===n.pending_buf_size)){s=1;break}s=n.gzindexi&&(e.adler=p(e.adler,n.pending_buf,n.pending-i,i)),0===s&&(n.gzindex=0,n.status=91)}else n.status=91;if(91===n.status)if(n.gzhead.comment){i=n.pending;do{if(n.pending===n.pending_buf_size&&(n.gzhead.hcrc&&n.pending>i&&(e.adler=p(e.adler,n.pending_buf,n.pending-i,i)),C(e),i=n.pending,n.pending===n.pending_buf_size)){s=1;break}s=n.gzindexi&&(e.adler=p(e.adler,n.pending_buf,n.pending-i,i)),0===s&&(n.status=103)}else n.status=103;if(103===n.status&&(n.gzhead.hcrc?(n.pending+2>n.pending_buf_size&&C(e),n.pending+2<=n.pending_buf_size&&(I(n,255&e.adler),I(n,e.adler>>8&255),e.adler=0,n.status=x)):n.status=x),0!==n.pending){if(C(e),0===e.avail_out)return n.last_flush=-1,l}else if(0===e.avail_in&&z(t)<=z(r)&&4!==t)return S(e,-5);if(666===n.status&&0!==e.avail_in)return S(e,-5);if(0!==e.avail_in||0!==n.lookahead||t!==f&&666!==n.status){var o=2===n.strategy?function(e,t){for(var r;;){if(0===e.lookahead&&(T(e),0===e.lookahead)){if(t===f)return 1;break}if(e.match_length=0,r=h._tr_tally(e,0,e.window[e.strstart]),e.lookahead--,e.strstart++,r&&(A(e,!1),0===e.strm.avail_out))return 1}return e.insert=0,4===t?(A(e,!0),0===e.strm.avail_out?3:4):e.last_lit&&(A(e,!1),0===e.strm.avail_out)?1:2}(n,t):3===n.strategy?function(e,t){for(var r,n,i,s,a=e.window;;){if(e.lookahead<=w){if(T(e),e.lookahead<=w&&t===f)return 1;if(0===e.lookahead)break}if(e.match_length=0,e.lookahead>=b&&0e.lookahead&&(e.match_length=e.lookahead)}if(e.match_length>=b?(r=h._tr_tally(e,1,e.match_length-b),e.lookahead-=e.match_length,e.strstart+=e.match_length,e.match_length=0):(r=h._tr_tally(e,0,e.window[e.strstart]),e.lookahead--,e.strstart++),r&&(A(e,!1),0===e.strm.avail_out))return 1}return e.insert=0,4===t?(A(e,!0),0===e.strm.avail_out?3:4):e.last_lit&&(A(e,!1),0===e.strm.avail_out)?1:2}(n,t):u[n.level].func(n,t);if(3!==o&&4!==o||(n.status=666),1===o||3===o)return 0===e.avail_out&&(n.last_flush=-1),l;if(2===o&&(1===t?h._tr_align(n):5!==t&&(h._tr_stored_block(n,0,0,!1),3===t&&(E(n.head),0===n.lookahead&&(n.strstart=0,n.block_start=0,n.insert=0))),C(e),0===e.avail_out))return n.last_flush=-1,l}return 4!==t?l:n.wrap<=0?1:(2===n.wrap?(I(n,255&e.adler),I(n,e.adler>>8&255),I(n,e.adler>>16&255),I(n,e.adler>>24&255),I(n,255&e.total_in),I(n,e.total_in>>8&255),I(n,e.total_in>>16&255),I(n,e.total_in>>24&255)):(O(n,e.adler>>>16),O(n,65535&e.adler)),C(e),0=r.w_size&&(0===s&&(E(r.head),r.strstart=0,r.block_start=0,r.insert=0),h=new d.Buf8(r.w_size),d.arraySet(h,t,f-r.w_size,r.w_size,0),t=h,f=r.w_size),a=e.avail_in,o=e.next_in,u=e.input,e.avail_in=f,e.next_in=0,e.input=t,T(r);r.lookahead>=b;){for(n=r.strstart,i=r.lookahead-(b-1);r.ins_h=(r.ins_h<>>=w=b>>>24,p-=w,0==(w=b>>>16&255))E[s++]=65535&b;else{if(!(16&w)){if(0==(64&w)){b=m[(65535&b)+(c&(1<>>=w,p-=w),p<15&&(c+=z[n++]<>>=w=b>>>24,p-=w,!(16&(w=b>>>16&255))){if(0==(64&w)){b=_[(65535&b)+(c&(1<>>=w,p-=w,(w=s-a)>3,c&=(1<<(p-=y<<3))-1,e.next_in=n,e.next_out=s,e.avail_in=n>>24&255)+(e>>>8&65280)+((65280&e)<<8)+((255&e)<<24)}function s(){this.mode=0,this.last=!1,this.wrap=0,this.havedict=!1,this.flags=0,this.dmax=0,this.check=0,this.total=0,this.head=null,this.wbits=0,this.wsize=0,this.whave=0,this.wnext=0,this.window=null,this.hold=0,this.bits=0,this.length=0,this.offset=0,this.extra=0,this.lencode=null,this.distcode=null,this.lenbits=0,this.distbits=0,this.ncode=0,this.nlen=0,this.ndist=0,this.have=0,this.next=null,this.lens=new I.Buf16(320),this.work=new I.Buf16(288),this.lendyn=null,this.distdyn=null,this.sane=0,this.back=0,this.was=0}function a(e){var t;return e&&e.state?(t=e.state,e.total_in=e.total_out=t.total=0,e.msg="",t.wrap&&(e.adler=1&t.wrap),t.mode=P,t.last=0,t.havedict=0,t.dmax=32768,t.head=null,t.hold=0,t.bits=0,t.lencode=t.lendyn=new I.Buf32(n),t.distcode=t.distdyn=new I.Buf32(i),t.sane=1,t.back=-1,N):U}function o(e){var t;return e&&e.state?((t=e.state).wsize=0,t.whave=0,t.wnext=0,a(e)):U}function u(e,t){var r,n;return e&&e.state?(n=e.state,t<0?(r=0,t=-t):(r=1+(t>>4),t<48&&(t&=15)),t&&(t<8||15=s.wsize?(I.arraySet(s.window,t,r-s.wsize,s.wsize,0),s.wnext=0,s.whave=s.wsize):(n<(i=s.wsize-s.wnext)&&(i=n),I.arraySet(s.window,t,r-n,i,s.wnext),(n-=i)?(I.arraySet(s.window,t,r-n,n,0),s.wnext=n,s.whave=s.wsize):(s.wnext+=i,s.wnext===s.wsize&&(s.wnext=0),s.whave>>8&255,r.check=B(r.check,C,2,0),f=h=0,r.mode=2;break}if(r.flags=0,r.head&&(r.head.done=!1),!(1&r.wrap)||(((255&h)<<8)+(h>>8))%31){e.msg="incorrect header check",r.mode=30;break}if(8!=(15&h)){e.msg="unknown compression method",r.mode=30;break}if(f-=4,k=8+(15&(h>>>=4)),0===r.wbits)r.wbits=k;else if(k>r.wbits){e.msg="invalid window size",r.mode=30;break}r.dmax=1<>8&1),512&r.flags&&(C[0]=255&h,C[1]=h>>>8&255,r.check=B(r.check,C,2,0)),f=h=0,r.mode=3;case 3:for(;f<32;){if(0===o)break e;o--,h+=n[s++]<>>8&255,C[2]=h>>>16&255,C[3]=h>>>24&255,r.check=B(r.check,C,4,0)),f=h=0,r.mode=4;case 4:for(;f<16;){if(0===o)break e;o--,h+=n[s++]<>8),512&r.flags&&(C[0]=255&h,C[1]=h>>>8&255,r.check=B(r.check,C,2,0)),f=h=0,r.mode=5;case 5:if(1024&r.flags){for(;f<16;){if(0===o)break e;o--,h+=n[s++]<>>8&255,r.check=B(r.check,C,2,0)),f=h=0}else r.head&&(r.head.extra=null);r.mode=6;case 6:if(1024&r.flags&&(o<(c=r.length)&&(c=o),c&&(r.head&&(k=r.head.extra_len-r.length,r.head.extra||(r.head.extra=new Array(r.head.extra_len)),I.arraySet(r.head.extra,n,s,c,k)),512&r.flags&&(r.check=B(r.check,n,c,s)),o-=c,s+=c,r.length-=c),r.length))break e;r.length=0,r.mode=7;case 7:if(2048&r.flags){if(0===o)break e;for(c=0;k=n[s+c++],r.head&&k&&r.length<65536&&(r.head.name+=String.fromCharCode(k)),k&&c>9&1,r.head.done=!0),e.adler=r.check=0,r.mode=12;break;case 10:for(;f<32;){if(0===o)break e;o--,h+=n[s++]<>>=7&f,f-=7&f,r.mode=27;break}for(;f<3;){if(0===o)break e;o--,h+=n[s++]<>>=1)){case 0:r.mode=14;break;case 1:if(j(r),r.mode=20,6!==t)break;h>>>=2,f-=2;break e;case 2:r.mode=17;break;case 3:e.msg="invalid block type",r.mode=30}h>>>=2,f-=2;break;case 14:for(h>>>=7&f,f-=7&f;f<32;){if(0===o)break e;o--,h+=n[s++]<>>16^65535)){e.msg="invalid stored block lengths",r.mode=30;break}if(r.length=65535&h,f=h=0,r.mode=15,6===t)break e;case 15:r.mode=16;case 16:if(c=r.length){if(o>>=5,f-=5,r.ndist=1+(31&h),h>>>=5,f-=5,r.ncode=4+(15&h),h>>>=4,f-=4,286>>=3,f-=3}for(;r.have<19;)r.lens[A[r.have++]]=0;if(r.lencode=r.lendyn,r.lenbits=7,S={bits:r.lenbits},x=R(0,r.lens,0,19,r.lencode,0,r.work,S),r.lenbits=S.bits,x){e.msg="invalid code lengths set",r.mode=30;break}r.have=0,r.mode=19;case 19:for(;r.have>>16&255,v=65535&E,!((_=E>>>24)<=f);){if(0===o)break e;o--,h+=n[s++]<>>=_,f-=_,r.lens[r.have++]=v;else{if(16===v){for(z=_+2;f>>=_,f-=_,0===r.have){e.msg="invalid bit length repeat",r.mode=30;break}k=r.lens[r.have-1],c=3+(3&h),h>>>=2,f-=2}else if(17===v){for(z=_+3;f>>=_)),h>>>=3,f-=3}else{for(z=_+7;f>>=_)),h>>>=7,f-=7}if(r.have+c>r.nlen+r.ndist){e.msg="invalid bit length repeat",r.mode=30;break}for(;c--;)r.lens[r.have++]=k}}if(30===r.mode)break;if(0===r.lens[256]){e.msg="invalid code -- missing end-of-block",r.mode=30;break}if(r.lenbits=9,S={bits:r.lenbits},x=R(D,r.lens,0,r.nlen,r.lencode,0,r.work,S),r.lenbits=S.bits,x){e.msg="invalid literal/lengths set",r.mode=30;break}if(r.distbits=6,r.distcode=r.distdyn,S={bits:r.distbits},x=R(F,r.lens,r.nlen,r.ndist,r.distcode,0,r.work,S),r.distbits=S.bits,x){e.msg="invalid distances set",r.mode=30;break}if(r.mode=20,6===t)break e;case 20:r.mode=21;case 21:if(6<=o&&258<=u){e.next_out=a,e.avail_out=u,e.next_in=s,e.avail_in=o,r.hold=h,r.bits=f,T(e,d),a=e.next_out,i=e.output,u=e.avail_out,s=e.next_in,n=e.input,o=e.avail_in,h=r.hold,f=r.bits,12===r.mode&&(r.back=-1);break}for(r.back=0;g=(E=r.lencode[h&(1<>>16&255,v=65535&E,!((_=E>>>24)<=f);){if(0===o)break e;o--,h+=n[s++]<>b)])>>>16&255,v=65535&E,!(b+(_=E>>>24)<=f);){if(0===o)break e;o--,h+=n[s++]<>>=b,f-=b,r.back+=b}if(h>>>=_,f-=_,r.back+=_,r.length=v,0===g){r.mode=26;break}if(32&g){r.back=-1,r.mode=12;break}if(64&g){e.msg="invalid literal/length code",r.mode=30;break}r.extra=15&g,r.mode=22;case 22:if(r.extra){for(z=r.extra;f>>=r.extra,f-=r.extra,r.back+=r.extra}r.was=r.length,r.mode=23;case 23:for(;g=(E=r.distcode[h&(1<>>16&255,v=65535&E,!((_=E>>>24)<=f);){if(0===o)break e;o--,h+=n[s++]<>b)])>>>16&255,v=65535&E,!(b+(_=E>>>24)<=f);){if(0===o)break e;o--,h+=n[s++]<>>=b,f-=b,r.back+=b}if(h>>>=_,f-=_,r.back+=_,64&g){e.msg="invalid distance code",r.mode=30;break}r.offset=v,r.extra=15&g,r.mode=24;case 24:if(r.extra){for(z=r.extra;f>>=r.extra,f-=r.extra,r.back+=r.extra}if(r.offset>r.dmax){e.msg="invalid distance too far back",r.mode=30;break}r.mode=25;case 25:if(0===u)break e;if(c=d-u,r.offset>c){if((c=r.offset-c)>r.whave&&r.sane){e.msg="invalid distance too far back",r.mode=30;break}p=c>r.wnext?(c-=r.wnext,r.wsize-c):r.wnext-c,c>r.length&&(c=r.length),m=r.window}else m=i,p=a-r.offset,c=r.length;for(uc?(m=T[R+a[b]],A[I+a[b]]):(m=96,0),u=1<>S)+(h-=u)]=p<<24|m<<16|_|0,0!==h;);for(u=1<>=1;if(0!==u?(C&=u-1,C+=u):C=0,b++,0==--O[v]){if(v===y)break;v=t[r+a[b]]}if(k>>7)]}function x(e,t){e.pending_buf[e.pending++]=255&t,e.pending_buf[e.pending++]=t>>>8&255}function S(e,t,r){e.bi_valid>i-r?(e.bi_buf|=t<>i-e.bi_valid,e.bi_valid+=r-i):(e.bi_buf|=t<>>=1,r<<=1,0<--t;);return r>>>1}function C(e,t,r){var n,i,s=new Array(_+1),a=0;for(n=1;n<=_;n++)s[n]=a=a+r[n-1]<<1;for(i=0;i<=t;i++){var o=e[2*i+1];0!==o&&(e[2*i]=E(s[o]++,o))}}function A(e){var t;for(t=0;t<286;t++)e.dyn_ltree[2*t]=0;for(t=0;t<30;t++)e.dyn_dtree[2*t]=0;for(t=0;t<19;t++)e.bl_tree[2*t]=0;e.dyn_ltree[512]=1,e.opt_len=e.static_len=0,e.last_lit=e.matches=0}function I(e){8>1;1<=r;r--)B(e,s,r);for(i=u;r=e.heap[1],e.heap[1]=e.heap[e.heap_len--],B(e,s,1),n=e.heap[1],e.heap[--e.heap_max]=r,e.heap[--e.heap_max]=n,s[2*i]=s[2*r]+s[2*n],e.depth[i]=(e.depth[r]>=e.depth[n]?e.depth[r]:e.depth[n])+1,s[2*r+1]=s[2*n+1]=i,e.heap[1]=i++,B(e,s,1),2<=e.heap_len;);e.heap[--e.heap_max]=e.heap[1],function(e,t){var r,n,i,s,a,o,u=t.dyn_tree,h=t.max_code,f=t.stat_desc.static_tree,l=t.stat_desc.has_stree,d=t.stat_desc.extra_bits,c=t.stat_desc.extra_base,p=t.stat_desc.max_length,m=0;for(s=0;s<=_;s++)e.bl_count[s]=0;for(u[2*e.heap[e.heap_max]+1]=0,r=e.heap_max+1;r<573;r++)p<(s=u[2*u[2*(n=e.heap[r])+1]+1]+1)&&(s=p,m++),u[2*n+1]=s,h>=7;n<30;n++)for(w[n]=i<<7,e=0;e<1<>>=1)if(1&r&&0!==e.dyn_ltree[2*t])return 0;if(0!==e.dyn_ltree[18]||0!==e.dyn_ltree[20]||0!==e.dyn_ltree[26])return 1;for(t=32;t<256;t++)if(0!==e.dyn_ltree[2*t])return 1;return 0}(e)),R(e,e.l_desc),R(e,e.d_desc),a=function(e){var t;for(D(e,e.dyn_ltree,e.l_desc.max_code),D(e,e.dyn_dtree,e.d_desc.max_code),R(e,e.bl_desc),t=18;3<=t&&0===e.bl_tree[2*f[t]+1];t--);return e.opt_len+=3*(t+1)+5+5+4,t}(e),i=e.opt_len+3+7>>>3,(s=e.static_len+3+7>>>3)<=i&&(i=s)):i=s=r+5,r+4<=i&&-1!==t?U(e,t,r,n):4===e.strategy||s===i?(S(e,2+(n?1:0),3),T(e,l,d)):(S(e,4+(n?1:0),3),function(e,t,r,n){var i;for(S(e,t-257,5),S(e,r-1,5),S(e,n-4,4),i=0;i>>8&255,e.pending_buf[e.d_buf+2*e.last_lit+1]=255&t,e.pending_buf[e.l_buf+e.last_lit]=255&r,e.last_lit++,0===t?e.dyn_ltree[2*r]++:(e.matches++,t--,e.dyn_ltree[2*(p[r]+256+1)]++,e.dyn_dtree[2*k(t)]++),e.last_lit===e.lit_bufsize-1},r._tr_align=function(e){var t;S(e,2,3),z(e,256,l),16===(t=e).bi_valid?(x(t,t.bi_buf),t.bi_buf=0,t.bi_valid=0):8<=t.bi_valid&&(t.pending_buf[t.pending++]=255&t.bi_buf,t.bi_buf>>=8,t.bi_valid-=8)}},{"../utils/common":41}],53:[function(e,t,r){"use strict";t.exports=function(){this.input=null,this.next_in=0,this.avail_in=0,this.total_in=0,this.output=null,this.next_out=0,this.avail_out=0,this.total_out=0,this.msg="",this.state=null,this.data_type=2,this.adler=0}},{}],54:[function(e,t,r){"use strict";t.exports="function"==typeof setImmediate?setImmediate:function(){var e=[].slice.apply(arguments);e.splice(1,0,0),setTimeout.apply(null,e)}},{}]},{},[10])(10)})}).call(this,void 0!==r?r:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}]},{},[1])(1)})}).call(this,void 0!==r?r:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}]},{},[1])(1)})}).call(this,void 0!==r?r:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}]},{},[1])(1)})}).call(this,void 0!==r?r:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}]},{},[1])(1)})}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}]},{},[1])(1)});
\ No newline at end of file
diff --git a/libs/lineclip.js b/libs/lineclip.js
deleted file mode 100644
index b43da33b..00000000
--- a/libs/lineclip.js
+++ /dev/null
@@ -1,103 +0,0 @@
-'use strict';
-// lineclip by mourner, https://github.com/mapbox/lineclip
-// Cohen-Sutherland line clippign algorithm, adapted to efficiently
-// handle polylines rather than just segments
-function lineclip(points, bbox, result) {
- var len = points.length,
- codeA = bitCode(points[0], bbox),
- part = [],
- i, a, b, codeB, lastCode;
- if (!result) result = [];
-
- for (i = 1; i < len; i++) {
- a = points[i - 1];
- b = points[i];
- codeB = lastCode = bitCode(b, bbox);
-
- while (true) {
- if (!(codeA | codeB)) { // accept
- part.push(a);
-
- if (codeB !== lastCode) { // segment went outside
- part.push(b);
- if (i < len - 1) { // start a new line
- result.push(part);
- part = [];
- }
- } else if (i === len - 1) {
- part.push(b);
- }
- break;
-
- } else if (codeA & codeB) { // trivial reject
- break;
- } else if (codeA) { // a outside, intersect with clip edge
- a = intersect(a, b, codeA, bbox);
- codeA = bitCode(a, bbox);
- } else { // b outside
- b = intersect(a, b, codeB, bbox);
- codeB = bitCode(b, bbox);
- }
- }
- codeA = lastCode;
- }
-
- if (part.length) result.push(part);
-
- return result;
-}
-
-// Sutherland-Hodgeman polygon clipping algorithm
-function polygonclip(points, bbox, secure = 0) {
- var result, edge, prev, prevInside, inter, i, p, inside;
-
- // clip against each side of the clip rectangle
- for (edge = 1; edge <= 8; edge *= 2) {
- result = [];
- prev = points[points.length-1];
- prevInside = !(bitCode(prev, bbox) & edge);
-
- for (i = 0; i < points.length; i++) {
- p = points[i];
- inside = !(bitCode(p, bbox) & edge);
- inter = inside !== prevInside; // segment goes through the clip window
-
- const pi = intersect(prev, p, edge, bbox);
- if (inter) result.push(pi); // add an intersection point
- if (secure && inter) result.push(pi, pi); // add additional intersection points to secure correct d3 curve
- if (inside) result.push(p); // add a point if it's inside
-
- prev = p;
- prevInside = inside;
- }
- points = result;
- if (!points.length) break;
- }
- //result.forEach(p => debug.append("circle").attr("cx", p[0]).attr("cy", p[1]).attr("r", .6).attr("fill", "red"));
- return result;
-}
-
-// intersect a segment against one of the 4 lines that make up the bbox
-function intersect(a, b, edge, bbox) {
- return edge & 8 ? [a[0] + (b[0] - a[0]) * (bbox[3] - a[1]) / (b[1] - a[1]), bbox[3]] : // top
- edge & 4 ? [a[0] + (b[0] - a[0]) * (bbox[1] - a[1]) / (b[1] - a[1]), bbox[1]] : // bottom
- edge & 2 ? [bbox[2], a[1] + (b[1] - a[1]) * (bbox[2] - a[0]) / (b[0] - a[0])] : // right
- edge & 1 ? [bbox[0], a[1] + (b[1] - a[1]) * (bbox[0] - a[0]) / (b[0] - a[0])] : null; // left
-}
-
-// bit code reflects the point position relative to the bbox:
-// left mid right
-// top 1001 1000 1010
-// mid 0001 0000 0010
-// bottom 0101 0100 0110
-function bitCode(p, bbox) {
- var code = 0;
-
- if (p[0] < bbox[0]) code |= 1; // left
- else if (p[0] > bbox[2]) code |= 2; // right
-
- if (p[1] < bbox[1]) code |= 4; // bottom
- else if (p[1] > bbox[3]) code |= 8; // top
-
- return code;
-}
\ No newline at end of file
diff --git a/libs/lineclip.min.js b/libs/lineclip.min.js
new file mode 100644
index 00000000..d1796476
--- /dev/null
+++ b/libs/lineclip.min.js
@@ -0,0 +1,2 @@
+// lineclip by mourner, https://github.com/mapbox/lineclip
+"use strict";function lineclip(t,e,n){var r,i,u,o,s,h=t.length,c=bitCode(t[0],e),f=[];for(n=n||[],r=1;re[2]&&(n|=2),t[1]e[3]&&(n|=8),n}
\ No newline at end of file
diff --git a/libs/loopsubdivison.min.js b/libs/loopsubdivison.min.js
new file mode 100644
index 00000000..b9482517
--- /dev/null
+++ b/libs/loopsubdivison.min.js
@@ -0,0 +1,132 @@
+/**
+ * @description Loop Subdivision Surface
+ * @about Smooth subdivision surface modifier for use with three.js BufferGeometry.
+ * @author Stephens Nunnally <@stevinz>
+ * @license MIT - Copyright (c) 2022 Stephens Nunnally
+ * @source https://github.com/stevinz/three-subdivide
+ */
+/////////////////////////////////////////////////////////////////////////////////////
+//
+// Functions
+// modify Applies Loop subdivision to BufferGeometry, returns new BufferGeometry
+// edgeSplit Splits all triangles at edges shared by coplanar triangles
+// flat One iteration of Loop subdivision, without point averaging
+// smooth One iteration of Loop subdivision, with point averaging
+//
+// Info
+// This modifier uses the Loop (Charles Loop, 1987) subdivision surface algorithm to smooth
+// modern three.js BufferGeometry.
+//
+// At one point, three.js included a subdivision surface modifier in the extended examples (see bottom
+// of file for links), it was removed in r125. The modifier was originally based on the Catmull-Clark
+// algorithm, which works best for geometry with convex coplanar n-gon faces. In three.js r60 the modifier
+// was changed to utilize the Loop algorithm. The Loop algorithm was designed to work better with triangle
+// based meshes.
+//
+// The Loop algorithm, however, doesn't always provide uniform results as the vertices are
+// skewed toward the most used vertex positions. A triangle based box (e.g. BoxGeometry for example) will
+// tend to favor the corners. To alleviate this issue, this implementation includes an initial pass to split
+// coplanar faces at their shared edges. It starts by splitting along the longest shared edge first, and then
+// from that midpoint it splits to any remaining coplanar shared edges.
+//
+// Also by default, this implementation inserts new uv coordinates, but does not average them using the Loop
+// algorithm. In some cases (often in flat geometries) this will produce undesired results, a
+// noticeable tearing will occur. In such cases, try passing 'uvSmooth' as true to enable uv averaging.
+//
+// Note(s)
+// - This modifier returns a new BufferGeometry instance, it does not dispose() of the old geometry.
+//
+// - This modifier returns a NonIndexed geometry. An Indexed geometry can be created by using the
+// BufferGeometryUtils.mergeVertices() function, see:
+// https://threejs.org/docs/?q=buffer#examples/en/utils/BufferGeometryUtils.mergeVertices
+//
+// - This modifier works best with geometry whose triangles share edges AND edge vertices. See diagram below.
+//
+// OKAY NOT OKAY
+// O O
+// /|\ / \
+// / | \ / \
+// / | \ / \
+// O---O---O O---O---O
+// \ | / \ | /
+// \ | / \ | /
+// \|/ \|/
+// O O
+//
+// Reference(s)
+// - Subdivision Surfaces
+// https://www.microsoft.com/en-us/research/wp-content/uploads/2016/02/thesis-10.pdf
+// https://en.wikipedia.org/wiki/Loop_subdivision_surface
+// https://cseweb.ucsd.edu/~alchern/teaching/cse167_fa21/6-3Surfaces.pdf
+//
+// - Original three.js SubdivisionModifier, r124 (Loop)
+// https://github.com/mrdoob/three.js/blob/r124/examples/jsm/modifiers/SubdivisionModifier.js
+//
+// - Original three.js SubdivisionModifier, r59 (Catmull-Clark)
+// https://github.com/mrdoob/three.js/blob/r59/examples/js/modifiers/SubdivisionModifier.js
+//
+/////////////////////////////////////////////////////////////////////////////////////
+
+/**
+ * @description Loop Subdivision Surface
+ * @about Smooth subdivision surface modifier for use with three.js BufferGeometry.
+ * @author Stephens Nunnally <@stevinz>
+ * @license MIT - Copyright (c) 2022 Stephens Nunnally
+ * @source https://github.com/stevinz/three-subdivide
+ */
+
+window.loopSubdivision={};(()=>{const POSITION_DECIMALS=2;const _average=new THREE.Vector3();const _center=new THREE.Vector3();const _midpoint=new THREE.Vector3();const _normal=new THREE.Vector3();const _temp=new THREE.Vector3();const _vector0=new THREE.Vector3();const _vector1=new THREE.Vector3();const _vector2=new THREE.Vector3();const _vec0to1=new THREE.Vector3();const _vec1to2=new THREE.Vector3();const _vec2to0=new THREE.Vector3();const _position=[new THREE.Vector3(),new THREE.Vector3(),new THREE.Vector3(),];const _vertex=[new THREE.Vector3(),new THREE.Vector3(),new THREE.Vector3(),];const _triangle=new THREE.Triangle();function modify(bufferGeometry,iterations=1,params={}){if(arguments.length>3)console.warn(`modify() now uses a parameter object. See readme for more info!`);if(typeof params!=='object')params={};if(params.split===undefined)params.split=!0;if(params.uvSmooth===undefined)params.uvSmooth=!1;if(params.preserveEdges===undefined)params.preserveEdges=!1;if(params.flatOnly===undefined)params.flatOnly=!1;if(params.maxTriangles===undefined)params.maxTriangles=Infinity;if(!verifyGeometry(bufferGeometry))return bufferGeometry;let modifiedGeometry=bufferGeometry.clone();if(params.split){const splitGeometry=edgeSplit(modifiedGeometry)
+modifiedGeometry.dispose();modifiedGeometry=splitGeometry}
+for(let i=0;i{subdividedGeometry.addGroup(group.start*4,group.count*4,group.materialIndex)});modifiedGeometry.dispose();modifiedGeometry=subdividedGeometry}}
+return modifiedGeometry}
+window.loopSubdivision.modify=modify;function edgeSplit(geometry){if(!verifyGeometry(geometry))return geometry;const existing=(geometry.index!==null)?geometry.toNonIndexed():geometry.clone();const split=new THREE.BufferGeometry();const attributeList=gatherAttributes(existing);const vertexCount=existing.attributes.position.count;const posAttribute=existing.getAttribute('position');const norAttribute=existing.getAttribute('normal');const edgeHashToTriangle={};const triangleEdgeHashes=[];const edgeLength={};const triangleExist=[];for(let i=0;i{const attribute=existing.getAttribute(attributeName);if(!attribute)return;const floatArray=splitAttribute(attribute,attributeName);split.setAttribute(attributeName,new THREE.BufferAttribute(floatArray,attribute.itemSize))});const morphAttributes=existing.morphAttributes;for(const attributeName in morphAttributes){const array=[];const morphAttribute=morphAttributes[attributeName];for(let i=0,l=morphAttribute.length;i0);let groupStart=undefined,groupMaterial=undefined;let index=0;let skipped=0;let step=attribute.itemSize;for(let i=0;ilength1to2||edgeCount1to2<=1)&&(length0to1>length2to0||edgeCount2to0<=1)&&edgeCount0to1>1){_center.copy(_vector0).add(_vector1).divideScalar(2.0);if(edgeCount2to0>1){_midpoint.copy(_vector2).add(_vector0).divideScalar(2.0);setTriangle(floatArray,index,step,_vector0,_center,_midpoint);index+=(step*3);setTriangle(floatArray,index,step,_center,_vector2,_midpoint);index+=(step*3)}else{setTriangle(floatArray,index,step,_vector0,_center,_vector2);index+=(step*3)}
+if(edgeCount1to2>1){_midpoint.copy(_vector1).add(_vector2).divideScalar(2.0);setTriangle(floatArray,index,step,_center,_vector1,_midpoint);index+=(step*3);setTriangle(floatArray,index,step,_midpoint,_vector2,_center);index+=(step*3)}else{setTriangle(floatArray,index,step,_vector1,_vector2,_center);index+=(step*3)}}else if((length1to2>length2to0||edgeCount2to0<=1)&&edgeCount1to2>1){_center.copy(_vector1).add(_vector2).divideScalar(2.0);if(edgeCount0to1>1){_midpoint.copy(_vector0).add(_vector1).divideScalar(2.0);setTriangle(floatArray,index,step,_center,_midpoint,_vector1);index+=(step*3);setTriangle(floatArray,index,step,_midpoint,_center,_vector0);index+=(step*3)}else{setTriangle(floatArray,index,step,_vector1,_center,_vector0);index+=(step*3)}
+if(edgeCount2to0>1){_midpoint.copy(_vector2).add(_vector0).divideScalar(2.0);setTriangle(floatArray,index,step,_center,_vector2,_midpoint);index+=(step*3);setTriangle(floatArray,index,step,_midpoint,_vector0,_center);index+=(step*3)}else{setTriangle(floatArray,index,step,_vector2,_vector0,_center);index+=(step*3)}}else if(edgeCount2to0>1){_center.copy(_vector2).add(_vector0).divideScalar(2.0);if(edgeCount1to2>1){_midpoint.copy(_vector1).add(_vector2).divideScalar(2.0);setTriangle(floatArray,index,step,_vector2,_center,_midpoint);index+=(step*3);setTriangle(floatArray,index,step,_center,_vector1,_midpoint);index+=(step*3)}else{setTriangle(floatArray,index,step,_vector2,_center,_vector1);index+=(step*3)}
+if(edgeCount0to1>1){_midpoint.copy(_vector0).add(_vector1).divideScalar(2.0);setTriangle(floatArray,index,step,_vector0,_midpoint,_center);index+=(step*3);setTriangle(floatArray,index,step,_midpoint,_vector1,_center);index+=(step*3)}else{setTriangle(floatArray,index,step,_vector0,_vector1,_center);index+=(step*3)}}else{setTriangle(floatArray,index,step,_vector0,_vector1,_vector2);index+=(step*3)}}
+if(processGroups){existing.groups.forEach((group)=>{if(group.start===(i-skipped)){if(groupStart!==undefined&&groupMaterial!==undefined){split.addGroup(groupStart,loopStartIndex-groupStart,groupMaterial)}
+groupStart=loopStartIndex;groupMaterial=group.materialIndex}})}
+skipped=0}
+const reducedCount=(index*3)/step;const reducedArray=new attribute.array.constructor(reducedCount);for(let i=0;i{const attribute=existing.getAttribute(attributeName);if(!attribute)return;loop.setAttribute(attributeName,flatAttribute(attribute,vertexCount))});const morphAttributes=existing.morphAttributes;for(const attributeName in morphAttributes){const array=[];const morphAttribute=morphAttributes[attributeName];for(let i=0,l=morphAttribute.length;i{const existingAttribute=existing.getAttribute(attributeName);const flatAttribute=flatGeometry.getAttribute(attributeName);if(existingAttribute===undefined||flatAttribute===undefined)return;const floatArray=subdivideAttribute(attributeName,existingAttribute,flatAttribute);loop.setAttribute(attributeName,new THREE.BufferAttribute(floatArray,flatAttribute.itemSize))});const morphAttributes=existing.morphAttributes;for(const attributeName in morphAttributes){const array=[];const morphAttribute=morphAttributes[attributeName];for(let i=0,l=morphAttribute.length;i{_average.fromBufferAttribute(flatAttribute,positionIndex);_average.multiplyScalar(beta);_vertex[v].add(_average)})}else{_vertex[v].fromBufferAttribute(flatAttribute,i+v);_position[v].fromBufferAttribute(flatPosition,i+v);const positionHash=hashFromVector(_position[v]);const neighbors=existingNeighbors[positionHash];const opposites=flatOpposites[positionHash];if(neighbors){if(params.preserveEdges){const edgeSet=existingEdges[positionHash];let hasPair=!0;for(const edgeHash of edgeSet){if(flatOpposites[edgeHash].length%2!==0)hasPair=!1}
+if(!hasPair)continue}
+const k=Object.keys(neighbors).length;const beta=1/k*((5/8)-Math.pow((3/8)+(1/4)*Math.cos(2*Math.PI/k),2));const startWeight=1.0-(beta*k);_vertex[v].multiplyScalar(startWeight);for(let neighborHash in neighbors){const neighborIndices=neighbors[neighborHash];_average.set(0,0,0);for(let j=0;j{_average.fromBufferAttribute(existingAttribute,oppositeIndex);_average.multiplyScalar(beta);_vertex[v].add(_average)})}}}
+setTriangle(floatArray,index,flatAttribute.itemSize,_vertex[0],_vertex[1],_vertex[2]);index+=(flatAttribute.itemSize*3)}
+return floatArray}}
+const _positionShift=Math.pow(10,POSITION_DECIMALS);function fuzzy(a,b,tolerance=0.00001){return((a<(b+tolerance))&&(a>(b-tolerance)))}
+function hashFromNumber(num,shift=_positionShift){let roundedNumber=round(num*shift);if(roundedNumber==0)roundedNumber=0;return `${roundedNumber}`}
+function hashFromVector(vector,shift=_positionShift){return `${hashFromNumber(vector.x, shift)},${hashFromNumber(vector.y, shift)},${hashFromNumber(vector.z, shift)}`}
+function round(x){return(x+((x>0)?0.5:-0.5))<<0}
+function calcNormal(target,vec1,vec2,vec3){_temp.subVectors(vec1,vec2);target.subVectors(vec2,vec3);target.cross(_temp).normalize()}
+function gatherAttributes(geometry){const desired=['position','normal','uv'];const contains=Object.keys(geometry.attributes);const attributeList=Array.from(new Set(desired.concat(contains)));return attributeList}
+function setTriangle(positions,index,step,vec0,vec1,vec2){if(step>=1){positions[index+0+(step*0)]=vec0.x;positions[index+0+(step*1)]=vec1.x;positions[index+0+(step*2)]=vec2.x}
+if(step>=2){positions[index+1+(step*0)]=vec0.y;positions[index+1+(step*1)]=vec1.y;positions[index+1+(step*2)]=vec2.y}
+if(step>=3){positions[index+2+(step*0)]=vec0.z;positions[index+2+(step*1)]=vec1.z;positions[index+2+(step*2)]=vec2.z}
+if(step>=4){positions[index+3+(step*0)]=vec0.w;positions[index+3+(step*1)]=vec1.w;positions[index+3+(step*2)]=vec2.w}}
+function verifyGeometry(geometry){if(geometry===undefined){console.warn(`window.loopSubdivision: Geometry provided is undefined`);return!1}
+if(!geometry.isBufferGeometry){console.warn(`window.loopSubdivision: Geometry provided is not 'BufferGeometry' type`);return!1}
+if(geometry.attributes.position===undefined){console.warn(`window.loopSubdivision: Geometry provided missing required 'position' attribute`);return!1}
+if(geometry.attributes.normal===undefined){geometry.computeVertexNormals()}
+return!0}})()
\ No newline at end of file
diff --git a/libs/objexporter.min.js b/libs/objexporter.min.js
new file mode 100644
index 00000000..24751dfc
--- /dev/null
+++ b/libs/objexporter.min.js
@@ -0,0 +1,25 @@
+(function(){class OBJExporter{parse(object){let output='';let indexVertex=0;let indexVertexUvs=0;let indexNormals=0;const vertex=new THREE.Vector3();const color=new THREE.Color();const normal=new THREE.Vector3();const uv=new THREE.Vector2();const face=[];function parseMesh(mesh){let nbVertex=0;let nbNormals=0;let nbVertexUvs=0;const geometry=mesh.geometry;const normalMatrixWorld=new THREE.Matrix3();if(geometry.isBufferGeometry!==!0){throw new Error('THREE.OBJExporter: Geometry is not of type THREE.BufferGeometry.')}
+const vertices=geometry.getAttribute('position');const normals=geometry.getAttribute('normal');const uvs=geometry.getAttribute('uv');const indices=geometry.getIndex();output+='o '+mesh.name+'\n';if(mesh.material&&mesh.material.name){output+='usemtl '+mesh.material.name+'\n'}
+if(vertices!==undefined){for(let i=0,l=vertices.count;ih||8*(1-c.dot(s.object.quaternion))>h)&&(s.dispatchEvent(r),i.copy(s.object.position),c.copy(s.object.quaternion),O=!1,!0)}),this.dispose=function(){s.domElement.removeEventListener("contextmenu",$,!1),s.domElement.removeEventListener("mousedown",I,!1),s.domElement.removeEventListener("wheel",K,!1),s.domElement.removeEventListener("touchstart",q,!1),s.domElement.removeEventListener("touchend",J,!1),s.domElement.removeEventListener("touchmove",Q,!1),document.removeEventListener("mousemove",B,!1),document.removeEventListener("mouseup",G,!1),window.removeEventListener("keydown",W,!1)};var s=this,r={type:"change"},u={type:"start"},E={type:"end"},l={NONE:-1,ROTATE:0,DOLLY:1,PAN:2,TOUCH_ROTATE:3,TOUCH_PAN:4,TOUCH_DOLLY_PAN:5,TOUCH_DOLLY_ROTATE:6},m=l.NONE,h=1e-6,p=new THREE.Spherical,d=new THREE.Spherical,b=1,T=new THREE.Vector3,O=!1,f=new THREE.Vector2,R=new THREE.Vector2,g=new THREE.Vector2,H=new THREE.Vector2,v=new THREE.Vector2,y=new THREE.Vector2,P=new THREE.Vector2,N=new THREE.Vector2,A=new THREE.Vector2;function L(){return Math.pow(.95,s.zoomSpeed)}function w(e){d.theta-=e}function j(e){d.phi-=e}var M,C=(M=new THREE.Vector3,function(e,t){M.setFromMatrixColumn(t,0),M.multiplyScalar(-e),T.add(M)}),S=function(){var e=new THREE.Vector3;return function(t,o){!0===s.screenSpacePanning?e.setFromMatrixColumn(o,1):(e.setFromMatrixColumn(o,0),e.crossVectors(s.object.up,e)),e.multiplyScalar(t),T.add(e)}}(),k=function(){var e=new THREE.Vector3;return function(t,o){var n=s.domElement;if(s.object.isPerspectiveCamera){var a=s.object.position;e.copy(a).sub(s.target);var i=e.length();i*=Math.tan(s.object.fov/2*Math.PI/180),C(2*t*i/n.clientHeight,s.object.matrix),S(2*o*i/n.clientHeight,s.object.matrix)}else s.object.isOrthographicCamera?(C(t*(s.object.right-s.object.left)/s.object.zoom/n.clientWidth,s.object.matrix),S(o*(s.object.top-s.object.bottom)/s.object.zoom/n.clientHeight,s.object.matrix)):(console.warn("WARNING: OrbitControls.js encountered an unknown camera type - pan disabled."),s.enablePan=!1)}}();function Y(e){s.object.isPerspectiveCamera?b/=e:s.object.isOrthographicCamera?(s.object.zoom=Math.max(s.minZoom,Math.min(s.maxZoom,s.object.zoom*e)),s.object.updateProjectionMatrix(),O=!0):(console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled."),s.enableZoom=!1)}function D(e){s.object.isPerspectiveCamera?b*=e:s.object.isOrthographicCamera?(s.object.zoom=Math.max(s.minZoom,Math.min(s.maxZoom,s.object.zoom/e)),s.object.updateProjectionMatrix(),O=!0):(console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled."),s.enableZoom=!1)}function U(e){f.set(e.clientX,e.clientY)}function x(e){H.set(e.clientX,e.clientY)}function V(e){if(1==e.touches.length)f.set(e.touches[0].pageX,e.touches[0].pageY);else{var t=.5*(e.touches[0].pageX+e.touches[1].pageX),o=.5*(e.touches[0].pageY+e.touches[1].pageY);f.set(t,o)}}function z(e){if(1==e.touches.length)H.set(e.touches[0].pageX,e.touches[0].pageY);else{var t=.5*(e.touches[0].pageX+e.touches[1].pageX),o=.5*(e.touches[0].pageY+e.touches[1].pageY);H.set(t,o)}}function X(e){var t=e.touches[0].pageX-e.touches[1].pageX,o=e.touches[0].pageY-e.touches[1].pageY,n=Math.sqrt(t*t+o*o);P.set(0,n)}function _(e){if(1==e.touches.length)R.set(e.touches[0].pageX,e.touches[0].pageY);else{var t=.5*(e.touches[0].pageX+e.touches[1].pageX),o=.5*(e.touches[0].pageY+e.touches[1].pageY);R.set(t,o)}g.subVectors(R,f).multiplyScalar(s.rotateSpeed);var n=s.domElement;w(2*Math.PI*g.x/n.clientHeight),j(2*Math.PI*g.y/n.clientHeight),f.copy(R)}function Z(e){if(1==e.touches.length)v.set(e.touches[0].pageX,e.touches[0].pageY);else{var t=.5*(e.touches[0].pageX+e.touches[1].pageX),o=.5*(e.touches[0].pageY+e.touches[1].pageY);v.set(t,o)}y.subVectors(v,H).multiplyScalar(s.panSpeed),k(y.x,y.y),H.copy(v)}function F(e){var t=e.touches[0].pageX-e.touches[1].pageX,o=e.touches[0].pageY-e.touches[1].pageY,n=Math.sqrt(t*t+o*o);N.set(0,n),A.set(0,Math.pow(N.y/P.y,s.zoomSpeed)),Y(A.y),P.copy(N)}function I(e){if(!1!==s.enabled){switch(e.preventDefault(),s.domElement.focus?s.domElement.focus():window.focus(),e.button){case 0:switch(s.mouseButtons.LEFT){case THREE.MOUSE.ROTATE:if(e.ctrlKey||e.metaKey||e.shiftKey){if(!1===s.enablePan)return;x(e),m=l.PAN}else{if(!1===s.enableRotate)return;U(e),m=l.ROTATE}break;case THREE.MOUSE.PAN:if(e.ctrlKey||e.metaKey||e.shiftKey){if(!1===s.enableRotate)return;U(e),m=l.ROTATE}else{if(!1===s.enablePan)return;x(e),m=l.PAN}break;default:m=l.NONE}break;case 1:switch(s.mouseButtons.MIDDLE){case THREE.MOUSE.DOLLY:if(!1===s.enableZoom)return;!function(e){P.set(e.clientX,e.clientY)}(e),m=l.DOLLY;break;default:m=l.NONE}break;case 2:switch(s.mouseButtons.RIGHT){case THREE.MOUSE.ROTATE:if(!1===s.enableRotate)return;U(e),m=l.ROTATE;break;case THREE.MOUSE.PAN:if(!1===s.enablePan)return;x(e),m=l.PAN;break;default:m=l.NONE}}m!==l.NONE&&(document.addEventListener("mousemove",B,!1),document.addEventListener("mouseup",G,!1),s.dispatchEvent(u))}}function B(e){if(!1!==s.enabled)switch(e.preventDefault(),m){case l.ROTATE:if(!1===s.enableRotate)return;!function(e){R.set(e.clientX,e.clientY),g.subVectors(R,f).multiplyScalar(s.rotateSpeed);var t=s.domElement;w(2*Math.PI*g.x/t.clientHeight),j(2*Math.PI*g.y/t.clientHeight),f.copy(R),s.update()}(e);break;case l.DOLLY:if(!1===s.enableZoom)return;!function(e){N.set(e.clientX,e.clientY),A.subVectors(N,P),A.y>0?Y(L()):A.y<0&&D(L()),P.copy(N),s.update()}(e);break;case l.PAN:if(!1===s.enablePan)return;!function(e){v.set(e.clientX,e.clientY),y.subVectors(v,H).multiplyScalar(s.panSpeed),k(y.x,y.y),H.copy(v),s.update()}(e)}}function G(e){!1!==s.enabled&&(document.removeEventListener("mousemove",B,!1),document.removeEventListener("mouseup",G,!1),s.dispatchEvent(E),m=l.NONE)}function K(e){!1===s.enabled||!1===s.enableZoom||m!==l.NONE&&m!==l.ROTATE||(e.preventDefault(),e.stopPropagation(),s.dispatchEvent(u),function(e){e.deltaY<0?D(L()):e.deltaY>0&&Y(L()),s.update()}(e),s.dispatchEvent(E))}function W(e){!1!==s.enabled&&!1!==s.enableKeys&&!1!==s.enablePan&&function(e){var t=!1;switch(e.keyCode){case s.keys.UP:k(0,s.keyPanSpeed),t=!0;break;case s.keys.BOTTOM:k(0,-s.keyPanSpeed),t=!0;break;case s.keys.LEFT:k(s.keyPanSpeed,0),t=!0;break;case s.keys.RIGHT:k(-s.keyPanSpeed,0),t=!0}t&&(e.preventDefault(),s.update())}(e)}function q(e){if(!1!==s.enabled){switch(e.preventDefault(),e.touches.length){case 1:switch(s.touches.ONE){case THREE.TOUCH.ROTATE:if(!1===s.enableRotate)return;V(e),m=l.TOUCH_ROTATE;break;case THREE.TOUCH.PAN:if(!1===s.enablePan)return;z(e),m=l.TOUCH_PAN;break;default:m=l.NONE}break;case 2:switch(s.touches.TWO){case THREE.TOUCH.DOLLY_PAN:if(!1===s.enableZoom&&!1===s.enablePan)return;!function(e){s.enableZoom&&X(e),s.enablePan&&z(e)}(e),m=l.TOUCH_DOLLY_PAN;break;case THREE.TOUCH.DOLLY_ROTATE:if(!1===s.enableZoom&&!1===s.enableRotate)return;!function(e){s.enableZoom&&X(e),s.enableRotate&&V(e)}(e),m=l.TOUCH_DOLLY_ROTATE;break;default:m=l.NONE}break;default:m=l.NONE}m!==l.NONE&&s.dispatchEvent(u)}}function Q(e){if(!1!==s.enabled)switch(e.preventDefault(),e.stopPropagation(),m){case l.TOUCH_ROTATE:if(!1===s.enableRotate)return;_(e),s.update();break;case l.TOUCH_PAN:if(!1===s.enablePan)return;Z(e),s.update();break;case l.TOUCH_DOLLY_PAN:if(!1===s.enableZoom&&!1===s.enablePan)return;!function(e){s.enableZoom&&F(e),s.enablePan&&Z(e)}(e),s.update();break;case l.TOUCH_DOLLY_ROTATE:if(!1===s.enableZoom&&!1===s.enableRotate)return;!function(e){s.enableZoom&&F(e),s.enableRotate&&_(e)}(e),s.update();break;default:m=l.NONE}}function J(e){!1!==s.enabled&&(s.dispatchEvent(E),m=l.NONE)}function $(e){!1!==s.enabled&&e.preventDefault()}s.domElement.addEventListener("contextmenu",$,!1),s.domElement.addEventListener("mousedown",I,!1),s.domElement.addEventListener("wheel",K,!1),s.domElement.addEventListener("touchstart",q,!1),s.domElement.addEventListener("touchend",J,!1),s.domElement.addEventListener("touchmove",Q,!1),window.addEventListener("keydown",W,!1),this.update()},THREE.OrbitControls.prototype=Object.create(THREE.EventDispatcher.prototype),THREE.OrbitControls.prototype.constructor=THREE.OrbitControls,THREE.MapControls=function(e,t){THREE.OrbitControls.call(this,e,t),this.mouseButtons.LEFT=THREE.MOUSE.PAN,this.mouseButtons.RIGHT=THREE.MOUSE.ROTATE,this.touches.ONE=THREE.TOUCH.PAN,this.touches.TWO=THREE.TOUCH.DOLLY_ROTATE},THREE.MapControls.prototype=Object.create(THREE.EventDispatcher.prototype),THREE.MapControls.prototype.constructor=THREE.MapControls;
\ No newline at end of file
+!function(){let e={type:"change"},t={type:"start"},n={type:"end"};class o extends THREE.EventDispatcher{constructor(o,a){super(),void 0===a&&console.warn('THREE.OrbitControls: The second parameter "domElement" is now mandatory.'),a===document&&console.error('THREE.OrbitControls: "document" should not be used as the target "domElement". Please use "renderer.domElement" instead.'),this.object=o,this.domElement=a,this.domElement.style.touchAction="none",this.enabled=!0,this.target=new THREE.Vector3,this.minDistance=0,this.maxDistance=1/0,this.minZoom=0,this.maxZoom=1/0,this.minPolarAngle=0,this.maxPolarAngle=Math.PI,this.minAzimuthAngle=-1/0,this.maxAzimuthAngle=1/0,this.enableDamping=!1,this.dampingFactor=.05,this.enableZoom=!0,this.zoomSpeed=1,this.enableRotate=!0,this.rotateSpeed=1,this.enablePan=!0,this.panSpeed=1,this.screenSpacePanning=!0,this.keyPanSpeed=7,this.autoRotate=!1,this.autoRotateSpeed=2,this.keys={LEFT:"ArrowLeft",UP:"ArrowUp",RIGHT:"ArrowRight",BOTTOM:"ArrowDown"},this.mouseButtons={LEFT:THREE.MOUSE.ROTATE,MIDDLE:THREE.MOUSE.DOLLY,RIGHT:THREE.MOUSE.PAN},this.touches={ONE:THREE.TOUCH.ROTATE,TWO:THREE.TOUCH.DOLLY_PAN},this.target0=this.target.clone(),this.position0=this.object.position.clone(),this.zoom0=this.object.zoom,this._domElementKeyEvents=null,this.getPolarAngle=function(){return l.phi},this.getAzimuthalAngle=function(){return l.theta},this.getDistance=function(){return this.object.position.distanceTo(this.target)},this.listenToKeyEvents=function(e){e.addEventListener("keydown",F),this._domElementKeyEvents=e},this.saveState=function(){i.target0.copy(i.target),i.position0.copy(i.object.position),i.zoom0=i.object.zoom},this.reset=function(){i.target.copy(i.target0),i.object.position.copy(i.position0),i.object.zoom=i.zoom0,i.object.updateProjectionMatrix(),i.dispatchEvent(e),i.update(),s=r.NONE},this.update=function(){let t=new THREE.Vector3,n=new THREE.Quaternion().setFromUnitVectors(o.up,new THREE.Vector3(0,1,0)),a=n.clone().invert(),h=new THREE.Vector3,b=new THREE.Quaternion,E=2*Math.PI;return function o(){let $=i.object.position;t.copy($).sub(i.target),t.applyQuaternion(n),l.setFromVector3(t),i.autoRotate&&s===r.NONE&&A(2*Math.PI/60/60*i.autoRotateSpeed),i.enableDamping?(l.theta+=m.theta*i.dampingFactor,l.phi+=m.phi*i.dampingFactor):(l.theta+=m.theta,l.phi+=m.phi);let g=i.minAzimuthAngle,O=i.maxAzimuthAngle;return isFinite(g)&&isFinite(O)&&(g<-Math.PI?g+=E:g>Math.PI&&(g-=E),O<-Math.PI?O+=E:O>Math.PI&&(O-=E),g<=O?l.theta=Math.max(g,Math.min(O,l.theta)):l.theta=l.theta>(g+O)/2?Math.max(g,l.theta):Math.min(O,l.theta)),l.phi=Math.max(i.minPolarAngle,Math.min(i.maxPolarAngle,l.phi)),l.makeSafe(),l.radius*=p,l.radius=Math.max(i.minDistance,Math.min(i.maxDistance,l.radius)),!0===i.enableDamping?i.target.addScaledVector(u,i.dampingFactor):i.target.add(u),t.setFromSpherical(l),t.applyQuaternion(a),$.copy(i.target).add(t),i.object.lookAt(i.target),!0===i.enableDamping?(m.theta*=1-i.dampingFactor,m.phi*=1-i.dampingFactor,u.multiplyScalar(1-i.dampingFactor)):(m.set(0,0,0),u.set(0,0,0)),p=1,!!(d||h.distanceToSquared(i.object.position)>c||8*(1-b.dot(i.object.quaternion))>c)&&(i.dispatchEvent(e),h.copy(i.object.position),b.copy(i.object.quaternion),d=!1,!0)}}(),this.dispose=function(){i.domElement.removeEventListener("contextmenu",K),i.domElement.removeEventListener("pointerdown",V),i.domElement.removeEventListener("pointercancel",Z),i.domElement.removeEventListener("wheel",M),i.domElement.removeEventListener("pointermove",z),i.domElement.removeEventListener("pointerup",X),null!==i._domElementKeyEvents&&i._domElementKeyEvents.removeEventListener("keydown",F)};let i=this,r={NONE:-1,ROTATE:0,DOLLY:1,PAN:2,TOUCH_ROTATE:3,TOUCH_PAN:4,TOUCH_DOLLY_PAN:5,TOUCH_DOLLY_ROTATE:6},s=r.NONE,c=1e-6,l=new THREE.Spherical,m=new THREE.Spherical,p=1,u=new THREE.Vector3,d=!1,h=new THREE.Vector2,b=new THREE.Vector2,E=new THREE.Vector2,$=new THREE.Vector2,g=new THREE.Vector2,O=new THREE.Vector2,f=new THREE.Vector2,T=new THREE.Vector2,_=new THREE.Vector2,y=[],P={};function v(){return Math.pow(.95,i.zoomSpeed)}function A(e){m.theta-=e}function L(e){m.phi-=e}let N=function(){let e=new THREE.Vector3;return function t(n,o){e.setFromMatrixColumn(o,0),e.multiplyScalar(-n),u.add(e)}}(),w=function(){let e=new THREE.Vector3;return function t(n,o){!0===i.screenSpacePanning?e.setFromMatrixColumn(o,1):(e.setFromMatrixColumn(o,0),e.crossVectors(i.object.up,e)),e.multiplyScalar(n),u.add(e)}}(),j=function(){let e=new THREE.Vector3;return function t(n,o){let a=i.domElement;if(i.object.isPerspectiveCamera){let r=i.object.position;e.copy(r).sub(i.target);let s=e.length();N(2*n*(s*=Math.tan(i.object.fov/2*Math.PI/180))/a.clientHeight,i.object.matrix),w(2*o*s/a.clientHeight,i.object.matrix)}else i.object.isOrthographicCamera?(N(n*(i.object.right-i.object.left)/i.object.zoom/a.clientWidth,i.object.matrix),w(o*(i.object.top-i.object.bottom)/i.object.zoom/a.clientHeight,i.object.matrix)):(console.warn("WARNING: OrbitControls.js encountered an unknown camera type - pan disabled."),i.enablePan=!1)}}();function R(e){i.object.isPerspectiveCamera?p/=e:i.object.isOrthographicCamera?(i.object.zoom=Math.max(i.minZoom,Math.min(i.maxZoom,i.object.zoom*e)),i.object.updateProjectionMatrix(),d=!0):(console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled."),i.enableZoom=!1)}function S(e){i.object.isPerspectiveCamera?p*=e:i.object.isOrthographicCamera?(i.object.zoom=Math.max(i.minZoom,Math.min(i.maxZoom,i.object.zoom/e)),i.object.updateProjectionMatrix(),d=!0):(console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled."),i.enableZoom=!1)}function k(e){h.set(e.clientX,e.clientY)}function C(e){$.set(e.clientX,e.clientY)}function Y(){if(1===y.length)h.set(y[0].pageX,y[0].pageY);else{let e=.5*(y[0].pageX+y[1].pageX),t=.5*(y[0].pageY+y[1].pageY);h.set(e,t)}}function x(){if(1===y.length)$.set(y[0].pageX,y[0].pageY);else{let e=.5*(y[0].pageX+y[1].pageX),t=.5*(y[0].pageY+y[1].pageY);$.set(e,t)}}function H(){let e=y[0].pageX-y[1].pageX,t=y[0].pageY-y[1].pageY;f.set(0,Math.sqrt(e*e+t*t))}function D(e){if(1==y.length)b.set(e.pageX,e.pageY);else{let t=W(e),n=.5*(e.pageX+t.x),o=.5*(e.pageY+t.y);b.set(n,o)}E.subVectors(b,h).multiplyScalar(i.rotateSpeed);let a=i.domElement;A(2*Math.PI*E.x/a.clientHeight),L(2*Math.PI*E.y/a.clientHeight),h.copy(b)}function I(e){if(1===y.length)g.set(e.pageX,e.pageY);else{let t=W(e),n=.5*(e.pageX+t.x),o=.5*(e.pageY+t.y);g.set(n,o)}O.subVectors(g,$).multiplyScalar(i.panSpeed),j(O.x,O.y),$.copy(g)}function U(e){let t=W(e),n=e.pageX-t.x,o=e.pageY-t.y;T.set(0,Math.sqrt(n*n+o*o)),_.set(0,Math.pow(T.y/f.y,i.zoomSpeed)),R(_.y),f.copy(T)}function V(e){var n;!1!==i.enabled&&(0===y.length&&(i.domElement.setPointerCapture(e.pointerId),i.domElement.addEventListener("pointermove",z),i.domElement.addEventListener("pointerup",X)),n=e,y.push(n),"touch"===e.pointerType?function e(n){switch(G(n),y.length){case 1:switch(i.touches.ONE){case THREE.TOUCH.ROTATE:if(!1===i.enableRotate)return;Y(),s=r.TOUCH_ROTATE;break;case THREE.TOUCH.PAN:if(!1===i.enablePan)return;x(),s=r.TOUCH_PAN;break;default:s=r.NONE}break;case 2:switch(i.touches.TWO){case THREE.TOUCH.DOLLY_PAN:if(!1===i.enableZoom&&!1===i.enablePan)return;i.enableZoom&&H(),i.enablePan&&x(),s=r.TOUCH_DOLLY_PAN;break;case THREE.TOUCH.DOLLY_ROTATE:if(!1===i.enableZoom&&!1===i.enableRotate)return;i.enableZoom&&H(),i.enableRotate&&Y(),s=r.TOUCH_DOLLY_ROTATE;break;default:s=r.NONE}break;default:s=r.NONE}s!==r.NONE&&i.dispatchEvent(t)}(e):function e(n){let o;switch(n.button){case 0:o=i.mouseButtons.LEFT;break;case 1:o=i.mouseButtons.MIDDLE;break;case 2:o=i.mouseButtons.RIGHT;break;default:o=-1}switch(o){case THREE.MOUSE.DOLLY:var a;if(!1===i.enableZoom)return;a=n,f.set(a.clientX,a.clientY),s=r.DOLLY;break;case THREE.MOUSE.ROTATE:if(n.ctrlKey||n.metaKey||n.shiftKey){if(!1===i.enablePan)return;C(n),s=r.PAN}else{if(!1===i.enableRotate)return;k(n),s=r.ROTATE}break;case THREE.MOUSE.PAN:if(n.ctrlKey||n.metaKey||n.shiftKey){if(!1===i.enableRotate)return;k(n),s=r.ROTATE}else{if(!1===i.enablePan)return;C(n),s=r.PAN}break;default:s=r.NONE}s!==r.NONE&&i.dispatchEvent(t)}(e))}function z(e){!1!==i.enabled&&("touch"===e.pointerType?function e(t){var n,o;switch(G(t),s){case r.TOUCH_ROTATE:if(!1===i.enableRotate)return;D(t),i.update();break;case r.TOUCH_PAN:if(!1===i.enablePan)return;I(t),i.update();break;case r.TOUCH_DOLLY_PAN:if(!1===i.enableZoom&&!1===i.enablePan)return;n=t,i.enableZoom&&U(n),i.enablePan&&I(n),i.update();break;case r.TOUCH_DOLLY_ROTATE:if(!1===i.enableZoom&&!1===i.enableRotate)return;o=t,i.enableZoom&&U(o),i.enableRotate&&D(o),i.update();break;default:s=r.NONE}}(e):function e(t){var n,o;if(!1!==i.enabled)switch(s){case r.ROTATE:if(!1===i.enableRotate)return;!function e(t){b.set(t.clientX,t.clientY),E.subVectors(b,h).multiplyScalar(i.rotateSpeed);let n=i.domElement;A(2*Math.PI*E.x/n.clientHeight),L(2*Math.PI*E.y/n.clientHeight),h.copy(b),i.update()}(t);break;case r.DOLLY:if(!1===i.enableZoom)return;n=t,T.set(n.clientX,n.clientY),_.subVectors(T,f),_.y>0?R(v()):_.y<0&&S(v()),f.copy(T),i.update();break;case r.PAN:if(!1===i.enablePan)return;o=t,g.set(o.clientX,o.clientY),O.subVectors(g,$).multiplyScalar(i.panSpeed),j(O.x,O.y),$.copy(g),i.update()}}(e))}function X(e){B(e),0===y.length&&(i.domElement.releasePointerCapture(e.pointerId),i.domElement.removeEventListener("pointermove",z),i.domElement.removeEventListener("pointerup",X)),i.dispatchEvent(n),s=r.NONE}function Z(e){B(e)}function M(e){if(!1!==i.enabled&&!1!==i.enableZoom&&s===r.NONE){var o;e.preventDefault(),i.dispatchEvent(t),(o=e).deltaY<0?S(v()):o.deltaY>0&&R(v()),i.update(),i.dispatchEvent(n)}}function F(e){!1!==i.enabled&&!1!==i.enablePan&&function e(t){let n=!1;switch(t.code){case i.keys.UP:j(0,i.keyPanSpeed),n=!0;break;case i.keys.BOTTOM:j(0,-i.keyPanSpeed),n=!0;break;case i.keys.LEFT:j(i.keyPanSpeed,0),n=!0;break;case i.keys.RIGHT:j(-i.keyPanSpeed,0),n=!0}n&&(t.preventDefault(),i.update())}(e)}function K(e){!1!==i.enabled&&e.preventDefault()}function B(e){delete P[e.pointerId];for(let t=0;tn!=l[1]>n&&t<(l[0]-d[0])*(n-d[1])/(l[1]-d[1])+d[0]&&(r=!r),o=Math.min(o,a(t,n,d,l))}return(r?1:-1)*Math.sqrt(o)}(t,n,r),this.max=this.d+this.h*Math.SQRT2}function a(t,n,e,r){var o=e[0],i=e[1],a=r[0]-o,u=r[1]-i;if(0!==a||0!==u){var f=((t-o)*a+(n-i)*u)/(a*a+u*u);f>1?(o=r[0],i=r[1]):f>0&&(o+=a*f,i+=u*f)}return(a=t-o)*a+(u=n-i)*u}n.exports=function(t,n,e){var a,u,f,h;n=n||1;for(var s=0;sf)&&(f=d[0]),(!s||d[1]>h)&&(h=d[1])}for(var l=f-a,p=h-u,c=Math.min(l,p),v=c/2,g=new r(null,o),x=a;xw.d&&(w=b,e&&console.log("found best %d after %d probes",Math.round(1e4*b.d)/1e4,m)),b.max-w.d<=n||(v=b.h/2,g.push(new i(b.x-v,b.y-v,v,t)),g.push(new i(b.x+v,b.y-v,v,t)),g.push(new i(b.x-v,b.y+v,v,t)),g.push(new i(b.x+v,b.y+v,v,t)),m+=4)}e&&(console.log("num probes: "+m),console.log("best distance: "+w.d));return[w.x,w.y]}},{tinyqueue:2}],2:[function(t,n,e){"use strict";function r(t,n){if(!(this instanceof r))return new r(t,n);if(this.data=t||[],this.length=this.data.length,this.compare=n||o,t)for(var e=Math.floor(this.length/2);e>=0;e--)this._down(e)}function o(t,n){return tn?1:0}function i(t,n,e){var r=t[n];t[n]=t[e],t[e]=r}n.exports=r,r.prototype={push:function(t){this.data.push(t),this.length++,this._up(this.length-1)},pop:function(){var t=this.data[0];return this.data[0]=this.data[this.length-1],this.length--,this.data.pop(),this._down(0),t},peek:function(){return this.data[0]},_up:function(t){for(var n=this.data,e=this.compare;t>0;){var r=Math.floor((t-1)/2);if(!(e(n[t],n[r])<0))break;i(n,r,t),t=r}},_down:function(t){for(var n=this.data,e=this.compare,r=this.length;;){var o=2*t+1,a=o+1,u=t;if(on!=l[1]>n&&t<(l[0]-d[0])*(n-d[1])/(l[1]-d[1])+d[0]&&(r=!r),o=Math.min(o,a(t,n,d,l))}return(r?1:-1)*Math.sqrt(o)}(t,n,r),this.max=this.d+this.h*Math.SQRT2}function a(t,n,e,r){var o=e[0],i=e[1],a=r[0]-o,u=r[1]-i;if(0!==a||0!==u){var f=((t-o)*a+(n-i)*u)/(a*a+u*u);f>1?(o=r[0],i=r[1]):f>0&&(o+=a*f,i+=u*f)}return(a=t-o)*a+(u=n-i)*u}n.exports=function(t,n,e){var a,u,f,h;n=n||1;for(var s=0;sf)&&(f=d[0]),(!s||d[1]>h)&&(h=d[1])}for(var l=f-a,p=h-u,c=Math.min(l,p),v=c/2,g=new r(null,o),x=a;xw.d&&(w=b,e&&console.info("found best %d after %d probes",Math.round(1e4*b.d)/1e4,m)),b.max-w.d<=n||(v=b.h/2,g.push(new i(b.x-v,b.y-v,v,t)),g.push(new i(b.x+v,b.y-v,v,t)),g.push(new i(b.x-v,b.y+v,v,t)),g.push(new i(b.x+v,b.y+v,v,t)),m+=4)}e&&(console.info("num probes: "+m),console.info("best distance: "+w.d));return[w.x,w.y]}},{tinyqueue:2}],2:[function(t,n,e){"use strict";function r(t,n){if(!(this instanceof r))return new r(t,n);if(this.data=t||[],this.length=this.data.length,this.compare=n||o,t)for(var e=Math.floor(this.length/2);e>=0;e--)this._down(e)}function o(t,n){return tn?1:0}function i(t,n,e){var r=t[n];t[n]=t[e],t[e]=r}n.exports=r,r.prototype={push:function(t){this.data.push(t),this.length++,this._up(this.length-1)},pop:function(){var t=this.data[0];return this.data[0]=this.data[this.length-1],this.length--,this.data.pop(),this._down(0),t},peek:function(){return this.data[0]},_up:function(t){for(var n=this.data,e=this.compare;t>0;){var r=Math.floor((t-1)/2);if(!(e(n[t],n[r])<0))break;i(n,r,t),t=r}},_down:function(t){for(var n=this.data,e=this.compare,r=this.length;;){var o=2*t+1,a=o+1,u=t;if(o>>1],e)>=0?o=a+1:r=a;return o},e.exports=function(){function t(t){var e;this.options=t,this.comparator=this.options.comparator,this.data=(null!=(e=this.options.initialValues)?e.slice(0):void 0)||[],this.data.sort(this.comparator).reverse()}return t.prototype.queue=function(t){var e;e=r(this.data,t,this.comparator),this.data.splice(e,0,t)},t.prototype.dequeue=function(){return this.data.pop()},t.prototype.peek=function(){return this.data[this.data.length-1]},t.prototype.clear=function(){this.data.length=0},t}()},{}],4:[function(t,e,i){e.exports=function(){function t(t){var e,i,r,o,a,n,s,h;for(this.comparator=(null!=t?t.comparator:void 0)||function(t,e){return t-e},this.pageSize=(null!=t?t.pageSize:void 0)||512,this.length=0,s=0;1<a;0<=a?++i:--i)e.push(null);if(this._memory=[],this._mask=this.pageSize-1,t.initialValues)for(r=0,o=(n=t.initialValues).length;r0&&(this._write(1,e),this._bubbleDown(1,e)),t},t.prototype.peek=function(){return this._read(1)},t.prototype.clear=function(){this.length=0,this._memory.length=0},t.prototype._write=function(t,e){var i;for(i=t>>this._shift;i>=this._memory.length;)this._memory.push(this._emptyMemoryPageTemplate.slice(0));return this._memory[i][t&this._mask]=e},t.prototype._read=function(t){return this._memory[t>>this._shift][t&this._mask]},t.prototype._bubbleUp=function(t,e){var i,r,o,a;for(i=this.comparator;t>1&&(r=t&this._mask,t3?o=t&~this._mask|r>>1:r<2?(o=t-this.pageSize>>this._shift,o+=o&~(this._mask>>1),o|=this.pageSize>>1):o=t-2,!(i(a=this._read(o),e)<0));)this._write(o,e),this._write(t,a),t=o},t.prototype._bubbleDown=function(t,e){var i,r,o,a,n;for(n=this.comparator;tthis._mask&&!(t&this._mask-1)?i=r=t+2:t&this.pageSize>>1?(i=(t&~this._mask)>>1,r=(i=(i|=t&this._mask>>1)+1<0)for(t=e=1,i=this.data.length;1<=i?ei;t=1<=i?++e:--e)this._bubbleUp(t)},t.prototype.queue=function(t){this.data.push(t),this._bubbleUp(this.data.length-1)},t.prototype.dequeue=function(){var t,e;return e=this.data[0],t=this.data.pop(),this.data.length>0&&(this.data[0]=t,this._bubbleDown(0)),e},t.prototype.peek=function(){return this.data[0]},t.prototype.clear=function(){this.length=0,this.data.length=0},t.prototype._bubbleUp=function(t){for(var e,i;t>0&&(e=t-1>>>1,this.comparator(this.data[t],this.data[e])<0);)i=this.data[e],this.data[e]=this.data[t],this.data[t]=i,t=e},t.prototype._bubbleDown=function(t){var e,i,r,o,a;for(e=this.data.length-1;o=(i=1+(t<<1))+1,r=t,i<=e&&this.comparator(this.data[i],this.data[r])<0&&(r=i),o<=e&&this.comparator(this.data[o],this.data[r])<0&&(r=o),r!==t;)a=this.data[r],this.data[r]=this.data[t],this.data[t]=a,t=r},t}()},{}]},{},[1])(1)});
\ No newline at end of file
diff --git a/libs/publicstorage.js b/libs/publicstorage.js
deleted file mode 100644
index 9d8ebe54..00000000
--- a/libs/publicstorage.js
+++ /dev/null
@@ -1,188 +0,0 @@
-// https://github.com/Highbrainer/jeevaneo-js-publicstorage. MIT
-const IFRAME_ROOT_URL = "https://publicstorage.neocities.org/shared-iframe.html";
-
-class PublicStorageAccess {
-
- constructor ({debug=false}={}) {
- this.uid = this.uniqueId();
- this.debug=debug;
- }
-
- uniqueId() {
- function chr4(){
- return Math.random().toString(16).slice(-4);
- }
- return chr4() + chr4() +
- '-' + chr4() +
- '-' + chr4() +
- '-' + chr4() +
- '-' + chr4() + chr4() + chr4();
- }
-
- _debug(msg) {
- if(this.debug) {
- if(console && console.debug) {
- console.debug(msg);
- }
- }
- }
-
- prepareIFrame() {
- const that = this;
- const iframe = document.createElement("iframe");
- iframe.id=that.uid;
- iframe.src=IFRAME_ROOT_URL + "?uid=init-"+that.uid;
- iframe.style.cssText="display:none;";
- return new Promise(function(resolve, reject) {
- window.addEventListener('message', function mafunc(tkn) {
-
- if (IFRAME_ROOT_URL.indexOf(tkn.origin)<0) {
- return;
- }
-
- try {
- const packet = JSON.parse(tkn.data);
-
- if(!(packet.frameId === "init-" + that.uid)) {
- // ignore
- return;
- }
-
- if(packet.ready) {
- resolve(iframe);
- }
- } catch (e) {
- reject(tkn.data);
- }
- window.removeEventListener('message', mafunc);
- });
- onLoadThen().then(() => {
- document.getElementsByTagName("body")[0].appendChild(iframe);
- });
-
- setTimeout(()=>reject(`Request ${that.uid} TIMEOUTED!`), 20000);
- });
- }
-
- access(access, prop, value = null, level = "local") {
-
- if(!(access === "get" || access === "set" || access === "delete")) {
- throw new Error("access can only be 'set', 'get' or 'delete' - not '" + access + "'");
- }
-
- if (!prop) {
- throw new Error("Prop name is mandatory");
- }
-
- if(!(level === "local" || level === "session")) {
- throw new Error("level can only be 'session' or 'local' - not '" + access + "'");
- }
-
- const that = this;
-
- const promise = new Promise(function(resolve, reject) {
- that.prepareIFrame().then(iframe => {
- window.addEventListener('message', function mafunc(tkn) {
- if (IFRAME_ROOT_URL.indexOf(tkn.origin)<0) {
- return;
- }
- try {
- var packet = JSON.parse(tkn.data);
-
- if(!(packet.uid === that.uid)) {
- // ignore
- return;
- }
- resolve(packet.body);
- } catch (e) {
- reject(tkn.data);
- }
- iframe.parentNode.removeChild(iframe);
- window.removeEventListener('message', mafunc);
- });
-
- const request = {uid:that.uid, access:access, prop:prop, value:value, level:level};
- iframe.contentWindow.postMessage(JSON.stringify(request), '*');
- setTimeout(()=>reject("TIMEOUTED!"), 20000);
- });
- });
- return promise;
- }
-
-}
-
-function __createDebugIFrame() {
- onLoadThen().then(function(){
- const iframe = document.createElement("iframe");
- iframe.src=IFRAME_ROOT_URL + "?for-debug-only";
- iframe.style.cssText="display:none;";
- document.getElementsByTagName("body")[0].appendChild(iframe);
- });
-}
-
-class PublicStorage {
-
- constructor({debug=false}={}) {
- if(debug) {
- __createDebugIFrame();
- }
- }
-
- sessionGet(prop) {
- return new PublicStorageAccess().access("get", prop, null, "session");
- }
- sessionSet(prop, value) {
- return new PublicStorageAccess().access("set", prop, value, "session");
- }
- sessionUnset(prop) {
- return new PublicStorageAccess().access("delete", prop, null, "session");
- }
- localGet(prop) {
- return new PublicStorageAccess().access("get", prop, null, "local");
- }
- localSet(prop, value) {
- return new PublicStorageAccess().access("set", prop, value, "local");
- }
- localUnset(prop) {
- return new PublicStorageAccess().access("delete", prop, null, "local");
- }
- get(prop) {
- return this.localGet(prop);
- }
- set(prop, value) {
- return this.localSet(prop, value);
- }
- unset(prop) {
- return this.localUnset(prop);
- }
-}
-
-const publicstorage = new PublicStorage();
-
-function onLoadThen() {
- return new Promise(function(resolve, reject) {
- if (window) {
- if(document.getElementsByTagName('BODY')[0]) {
- resolve();
- } else {
- registerOnLoad(function unregisterme() {
- resolve();
- window.removeEventListener('load', unregisterme);
- });
- }
- }
- setTimeout(function() {reject(new Error("Timeout waiting for onLoad!"));}, 10000);
- });
-}
-
-function registerOnLoad(lambda) {
- if (window.addEventListener) {
- window.addEventListener('load', lambda);
- } else if (window.attachEvent) {
- window.attachEvent('onload', lambda);
- }
-}
-
-onLoadThen().then(() => window.publicstorage = publicstorage).catch(e=> console.error(e));
-//export {onLoadThen, PublicStorage, publicstorage as default}
-// module.exports = onLoadThen();
diff --git a/libs/rgbquant.js b/libs/rgbquant.js
deleted file mode 100644
index bc0bd1b9..00000000
--- a/libs/rgbquant.js
+++ /dev/null
@@ -1,935 +0,0 @@
-/*
-* Copyright (c) 2015, Leon Sorokin
-* All rights reserved. (MIT Licensed)
-*
-* RgbQuant.js - an image quantization lib
-*/
-
-(function(){
- function RgbQuant(opts) {
- opts = opts || {};
-
- // 1 = by global population, 2 = subregion population threshold
- this.method = opts.method || 2;
- // desired final palette size
- this.colors = opts.colors || 256;
- // # of highest-frequency colors to start with for palette reduction
- this.initColors = opts.initColors || 4096;
- // color-distance threshold for initial reduction pass
- this.initDist = opts.initDist || 0.01;
- // subsequent passes threshold
- this.distIncr = opts.distIncr || 0.005;
- // palette grouping
- this.hueGroups = opts.hueGroups || 10;
- this.satGroups = opts.satGroups || 10;
- this.lumGroups = opts.lumGroups || 10;
- // if > 0, enables hues stats and min-color retention per group
- this.minHueCols = opts.minHueCols || 0;
- // HueStats instance
- this.hueStats = this.minHueCols ? new HueStats(this.hueGroups, this.minHueCols) : null;
-
- // subregion partitioning box size
- this.boxSize = opts.boxSize || [64,64];
- // number of same pixels required within box for histogram inclusion
- this.boxPxls = opts.boxPxls || 2;
- // palette locked indicator
- this.palLocked = false;
- // palette sort order
-// this.sortPal = ['hue-','lum-','sat-'];
-
- // dithering/error diffusion kernel name
- this.dithKern = opts.dithKern || null;
- // dither serpentine pattern
- this.dithSerp = opts.dithSerp || false;
- // minimum color difference (0-1) needed to dither
- this.dithDelta = opts.dithDelta || 0;
-
- // accumulated histogram
- this.histogram = {};
- // palette - rgb triplets
- this.idxrgb = opts.palette ? opts.palette.slice(0) : [];
- // palette - int32 vals
- this.idxi32 = [];
- // reverse lookup {i32:idx}
- this.i32idx = {};
- // {i32:rgb}
- this.i32rgb = {};
- // enable color caching (also incurs overhead of cache misses and cache building)
- this.useCache = opts.useCache !== false;
- // min color occurance count needed to qualify for caching
- this.cacheFreq = opts.cacheFreq || 10;
- // allows pre-defined palettes to be re-indexed (enabling palette compacting and sorting)
- this.reIndex = opts.reIndex || this.idxrgb.length == 0;
- // selection of color-distance equation
- this.colorDist = opts.colorDist == "manhattan" ? distManhattan : distEuclidean;
-
- // if pre-defined palette, build lookups
- if (this.idxrgb.length > 0) {
- var self = this;
- this.idxrgb.forEach(function(rgb, i) {
- var i32 = (
- (255 << 24) | // alpha
- (rgb[2] << 16) | // blue
- (rgb[1] << 8) | // green
- rgb[0] // red
- ) >>> 0;
-
- self.idxi32[i] = i32;
- self.i32idx[i32] = i;
- self.i32rgb[i32] = rgb;
- });
- }
- }
-
- // gathers histogram info
- RgbQuant.prototype.sample = function sample(img, width) {
- if (this.palLocked)
- throw "Cannot sample additional images, palette already assembled.";
-
- var data = getImageData(img, width);
-
- switch (this.method) {
- case 1: this.colorStats1D(data.buf32); break;
- case 2: this.colorStats2D(data.buf32, data.width); break;
- }
- };
-
- // image quantizer
- // todo: memoize colors here also
- // @retType: 1 - Uint8Array (default), 2 - Indexed array, 3 - Match @img type (unimplemented, todo)
- RgbQuant.prototype.reduce = function reduce(img, retType, dithKern, dithSerp) {
- if (!this.palLocked)
- this.buildPal();
-
- dithKern = dithKern || this.dithKern;
- dithSerp = typeof dithSerp != "undefined" ? dithSerp : this.dithSerp;
-
- retType = retType || 1;
-
- // reduce w/dither
- if (dithKern)
- var out32 = this.dither(img, dithKern, dithSerp);
- else {
- var data = getImageData(img),
- buf32 = data.buf32,
- len = buf32.length,
- out32 = new Uint32Array(len);
-
- for (var i = 0; i < len; i++) {
- var i32 = buf32[i];
- out32[i] = this.nearestColor(i32);
- }
- }
-
- if (retType == 1)
- return new Uint8Array(out32.buffer);
-
- if (retType == 2) {
- var out = [],
- len = out32.length;
-
- for (var i = 0; i < len; i++) {
- var i32 = out32[i];
- out[i] = this.i32idx[i32];
- }
-
- return out;
- }
- };
-
- // adapted from http://jsbin.com/iXofIji/2/edit by PAEz
- RgbQuant.prototype.dither = function(img, kernel, serpentine) {
- // http://www.tannerhelland.com/4660/dithering-eleven-algorithms-source-code/
- var kernels = {
- FloydSteinberg: [
- [7 / 16, 1, 0],
- [3 / 16, -1, 1],
- [5 / 16, 0, 1],
- [1 / 16, 1, 1]
- ],
- FalseFloydSteinberg: [
- [3 / 8, 1, 0],
- [3 / 8, 0, 1],
- [2 / 8, 1, 1]
- ],
- Stucki: [
- [8 / 42, 1, 0],
- [4 / 42, 2, 0],
- [2 / 42, -2, 1],
- [4 / 42, -1, 1],
- [8 / 42, 0, 1],
- [4 / 42, 1, 1],
- [2 / 42, 2, 1],
- [1 / 42, -2, 2],
- [2 / 42, -1, 2],
- [4 / 42, 0, 2],
- [2 / 42, 1, 2],
- [1 / 42, 2, 2]
- ],
- Atkinson: [
- [1 / 8, 1, 0],
- [1 / 8, 2, 0],
- [1 / 8, -1, 1],
- [1 / 8, 0, 1],
- [1 / 8, 1, 1],
- [1 / 8, 0, 2]
- ],
- Jarvis: [ // Jarvis, Judice, and Ninke / JJN?
- [7 / 48, 1, 0],
- [5 / 48, 2, 0],
- [3 / 48, -2, 1],
- [5 / 48, -1, 1],
- [7 / 48, 0, 1],
- [5 / 48, 1, 1],
- [3 / 48, 2, 1],
- [1 / 48, -2, 2],
- [3 / 48, -1, 2],
- [5 / 48, 0, 2],
- [3 / 48, 1, 2],
- [1 / 48, 2, 2]
- ],
- Burkes: [
- [8 / 32, 1, 0],
- [4 / 32, 2, 0],
- [2 / 32, -2, 1],
- [4 / 32, -1, 1],
- [8 / 32, 0, 1],
- [4 / 32, 1, 1],
- [2 / 32, 2, 1],
- ],
- Sierra: [
- [5 / 32, 1, 0],
- [3 / 32, 2, 0],
- [2 / 32, -2, 1],
- [4 / 32, -1, 1],
- [5 / 32, 0, 1],
- [4 / 32, 1, 1],
- [2 / 32, 2, 1],
- [2 / 32, -1, 2],
- [3 / 32, 0, 2],
- [2 / 32, 1, 2],
- ],
- TwoSierra: [
- [4 / 16, 1, 0],
- [3 / 16, 2, 0],
- [1 / 16, -2, 1],
- [2 / 16, -1, 1],
- [3 / 16, 0, 1],
- [2 / 16, 1, 1],
- [1 / 16, 2, 1],
- ],
- SierraLite: [
- [2 / 4, 1, 0],
- [1 / 4, -1, 1],
- [1 / 4, 0, 1],
- ],
- };
-
- if (!kernel || !kernels[kernel]) {
- throw 'Unknown dithering kernel: ' + kernel;
- }
-
- var ds = kernels[kernel];
-
- var data = getImageData(img),
-// buf8 = data.buf8,
- buf32 = data.buf32,
- width = data.width,
- height = data.height,
- len = buf32.length;
-
- var dir = serpentine ? -1 : 1;
-
- for (var y = 0; y < height; y++) {
- if (serpentine)
- dir = dir * -1;
-
- var lni = y * width;
-
- for (var x = (dir == 1 ? 0 : width - 1), xend = (dir == 1 ? width : 0); x !== xend; x += dir) {
- // Image pixel
- var idx = lni + x,
- i32 = buf32[idx],
- r1 = (i32 & 0xff),
- g1 = (i32 & 0xff00) >> 8,
- b1 = (i32 & 0xff0000) >> 16;
-
- // Reduced pixel
- var i32x = this.nearestColor(i32),
- r2 = (i32x & 0xff),
- g2 = (i32x & 0xff00) >> 8,
- b2 = (i32x & 0xff0000) >> 16;
-
- buf32[idx] =
- (255 << 24) | // alpha
- (b2 << 16) | // blue
- (g2 << 8) | // green
- r2;
-
- // dithering strength
- if (this.dithDelta) {
- var dist = this.colorDist([r1, g1, b1], [r2, g2, b2]);
- if (dist < this.dithDelta)
- continue;
- }
-
- // Component distance
- var er = r1 - r2,
- eg = g1 - g2,
- eb = b1 - b2;
-
- for (var i = (dir == 1 ? 0 : ds.length - 1), end = (dir == 1 ? ds.length : 0); i !== end; i += dir) {
- var x1 = ds[i][1] * dir,
- y1 = ds[i][2];
-
- var lni2 = y1 * width;
-
- if (x1 + x >= 0 && x1 + x < width && y1 + y >= 0 && y1 + y < height) {
- var d = ds[i][0];
- var idx2 = idx + (lni2 + x1);
-
- var r3 = (buf32[idx2] & 0xff),
- g3 = (buf32[idx2] & 0xff00) >> 8,
- b3 = (buf32[idx2] & 0xff0000) >> 16;
-
- var r4 = Math.max(0, Math.min(255, r3 + er * d)),
- g4 = Math.max(0, Math.min(255, g3 + eg * d)),
- b4 = Math.max(0, Math.min(255, b3 + eb * d));
-
- buf32[idx2] =
- (255 << 24) | // alpha
- (b4 << 16) | // blue
- (g4 << 8) | // green
- r4; // red
- }
- }
- }
- }
-
- return buf32;
- };
-
- // reduces histogram to palette, remaps & memoizes reduced colors
- RgbQuant.prototype.buildPal = function buildPal(noSort) {
- if (this.palLocked || this.idxrgb.length > 0 && this.idxrgb.length <= this.colors) return;
-
- var histG = this.histogram,
- sorted = sortedHashKeys(histG, true);
-
- if (sorted.length == 0)
- throw "Nothing has been sampled, palette cannot be built.";
-
- switch (this.method) {
- case 1:
- var cols = this.initColors,
- last = sorted[cols - 1],
- freq = histG[last];
-
- var idxi32 = sorted.slice(0, cols);
-
- // add any cut off colors with same freq as last
- var pos = cols, len = sorted.length;
- while (pos < len && histG[sorted[pos]] == freq)
- idxi32.push(sorted[pos++]);
-
- // inject min huegroup colors
- if (this.hueStats)
- this.hueStats.inject(idxi32);
-
- break;
- case 2:
- var idxi32 = sorted;
- break;
- }
-
- // int32-ify values
- idxi32 = idxi32.map(function(v){return +v;});
-
- this.reducePal(idxi32);
-
- if (!noSort && this.reIndex)
- this.sortPal();
-
- // build cache of top histogram colors
- if (this.useCache)
- this.cacheHistogram(idxi32);
-
- this.palLocked = true;
- };
-
- RgbQuant.prototype.palette = function palette(tuples, noSort) {
- this.buildPal(noSort);
- return tuples ? this.idxrgb : new Uint8Array((new Uint32Array(this.idxi32)).buffer);
- };
-
- RgbQuant.prototype.prunePal = function prunePal(keep) {
- var i32;
-
- for (var j = 0; j < this.idxrgb.length; j++) {
- if (!keep[j]) {
- i32 = this.idxi32[j];
- this.idxrgb[j] = null;
- this.idxi32[j] = null;
- delete this.i32idx[i32];
- }
- }
-
- // compact
- if (this.reIndex) {
- var idxrgb = [],
- idxi32 = [],
- i32idx = {};
-
- for (var j = 0, i = 0; j < this.idxrgb.length; j++) {
- if (this.idxrgb[j]) {
- i32 = this.idxi32[j];
- idxrgb[i] = this.idxrgb[j];
- i32idx[i32] = i;
- idxi32[i] = i32;
- i++;
- }
- }
-
- this.idxrgb = idxrgb;
- this.idxi32 = idxi32;
- this.i32idx = i32idx;
- }
- };
-
- // reduces similar colors from an importance-sorted Uint32 rgba array
- RgbQuant.prototype.reducePal = function reducePal(idxi32) {
- // if pre-defined palette's length exceeds target
- if (this.idxrgb.length > this.colors) {
- // quantize histogram to existing palette
- var len = idxi32.length, keep = {}, uniques = 0, idx, pruned = false;
-
- for (var i = 0; i < len; i++) {
- // palette length reached, unset all remaining colors (sparse palette)
- if (uniques == this.colors && !pruned) {
- this.prunePal(keep);
- pruned = true;
- }
-
- idx = this.nearestIndex(idxi32[i]);
-
- if (uniques < this.colors && !keep[idx]) {
- keep[idx] = true;
- uniques++;
- }
- }
-
- if (!pruned) {
- this.prunePal(keep);
- pruned = true;
- }
- }
- // reduce histogram to create initial palette
- else {
- // build full rgb palette
- var idxrgb = idxi32.map(function(i32) {
- return [
- (i32 & 0xff),
- (i32 & 0xff00) >> 8,
- (i32 & 0xff0000) >> 16,
- ];
- });
-
- var len = idxrgb.length,
- palLen = len,
- thold = this.initDist;
-
- // palette already at or below desired length
- if (palLen > this.colors) {
- while (palLen > this.colors) {
- var memDist = [];
-
- // iterate palette
- for (var i = 0; i < len; i++) {
- var pxi = idxrgb[i], i32i = idxi32[i];
- if (!pxi) continue;
-
- for (var j = i + 1; j < len; j++) {
- var pxj = idxrgb[j], i32j = idxi32[j];
- if (!pxj) continue;
-
- var dist = this.colorDist(pxi, pxj);
-
- if (dist < thold) {
- // store index,rgb,dist
- memDist.push([j, pxj, i32j, dist]);
-
- // kill squashed value
- delete(idxrgb[j]);
- palLen--;
- }
- }
- }
-
- // palette reduction pass
- // console.log("palette length: " + palLen);
-
- // if palette is still much larger than target, increment by larger initDist
- thold += (palLen > this.colors * 3) ? this.initDist : this.distIncr;
- }
-
- // if palette is over-reduced, re-add removed colors with largest distances from last round
- if (palLen < this.colors) {
- // sort descending
- sort.call(memDist, function(a,b) {
- return b[3] - a[3];
- });
-
- var k = 0;
- while (palLen < this.colors) {
- // re-inject rgb into final palette
- idxrgb[memDist[k][0]] = memDist[k][1];
-
- palLen++;
- k++;
- }
- }
- }
-
- var len = idxrgb.length;
- for (var i = 0; i < len; i++) {
- if (!idxrgb[i]) continue;
-
- this.idxrgb.push(idxrgb[i]);
- this.idxi32.push(idxi32[i]);
-
- this.i32idx[idxi32[i]] = this.idxi32.length - 1;
- this.i32rgb[idxi32[i]] = idxrgb[i];
- }
- }
- };
-
- // global top-population
- RgbQuant.prototype.colorStats1D = function colorStats1D(buf32) {
- var histG = this.histogram,
- num = 0, col,
- len = buf32.length;
-
- for (var i = 0; i < len; i++) {
- col = buf32[i];
-
- // skip transparent
- if ((col & 0xff000000) >> 24 == 0) continue;
-
- // collect hue stats
- if (this.hueStats)
- this.hueStats.check(col);
-
- if (col in histG)
- histG[col]++;
- else
- histG[col] = 1;
- }
- };
-
- // population threshold within subregions
- // FIXME: this can over-reduce (few/no colors same?), need a way to keep
- // important colors that dont ever reach local thresholds (gradients?)
- RgbQuant.prototype.colorStats2D = function colorStats2D(buf32, width) {
- var boxW = this.boxSize[0],
- boxH = this.boxSize[1],
- area = boxW * boxH,
- boxes = makeBoxes(width, buf32.length / width, boxW, boxH),
- histG = this.histogram,
- self = this;
-
- boxes.forEach(function(box) {
- var effc = Math.max(Math.round((box.w * box.h) / area) * self.boxPxls, 2),
- histL = {}, col;
-
- iterBox(box, width, function(i) {
- col = buf32[i];
-
- // skip transparent
- if ((col & 0xff000000) >> 24 == 0) return;
-
- // collect hue stats
- if (self.hueStats)
- self.hueStats.check(col);
-
- if (col in histG)
- histG[col]++;
- else if (col in histL) {
- if (++histL[col] >= effc)
- histG[col] = histL[col];
- }
- else
- histL[col] = 1;
- });
- });
-
- if (this.hueStats)
- this.hueStats.inject(histG);
- };
-
- // TODO: group very low lum and very high lum colors
- // TODO: pass custom sort order
- RgbQuant.prototype.sortPal = function sortPal() {
- var self = this;
-
- this.idxi32.sort(function(a,b) {
- var idxA = self.i32idx[a],
- idxB = self.i32idx[b],
- rgbA = self.idxrgb[idxA],
- rgbB = self.idxrgb[idxB];
-
- var hslA = rgb2hsl(rgbA[0],rgbA[1],rgbA[2]),
- hslB = rgb2hsl(rgbB[0],rgbB[1],rgbB[2]);
-
- // sort all grays + whites together
- var hueA = (rgbA[0] == rgbA[1] && rgbA[1] == rgbA[2]) ? -1 : hueGroup(hslA.h, self.hueGroups);
- var hueB = (rgbB[0] == rgbB[1] && rgbB[1] == rgbB[2]) ? -1 : hueGroup(hslB.h, self.hueGroups);
-
- var hueDiff = hueB - hueA;
- if (hueDiff) return -hueDiff;
-
- var lumDiff = lumGroup(+hslB.l.toFixed(2)) - lumGroup(+hslA.l.toFixed(2));
- if (lumDiff) return -lumDiff;
-
- var satDiff = satGroup(+hslB.s.toFixed(2)) - satGroup(+hslA.s.toFixed(2));
- if (satDiff) return -satDiff;
- });
-
- // sync idxrgb & i32idx
- this.idxi32.forEach(function(i32, i) {
- self.idxrgb[i] = self.i32rgb[i32];
- self.i32idx[i32] = i;
- });
- };
-
- // TOTRY: use HUSL - http://boronine.com/husl/
- RgbQuant.prototype.nearestColor = function nearestColor(i32) {
- var idx = this.nearestIndex(i32);
- return idx === null ? 0 : this.idxi32[idx];
- };
-
- // TOTRY: use HUSL - http://boronine.com/husl/
- RgbQuant.prototype.nearestIndex = function nearestIndex(i32) {
- // alpha 0 returns null index
- if ((i32 & 0xff000000) >> 24 == 0)
- return null;
-
- if (this.useCache && (""+i32) in this.i32idx)
- return this.i32idx[i32];
-
- var min = 1000,
- idx,
- rgb = [
- (i32 & 0xff),
- (i32 & 0xff00) >> 8,
- (i32 & 0xff0000) >> 16,
- ],
- len = this.idxrgb.length;
-
- for (var i = 0; i < len; i++) {
- if (!this.idxrgb[i]) continue; // sparse palettes
-
- var dist = this.colorDist(rgb, this.idxrgb[i]);
-
- if (dist < min) {
- min = dist;
- idx = i;
- }
- }
-
- return idx;
- };
-
- RgbQuant.prototype.cacheHistogram = function cacheHistogram(idxi32) {
- for (var i = 0, i32 = idxi32[i]; i < idxi32.length && this.histogram[i32] >= this.cacheFreq; i32 = idxi32[i++])
- this.i32idx[i32] = this.nearestIndex(i32);
- };
-
- function HueStats(numGroups, minCols) {
- this.numGroups = numGroups;
- this.minCols = minCols;
- this.stats = {};
-
- for (var i = -1; i < numGroups; i++)
- this.stats[i] = {num: 0, cols: []};
-
- this.groupsFull = 0;
- }
-
- HueStats.prototype.check = function checkHue(i32) {
- if (this.groupsFull == this.numGroups + 1)
- this.check = function() {return;};
-
- var r = (i32 & 0xff),
- g = (i32 & 0xff00) >> 8,
- b = (i32 & 0xff0000) >> 16,
- hg = (r == g && g == b) ? -1 : hueGroup(rgb2hsl(r,g,b).h, this.numGroups),
- gr = this.stats[hg],
- min = this.minCols;
-
- gr.num++;
-
- if (gr.num > min)
- return;
- if (gr.num == min)
- this.groupsFull++;
-
- if (gr.num <= min)
- this.stats[hg].cols.push(i32);
- };
-
- HueStats.prototype.inject = function injectHues(histG) {
- for (var i = -1; i < this.numGroups; i++) {
- if (this.stats[i].num <= this.minCols) {
- switch (typeOf(histG)) {
- case "Array":
- this.stats[i].cols.forEach(function(col){
- if (histG.indexOf(col) == -1)
- histG.push(col);
- });
- break;
- case "Object":
- this.stats[i].cols.forEach(function(col){
- if (!histG[col])
- histG[col] = 1;
- else
- histG[col]++;
- });
- break;
- }
- }
- }
- };
-
- // Rec. 709 (sRGB) luma coef
- var Pr = .2126,
- Pg = .7152,
- Pb = .0722;
-
- // http://alienryderflex.com/hsp.html
- function rgb2lum(r,g,b) {
- return Math.sqrt(
- Pr * r*r +
- Pg * g*g +
- Pb * b*b
- );
- }
-
- var rd = 255,
- gd = 255,
- bd = 255;
-
- var euclMax = Math.sqrt(Pr*rd*rd + Pg*gd*gd + Pb*bd*bd);
- // perceptual Euclidean color distance
- function distEuclidean(rgb0, rgb1) {
- var rd = rgb1[0]-rgb0[0],
- gd = rgb1[1]-rgb0[1],
- bd = rgb1[2]-rgb0[2];
-
- return Math.sqrt(Pr*rd*rd + Pg*gd*gd + Pb*bd*bd) / euclMax;
- }
-
- var manhMax = Pr*rd + Pg*gd + Pb*bd;
- // perceptual Manhattan color distance
- function distManhattan(rgb0, rgb1) {
- var rd = Math.abs(rgb1[0]-rgb0[0]),
- gd = Math.abs(rgb1[1]-rgb0[1]),
- bd = Math.abs(rgb1[2]-rgb0[2]);
-
- return (Pr*rd + Pg*gd + Pb*bd) / manhMax;
- }
-
- // http://rgb2hsl.nichabi.com/javascript-function.php
- function rgb2hsl(r, g, b) {
- var max, min, h, s, l, d;
- r /= 255;
- g /= 255;
- b /= 255;
- max = Math.max(r, g, b);
- min = Math.min(r, g, b);
- l = (max + min) / 2;
- if (max == min) {
- h = s = 0;
- } else {
- d = max - min;
- s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
- switch (max) {
- case r: h = (g - b) / d + (g < b ? 6 : 0); break;
- case g: h = (b - r) / d + 2; break;
- case b: h = (r - g) / d + 4; break
- }
- h /= 6;
- }
-// h = Math.floor(h * 360)
-// s = Math.floor(s * 100)
-// l = Math.floor(l * 100)
- return {
- h: h,
- s: s,
- l: rgb2lum(r,g,b),
- };
- }
-
- function hueGroup(hue, segs) {
- var seg = 1/segs,
- haf = seg/2;
-
- if (hue >= 1 - haf || hue <= haf)
- return 0;
-
- for (var i = 1; i < segs; i++) {
- var mid = i*seg;
- if (hue >= mid - haf && hue <= mid + haf)
- return i;
- }
- }
-
- function satGroup(sat) {
- return sat;
- }
-
- function lumGroup(lum) {
- return lum;
- }
-
- function typeOf(val) {
- return Object.prototype.toString.call(val).slice(8,-1);
- }
-
- var sort = isArrSortStable() ? Array.prototype.sort : stableSort;
-
- // must be used via stableSort.call(arr, fn)
- function stableSort(fn) {
- var type = typeOf(this[0]);
-
- if (type == "Number" || type == "String") {
- var ord = {}, len = this.length, val;
-
- for (var i = 0; i < len; i++) {
- val = this[i];
- if (ord[val] || ord[val] === 0) continue;
- ord[val] = i;
- }
-
- return this.sort(function(a,b) {
- return fn(a,b) || ord[a] - ord[b];
- });
- }
- else {
- var ord = this.map(function(v){return v});
-
- return this.sort(function(a,b) {
- return fn(a,b) || ord.indexOf(a) - ord.indexOf(b);
- });
- }
- }
-
- // test if js engine's Array#sort implementation is stable
- function isArrSortStable() {
- var str = "abcdefghijklmnopqrstuvwxyz";
-
- return "xyzvwtursopqmnklhijfgdeabc" == str.split("").sort(function(a,b) {
- return ~~(str.indexOf(b)/2.3) - ~~(str.indexOf(a)/2.3);
- }).join("");
- }
-
- // returns uniform pixel data from various img
- // TODO?: if array is passed, createimagedata, createlement canvas? take a pxlen?
- function getImageData(img, width) {
- var can, ctx, imgd, buf8, buf32, height;
-
- switch (typeOf(img)) {
- case "HTMLImageElement":
- can = document.createElement("canvas");
- can.width = img.naturalWidth;
- can.height = img.naturalHeight;
- ctx = can.getContext("2d");
- ctx.drawImage(img,0,0);
- case "Canvas":
- case "HTMLCanvasElement":
- can = can || img;
- ctx = ctx || can.getContext("2d");
- case "CanvasRenderingContext2D":
- ctx = ctx || img;
- can = can || ctx.canvas;
- imgd = ctx.getImageData(0, 0, can.width, can.height);
- case "ImageData":
- imgd = imgd || img;
- width = imgd.width;
- if (typeOf(imgd.data) == "CanvasPixelArray")
- buf8 = new Uint8Array(imgd.data);
- else
- buf8 = imgd.data;
- case "Array":
- case "CanvasPixelArray":
- buf8 = buf8 || new Uint8Array(img);
- case "Uint8Array":
- case "Uint8ClampedArray":
- buf8 = buf8 || img;
- buf32 = new Uint32Array(buf8.buffer);
- case "Uint32Array":
- buf32 = buf32 || img;
- buf8 = buf8 || new Uint8Array(buf32.buffer);
- width = width || buf32.length;
- height = buf32.length / width;
- }
-
- return {
- can: can,
- ctx: ctx,
- imgd: imgd,
- buf8: buf8,
- buf32: buf32,
- width: width,
- height: height,
- };
- }
-
- // partitions a rect of wid x hgt into
- // array of bboxes of w0 x h0 (or less)
- function makeBoxes(wid, hgt, w0, h0) {
- var wnum = ~~(wid/w0), wrem = wid%w0,
- hnum = ~~(hgt/h0), hrem = hgt%h0,
- xend = wid-wrem, yend = hgt-hrem;
-
- var bxs = [];
- for (var y = 0; y < hgt; y += h0)
- for (var x = 0; x < wid; x += w0)
- bxs.push({x:x, y:y, w:(x==xend?wrem:w0), h:(y==yend?hrem:h0)});
-
- return bxs;
- }
-
- // iterates @bbox within a parent rect of width @wid; calls @fn, passing index within parent
- function iterBox(bbox, wid, fn) {
- var b = bbox,
- i0 = b.y * wid + b.x,
- i1 = (b.y + b.h - 1) * wid + (b.x + b.w - 1),
- cnt = 0, incr = wid - b.w + 1, i = i0;
-
- do {
- fn.call(this, i);
- i += (++cnt % b.w == 0) ? incr : 1;
- } while (i <= i1);
- }
-
- // returns array of hash keys sorted by their values
- function sortedHashKeys(obj, desc) {
- var keys = [];
-
- for (var key in obj)
- keys.push(key);
-
- return sort.call(keys, function(a,b) {
- return desc ? obj[b] - obj[a] : obj[a] - obj[b];
- });
- }
-
- // expose
- this.RgbQuant = RgbQuant;
-
- // expose to commonJS
- if (typeof module !== 'undefined' && module.exports) {
- module.exports = RgbQuant;
- }
-
-}).call(this);
\ No newline at end of file
diff --git a/libs/rgbquant.min.js b/libs/rgbquant.min.js
new file mode 100644
index 00000000..1cc0104e
--- /dev/null
+++ b/libs/rgbquant.min.js
@@ -0,0 +1,2 @@
+// © 2015, Leon Sorokin, MIT
+(function(){function t(t){var s;t=t||{},this.method=t.method||2,this.colors=t.colors||256,this.initColors=t.initColors||4096,this.initDist=t.initDist||.01,this.distIncr=t.distIncr||.005,this.hueGroups=t.hueGroups||10,this.satGroups=t.satGroups||10,this.lumGroups=t.lumGroups||10,this.minHueCols=t.minHueCols||0,this.hueStats=this.minHueCols?new i(this.hueGroups,this.minHueCols):null,this.boxSize=t.boxSize||[64,64],this.boxPxls=t.boxPxls||2,this.palLocked=!1,this.dithKern=t.dithKern||null,this.dithSerp=t.dithSerp||!1,this.dithDelta=t.dithDelta||0,this.histogram={},this.idxrgb=t.palette?t.palette.slice(0):[],this.idxi32=[],this.i32idx={},this.i32rgb={},this.useCache=!1!==t.useCache,this.cacheFreq=t.cacheFreq||10,this.reIndex=t.reIndex||0==this.idxrgb.length,this.colorDist="manhattan"==t.colorDist?n:r,0>>0;s.idxi32[i]=r,s.i32idx[r]=i,s.i32rgb[r]=t})}function i(t,i){this.numGroups=t,this.minCols=i,this.stats={};for(var r=-1;r>8,b=(16711680&x)>>16,m=this.nearestColor(x),v=255&m,x=(65280&m)>>8,m=(16711680&m)>>16;if(h[f]=255<<24|m<<16|x<<8|v,this.dithDelta)if(this.colorDist([p,g,b],[v,x,m])>8,A=(16711680&h[D])>>16,I=Math.max(0,Math.min(255,I+y*M)),P=Math.max(0,Math.min(255,P+w*M)),M=Math.max(0,Math.min(255,A+S*M)),h[D]=255<<24|M<<16|P<<8|I)}}}return h},t.prototype.buildPal=function(t){if(!(this.palLocked||0this.colors){for(var i,r=t.length,s={},e=0,h=!1,n=0;n>8,(16711680&t)>>16]}),o=r=a.length,u=this.initDist;if(o>this.colors){for(;o>this.colors;){for(var l=[],n=0;n3*this.colors?this.initDist:this.distIncr}if(o>24!=0&&(this.hueStats&&this.hueStats.check(i),i in r?r[i]++:r[i]=1)},t.prototype.colorStats2D=function(e,h){var t=this.boxSize[0],i=this.boxSize[1],n=t*i,i=function(t,i,r,s){for(var e=t%r,h=i%s,n=t-e,a=i-h,o=[],u=0;u>24!=0&&(o.hueStats&&o.hueStats.check(i),i in a?a[i]++:i in s?++s[i]>=r&&(a[i]=s[i]):s[i]=1)})}),this.hueStats&&this.hueStats.inject(a)},t.prototype.sortPal=function(){var e=this;this.idxi32.sort(function(t,i){var r=e.i32idx[t],s=e.i32idx[i],t=e.idxrgb[r],i=e.idxrgb[s],r=a(t[0],t[1],t[2]),s=a(i[0],i[1],i[2]),t=t[0]==t[1]&&t[1]==t[2]?-1:c(r.h,e.hueGroups),t=(i[0]==i[1]&&i[1]==i[2]?-1:c(s.h,e.hueGroups))-t;if(t)return-t;t=+s.l.toFixed(2)-+r.l.toFixed(2);if(t)return-t;r=+s.s.toFixed(2)-+r.s.toFixed(2);return r?-r:void 0}),this.idxi32.forEach(function(t,i){e.idxrgb[i]=e.i32rgb[t],e.i32idx[t]=i})},t.prototype.nearestColor=function(t){t=this.nearestIndex(t);return null===t?0:this.idxi32[t]},t.prototype.nearestIndex=function(t){if((4278190080&t)>>24==0)return null;if(this.useCache&&""+t in this.i32idx)return this.i32idx[t];for(var i,r,s=1e3,e=[255&t,(65280&t)>>8,(16711680&t)>>16],h=this.idxrgb.length,n=0;n=this.cacheFreq;r=t[i++])this.i32idx[r]=this.nearestIndex(r)},i.prototype.check=function(t){this.groupsFull==this.numGroups+1&&(this.check=function(){});var i=255&t,r=(65280&t)>>8,s=(16711680&t)>>16,i=i==r&&r==s?-1:c(a(i,r,s).h,this.numGroups),r=this.stats[i],s=this.minCols;r.num++,r.num>s||(r.num==s&&this.groupsFull++,r.num<=s&&this.stats[i].cols.push(t))},i.prototype.inject=function(i){for(var t=-1;t>>=1;return(n+t)/r};return m.int32=function(){return 0|p.g(4)},m.quick=function(){return p.g(4)/4294967296},m.double=m,q(s(p.S),a),(t.pass||e||function(n,r,t,e){return e&&(e.S&&o(e,p),n.state=function(){return o(p,{})}),t?(b[g]=n,r):n})(m,f,"global"in t?t.global:this==b,t.state)}function n(n){var r,t=n.length,u=this,e=0,o=u.i=u.j=0,i=u.S=[];for(t||(n=[t++]);e 1) {
+ x = x2;
+ y = y2;
+ } else if (t > 0) {
+ x += dx * t;
+ y += dy * t;
+ }
+ }
+
+ dx = x1 - x;
+ dy = y1 - y;
+
+ return dx * dx + dy * dy;
+ }
+ // rest of the code doesn't care about point format
+
+ // basic distance-based simplification
+ function simplifyRadialDist(points, sqTolerance) {
+ let prevPoint = points[0];
+ const newPoints = [prevPoint];
+ let point;
+
+ for (let i = 1; i < points.length; i++) {
+ point = points[i];
+ if (!point) continue;
+
+ if (getSqDist(point, prevPoint) > sqTolerance) {
+ newPoints.push(point);
+ prevPoint = point;
+ }
+ }
+
+ if (prevPoint !== point) newPoints.push(point);
+ return newPoints;
+ }
+
+ function simplifyDPStep(points, first, last, sqTolerance, simplified) {
+ let maxSqDist = sqTolerance;
+ let index = first;
+
+ for (let i = first + 1; i < last; i++) {
+ const sqDist = getSqSegDist(points[i], points[first], points[last]);
+
+ if (sqDist > maxSqDist) {
+ index = i;
+ maxSqDist = sqDist;
+ }
+ }
+
+ if (maxSqDist > sqTolerance) {
+ if (index - first > 1) simplifyDPStep(points, first, index, sqTolerance, simplified);
+ simplified.push(points[index]);
+ if (last - index > 1) simplifyDPStep(points, index, last, sqTolerance, simplified);
+ }
+ }
+
+ // simplification using Ramer-Douglas-Peucker algorithm
+ function simplifyDouglasPeucker(points, sqTolerance) {
+ const last = points.length - 1;
+
+ const simplified = [points[0]];
+ simplifyDPStep(points, 0, last, sqTolerance, simplified);
+ simplified.push(points[last]);
+
+ return simplified;
+ }
+
+ // both algorithms combined for awesome performance
+ function simplify(points, tolerance, highestQuality = false) {
+ if (points.length <= 2) return points;
+
+ const sqTolerance = tolerance * tolerance;
+
+ points = highestQuality ? points : simplifyRadialDist(points, sqTolerance);
+ points = simplifyDouglasPeucker(points, sqTolerance);
+
+ return points;
+ }
+
+ window.simplify = simplify;
+}
diff --git a/libs/three.min.js b/libs/three.min.js
index 0652e62b..509bffa0 100644
--- a/libs/three.min.js
+++ b/libs/three.min.js
@@ -1,1010 +1,6 @@
-// threejs.org/license
-(function(k,Ba){"object"===typeof exports&&"undefined"!==typeof module?Ba(exports):"function"===typeof define&&define.amd?define(["exports"],Ba):(k=k||self,Ba(k.THREE={}))})(this,function(k){function Ba(){}function w(a,b){this.x=a||0;this.y=b||0}function ua(a,b,c,d){this._x=a||0;this._y=b||0;this._z=c||0;this._w=void 0!==d?d:1}function n(a,b,c){this.x=a||0;this.y=b||0;this.z=c||0}function Y(){this.elements=[1,0,0,0,1,0,0,0,1];0h)return!1}return!0}function nb(a,b){this.center=void 0!==a?a:new n;this.radius=void 0!==b?b:0}function Sb(a,b){this.origin=void 0!==a?a:new n;this.direction=void 0!==b?b:new n}function R(a,b,c){this.a=void 0!==a?a:new n;this.b=void 0!==b?b:new n;this.c=void 0!==c?c:new n}function H(a,b,c){return void 0===b&&void 0===
-c?this.set(a):this.setRGB(a,b,c)}function Rf(a,b,c){0>c&&(c+=1);1c?b:c<2/3?a+6*(b-a)*(2/3-c):a}function Sf(a){return.04045>a?.0773993808*a:Math.pow(.9478672986*a+.0521327014,2.4)}function Tf(a){return.0031308>a?12.92*a:1.055*Math.pow(a,.41666)-.055}function zc(a,b,c,d,e,f){this.a=a;this.b=b;this.c=c;this.normal=d&&d.isVector3?d:new n;this.vertexNormals=Array.isArray(d)?d:[];this.color=e&&e.isColor?e:new H;this.vertexColors=Array.isArray(e)?e:[];this.materialIndex=
-void 0!==f?f:0}function M(){Object.defineProperty(this,"id",{value:Ti++});this.uuid=L.generateUUID();this.name="";this.type="Material";this.fog=!0;this.blending=1;this.side=0;this.vertexTangents=this.flatShading=!1;this.vertexColors=0;this.opacity=1;this.transparent=!1;this.blendSrc=204;this.blendDst=205;this.blendEquation=100;this.blendEquationAlpha=this.blendDstAlpha=this.blendSrcAlpha=null;this.depthFunc=3;this.depthWrite=this.depthTest=!0;this.stencilWriteMask=255;this.stencilFunc=519;this.stencilRef=
-0;this.stencilFuncMask=255;this.stencilZPass=this.stencilZFail=this.stencilFail=7680;this.stencilWrite=!1;this.clippingPlanes=null;this.clipShadows=this.clipIntersection=!1;this.shadowSide=null;this.colorWrite=!0;this.precision=null;this.polygonOffset=!1;this.polygonOffsetUnits=this.polygonOffsetFactor=0;this.dithering=!1;this.alphaTest=0;this.premultipliedAlpha=!1;this.toneMapped=this.visible=!0;this.userData={};this.needsUpdate=!0}function Ga(a){M.call(this);this.type="MeshBasicMaterial";this.color=
-new H(16777215);this.lightMap=this.map=null;this.lightMapIntensity=1;this.aoMap=null;this.aoMapIntensity=1;this.envMap=this.alphaMap=this.specularMap=null;this.combine=0;this.reflectivity=1;this.refractionRatio=.98;this.wireframe=!1;this.wireframeLinewidth=1;this.wireframeLinejoin=this.wireframeLinecap="round";this.morphTargets=this.skinning=!1;this.setValues(a)}function O(a,b,c){if(Array.isArray(a))throw new TypeError("THREE.BufferAttribute: array should be a Typed Array.");this.name="";this.array=
-a;this.itemSize=b;this.count=void 0!==a?a.length/b:0;this.normalized=!0===c;this.dynamic=!1;this.updateRange={offset:0,count:-1};this.version=0}function xd(a,b,c){O.call(this,new Int8Array(a),b,c)}function yd(a,b,c){O.call(this,new Uint8Array(a),b,c)}function zd(a,b,c){O.call(this,new Uint8ClampedArray(a),b,c)}function Ad(a,b,c){O.call(this,new Int16Array(a),b,c)}function Tb(a,b,c){O.call(this,new Uint16Array(a),b,c)}function Bd(a,b,c){O.call(this,new Int32Array(a),b,c)}function Ub(a,b,c){O.call(this,
-new Uint32Array(a),b,c)}function A(a,b,c){O.call(this,new Float32Array(a),b,c)}function Cd(a,b,c){O.call(this,new Float64Array(a),b,c)}function jh(){this.vertices=[];this.normals=[];this.colors=[];this.uvs=[];this.uvs2=[];this.groups=[];this.morphTargets={};this.skinWeights=[];this.skinIndices=[];this.boundingSphere=this.boundingBox=null;this.groupsNeedUpdate=this.uvsNeedUpdate=this.colorsNeedUpdate=this.normalsNeedUpdate=this.verticesNeedUpdate=!1}function kh(a){if(0===a.length)return-Infinity;for(var b=
-a[0],c=1,d=a.length;cb&&(b=a[c]);return b}function E(){Object.defineProperty(this,"id",{value:Ui+=2});this.uuid=L.generateUUID();this.name="";this.type="BufferGeometry";this.index=null;this.attributes={};this.morphAttributes={};this.groups=[];this.boundingSphere=this.boundingBox=null;this.drawRange={start:0,count:Infinity};this.userData={}}function ja(a,b){B.call(this);this.type="Mesh";this.geometry=void 0!==a?a:new E;this.material=void 0!==b?b:new Ga({color:16777215*Math.random()});this.drawMode=
-0;this.updateMorphTargets()}function lh(a,b,c,d,e,f,g,h){if(null===(1===b.side?d.intersectTriangle(g,f,e,!0,h):d.intersectTriangle(e,f,g,2!==b.side,h)))return null;Ee.copy(h);Ee.applyMatrix4(a.matrixWorld);b=c.ray.origin.distanceTo(Ee);return bc.far?null:{distance:b,point:Ee.clone(),object:a}}function Fe(a,b,c,d,e,f,g,h,l,m,q){Vb.fromBufferAttribute(e,l);Wb.fromBufferAttribute(e,m);Xb.fromBufferAttribute(e,q);e=a.morphTargetInfluences;if(b.morphTargets&&f&&e){Uf.set(0,0,0);Vf.set(0,0,0);
-Wf.set(0,0,0);for(var u=0,t=f.length;ug;g++)a.setRenderTarget(f,g),a.clear(b,c,d);a.setRenderTarget(e)}}function Ab(a,b,c){la.call(this,a,b,c)}function Zb(a,b,c,d,e,f,g,h,l,m,q,u){W.call(this,null,f,g,h,l,m,d,e,q,u);this.image={data:a||null,
-width:b||1,height:c||1};this.magFilter=void 0!==l?l:1003;this.minFilter=void 0!==m?m:1003;this.flipY=this.generateMipmaps=!1;this.unpackAlignment=1;this.needsUpdate=!0}function cb(a,b){this.normal=void 0!==a?a:new n(1,0,0);this.constant=void 0!==b?b:0}function Ed(a,b,c,d,e,f){this.planes=[void 0!==a?a:new cb,void 0!==b?b:new cb,void 0!==c?c:new cb,void 0!==d?d:new cb,void 0!==e?e:new cb,void 0!==f?f:new cb]}function Xf(){function a(e,f){!1!==c&&(d(e,f),b.requestAnimationFrame(a))}var b=null,c=!1,
-d=null;return{start:function(){!0!==c&&null!==d&&(b.requestAnimationFrame(a),c=!0)},stop:function(){c=!1},setAnimationLoop:function(a){d=a},setContext:function(a){b=a}}}function Wi(a){function b(b,c){var d=b.array,e=b.dynamic?35048:35044,h=a.createBuffer();a.bindBuffer(c,h);a.bufferData(c,d,e);b.onUploadCallback();c=5126;d instanceof Float32Array?c=5126:d instanceof Float64Array?console.warn("THREE.WebGLAttributes: Unsupported data buffer format: Float64Array."):d instanceof Uint16Array?c=5123:d instanceof
-Int16Array?c=5122:d instanceof Uint32Array?c=5125:d instanceof Int32Array?c=5124:d instanceof Int8Array?c=5120:d instanceof Uint8Array&&(c=5121);return{buffer:h,type:c,bytesPerElement:d.BYTES_PER_ELEMENT,version:b.version}}var c=new WeakMap;return{get:function(a){a.isInterleavedBufferAttribute&&(a=a.data);return c.get(a)},remove:function(b){b.isInterleavedBufferAttribute&&(b=b.data);var d=c.get(b);d&&(a.deleteBuffer(d.buffer),c.delete(b))},update:function(d,e){d.isInterleavedBufferAttribute&&(d=d.data);
-var f=c.get(d);if(void 0===f)c.set(d,b(d,e));else if(f.versionm;m++){if(u=d[m])if(h=u[0],l=u[1]){q&&e.addAttribute("morphTarget"+m,q[h]);f&&e.addAttribute("morphNormal"+m,f[h]);c[m]=l;continue}c[m]=0}g.getUniforms().setValue(a,"morphTargetInfluences",c)}}}function gj(a,b,c,d){var e={};return{update:function(a){var f=d.render.frame,h=a.geometry,l=b.get(a,h);e[l.id]!==f&&(h.isGeometry&&l.updateFromObject(a),b.update(l),e[l.id]=f);a.isInstancedMesh&&c.update(a.instanceMatrix,34962);return l},dispose:function(){e={}}}}function ob(a,b,c,d,e,f,g,h,l,m){a=
-void 0!==a?a:[];W.call(this,a,void 0!==b?b:301,c,d,e,f,void 0!==g?g:1022,h,l,m);this.flipY=!1}function Ec(a,b,c,d){W.call(this,null);this.image={data:a||null,width:b||1,height:c||1,depth:d||1};this.minFilter=this.magFilter=1003;this.wrapR=1001;this.flipY=this.generateMipmaps=!1;this.needsUpdate=!0}function Fc(a,b,c,d){W.call(this,null);this.image={data:a||null,width:b||1,height:c||1,depth:d||1};this.minFilter=this.magFilter=1003;this.wrapR=1001;this.flipY=this.generateMipmaps=!1;this.needsUpdate=
-!0}function Gc(a,b,c){var d=a[0];if(0>=d||0");return a.replace($f,Zf)}function Eh(a,b,c,d){a="";for(b=parseInt(b);bc;c++)b.probe.push(new n);var d=new n,e=new U,f=new U;return{setup:function(c,h,l){for(var g=0,q=0,u=0,k=0;9>k;k++)b.probe[k].set(0,0,0);var r=h=0,p=0,v=0,n=0,z=0,y=0,V=0;l=l.matrixWorldInverse;c.sort(ek);k=0;for(var P=c.length;kwa;wa++)b.probe[wa].addScaledVector(C.sh.coefficients[wa],w);else if(C.isDirectionalLight){var G=a.get(C);G.color.copy(C.color).multiplyScalar(C.intensity);G.direction.setFromMatrixPosition(C.matrixWorld);d.setFromMatrixPosition(C.target.matrixWorld);G.direction.sub(d);G.direction.transformDirection(l);if(G.shadow=C.castShadow)w=C.shadow,G.shadowBias=w.bias,G.shadowRadius=w.radius,G.shadowMapSize=w.mapSize,b.directionalShadowMap[h]=wa,b.directionalShadowMatrix[h]=
-C.shadow.matrix,z++;b.directional[h]=G;h++}else if(C.isSpotLight){G=a.get(C);G.position.setFromMatrixPosition(C.matrixWorld);G.position.applyMatrix4(l);G.color.copy(Cb).multiplyScalar(w);G.distance=A;G.direction.setFromMatrixPosition(C.matrixWorld);d.setFromMatrixPosition(C.target.matrixWorld);G.direction.sub(d);G.direction.transformDirection(l);G.coneCos=Math.cos(C.angle);G.penumbraCos=Math.cos(C.angle*(1-C.penumbra));G.decay=C.decay;if(G.shadow=C.castShadow)w=C.shadow,G.shadowBias=w.bias,G.shadowRadius=
-w.radius,G.shadowMapSize=w.mapSize,b.spotShadowMap[p]=wa,b.spotShadowMatrix[p]=C.shadow.matrix,V++;b.spot[p]=G;p++}else if(C.isRectAreaLight)G=a.get(C),G.color.copy(Cb).multiplyScalar(w),G.position.setFromMatrixPosition(C.matrixWorld),G.position.applyMatrix4(l),f.identity(),e.copy(C.matrixWorld),e.premultiply(l),f.extractRotation(e),G.halfWidth.set(.5*C.width,0,0),G.halfHeight.set(0,.5*C.height,0),G.halfWidth.applyMatrix4(f),G.halfHeight.applyMatrix4(f),b.rectArea[v]=G,v++;else if(C.isPointLight){G=
-a.get(C);G.position.setFromMatrixPosition(C.matrixWorld);G.position.applyMatrix4(l);G.color.copy(C.color).multiplyScalar(C.intensity);G.distance=C.distance;G.decay=C.decay;if(G.shadow=C.castShadow)w=C.shadow,G.shadowBias=w.bias,G.shadowRadius=w.radius,G.shadowMapSize=w.mapSize,G.shadowCameraNear=w.camera.near,G.shadowCameraFar=w.camera.far,b.pointShadowMap[r]=wa,b.pointShadowMatrix[r]=C.shadow.matrix,y++;b.point[r]=G;r++}else C.isHemisphereLight&&(G=a.get(C),G.direction.setFromMatrixPosition(C.matrixWorld),
-G.direction.transformDirection(l),G.direction.normalize(),G.skyColor.copy(C.color).multiplyScalar(w),G.groundColor.copy(C.groundColor).multiplyScalar(w),b.hemi[n]=G,n++)}b.ambient[0]=g;b.ambient[1]=q;b.ambient[2]=u;c=b.hash;if(c.directionalLength!==h||c.pointLength!==r||c.spotLength!==p||c.rectAreaLength!==v||c.hemiLength!==n||c.numDirectionalShadows!==z||c.numPointShadows!==y||c.numSpotShadows!==V)b.directional.length=h,b.spot.length=p,b.rectArea.length=v,b.point.length=r,b.hemi.length=n,b.directionalShadowMap.length=
-z,b.pointShadowMap.length=y,b.spotShadowMap.length=V,b.directionalShadowMatrix.length=z,b.pointShadowMatrix.length=y,b.spotShadowMatrix.length=V,c.directionalLength=h,c.pointLength=r,c.spotLength=p,c.rectAreaLength=v,c.hemiLength=n,c.numDirectionalShadows=z,c.numPointShadows=y,c.numSpotShadows=V,b.version=gk++},state:b}}function Ih(){var a=new fk,b=[],c=[];return{init:function(){b.length=0;c.length=0},state:{lightsArray:b,shadowsArray:c,lights:a},setupLights:function(d){a.setup(b,c,d)},pushLight:function(a){b.push(a)},
-pushShadow:function(a){c.push(a)}}}function hk(){function a(c){c=c.target;c.removeEventListener("dispose",a);b.delete(c)}var b=new WeakMap;return{get:function(c,d){if(!1===b.has(c)){var e=new Ih;b.set(c,new WeakMap);b.get(c).set(d,e);c.addEventListener("dispose",a)}else!1===b.get(c).has(d)?(e=new Ih,b.get(c).set(d,e)):e=b.get(c).get(d);return e},dispose:function(){b=new WeakMap}}}function Db(a){M.call(this);this.type="MeshDepthMaterial";this.depthPacking=3200;this.morphTargets=this.skinning=!1;this.displacementMap=
-this.alphaMap=this.map=null;this.displacementScale=1;this.displacementBias=0;this.wireframe=!1;this.wireframeLinewidth=1;this.fog=!1;this.setValues(a)}function Eb(a){M.call(this);this.type="MeshDistanceMaterial";this.referencePosition=new n;this.nearDistance=1;this.farDistance=1E3;this.morphTargets=this.skinning=!1;this.displacementMap=this.alphaMap=this.map=null;this.displacementScale=1;this.displacementBias=0;this.fog=!1;this.setValues(a)}function Jh(a,b,c){function d(b,c,d,e,f,g){var h=b.geometry;
-var l=m;var p=b.customDepthMaterial;d.isPointLight&&(l=q,p=b.customDistanceMaterial);p?l=p:(p=!1,c.morphTargets&&(h&&h.isBufferGeometry?p=h.morphAttributes&&h.morphAttributes.position&&0\nvoid main() {\n float mean = 0.0;\n float squared_mean = 0.0;\n \n\tfloat depth = unpackRGBAToDepth( texture2D( shadow_pass, ( gl_FragCoord.xy ) / resolution ) );\n for ( float i = -1.0; i < 1.0 ; i += SAMPLE_RATE) {\n #ifdef HORIZONAL_PASS\n vec2 distribution = decodeHalfRGBA ( texture2D( shadow_pass, ( gl_FragCoord.xy + vec2( i, 0.0 ) * radius ) / resolution ) );\n mean += distribution.x;\n squared_mean += distribution.y * distribution.y + distribution.x * distribution.x;\n #else\n float depth = unpackRGBAToDepth( texture2D( shadow_pass, ( gl_FragCoord.xy + vec2( 0.0, i ) * radius ) / resolution ) );\n mean += depth;\n squared_mean += depth * depth;\n #endif\n }\n mean = mean * HALF_SAMPLE_RATE;\n squared_mean = squared_mean * HALF_SAMPLE_RATE;\n float std_dev = pow( squared_mean - mean * mean, 0.5 );\n gl_FragColor = encodeHalfRGBA( vec2( mean, std_dev ) );\n}"}),
-p=r.clone();p.defines.HORIZONAL_PASS=1;var v=new E;v.addAttribute("position",new O(new Float32Array([-1,-1,.5,3,-1,.5,-1,3,.5]),3));var n=new ja(v,r);for(v=0;4!==v;++v){var z=0!==(v&1),y=0!==(v&2),V=new Db({depthPacking:3201,morphTargets:z,skinning:y});m[v]=V;z=new Eb({morphTargets:z,skinning:y});q[v]=z}var P=this;this.enabled=!1;this.autoUpdate=!0;this.needsUpdate=!1;this.type=1;this.render=function(d,m,q){if(!1!==P.enabled&&(!1!==P.autoUpdate||!1!==P.needsUpdate)&&0!==d.length){var u=a.getRenderTarget(),
-k=a.getActiveCubeFace(),t=a.getActiveMipmapLevel(),v=a.state;v.setBlending(0);v.buffers.color.setClear(1,1,1,1);v.buffers.depth.setTest(!0);v.setScissorTest(!1);for(var x=0,y=d.length;xc||g.y>c)console.warn("THREE.WebGLShadowMap:",z,"has shadow exceeding max texture size, reducing"),g.x>c&&(h.x=Math.floor(c/X.x),
-g.x=h.x*X.x,T.mapSize.x=h.x),g.y>c&&(h.y=Math.floor(c/X.y),g.y=h.y*X.y,T.mapSize.y=h.y);null!==T.map||T.isPointLightShadow||3!==this.type||(X={minFilter:1006,magFilter:1006,format:1023},T.map=new la(g.x,g.y,X),T.map.texture.name=z.name+".shadowMap",T.mapPass=new la(g.x,g.y,X),T.camera.updateProjectionMatrix());null===T.map&&(X={minFilter:1003,magFilter:1003,format:1023},T.map=new la(g.x,g.y,X),T.map.texture.name=z.name+".shadowMap",T.camera.updateProjectionMatrix());a.setRenderTarget(T.map);a.clear();
-X=T.getViewportCount();for(var V=0;Vd||a.height>d)e=d/Math.max(a.width,a.height);if(1>e||!0===b){if("undefined"!==typeof HTMLImageElement&&a instanceof HTMLImageElement||"undefined"!==typeof HTMLCanvasElement&&a instanceof HTMLCanvasElement||"undefined"!==typeof ImageBitmap&&a instanceof ImageBitmap)return d=b?L.floorPowerOfTwo:Math.floor,
-b=d(e*a.width),e=d(e*a.height),void 0===G&&(G=h(b,e)),c=c?h(b,e):G,c.width=b,c.height=e,c.getContext("2d").drawImage(a,0,0,b,e),console.warn("THREE.WebGLRenderer: Texture has been resized from ("+a.width+"x"+a.height+") to ("+b+"x"+e+")."),c;"data"in a&&console.warn("THREE.WebGLRenderer: Image in DataTexture is too big ("+a.width+"x"+a.height+").")}return a}function m(a){return L.isPowerOfTwo(a.width)&&L.isPowerOfTwo(a.height)}function q(a,b){return a.generateMipmaps&&b&&1003!==a.minFilter&&1006!==
-a.minFilter}function u(b,c,e,f){a.generateMipmap(b);d.get(c).__maxMipLevel=Math.log(Math.max(e,f))*Math.LOG2E}function k(a,c){if(!e.isWebGL2)return a;var d=a;6403===a&&(5126===c&&(d=33326),5131===c&&(d=33325),5121===c&&(d=33321));6407===a&&(5126===c&&(d=34837),5131===c&&(d=34843),5121===c&&(d=32849));6408===a&&(5126===c&&(d=34836),5131===c&&(d=34842),5121===c&&(d=32856));33325===d||33326===d||34842===d||34836===d?b.get("EXT_color_buffer_float"):(34843===d||34837===d)&&console.warn("THREE.WebGLRenderer: Floating point textures with RGB format not supported. Please use RGBA instead.");
-return d}function r(a){return 1003===a||1004===a||1005===a?9728:9729}function p(b){b=b.target;b.removeEventListener("dispose",p);var c=d.get(b);void 0!==c.__webglInit&&(a.deleteTexture(c.__webglTexture),d.remove(b));b.isVideoTexture&&wa.delete(b);g.memory.textures--}function v(b){b=b.target;b.removeEventListener("dispose",v);var c=d.get(b),e=d.get(b.texture);if(b){void 0!==e.__webglTexture&&a.deleteTexture(e.__webglTexture);b.depthTexture&&b.depthTexture.dispose();if(b.isWebGLRenderTargetCube)for(e=
-0;6>e;e++)a.deleteFramebuffer(c.__webglFramebuffer[e]),c.__webglDepthbuffer&&a.deleteRenderbuffer(c.__webglDepthbuffer[e]);else a.deleteFramebuffer(c.__webglFramebuffer),c.__webglDepthbuffer&&a.deleteRenderbuffer(c.__webglDepthbuffer);if(b.isWebGLMultiviewRenderTarget){a.deleteTexture(c.__webglColorTexture);a.deleteTexture(c.__webglDepthStencilTexture);g.memory.textures-=2;e=0;for(var f=c.__webglViewFramebuffers.length;er;r++)t[r]=p||g?g?b.image[r].image:b.image[r]:l(b.image[r],!1,!0,e.maxCubemapSize);var v=t[0],n=m(v)||e.isWebGL2,x=f.convert(b.format),y=f.convert(b.type),z=k(x,y);V(34067,b,n);if(p){for(r=0;6>r;r++){var T=t[r].mipmaps;for(p=0;pr;r++)if(g)for(c.texImage2D(34069+r,0,z,t[r].width,t[r].height,0,x,y,t[r].data),p=0;p=e.maxTextures&&console.warn("THREE.WebGLTextures: Trying to use "+a+" texture units while this GPU supports only "+e.maxTextures);I+=1;return a};this.resetTextureUnits=function(){I=0};this.setTexture2D=n;this.setTexture2DArray=function(a,b){var e=d.get(a);0z;z++)l.__webglFramebuffer[z]=
-a.createFramebuffer()}else if(l.__webglFramebuffer=a.createFramebuffer(),r)if(e.isWebGL2){l.__webglMultisampledFramebuffer=a.createFramebuffer();l.__webglColorRenderbuffer=a.createRenderbuffer();a.bindRenderbuffer(36161,l.__webglColorRenderbuffer);r=f.convert(h.texture.format);var C=f.convert(h.texture.type);r=k(r,C);C=B(h);a.renderbufferStorageMultisample(36161,C,r,h.width,h.height);a.bindFramebuffer(36160,l.__webglMultisampledFramebuffer);a.framebufferRenderbuffer(36160,36064,36161,l.__webglColorRenderbuffer);
-a.bindRenderbuffer(36161,null);h.depthBuffer&&(l.__webglDepthRenderbuffer=a.createRenderbuffer(),A(l.__webglDepthRenderbuffer,h,!0));a.bindFramebuffer(36160,null)}else console.warn("THREE.WebGLRenderer: WebGLMultisampleRenderTarget can only be used with WebGL2.");else if(x){z=h.width;var P=h.height;r=h.numViews;a.bindFramebuffer(36160,l.__webglFramebuffer);var G=b.get("OVR_multiview2");g.memory.textures+=2;C=a.createTexture();a.bindTexture(35866,C);a.texParameteri(35866,10240,9728);a.texParameteri(35866,
-10241,9728);a.texImage3D(35866,0,32856,z,P,r,0,6408,5121,null);G.framebufferTextureMultiviewOVR(36160,36064,C,0,0,r);var wa=a.createTexture();a.bindTexture(35866,wa);a.texParameteri(35866,10240,9728);a.texParameteri(35866,10241,9728);a.texImage3D(35866,0,35056,z,P,r,0,34041,34042,null);G.framebufferTextureMultiviewOVR(36160,33306,wa,0,0,r);P=Array(r);for(z=0;zz;z++)w(l.__webglFramebuffer[z],h,36064,34069+z);q(h.texture,y)&&u(34067,h.texture,h.width,h.height);c.bindTexture(34067,null)}else x||(c.bindTexture(3553,p.__webglTexture),V(3553,h.texture,y),w(l.__webglFramebuffer,h,36064,3553),q(h.texture,y)&&u(3553,h.texture,h.width,h.height),c.bindTexture(3553,null));if(h.depthBuffer){l=d.get(h);p=!0===
-h.isWebGLRenderTargetCube;if(h.depthTexture){if(p)throw Error("target.depthTexture not supported in Cube render targets");if(h&&h.isWebGLRenderTargetCube)throw Error("Depth Texture with cube render targets is not supported");a.bindFramebuffer(36160,l.__webglFramebuffer);if(!h.depthTexture||!h.depthTexture.isDepthTexture)throw Error("renderTarget.depthTexture must be an instance of THREE.DepthTexture");d.get(h.depthTexture).__webglTexture&&h.depthTexture.image.width===h.width&&h.depthTexture.image.height===
-h.height||(h.depthTexture.image.width=h.width,h.depthTexture.image.height=h.height,h.depthTexture.needsUpdate=!0);n(h.depthTexture,0);l=d.get(h.depthTexture).__webglTexture;if(1026===h.depthTexture.format)a.framebufferTexture2D(36160,36096,3553,l,0);else if(1027===h.depthTexture.format)a.framebufferTexture2D(36160,33306,3553,l,0);else throw Error("Unknown depthTexture format");}else if(p)for(l.__webglDepthbuffer=[],p=0;6>p;p++)a.bindFramebuffer(36160,l.__webglFramebuffer[p]),l.__webglDepthbuffer[p]=
-a.createRenderbuffer(),A(l.__webglDepthbuffer[p],h);else a.bindFramebuffer(36160,l.__webglFramebuffer),l.__webglDepthbuffer=a.createRenderbuffer(),A(l.__webglDepthbuffer,h);a.bindFramebuffer(36160,null)}};this.updateRenderTargetMipmap=function(a){var b=a.texture,f=m(a)||e.isWebGL2;if(q(b,f)){f=a.isWebGLRenderTargetCube?34067:3553;var g=d.get(b).__webglTexture;c.bindTexture(f,g);u(f,b,a.width,a.height);c.bindTexture(f,null)}};this.updateMultisampleRenderTarget=function(b){if(b.isWebGLMultisampleRenderTarget)if(e.isWebGL2){var c=
-d.get(b);a.bindFramebuffer(36008,c.__webglMultisampledFramebuffer);a.bindFramebuffer(36009,c.__webglFramebuffer);c=b.width;var f=b.height,g=16384;b.depthBuffer&&(g|=256);b.stencilBuffer&&(g|=1024);a.blitFramebuffer(0,0,c,f,0,0,c,f,g,9728)}else console.warn("THREE.WebGLRenderer: WebGLMultisampleRenderTarget can only be used with WebGL2.")};this.safeSetTexture2D=function(a,b){a&&a.isWebGLRenderTarget&&(!1===H&&(console.warn("THREE.WebGLTextures.safeSetTexture2D: don't use render targets as textures. Use their .texture property instead."),
-H=!0),a=a.texture);n(a,b)};this.safeSetTextureCube=function(a,b){a&&a.isWebGLRenderTargetCube&&(!1===D&&(console.warn("THREE.WebGLTextures.safeSetTextureCube: don't use cube render targets as textures. Use their .texture property instead."),D=!0),a=a.texture);a&&a.isCubeTexture||Array.isArray(a.image)&&6===a.image.length?z(a,b):y(a,b)}}function Kh(a,b,c){return{convert:function(a){if(1E3===a)return 10497;if(1001===a)return 33071;if(1002===a)return 33648;if(1003===a)return 9728;if(1004===a)return 9984;
-if(1005===a)return 9986;if(1006===a)return 9729;if(1007===a)return 9985;if(1008===a)return 9987;if(1009===a)return 5121;if(1017===a)return 32819;if(1018===a)return 32820;if(1019===a)return 33635;if(1010===a)return 5120;if(1011===a)return 5122;if(1012===a)return 5123;if(1013===a)return 5124;if(1014===a)return 5125;if(1015===a)return 5126;if(1016===a){if(c.isWebGL2)return 5131;var d=b.get("OES_texture_half_float");if(null!==d)return d.HALF_FLOAT_OES}if(1021===a)return 6406;if(1022===a)return 6407;if(1023===
-a)return 6408;if(1024===a)return 6409;if(1025===a)return 6410;if(1026===a)return 6402;if(1027===a)return 34041;if(1028===a)return 6403;if(100===a)return 32774;if(101===a)return 32778;if(102===a)return 32779;if(200===a)return 0;if(201===a)return 1;if(202===a)return 768;if(203===a)return 769;if(204===a)return 770;if(205===a)return 771;if(206===a)return 772;if(207===a)return 773;if(208===a)return 774;if(209===a)return 775;if(210===a)return 776;if(33776===a||33777===a||33778===a||33779===a)if(d=b.get("WEBGL_compressed_texture_s3tc"),
-null!==d){if(33776===a)return d.COMPRESSED_RGB_S3TC_DXT1_EXT;if(33777===a)return d.COMPRESSED_RGBA_S3TC_DXT1_EXT;if(33778===a)return d.COMPRESSED_RGBA_S3TC_DXT3_EXT;if(33779===a)return d.COMPRESSED_RGBA_S3TC_DXT5_EXT}if(35840===a||35841===a||35842===a||35843===a)if(d=b.get("WEBGL_compressed_texture_pvrtc"),null!==d){if(35840===a)return d.COMPRESSED_RGB_PVRTC_4BPPV1_IMG;if(35841===a)return d.COMPRESSED_RGB_PVRTC_2BPPV1_IMG;if(35842===a)return d.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;if(35843===a)return d.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG}if(36196===
-a&&(d=b.get("WEBGL_compressed_texture_etc1"),null!==d))return d.COMPRESSED_RGB_ETC1_WEBGL;if(37808===a||37809===a||37810===a||37811===a||37812===a||37813===a||37814===a||37815===a||37816===a||37817===a||37818===a||37819===a||37820===a||37821===a)if(d=b.get("WEBGL_compressed_texture_astc"),null!==d)return a;if(103===a||104===a){if(c.isWebGL2){if(103===a)return 32775;if(104===a)return 32776}d=b.get("EXT_blend_minmax");if(null!==d){if(103===a)return d.MIN_EXT;if(104===a)return d.MAX_EXT}}if(1020===a){if(c.isWebGL2)return 34042;
-d=b.get("WEBGL_depth_texture");if(null!==d)return d.UNSIGNED_INT_24_8_WEBGL}return 0}}}function fg(a,b,c,d){la.call(this,a,b,d);this.stencilBuffer=this.depthBuffer=!1;this.numViews=c}function kk(a,b){function c(a){if(a.isArrayCamera)return a.cameras;q[0]=a;return q}function d(a){if(void 0===a.isArrayCamera)return!0;a=a.cameras;if(a.length>r)return!1;for(var b=1,c=a.length;bf.matrixWorld.determinant();ba.setMaterial(e,h);var l=k(a,c,e,f),m=!1;if(b!==d.id||bc!==l.id||S!==(!0===e.wireframe))b=d.id,bc=l.id,S=!0===e.wireframe,m=!0;f.morphTargetInfluences&&(ya.update(f,d,e,l),m=!0);h=d.index;var q=d.attributes.position;c=1;!0===e.wireframe&&(h=xa.getWireframeAttribute(d),c=2);a=Aa;if(null!==h){var u=pa.get(h);a=Ba;a.setIndex(u)}if(m){if(!1!==Ea.isWebGL2||
-!f.isInstancedMesh&&!d.isInstancedBufferGeometry||null!==ra.get("ANGLE_instanced_arrays")){ba.initAttributes();m=d.attributes;l=l.getAttributes();var r=e.defaultAttributeValues;for(w in l){var p=l[w];if(0<=p){var t=m[w];if(void 0!==t){var n=t.normalized,v=t.itemSize,x=pa.get(t);if(void 0!==x){var y=x.buffer,z=x.type;x=x.bytesPerElement;if(t.isInterleavedBufferAttribute){var C=t.data,V=C.stride;t=t.offset;C&&C.isInstancedInterleavedBuffer?(ba.enableAttributeAndDivisor(p,C.meshPerAttribute),void 0===
-d.maxInstancedCount&&(d.maxInstancedCount=C.meshPerAttribute*C.count)):ba.enableAttribute(p);J.bindBuffer(34962,y);J.vertexAttribPointer(p,v,z,n,V*x,t*x)}else t.isInstancedBufferAttribute?(ba.enableAttributeAndDivisor(p,t.meshPerAttribute),void 0===d.maxInstancedCount&&(d.maxInstancedCount=t.meshPerAttribute*t.count)):ba.enableAttribute(p),J.bindBuffer(34962,y),J.vertexAttribPointer(p,v,z,n,0,0)}}else if("instanceMatrix"===w)x=pa.get(f.instanceMatrix),void 0!==x&&(y=x.buffer,z=x.type,ba.enableAttributeAndDivisor(p+
-0,1),ba.enableAttributeAndDivisor(p+1,1),ba.enableAttributeAndDivisor(p+2,1),ba.enableAttributeAndDivisor(p+3,1),J.bindBuffer(34962,y),J.vertexAttribPointer(p+0,4,z,!1,64,0),J.vertexAttribPointer(p+1,4,z,!1,64,16),J.vertexAttribPointer(p+2,4,z,!1,64,32),J.vertexAttribPointer(p+3,4,z,!1,64,48));else if(void 0!==r&&(n=r[w],void 0!==n))switch(n.length){case 2:J.vertexAttrib2fv(p,n);break;case 3:J.vertexAttrib3fv(p,n);break;case 4:J.vertexAttrib4fv(p,n);break;default:J.vertexAttrib1fv(p,n)}}}ba.disableUnusedAttributes()}null!==
-h&&J.bindBuffer(34963,u.buffer)}u=Infinity;null!==h?u=h.count:void 0!==q&&(u=q.count);h=d.drawRange.start*c;q=null!==g?g.start*c:0;var w=Math.max(h,q);g=Math.max(0,Math.min(u,h+d.drawRange.count*c,q+(null!==g?g.count*c:Infinity))-1-w+1);if(0!==g){if(f.isMesh)if(!0===e.wireframe)ba.setLineWidth(e.wireframeLinewidth*(null===N?fa:1)),a.setMode(1);else switch(f.drawMode){case 0:a.setMode(4);break;case 1:a.setMode(5);break;case 2:a.setMode(6)}else f.isLine?(e=e.linewidth,void 0===e&&(e=1),ba.setLineWidth(e*
-(null===N?fa:1)),f.isLineSegments?a.setMode(1):f.isLineLoop?a.setMode(2):a.setMode(3)):f.isPoints?a.setMode(0):f.isSprite&&a.setMode(4);f.isInstancedMesh?a.renderInstances(d,w,g,f.count):d.isInstancedBufferGeometry?a.renderInstances(d,w,g,d.maxInstancedCount):a.render(w,g)}};this.compile=function(a,b){D=ua.get(a,b);D.init();a.traverse(function(a){a.isLight&&(D.pushLight(a),a.castShadow&&D.pushShadow(a))});D.setupLights(b);a.traverse(function(b){if(b.material)if(Array.isArray(b.material))for(var c=
-0;ce.far||f.push({distance:a,distanceToRay:Math.sqrt(h),point:c,index:b,face:null,object:g}))}function mg(a,b,c,d,e,f,g,h,l){W.call(this,a,b,c,d,e,f,g,h,l);this.format=void 0!==g?g:1022;this.minFilter=void 0!==f?f:1006;this.magFilter=void 0!==e?e:1006;this.generateMipmaps=!1}function Lc(a,b,c,d,e,f,g,h,l,m,q,k){W.call(this,null,f,g,h,l,m,d,e,q,k);this.image={width:b,height:c};
-this.mipmaps=a;this.generateMipmaps=this.flipY=!1}function Pd(a,b,c,d,e,f,g,h,l){W.call(this,a,b,c,d,e,f,g,h,l);this.needsUpdate=!0}function Qd(a,b,c,d,e,f,g,h,l,m){m=void 0!==m?m:1026;if(1026!==m&&1027!==m)throw Error("DepthTexture format must be either THREE.DepthFormat or THREE.DepthStencilFormat");void 0===c&&1026===m&&(c=1012);void 0===c&&1027===m&&(c=1020);W.call(this,null,d,e,f,g,h,m,c,l);this.image={width:a,height:b};this.magFilter=void 0!==g?g:1003;this.minFilter=void 0!==h?h:1003;this.generateMipmaps=
-this.flipY=!1}function Mc(a){E.call(this);this.type="WireframeGeometry";var b=[],c,d,e,f=[0,0],g={},h=["a","b","c"];if(a&&a.isGeometry){var l=a.faces;var m=0;for(d=l.length;mc;c++){var k=q[h[c]];var t=q[h[(c+1)%3]];f[0]=Math.min(k,t);f[1]=Math.max(k,t);k=f[0]+","+f[1];void 0===g[k]&&(g[k]={index1:f[0],index2:f[1]})}}for(k in g)m=g[k],h=a.vertices[m.index1],b.push(h.x,h.y,h.z),h=a.vertices[m.index2],b.push(h.x,h.y,h.z)}else if(a&&a.isBufferGeometry)if(h=new n,null!==a.index){l=
-a.attributes.position;q=a.index;var r=a.groups;0===r.length&&(r=[{start:0,count:q.count,materialIndex:0}]);a=0;for(e=r.length;ac;c++)k=q.getX(m+c),t=q.getX(m+(c+1)%3),f[0]=Math.min(k,t),f[1]=Math.max(k,t),k=f[0]+","+f[1],void 0===g[k]&&(g[k]={index1:f[0],index2:f[1]});for(k in g)m=g[k],h.fromBufferAttribute(l,m.index1),b.push(h.x,h.y,h.z),h.fromBufferAttribute(l,m.index2),b.push(h.x,h.y,h.z)}else for(l=a.attributes.position,m=0,d=
-l.count/3;mc;c++)g=3*m+c,h.fromBufferAttribute(l,g),b.push(h.x,h.y,h.z),g=3*m+(c+1)%3,h.fromBufferAttribute(l,g),b.push(h.x,h.y,h.z);this.addAttribute("position",new A(b,3))}function Rd(a,b,c){F.call(this);this.type="ParametricGeometry";this.parameters={func:a,slices:b,stacks:c};this.fromBufferGeometry(new Nc(a,b,c));this.mergeVertices()}function Nc(a,b,c){E.call(this);this.type="ParametricBufferGeometry";this.parameters={func:a,slices:b,stacks:c};var d=[],e=[],f=[],g=[],h=new n,
-l=new n,m=new n,q=new n,k=new n,t,r;3>a.length&&console.error("THREE.ParametricGeometry: Function must now modify a Vector3 as third parameter.");var p=b+1;for(t=0;t<=c;t++){var v=t/c;for(r=0;r<=b;r++){var x=r/b;a(x,v,l);e.push(l.x,l.y,l.z);0<=x-1E-5?(a(x-1E-5,v,m),q.subVectors(l,m)):(a(x+1E-5,v,m),q.subVectors(m,l));0<=v-1E-5?(a(x,v-1E-5,m),k.subVectors(l,m)):(a(x,v+1E-5,m),k.subVectors(m,l));h.crossVectors(q,k).normalize();f.push(h.x,h.y,h.z);g.push(x,v)}}for(t=0;td&&1===a.x&&(l[b]=a.x-1);0===c.x&&0===c.z&&(l[b]=d/2/Math.PI+.5)}E.call(this);this.type="PolyhedronBufferGeometry";this.parameters={vertices:a,indices:b,radius:c,detail:d};c=c||1;d=d||0;var h=[],l=[];(function(a){for(var c=new n,d=new n,g=new n,h=0;he&&(.2>b&&(l[a+0]+=1),.2>c&&(l[a+2]+=1),.2>d&&(l[a+4]+=1))})();this.addAttribute("position",
-new A(h,3));this.addAttribute("normal",new A(h.slice(),3));this.addAttribute("uv",new A(l,2));0===d?this.computeVertexNormals():this.normalizeNormals()}function Td(a,b){F.call(this);this.type="TetrahedronGeometry";this.parameters={radius:a,detail:b};this.fromBufferGeometry(new Oc(a,b));this.mergeVertices()}function Oc(a,b){Ca.call(this,[1,1,1,-1,-1,1,-1,1,-1,1,-1,-1],[2,1,0,0,3,2,1,3,0,2,3,1],a,b);this.type="TetrahedronBufferGeometry";this.parameters={radius:a,detail:b}}function Ud(a,b){F.call(this);
-this.type="OctahedronGeometry";this.parameters={radius:a,detail:b};this.fromBufferGeometry(new cc(a,b));this.mergeVertices()}function cc(a,b){Ca.call(this,[1,0,0,-1,0,0,0,1,0,0,-1,0,0,0,1,0,0,-1],[0,2,4,0,4,3,0,3,5,0,5,2,1,2,5,1,5,3,1,3,4,1,4,2],a,b);this.type="OctahedronBufferGeometry";this.parameters={radius:a,detail:b}}function Vd(a,b){F.call(this);this.type="IcosahedronGeometry";this.parameters={radius:a,detail:b};this.fromBufferGeometry(new Pc(a,b));this.mergeVertices()}function Pc(a,b){var c=
-(1+Math.sqrt(5))/2;Ca.call(this,[-1,c,0,1,c,0,-1,-c,0,1,-c,0,0,-1,c,0,1,c,0,-1,-c,0,1,-c,c,0,-1,c,0,1,-c,0,-1,-c,0,1],[0,11,5,0,5,1,0,1,7,0,7,10,0,10,11,1,5,9,5,11,4,11,10,2,10,7,6,7,1,8,3,9,4,3,4,2,3,2,6,3,6,8,3,8,9,4,9,5,2,4,11,6,2,10,8,6,7,9,8,1],a,b);this.type="IcosahedronBufferGeometry";this.parameters={radius:a,detail:b}}function Wd(a,b){F.call(this);this.type="DodecahedronGeometry";this.parameters={radius:a,detail:b};this.fromBufferGeometry(new Qc(a,b));this.mergeVertices()}function Qc(a,b){var c=
-(1+Math.sqrt(5))/2,d=1/c;Ca.call(this,[-1,-1,-1,-1,-1,1,-1,1,-1,-1,1,1,1,-1,-1,1,-1,1,1,1,-1,1,1,1,0,-d,-c,0,-d,c,0,d,-c,0,d,c,-d,-c,0,-d,c,0,d,-c,0,d,c,0,-c,0,-d,c,0,-d,-c,0,d,c,0,d],[3,11,7,3,7,15,3,15,13,7,19,17,7,17,6,7,6,15,17,4,8,17,8,10,17,10,6,8,0,16,8,16,2,8,2,10,0,12,1,0,1,18,0,18,16,6,10,2,6,2,13,6,13,15,2,16,18,2,18,3,2,3,13,18,1,9,18,9,11,18,11,3,4,14,12,4,12,0,4,0,8,11,9,5,11,5,19,11,19,7,19,5,14,19,14,4,19,4,17,1,12,14,1,14,5,1,5,9],a,b);this.type="DodecahedronBufferGeometry";this.parameters=
-{radius:a,detail:b}}function Xd(a,b,c,d,e,f){F.call(this);this.type="TubeGeometry";this.parameters={path:a,tubularSegments:b,radius:c,radialSegments:d,closed:e};void 0!==f&&console.warn("THREE.TubeGeometry: taper has been removed.");a=new dc(a,b,c,d,e);this.tangents=a.tangents;this.normals=a.normals;this.binormals=a.binormals;this.fromBufferGeometry(a);this.mergeVertices()}function dc(a,b,c,d,e){function f(e){q=a.getPointAt(e/b,q);var f=g.normals[e];e=g.binormals[e];for(t=0;t<=d;t++){var m=t/d*Math.PI*
-2,k=Math.sin(m);m=-Math.cos(m);l.x=m*f.x+k*e.x;l.y=m*f.y+k*e.y;l.z=m*f.z+k*e.z;l.normalize();p.push(l.x,l.y,l.z);h.x=q.x+c*l.x;h.y=q.y+c*l.y;h.z=q.z+c*l.z;r.push(h.x,h.y,h.z)}}E.call(this);this.type="TubeBufferGeometry";this.parameters={path:a,tubularSegments:b,radius:c,radialSegments:d,closed:e};b=b||64;c=c||1;d=d||8;e=e||!1;var g=a.computeFrenetFrames(b,e);this.tangents=g.tangents;this.normals=g.normals;this.binormals=g.binormals;var h=new n,l=new n,m=new w,q=new n,k,t,r=[],p=[],v=[],x=[];for(k=
-0;k=b;e-=d)f=Sh(e,a[e],a[e+1],f);f&&ec(f,f.next)&&($d(f),f=f.next);return f}function ae(a,b){if(!a)return a;
-b||(b=a);do{var c=!1;if(a.steiner||!ec(a,a.next)&&0!==sa(a.prev,a,a.next))a=a.next;else{$d(a);a=b=a.prev;if(a===a.next)break;c=!0}}while(c||a!==b);return b}function be(a,b,c,d,e,f,g){if(a){if(!g&&f){var h=a,l=h;do null===l.z&&(l.z=ng(l.x,l.y,d,e,f)),l.prevZ=l.prev,l=l.nextZ=l.next;while(l!==h);l.prevZ.nextZ=null;l.prevZ=null;h=l;var m,q,k,t,r=1;do{l=h;var p=h=null;for(q=0;l;){q++;var n=l;for(m=k=0;mn!==p.next.y>n&&p.next.y!==p.y&&k<(p.next.x-
-p.x)*(n-p.y)/(p.next.y-p.y)+p.x&&(q=!q),p=p.next;while(p!==l);p=q}l=p}if(l){a=Uh(g,h);g=ae(g,g.next);a=ae(a,a.next);be(g,b,c,d,e,f);be(a,b,c,d,e,f);break a}h=h.next}g=g.next}while(g!==a)}break}}}}function lk(a,b,c,d){var e=a.prev,f=a.next;if(0<=sa(e,a,f))return!1;var g=e.x>a.x?e.x>f.x?e.x:f.x:a.x>f.x?a.x:f.x,h=e.y>a.y?e.y>f.y?e.y:f.y:a.y>f.y?a.y:f.y,l=ng(e.x=l&&d&&d.z<=
-b;){if(c!==a.prev&&c!==a.next&&Tc(e.x,e.y,a.x,a.y,f.x,f.y,c.x,c.y)&&0<=sa(c.prev,c,c.next))return!1;c=c.prevZ;if(d!==a.prev&&d!==a.next&&Tc(e.x,e.y,a.x,a.y,f.x,f.y,d.x,d.y)&&0<=sa(d.prev,d,d.next))return!1;d=d.nextZ}for(;c&&c.z>=l;){if(c!==a.prev&&c!==a.next&&Tc(e.x,e.y,a.x,a.y,f.x,f.y,c.x,c.y)&&0<=sa(c.prev,c,c.next))return!1;c=c.prevZ}for(;d&&d.z<=b;){if(d!==a.prev&&d!==a.next&&Tc(e.x,e.y,a.x,a.y,f.x,f.y,d.x,d.y)&&0<=sa(d.prev,d,d.next))return!1;d=d.nextZ}return!0}function mk(a,b){return a.x-b.x}
-function nk(a,b){var c=b,d=a.x,e=a.y,f=-Infinity;do{if(e<=c.y&&e>=c.next.y&&c.next.y!==c.y){var g=c.x+(e-c.y)*(c.next.x-c.x)/(c.next.y-c.y);if(g<=d&&g>f){f=g;if(g===d){if(e===c.y)return c;if(e===c.next.y)return c.next}var h=c.x=c.x&&c.x>=g&&d!==c.x&&Tc(eh.x)&&ce(c,a)&&(h=c,m=q)}c=
-c.next}return h}function ng(a,b,c,d,e){a=32767*(a-c)*e;b=32767*(b-d)*e;a=(a|a<<8)&16711935;a=(a|a<<4)&252645135;a=(a|a<<2)&858993459;b=(b|b<<8)&16711935;b=(b|b<<4)&252645135;b=(b|b<<2)&858993459;return(a|a<<1)&1431655765|((b|b<<1)&1431655765)<<1}function ok(a){var b=a,c=a;do{if(b.xsa(a.prev,a,a.next)?0<=sa(a,b,a.next)&&0<=sa(a,a.prev,b):0>sa(a,b,a.prev)||0>sa(a,a.next,b)}function Uh(a,b){var c=new og(a.i,a.x,a.y),d=new og(b.i,b.x,b.y),e=a.next,f=b.prev;a.next=b;b.prev=a;c.next=e;e.prev=c;d.next=c;c.prev=d;f.next=d;d.prev=f;return d}function Sh(a,b,c,d){a=new og(a,
-b,c);d?(a.next=d.next,a.prev=d,d.next.prev=a,d.next=a):(a.prev=a,a.next=a);return a}function $d(a){a.next.prev=a.prev;a.prev.next=a.next;a.prevZ&&(a.prevZ.nextZ=a.nextZ);a.nextZ&&(a.nextZ.prevZ=a.prevZ)}function og(a,b,c){this.i=a;this.x=b;this.y=c;this.nextZ=this.prevZ=this.z=this.next=this.prev=null;this.steiner=!1}function Vh(a){var b=a.length;2Number.EPSILON){var l=Math.sqrt(h),m=Math.sqrt(f*f+g*g);h=b.x-e/l;b=b.y+d/l;g=((c.x-g/m-h)*g-(c.y+f/m-b)*f)/(d*g-e*f);f=h+d*g-a.x;d=b+e*g-a.y;e=f*f+
-d*d;if(2>=e)return new w(f,d);e=Math.sqrt(e/2)}else a=!1,d>Number.EPSILON?f>Number.EPSILON&&(a=!0):d<-Number.EPSILON?f<-Number.EPSILON&&(a=!0):Math.sign(e)===Math.sign(g)&&(a=!0),a?(f=-e,e=Math.sqrt(h)):(f=d,d=e,e=Math.sqrt(h/2));return new w(f/e,d/e)}function h(a,b){for(K=a.length;0<=--K;){var c=K;var f=K-1;0>f&&(f=a.length-1);var g,h=y+2*E;for(g=0;gk;k++){var u=m[f[k]];var n=m[f[(k+1)%3]];d[0]=Math.min(u,n);d[1]=Math.max(u,n);u=d[0]+","+d[1];void 0===e[u]?e[u]={index1:d[0],index2:d[1],face1:h,face2:void 0}:e[u].face2=h}for(u in e)if(d=e[u],void 0===d.face2||g[d.face1].normal.dot(g[d.face2].normal)<=
-b)f=a[d.index1],c.push(f.x,f.y,f.z),f=a[d.index2],c.push(f.x,f.y,f.z);this.addAttribute("position",new A(c,3))}function ic(a,b,c,d,e,f,g,h){F.call(this);this.type="CylinderGeometry";this.parameters={radiusTop:a,radiusBottom:b,height:c,radialSegments:d,heightSegments:e,openEnded:f,thetaStart:g,thetaLength:h};this.fromBufferGeometry(new qb(a,b,c,d,e,f,g,h));this.mergeVertices()}function qb(a,b,c,d,e,f,g,h){function l(c){var e,f=new w,l=new n,q=0,v=!0===c?a:b,y=!0===c?1:-1;var A=p;for(e=1;e<=d;e++)u.push(0,
-x*y,0),t.push(0,y,0),r.push(.5,.5),p++;var B=p;for(e=0;e<=d;e++){var E=e/d*h+g,D=Math.cos(E);E=Math.sin(E);l.x=v*E;l.y=x*y;l.z=v*D;u.push(l.x,l.y,l.z);t.push(0,y,0);f.x=.5*D+.5;f.y=.5*E*y+.5;r.push(f.x,f.y);p++}for(e=0;ethis.duration&&
-this.resetDuration()}function qk(a){switch(a.toLowerCase()){case "scalar":case "double":case "float":case "number":case "integer":return $c;case "vector":case "vector2":case "vector3":case "vector4":return ad;case "color":return Qe;case "quaternion":return le;case "bool":case "boolean":return Pe;case "string":return Se}throw Error("THREE.KeyframeTrack: Unsupported typeName: "+a);}function rk(a){if(void 0===a.type)throw Error("THREE.KeyframeTrack: track type undefined, can not parse");var b=qk(a.type);
-if(void 0===a.times){var c=[],d=[];pa.flattenJSON(a.keys,c,d,"value");a.times=c;a.values=d}return void 0!==b.parse?b.parse(a):new b(a.name,a.times,a.values,a.interpolation)}function pg(a,b,c){var d=this,e=!1,f=0,g=0,h=void 0,l=[];this.onStart=void 0;this.onLoad=a;this.onProgress=b;this.onError=c;this.itemStart=function(a){g++;if(!1===e&&void 0!==d.onStart)d.onStart(a,f,g);e=!0};this.itemEnd=function(a){f++;if(void 0!==d.onProgress)d.onProgress(a,f,g);if(f===g&&(e=!1,void 0!==d.onLoad))d.onLoad()};
-this.itemError=function(a){if(void 0!==d.onError)d.onError(a)};this.resolveURL=function(a){return h?h(a):a};this.setURLModifier=function(a){h=a;return this};this.addHandler=function(a,b){l.push(a,b);return this};this.removeHandler=function(a){a=l.indexOf(a);-1!==a&&l.splice(a,2);return this};this.getHandler=function(a){for(var b=0,c=l.length;ba;a++)this.coefficients.push(new n)}function Xa(a,b){da.call(this,void 0,b);this.sh=void 0!==a?a:new kf}function yg(a,b,c){Xa.call(this,void 0,c);a=(new H).set(a);c=(new H).set(b);b=new n(a.r,a.g,a.b);a=new n(c.r,c.g,c.b);c=Math.sqrt(Math.PI);var d=c*Math.sqrt(.75);this.sh.coefficients[0].copy(b).add(a).multiplyScalar(c);this.sh.coefficients[1].copy(b).sub(a).multiplyScalar(d)}function zg(a,b){Xa.call(this,void 0,b);a=(new H).set(a);this.sh.coefficients[0].set(a.r,a.g,a.b).multiplyScalar(2*Math.sqrt(Math.PI))}
-function ai(){this.type="StereoCamera";this.aspect=1;this.eyeSep=.064;this.cameraL=new na;this.cameraL.layers.enable(1);this.cameraL.matrixAutoUpdate=!1;this.cameraR=new na;this.cameraR.layers.enable(2);this.cameraR.matrixAutoUpdate=!1;this._cache={focus:null,fov:null,aspect:null,near:null,far:null,zoom:null,eyeSep:null}}function Ag(a){this.autoStart=void 0!==a?a:!0;this.elapsedTime=this.oldTime=this.startTime=0;this.running=!1}function Bg(){B.call(this);this.type="AudioListener";this.context=Cg.getContext();
-this.gain=this.context.createGain();this.gain.connect(this.context.destination);this.filter=null;this.timeDelta=0;this._clock=new Ag}function dd(a){B.call(this);this.type="Audio";this.listener=a;this.context=a.context;this.gain=this.context.createGain();this.gain.connect(a.getInput());this.autoplay=!1;this.buffer=null;this.detune=0;this.loop=!1;this.offset=this.startTime=0;this.duration=void 0;this.playbackRate=1;this.isPlaying=!1;this.hasPlaybackControl=!0;this.sourceType="empty";this.filters=[]}
-function Dg(a){dd.call(this,a);this.panner=this.context.createPanner();this.panner.panningModel="HRTF";this.panner.connect(this.gain)}function Eg(a,b){this.analyser=a.context.createAnalyser();this.analyser.fftSize=void 0!==b?b:2048;this.data=new Uint8Array(this.analyser.frequencyBinCount);a.getOutput().connect(this.analyser)}function Fg(a,b,c){this.binding=a;this.valueSize=c;a=Float64Array;switch(b){case "quaternion":b=this._slerp;break;case "string":case "bool":a=Array;b=this._select;break;default:b=
-this._lerp}this.buffer=new a(4*c);this._mixBufferRegion=b;this.referenceCount=this.useCount=this.cumulativeWeight=0}function bi(a,b,c){c=c||Aa.parseTrackName(b);this._targetGroup=a;this._bindings=a.subscribe_(b,c)}function Aa(a,b,c){this.path=b;this.parsedPath=c||Aa.parseTrackName(b);this.node=Aa.findNode(a,this.parsedPath.nodeName)||a;this.rootNode=a}function ci(){this.uuid=L.generateUUID();this._objects=Array.prototype.slice.call(arguments);this.nCachedObjects_=0;var a={};this._indicesByUUID=a;
-for(var b=0,c=arguments.length;b!==c;++b)a[arguments[b].uuid]=b;this._paths=[];this._parsedPaths=[];this._bindings=[];this._bindingsIndicesByPath={};var d=this;this.stats={objects:{get total(){return d._objects.length},get inUse(){return this.total-d.nCachedObjects_}},get bindingsPerObject(){return d._bindings.length}}}function di(a,b,c){this._mixer=a;this._clip=b;this._localRoot=c||null;a=b.tracks;b=a.length;c=Array(b);for(var d={endingStart:2400,endingEnd:2400},e=0;e!==b;++e){var f=a[e].createInterpolant(null);
-c[e]=f;f.settings=d}this._interpolantSettings=d;this._interpolants=c;this._propertyBindings=Array(b);this._weightInterpolant=this._timeScaleInterpolant=this._byClipCacheIndex=this._cacheIndex=null;this.loop=2201;this._loopCount=-1;this._startTime=null;this.time=0;this._effectiveWeight=this.weight=this._effectiveTimeScale=this.timeScale=1;this.repetitions=Infinity;this.paused=!1;this.enabled=!0;this.clampWhenFinished=!1;this.zeroSlopeAtEnd=this.zeroSlopeAtStart=!0}function Gg(a){this._root=a;this._initMemoryManager();
-this.time=this._accuIndex=0;this.timeScale=1}function lf(a,b){"string"===typeof a&&(console.warn("THREE.Uniform: Type parameter is no longer needed."),a=b);this.value=a}function Hg(a,b,c){Gb.call(this,a,b);this.meshPerAttribute=c||1}function ei(a,b,c,d){this.ray=new Sb(a,b);this.near=c||0;this.far=d||Infinity;this.camera=null;this.params={Mesh:{},Line:{},LOD:{},Points:{threshold:1},Sprite:{}};Object.defineProperties(this.params,{PointCloud:{get:function(){console.warn("THREE.Raycaster: params.PointCloud has been renamed to params.Points.");
-return this.Points}}})}function fi(a,b){return a.distance-b.distance}function Ig(a,b,c,d){if(!1!==a.visible&&(a.raycast(b,c),!0===d)){a=a.children;d=0;for(var e=a.length;dc;c++,d++){var e=c/32*Math.PI*2,f=d/32*Math.PI*2;b.push(Math.cos(e),Math.sin(e),1,Math.cos(f),Math.sin(f),1)}a.addAttribute("position",new A(b,3));b=new Q({fog:!1});this.cone=new ca(a,b);this.add(this.cone);this.update()}function ii(a){var b=[];a&&a.isBone&&b.push(a);for(var c=
-0;ca?-1:0we;we++)va[we]=(16>we?"0":"")+
-we.toString(16);var L={DEG2RAD:Math.PI/180,RAD2DEG:180/Math.PI,generateUUID:function(){var a=4294967295*Math.random()|0,b=4294967295*Math.random()|0,c=4294967295*Math.random()|0,d=4294967295*Math.random()|0;return(va[a&255]+va[a>>8&255]+va[a>>16&255]+va[a>>24&255]+"-"+va[b&255]+va[b>>8&255]+"-"+va[b>>16&15|64]+va[b>>24&255]+"-"+va[c&63|128]+va[c>>8&255]+"-"+va[c>>16&255]+va[c>>24&255]+va[d&255]+va[d>>8&255]+va[d>>16&255]+va[d>>24&255]).toUpperCase()},clamp:function(a,b,c){return Math.max(b,Math.min(c,
-a))},euclideanModulo:function(a,b){return(a%b+b)%b},mapLinear:function(a,b,c,d,e){return d+(a-b)*(e-d)/(c-b)},lerp:function(a,b,c){return(1-c)*a+c*b},smoothstep:function(a,b,c){if(a<=b)return 0;if(a>=c)return 1;a=(a-b)/(c-b);return a*a*(3-2*a)},smootherstep:function(a,b,c){if(a<=b)return 0;if(a>=c)return 1;a=(a-b)/(c-b);return a*a*a*(a*(6*a-15)+10)},randInt:function(a,b){return a+Math.floor(Math.random()*(b-a+1))},randFloat:function(a,b){return a+Math.random()*(b-a)},randFloatSpread:function(a){return a*
-(.5-Math.random())},degToRad:function(a){return a*L.DEG2RAD},radToDeg:function(a){return a*L.RAD2DEG},isPowerOfTwo:function(a){return 0===(a&a-1)&&0!==a},ceilPowerOfTwo:function(a){return Math.pow(2,Math.ceil(Math.log(a)/Math.LN2))},floorPowerOfTwo:function(a){return Math.pow(2,Math.floor(Math.log(a)/Math.LN2))}};Object.defineProperties(w.prototype,{width:{get:function(){return this.x},set:function(a){this.x=a}},height:{get:function(){return this.y},set:function(a){this.y=a}}});Object.assign(w.prototype,
-{isVector2:!0,set:function(a,b){this.x=a;this.y=b;return this},setScalar:function(a){this.y=this.x=a;return this},setX:function(a){this.x=a;return this},setY:function(a){this.y=a;return this},setComponent:function(a,b){switch(a){case 0:this.x=b;break;case 1:this.y=b;break;default:throw Error("index is out of range: "+a);}return this},getComponent:function(a){switch(a){case 0:return this.x;case 1:return this.y;default:throw Error("index is out of range: "+a);}},clone:function(){return new this.constructor(this.x,
-this.y)},copy:function(a){this.x=a.x;this.y=a.y;return this},add:function(a,b){if(void 0!==b)return console.warn("THREE.Vector2: .add() now only accepts one argument. Use .addVectors( a, b ) instead."),this.addVectors(a,b);this.x+=a.x;this.y+=a.y;return this},addScalar:function(a){this.x+=a;this.y+=a;return this},addVectors:function(a,b){this.x=a.x+b.x;this.y=a.y+b.y;return this},addScaledVector:function(a,b){this.x+=a.x*b;this.y+=a.y*b;return this},sub:function(a,b){if(void 0!==b)return console.warn("THREE.Vector2: .sub() now only accepts one argument. Use .subVectors( a, b ) instead."),
-this.subVectors(a,b);this.x-=a.x;this.y-=a.y;return this},subScalar:function(a){this.x-=a;this.y-=a;return this},subVectors:function(a,b){this.x=a.x-b.x;this.y=a.y-b.y;return this},multiply:function(a){this.x*=a.x;this.y*=a.y;return this},multiplyScalar:function(a){this.x*=a;this.y*=a;return this},divide:function(a){this.x/=a.x;this.y/=a.y;return this},divideScalar:function(a){return this.multiplyScalar(1/a)},applyMatrix3:function(a){var b=this.x,c=this.y;a=a.elements;this.x=a[0]*b+a[3]*c+a[6];this.y=
-a[1]*b+a[4]*c+a[7];return this},min:function(a){this.x=Math.min(this.x,a.x);this.y=Math.min(this.y,a.y);return this},max:function(a){this.x=Math.max(this.x,a.x);this.y=Math.max(this.y,a.y);return this},clamp:function(a,b){this.x=Math.max(a.x,Math.min(b.x,this.x));this.y=Math.max(a.y,Math.min(b.y,this.y));return this},clampScalar:function(a,b){this.x=Math.max(a,Math.min(b,this.x));this.y=Math.max(a,Math.min(b,this.y));return this},clampLength:function(a,b){var c=this.length();return this.divideScalar(c||
-1).multiplyScalar(Math.max(a,Math.min(b,c)))},floor:function(){this.x=Math.floor(this.x);this.y=Math.floor(this.y);return this},ceil:function(){this.x=Math.ceil(this.x);this.y=Math.ceil(this.y);return this},round:function(){this.x=Math.round(this.x);this.y=Math.round(this.y);return this},roundToZero:function(){this.x=0>this.x?Math.ceil(this.x):Math.floor(this.x);this.y=0>this.y?Math.ceil(this.y):Math.floor(this.y);return this},negate:function(){this.x=-this.x;this.y=-this.y;return this},dot:function(a){return this.x*
-a.x+this.y*a.y},cross:function(a){return this.x*a.y-this.y*a.x},lengthSq:function(){return this.x*this.x+this.y*this.y},length:function(){return Math.sqrt(this.x*this.x+this.y*this.y)},manhattanLength:function(){return Math.abs(this.x)+Math.abs(this.y)},normalize:function(){return this.divideScalar(this.length()||1)},angle:function(){var a=Math.atan2(this.y,this.x);0>a&&(a+=2*Math.PI);return a},distanceTo:function(a){return Math.sqrt(this.distanceToSquared(a))},distanceToSquared:function(a){var b=
-this.x-a.x;a=this.y-a.y;return b*b+a*a},manhattanDistanceTo:function(a){return Math.abs(this.x-a.x)+Math.abs(this.y-a.y)},setLength:function(a){return this.normalize().multiplyScalar(a)},lerp:function(a,b){this.x+=(a.x-this.x)*b;this.y+=(a.y-this.y)*b;return this},lerpVectors:function(a,b,c){return this.subVectors(b,a).multiplyScalar(c).add(a)},equals:function(a){return a.x===this.x&&a.y===this.y},fromArray:function(a,b){void 0===b&&(b=0);this.x=a[b];this.y=a[b+1];return this},toArray:function(a,
-b){void 0===a&&(a=[]);void 0===b&&(b=0);a[b]=this.x;a[b+1]=this.y;return a},fromBufferAttribute:function(a,b,c){void 0!==c&&console.warn("THREE.Vector2: offset has been removed from .fromBufferAttribute().");this.x=a.getX(b);this.y=a.getY(b);return this},rotateAround:function(a,b){var c=Math.cos(b);b=Math.sin(b);var d=this.x-a.x,e=this.y-a.y;this.x=d*c-e*b+a.x;this.y=d*b+e*c+a.y;return this}});Object.assign(ua,{slerp:function(a,b,c,d){return c.copy(a).slerp(b,d)},slerpFlat:function(a,b,c,d,e,f,g){var h=
-c[d+0],l=c[d+1],m=c[d+2];c=c[d+3];d=e[f+0];var k=e[f+1],n=e[f+2];e=e[f+3];if(c!==e||h!==d||l!==k||m!==n){f=1-g;var t=h*d+l*k+m*n+c*e,r=0<=t?1:-1,p=1-t*t;p>Number.EPSILON&&(p=Math.sqrt(p),t=Math.atan2(p,t*r),f=Math.sin(f*t)/p,g=Math.sin(g*t)/p);r*=g;h=h*f+d*r;l=l*f+k*r;m=m*f+n*r;c=c*f+e*r;f===1-g&&(g=1/Math.sqrt(h*h+l*l+m*m+c*c),h*=g,l*=g,m*=g,c*=g)}a[b]=h;a[b+1]=l;a[b+2]=m;a[b+3]=c}});Object.defineProperties(ua.prototype,{x:{get:function(){return this._x},set:function(a){this._x=a;this._onChangeCallback()}},
-y:{get:function(){return this._y},set:function(a){this._y=a;this._onChangeCallback()}},z:{get:function(){return this._z},set:function(a){this._z=a;this._onChangeCallback()}},w:{get:function(){return this._w},set:function(a){this._w=a;this._onChangeCallback()}}});Object.assign(ua.prototype,{isQuaternion:!0,set:function(a,b,c,d){this._x=a;this._y=b;this._z=c;this._w=d;this._onChangeCallback();return this},clone:function(){return new this.constructor(this._x,this._y,this._z,this._w)},copy:function(a){this._x=
-a.x;this._y=a.y;this._z=a.z;this._w=a.w;this._onChangeCallback();return this},setFromEuler:function(a,b){if(!a||!a.isEuler)throw Error("THREE.Quaternion: .setFromEuler() now expects an Euler rotation rather than a Vector3 and order.");var c=a._x,d=a._y,e=a._z;a=a.order;var f=Math.cos,g=Math.sin,h=f(c/2),l=f(d/2);f=f(e/2);c=g(c/2);d=g(d/2);e=g(e/2);"XYZ"===a?(this._x=c*l*f+h*d*e,this._y=h*d*f-c*l*e,this._z=h*l*e+c*d*f,this._w=h*l*f-c*d*e):"YXZ"===a?(this._x=c*l*f+h*d*e,this._y=h*d*f-c*l*e,this._z=
-h*l*e-c*d*f,this._w=h*l*f+c*d*e):"ZXY"===a?(this._x=c*l*f-h*d*e,this._y=h*d*f+c*l*e,this._z=h*l*e+c*d*f,this._w=h*l*f-c*d*e):"ZYX"===a?(this._x=c*l*f-h*d*e,this._y=h*d*f+c*l*e,this._z=h*l*e-c*d*f,this._w=h*l*f+c*d*e):"YZX"===a?(this._x=c*l*f+h*d*e,this._y=h*d*f+c*l*e,this._z=h*l*e-c*d*f,this._w=h*l*f-c*d*e):"XZY"===a&&(this._x=c*l*f-h*d*e,this._y=h*d*f-c*l*e,this._z=h*l*e+c*d*f,this._w=h*l*f+c*d*e);!1!==b&&this._onChangeCallback();return this},setFromAxisAngle:function(a,b){b/=2;var c=Math.sin(b);
-this._x=a.x*c;this._y=a.y*c;this._z=a.z*c;this._w=Math.cos(b);this._onChangeCallback();return this},setFromRotationMatrix:function(a){var b=a.elements,c=b[0];a=b[4];var d=b[8],e=b[1],f=b[5],g=b[9],h=b[2],l=b[6];b=b[10];var m=c+f+b;0f&&c>b?(c=2*Math.sqrt(1+c-f-b),this._w=(l-g)/c,this._x=.25*c,this._y=(a+e)/c,this._z=(d+h)/c):f>b?(c=2*Math.sqrt(1+f-c-b),this._w=(d-h)/c,this._x=(a+e)/c,this._y=.25*c,this._z=(g+l)/
-c):(c=2*Math.sqrt(1+b-c-f),this._w=(e-a)/c,this._x=(d+h)/c,this._y=(g+l)/c,this._z=.25*c);this._onChangeCallback();return this},setFromUnitVectors:function(a,b){var c=a.dot(b)+1;1E-6>c?(c=0,Math.abs(a.x)>Math.abs(a.z)?(this._x=-a.y,this._y=a.x,this._z=0):(this._x=0,this._y=-a.z,this._z=a.y)):(this._x=a.y*b.z-a.z*b.y,this._y=a.z*b.x-a.x*b.z,this._z=a.x*b.y-a.y*b.x);this._w=c;return this.normalize()},angleTo:function(a){return 2*Math.acos(Math.abs(L.clamp(this.dot(a),-1,1)))},rotateTowards:function(a,
-b){var c=this.angleTo(a);if(0===c)return this;this.slerp(a,Math.min(1,b/c));return this},inverse:function(){return this.conjugate()},conjugate:function(){this._x*=-1;this._y*=-1;this._z*=-1;this._onChangeCallback();return this},dot:function(a){return this._x*a._x+this._y*a._y+this._z*a._z+this._w*a._w},lengthSq:function(){return this._x*this._x+this._y*this._y+this._z*this._z+this._w*this._w},length:function(){return Math.sqrt(this._x*this._x+this._y*this._y+this._z*this._z+this._w*this._w)},normalize:function(){var a=
-this.length();0===a?(this._z=this._y=this._x=0,this._w=1):(a=1/a,this._x*=a,this._y*=a,this._z*=a,this._w*=a);this._onChangeCallback();return this},multiply:function(a,b){return void 0!==b?(console.warn("THREE.Quaternion: .multiply() now only accepts one argument. Use .multiplyQuaternions( a, b ) instead."),this.multiplyQuaternions(a,b)):this.multiplyQuaternions(this,a)},premultiply:function(a){return this.multiplyQuaternions(a,this)},multiplyQuaternions:function(a,b){var c=a._x,d=a._y,e=a._z;a=a._w;
-var f=b._x,g=b._y,h=b._z;b=b._w;this._x=c*b+a*f+d*h-e*g;this._y=d*b+a*g+e*f-c*h;this._z=e*b+a*h+c*g-d*f;this._w=a*b-c*f-d*g-e*h;this._onChangeCallback();return this},slerp:function(a,b){if(0===b)return this;if(1===b)return this.copy(a);var c=this._x,d=this._y,e=this._z,f=this._w,g=f*a._w+c*a._x+d*a._y+e*a._z;0>g?(this._w=-a._w,this._x=-a._x,this._y=-a._y,this._z=-a._z,g=-g):this.copy(a);if(1<=g)return this._w=f,this._x=c,this._y=d,this._z=e,this;a=1-g*g;if(a<=Number.EPSILON)return g=1-b,this._w=g*
-f+b*this._w,this._x=g*c+b*this._x,this._y=g*d+b*this._y,this._z=g*e+b*this._z,this.normalize(),this._onChangeCallback(),this;a=Math.sqrt(a);var h=Math.atan2(a,g);g=Math.sin((1-b)*h)/a;b=Math.sin(b*h)/a;this._w=f*g+this._w*b;this._x=c*g+this._x*b;this._y=d*g+this._y*b;this._z=e*g+this._z*b;this._onChangeCallback();return this},equals:function(a){return a._x===this._x&&a._y===this._y&&a._z===this._z&&a._w===this._w},fromArray:function(a,b){void 0===b&&(b=0);this._x=a[b];this._y=a[b+1];this._z=a[b+2];
-this._w=a[b+3];this._onChangeCallback();return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);a[b]=this._x;a[b+1]=this._y;a[b+2]=this._z;a[b+3]=this._w;return a},_onChange:function(a){this._onChangeCallback=a;return this},_onChangeCallback:function(){}});var Ng=new n,li=new ua;Object.assign(n.prototype,{isVector3:!0,set:function(a,b,c){this.x=a;this.y=b;this.z=c;return this},setScalar:function(a){this.z=this.y=this.x=a;return this},setX:function(a){this.x=a;return this},setY:function(a){this.y=
-a;return this},setZ:function(a){this.z=a;return this},setComponent:function(a,b){switch(a){case 0:this.x=b;break;case 1:this.y=b;break;case 2:this.z=b;break;default:throw Error("index is out of range: "+a);}return this},getComponent:function(a){switch(a){case 0:return this.x;case 1:return this.y;case 2:return this.z;default:throw Error("index is out of range: "+a);}},clone:function(){return new this.constructor(this.x,this.y,this.z)},copy:function(a){this.x=a.x;this.y=a.y;this.z=a.z;return this},
-add:function(a,b){if(void 0!==b)return console.warn("THREE.Vector3: .add() now only accepts one argument. Use .addVectors( a, b ) instead."),this.addVectors(a,b);this.x+=a.x;this.y+=a.y;this.z+=a.z;return this},addScalar:function(a){this.x+=a;this.y+=a;this.z+=a;return this},addVectors:function(a,b){this.x=a.x+b.x;this.y=a.y+b.y;this.z=a.z+b.z;return this},addScaledVector:function(a,b){this.x+=a.x*b;this.y+=a.y*b;this.z+=a.z*b;return this},sub:function(a,b){if(void 0!==b)return console.warn("THREE.Vector3: .sub() now only accepts one argument. Use .subVectors( a, b ) instead."),
-this.subVectors(a,b);this.x-=a.x;this.y-=a.y;this.z-=a.z;return this},subScalar:function(a){this.x-=a;this.y-=a;this.z-=a;return this},subVectors:function(a,b){this.x=a.x-b.x;this.y=a.y-b.y;this.z=a.z-b.z;return this},multiply:function(a,b){if(void 0!==b)return console.warn("THREE.Vector3: .multiply() now only accepts one argument. Use .multiplyVectors( a, b ) instead."),this.multiplyVectors(a,b);this.x*=a.x;this.y*=a.y;this.z*=a.z;return this},multiplyScalar:function(a){this.x*=a;this.y*=a;this.z*=
-a;return this},multiplyVectors:function(a,b){this.x=a.x*b.x;this.y=a.y*b.y;this.z=a.z*b.z;return this},applyEuler:function(a){a&&a.isEuler||console.error("THREE.Vector3: .applyEuler() now expects an Euler rotation rather than a Vector3 and order.");return this.applyQuaternion(li.setFromEuler(a))},applyAxisAngle:function(a,b){return this.applyQuaternion(li.setFromAxisAngle(a,b))},applyMatrix3:function(a){var b=this.x,c=this.y,d=this.z;a=a.elements;this.x=a[0]*b+a[3]*c+a[6]*d;this.y=a[1]*b+a[4]*c+a[7]*
-d;this.z=a[2]*b+a[5]*c+a[8]*d;return this},applyMatrix4:function(a){var b=this.x,c=this.y,d=this.z;a=a.elements;var e=1/(a[3]*b+a[7]*c+a[11]*d+a[15]);this.x=(a[0]*b+a[4]*c+a[8]*d+a[12])*e;this.y=(a[1]*b+a[5]*c+a[9]*d+a[13])*e;this.z=(a[2]*b+a[6]*c+a[10]*d+a[14])*e;return this},applyQuaternion:function(a){var b=this.x,c=this.y,d=this.z,e=a.x,f=a.y,g=a.z;a=a.w;var h=a*b+f*d-g*c,l=a*c+g*b-e*d,m=a*d+e*c-f*b;b=-e*b-f*c-g*d;this.x=h*a+b*-e+l*-g-m*-f;this.y=l*a+b*-f+m*-e-h*-g;this.z=m*a+b*-g+h*-f-l*-e;return this},
-project:function(a){return this.applyMatrix4(a.matrixWorldInverse).applyMatrix4(a.projectionMatrix)},unproject:function(a){return this.applyMatrix4(a.projectionMatrixInverse).applyMatrix4(a.matrixWorld)},transformDirection:function(a){var b=this.x,c=this.y,d=this.z;a=a.elements;this.x=a[0]*b+a[4]*c+a[8]*d;this.y=a[1]*b+a[5]*c+a[9]*d;this.z=a[2]*b+a[6]*c+a[10]*d;return this.normalize()},divide:function(a){this.x/=a.x;this.y/=a.y;this.z/=a.z;return this},divideScalar:function(a){return this.multiplyScalar(1/
-a)},min:function(a){this.x=Math.min(this.x,a.x);this.y=Math.min(this.y,a.y);this.z=Math.min(this.z,a.z);return this},max:function(a){this.x=Math.max(this.x,a.x);this.y=Math.max(this.y,a.y);this.z=Math.max(this.z,a.z);return this},clamp:function(a,b){this.x=Math.max(a.x,Math.min(b.x,this.x));this.y=Math.max(a.y,Math.min(b.y,this.y));this.z=Math.max(a.z,Math.min(b.z,this.z));return this},clampScalar:function(a,b){this.x=Math.max(a,Math.min(b,this.x));this.y=Math.max(a,Math.min(b,this.y));this.z=Math.max(a,
-Math.min(b,this.z));return this},clampLength:function(a,b){var c=this.length();return this.divideScalar(c||1).multiplyScalar(Math.max(a,Math.min(b,c)))},floor:function(){this.x=Math.floor(this.x);this.y=Math.floor(this.y);this.z=Math.floor(this.z);return this},ceil:function(){this.x=Math.ceil(this.x);this.y=Math.ceil(this.y);this.z=Math.ceil(this.z);return this},round:function(){this.x=Math.round(this.x);this.y=Math.round(this.y);this.z=Math.round(this.z);return this},roundToZero:function(){this.x=
-0>this.x?Math.ceil(this.x):Math.floor(this.x);this.y=0>this.y?Math.ceil(this.y):Math.floor(this.y);this.z=0>this.z?Math.ceil(this.z):Math.floor(this.z);return this},negate:function(){this.x=-this.x;this.y=-this.y;this.z=-this.z;return this},dot:function(a){return this.x*a.x+this.y*a.y+this.z*a.z},lengthSq:function(){return this.x*this.x+this.y*this.y+this.z*this.z},length:function(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z)},manhattanLength:function(){return Math.abs(this.x)+Math.abs(this.y)+
-Math.abs(this.z)},normalize:function(){return this.divideScalar(this.length()||1)},setLength:function(a){return this.normalize().multiplyScalar(a)},lerp:function(a,b){this.x+=(a.x-this.x)*b;this.y+=(a.y-this.y)*b;this.z+=(a.z-this.z)*b;return this},lerpVectors:function(a,b,c){return this.subVectors(b,a).multiplyScalar(c).add(a)},cross:function(a,b){return void 0!==b?(console.warn("THREE.Vector3: .cross() now only accepts one argument. Use .crossVectors( a, b ) instead."),this.crossVectors(a,b)):this.crossVectors(this,
-a)},crossVectors:function(a,b){var c=a.x,d=a.y;a=a.z;var e=b.x,f=b.y;b=b.z;this.x=d*b-a*f;this.y=a*e-c*b;this.z=c*f-d*e;return this},projectOnVector:function(a){var b=a.dot(this)/a.lengthSq();return this.copy(a).multiplyScalar(b)},projectOnPlane:function(a){Ng.copy(this).projectOnVector(a);return this.sub(Ng)},reflect:function(a){return this.sub(Ng.copy(a).multiplyScalar(2*this.dot(a)))},angleTo:function(a){var b=Math.sqrt(this.lengthSq()*a.lengthSq());0===b&&console.error("THREE.Vector3: angleTo() can't handle zero length vectors.");
-a=this.dot(a)/b;return Math.acos(L.clamp(a,-1,1))},distanceTo:function(a){return Math.sqrt(this.distanceToSquared(a))},distanceToSquared:function(a){var b=this.x-a.x,c=this.y-a.y;a=this.z-a.z;return b*b+c*c+a*a},manhattanDistanceTo:function(a){return Math.abs(this.x-a.x)+Math.abs(this.y-a.y)+Math.abs(this.z-a.z)},setFromSpherical:function(a){return this.setFromSphericalCoords(a.radius,a.phi,a.theta)},setFromSphericalCoords:function(a,b,c){var d=Math.sin(b)*a;this.x=d*Math.sin(c);this.y=Math.cos(b)*
-a;this.z=d*Math.cos(c);return this},setFromCylindrical:function(a){return this.setFromCylindricalCoords(a.radius,a.theta,a.y)},setFromCylindricalCoords:function(a,b,c){this.x=a*Math.sin(b);this.y=c;this.z=a*Math.cos(b);return this},setFromMatrixPosition:function(a){a=a.elements;this.x=a[12];this.y=a[13];this.z=a[14];return this},setFromMatrixScale:function(a){var b=this.setFromMatrixColumn(a,0).length(),c=this.setFromMatrixColumn(a,1).length();a=this.setFromMatrixColumn(a,2).length();this.x=b;this.y=
-c;this.z=a;return this},setFromMatrixColumn:function(a,b){return this.fromArray(a.elements,4*b)},equals:function(a){return a.x===this.x&&a.y===this.y&&a.z===this.z},fromArray:function(a,b){void 0===b&&(b=0);this.x=a[b];this.y=a[b+1];this.z=a[b+2];return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);a[b]=this.x;a[b+1]=this.y;a[b+2]=this.z;return a},fromBufferAttribute:function(a,b,c){void 0!==c&&console.warn("THREE.Vector3: offset has been removed from .fromBufferAttribute().");
-this.x=a.getX(b);this.y=a.getY(b);this.z=a.getZ(b);return this}});var qc=new n;Object.assign(Y.prototype,{isMatrix3:!0,set:function(a,b,c,d,e,f,g,h,l){var m=this.elements;m[0]=a;m[1]=d;m[2]=g;m[3]=b;m[4]=e;m[5]=h;m[6]=c;m[7]=f;m[8]=l;return this},identity:function(){this.set(1,0,0,0,1,0,0,0,1);return this},clone:function(){return(new this.constructor).fromArray(this.elements)},copy:function(a){var b=this.elements;a=a.elements;b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=a[3];b[4]=a[4];b[5]=a[5];b[6]=a[6];b[7]=
-a[7];b[8]=a[8];return this},setFromMatrix4:function(a){a=a.elements;this.set(a[0],a[4],a[8],a[1],a[5],a[9],a[2],a[6],a[10]);return this},applyToBufferAttribute:function(a){for(var b=0,c=a.count;bc;c++)if(b[c]!==a[c])return!1;return!0},fromArray:function(a,b){void 0===b&&(b=0);for(var c=0;9>c;c++)this.elements[c]=a[c+b];return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);var c=this.elements;a[b]=c[0];a[b+1]=c[1];a[b+2]=c[2];a[b+3]=c[3];a[b+4]=c[4];a[b+5]=c[5];a[b+6]=c[6];a[b+7]=c[7];a[b+8]=c[8];
-return a}});var md,Kb={getDataURL:function(a){if("undefined"==typeof HTMLCanvasElement)return a.src;if(!(a instanceof HTMLCanvasElement)){void 0===md&&(md=document.createElementNS("http://www.w3.org/1999/xhtml","canvas"));md.width=a.width;md.height=a.height;var b=md.getContext("2d");a instanceof ImageData?b.putImageData(a,0,0):b.drawImage(a,0,0,a.width,a.height);a=md}return 2048a.x||1a.x?0:1;break;case 1002:a.x=1===Math.abs(Math.floor(a.x)%2)?Math.ceil(a.x)-a.x:a.x-Math.floor(a.x)}if(0>a.y||1a.y?0:1;break;case 1002:a.y=1===Math.abs(Math.floor(a.y)%2)?Math.ceil(a.y)-a.y:a.y-Math.floor(a.y)}this.flipY&&(a.y=1-a.y);return a}});Object.defineProperty(W.prototype,"needsUpdate",{set:function(a){!0===a&&this.version++}});Object.defineProperties(aa.prototype,{width:{get:function(){return this.z},
-set:function(a){this.z=a}},height:{get:function(){return this.w},set:function(a){this.w=a}}});Object.assign(aa.prototype,{isVector4:!0,set:function(a,b,c,d){this.x=a;this.y=b;this.z=c;this.w=d;return this},setScalar:function(a){this.w=this.z=this.y=this.x=a;return this},setX:function(a){this.x=a;return this},setY:function(a){this.y=a;return this},setZ:function(a){this.z=a;return this},setW:function(a){this.w=a;return this},setComponent:function(a,b){switch(a){case 0:this.x=b;break;case 1:this.y=b;
-break;case 2:this.z=b;break;case 3:this.w=b;break;default:throw Error("index is out of range: "+a);}return this},getComponent:function(a){switch(a){case 0:return this.x;case 1:return this.y;case 2:return this.z;case 3:return this.w;default:throw Error("index is out of range: "+a);}},clone:function(){return new this.constructor(this.x,this.y,this.z,this.w)},copy:function(a){this.x=a.x;this.y=a.y;this.z=a.z;this.w=void 0!==a.w?a.w:1;return this},add:function(a,b){if(void 0!==b)return console.warn("THREE.Vector4: .add() now only accepts one argument. Use .addVectors( a, b ) instead."),
-this.addVectors(a,b);this.x+=a.x;this.y+=a.y;this.z+=a.z;this.w+=a.w;return this},addScalar:function(a){this.x+=a;this.y+=a;this.z+=a;this.w+=a;return this},addVectors:function(a,b){this.x=a.x+b.x;this.y=a.y+b.y;this.z=a.z+b.z;this.w=a.w+b.w;return this},addScaledVector:function(a,b){this.x+=a.x*b;this.y+=a.y*b;this.z+=a.z*b;this.w+=a.w*b;return this},sub:function(a,b){if(void 0!==b)return console.warn("THREE.Vector4: .sub() now only accepts one argument. Use .subVectors( a, b ) instead."),this.subVectors(a,
-b);this.x-=a.x;this.y-=a.y;this.z-=a.z;this.w-=a.w;return this},subScalar:function(a){this.x-=a;this.y-=a;this.z-=a;this.w-=a;return this},subVectors:function(a,b){this.x=a.x-b.x;this.y=a.y-b.y;this.z=a.z-b.z;this.w=a.w-b.w;return this},multiplyScalar:function(a){this.x*=a;this.y*=a;this.z*=a;this.w*=a;return this},applyMatrix4:function(a){var b=this.x,c=this.y,d=this.z,e=this.w;a=a.elements;this.x=a[0]*b+a[4]*c+a[8]*d+a[12]*e;this.y=a[1]*b+a[5]*c+a[9]*d+a[13]*e;this.z=a[2]*b+a[6]*c+a[10]*d+a[14]*
-e;this.w=a[3]*b+a[7]*c+a[11]*d+a[15]*e;return this},divideScalar:function(a){return this.multiplyScalar(1/a)},setAxisAngleFromQuaternion:function(a){this.w=2*Math.acos(a.w);var b=Math.sqrt(1-a.w*a.w);1E-4>b?(this.x=1,this.z=this.y=0):(this.x=a.x/b,this.y=a.y/b,this.z=a.z/b);return this},setAxisAngleFromRotationMatrix:function(a){a=a.elements;var b=a[0];var c=a[4];var d=a[8],e=a[1],f=a[5],g=a[9];var h=a[2];var l=a[6];var m=a[10];if(.01>Math.abs(c-e)&&.01>Math.abs(d-h)&&.01>Math.abs(g-l)){if(.1>Math.abs(c+
-e)&&.1>Math.abs(d+h)&&.1>Math.abs(g+l)&&.1>Math.abs(b+f+m-3))return this.set(1,0,0,0),this;a=Math.PI;b=(b+1)/2;f=(f+1)/2;m=(m+1)/2;c=(c+e)/4;d=(d+h)/4;g=(g+l)/4;b>f&&b>m?.01>b?(l=0,c=h=.707106781):(l=Math.sqrt(b),h=c/l,c=d/l):f>m?.01>f?(l=.707106781,h=0,c=.707106781):(h=Math.sqrt(f),l=c/h,c=g/h):.01>m?(h=l=.707106781,c=0):(c=Math.sqrt(m),l=d/c,h=g/c);this.set(l,h,c,a);return this}a=Math.sqrt((l-g)*(l-g)+(d-h)*(d-h)+(e-c)*(e-c));.001>Math.abs(a)&&(a=1);this.x=(l-g)/a;this.y=(d-h)/a;this.z=(e-c)/a;
-this.w=Math.acos((b+f+m-1)/2);return this},min:function(a){this.x=Math.min(this.x,a.x);this.y=Math.min(this.y,a.y);this.z=Math.min(this.z,a.z);this.w=Math.min(this.w,a.w);return this},max:function(a){this.x=Math.max(this.x,a.x);this.y=Math.max(this.y,a.y);this.z=Math.max(this.z,a.z);this.w=Math.max(this.w,a.w);return this},clamp:function(a,b){this.x=Math.max(a.x,Math.min(b.x,this.x));this.y=Math.max(a.y,Math.min(b.y,this.y));this.z=Math.max(a.z,Math.min(b.z,this.z));this.w=Math.max(a.w,Math.min(b.w,
-this.w));return this},clampScalar:function(a,b){this.x=Math.max(a,Math.min(b,this.x));this.y=Math.max(a,Math.min(b,this.y));this.z=Math.max(a,Math.min(b,this.z));this.w=Math.max(a,Math.min(b,this.w));return this},clampLength:function(a,b){var c=this.length();return this.divideScalar(c||1).multiplyScalar(Math.max(a,Math.min(b,c)))},floor:function(){this.x=Math.floor(this.x);this.y=Math.floor(this.y);this.z=Math.floor(this.z);this.w=Math.floor(this.w);return this},ceil:function(){this.x=Math.ceil(this.x);
-this.y=Math.ceil(this.y);this.z=Math.ceil(this.z);this.w=Math.ceil(this.w);return this},round:function(){this.x=Math.round(this.x);this.y=Math.round(this.y);this.z=Math.round(this.z);this.w=Math.round(this.w);return this},roundToZero:function(){this.x=0>this.x?Math.ceil(this.x):Math.floor(this.x);this.y=0>this.y?Math.ceil(this.y):Math.floor(this.y);this.z=0>this.z?Math.ceil(this.z):Math.floor(this.z);this.w=0>this.w?Math.ceil(this.w):Math.floor(this.w);return this},negate:function(){this.x=-this.x;
-this.y=-this.y;this.z=-this.z;this.w=-this.w;return this},dot:function(a){return this.x*a.x+this.y*a.y+this.z*a.z+this.w*a.w},lengthSq:function(){return this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w},length:function(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w)},manhattanLength:function(){return Math.abs(this.x)+Math.abs(this.y)+Math.abs(this.z)+Math.abs(this.w)},normalize:function(){return this.divideScalar(this.length()||1)},setLength:function(a){return this.normalize().multiplyScalar(a)},
-lerp:function(a,b){this.x+=(a.x-this.x)*b;this.y+=(a.y-this.y)*b;this.z+=(a.z-this.z)*b;this.w+=(a.w-this.w)*b;return this},lerpVectors:function(a,b,c){return this.subVectors(b,a).multiplyScalar(c).add(a)},equals:function(a){return a.x===this.x&&a.y===this.y&&a.z===this.z&&a.w===this.w},fromArray:function(a,b){void 0===b&&(b=0);this.x=a[b];this.y=a[b+1];this.z=a[b+2];this.w=a[b+3];return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);a[b]=this.x;a[b+1]=this.y;a[b+2]=this.z;a[b+3]=
-this.w;return a},fromBufferAttribute:function(a,b,c){void 0!==c&&console.warn("THREE.Vector4: offset has been removed from .fromBufferAttribute().");this.x=a.getX(b);this.y=a.getY(b);this.z=a.getZ(b);this.w=a.getW(b);return this}});la.prototype=Object.assign(Object.create(Ba.prototype),{constructor:la,isWebGLRenderTarget:!0,setSize:function(a,b){if(this.width!==a||this.height!==b)this.width=a,this.height=b,this.texture.image.width=a,this.texture.image.height=b,this.dispose();this.viewport.set(0,0,
-a,b);this.scissor.set(0,0,a,b)},clone:function(){return(new this.constructor).copy(this)},copy:function(a){this.width=a.width;this.height=a.height;this.viewport.copy(a.viewport);this.texture=a.texture.clone();this.depthBuffer=a.depthBuffer;this.stencilBuffer=a.stencilBuffer;this.depthTexture=a.depthTexture;return this},dispose:function(){this.dispatchEvent({type:"dispose"})}});Of.prototype=Object.assign(Object.create(la.prototype),{constructor:Of,isWebGLMultisampleRenderTarget:!0,copy:function(a){la.prototype.copy.call(this,
-a);this.samples=a.samples;return this}});var Ka=new n,ea=new U,sk=new n(0,0,0),tk=new n(1,1,1),Lb=new n,qf=new n,ka=new n;Object.assign(U.prototype,{isMatrix4:!0,set:function(a,b,c,d,e,f,g,h,l,m,k,n,t,r,p,v){var q=this.elements;q[0]=a;q[4]=b;q[8]=c;q[12]=d;q[1]=e;q[5]=f;q[9]=g;q[13]=h;q[2]=l;q[6]=m;q[10]=k;q[14]=n;q[3]=t;q[7]=r;q[11]=p;q[15]=v;return this},identity:function(){this.set(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1);return this},clone:function(){return(new U).fromArray(this.elements)},copy:function(a){var b=
-this.elements;a=a.elements;b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=a[3];b[4]=a[4];b[5]=a[5];b[6]=a[6];b[7]=a[7];b[8]=a[8];b[9]=a[9];b[10]=a[10];b[11]=a[11];b[12]=a[12];b[13]=a[13];b[14]=a[14];b[15]=a[15];return this},copyPosition:function(a){var b=this.elements;a=a.elements;b[12]=a[12];b[13]=a[13];b[14]=a[14];return this},extractBasis:function(a,b,c){a.setFromMatrixColumn(this,0);b.setFromMatrixColumn(this,1);c.setFromMatrixColumn(this,2);return this},makeBasis:function(a,b,c){this.set(a.x,b.x,c.x,0,a.y,
-b.y,c.y,0,a.z,b.z,c.z,0,0,0,0,1);return this},extractRotation:function(a){var b=this.elements,c=a.elements,d=1/Ka.setFromMatrixColumn(a,0).length(),e=1/Ka.setFromMatrixColumn(a,1).length();a=1/Ka.setFromMatrixColumn(a,2).length();b[0]=c[0]*d;b[1]=c[1]*d;b[2]=c[2]*d;b[3]=0;b[4]=c[4]*e;b[5]=c[5]*e;b[6]=c[6]*e;b[7]=0;b[8]=c[8]*a;b[9]=c[9]*a;b[10]=c[10]*a;b[11]=0;b[12]=0;b[13]=0;b[14]=0;b[15]=1;return this},makeRotationFromEuler:function(a){a&&a.isEuler||console.error("THREE.Matrix4: .makeRotationFromEuler() now expects a Euler rotation rather than a Vector3 and order.");
-var b=this.elements,c=a.x,d=a.y,e=a.z,f=Math.cos(c);c=Math.sin(c);var g=Math.cos(d);d=Math.sin(d);var h=Math.cos(e);e=Math.sin(e);if("XYZ"===a.order){a=f*h;var l=f*e,m=c*h,k=c*e;b[0]=g*h;b[4]=-g*e;b[8]=d;b[1]=l+m*d;b[5]=a-k*d;b[9]=-c*g;b[2]=k-a*d;b[6]=m+l*d;b[10]=f*g}else"YXZ"===a.order?(a=g*h,l=g*e,m=d*h,k=d*e,b[0]=a+k*c,b[4]=m*c-l,b[8]=f*d,b[1]=f*e,b[5]=f*h,b[9]=-c,b[2]=l*c-m,b[6]=k+a*c,b[10]=f*g):"ZXY"===a.order?(a=g*h,l=g*e,m=d*h,k=d*e,b[0]=a-k*c,b[4]=-f*e,b[8]=m+l*c,b[1]=l+m*c,b[5]=f*h,b[9]=
-k-a*c,b[2]=-f*d,b[6]=c,b[10]=f*g):"ZYX"===a.order?(a=f*h,l=f*e,m=c*h,k=c*e,b[0]=g*h,b[4]=m*d-l,b[8]=a*d+k,b[1]=g*e,b[5]=k*d+a,b[9]=l*d-m,b[2]=-d,b[6]=c*g,b[10]=f*g):"YZX"===a.order?(a=f*g,l=f*d,m=c*g,k=c*d,b[0]=g*h,b[4]=k-a*e,b[8]=m*e+l,b[1]=e,b[5]=f*h,b[9]=-c*h,b[2]=-d*h,b[6]=l*e+m,b[10]=a-k*e):"XZY"===a.order&&(a=f*g,l=f*d,m=c*g,k=c*d,b[0]=g*h,b[4]=-e,b[8]=d*h,b[1]=a*e+k,b[5]=f*h,b[9]=l*e-m,b[2]=m*e-l,b[6]=c*h,b[10]=k*e+a);b[3]=0;b[7]=0;b[11]=0;b[12]=0;b[13]=0;b[14]=0;b[15]=1;return this},makeRotationFromQuaternion:function(a){return this.compose(sk,
-a,tk)},lookAt:function(a,b,c){var d=this.elements;ka.subVectors(a,b);0===ka.lengthSq()&&(ka.z=1);ka.normalize();Lb.crossVectors(c,ka);0===Lb.lengthSq()&&(1===Math.abs(c.z)?ka.x+=1E-4:ka.z+=1E-4,ka.normalize(),Lb.crossVectors(c,ka));Lb.normalize();qf.crossVectors(ka,Lb);d[0]=Lb.x;d[4]=qf.x;d[8]=ka.x;d[1]=Lb.y;d[5]=qf.y;d[9]=ka.y;d[2]=Lb.z;d[6]=qf.z;d[10]=ka.z;return this},multiply:function(a,b){return void 0!==b?(console.warn("THREE.Matrix4: .multiply() now only accepts one argument. Use .multiplyMatrices( a, b ) instead."),
-this.multiplyMatrices(a,b)):this.multiplyMatrices(this,a)},premultiply:function(a){return this.multiplyMatrices(a,this)},multiplyMatrices:function(a,b){var c=a.elements,d=b.elements;b=this.elements;a=c[0];var e=c[4],f=c[8],g=c[12],h=c[1],l=c[5],m=c[9],k=c[13],n=c[2],t=c[6],r=c[10],p=c[14],v=c[3],x=c[7],z=c[11];c=c[15];var y=d[0],w=d[4],A=d[8],C=d[12],B=d[1],E=d[5],D=d[9],F=d[13],G=d[2],H=d[6],I=d[10],L=d[14],M=d[3],N=d[7],O=d[11];d=d[15];b[0]=a*y+e*B+f*G+g*M;b[4]=a*w+e*E+f*H+g*N;b[8]=a*A+e*D+f*I+
-g*O;b[12]=a*C+e*F+f*L+g*d;b[1]=h*y+l*B+m*G+k*M;b[5]=h*w+l*E+m*H+k*N;b[9]=h*A+l*D+m*I+k*O;b[13]=h*C+l*F+m*L+k*d;b[2]=n*y+t*B+r*G+p*M;b[6]=n*w+t*E+r*H+p*N;b[10]=n*A+t*D+r*I+p*O;b[14]=n*C+t*F+r*L+p*d;b[3]=v*y+x*B+z*G+c*M;b[7]=v*w+x*E+z*H+c*N;b[11]=v*A+x*D+z*I+c*O;b[15]=v*C+x*F+z*L+c*d;return this},multiplyScalar:function(a){var b=this.elements;b[0]*=a;b[4]*=a;b[8]*=a;b[12]*=a;b[1]*=a;b[5]*=a;b[9]*=a;b[13]*=a;b[2]*=a;b[6]*=a;b[10]*=a;b[14]*=a;b[3]*=a;b[7]*=a;b[11]*=a;b[15]*=a;return this},applyToBufferAttribute:function(a){for(var b=
-0,c=a.count;bthis.determinant()&&(e=-e);a.x=d[12];a.y=d[13];a.z=d[14];ea.copy(this);a=1/e;d=1/f;var h=1/g;ea.elements[0]*=a;ea.elements[1]*=a;ea.elements[2]*=a;ea.elements[4]*=d;ea.elements[5]*=d;ea.elements[6]*=d;ea.elements[8]*=h;ea.elements[9]*=h;ea.elements[10]*=h;b.setFromRotationMatrix(ea);c.x=e;c.y=f;c.z=g;return this},makePerspective:function(a,b,c,d,e,f){void 0===f&&console.warn("THREE.Matrix4: .makePerspective() has been redefined and has a new signature. Please check the docs.");
-var g=this.elements;g[0]=2*e/(b-a);g[4]=0;g[8]=(b+a)/(b-a);g[12]=0;g[1]=0;g[5]=2*e/(c-d);g[9]=(c+d)/(c-d);g[13]=0;g[2]=0;g[6]=0;g[10]=-(f+e)/(f-e);g[14]=-2*f*e/(f-e);g[3]=0;g[7]=0;g[11]=-1;g[15]=0;return this},makeOrthographic:function(a,b,c,d,e,f){var g=this.elements,h=1/(b-a),l=1/(c-d),m=1/(f-e);g[0]=2*h;g[4]=0;g[8]=0;g[12]=-((b+a)*h);g[1]=0;g[5]=2*l;g[9]=0;g[13]=-((c+d)*l);g[2]=0;g[6]=0;g[10]=-2*m;g[14]=-((f+e)*m);g[3]=0;g[7]=0;g[11]=0;g[15]=1;return this},equals:function(a){var b=this.elements;
-a=a.elements;for(var c=0;16>c;c++)if(b[c]!==a[c])return!1;return!0},fromArray:function(a,b){void 0===b&&(b=0);for(var c=0;16>c;c++)this.elements[c]=a[c+b];return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);var c=this.elements;a[b]=c[0];a[b+1]=c[1];a[b+2]=c[2];a[b+3]=c[3];a[b+4]=c[4];a[b+5]=c[5];a[b+6]=c[6];a[b+7]=c[7];a[b+8]=c[8];a[b+9]=c[9];a[b+10]=c[10];a[b+11]=c[11];a[b+12]=c[12];a[b+13]=c[13];a[b+14]=c[14];a[b+15]=c[15];return a}});var mi=new U,ni=new ua;Qb.RotationOrders=
-"XYZ YZX ZXY XZY YXZ ZYX".split(" ");Qb.DefaultOrder="XYZ";Object.defineProperties(Qb.prototype,{x:{get:function(){return this._x},set:function(a){this._x=a;this._onChangeCallback()}},y:{get:function(){return this._y},set:function(a){this._y=a;this._onChangeCallback()}},z:{get:function(){return this._z},set:function(a){this._z=a;this._onChangeCallback()}},order:{get:function(){return this._order},set:function(a){this._order=a;this._onChangeCallback()}}});Object.assign(Qb.prototype,{isEuler:!0,set:function(a,
-b,c,d){this._x=a;this._y=b;this._z=c;this._order=d||this._order;this._onChangeCallback();return this},clone:function(){return new this.constructor(this._x,this._y,this._z,this._order)},copy:function(a){this._x=a._x;this._y=a._y;this._z=a._z;this._order=a._order;this._onChangeCallback();return this},setFromRotationMatrix:function(a,b,c){var d=L.clamp,e=a.elements;a=e[0];var f=e[4],g=e[8],h=e[1],l=e[5],m=e[9],k=e[2],n=e[6];e=e[10];b=b||this._order;"XYZ"===b?(this._y=Math.asin(d(g,-1,1)),.9999999>Math.abs(g)?
-(this._x=Math.atan2(-m,e),this._z=Math.atan2(-f,a)):(this._x=Math.atan2(n,l),this._z=0)):"YXZ"===b?(this._x=Math.asin(-d(m,-1,1)),.9999999>Math.abs(m)?(this._y=Math.atan2(g,e),this._z=Math.atan2(h,l)):(this._y=Math.atan2(-k,a),this._z=0)):"ZXY"===b?(this._x=Math.asin(d(n,-1,1)),.9999999>Math.abs(n)?(this._y=Math.atan2(-k,e),this._z=Math.atan2(-f,l)):(this._y=0,this._z=Math.atan2(h,a))):"ZYX"===b?(this._y=Math.asin(-d(k,-1,1)),.9999999>Math.abs(k)?(this._x=Math.atan2(n,e),this._z=Math.atan2(h,a)):
-(this._x=0,this._z=Math.atan2(-f,l))):"YZX"===b?(this._z=Math.asin(d(h,-1,1)),.9999999>Math.abs(h)?(this._x=Math.atan2(-m,l),this._y=Math.atan2(-k,a)):(this._x=0,this._y=Math.atan2(g,e))):"XZY"===b?(this._z=Math.asin(-d(f,-1,1)),.9999999>Math.abs(f)?(this._x=Math.atan2(n,l),this._y=Math.atan2(g,a)):(this._x=Math.atan2(-m,e),this._y=0)):console.warn("THREE.Euler: .setFromRotationMatrix() given unsupported order: "+b);this._order=b;!1!==c&&this._onChangeCallback();return this},setFromQuaternion:function(a,
-b,c){mi.makeRotationFromQuaternion(a);return this.setFromRotationMatrix(mi,b,c)},setFromVector3:function(a,b){return this.set(a.x,a.y,a.z,b||this._order)},reorder:function(a){ni.setFromEuler(this);return this.setFromQuaternion(ni,a)},equals:function(a){return a._x===this._x&&a._y===this._y&&a._z===this._z&&a._order===this._order},fromArray:function(a){this._x=a[0];this._y=a[1];this._z=a[2];void 0!==a[3]&&(this._order=a[3]);this._onChangeCallback();return this},toArray:function(a,b){void 0===a&&(a=
-[]);void 0===b&&(b=0);a[b]=this._x;a[b+1]=this._y;a[b+2]=this._z;a[b+3]=this._order;return a},toVector3:function(a){return a?a.set(this._x,this._y,this._z):new n(this._x,this._y,this._z)},_onChange:function(a){this._onChangeCallback=a;return this},_onChangeCallback:function(){}});Object.assign(Pf.prototype,{set:function(a){this.mask=1<e&&(e=m);k>f&&(f=k);n>g&&(g=n)}this.min.set(b,c,d);
-this.max.set(e,f,g);return this},setFromBufferAttribute:function(a){for(var b=Infinity,c=Infinity,d=Infinity,e=-Infinity,f=-Infinity,g=-Infinity,h=0,l=a.count;he&&(e=m);k>f&&(f=k);n>g&&(g=n)}this.min.set(b,c,d);this.max.set(e,f,g);return this},setFromPoints:function(a){this.makeEmpty();for(var b=0,c=a.length;bthis.max.x||a.ythis.max.y||a.zthis.max.z?!1:!0},containsBox:function(a){return this.min.x<=a.min.x&&a.max.x<=this.max.x&&this.min.y<=a.min.y&&a.max.y<=this.max.y&&this.min.z<=a.min.z&&a.max.z<=this.max.z},getParameter:function(a,b){void 0===b&&(console.warn("THREE.Box3: .getParameter() target is now required"),b=new n);return b.set((a.x-this.min.x)/(this.max.x-this.min.x),(a.y-this.min.y)/(this.max.y-this.min.y),
-(a.z-this.min.z)/(this.max.z-this.min.z))},intersectsBox:function(a){return a.max.xthis.max.x||a.max.ythis.max.y||a.max.zthis.max.z?!1:!0},intersectsSphere:function(a){this.clampPoint(a.center,jb);return jb.distanceToSquared(a.center)<=a.radius*a.radius},intersectsPlane:function(a){if(0=-a.constant},intersectsTriangle:function(a){if(this.isEmpty())return!1;this.getCenter(ye);sf.subVectors(this.max,ye);od.subVectors(a.a,ye);pd.subVectors(a.b,ye);qd.subVectors(a.c,ye);Mb.subVectors(pd,od);Nb.subVectors(qd,pd);rc.subVectors(od,qd);a=[0,-Mb.z,Mb.y,0,-Nb.z,Nb.y,0,-rc.z,
-rc.y,Mb.z,0,-Mb.x,Nb.z,0,-Nb.x,rc.z,0,-rc.x,-Mb.y,Mb.x,0,-Nb.y,Nb.x,0,-rc.y,rc.x,0];if(!Qf(a,od,pd,qd,sf))return!1;a=[1,0,0,0,1,0,0,0,1];if(!Qf(a,od,pd,qd,sf))return!1;tf.crossVectors(Mb,Nb);a=[tf.x,tf.y,tf.z];return Qf(a,od,pd,qd,sf)},clampPoint:function(a,b){void 0===b&&(console.warn("THREE.Box3: .clampPoint() target is now required"),b=new n);return b.copy(a).clamp(this.min,this.max)},distanceToPoint:function(a){return jb.copy(a).clamp(this.min,this.max).sub(a).length()},getBoundingSphere:function(a){void 0===
-a&&console.error("THREE.Box3: .getBoundingSphere() target is now required");this.getCenter(a.center);a.radius=.5*this.getSize(jb).length();return a},intersect:function(a){this.min.max(a.min);this.max.min(a.max);this.isEmpty()&&this.makeEmpty();return this},union:function(a){this.min.min(a.min);this.max.max(a.max);return this},applyMatrix4:function(a){if(this.isEmpty())return this;vb[0].set(this.min.x,this.min.y,this.min.z).applyMatrix4(a);vb[1].set(this.min.x,this.min.y,this.max.z).applyMatrix4(a);
-vb[2].set(this.min.x,this.max.y,this.min.z).applyMatrix4(a);vb[3].set(this.min.x,this.max.y,this.max.z).applyMatrix4(a);vb[4].set(this.max.x,this.min.y,this.min.z).applyMatrix4(a);vb[5].set(this.max.x,this.min.y,this.max.z).applyMatrix4(a);vb[6].set(this.max.x,this.max.y,this.min.z).applyMatrix4(a);vb[7].set(this.max.x,this.max.y,this.max.z).applyMatrix4(a);this.setFromPoints(vb);return this},translate:function(a){this.min.add(a);this.max.add(a);return this},equals:function(a){return a.min.equals(this.min)&&
-a.max.equals(this.max)}});var yk=new ab;Object.assign(nb.prototype,{set:function(a,b){this.center.copy(a);this.radius=b;return this},setFromPoints:function(a,b){var c=this.center;void 0!==b?c.copy(b):yk.setFromPoints(a).getCenter(c);for(var d=b=0,e=a.length;d=
-this.radius},containsPoint:function(a){return a.distanceToSquared(this.center)<=this.radius*this.radius},distanceToPoint:function(a){return a.distanceTo(this.center)-this.radius},intersectsSphere:function(a){var b=this.radius+a.radius;return a.center.distanceToSquared(this.center)<=b*b},intersectsBox:function(a){return a.intersectsSphere(this)},intersectsPlane:function(a){return Math.abs(a.distanceToPoint(this.center))<=this.radius},clampPoint:function(a,b){var c=this.center.distanceToSquared(a);
-void 0===b&&(console.warn("THREE.Sphere: .clampPoint() target is now required"),b=new n);b.copy(a);c>this.radius*this.radius&&(b.sub(this.center).normalize(),b.multiplyScalar(this.radius).add(this.center));return b},getBoundingBox:function(a){void 0===a&&(console.warn("THREE.Sphere: .getBoundingBox() target is now required"),a=new ab);a.set(this.center,this.center);a.expandByScalar(this.radius);return a},applyMatrix4:function(a){this.center.applyMatrix4(a);this.radius*=a.getMaxScaleOnAxis();return this},
-translate:function(a){this.center.add(a);return this},equals:function(a){return a.center.equals(this.center)&&a.radius===this.radius}});var wb=new n,Og=new n,uf=new n,Ob=new n,Pg=new n,vf=new n,Qg=new n;Object.assign(Sb.prototype,{set:function(a,b){this.origin.copy(a);this.direction.copy(b);return this},clone:function(){return(new this.constructor).copy(this)},copy:function(a){this.origin.copy(a.origin);this.direction.copy(a.direction);return this},at:function(a,b){void 0===b&&(console.warn("THREE.Ray: .at() target is now required"),
-b=new n);return b.copy(this.direction).multiplyScalar(a).add(this.origin)},lookAt:function(a){this.direction.copy(a).sub(this.origin).normalize();return this},recast:function(a){this.origin.copy(this.at(a,wb));return this},closestPointToPoint:function(a,b){void 0===b&&(console.warn("THREE.Ray: .closestPointToPoint() target is now required"),b=new n);b.subVectors(a,this.origin);a=b.dot(this.direction);return 0>a?b.copy(this.origin):b.copy(this.direction).multiplyScalar(a).add(this.origin)},distanceToPoint:function(a){return Math.sqrt(this.distanceSqToPoint(a))},
-distanceSqToPoint:function(a){var b=wb.subVectors(a,this.origin).dot(this.direction);if(0>b)return this.origin.distanceToSquared(a);wb.copy(this.direction).multiplyScalar(b).add(this.origin);return wb.distanceToSquared(a)},distanceSqToSegment:function(a,b,c,d){Og.copy(a).add(b).multiplyScalar(.5);uf.copy(b).sub(a).normalize();Ob.copy(this.origin).sub(Og);var e=.5*a.distanceTo(b),f=-this.direction.dot(uf),g=Ob.dot(this.direction),h=-Ob.dot(uf),l=Ob.lengthSq(),m=Math.abs(1-f*f);if(0=-k?b<=k?(e=1/m,a*=e,b*=e,f=a*(a+f*b+2*g)+b*(f*a+b+2*h)+l):(b=e,a=Math.max(0,-(f*b+g)),f=-a*a+b*(b+2*h)+l):(b=-e,a=Math.max(0,-(f*b+g)),f=-a*a+b*(b+2*h)+l):b<=-k?(a=Math.max(0,-(-f*e+g)),b=0a)return null;a=Math.sqrt(a-d);d=c-a;c+=a;return 0>d&&0>c?null:0>d?this.at(c,b):this.at(d,b)},intersectsSphere:function(a){return this.distanceSqToPoint(a.center)<=a.radius*a.radius},distanceToPlane:function(a){var b=a.normal.dot(this.direction);if(0===b)return 0===a.distanceToPoint(this.origin)?0:null;a=-(this.origin.dot(a.normal)+
-a.constant)/b;return 0<=a?a:null},intersectPlane:function(a,b){a=this.distanceToPlane(a);return null===a?null:this.at(a,b)},intersectsPlane:function(a){var b=a.distanceToPoint(this.origin);return 0===b||0>a.normal.dot(this.direction)*b?!0:!1},intersectBox:function(a,b){var c=1/this.direction.x;var d=1/this.direction.y;var e=1/this.direction.z,f=this.origin;if(0<=c){var g=(a.min.x-f.x)*c;c*=a.max.x-f.x}else g=(a.max.x-f.x)*c,c*=a.min.x-f.x;if(0<=d){var h=(a.min.y-f.y)*d;d*=a.max.y-f.y}else h=(a.max.y-
-f.y)*d,d*=a.min.y-f.y;if(g>d||h>c)return null;if(h>g||g!==g)g=h;if(da||h>c)return null;if(h>g||g!==g)g=h;if(ac?null:this.at(0<=g?g:c,b)},intersectsBox:function(a){return null!==this.intersectBox(a,wb)},intersectTriangle:function(a,b,c,d,e){Pg.subVectors(b,a);vf.subVectors(c,a);Qg.crossVectors(Pg,vf);b=this.direction.dot(Qg);if(0b)d=-1,b=-b;else return null;
-Ob.subVectors(this.origin,a);a=d*this.direction.dot(vf.crossVectors(Ob,vf));if(0>a)return null;c=d*this.direction.dot(Pg.cross(Ob));if(0>c||a+c>b)return null;a=-d*Ob.dot(Qg);return 0>a?null:this.at(a/b,e)},applyMatrix4:function(a){this.origin.applyMatrix4(a);this.direction.transformDirection(a);return this},equals:function(a){return a.origin.equals(this.origin)&&a.direction.equals(this.direction)}});var Ya=new n,xb=new n,Rg=new n,yb=new n,rd=new n,sd=new n,si=new n,Sg=new n,Tg=new n,Ug=new n;Object.assign(R,
-{getNormal:function(a,b,c,d){void 0===d&&(console.warn("THREE.Triangle: .getNormal() target is now required"),d=new n);d.subVectors(c,b);Ya.subVectors(a,b);d.cross(Ya);a=d.lengthSq();return 0=yb.x+yb.y},getUV:function(a,b,c,d,e,f,g,h){this.getBarycoord(a,b,c,d,yb);h.set(0,0);h.addScaledVector(e,yb.x);h.addScaledVector(f,yb.y);h.addScaledVector(g,yb.z);return h},isFrontFacing:function(a,b,c,d){Ya.subVectors(c,b);xb.subVectors(a,b);return 0>Ya.cross(xb).dot(d)?!0:!1}});Object.assign(R.prototype,{set:function(a,b,
-c){this.a.copy(a);this.b.copy(b);this.c.copy(c);return this},setFromPointsAndIndices:function(a,b,c,d){this.a.copy(a[b]);this.b.copy(a[c]);this.c.copy(a[d]);return this},clone:function(){return(new this.constructor).copy(this)},copy:function(a){this.a.copy(a.a);this.b.copy(a.b);this.c.copy(a.c);return this},getArea:function(){Ya.subVectors(this.c,this.b);xb.subVectors(this.a,this.b);return.5*Ya.cross(xb).length()},getMidpoint:function(a){void 0===a&&(console.warn("THREE.Triangle: .getMidpoint() target is now required"),
-a=new n);return a.addVectors(this.a,this.b).add(this.c).multiplyScalar(1/3)},getNormal:function(a){return R.getNormal(this.a,this.b,this.c,a)},getPlane:function(a){void 0===a&&(console.warn("THREE.Triangle: .getPlane() target is now required"),a=new n);return a.setFromCoplanarPoints(this.a,this.b,this.c)},getBarycoord:function(a,b){return R.getBarycoord(a,this.a,this.b,this.c,b)},getUV:function(a,b,c,d,e){return R.getUV(a,this.a,this.b,this.c,b,c,d,e)},containsPoint:function(a){return R.containsPoint(a,
-this.a,this.b,this.c)},isFrontFacing:function(a){return R.isFrontFacing(this.a,this.b,this.c,a)},intersectsBox:function(a){return a.intersectsTriangle(this)},closestPointToPoint:function(a,b){void 0===b&&(console.warn("THREE.Triangle: .closestPointToPoint() target is now required"),b=new n);var c=this.a,d=this.b,e=this.c;rd.subVectors(d,c);sd.subVectors(e,c);Sg.subVectors(a,c);var f=rd.dot(Sg),g=sd.dot(Sg);if(0>=f&&0>=g)return b.copy(c);Tg.subVectors(a,d);var h=rd.dot(Tg),l=sd.dot(Tg);if(0<=h&&l<=
-h)return b.copy(d);var m=f*l-h*g;if(0>=m&&0<=f&&0>=h)return d=f/(f-h),b.copy(c).addScaledVector(rd,d);Ug.subVectors(a,e);a=rd.dot(Ug);var k=sd.dot(Ug);if(0<=k&&a<=k)return b.copy(e);f=a*g-f*k;if(0>=f&&0<=g&&0>=k)return m=g/(g-k),b.copy(c).addScaledVector(sd,m);g=h*k-a*l;if(0>=g&&0<=l-h&&0<=a-k)return si.subVectors(e,d),m=(l-h)/(l-h+(a-k)),b.copy(d).addScaledVector(si,m);e=1/(g+f+m);d=f*e;m*=e;return b.copy(c).addScaledVector(rd,d).addScaledVector(sd,m)},equals:function(a){return a.a.equals(this.a)&&
-a.b.equals(this.b)&&a.c.equals(this.c)}});var zk={aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,
-darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,
-green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,
-lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,
-palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,rebeccapurple:6697881,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,
-steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074},Fa={h:0,s:0,l:0},wf={h:0,s:0,l:0};Object.assign(H.prototype,{isColor:!0,r:1,g:1,b:1,set:function(a){a&&a.isColor?this.copy(a):"number"===typeof a?this.setHex(a):"string"===typeof a&&this.setStyle(a);return this},setScalar:function(a){this.b=this.g=this.r=a;return this},setHex:function(a){a=Math.floor(a);
-this.r=(a>>16&255)/255;this.g=(a>>8&255)/255;this.b=(a&255)/255;return this},setRGB:function(a,b,c){this.r=a;this.g=b;this.b=c;return this},setHSL:function(a,b,c){a=L.euclideanModulo(a,1);b=L.clamp(b,0,1);c=L.clamp(c,0,1);0===b?this.r=this.g=this.b=c:(b=.5>=c?c*(1+b):c+b-c*b,c=2*c-b,this.r=Rf(c,b,a+1/3),this.g=Rf(c,b,a),this.b=Rf(c,b,a-1/3));return this},setStyle:function(a){function b(b){void 0!==b&&1>parseFloat(b)&&console.warn("THREE.Color: Alpha component of "+a+" will be ignored.")}var c;if(c=
-/^((?:rgb|hsl)a?)\(\s*([^\)]*)\)/.exec(a)){var d=c[2];switch(c[1]){case "rgb":case "rgba":if(c=/^(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec(d))return this.r=Math.min(255,parseInt(c[1],10))/255,this.g=Math.min(255,parseInt(c[2],10))/255,this.b=Math.min(255,parseInt(c[3],10))/255,b(c[5]),this;if(c=/^(\d+)%\s*,\s*(\d+)%\s*,\s*(\d+)%\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec(d))return this.r=Math.min(100,parseInt(c[1],10))/100,this.g=Math.min(100,parseInt(c[2],10))/100,this.b=Math.min(100,
-parseInt(c[3],10))/100,b(c[5]),this;break;case "hsl":case "hsla":if(c=/^([0-9]*\.?[0-9]+)\s*,\s*(\d+)%\s*,\s*(\d+)%\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec(d)){d=parseFloat(c[1])/360;var e=parseInt(c[2],10)/100,f=parseInt(c[3],10)/100;b(c[5]);return this.setHSL(d,e,f)}}}else if(c=/^#([A-Fa-f0-9]+)$/.exec(a)){c=c[1];d=c.length;if(3===d)return this.r=parseInt(c.charAt(0)+c.charAt(0),16)/255,this.g=parseInt(c.charAt(1)+c.charAt(1),16)/255,this.b=parseInt(c.charAt(2)+c.charAt(2),16)/255,this;if(6===d)return this.r=
-parseInt(c.charAt(0)+c.charAt(1),16)/255,this.g=parseInt(c.charAt(2)+c.charAt(3),16)/255,this.b=parseInt(c.charAt(4)+c.charAt(5),16)/255,this}a&&0 =h?l/(e+f):l/(2-e-f);switch(e){case b:g=(c-
-d)/l+(cthis.opacity&&(d.opacity=this.opacity);!0===this.transparent&&(d.transparent=this.transparent);d.depthFunc=this.depthFunc;d.depthTest=this.depthTest;d.depthWrite=this.depthWrite;d.stencilWrite=this.stencilWrite;
-d.stencilWriteMask=this.stencilWriteMask;d.stencilFunc=this.stencilFunc;d.stencilRef=this.stencilRef;d.stencilFuncMask=this.stencilFuncMask;d.stencilFail=this.stencilFail;d.stencilZFail=this.stencilZFail;d.stencilZPass=this.stencilZPass;this.rotation&&0!==this.rotation&&(d.rotation=this.rotation);!0===this.polygonOffset&&(d.polygonOffset=!0);0!==this.polygonOffsetFactor&&(d.polygonOffsetFactor=this.polygonOffsetFactor);0!==this.polygonOffsetUnits&&(d.polygonOffsetUnits=this.polygonOffsetUnits);this.linewidth&&
-1!==this.linewidth&&(d.linewidth=this.linewidth);void 0!==this.dashSize&&(d.dashSize=this.dashSize);void 0!==this.gapSize&&(d.gapSize=this.gapSize);void 0!==this.scale&&(d.scale=this.scale);!0===this.dithering&&(d.dithering=!0);0g;g++)if(d[g]===d[(g+1)%3]){a.push(f);break}for(f=a.length-1;0<=f;f--)for(d=a[f],this.faces.splice(d,1),c=0,e=this.faceVertexUvs.length;c\n\t#include \n}",
-fragmentShader:"uniform sampler2D tEquirect;\nvarying vec3 vWorldDirection;\n#define RECIPROCAL_PI 0.31830988618\n#define RECIPROCAL_PI2 0.15915494\nvoid main() {\n\tvec3 direction = normalize( vWorldDirection );\n\tvec2 sampleUV;\n\tsampleUV.y = asin( clamp( direction.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\tsampleUV.x = atan( direction.z, direction.x ) * RECIPROCAL_PI2 + 0.5;\n\tgl_FragColor = texture2D( tEquirect, sampleUV );\n}",side:1,blending:0});d.uniforms.tEquirect.value=b;b=new ja(new Gd(5,
-5,5),d);c.add(b);d=new Dc(1,10,1);d.renderTarget=this;d.renderTarget.texture.name="CubeCameraTexture";d.update(a,c);b.geometry.dispose();b.material.dispose();return this};Zb.prototype=Object.create(W.prototype);Zb.prototype.constructor=Zb;Zb.prototype.isDataTexture=!0;var $g=new n,Bk=new n,Ck=new Y;Object.assign(cb.prototype,{isPlane:!0,set:function(a,b){this.normal.copy(a);this.constant=b;return this},setComponents:function(a,b,c,d){this.normal.set(a,b,c);this.constant=d;return this},setFromNormalAndCoplanarPoint:function(a,
-b){this.normal.copy(a);this.constant=-b.dot(this.normal);return this},setFromCoplanarPoints:function(a,b,c){b=$g.subVectors(c,b).cross(Bk.subVectors(a,b)).normalize();this.setFromNormalAndCoplanarPoint(b,a);return this},clone:function(){return(new this.constructor).copy(this)},copy:function(a){this.normal.copy(a.normal);this.constant=a.constant;return this},normalize:function(){var a=1/this.normal.length();this.normal.multiplyScalar(a);this.constant*=a;return this},negate:function(){this.constant*=
--1;this.normal.negate();return this},distanceToPoint:function(a){return this.normal.dot(a)+this.constant},distanceToSphere:function(a){return this.distanceToPoint(a.center)-a.radius},projectPoint:function(a,b){void 0===b&&(console.warn("THREE.Plane: .projectPoint() target is now required"),b=new n);return b.copy(this.normal).multiplyScalar(-this.distanceToPoint(a)).add(a)},intersectLine:function(a,b){void 0===b&&(console.warn("THREE.Plane: .intersectLine() target is now required"),b=new n);var c=
-a.delta($g),d=this.normal.dot(c);if(0===d){if(0===this.distanceToPoint(a.start))return b.copy(a.start)}else if(d=-(a.start.dot(this.normal)+this.constant)/d,!(0>d||1b&&0a&&0c;c++)b[c].copy(a.planes[c]);return this},setFromMatrix:function(a){var b=this.planes,c=a.elements;a=c[0];var d=c[1],e=c[2],f=c[3],g=c[4],h=c[5],l=c[6],k=c[7],n=c[8],u=c[9],t=c[10],r=c[11],p=c[12],v=c[13],x=c[14];c=c[15];b[0].setComponents(f-a,k-g,r-n,c-p).normalize();b[1].setComponents(f+a,k+g,r+n,c+p).normalize();b[2].setComponents(f+
-d,k+h,r+u,c+v).normalize();b[3].setComponents(f-d,k-h,r-u,c-v).normalize();b[4].setComponents(f-e,k-l,r-t,c-x).normalize();b[5].setComponents(f+e,k+l,r+t,c+x).normalize();return this},intersectsObject:function(a){var b=a.geometry;null===b.boundingSphere&&b.computeBoundingSphere();td.copy(b.boundingSphere).applyMatrix4(a.matrixWorld);return this.intersectsSphere(td)},intersectsSprite:function(a){td.center.set(0,0,0);td.radius=.7071067811865476;td.applyMatrix4(a.matrixWorld);return this.intersectsSphere(td)},
-intersectsSphere:function(a){var b=this.planes,c=a.center;a=-a.radius;for(var d=0;6>d;d++)if(b[d].distanceToPoint(c)c;c++){var d=b[c];zf.x=0d.distanceToPoint(zf))return!1}return!0},containsPoint:function(a){for(var b=this.planes,c=0;6>c;c++)if(0>b[c].distanceToPoint(a))return!1;return!0}});var N={alphamap_fragment:"#ifdef USE_ALPHAMAP\n\tdiffuseColor.a *= texture2D( alphaMap, vUv ).g;\n#endif",
-alphamap_pars_fragment:"#ifdef USE_ALPHAMAP\n\tuniform sampler2D alphaMap;\n#endif",alphatest_fragment:"#ifdef ALPHATEST\n\tif ( diffuseColor.a < ALPHATEST ) discard;\n#endif",aomap_fragment:"#ifdef USE_AOMAP\n\tfloat ambientOcclusion = ( texture2D( aoMap, vUv2 ).r - 1.0 ) * aoMapIntensity + 1.0;\n\treflectedLight.indirectDiffuse *= ambientOcclusion;\n\t#if defined( USE_ENVMAP ) && defined( STANDARD )\n\t\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\t\treflectedLight.indirectSpecular *= computeSpecularOcclusion( dotNV, ambientOcclusion, material.specularRoughness );\n\t#endif\n#endif",
-aomap_pars_fragment:"#ifdef USE_AOMAP\n\tuniform sampler2D aoMap;\n\tuniform float aoMapIntensity;\n#endif",begin_vertex:"vec3 transformed = vec3( position );",beginnormal_vertex:"vec3 objectNormal = vec3( normal );\n#ifdef USE_TANGENT\n\tvec3 objectTangent = vec3( tangent.xyz );\n#endif",bsdfs:"vec2 integrateSpecularBRDF( const in float dotNV, const in float roughness ) {\n\tconst vec4 c0 = vec4( - 1, - 0.0275, - 0.572, 0.022 );\n\tconst vec4 c1 = vec4( 1, 0.0425, 1.04, - 0.04 );\n\tvec4 r = roughness * c0 + c1;\n\tfloat a004 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y;\n\treturn vec2( -1.04, 1.04 ) * a004 + r.zw;\n}\nfloat punctualLightIntensityToIrradianceFactor( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {\n#if defined ( PHYSICALLY_CORRECT_LIGHTS )\n\tfloat distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );\n\tif( cutoffDistance > 0.0 ) {\n\t\tdistanceFalloff *= pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );\n\t}\n\treturn distanceFalloff;\n#else\n\tif( cutoffDistance > 0.0 && decayExponent > 0.0 ) {\n\t\treturn pow( saturate( -lightDistance / cutoffDistance + 1.0 ), decayExponent );\n\t}\n\treturn 1.0;\n#endif\n}\nvec3 BRDF_Diffuse_Lambert( const in vec3 diffuseColor ) {\n\treturn RECIPROCAL_PI * diffuseColor;\n}\nvec3 F_Schlick( const in vec3 specularColor, const in float dotLH ) {\n\tfloat fresnel = exp2( ( -5.55473 * dotLH - 6.98316 ) * dotLH );\n\treturn ( 1.0 - specularColor ) * fresnel + specularColor;\n}\nvec3 F_Schlick_RoughnessDependent( const in vec3 F0, const in float dotNV, const in float roughness ) {\n\tfloat fresnel = exp2( ( -5.55473 * dotNV - 6.98316 ) * dotNV );\n\tvec3 Fr = max( vec3( 1.0 - roughness ), F0 ) - F0;\n\treturn Fr * fresnel + F0;\n}\nfloat G_GGX_Smith( const in float alpha, const in float dotNL, const in float dotNV ) {\n\tfloat a2 = pow2( alpha );\n\tfloat gl = dotNL + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n\tfloat gv = dotNV + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n\treturn 1.0 / ( gl * gv );\n}\nfloat G_GGX_SmithCorrelated( const in float alpha, const in float dotNL, const in float dotNV ) {\n\tfloat a2 = pow2( alpha );\n\tfloat gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n\tfloat gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n\treturn 0.5 / max( gv + gl, EPSILON );\n}\nfloat D_GGX( const in float alpha, const in float dotNH ) {\n\tfloat a2 = pow2( alpha );\n\tfloat denom = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0;\n\treturn RECIPROCAL_PI * a2 / pow2( denom );\n}\nvec3 BRDF_Specular_GGX( const in IncidentLight incidentLight, const in vec3 viewDir, const in vec3 normal, const in vec3 specularColor, const in float roughness ) {\n\tfloat alpha = pow2( roughness );\n\tvec3 halfDir = normalize( incidentLight.direction + viewDir );\n\tfloat dotNL = saturate( dot( normal, incidentLight.direction ) );\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tfloat dotNH = saturate( dot( normal, halfDir ) );\n\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\n\tvec3 F = F_Schlick( specularColor, dotLH );\n\tfloat G = G_GGX_SmithCorrelated( alpha, dotNL, dotNV );\n\tfloat D = D_GGX( alpha, dotNH );\n\treturn F * ( G * D );\n}\nvec2 LTC_Uv( const in vec3 N, const in vec3 V, const in float roughness ) {\n\tconst float LUT_SIZE = 64.0;\n\tconst float LUT_SCALE = ( LUT_SIZE - 1.0 ) / LUT_SIZE;\n\tconst float LUT_BIAS = 0.5 / LUT_SIZE;\n\tfloat dotNV = saturate( dot( N, V ) );\n\tvec2 uv = vec2( roughness, sqrt( 1.0 - dotNV ) );\n\tuv = uv * LUT_SCALE + LUT_BIAS;\n\treturn uv;\n}\nfloat LTC_ClippedSphereFormFactor( const in vec3 f ) {\n\tfloat l = length( f );\n\treturn max( ( l * l + f.z ) / ( l + 1.0 ), 0.0 );\n}\nvec3 LTC_EdgeVectorFormFactor( const in vec3 v1, const in vec3 v2 ) {\n\tfloat x = dot( v1, v2 );\n\tfloat y = abs( x );\n\tfloat a = 0.8543985 + ( 0.4965155 + 0.0145206 * y ) * y;\n\tfloat b = 3.4175940 + ( 4.1616724 + y ) * y;\n\tfloat v = a / b;\n\tfloat theta_sintheta = ( x > 0.0 ) ? v : 0.5 * inversesqrt( max( 1.0 - x * x, 1e-7 ) ) - v;\n\treturn cross( v1, v2 ) * theta_sintheta;\n}\nvec3 LTC_Evaluate( const in vec3 N, const in vec3 V, const in vec3 P, const in mat3 mInv, const in vec3 rectCoords[ 4 ] ) {\n\tvec3 v1 = rectCoords[ 1 ] - rectCoords[ 0 ];\n\tvec3 v2 = rectCoords[ 3 ] - rectCoords[ 0 ];\n\tvec3 lightNormal = cross( v1, v2 );\n\tif( dot( lightNormal, P - rectCoords[ 0 ] ) < 0.0 ) return vec3( 0.0 );\n\tvec3 T1, T2;\n\tT1 = normalize( V - N * dot( V, N ) );\n\tT2 = - cross( N, T1 );\n\tmat3 mat = mInv * transposeMat3( mat3( T1, T2, N ) );\n\tvec3 coords[ 4 ];\n\tcoords[ 0 ] = mat * ( rectCoords[ 0 ] - P );\n\tcoords[ 1 ] = mat * ( rectCoords[ 1 ] - P );\n\tcoords[ 2 ] = mat * ( rectCoords[ 2 ] - P );\n\tcoords[ 3 ] = mat * ( rectCoords[ 3 ] - P );\n\tcoords[ 0 ] = normalize( coords[ 0 ] );\n\tcoords[ 1 ] = normalize( coords[ 1 ] );\n\tcoords[ 2 ] = normalize( coords[ 2 ] );\n\tcoords[ 3 ] = normalize( coords[ 3 ] );\n\tvec3 vectorFormFactor = vec3( 0.0 );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 0 ], coords[ 1 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 1 ], coords[ 2 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 2 ], coords[ 3 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 3 ], coords[ 0 ] );\n\tfloat result = LTC_ClippedSphereFormFactor( vectorFormFactor );\n\treturn vec3( result );\n}\nvec3 BRDF_Specular_GGX_Environment( const in vec3 viewDir, const in vec3 normal, const in vec3 specularColor, const in float roughness ) {\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tvec2 brdf = integrateSpecularBRDF( dotNV, roughness );\n\treturn specularColor * brdf.x + brdf.y;\n}\nvoid BRDF_Specular_Multiscattering_Environment( const in GeometricContext geometry, const in vec3 specularColor, const in float roughness, inout vec3 singleScatter, inout vec3 multiScatter ) {\n\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\tvec3 F = F_Schlick_RoughnessDependent( specularColor, dotNV, roughness );\n\tvec2 brdf = integrateSpecularBRDF( dotNV, roughness );\n\tvec3 FssEss = F * brdf.x + brdf.y;\n\tfloat Ess = brdf.x + brdf.y;\n\tfloat Ems = 1.0 - Ess;\n\tvec3 Favg = specularColor + ( 1.0 - specularColor ) * 0.047619;\tvec3 Fms = FssEss * Favg / ( 1.0 - Ems * Favg );\n\tsingleScatter += FssEss;\n\tmultiScatter += Fms * Ems;\n}\nfloat G_BlinnPhong_Implicit( ) {\n\treturn 0.25;\n}\nfloat D_BlinnPhong( const in float shininess, const in float dotNH ) {\n\treturn RECIPROCAL_PI * ( shininess * 0.5 + 1.0 ) * pow( dotNH, shininess );\n}\nvec3 BRDF_Specular_BlinnPhong( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float shininess ) {\n\tvec3 halfDir = normalize( incidentLight.direction + geometry.viewDir );\n\tfloat dotNH = saturate( dot( geometry.normal, halfDir ) );\n\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\n\tvec3 F = F_Schlick( specularColor, dotLH );\n\tfloat G = G_BlinnPhong_Implicit( );\n\tfloat D = D_BlinnPhong( shininess, dotNH );\n\treturn F * ( G * D );\n}\nfloat GGXRoughnessToBlinnExponent( const in float ggxRoughness ) {\n\treturn ( 2.0 / pow2( ggxRoughness + 0.0001 ) - 2.0 );\n}\nfloat BlinnExponentToGGXRoughness( const in float blinnExponent ) {\n\treturn sqrt( 2.0 / ( blinnExponent + 2.0 ) );\n}\n#if defined( USE_SHEEN )\nfloat D_Charlie(float roughness, float NoH) {\n\tfloat invAlpha = 1.0 / roughness;\n\tfloat cos2h = NoH * NoH;\n\tfloat sin2h = max(1.0 - cos2h, 0.0078125);\treturn (2.0 + invAlpha) * pow(sin2h, invAlpha * 0.5) / (2.0 * PI);\n}\nfloat V_Neubelt(float NoV, float NoL) {\n\treturn saturate(1.0 / (4.0 * (NoL + NoV - NoL * NoV)));\n}\nvec3 BRDF_Specular_Sheen( const in float roughness, const in vec3 L, const in GeometricContext geometry, vec3 specularColor ) {\n\tvec3 N = geometry.normal;\n\tvec3 V = geometry.viewDir;\n\tvec3 H = normalize( V + L );\n\tfloat dotNH = saturate( dot( N, H ) );\n\treturn specularColor * D_Charlie( roughness, dotNH ) * V_Neubelt( dot(N, V), dot(N, L) );\n}\n#endif",
-bumpmap_pars_fragment:"#ifdef USE_BUMPMAP\n\tuniform sampler2D bumpMap;\n\tuniform float bumpScale;\n\tvec2 dHdxy_fwd() {\n\t\tvec2 dSTdx = dFdx( vUv );\n\t\tvec2 dSTdy = dFdy( vUv );\n\t\tfloat Hll = bumpScale * texture2D( bumpMap, vUv ).x;\n\t\tfloat dBx = bumpScale * texture2D( bumpMap, vUv + dSTdx ).x - Hll;\n\t\tfloat dBy = bumpScale * texture2D( bumpMap, vUv + dSTdy ).x - Hll;\n\t\treturn vec2( dBx, dBy );\n\t}\n\tvec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy ) {\n\t\tvec3 vSigmaX = vec3( dFdx( surf_pos.x ), dFdx( surf_pos.y ), dFdx( surf_pos.z ) );\n\t\tvec3 vSigmaY = vec3( dFdy( surf_pos.x ), dFdy( surf_pos.y ), dFdy( surf_pos.z ) );\n\t\tvec3 vN = surf_norm;\n\t\tvec3 R1 = cross( vSigmaY, vN );\n\t\tvec3 R2 = cross( vN, vSigmaX );\n\t\tfloat fDet = dot( vSigmaX, R1 );\n\t\tfDet *= ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\tvec3 vGrad = sign( fDet ) * ( dHdxy.x * R1 + dHdxy.y * R2 );\n\t\treturn normalize( abs( fDet ) * surf_norm - vGrad );\n\t}\n#endif",
-clipping_planes_fragment:"#if NUM_CLIPPING_PLANES > 0\n\tvec4 plane;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < UNION_CLIPPING_PLANES; i ++ ) {\n\t\tplane = clippingPlanes[ i ];\n\t\tif ( dot( vViewPosition, plane.xyz ) > plane.w ) discard;\n\t}\n\t#if UNION_CLIPPING_PLANES < NUM_CLIPPING_PLANES\n\t\tbool clipped = true;\n\t\t#pragma unroll_loop\n\t\tfor ( int i = UNION_CLIPPING_PLANES; i < NUM_CLIPPING_PLANES; i ++ ) {\n\t\t\tplane = clippingPlanes[ i ];\n\t\t\tclipped = ( dot( vViewPosition, plane.xyz ) > plane.w ) && clipped;\n\t\t}\n\t\tif ( clipped ) discard;\n\t#endif\n#endif",
-clipping_planes_pars_fragment:"#if NUM_CLIPPING_PLANES > 0\n\t#if ! defined( STANDARD ) && ! defined( PHONG ) && ! defined( MATCAP )\n\t\tvarying vec3 vViewPosition;\n\t#endif\n\tuniform vec4 clippingPlanes[ NUM_CLIPPING_PLANES ];\n#endif",clipping_planes_pars_vertex:"#if NUM_CLIPPING_PLANES > 0 && ! defined( STANDARD ) && ! defined( PHONG ) && ! defined( MATCAP )\n\tvarying vec3 vViewPosition;\n#endif",clipping_planes_vertex:"#if NUM_CLIPPING_PLANES > 0 && ! defined( STANDARD ) && ! defined( PHONG ) && ! defined( MATCAP )\n\tvViewPosition = - mvPosition.xyz;\n#endif",
-color_fragment:"#ifdef USE_COLOR\n\tdiffuseColor.rgb *= vColor;\n#endif",color_pars_fragment:"#ifdef USE_COLOR\n\tvarying vec3 vColor;\n#endif",color_pars_vertex:"#ifdef USE_COLOR\n\tvarying vec3 vColor;\n#endif",color_vertex:"#ifdef USE_COLOR\n\tvColor.xyz = color.xyz;\n#endif",common:"#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI_HALF 1.5707963267949\n#define RECIPROCAL_PI 0.31830988618\n#define RECIPROCAL_PI2 0.15915494\n#define LOG2 1.442695\n#define EPSILON 1e-6\n#ifndef saturate\n#define saturate(a) clamp( a, 0.0, 1.0 )\n#endif\n#define whiteComplement(a) ( 1.0 - saturate( a ) )\nfloat pow2( const in float x ) { return x*x; }\nfloat pow3( const in float x ) { return x*x*x; }\nfloat pow4( const in float x ) { float x2 = x*x; return x2*x2; }\nfloat average( const in vec3 color ) { return dot( color, vec3( 0.3333 ) ); }\nhighp float rand( const in vec2 uv ) {\n\tconst highp float a = 12.9898, b = 78.233, c = 43758.5453;\n\thighp float dt = dot( uv.xy, vec2( a,b ) ), sn = mod( dt, PI );\n\treturn fract(sin(sn) * c);\n}\n#ifdef HIGH_PRECISION\n\tfloat precisionSafeLength( vec3 v ) { return length( v ); }\n#else\n\tfloat max3( vec3 v ) { return max( max( v.x, v.y ), v.z ); }\n\tfloat precisionSafeLength( vec3 v ) {\n\t\tfloat maxComponent = max3( abs( v ) );\n\t\treturn length( v / maxComponent ) * maxComponent;\n\t}\n#endif\nstruct IncidentLight {\n\tvec3 color;\n\tvec3 direction;\n\tbool visible;\n};\nstruct ReflectedLight {\n\tvec3 directDiffuse;\n\tvec3 directSpecular;\n\tvec3 indirectDiffuse;\n\tvec3 indirectSpecular;\n};\nstruct GeometricContext {\n\tvec3 position;\n\tvec3 normal;\n\tvec3 viewDir;\n#ifdef CLEARCOAT\n\tvec3 clearcoatNormal;\n#endif\n};\nvec3 transformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );\n}\nvec3 inverseTransformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( vec4( dir, 0.0 ) * matrix ).xyz );\n}\nvec3 projectOnPlane(in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\tfloat distance = dot( planeNormal, point - pointOnPlane );\n\treturn - distance * planeNormal + point;\n}\nfloat sideOfPlane( in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\treturn sign( dot( point - pointOnPlane, planeNormal ) );\n}\nvec3 linePlaneIntersect( in vec3 pointOnLine, in vec3 lineDirection, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\treturn lineDirection * ( dot( planeNormal, pointOnPlane - pointOnLine ) / dot( planeNormal, lineDirection ) ) + pointOnLine;\n}\nmat3 transposeMat3( const in mat3 m ) {\n\tmat3 tmp;\n\ttmp[ 0 ] = vec3( m[ 0 ].x, m[ 1 ].x, m[ 2 ].x );\n\ttmp[ 1 ] = vec3( m[ 0 ].y, m[ 1 ].y, m[ 2 ].y );\n\ttmp[ 2 ] = vec3( m[ 0 ].z, m[ 1 ].z, m[ 2 ].z );\n\treturn tmp;\n}\nfloat linearToRelativeLuminance( const in vec3 color ) {\n\tvec3 weights = vec3( 0.2126, 0.7152, 0.0722 );\n\treturn dot( weights, color.rgb );\n}\nbool isPerspectiveMatrix( mat4 m ) {\n return m[ 2 ][ 3 ] == - 1.0;\n}",
-cube_uv_reflection_fragment:"#ifdef ENVMAP_TYPE_CUBE_UV\n#define cubeUV_textureSize (1024.0)\nint getFaceFromDirection(vec3 direction) {\n\tvec3 absDirection = abs(direction);\n\tint face = -1;\n\tif( absDirection.x > absDirection.z ) {\n\t\tif(absDirection.x > absDirection.y )\n\t\t\tface = direction.x > 0.0 ? 0 : 3;\n\t\telse\n\t\t\tface = direction.y > 0.0 ? 1 : 4;\n\t}\n\telse {\n\t\tif(absDirection.z > absDirection.y )\n\t\t\tface = direction.z > 0.0 ? 2 : 5;\n\t\telse\n\t\t\tface = direction.y > 0.0 ? 1 : 4;\n\t}\n\treturn face;\n}\n#define cubeUV_maxLods1 (log2(cubeUV_textureSize*0.25) - 1.0)\n#define cubeUV_rangeClamp (exp2((6.0 - 1.0) * 2.0))\nvec2 MipLevelInfo( vec3 vec, float roughnessLevel, float roughness ) {\n\tfloat scale = exp2(cubeUV_maxLods1 - roughnessLevel);\n\tfloat dxRoughness = dFdx(roughness);\n\tfloat dyRoughness = dFdy(roughness);\n\tvec3 dx = dFdx( vec * scale * dxRoughness );\n\tvec3 dy = dFdy( vec * scale * dyRoughness );\n\tfloat d = max( dot( dx, dx ), dot( dy, dy ) );\n\td = clamp(d, 1.0, cubeUV_rangeClamp);\n\tfloat mipLevel = 0.5 * log2(d);\n\treturn vec2(floor(mipLevel), fract(mipLevel));\n}\n#define cubeUV_maxLods2 (log2(cubeUV_textureSize*0.25) - 2.0)\n#define cubeUV_rcpTextureSize (1.0 / cubeUV_textureSize)\nvec2 getCubeUV(vec3 direction, float roughnessLevel, float mipLevel) {\n\tmipLevel = roughnessLevel > cubeUV_maxLods2 - 3.0 ? 0.0 : mipLevel;\n\tfloat a = 16.0 * cubeUV_rcpTextureSize;\n\tvec2 exp2_packed = exp2( vec2( roughnessLevel, mipLevel ) );\n\tvec2 rcp_exp2_packed = vec2( 1.0 ) / exp2_packed;\n\tfloat powScale = exp2_packed.x * exp2_packed.y;\n\tfloat scale = rcp_exp2_packed.x * rcp_exp2_packed.y * 0.25;\n\tfloat mipOffset = 0.75*(1.0 - rcp_exp2_packed.y) * rcp_exp2_packed.x;\n\tbool bRes = mipLevel == 0.0;\n\tscale = bRes && (scale < a) ? a : scale;\n\tvec3 r;\n\tvec2 offset;\n\tint face = getFaceFromDirection(direction);\n\tfloat rcpPowScale = 1.0 / powScale;\n\tif( face == 0) {\n\t\tr = vec3(direction.x, -direction.z, direction.y);\n\t\toffset = vec2(0.0+mipOffset,0.75 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\n\t}\n\telse if( face == 1) {\n\t\tr = vec3(direction.y, direction.x, direction.z);\n\t\toffset = vec2(scale+mipOffset, 0.75 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\n\t}\n\telse if( face == 2) {\n\t\tr = vec3(direction.z, direction.x, direction.y);\n\t\toffset = vec2(2.0*scale+mipOffset, 0.75 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\n\t}\n\telse if( face == 3) {\n\t\tr = vec3(direction.x, direction.z, direction.y);\n\t\toffset = vec2(0.0+mipOffset,0.5 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\n\t}\n\telse if( face == 4) {\n\t\tr = vec3(direction.y, direction.x, -direction.z);\n\t\toffset = vec2(scale+mipOffset, 0.5 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\n\t}\n\telse {\n\t\tr = vec3(direction.z, -direction.x, direction.y);\n\t\toffset = vec2(2.0*scale+mipOffset, 0.5 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\n\t}\n\tr = normalize(r);\n\tfloat texelOffset = 0.5 * cubeUV_rcpTextureSize;\n\tvec2 s = ( r.yz / abs( r.x ) + vec2( 1.0 ) ) * 0.5;\n\tvec2 base = offset + vec2( texelOffset );\n\treturn base + s * ( scale - 2.0 * texelOffset );\n}\n#define cubeUV_maxLods3 (log2(cubeUV_textureSize*0.25) - 3.0)\nvec4 textureCubeUV( sampler2D envMap, vec3 reflectedDirection, float roughness ) {\n\tfloat roughnessVal = roughness* cubeUV_maxLods3;\n\tfloat r1 = floor(roughnessVal);\n\tfloat r2 = r1 + 1.0;\n\tfloat t = fract(roughnessVal);\n\tvec2 mipInfo = MipLevelInfo(reflectedDirection, r1, roughness);\n\tfloat s = mipInfo.y;\n\tfloat level0 = mipInfo.x;\n\tfloat level1 = level0 + 1.0;\n\tlevel1 = level1 > 5.0 ? 5.0 : level1;\n\tlevel0 += min( floor( s + 0.5 ), 5.0 );\n\tvec2 uv_10 = getCubeUV(reflectedDirection, r1, level0);\n\tvec4 color10 = envMapTexelToLinear(texture2D(envMap, uv_10));\n\tvec2 uv_20 = getCubeUV(reflectedDirection, r2, level0);\n\tvec4 color20 = envMapTexelToLinear(texture2D(envMap, uv_20));\n\tvec4 result = mix(color10, color20, t);\n\treturn vec4(result.rgb, 1.0);\n}\n#endif",
-defaultnormal_vertex:"vec3 transformedNormal = objectNormal;\n#ifdef USE_INSTANCING\n\ttransformedNormal = mat3( instanceMatrix ) * transformedNormal;\n#endif\ntransformedNormal = normalMatrix * transformedNormal;\n#ifdef FLIP_SIDED\n\ttransformedNormal = - transformedNormal;\n#endif\n#ifdef USE_TANGENT\n\tvec3 transformedTangent = normalMatrix * objectTangent;\n\t#ifdef FLIP_SIDED\n\t\ttransformedTangent = - transformedTangent;\n\t#endif\n#endif",displacementmap_pars_vertex:"#ifdef USE_DISPLACEMENTMAP\n\tuniform sampler2D displacementMap;\n\tuniform float displacementScale;\n\tuniform float displacementBias;\n#endif",
-displacementmap_vertex:"#ifdef USE_DISPLACEMENTMAP\n\ttransformed += normalize( objectNormal ) * ( texture2D( displacementMap, vUv ).x * displacementScale + displacementBias );\n#endif",emissivemap_fragment:"#ifdef USE_EMISSIVEMAP\n\tvec4 emissiveColor = texture2D( emissiveMap, vUv );\n\temissiveColor.rgb = emissiveMapTexelToLinear( emissiveColor ).rgb;\n\ttotalEmissiveRadiance *= emissiveColor.rgb;\n#endif",emissivemap_pars_fragment:"#ifdef USE_EMISSIVEMAP\n\tuniform sampler2D emissiveMap;\n#endif",
-encodings_fragment:"gl_FragColor = linearToOutputTexel( gl_FragColor );",encodings_pars_fragment:"\nvec4 LinearToLinear( in vec4 value ) {\n\treturn value;\n}\nvec4 GammaToLinear( in vec4 value, in float gammaFactor ) {\n\treturn vec4( pow( value.rgb, vec3( gammaFactor ) ), value.a );\n}\nvec4 LinearToGamma( in vec4 value, in float gammaFactor ) {\n\treturn vec4( pow( value.rgb, vec3( 1.0 / gammaFactor ) ), value.a );\n}\nvec4 sRGBToLinear( in vec4 value ) {\n\treturn vec4( mix( pow( value.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), value.rgb * 0.0773993808, vec3( lessThanEqual( value.rgb, vec3( 0.04045 ) ) ) ), value.a );\n}\nvec4 LinearTosRGB( in vec4 value ) {\n\treturn vec4( mix( pow( value.rgb, vec3( 0.41666 ) ) * 1.055 - vec3( 0.055 ), value.rgb * 12.92, vec3( lessThanEqual( value.rgb, vec3( 0.0031308 ) ) ) ), value.a );\n}\nvec4 RGBEToLinear( in vec4 value ) {\n\treturn vec4( value.rgb * exp2( value.a * 255.0 - 128.0 ), 1.0 );\n}\nvec4 LinearToRGBE( in vec4 value ) {\n\tfloat maxComponent = max( max( value.r, value.g ), value.b );\n\tfloat fExp = clamp( ceil( log2( maxComponent ) ), -128.0, 127.0 );\n\treturn vec4( value.rgb / exp2( fExp ), ( fExp + 128.0 ) / 255.0 );\n}\nvec4 RGBMToLinear( in vec4 value, in float maxRange ) {\n\treturn vec4( value.rgb * value.a * maxRange, 1.0 );\n}\nvec4 LinearToRGBM( in vec4 value, in float maxRange ) {\n\tfloat maxRGB = max( value.r, max( value.g, value.b ) );\n\tfloat M = clamp( maxRGB / maxRange, 0.0, 1.0 );\n\tM = ceil( M * 255.0 ) / 255.0;\n\treturn vec4( value.rgb / ( M * maxRange ), M );\n}\nvec4 RGBDToLinear( in vec4 value, in float maxRange ) {\n\treturn vec4( value.rgb * ( ( maxRange / 255.0 ) / value.a ), 1.0 );\n}\nvec4 LinearToRGBD( in vec4 value, in float maxRange ) {\n\tfloat maxRGB = max( value.r, max( value.g, value.b ) );\n\tfloat D = max( maxRange / maxRGB, 1.0 );\n\tD = min( floor( D ) / 255.0, 1.0 );\n\treturn vec4( value.rgb * ( D * ( 255.0 / maxRange ) ), D );\n}\nconst mat3 cLogLuvM = mat3( 0.2209, 0.3390, 0.4184, 0.1138, 0.6780, 0.7319, 0.0102, 0.1130, 0.2969 );\nvec4 LinearToLogLuv( in vec4 value ) {\n\tvec3 Xp_Y_XYZp = cLogLuvM * value.rgb;\n\tXp_Y_XYZp = max( Xp_Y_XYZp, vec3( 1e-6, 1e-6, 1e-6 ) );\n\tvec4 vResult;\n\tvResult.xy = Xp_Y_XYZp.xy / Xp_Y_XYZp.z;\n\tfloat Le = 2.0 * log2(Xp_Y_XYZp.y) + 127.0;\n\tvResult.w = fract( Le );\n\tvResult.z = ( Le - ( floor( vResult.w * 255.0 ) ) / 255.0 ) / 255.0;\n\treturn vResult;\n}\nconst mat3 cLogLuvInverseM = mat3( 6.0014, -2.7008, -1.7996, -1.3320, 3.1029, -5.7721, 0.3008, -1.0882, 5.6268 );\nvec4 LogLuvToLinear( in vec4 value ) {\n\tfloat Le = value.z * 255.0 + value.w;\n\tvec3 Xp_Y_XYZp;\n\tXp_Y_XYZp.y = exp2( ( Le - 127.0 ) / 2.0 );\n\tXp_Y_XYZp.z = Xp_Y_XYZp.y / value.y;\n\tXp_Y_XYZp.x = value.x * Xp_Y_XYZp.z;\n\tvec3 vRGB = cLogLuvInverseM * Xp_Y_XYZp.rgb;\n\treturn vec4( max( vRGB, 0.0 ), 1.0 );\n}",
-envmap_fragment:"#ifdef USE_ENVMAP\n\t#ifdef ENV_WORLDPOS\n\t\tvec3 cameraToVertex = normalize( vWorldPosition - cameraPosition );\n\t\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvec3 reflectVec = reflect( cameraToVertex, worldNormal );\n\t\t#else\n\t\t\tvec3 reflectVec = refract( cameraToVertex, worldNormal, refractionRatio );\n\t\t#endif\n\t#else\n\t\tvec3 reflectVec = vReflect;\n\t#endif\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tvec4 envColor = textureCube( envMap, vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );\n\t#elif defined( ENVMAP_TYPE_EQUIREC )\n\t\tvec2 sampleUV;\n\t\treflectVec = normalize( reflectVec );\n\t\tsampleUV.y = asin( clamp( reflectVec.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\t\tsampleUV.x = atan( reflectVec.z, reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\n\t\tvec4 envColor = texture2D( envMap, sampleUV );\n\t#elif defined( ENVMAP_TYPE_SPHERE )\n\t\treflectVec = normalize( reflectVec );\n\t\tvec3 reflectView = normalize( ( viewMatrix * vec4( reflectVec, 0.0 ) ).xyz + vec3( 0.0, 0.0, 1.0 ) );\n\t\tvec4 envColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5 );\n\t#else\n\t\tvec4 envColor = vec4( 0.0 );\n\t#endif\n\tenvColor = envMapTexelToLinear( envColor );\n\t#ifdef ENVMAP_BLENDING_MULTIPLY\n\t\toutgoingLight = mix( outgoingLight, outgoingLight * envColor.xyz, specularStrength * reflectivity );\n\t#elif defined( ENVMAP_BLENDING_MIX )\n\t\toutgoingLight = mix( outgoingLight, envColor.xyz, specularStrength * reflectivity );\n\t#elif defined( ENVMAP_BLENDING_ADD )\n\t\toutgoingLight += envColor.xyz * specularStrength * reflectivity;\n\t#endif\n#endif",
-envmap_common_pars_fragment:"#ifdef USE_ENVMAP\n\tuniform float envMapIntensity;\n\tuniform float flipEnvMap;\n\tuniform int maxMipLevel;\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tuniform samplerCube envMap;\n\t#else\n\t\tuniform sampler2D envMap;\n\t#endif\n\t\n#endif",envmap_pars_fragment:"#ifdef USE_ENVMAP\n\tuniform float reflectivity;\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\n\t\t#define ENV_WORLDPOS\n\t#endif\n\t#ifdef ENV_WORLDPOS\n\t\tvarying vec3 vWorldPosition;\n\t\tuniform float refractionRatio;\n\t#else\n\t\tvarying vec3 vReflect;\n\t#endif\n#endif",
-envmap_pars_vertex:"#ifdef USE_ENVMAP\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) ||defined( PHONG )\n\t\t#define ENV_WORLDPOS\n\t#endif\n\t#ifdef ENV_WORLDPOS\n\t\t\n\t\tvarying vec3 vWorldPosition;\n\t#else\n\t\tvarying vec3 vReflect;\n\t\tuniform float refractionRatio;\n\t#endif\n#endif",envmap_physical_pars_fragment:"#if defined( USE_ENVMAP )\n\t#ifdef ENVMAP_MODE_REFRACTION\n\t\tuniform float refractionRatio;\n\t#endif\n\tvec3 getLightProbeIndirectIrradiance( const in GeometricContext geometry, const in int maxMIPLevel ) {\n\t\tvec3 worldNormal = inverseTransformDirection( geometry.normal, viewMatrix );\n\t\t#ifdef ENVMAP_TYPE_CUBE\n\t\t\tvec3 queryVec = vec3( flipEnvMap * worldNormal.x, worldNormal.yz );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = textureCubeLodEXT( envMap, queryVec, float( maxMIPLevel ) );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = textureCube( envMap, queryVec, float( maxMIPLevel ) );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_CUBE_UV )\n\t\t\tvec3 queryVec = vec3( flipEnvMap * worldNormal.x, worldNormal.yz );\n\t\t\tvec4 envMapColor = textureCubeUV( envMap, queryVec, 1.0 );\n\t\t#else\n\t\t\tvec4 envMapColor = vec4( 0.0 );\n\t\t#endif\n\t\treturn PI * envMapColor.rgb * envMapIntensity;\n\t}\n\tfloat getSpecularMIPLevel( const in float roughness, const in int maxMIPLevel ) {\n\t\tfloat maxMIPLevelScalar = float( maxMIPLevel );\n\t\tfloat sigma = PI * roughness * roughness / ( 1.0 + roughness );\n\t\tfloat desiredMIPLevel = maxMIPLevelScalar + log2( sigma );\n\t\treturn clamp( desiredMIPLevel, 0.0, maxMIPLevelScalar );\n\t}\n\tvec3 getLightProbeIndirectRadiance( const in vec3 viewDir, const in vec3 normal, const in float roughness, const in int maxMIPLevel ) {\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t vec3 reflectVec = reflect( -viewDir, normal );\n\t\t reflectVec = normalize( mix( reflectVec, normal, roughness * roughness) );\n\t\t#else\n\t\t vec3 reflectVec = refract( -viewDir, normal, refractionRatio );\n\t\t#endif\n\t\treflectVec = inverseTransformDirection( reflectVec, viewMatrix );\n\t\tfloat specularMIPLevel = getSpecularMIPLevel( roughness, maxMIPLevel );\n\t\t#ifdef ENVMAP_TYPE_CUBE\n\t\t\tvec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = textureCubeLodEXT( envMap, queryReflectVec, specularMIPLevel );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = textureCube( envMap, queryReflectVec, specularMIPLevel );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_CUBE_UV )\n\t\t\tvec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz );\n\t\t\tvec4 envMapColor = textureCubeUV( envMap, queryReflectVec, roughness );\n\t\t#elif defined( ENVMAP_TYPE_EQUIREC )\n\t\t\tvec2 sampleUV;\n\t\t\tsampleUV.y = asin( clamp( reflectVec.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\t\t\tsampleUV.x = atan( reflectVec.z, reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = texture2DLodEXT( envMap, sampleUV, specularMIPLevel );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = texture2D( envMap, sampleUV, specularMIPLevel );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_SPHERE )\n\t\t\tvec3 reflectView = normalize( ( viewMatrix * vec4( reflectVec, 0.0 ) ).xyz + vec3( 0.0,0.0,1.0 ) );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = texture2DLodEXT( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#endif\n\t\treturn envMapColor.rgb * envMapIntensity;\n\t}\n#endif",
-envmap_vertex:"#ifdef USE_ENVMAP\n\t#ifdef ENV_WORLDPOS\n\t\tvWorldPosition = worldPosition.xyz;\n\t#else\n\t\tvec3 cameraToVertex = normalize( worldPosition.xyz - cameraPosition );\n\t\tvec3 worldNormal = inverseTransformDirection( transformedNormal, viewMatrix );\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvReflect = reflect( cameraToVertex, worldNormal );\n\t\t#else\n\t\t\tvReflect = refract( cameraToVertex, worldNormal, refractionRatio );\n\t\t#endif\n\t#endif\n#endif",fog_vertex:"#ifdef USE_FOG\n\tfogDepth = -mvPosition.z;\n#endif",
-fog_pars_vertex:"#ifdef USE_FOG\n\tvarying float fogDepth;\n#endif",fog_fragment:"#ifdef USE_FOG\n\t#ifdef FOG_EXP2\n\t\tfloat fogFactor = 1.0 - exp( - fogDensity * fogDensity * fogDepth * fogDepth );\n\t#else\n\t\tfloat fogFactor = smoothstep( fogNear, fogFar, fogDepth );\n\t#endif\n\tgl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );\n#endif",fog_pars_fragment:"#ifdef USE_FOG\n\tuniform vec3 fogColor;\n\tvarying float fogDepth;\n\t#ifdef FOG_EXP2\n\t\tuniform float fogDensity;\n\t#else\n\t\tuniform float fogNear;\n\t\tuniform float fogFar;\n\t#endif\n#endif",
-gradientmap_pars_fragment:"#ifdef TOON\n\tuniform sampler2D gradientMap;\n\tvec3 getGradientIrradiance( vec3 normal, vec3 lightDirection ) {\n\t\tfloat dotNL = dot( normal, lightDirection );\n\t\tvec2 coord = vec2( dotNL * 0.5 + 0.5, 0.0 );\n\t\t#ifdef USE_GRADIENTMAP\n\t\t\treturn texture2D( gradientMap, coord ).rgb;\n\t\t#else\n\t\t\treturn ( coord.x < 0.7 ) ? vec3( 0.7 ) : vec3( 1.0 );\n\t\t#endif\n\t}\n#endif",lightmap_fragment:"#ifdef USE_LIGHTMAP\n\treflectedLight.indirectDiffuse += PI * texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\n#endif",
-lightmap_pars_fragment:"#ifdef USE_LIGHTMAP\n\tuniform sampler2D lightMap;\n\tuniform float lightMapIntensity;\n#endif",lights_lambert_vertex:"vec3 diffuse = vec3( 1.0 );\nGeometricContext geometry;\ngeometry.position = mvPosition.xyz;\ngeometry.normal = normalize( transformedNormal );\ngeometry.viewDir = normalize( -mvPosition.xyz );\nGeometricContext backGeometry;\nbackGeometry.position = geometry.position;\nbackGeometry.normal = -geometry.normal;\nbackGeometry.viewDir = geometry.viewDir;\nvLightFront = vec3( 0.0 );\nvIndirectFront = vec3( 0.0 );\n#ifdef DOUBLE_SIDED\n\tvLightBack = vec3( 0.0 );\n\tvIndirectBack = vec3( 0.0 );\n#endif\nIncidentLight directLight;\nfloat dotNL;\nvec3 directLightColor_Diffuse;\n#if NUM_POINT_LIGHTS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tgetPointDirectLightIrradiance( pointLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = PI * directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n#endif\n#if NUM_SPOT_LIGHTS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tgetSpotDirectLightIrradiance( spotLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = PI * directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n#endif\n#if NUM_DIR_LIGHTS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tgetDirectionalDirectLightIrradiance( directionalLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = PI * directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n#endif\n#if NUM_HEMI_LIGHTS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\tvIndirectFront += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvIndirectBack += getHemisphereLightIrradiance( hemisphereLights[ i ], backGeometry );\n\t\t#endif\n\t}\n#endif",
-lights_pars_begin:"uniform bool receiveShadow;\nuniform vec3 ambientLightColor;\nuniform vec3 lightProbe[ 9 ];\nvec3 shGetIrradianceAt( in vec3 normal, in vec3 shCoefficients[ 9 ] ) {\n\tfloat x = normal.x, y = normal.y, z = normal.z;\n\tvec3 result = shCoefficients[ 0 ] * 0.886227;\n\tresult += shCoefficients[ 1 ] * 2.0 * 0.511664 * y;\n\tresult += shCoefficients[ 2 ] * 2.0 * 0.511664 * z;\n\tresult += shCoefficients[ 3 ] * 2.0 * 0.511664 * x;\n\tresult += shCoefficients[ 4 ] * 2.0 * 0.429043 * x * y;\n\tresult += shCoefficients[ 5 ] * 2.0 * 0.429043 * y * z;\n\tresult += shCoefficients[ 6 ] * ( 0.743125 * z * z - 0.247708 );\n\tresult += shCoefficients[ 7 ] * 2.0 * 0.429043 * x * z;\n\tresult += shCoefficients[ 8 ] * 0.429043 * ( x * x - y * y );\n\treturn result;\n}\nvec3 getLightProbeIrradiance( const in vec3 lightProbe[ 9 ], const in GeometricContext geometry ) {\n\tvec3 worldNormal = inverseTransformDirection( geometry.normal, viewMatrix );\n\tvec3 irradiance = shGetIrradianceAt( worldNormal, lightProbe );\n\treturn irradiance;\n}\nvec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) {\n\tvec3 irradiance = ambientLightColor;\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\treturn irradiance;\n}\n#if NUM_DIR_LIGHTS > 0\n\tstruct DirectionalLight {\n\t\tvec3 direction;\n\t\tvec3 color;\n\t\tint shadow;\n\t\tfloat shadowBias;\n\t\tfloat shadowRadius;\n\t\tvec2 shadowMapSize;\n\t};\n\tuniform DirectionalLight directionalLights[ NUM_DIR_LIGHTS ];\n\tvoid getDirectionalDirectLightIrradiance( const in DirectionalLight directionalLight, const in GeometricContext geometry, out IncidentLight directLight ) {\n\t\tdirectLight.color = directionalLight.color;\n\t\tdirectLight.direction = directionalLight.direction;\n\t\tdirectLight.visible = true;\n\t}\n#endif\n#if NUM_POINT_LIGHTS > 0\n\tstruct PointLight {\n\t\tvec3 position;\n\t\tvec3 color;\n\t\tfloat distance;\n\t\tfloat decay;\n\t\tint shadow;\n\t\tfloat shadowBias;\n\t\tfloat shadowRadius;\n\t\tvec2 shadowMapSize;\n\t\tfloat shadowCameraNear;\n\t\tfloat shadowCameraFar;\n\t};\n\tuniform PointLight pointLights[ NUM_POINT_LIGHTS ];\n\tvoid getPointDirectLightIrradiance( const in PointLight pointLight, const in GeometricContext geometry, out IncidentLight directLight ) {\n\t\tvec3 lVector = pointLight.position - geometry.position;\n\t\tdirectLight.direction = normalize( lVector );\n\t\tfloat lightDistance = length( lVector );\n\t\tdirectLight.color = pointLight.color;\n\t\tdirectLight.color *= punctualLightIntensityToIrradianceFactor( lightDistance, pointLight.distance, pointLight.decay );\n\t\tdirectLight.visible = ( directLight.color != vec3( 0.0 ) );\n\t}\n#endif\n#if NUM_SPOT_LIGHTS > 0\n\tstruct SpotLight {\n\t\tvec3 position;\n\t\tvec3 direction;\n\t\tvec3 color;\n\t\tfloat distance;\n\t\tfloat decay;\n\t\tfloat coneCos;\n\t\tfloat penumbraCos;\n\t\tint shadow;\n\t\tfloat shadowBias;\n\t\tfloat shadowRadius;\n\t\tvec2 shadowMapSize;\n\t};\n\tuniform SpotLight spotLights[ NUM_SPOT_LIGHTS ];\n\tvoid getSpotDirectLightIrradiance( const in SpotLight spotLight, const in GeometricContext geometry, out IncidentLight directLight ) {\n\t\tvec3 lVector = spotLight.position - geometry.position;\n\t\tdirectLight.direction = normalize( lVector );\n\t\tfloat lightDistance = length( lVector );\n\t\tfloat angleCos = dot( directLight.direction, spotLight.direction );\n\t\tif ( angleCos > spotLight.coneCos ) {\n\t\t\tfloat spotEffect = smoothstep( spotLight.coneCos, spotLight.penumbraCos, angleCos );\n\t\t\tdirectLight.color = spotLight.color;\n\t\t\tdirectLight.color *= spotEffect * punctualLightIntensityToIrradianceFactor( lightDistance, spotLight.distance, spotLight.decay );\n\t\t\tdirectLight.visible = true;\n\t\t} else {\n\t\t\tdirectLight.color = vec3( 0.0 );\n\t\t\tdirectLight.visible = false;\n\t\t}\n\t}\n#endif\n#if NUM_RECT_AREA_LIGHTS > 0\n\tstruct RectAreaLight {\n\t\tvec3 color;\n\t\tvec3 position;\n\t\tvec3 halfWidth;\n\t\tvec3 halfHeight;\n\t};\n\tuniform sampler2D ltc_1;\tuniform sampler2D ltc_2;\n\tuniform RectAreaLight rectAreaLights[ NUM_RECT_AREA_LIGHTS ];\n#endif\n#if NUM_HEMI_LIGHTS > 0\n\tstruct HemisphereLight {\n\t\tvec3 direction;\n\t\tvec3 skyColor;\n\t\tvec3 groundColor;\n\t};\n\tuniform HemisphereLight hemisphereLights[ NUM_HEMI_LIGHTS ];\n\tvec3 getHemisphereLightIrradiance( const in HemisphereLight hemiLight, const in GeometricContext geometry ) {\n\t\tfloat dotNL = dot( geometry.normal, hemiLight.direction );\n\t\tfloat hemiDiffuseWeight = 0.5 * dotNL + 0.5;\n\t\tvec3 irradiance = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight );\n\t\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\t\tirradiance *= PI;\n\t\t#endif\n\t\treturn irradiance;\n\t}\n#endif",
-lights_phong_fragment:"BlinnPhongMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;\nmaterial.specularColor = specular;\nmaterial.specularShininess = shininess;\nmaterial.specularStrength = specularStrength;",lights_phong_pars_fragment:"varying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\nstruct BlinnPhongMaterial {\n\tvec3\tdiffuseColor;\n\tvec3\tspecularColor;\n\tfloat\tspecularShininess;\n\tfloat\tspecularStrength;\n};\nvoid RE_Direct_BlinnPhong( const in IncidentLight directLight, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n\t#ifdef TOON\n\t\tvec3 irradiance = getGradientIrradiance( geometry.normal, directLight.direction ) * directLight.color;\n\t#else\n\t\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\n\t\tvec3 irradiance = dotNL * directLight.color;\n\t#endif\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\treflectedLight.directDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n\treflectedLight.directSpecular += irradiance * BRDF_Specular_BlinnPhong( directLight, geometry, material.specularColor, material.specularShininess ) * material.specularStrength;\n}\nvoid RE_IndirectDiffuse_BlinnPhong( const in vec3 irradiance, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\n#define RE_Direct\t\t\t\tRE_Direct_BlinnPhong\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_BlinnPhong\n#define Material_LightProbeLOD( material )\t(0)",
-lights_physical_fragment:"PhysicalMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb * ( 1.0 - metalnessFactor );\nmaterial.specularRoughness = clamp( roughnessFactor, 0.04, 1.0 );\n#ifdef REFLECTIVITY\n\tmaterial.specularColor = mix( vec3( MAXIMUM_SPECULAR_COEFFICIENT * pow2( reflectivity ) ), diffuseColor.rgb, metalnessFactor );\n#else\n\tmaterial.specularColor = mix( vec3( DEFAULT_SPECULAR_COEFFICIENT ), diffuseColor.rgb, metalnessFactor );\n#endif\n#ifdef CLEARCOAT\n\tmaterial.clearcoat = saturate( clearcoat );\tmaterial.clearcoatRoughness = clamp( clearcoatRoughness, 0.04, 1.0 );\n#endif\n#ifdef USE_SHEEN\n\tmaterial.sheenColor = sheen;\n#endif",
-lights_physical_pars_fragment:"struct PhysicalMaterial {\n\tvec3\tdiffuseColor;\n\tfloat\tspecularRoughness;\n\tvec3\tspecularColor;\n#ifdef CLEARCOAT\n\tfloat clearcoat;\n\tfloat clearcoatRoughness;\n#endif\n#ifdef USE_SHEEN\n\tvec3 sheenColor;\n#endif\n};\n#define MAXIMUM_SPECULAR_COEFFICIENT 0.16\n#define DEFAULT_SPECULAR_COEFFICIENT 0.04\nfloat clearcoatDHRApprox( const in float roughness, const in float dotNL ) {\n\treturn DEFAULT_SPECULAR_COEFFICIENT + ( 1.0 - DEFAULT_SPECULAR_COEFFICIENT ) * ( pow( 1.0 - dotNL, 5.0 ) * pow( 1.0 - roughness, 2.0 ) );\n}\n#if NUM_RECT_AREA_LIGHTS > 0\n\tvoid RE_Direct_RectArea_Physical( const in RectAreaLight rectAreaLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\t\tvec3 normal = geometry.normal;\n\t\tvec3 viewDir = geometry.viewDir;\n\t\tvec3 position = geometry.position;\n\t\tvec3 lightPos = rectAreaLight.position;\n\t\tvec3 halfWidth = rectAreaLight.halfWidth;\n\t\tvec3 halfHeight = rectAreaLight.halfHeight;\n\t\tvec3 lightColor = rectAreaLight.color;\n\t\tfloat roughness = material.specularRoughness;\n\t\tvec3 rectCoords[ 4 ];\n\t\trectCoords[ 0 ] = lightPos + halfWidth - halfHeight;\t\trectCoords[ 1 ] = lightPos - halfWidth - halfHeight;\n\t\trectCoords[ 2 ] = lightPos - halfWidth + halfHeight;\n\t\trectCoords[ 3 ] = lightPos + halfWidth + halfHeight;\n\t\tvec2 uv = LTC_Uv( normal, viewDir, roughness );\n\t\tvec4 t1 = texture2D( ltc_1, uv );\n\t\tvec4 t2 = texture2D( ltc_2, uv );\n\t\tmat3 mInv = mat3(\n\t\t\tvec3( t1.x, 0, t1.y ),\n\t\t\tvec3( 0, 1, 0 ),\n\t\t\tvec3( t1.z, 0, t1.w )\n\t\t);\n\t\tvec3 fresnel = ( material.specularColor * t2.x + ( vec3( 1.0 ) - material.specularColor ) * t2.y );\n\t\treflectedLight.directSpecular += lightColor * fresnel * LTC_Evaluate( normal, viewDir, position, mInv, rectCoords );\n\t\treflectedLight.directDiffuse += lightColor * material.diffuseColor * LTC_Evaluate( normal, viewDir, position, mat3( 1.0 ), rectCoords );\n\t}\n#endif\nvoid RE_Direct_Physical( const in IncidentLight directLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\n\tvec3 irradiance = dotNL * directLight.color;\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\t#ifdef CLEARCOAT\n\t\tfloat ccDotNL = saturate( dot( geometry.clearcoatNormal, directLight.direction ) );\n\t\tvec3 ccIrradiance = ccDotNL * directLight.color;\n\t\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\t\tccIrradiance *= PI;\n\t\t#endif\n\t\tfloat clearcoatDHR = material.clearcoat * clearcoatDHRApprox( material.clearcoatRoughness, ccDotNL );\n\t\treflectedLight.directSpecular += ccIrradiance * material.clearcoat * BRDF_Specular_GGX( directLight, geometry.viewDir, geometry.clearcoatNormal, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearcoatRoughness );\n\t#else\n\t\tfloat clearcoatDHR = 0.0;\n\t#endif\n\t#ifdef USE_SHEEN\n\t\treflectedLight.directSpecular += ( 1.0 - clearcoatDHR ) * irradiance * BRDF_Specular_Sheen(\n\t\t\tmaterial.specularRoughness,\n\t\t\tdirectLight.direction,\n\t\t\tgeometry,\n\t\t\tmaterial.sheenColor\n\t\t);\n\t#else\n\t\treflectedLight.directSpecular += ( 1.0 - clearcoatDHR ) * irradiance * BRDF_Specular_GGX( directLight, geometry.viewDir, geometry.normal, material.specularColor, material.specularRoughness);\n\t#endif\n\treflectedLight.directDiffuse += ( 1.0 - clearcoatDHR ) * irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectDiffuse_Physical( const in vec3 irradiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectSpecular_Physical( const in vec3 radiance, const in vec3 irradiance, const in vec3 clearcoatRadiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight) {\n\t#ifdef CLEARCOAT\n\t\tfloat ccDotNV = saturate( dot( geometry.clearcoatNormal, geometry.viewDir ) );\n\t\treflectedLight.indirectSpecular += clearcoatRadiance * material.clearcoat * BRDF_Specular_GGX_Environment( geometry.viewDir, geometry.clearcoatNormal, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearcoatRoughness );\n\t\tfloat ccDotNL = ccDotNV;\n\t\tfloat clearcoatDHR = material.clearcoat * clearcoatDHRApprox( material.clearcoatRoughness, ccDotNL );\n\t#else\n\t\tfloat clearcoatDHR = 0.0;\n\t#endif\n\tfloat clearcoatInv = 1.0 - clearcoatDHR;\n\tvec3 singleScattering = vec3( 0.0 );\n\tvec3 multiScattering = vec3( 0.0 );\n\tvec3 cosineWeightedIrradiance = irradiance * RECIPROCAL_PI;\n\tBRDF_Specular_Multiscattering_Environment( geometry, material.specularColor, material.specularRoughness, singleScattering, multiScattering );\n\tvec3 diffuse = material.diffuseColor * ( 1.0 - ( singleScattering + multiScattering ) );\n\treflectedLight.indirectSpecular += clearcoatInv * radiance * singleScattering;\n\treflectedLight.indirectSpecular += multiScattering * cosineWeightedIrradiance;\n\treflectedLight.indirectDiffuse += diffuse * cosineWeightedIrradiance;\n}\n#define RE_Direct\t\t\t\tRE_Direct_Physical\n#define RE_Direct_RectArea\t\tRE_Direct_RectArea_Physical\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_Physical\n#define RE_IndirectSpecular\t\tRE_IndirectSpecular_Physical\nfloat computeSpecularOcclusion( const in float dotNV, const in float ambientOcclusion, const in float roughness ) {\n\treturn saturate( pow( dotNV + ambientOcclusion, exp2( - 16.0 * roughness - 1.0 ) ) - 1.0 + ambientOcclusion );\n}",
-lights_fragment_begin:"\nGeometricContext geometry;\ngeometry.position = - vViewPosition;\ngeometry.normal = normal;\ngeometry.viewDir = normalize( vViewPosition );\n#ifdef CLEARCOAT\n\tgeometry.clearcoatNormal = clearcoatNormal;\n#endif\nIncidentLight directLight;\n#if ( NUM_POINT_LIGHTS > 0 ) && defined( RE_Direct )\n\tPointLight pointLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tpointLight = pointLights[ i ];\n\t\tgetPointDirectLightIrradiance( pointLight, geometry, directLight );\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_POINT_LIGHT_SHADOWS )\n\t\tdirectLight.color *= all( bvec3( pointLight.shadow, directLight.visible, receiveShadow ) ) ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ], pointLight.shadowCameraNear, pointLight.shadowCameraFar ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if ( NUM_SPOT_LIGHTS > 0 ) && defined( RE_Direct )\n\tSpotLight spotLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tspotLight = spotLights[ i ];\n\t\tgetSpotDirectLightIrradiance( spotLight, geometry, directLight );\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n\t\tdirectLight.color *= all( bvec3( spotLight.shadow, directLight.visible, receiveShadow ) ) ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if ( NUM_DIR_LIGHTS > 0 ) && defined( RE_Direct )\n\tDirectionalLight directionalLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tdirectionalLight = directionalLights[ i ];\n\t\tgetDirectionalDirectLightIrradiance( directionalLight, geometry, directLight );\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_DIR_LIGHT_SHADOWS )\n\t\tdirectLight.color *= all( bvec3( directionalLight.shadow, directLight.visible, receiveShadow ) ) ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if ( NUM_RECT_AREA_LIGHTS > 0 ) && defined( RE_Direct_RectArea )\n\tRectAreaLight rectAreaLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_RECT_AREA_LIGHTS; i ++ ) {\n\t\trectAreaLight = rectAreaLights[ i ];\n\t\tRE_Direct_RectArea( rectAreaLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if defined( RE_IndirectDiffuse )\n\tvec3 iblIrradiance = vec3( 0.0 );\n\tvec3 irradiance = getAmbientLightIrradiance( ambientLightColor );\n\tirradiance += getLightProbeIrradiance( lightProbe, geometry );\n\t#if ( NUM_HEMI_LIGHTS > 0 )\n\t\t#pragma unroll_loop\n\t\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\t\tirradiance += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\n\t\t}\n\t#endif\n#endif\n#if defined( RE_IndirectSpecular )\n\tvec3 radiance = vec3( 0.0 );\n\tvec3 clearcoatRadiance = vec3( 0.0 );\n#endif",
-lights_fragment_maps:"#if defined( RE_IndirectDiffuse )\n\t#ifdef USE_LIGHTMAP\n\t\tvec3 lightMapIrradiance = texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\n\t\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\t\tlightMapIrradiance *= PI;\n\t\t#endif\n\t\tirradiance += lightMapIrradiance;\n\t#endif\n\t#if defined( USE_ENVMAP ) && defined( STANDARD ) && defined( ENVMAP_TYPE_CUBE_UV )\n\t\tiblIrradiance += getLightProbeIndirectIrradiance( geometry, maxMipLevel );\n\t#endif\n#endif\n#if defined( USE_ENVMAP ) && defined( RE_IndirectSpecular )\n\tradiance += getLightProbeIndirectRadiance( geometry.viewDir, geometry.normal, material.specularRoughness, maxMipLevel );\n\t#ifdef CLEARCOAT\n\t\tclearcoatRadiance += getLightProbeIndirectRadiance( geometry.viewDir, geometry.clearcoatNormal, material.clearcoatRoughness, maxMipLevel );\n\t#endif\n#endif",
-lights_fragment_end:"#if defined( RE_IndirectDiffuse )\n\tRE_IndirectDiffuse( irradiance, geometry, material, reflectedLight );\n#endif\n#if defined( RE_IndirectSpecular )\n\tRE_IndirectSpecular( radiance, iblIrradiance, clearcoatRadiance, geometry, material, reflectedLight );\n#endif",logdepthbuf_fragment:"#if defined( USE_LOGDEPTHBUF ) && defined( USE_LOGDEPTHBUF_EXT )\n\tgl_FragDepthEXT = vIsPerspective == 1.0 ? log2( vFragDepth ) * logDepthBufFC * 0.5 : gl_FragCoord.z;\n#endif",logdepthbuf_pars_fragment:"#if defined( USE_LOGDEPTHBUF ) && defined( USE_LOGDEPTHBUF_EXT )\n\tuniform float logDepthBufFC;\n\tvarying float vFragDepth;\n\tvarying float vIsPerspective;\n#endif",
-logdepthbuf_pars_vertex:"#ifdef USE_LOGDEPTHBUF\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tvarying float vFragDepth;\n\t\tvarying float vIsPerspective;\n\t#else\n\t\tuniform float logDepthBufFC;\n\t#endif\n#endif",logdepthbuf_vertex:"#ifdef USE_LOGDEPTHBUF\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tvFragDepth = 1.0 + gl_Position.w;\n\t\tvIsPerspective = float( isPerspectiveMatrix( projectionMatrix ) );\n\t#else\n\t\tif ( isPerspectiveMatrix( projectionMatrix ) ) {\n\t\t\tgl_Position.z = log2( max( EPSILON, gl_Position.w + 1.0 ) ) * logDepthBufFC - 1.0;\n\t\t\tgl_Position.z *= gl_Position.w;\n\t\t}\n\t#endif\n#endif",
-map_fragment:"#ifdef USE_MAP\n\tvec4 texelColor = texture2D( map, vUv );\n\ttexelColor = mapTexelToLinear( texelColor );\n\tdiffuseColor *= texelColor;\n#endif",map_pars_fragment:"#ifdef USE_MAP\n\tuniform sampler2D map;\n#endif",map_particle_fragment:"#ifdef USE_MAP\n\tvec2 uv = ( uvTransform * vec3( gl_PointCoord.x, 1.0 - gl_PointCoord.y, 1 ) ).xy;\n\tvec4 mapTexel = texture2D( map, uv );\n\tdiffuseColor *= mapTexelToLinear( mapTexel );\n#endif",map_particle_pars_fragment:"#ifdef USE_MAP\n\tuniform mat3 uvTransform;\n\tuniform sampler2D map;\n#endif",
-metalnessmap_fragment:"float metalnessFactor = metalness;\n#ifdef USE_METALNESSMAP\n\tvec4 texelMetalness = texture2D( metalnessMap, vUv );\n\tmetalnessFactor *= texelMetalness.b;\n#endif",metalnessmap_pars_fragment:"#ifdef USE_METALNESSMAP\n\tuniform sampler2D metalnessMap;\n#endif",morphnormal_vertex:"#ifdef USE_MORPHNORMALS\n\tobjectNormal += ( morphNormal0 - normal ) * morphTargetInfluences[ 0 ];\n\tobjectNormal += ( morphNormal1 - normal ) * morphTargetInfluences[ 1 ];\n\tobjectNormal += ( morphNormal2 - normal ) * morphTargetInfluences[ 2 ];\n\tobjectNormal += ( morphNormal3 - normal ) * morphTargetInfluences[ 3 ];\n#endif",
-morphtarget_pars_vertex:"#ifdef USE_MORPHTARGETS\n\t#ifndef USE_MORPHNORMALS\n\tuniform float morphTargetInfluences[ 8 ];\n\t#else\n\tuniform float morphTargetInfluences[ 4 ];\n\t#endif\n#endif",morphtarget_vertex:"#ifdef USE_MORPHTARGETS\n\ttransformed += ( morphTarget0 - position ) * morphTargetInfluences[ 0 ];\n\ttransformed += ( morphTarget1 - position ) * morphTargetInfluences[ 1 ];\n\ttransformed += ( morphTarget2 - position ) * morphTargetInfluences[ 2 ];\n\ttransformed += ( morphTarget3 - position ) * morphTargetInfluences[ 3 ];\n\t#ifndef USE_MORPHNORMALS\n\ttransformed += ( morphTarget4 - position ) * morphTargetInfluences[ 4 ];\n\ttransformed += ( morphTarget5 - position ) * morphTargetInfluences[ 5 ];\n\ttransformed += ( morphTarget6 - position ) * morphTargetInfluences[ 6 ];\n\ttransformed += ( morphTarget7 - position ) * morphTargetInfluences[ 7 ];\n\t#endif\n#endif",
-normal_fragment_begin:"#ifdef FLAT_SHADED\n\tvec3 fdx = vec3( dFdx( vViewPosition.x ), dFdx( vViewPosition.y ), dFdx( vViewPosition.z ) );\n\tvec3 fdy = vec3( dFdy( vViewPosition.x ), dFdy( vViewPosition.y ), dFdy( vViewPosition.z ) );\n\tvec3 normal = normalize( cross( fdx, fdy ) );\n#else\n\tvec3 normal = normalize( vNormal );\n\t#ifdef DOUBLE_SIDED\n\t\tnormal = normal * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t#endif\n\t#ifdef USE_TANGENT\n\t\tvec3 tangent = normalize( vTangent );\n\t\tvec3 bitangent = normalize( vBitangent );\n\t\t#ifdef DOUBLE_SIDED\n\t\t\ttangent = tangent * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\t\tbitangent = bitangent * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\t#endif\n\t#endif\n#endif\nvec3 geometryNormal = normal;",
-normal_fragment_maps:"#ifdef OBJECTSPACE_NORMALMAP\n\tnormal = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\t#ifdef FLIP_SIDED\n\t\tnormal = - normal;\n\t#endif\n\t#ifdef DOUBLE_SIDED\n\t\tnormal = normal * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t#endif\n\tnormal = normalize( normalMatrix * normal );\n#elif defined( TANGENTSPACE_NORMALMAP )\n\t#ifdef USE_TANGENT\n\t\tmat3 vTBN = mat3( tangent, bitangent, normal );\n\t\tvec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\t\tmapN.xy = normalScale * mapN.xy;\n\t\tnormal = normalize( vTBN * mapN );\n\t#else\n\t\tnormal = perturbNormal2Arb( -vViewPosition, normal, normalScale, normalMap );\n\t#endif\n#elif defined( USE_BUMPMAP )\n\tnormal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() );\n#endif",
-normalmap_pars_fragment:"#ifdef USE_NORMALMAP\n\tuniform sampler2D normalMap;\n\tuniform vec2 normalScale;\n#endif\n#ifdef OBJECTSPACE_NORMALMAP\n\tuniform mat3 normalMatrix;\n#endif\n#if ! defined ( USE_TANGENT ) && ( defined ( TANGENTSPACE_NORMALMAP ) || defined ( USE_CLEARCOAT_NORMALMAP ) )\n\tvec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm, vec2 normalScale, in sampler2D normalMap ) {\n\t\tvec3 q0 = vec3( dFdx( eye_pos.x ), dFdx( eye_pos.y ), dFdx( eye_pos.z ) );\n\t\tvec3 q1 = vec3( dFdy( eye_pos.x ), dFdy( eye_pos.y ), dFdy( eye_pos.z ) );\n\t\tvec2 st0 = dFdx( vUv.st );\n\t\tvec2 st1 = dFdy( vUv.st );\n\t\tfloat scale = sign( st1.t * st0.s - st0.t * st1.s );\n\t\tvec3 S = normalize( ( q0 * st1.t - q1 * st0.t ) * scale );\n\t\tvec3 T = normalize( ( - q0 * st1.s + q1 * st0.s ) * scale );\n\t\tvec3 N = normalize( surf_norm );\n\t\tvec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\t\tmapN.xy *= normalScale;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tbool frontFacing = dot( cross( S, T ), N ) > 0.0;\n\t\t\tmapN.xy *= ( float( frontFacing ) * 2.0 - 1.0 );\n\t\t#else\n\t\t\tmapN.xy *= ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\t#endif\n\t\tmat3 tsn = mat3( S, T, N );\n\t\treturn normalize( tsn * mapN );\n\t}\n#endif",
-clearcoat_normal_fragment_begin:"#ifdef CLEARCOAT\n\tvec3 clearcoatNormal = geometryNormal;\n#endif",clearcoat_normal_fragment_maps:"#ifdef USE_CLEARCOAT_NORMALMAP\n\t#ifdef USE_TANGENT\n\t\tmat3 vTBN = mat3( tangent, bitangent, clearcoatNormal );\n\t\tvec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\t\tmapN.xy = clearcoatNormalScale * mapN.xy;\n\t\tclearcoatNormal = normalize( vTBN * mapN );\n\t#else\n\t\tclearcoatNormal = perturbNormal2Arb( - vViewPosition, clearcoatNormal, clearcoatNormalScale, clearcoatNormalMap );\n\t#endif\n#endif",
-clearcoat_normalmap_pars_fragment:"#ifdef USE_CLEARCOAT_NORMALMAP\n\tuniform sampler2D clearcoatNormalMap;\n\tuniform vec2 clearcoatNormalScale;\n#endif",packing:"vec3 packNormalToRGB( const in vec3 normal ) {\n\treturn normalize( normal ) * 0.5 + 0.5;\n}\nvec3 unpackRGBToNormal( const in vec3 rgb ) {\n\treturn 2.0 * rgb.xyz - 1.0;\n}\nconst float PackUpscale = 256. / 255.;const float UnpackDownscale = 255. / 256.;\nconst vec3 PackFactors = vec3( 256. * 256. * 256., 256. * 256., 256. );\nconst vec4 UnpackFactors = UnpackDownscale / vec4( PackFactors, 1. );\nconst float ShiftRight8 = 1. / 256.;\nvec4 packDepthToRGBA( const in float v ) {\n\tvec4 r = vec4( fract( v * PackFactors ), v );\n\tr.yzw -= r.xyz * ShiftRight8;\treturn r * PackUpscale;\n}\nfloat unpackRGBAToDepth( const in vec4 v ) {\n\treturn dot( v, UnpackFactors );\n}\nvec4 encodeHalfRGBA ( vec2 v ) {\n\tvec4 encoded = vec4( 0.0 );\n\tconst vec2 offset = vec2( 1.0 / 255.0, 0.0 );\n\tencoded.xy = vec2( v.x, fract( v.x * 255.0 ) );\n\tencoded.xy = encoded.xy - ( encoded.yy * offset );\n\tencoded.zw = vec2( v.y, fract( v.y * 255.0 ) );\n\tencoded.zw = encoded.zw - ( encoded.ww * offset );\n\treturn encoded;\n}\nvec2 decodeHalfRGBA( vec4 v ) {\n\treturn vec2( v.x + ( v.y / 255.0 ), v.z + ( v.w / 255.0 ) );\n}\nfloat viewZToOrthographicDepth( const in float viewZ, const in float near, const in float far ) {\n\treturn ( viewZ + near ) / ( near - far );\n}\nfloat orthographicDepthToViewZ( const in float linearClipZ, const in float near, const in float far ) {\n\treturn linearClipZ * ( near - far ) - near;\n}\nfloat viewZToPerspectiveDepth( const in float viewZ, const in float near, const in float far ) {\n\treturn (( near + viewZ ) * far ) / (( far - near ) * viewZ );\n}\nfloat perspectiveDepthToViewZ( const in float invClipZ, const in float near, const in float far ) {\n\treturn ( near * far ) / ( ( far - near ) * invClipZ - far );\n}",
-premultiplied_alpha_fragment:"#ifdef PREMULTIPLIED_ALPHA\n\tgl_FragColor.rgb *= gl_FragColor.a;\n#endif",project_vertex:"vec4 mvPosition = vec4( transformed, 1.0 );\n#ifdef USE_INSTANCING\n\tmvPosition = instanceMatrix * mvPosition;\n#endif\nmvPosition = modelViewMatrix * mvPosition;\ngl_Position = projectionMatrix * mvPosition;",dithering_fragment:"#ifdef DITHERING\n\tgl_FragColor.rgb = dithering( gl_FragColor.rgb );\n#endif",dithering_pars_fragment:"#ifdef DITHERING\n\tvec3 dithering( vec3 color ) {\n\t\tfloat grid_position = rand( gl_FragCoord.xy );\n\t\tvec3 dither_shift_RGB = vec3( 0.25 / 255.0, -0.25 / 255.0, 0.25 / 255.0 );\n\t\tdither_shift_RGB = mix( 2.0 * dither_shift_RGB, -2.0 * dither_shift_RGB, grid_position );\n\t\treturn color + dither_shift_RGB;\n\t}\n#endif",
-roughnessmap_fragment:"float roughnessFactor = roughness;\n#ifdef USE_ROUGHNESSMAP\n\tvec4 texelRoughness = texture2D( roughnessMap, vUv );\n\troughnessFactor *= texelRoughness.g;\n#endif",roughnessmap_pars_fragment:"#ifdef USE_ROUGHNESSMAP\n\tuniform sampler2D roughnessMap;\n#endif",shadowmap_pars_fragment:"#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\t\tuniform sampler2D directionalShadowMap[ NUM_DIR_LIGHT_SHADOWS ];\n\t\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\t\tuniform sampler2D spotShadowMap[ NUM_SPOT_LIGHT_SHADOWS ];\n\t\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\t\tuniform sampler2D pointShadowMap[ NUM_POINT_LIGHT_SHADOWS ];\n\t\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHT_SHADOWS ];\n\t#endif\n\tfloat texture2DCompare( sampler2D depths, vec2 uv, float compare ) {\n\t\treturn step( compare, unpackRGBAToDepth( texture2D( depths, uv ) ) );\n\t}\n\tvec2 texture2DDistribution( sampler2D shadow, vec2 uv ) {\n\t\treturn decodeHalfRGBA( texture2D( shadow, uv ) );\n\t}\n\tfloat VSMShadow (sampler2D shadow, vec2 uv, float compare ){\n\t\tfloat occlusion = 1.0;\n\t\tvec2 distribution = texture2DDistribution( shadow, uv );\n\t\tfloat hard_shadow = step( compare , distribution.x );\n\t\tif (hard_shadow != 1.0 ) {\n\t\t\tfloat distance = compare - distribution.x ;\n\t\t\tfloat variance = max( 0.00000, distribution.y * distribution.y );\n\t\t\tfloat softness_probability = variance / (variance + distance * distance );\t\t\tsoftness_probability = clamp( ( softness_probability - 0.3 ) / ( 0.95 - 0.3 ), 0.0, 1.0 );\t\t\tocclusion = clamp( max( hard_shadow, softness_probability ), 0.0, 1.0 );\n\t\t}\n\t\treturn occlusion;\n\t}\n\tfloat texture2DShadowLerp( sampler2D depths, vec2 size, vec2 uv, float compare ) {\n\t\tconst vec2 offset = vec2( 0.0, 1.0 );\n\t\tvec2 texelSize = vec2( 1.0 ) / size;\n\t\tvec2 centroidUV = ( floor( uv * size - 0.5 ) + 0.5 ) * texelSize;\n\t\tfloat lb = texture2DCompare( depths, centroidUV + texelSize * offset.xx, compare );\n\t\tfloat lt = texture2DCompare( depths, centroidUV + texelSize * offset.xy, compare );\n\t\tfloat rb = texture2DCompare( depths, centroidUV + texelSize * offset.yx, compare );\n\t\tfloat rt = texture2DCompare( depths, centroidUV + texelSize * offset.yy, compare );\n\t\tvec2 f = fract( uv * size + 0.5 );\n\t\tfloat a = mix( lb, lt, f.y );\n\t\tfloat b = mix( rb, rt, f.y );\n\t\tfloat c = mix( a, b, f.x );\n\t\treturn c;\n\t}\n\tfloat getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\n\t\tfloat shadow = 1.0;\n\t\tshadowCoord.xyz /= shadowCoord.w;\n\t\tshadowCoord.z += shadowBias;\n\t\tbvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 );\n\t\tbool inFrustum = all( inFrustumVec );\n\t\tbvec2 frustumTestVec = bvec2( inFrustum, shadowCoord.z <= 1.0 );\n\t\tbool frustumTest = all( frustumTestVec );\n\t\tif ( frustumTest ) {\n\t\t#if defined( SHADOWMAP_TYPE_PCF )\n\t\t\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n\t\t\tfloat dx0 = - texelSize.x * shadowRadius;\n\t\t\tfloat dy0 = - texelSize.y * shadowRadius;\n\t\t\tfloat dx1 = + texelSize.x * shadowRadius;\n\t\t\tfloat dy1 = + texelSize.y * shadowRadius;\n\t\t\tfloat dx2 = dx0 / 2.0;\n\t\t\tfloat dy2 = dy0 / 2.0;\n\t\t\tfloat dx3 = dx1 / 2.0;\n\t\t\tfloat dy3 = dy1 / 2.0;\n\t\t\tshadow = (\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, dy2 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy2 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, dy2 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, dy3 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy3 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, dy3 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\n\t\t\t) * ( 1.0 / 17.0 );\n\t\t#elif defined( SHADOWMAP_TYPE_PCF_SOFT )\n\t\t\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n\t\t\tfloat dx0 = - texelSize.x * shadowRadius;\n\t\t\tfloat dy0 = - texelSize.y * shadowRadius;\n\t\t\tfloat dx1 = + texelSize.x * shadowRadius;\n\t\t\tfloat dy1 = + texelSize.y * shadowRadius;\n\t\t\tshadow = (\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy, shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\n\t\t\t) * ( 1.0 / 9.0 );\n\t\t#elif defined( SHADOWMAP_TYPE_VSM )\n\t\t\tshadow = VSMShadow( shadowMap, shadowCoord.xy, shadowCoord.z );\n\t\t#else\n\t\t\tshadow = texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z );\n\t\t#endif\n\t\t}\n\t\treturn shadow;\n\t}\n\tvec2 cubeToUV( vec3 v, float texelSizeY ) {\n\t\tvec3 absV = abs( v );\n\t\tfloat scaleToCube = 1.0 / max( absV.x, max( absV.y, absV.z ) );\n\t\tabsV *= scaleToCube;\n\t\tv *= scaleToCube * ( 1.0 - 2.0 * texelSizeY );\n\t\tvec2 planar = v.xy;\n\t\tfloat almostATexel = 1.5 * texelSizeY;\n\t\tfloat almostOne = 1.0 - almostATexel;\n\t\tif ( absV.z >= almostOne ) {\n\t\t\tif ( v.z > 0.0 )\n\t\t\t\tplanar.x = 4.0 - v.x;\n\t\t} else if ( absV.x >= almostOne ) {\n\t\t\tfloat signX = sign( v.x );\n\t\t\tplanar.x = v.z * signX + 2.0 * signX;\n\t\t} else if ( absV.y >= almostOne ) {\n\t\t\tfloat signY = sign( v.y );\n\t\t\tplanar.x = v.x + 2.0 * signY + 2.0;\n\t\t\tplanar.y = v.z * signY - 2.0;\n\t\t}\n\t\treturn vec2( 0.125, 0.25 ) * planar + vec2( 0.375, 0.75 );\n\t}\n\tfloat getPointShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord, float shadowCameraNear, float shadowCameraFar ) {\n\t\tvec2 texelSize = vec2( 1.0 ) / ( shadowMapSize * vec2( 4.0, 2.0 ) );\n\t\tvec3 lightToPosition = shadowCoord.xyz;\n\t\tfloat dp = ( length( lightToPosition ) - shadowCameraNear ) / ( shadowCameraFar - shadowCameraNear );\t\tdp += shadowBias;\n\t\tvec3 bd3D = normalize( lightToPosition );\n\t\t#if defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_PCF_SOFT ) || defined( SHADOWMAP_TYPE_VSM )\n\t\t\tvec2 offset = vec2( - 1, 1 ) * shadowRadius * texelSize.y;\n\t\t\treturn (\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxx, texelSize.y ), dp )\n\t\t\t) * ( 1.0 / 9.0 );\n\t\t#else\n\t\t\treturn texture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp );\n\t\t#endif\n\t}\n#endif",
-shadowmap_pars_vertex:"#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\t\tuniform mat4 directionalShadowMatrix[ NUM_DIR_LIGHT_SHADOWS ];\n\t\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\t\tuniform mat4 spotShadowMatrix[ NUM_SPOT_LIGHT_SHADOWS ];\n\t\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\t\tuniform mat4 pointShadowMatrix[ NUM_POINT_LIGHT_SHADOWS ];\n\t\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHT_SHADOWS ];\n\t#endif\n#endif",
-shadowmap_vertex:"#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_DIR_LIGHT_SHADOWS; i ++ ) {\n\t\tvDirectionalShadowCoord[ i ] = directionalShadowMatrix[ i ] * worldPosition;\n\t}\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_SPOT_LIGHT_SHADOWS; i ++ ) {\n\t\tvSpotShadowCoord[ i ] = spotShadowMatrix[ i ] * worldPosition;\n\t}\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_POINT_LIGHT_SHADOWS; i ++ ) {\n\t\tvPointShadowCoord[ i ] = pointShadowMatrix[ i ] * worldPosition;\n\t}\n\t#endif\n#endif",
-shadowmask_pars_fragment:"float getShadowMask() {\n\tfloat shadow = 1.0;\n\t#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\tDirectionalLight directionalLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_DIR_LIGHT_SHADOWS; i ++ ) {\n\t\tdirectionalLight = directionalLights[ i ];\n\t\tshadow *= all( bvec2( directionalLight.shadow, receiveShadow ) ) ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t}\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\tSpotLight spotLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_SPOT_LIGHT_SHADOWS; i ++ ) {\n\t\tspotLight = spotLights[ i ];\n\t\tshadow *= all( bvec2( spotLight.shadow, receiveShadow ) ) ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\n\t}\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\tPointLight pointLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_POINT_LIGHT_SHADOWS; i ++ ) {\n\t\tpointLight = pointLights[ i ];\n\t\tshadow *= all( bvec2( pointLight.shadow, receiveShadow ) ) ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ], pointLight.shadowCameraNear, pointLight.shadowCameraFar ) : 1.0;\n\t}\n\t#endif\n\t#endif\n\treturn shadow;\n}",
-skinbase_vertex:"#ifdef USE_SKINNING\n\tmat4 boneMatX = getBoneMatrix( skinIndex.x );\n\tmat4 boneMatY = getBoneMatrix( skinIndex.y );\n\tmat4 boneMatZ = getBoneMatrix( skinIndex.z );\n\tmat4 boneMatW = getBoneMatrix( skinIndex.w );\n#endif",skinning_pars_vertex:"#ifdef USE_SKINNING\n\tuniform mat4 bindMatrix;\n\tuniform mat4 bindMatrixInverse;\n\t#ifdef BONE_TEXTURE\n\t\tuniform highp sampler2D boneTexture;\n\t\tuniform int boneTextureSize;\n\t\tmat4 getBoneMatrix( const in float i ) {\n\t\t\tfloat j = i * 4.0;\n\t\t\tfloat x = mod( j, float( boneTextureSize ) );\n\t\t\tfloat y = floor( j / float( boneTextureSize ) );\n\t\t\tfloat dx = 1.0 / float( boneTextureSize );\n\t\t\tfloat dy = 1.0 / float( boneTextureSize );\n\t\t\ty = dy * ( y + 0.5 );\n\t\t\tvec4 v1 = texture2D( boneTexture, vec2( dx * ( x + 0.5 ), y ) );\n\t\t\tvec4 v2 = texture2D( boneTexture, vec2( dx * ( x + 1.5 ), y ) );\n\t\t\tvec4 v3 = texture2D( boneTexture, vec2( dx * ( x + 2.5 ), y ) );\n\t\t\tvec4 v4 = texture2D( boneTexture, vec2( dx * ( x + 3.5 ), y ) );\n\t\t\tmat4 bone = mat4( v1, v2, v3, v4 );\n\t\t\treturn bone;\n\t\t}\n\t#else\n\t\tuniform mat4 boneMatrices[ MAX_BONES ];\n\t\tmat4 getBoneMatrix( const in float i ) {\n\t\t\tmat4 bone = boneMatrices[ int(i) ];\n\t\t\treturn bone;\n\t\t}\n\t#endif\n#endif",
-skinning_vertex:"#ifdef USE_SKINNING\n\tvec4 skinVertex = bindMatrix * vec4( transformed, 1.0 );\n\tvec4 skinned = vec4( 0.0 );\n\tskinned += boneMatX * skinVertex * skinWeight.x;\n\tskinned += boneMatY * skinVertex * skinWeight.y;\n\tskinned += boneMatZ * skinVertex * skinWeight.z;\n\tskinned += boneMatW * skinVertex * skinWeight.w;\n\ttransformed = ( bindMatrixInverse * skinned ).xyz;\n#endif",skinnormal_vertex:"#ifdef USE_SKINNING\n\tmat4 skinMatrix = mat4( 0.0 );\n\tskinMatrix += skinWeight.x * boneMatX;\n\tskinMatrix += skinWeight.y * boneMatY;\n\tskinMatrix += skinWeight.z * boneMatZ;\n\tskinMatrix += skinWeight.w * boneMatW;\n\tskinMatrix = bindMatrixInverse * skinMatrix * bindMatrix;\n\tobjectNormal = vec4( skinMatrix * vec4( objectNormal, 0.0 ) ).xyz;\n\t#ifdef USE_TANGENT\n\t\tobjectTangent = vec4( skinMatrix * vec4( objectTangent, 0.0 ) ).xyz;\n\t#endif\n#endif",
-specularmap_fragment:"float specularStrength;\n#ifdef USE_SPECULARMAP\n\tvec4 texelSpecular = texture2D( specularMap, vUv );\n\tspecularStrength = texelSpecular.r;\n#else\n\tspecularStrength = 1.0;\n#endif",specularmap_pars_fragment:"#ifdef USE_SPECULARMAP\n\tuniform sampler2D specularMap;\n#endif",tonemapping_fragment:"#if defined( TONE_MAPPING )\n\tgl_FragColor.rgb = toneMapping( gl_FragColor.rgb );\n#endif",tonemapping_pars_fragment:"#ifndef saturate\n#define saturate(a) clamp( a, 0.0, 1.0 )\n#endif\nuniform float toneMappingExposure;\nuniform float toneMappingWhitePoint;\nvec3 LinearToneMapping( vec3 color ) {\n\treturn toneMappingExposure * color;\n}\nvec3 ReinhardToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\treturn saturate( color / ( vec3( 1.0 ) + color ) );\n}\n#define Uncharted2Helper( x ) max( ( ( x * ( 0.15 * x + 0.10 * 0.50 ) + 0.20 * 0.02 ) / ( x * ( 0.15 * x + 0.50 ) + 0.20 * 0.30 ) ) - 0.02 / 0.30, vec3( 0.0 ) )\nvec3 Uncharted2ToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\treturn saturate( Uncharted2Helper( color ) / Uncharted2Helper( vec3( toneMappingWhitePoint ) ) );\n}\nvec3 OptimizedCineonToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\tcolor = max( vec3( 0.0 ), color - 0.004 );\n\treturn pow( ( color * ( 6.2 * color + 0.5 ) ) / ( color * ( 6.2 * color + 1.7 ) + 0.06 ), vec3( 2.2 ) );\n}\nvec3 ACESFilmicToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\treturn saturate( ( color * ( 2.51 * color + 0.03 ) ) / ( color * ( 2.43 * color + 0.59 ) + 0.14 ) );\n}",
-uv_pars_fragment:"#ifdef USE_UV\n\tvarying vec2 vUv;\n#endif",uv_pars_vertex:"#ifdef USE_UV\n\tvarying vec2 vUv;\n\tuniform mat3 uvTransform;\n#endif",uv_vertex:"#ifdef USE_UV\n\tvUv = ( uvTransform * vec3( uv, 1 ) ).xy;\n#endif",uv2_pars_fragment:"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tvarying vec2 vUv2;\n#endif",uv2_pars_vertex:"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tattribute vec2 uv2;\n\tvarying vec2 vUv2;\n#endif",uv2_vertex:"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tvUv2 = uv2;\n#endif",
-worldpos_vertex:"#if defined( USE_ENVMAP ) || defined( DISTANCE ) || defined ( USE_SHADOWMAP )\n\tvec4 worldPosition = vec4( transformed, 1.0 );\n\t#ifdef USE_INSTANCING\n\t\tworldPosition = instanceMatrix * worldPosition;\n\t#endif\n\tworldPosition = modelMatrix * worldPosition;\n#endif",background_frag:"uniform sampler2D t2D;\nvarying vec2 vUv;\nvoid main() {\n\tvec4 texColor = texture2D( t2D, vUv );\n\tgl_FragColor = mapTexelToLinear( texColor );\n\t#include \n\t#include \n}",
-background_vert:"varying vec2 vUv;\nuniform mat3 uvTransform;\nvoid main() {\n\tvUv = ( uvTransform * vec3( uv, 1 ) ).xy;\n\tgl_Position = vec4( position.xy, 1.0, 1.0 );\n}",cube_frag:"uniform samplerCube tCube;\nuniform float tFlip;\nuniform float opacity;\nvarying vec3 vWorldDirection;\nvoid main() {\n\tvec4 texColor = textureCube( tCube, vec3( tFlip * vWorldDirection.x, vWorldDirection.yz ) );\n\tgl_FragColor = mapTexelToLinear( texColor );\n\tgl_FragColor.a *= opacity;\n\t#include \n\t#include \n}",
-cube_vert:"varying vec3 vWorldDirection;\n#include \nvoid main() {\n\tvWorldDirection = transformDirection( position, modelMatrix );\n\t#include \n\t#include \n\tgl_Position.z = gl_Position.w;\n}",depth_frag:"#if DEPTH_PACKING == 3200\n\tuniform float opacity;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( 1.0 );\n\t#if DEPTH_PACKING == 3200\n\t\tdiffuseColor.a = opacity;\n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#if DEPTH_PACKING == 3200\n\t\tgl_FragColor = vec4( vec3( 1.0 - gl_FragCoord.z ), opacity );\n\t#elif DEPTH_PACKING == 3201\n\t\tgl_FragColor = packDepthToRGBA( gl_FragCoord.z );\n\t#endif\n}",
-depth_vert:"#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#ifdef USE_DISPLACEMENTMAP\n\t\t#include \n\t\t#include \n\t\t#include \n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}",
-distanceRGBA_frag:"#define DISTANCE\nuniform vec3 referencePosition;\nuniform float nearDistance;\nuniform float farDistance;\nvarying vec3 vWorldPosition;\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main () {\n\t#include \n\tvec4 diffuseColor = vec4( 1.0 );\n\t#include \n\t#include \n\t#include \n\tfloat dist = length( vWorldPosition - referencePosition );\n\tdist = ( dist - nearDistance ) / ( farDistance - nearDistance );\n\tdist = saturate( dist );\n\tgl_FragColor = packDepthToRGBA( dist );\n}",
-distanceRGBA_vert:"#define DISTANCE\nvarying vec3 vWorldPosition;\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#ifdef USE_DISPLACEMENTMAP\n\t\t#include \n\t\t#include