diff --git a/.editorconfig b/.editorconfig
index 9a3e06f4..dc610a65 100755
--- a/.editorconfig
+++ b/.editorconfig
@@ -1,7 +1,7 @@
root = true
-[{src, translations}/*]
-end_of_line = crlf
+[*]
+end_of_line = lf
insert_final_newline = true
indent_style = space
indent_size = 4
diff --git a/.eslintignore b/.eslintignore
deleted file mode 100644
index d3510226..00000000
--- a/.eslintignore
+++ /dev/null
@@ -1,11 +0,0 @@
-artwork/*
-build/*
-electron/*
-gulp/*
-node_modules/*
-res/*
-res_built/*
-res_raw/*
-tmp_standalone_files/*
-tools/*
-translations/*
diff --git a/.eslintrc.yml b/.eslintrc.yml
deleted file mode 100644
index 60ddb5cd..00000000
--- a/.eslintrc.yml
+++ /dev/null
@@ -1,26 +0,0 @@
-env:
- browser: true
- es6: true
-extends:
- - "eslint:recommended"
- - "plugin:@typescript-eslint/eslint-recommended"
- - "prettier"
-globals:
- Atomics: readonly
- SharedArrayBuffer: readonly
-parser: "@typescript-eslint/parser"
-parserOptions:
- ecmaVersion: 6
- sourceType: "module"
- ecmaFeatures:
- - modules: true
-plugins:
- - "@typescript-eslint"
- - "prettier"
-rules:
- prettier/prettier: error
- no-undef: off
- no-unused-vars: off
- no-unreachable: off
- no-prototype-builtins: off
- linebreak-style: off
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 78a05301..96ed4382 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -10,42 +10,6 @@ on:
- master
jobs:
- setup:
- name: CI
-
- runs-on: ubuntu-latest
-
- steps:
- - name: Install Dependencies
- run: |
- sudo apt-get update
- sudo apt-get install ffmpeg
-
- - name: Setup Node
- uses: actions/setup-node@v2-beta
- with:
- node-version: 16.x
-
- - name: Checkout repo
- uses: actions/checkout@v2
-
- - name: Install Yarn Dependencies
- run: |
- yarn
- cd gulp/
- yarn
- cd ..
- - name: Lint
- run: |
- yarn lint
- - name: TSLint
- run: |
- cd gulp
- yarn gulp translations.fullBuild
- yarn gulp localConfig.findOrCreate
- cd ..
- yarn tslint
-
yaml-lint:
name: yaml-lint
runs-on: ubuntu-latest
diff --git a/.gitignore b/.gitignore
index 0e74d8cd..a72a2050 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,8 +2,6 @@
logs
*.log
npm-debug.log*
-yarn-debug.log*
-yarn-error.log*
lerna-debug.log*
# Diagnostic reports (https://nodejs.org/api/report.html)
@@ -27,15 +25,9 @@ node_modules/
# Optional npm cache directory
.npm
-# Optional eslint cache
-.eslintcache
-
# Optional REPL history
.node_repl_history
-# Yarn Integrity file
-.yarn-integrity
-
# dotenv environment variables file
.env
.env.test
@@ -46,8 +38,6 @@ res_built
gulp/runnable-texturepacker.jar
tmp_standalone_files
-tmp_standalone_files_china
-tmp_standalone_files_wegame
# Local config
config.local.js
@@ -56,9 +46,12 @@ config.local.js
# Editor artifacts
*.*.swp
*.*.swo
-app.vdf
-steamtmp
build_output
-built_vdfs
tmp
+
+src/js/built-temp
+translations/tmp
+gulp/additional_build_files
+
+electron/dist
diff --git a/.gitpod.Dockerfile b/.gitpod.Dockerfile
deleted file mode 100644
index 41956947..00000000
--- a/.gitpod.Dockerfile
+++ /dev/null
@@ -1,4 +0,0 @@
-FROM gitpod/workspace-full
-
-RUN sudo apt-get update \
- && sudo apt install ffmpeg -yq
diff --git a/.gitpod.yml b/.gitpod.yml
deleted file mode 100644
index 18373c95..00000000
--- a/.gitpod.yml
+++ /dev/null
@@ -1,10 +0,0 @@
-image:
- file: .gitpod.Dockerfile
-tasks:
- - init: yarn && gp sync-done boot
- - before: cd gulp
- init: gp sync-await boot && yarn
- command: yarn gulp
-ports:
- - port: 3005
- onOpen: open-preview
diff --git a/.prettierignore b/.prettierignore
new file mode 100644
index 00000000..43d24495
--- /dev/null
+++ b/.prettierignore
@@ -0,0 +1,7 @@
+*.gif
+*.jpg
+*.mp3
+*.png
+*.wav
+*.webm
+*.woff2
diff --git a/.prettierrc b/.prettierrc
new file mode 100644
index 00000000..ec6ce6df
--- /dev/null
+++ b/.prettierrc
@@ -0,0 +1,9 @@
+{
+ "arrowParens": "avoid",
+ "bracketSpacing": true,
+ "printWidth": 110,
+ "quoteProps": "consistent",
+ "semi": true,
+ "singleQuote": false,
+ "trailingComma": "es5"
+}
diff --git a/.prettierrc.yaml b/.prettierrc.yaml
deleted file mode 100644
index 0b5b2dba..00000000
--- a/.prettierrc.yaml
+++ /dev/null
@@ -1,11 +0,0 @@
-# .prettierrc or .prettierrc.yaml
-trailingComma: "es5"
-tabWidth: 4
-semi: true
-singleQuote: false
-printWidth: 110
-useTabs: false
-quoteProps: "consistent"
-bracketSpacing: true
-arrowParens: avoid
-endOfLine: auto
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 6b8b5e97..00000000
--- a/.travis.yml
+++ /dev/null
@@ -1,166 +0,0 @@
-# validate config at https://config.travis-ci.com/explore
-os: linux
-dist: xenial
-language: node_js
-node_js:
- - "12"
-cache: yarn
-
-# platform specific configuration
-jobs:
- # jobs which have to succeed
- include:
- # OS: MAC
- ## -> build darwin
- # - name: "Standalone MacOS on MacOS"
- # os: osx
- # osx_image: xcode11.3
- # before_install:
- # - HOMEBREW_NO_AUTO_UPDATE=1 brew install git-lfs
- # - HOMEBREW_NO_AUTO_UPDATE=1 brew install ffmpeg
- # script:
- # - cd gulp
- # - yarn gulp build.standalone-prod || travis_terminate 1
- # - yarn gulp standalone.prepare
- # - yarn gulp standalone.package.prod.darwin64
- # - cd ..
-
- ## -> build win
- # - name: "Standalone Windows on MacOS"
- # os: osx
- # osx_image: xcode11.3
- # before_install:
- # - HOMEBREW_NO_AUTO_UPDATE=1 brew install git-lfs
- # - HOMEBREW_NO_AUTO_UPDATE=1 brew install ffmpeg
- # - HOMEBREW_NO_AUTO_UPDATE=1 brew cask install wine-stable
- # # prevent Wine popup dialogs about installing additional packages
- # - export WINEDLLOVERRIDES="mscoree,mshtml="
- # - export WINEDEBUG="-all"
- # script:
- # - cd gulp
- # - yarn gulp build.standalone-prod || travis_terminate 1
- # - yarn gulp standalone.prepare
- # - yarn gulp standalone.package.prod.win64
- # - yarn gulp standalone.package.prod.win32
- # - cd ..
-
- ## -> build linux
- # - name: "Standalone Linux on MacOS"
- # os: osx
- # osx_image: xcode11.3
- # before_install:
- # - HOMEBREW_NO_AUTO_UPDATE=1 brew install git-lfs
- # - HOMEBREW_NO_AUTO_UPDATE=1 brew install ffmpeg
- # script:
- # - cd gulp
- # - yarn gulp build.standalone-prod || travis_terminate 1
- # - yarn gulp standalone.prepare
- # - yarn gulp standalone.package.prod.linux64
- # - yarn gulp standalone.package.prod.linux32
- # - cd ..
-
- # OS: LINUX
- ## -> build darwin
- ## not possible
-
- ## -> build win
- # - name: "Standalone Windows on Linux"
- # os: linux
- # addons:
- # apt:
- # packages:
- # - libavformat-dev
- # - libavfilter-dev
- # - libavdevice-dev
- # - ffmpeg
- # - wine
- # script:
- # - cd gulp
- # - yarn gulp build.standalone-prod || travis_terminate 1
- # - yarn gulp standalone.prepare
- # - yarn gulp standalone.package.prod.win64
- # - yarn gulp standalone.package.prod.win32
- # - cd ..
-
- ## -> build linux
- # - name: "Standalone Linux on Linux"
- # os: linux
- # addons:
- # apt:
- # packages:
- # - libavformat-dev
- # - libavfilter-dev
- # - libavdevice-dev
- # - ffmpeg
- # script:
- # - cd gulp
- # - yarn gulp build.standalone-prod || travis_terminate 1
- # - yarn gulp standalone.prepare
- # - yarn gulp standalone.package.prod.linux64
- # - yarn gulp standalone.package.prod.linux32
- # - cd ..
-
- # OS: WINDOWS
- ## -> build darwin
- ## not possible
-
- ## -> build linux
- # - name: "Standalone Linux on Windows"
- # os: windows
- # env: YARN_GPG=no
- # before_install:
- # - choco install git-lfs -y -f || echo "0" # choco fails but git-lfs is still installed
- # - choco install ffmpeg --version=4.2.3
- # - export PATH=/C/ProgramData/chocolatey/lib/ffmpeg/tools/ffmpeg/bin:$PATH
- # - wget https://github.com/moiamond/docker-ffmpeg-base-windowsservercore/raw/master/System32/avicap32.dll -P /C/Windows/System32/
- # - wget https://github.com/moiamond/docker-ffmpeg-base-windowsservercore/raw/master/System32/msvfw32.dll -P /C/Windows/System32/
- # script:
- # - cd gulp
- # - yarn gulp build.standalone-prod || travis_terminate 1
- # - yarn gulp standalone.prepare
- # - yarn gulp standalone.package.prod.linux64
- # - yarn gulp standalone.package.prod.linux32
- # - cd ..
-
- ## -> build win
- - name: "Standalone Windows on Windows"
- os: windows
- env: YARN_GPG=no
- before_install:
- - choco install git-lfs -y -f || echo "0" # choco fails but git-lfs is still installed
- - choco install ffmpeg --version=4.2.3
- - choco install wget
- - export PATH=/C/ProgramData/chocolatey/lib/ffmpeg/tools/ffmpeg/bin:$PATH
- - wget https://github.com/moiamond/docker-ffmpeg-base-windowsservercore/raw/master/System32/avicap32.dll -P /C/Windows/System32/
- - wget https://github.com/moiamond/docker-ffmpeg-base-windowsservercore/raw/master/System32/msvfw32.dll -P /C/Windows/System32/
- script:
- - cd gulp
- - yarn gulp build.standalone-prod || travis_terminate 1
- - yarn gulp standalone.prepare
- - yarn gulp standalone.package.prod.win64
- - yarn gulp standalone.package.prod.win32
- - cd ..
-
- # mark build as finished even if "allow_failures" are still running
- fast_finish: true
-
- # optional jobs which may fail
- #allow_failures:
- # - name: ""
-
-# shared
-install:
- - git lfs install
- - git lfs pull
-
- - yarn
-
- # electron dependencies
- - cd electron
- - yarn
- - cd ..
-
- # gulp dependendencies
- - cd gulp
- - yarn
- - cd ..
diff --git a/.vscode/extensions.json b/.vscode/extensions.json
index 84a7327f..ce27cbd6 100644
--- a/.vscode/extensions.json
+++ b/.vscode/extensions.json
@@ -1,9 +1,3 @@
{
- // See https://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations.
- // Extension identifier format: ${publisher}.${name}. Example: vscode.csharp
-
- // List of extensions which should be recommended for users of this workspace.
- "recommendations": ["esbenp.prettier-vscode"],
- // List of extensions recommended by VS Code that should not be recommended for users of this workspace.
- "unwantedRecommendations": []
+ "recommendations": ["esbenp.prettier-vscode", "EditorConfig.EditorConfig", "dbaeumer.vscode-eslint"]
}
diff --git a/.vscode/settings.json b/.vscode/settings.json
index e47654f3..a23a2942 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -1,5 +1,13 @@
{
"editor.defaultFormatter": "esbenp.prettier-vscode",
"files.trimTrailingWhitespace": true,
- "editor.formatOnSave": true
-}
\ No newline at end of file
+ "editor.formatOnSave": true,
+ "files.exclude": {
+ "**/.git": true,
+ "**/.DS_Store": true,
+ "**/Thumbs.db": true,
+ "node_modules/": true,
+ "build/": true,
+ "build_output/": true
+ }
+}
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
deleted file mode 100644
index 6055ac1c..00000000
--- a/CONTRIBUTING.md
+++ /dev/null
@@ -1,33 +0,0 @@
-Contributor license agreement (CLA)
-
-1. Preamble
- Thank you for your interest in shapez by tobspr IT Solutions (the "Company"). In order to clarify the intellectual property license granted with Contributions from any person or entity, the Company must have a Contributor License Agreement ("CLA") on file that has been signed by each Contributor, indicating agreement to the license terms below. This license is for your protection as a Contributor as well as the protection of the Company and its users; it does not change your rights to use your own Contributions for any other purpose.
-
-2. General
- You accept and agree to the following terms and conditions for Your present and future Contributions submitted to the Company. In return, the Company shall not use Your Contributions in a way that is contrary to the public benefit or inconsistent with its bylaws in effect at the time of the Contribution. Except for the license granted herein to the Company and recipients of software distributed by the Company, You reserve all right, title, and interest in and to Your Contributions.
- You represent that you have the full authority to enter into this agreement.
-
-3. Definitions
- "You" (or "Your") "You" (or "Your") shall mean the copyright owner or legal entity authorized by the copyright owner that is making this Agreement with the Company. For legal entities, the entity making a Contribution and all other entities that control, are controlled by, or are under common control with that entity are considered to be a single Contributor. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
-
- "Contribution" "Contribution" shall mean any original work of authorship, including any modifications or additions to an existing work, that is intentionally submitted by You to the Company for inclusion in, or documentation of, any of the products owned or managed by the Company (the "Work"). For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Company or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Company for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by You as "Not a Contribution."
-
-4. Grant of Copyright License
- Subject to the terms and conditions of this Agreement, You hereby grant to the Company and to recipients of software distributed by the Company a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, sublicense, and distribute Your Contributions and such derivative works.
- You agree that your changes/additions are incorporated into the source code under a GPL-3 license.
- You agree that the Company is free to use its code without a GPL-3 license as closed source in any context, including for commercial purposes, without any license whatsoever
-
-5. Grant of Patent License
- Subject to the terms and conditions of this Agreement, You hereby grant to the Company and to recipients of software distributed by the Company a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by You that are necessarily infringed by Your Contribution(s) alone or by combination of Your Contribution(s) with the Work to which such Contribution(s) was submitted. If any entity institutes patent litigation against You or any other entity (including a cross-claim or counterclaim in a lawsuit) alleging that your Contribution, or the Work to which you have contributed, constitutes direct or contributory patent infringement, then any patent licenses granted to that entity under this Agreement for that Contribution or Work shall terminate as of the date such litigation is filed.
-
-6. Liability / Obligations
- You represent that you are legally entitled to grant the above license. If your employer(s) has rights to intellectual property that you create that includes your Contributions, you represent that you have received permission to make Contributions on behalf of that employer, that your employer has waived such rights for your Contributions to the Company, or that your employer has executed a separate Corporate CLA with the Company.
- You represent that each of Your Contributions is Your original creation (see section 7 for submissions on behalf of others). You represent that Your Contribution submissions include complete details of any third-party license or other restriction (including, but not limited to, related patents and trademarks) of which you are personally aware and which are associated with any part of Your Contributions.
- If you make changes or additions to the code, you assume full liability for this and assure that the changes/additions do not infringe the rights of third parties (e.g. copyrights).
- You are not expected to provide support for Your Contributions, except to the extent You desire to provide support. You may provide support for free, for a fee, or not at all. Unless required by applicable law or agreed to in writing, You provide Your Contributions on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON- INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE.
- Should You wish to submit work that is not Your original creation, You may submit it to the Company separately from any Contribution, identifying the complete details of its source and of any license or other restriction (including, but not limited to, related patents, trademarks, and license agreements) of which you are personally aware, and conspicuously marking the work as "Submitted on behalf of a third-party: [named here]".
- You agree to notify the Company of any facts or circumstances of which you become aware that would make these representations inaccurate in any respect.
-
-7. Final provisions
- The law of the Federal Republic of Germany applies to this agreement.
- The contract remains binding in its remaining parts even if individual points are legally ineffective. In place of the ineffective points, the statutory provisions, if any, apply. Insofar as this would represent unreasonable hardship for one of the contracting parties, the contract as a whole will become ineffective.
diff --git a/CONTRIBUTORS b/CONTRIBUTORS
deleted file mode 100644
index d6233b1c..00000000
--- a/CONTRIBUTORS
+++ /dev/null
@@ -1,5 +0,0 @@
-dengr1065
-- Contributed various fixes to the dark mode
-
-thelockj
-- Contributed the design and initial implementation for the storage building
\ No newline at end of file
diff --git a/Dockerfile b/Dockerfile
index 0fc1601a..453cb893 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -7,7 +7,7 @@ WORKDIR /shapez.io
RUN apt-get update && apt-get install -y --no-install-recommends \
ffmpeg default-jre \
&& apt-get clean \
- && rm -rf /var/lib/apt/lists/*
+ && rm -rf /var/lib/apt/lists/*
COPY package.json yarn.lock ./
RUN yarn
@@ -20,7 +20,6 @@ WORKDIR /shapez.io
COPY res ./res
COPY src/html ./src/html
COPY src/css ./src/css
-COPY version ./version
COPY sync-translations.js ./
COPY translations ./translations
COPY src/js ./src/js
diff --git a/README.md b/README.md
index 0c34ed22..e5109242 100644
--- a/README.md
+++ b/README.md
@@ -1,95 +1,84 @@
-## NEW: Shapez 2!
+# shapez Community Edition
-We are currently working on a successor to shapez, with 3D Graphics, Exploration, Layers, Mass transport, New Shape Mechanics, Research and a lot more! Be sure to check it out:
+**shapez Community Edition** (abbreviated as **CE**) is a community-maintained version of [shapez](https://store.steampowered.com/app/1318690/shapez/)!
-
-
-
+CE was created as the tobspr Games team moved away from shapez to work full-time on the upcoming [Shapez 2](https://store.steampowered.com/app/2162800/shapez_2/).
+CE aims to:
-
+- Continue the development of shapez as guided by the community.
+- Allow contributors to continue submitting new features and improvements to the game.
+- Provide an experimental and forgiving environment for faster development.
-# shapez
+> [!IMPORTANT]
+> CE is different from the official game published on Steam and other platforms.
+> CE was forked off of the official shapez, which has [its own repository](https://github.com/tobspr-games/shapez.io).
+> No plans exist to merge the two versions of shapez.
-
-
-
-
-
-This is the source code for shapez, an open source base building game inspired by Factorio.
-Your goal is to produce shapes by cutting, rotating, merging and painting parts of shapes.
-
-- [Play on Steam](https://get.shapez.io/ghr)
-- [Online Demo](https://shapez.io)
-- [Official Discord](https://discord.com/invite/HN7EVzV) <- _Highly recommended to join!_
-- [Trello Board & Roadmap](https://trello.com/b/ISQncpJP/shapezio)
-
-## Reporting issues, suggestions, feedback, bugs
-
-1. Ask in `#bugs` / `#feedback` / `#questions` on the [Official Discord](https://discord.com/invite/HN7EVzV) if you are not entirely sure if it's a bug
-2. Check out the trello board: https://trello.com/b/ISQncpJP/shapezio
-3. See if it's already there - If so, vote for it, done. I will see it. (You have to be signed in on trello)
-4. If not, check if it's already reported here: https://github.com/tobspr-games/shapez.io/issues
-5. If not, file a new issue here: https://github.com/tobspr-games/shapez.io/issues/new
-6. I will then have a look (This can take days or weeks) and convert it to trello, and comment with the link. You can then vote there ;)
-
-## Building
-
-- Make sure `ffmpeg` is on your path
-- Install Node.js 16 and Yarn
-- Install Java (required for texture packer)
-- Run `yarn` in the root folder
-- `cd` into `gulp` folder
-- Run `yarn` and then `yarn gulp` - it should now open in your browser
-
-**Notice**: This will produce a debug build with several debugging flags enabled. If you want to disable them, modify [`src/js/core/config.js`](src/js/core/config.js).
-
-## Creating Mods
-
-Mods can be found [here](https://shapez.mod.io). The documentation for creating mods can be found [here](mod_examples/), including a bunch of sample mods.
-
-## Build Online with one-click setup
-
-You can use [Gitpod](https://www.gitpod.io/) (an Online Open Source VS Code-like IDE which is free for Open Source) for working on issues and making PRs to this project. With a single click it will start a workspace and automatically:
-
-- clone the `shapez.io` repo.
-- install all of the dependencies.
-- start `gulp` in `gulp/` directory.
-
-[](https://gitpod.io/#https://github.com/tobspr-games/shapez.io)
-
-## Helping translate
-
-Please checkout the [Translations readme](translations/).
+As of now, CE must be built from source and supports only a standalone build,
+with no plans for re-supporting a web version.
+In the future, builds of CE may provided for owners of the full version of shapez.
## Contributing
-I will only accept pull requests which add a benefit to a large portion of the player base. If the feature is useful but only to a fraction of players, or is controversial, I recommend making a mod instead.
+We communicate on the [official shapez Discord server](https://discord.com/invite/HN7EVzV).
+For historical reasons, we have communicated in a private channel,
+but we are moving to the public `#contributing` channel.
+If you would like to contribute to CE, feel free to share your ideas, plans, etc. there.
-If you want to add a new feature or in generally contribute I recommend to get in touch on Discord in advance, which largely increases the chance of the PR to get merged:
+In our current workflow, we (the "collaborators" of the repository) create internal branches and corresponding pull requests to work on a feature, refactor, etc.
+We discuss changes in the Discord, and when 2 collaborators (including the PR creator) approve of a change, it can be merged.
+See our existing [pull requests](https://github.com/tobspr-games/shapez-community-edition/pulls?q=) for examples.
-
-
-
+If you are not a collaborator and want to submit a change,
+you can fork our repo and make a pull request.
+Note that because of plans to overhaul many parts of the game,
+unless you are improving translations, you should probably communicate with us on Discord!
+
+> [!TIP]
+> Be aware that [pull requests to the official shapez repository](https://github.com/tobspr-games/shapez.io/pulls) are unlikely to get merged in the near future. Instead, submit them to CE!
+> In fact, because the game is licensed under the [GNU GPL v3.0](https://www.gnu.org/licenses/gpl-3.0.html),
+> existing pull requests can be resubmitted to CE even if you aren't the author! **This is not legal advice.**
### Code
-The game is based on a custom engine which itself is based on the YORG.io 3 game engine (Actually it shares almost the same core).
+The game uses a custom engine originally based on the YORG.io 3 game engine.
The code within the engine is relatively clean with some code for the actual game on top being hacky.
-This project is based on ES5 (If I would develop it again, I would definitely use TypeScript). Some ES2015 features are used but most of them are too slow, especially when polyfilled. For example, `Array.prototype.forEach` is only used within non-critical loops since its slower than a plain for loop.
+We are in the process of migrating to TypeScript and JSX/TSX.
+New changes should be implemented in TypeScript if possible,
+but because we are planning on overhauling many parts of the game,
+there is no need to convert existing code to TypeScript.
-### Assets
+This project is fine with using cutting-edge and bleeding-edge features
+and does not intend to provide compatibility for older clients.
-You can find most assets here .
+## Building
-All assets will be automatically rebuilt into the atlas once changed (Thanks to dengr1065!)
+### Prerequisites
-
+- [Node.js](https://nodejs.org)
+- [ffmpeg](https://www.ffmpeg.org/download.html) for audio transcoding
+- [Java](https://www.oracle.com/java/technologies/downloads/) (or [OpenJDK](https://openjdk.org/)) to run the texture packer
-
+### Development
-## Check out our other games!
+- Run `npm i` in the root folder and in `electron/`.
+- Run `npm run gulp` in the root folder to build and serve files.
+ If a new browser tab opens, ignore it.
+- Open a new terminal and run `npm start` in `electron/` to open an Electron window.
+ - Use `npm start -- --dev` to run in development mode.
+ - Tip: If you open the Electron window too early, you can reload it when focused on DevTools.
-
-
-
+### Release
+
+- Run `npm i` in the root folder and in `electron/`.
+- In the root folder, run `npm run package-$PLATFORM-$ARCH` where:
+ - `$PLATFORM` is `win32`, `linux` or `darwin` depending on your system.
+ - `$ARCH` is the target system architecture (`x64` or `arm64`)
+- The build will be found under `build_output/standalone` as `shapez-...`.
+
+## Credits
+
+Thanks to [tobspr](https://tobspr.io) for creating this project!
+
+[ ](https://tobspr.io)
diff --git a/electron/.gitignore b/electron/.gitignore
deleted file mode 100644
index 0cdb30f4..00000000
--- a/electron/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-mods/*.js
\ No newline at end of file
diff --git a/electron/electron.code-workspace b/electron/electron.code-workspace
deleted file mode 100644
index fc9ab864..00000000
--- a/electron/electron.code-workspace
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "folders": [
- {
- "path": "."
- }
- ],
- "settings": {
- "files.exclude": {
- "**/node_modules": true,
- "**/typedefs_gen": true
- }
- }
-}
\ No newline at end of file
diff --git a/electron/index.js b/electron/index.js
deleted file mode 100644
index 31b4bca2..00000000
--- a/electron/index.js
+++ /dev/null
@@ -1,389 +0,0 @@
-/* eslint-disable quotes,no-undef */
-
-const { app, BrowserWindow, Menu, MenuItem, ipcMain, shell, dialog, session } = require("electron");
-const path = require("path");
-const url = require("url");
-const fs = require("fs");
-const steam = require("./steam");
-const asyncLock = require("async-lock");
-const windowStateKeeper = require("electron-window-state");
-
-// Disable hardware key handling, i.e. being able to pause/resume the game music
-// with hardware keys
-app.commandLine.appendSwitch("disable-features", "HardwareMediaKeyHandling");
-
-const isDev = app.commandLine.hasSwitch("dev");
-const isLocal = app.commandLine.hasSwitch("local");
-const safeMode = app.commandLine.hasSwitch("safe-mode");
-const externalMod = app.commandLine.getSwitchValue("load-mod");
-
-const roamingFolder =
- process.env.APPDATA ||
- (process.platform == "darwin"
- ? process.env.HOME + "/Library/Preferences"
- : process.env.HOME + "/.local/share");
-
-let storePath = path.join(roamingFolder, "shapez.io", "saves");
-let modsPath = path.join(roamingFolder, "shapez.io", "mods");
-
-if (!fs.existsSync(storePath)) {
- // No try-catch by design
- fs.mkdirSync(storePath, { recursive: true });
-}
-
-if (!fs.existsSync(modsPath)) {
- fs.mkdirSync(modsPath, { recursive: true });
-}
-
-/** @type {BrowserWindow} */
-let win = null;
-let menu = null;
-
-function createWindow() {
- let faviconExtension = ".png";
- if (process.platform === "win32") {
- faviconExtension = ".ico";
- }
-
- const mainWindowState = windowStateKeeper({
- defaultWidth: 1000,
- defaultHeight: 800,
- });
-
- win = new BrowserWindow({
- x: mainWindowState.x,
- y: mainWindowState.y,
- width: mainWindowState.width,
- height: mainWindowState.height,
- show: false,
- backgroundColor: "#222428",
- useContentSize: false,
- minWidth: 800,
- minHeight: 600,
- title: "shapez",
- transparent: false,
- icon: path.join(__dirname, "favicon" + faviconExtension),
- // fullscreen: true,
- autoHideMenuBar: !isDev,
- webPreferences: {
- nodeIntegration: false,
- nodeIntegrationInWorker: false,
- nodeIntegrationInSubFrames: false,
- contextIsolation: true,
- enableRemoteModule: false,
- disableBlinkFeatures: "Auxclick",
-
- webSecurity: true,
- sandbox: true,
- preload: path.join(__dirname, "preload.js"),
- experimentalFeatures: false,
- },
- allowRunningInsecureContent: false,
- });
-
- mainWindowState.manage(win);
-
- if (isLocal) {
- win.loadURL("http://localhost:3005");
- } else {
- win.loadURL(
- url.format({
- pathname: path.join(__dirname, "index.html"),
- protocol: "file:",
- slashes: true,
- })
- );
- }
- win.webContents.session.clearCache();
- win.webContents.session.clearStorageData();
-
- ////// SECURITY
-
- // Disable permission requests
- win.webContents.session.setPermissionRequestHandler((webContents, permission, callback) => {
- callback(false);
- });
- session.fromPartition("default").setPermissionRequestHandler((webContents, permission, callback) => {
- callback(false);
- });
-
- app.on("web-contents-created", (event, contents) => {
- // Disable vewbiew
- contents.on("will-attach-webview", (event, webPreferences, params) => {
- event.preventDefault();
- });
- // Disable navigation
- contents.on("will-navigate", (event, navigationUrl) => {
- event.preventDefault();
- });
- });
-
- win.webContents.on("will-redirect", (contentsEvent, navigationUrl) => {
- // Log and prevent the app from redirecting to a new page
- console.error(
- `The application tried to redirect to the following address: '${navigationUrl}'. This attempt was blocked.`
- );
- contentsEvent.preventDefault();
- });
-
- // Filter loading any module via remote;
- // you shouldn't be using remote at all, though
- // https://electronjs.org/docs/tutorial/security#16-filter-the-remote-module
- app.on("remote-require", (event, webContents, moduleName) => {
- event.preventDefault();
- });
-
- // built-ins are modules such as "app"
- app.on("remote-get-builtin", (event, webContents, moduleName) => {
- event.preventDefault();
- });
-
- app.on("remote-get-global", (event, webContents, globalName) => {
- event.preventDefault();
- });
-
- app.on("remote-get-current-window", (event, webContents) => {
- event.preventDefault();
- });
-
- app.on("remote-get-current-web-contents", (event, webContents) => {
- event.preventDefault();
- });
-
- //// END SECURITY
-
- win.webContents.on("new-window", (event, pth) => {
- event.preventDefault();
-
- if (pth.startsWith("https://") || pth.startsWith("steam://")) {
- shell.openExternal(pth);
- }
- });
-
- win.on("closed", () => {
- console.log("Window closed");
- win = null;
- });
-
- if (isDev) {
- menu = new Menu();
-
- win.webContents.toggleDevTools();
-
- const mainItem = new MenuItem({
- label: "Toggle Dev Tools",
- click: () => win.webContents.toggleDevTools(),
- accelerator: "F12",
- });
- menu.append(mainItem);
-
- const reloadItem = new MenuItem({
- label: "Reload",
- click: () => win.reload(),
- accelerator: "F5",
- });
- menu.append(reloadItem);
-
- const fullscreenItem = new MenuItem({
- label: "Fullscreen",
- click: () => win.setFullScreen(!win.isFullScreen()),
- accelerator: "F11",
- });
- menu.append(fullscreenItem);
-
- const mainMenu = new Menu();
- mainMenu.append(
- new MenuItem({
- label: "shapez.io",
- submenu: menu,
- })
- );
-
- Menu.setApplicationMenu(mainMenu);
- } else {
- Menu.setApplicationMenu(null);
- }
-
- win.once("ready-to-show", () => {
- win.show();
- win.focus();
- });
-}
-
-if (!app.requestSingleInstanceLock()) {
- app.exit(0);
-} else {
- app.on("second-instance", () => {
- // Someone tried to run a second instance, we should focus
- if (win) {
- if (win.isMinimized()) {
- win.restore();
- }
- win.focus();
- }
- });
-}
-
-app.on("ready", createWindow);
-
-app.on("window-all-closed", () => {
- console.log("All windows closed");
- app.quit();
-});
-
-ipcMain.on("set-fullscreen", (event, flag) => {
- win.setFullScreen(flag);
-});
-
-ipcMain.on("exit-app", () => {
- win.close();
- app.quit();
-});
-
-let renameCounter = 1;
-
-const fileLock = new asyncLock({
- timeout: 30000,
- maxPending: 1000,
-});
-
-function niceFileName(filename) {
- return filename.replace(storePath, "@");
-}
-
-async function writeFileSafe(filename, contents) {
- ++renameCounter;
- const prefix = "[ " + renameCounter + ":" + niceFileName(filename) + " ] ";
- const transactionId = String(new Date().getTime()) + "." + renameCounter;
-
- if (fileLock.isBusy()) {
- console.warn(prefix, "Concurrent write process on", filename);
- }
-
- fileLock.acquire(filename, async () => {
- console.log(prefix, "Starting write on", niceFileName(filename), "in transaction", transactionId);
-
- if (!fs.existsSync(filename)) {
- // this one is easy
- console.log(prefix, "Writing file instantly because it does not exist:", niceFileName(filename));
- await fs.promises.writeFile(filename, contents, "utf8");
- return;
- }
-
- // first, write a temporary file (.tmp-XXX)
- const tempName = filename + ".tmp-" + transactionId;
- console.log(prefix, "Writing temporary file", niceFileName(tempName));
- await fs.promises.writeFile(tempName, contents, "utf8");
-
- // now, rename the original file to (.backup-XXX)
- const oldTemporaryName = filename + ".backup-" + transactionId;
- console.log(
- prefix,
- "Renaming old file",
- niceFileName(filename),
- "to",
- niceFileName(oldTemporaryName)
- );
- await fs.promises.rename(filename, oldTemporaryName);
-
- // now, rename the temporary file (.tmp-XXX) to the target
- console.log(
- prefix,
- "Renaming the temporary file",
- niceFileName(tempName),
- "to the original",
- niceFileName(filename)
- );
- await fs.promises.rename(tempName, filename);
-
- // we are done now, try to create a backup, but don't fail if the backup fails
- try {
- // check if there is an old backup file
- const backupFileName = filename + ".backup";
- if (fs.existsSync(backupFileName)) {
- console.log(prefix, "Deleting old backup file", niceFileName(backupFileName));
- // delete the old backup
- await fs.promises.unlink(backupFileName);
- }
-
- // rename the old file to the new backup file
- console.log(prefix, "Moving", niceFileName(oldTemporaryName), "to the backup file location");
- await fs.promises.rename(oldTemporaryName, backupFileName);
- } catch (ex) {
- console.error(prefix, "Failed to switch backup files:", ex);
- }
- });
-}
-
-ipcMain.handle("fs-job", async (event, job) => {
- const filenameSafe = job.filename.replace(/[^a-z\.\-_0-9]/gi, "_");
- const fname = path.join(storePath, filenameSafe);
- switch (job.type) {
- case "read": {
- if (!fs.existsSync(fname)) {
- // Special FILE_NOT_FOUND error code
- return { error: "file_not_found" };
- }
- return await fs.promises.readFile(fname, "utf8");
- }
- case "write": {
- await writeFileSafe(fname, job.contents);
- return job.contents;
- }
-
- case "delete": {
- await fs.promises.unlink(fname);
- return;
- }
-
- default:
- throw new Error("Unknown fs job: " + job.type);
- }
-});
-
-ipcMain.handle("open-mods-folder", async () => {
- shell.openPath(modsPath);
-});
-
-console.log("Loading mods ...");
-
-function loadMods() {
- if (safeMode) {
- console.log("Safe Mode enabled for mods, skipping mod search");
- }
- console.log("Loading mods from", modsPath);
- let modFiles = safeMode
- ? []
- : fs
- .readdirSync(modsPath)
- .filter(filename => filename.endsWith(".js"))
- .map(filename => path.join(modsPath, filename));
-
- if (externalMod) {
- console.log("Adding external mod source:", externalMod);
- const externalModPaths = externalMod.split(",");
- modFiles = modFiles.concat(externalModPaths);
- }
-
- return modFiles.map(filename => fs.readFileSync(filename, "utf8"));
-}
-
-let mods = [];
-try {
- mods = loadMods();
- console.log("Loaded", mods.length, "mods");
-} catch (ex) {
- console.error("Failed to load mods");
- dialog.showErrorBox("Failed to load mods:", ex);
-}
-
-ipcMain.handle("get-mods", async () => {
- return mods;
-});
-
-steam.init(isDev);
-
-// Only allow achievements and puzzle DLC if no mods are loaded
-if (mods.length === 0) {
- steam.listen();
-}
diff --git a/electron/mods/README.txt b/electron/mods/README.txt
deleted file mode 100644
index 666cc18f..00000000
--- a/electron/mods/README.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-Here you can place mods. Every mod should be a single file ending with ".js".
-
---- WARNING ---
-Mods can potentially access to your filesystem.
-Please only install mods from trusted sources and developers.
---- WARNING ---
diff --git a/electron/package-lock.json b/electron/package-lock.json
new file mode 100644
index 00000000..0ddfd19d
--- /dev/null
+++ b/electron/package-lock.json
@@ -0,0 +1,935 @@
+{
+ "name": "electron",
+ "version": "1.0.0",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "electron",
+ "version": "1.0.0",
+ "license": "MIT",
+ "dependencies": {
+ "chokidar": "^4.0.3",
+ "semver": "^7.7.1",
+ "zod": "^3.24.2"
+ },
+ "devDependencies": {
+ "@types/semver": "^7.7.0",
+ "electron": "^37.2.3",
+ "typescript": "^5.8.2"
+ }
+ },
+ "node_modules/@electron/get": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/@electron/get/-/get-2.0.3.tgz",
+ "integrity": "sha512-Qkzpg2s9GnVV2I2BjRksUi43U5e6+zaQMcjoJy0C+C5oxaKl+fmckGDQFtRpZpZV0NQekuZZ+tGz7EA9TVnQtQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^4.1.1",
+ "env-paths": "^2.2.0",
+ "fs-extra": "^8.1.0",
+ "got": "^11.8.5",
+ "progress": "^2.0.3",
+ "semver": "^6.2.0",
+ "sumchecker": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "optionalDependencies": {
+ "global-agent": "^3.0.0"
+ }
+ },
+ "node_modules/@electron/get/node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/@sindresorhus/is": {
+ "version": "4.6.0",
+ "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz",
+ "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sindresorhus/is?sponsor=1"
+ }
+ },
+ "node_modules/@szmarczak/http-timer": {
+ "version": "4.0.6",
+ "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz",
+ "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "defer-to-connect": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@types/cacheable-request": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz",
+ "integrity": "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/http-cache-semantics": "*",
+ "@types/keyv": "^3.1.4",
+ "@types/node": "*",
+ "@types/responselike": "^1.0.0"
+ }
+ },
+ "node_modules/@types/http-cache-semantics": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz",
+ "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/keyv": {
+ "version": "3.1.4",
+ "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz",
+ "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/node": {
+ "version": "22.16.4",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-22.16.4.tgz",
+ "integrity": "sha512-PYRhNtZdm2wH/NT2k/oAJ6/f2VD2N2Dag0lGlx2vWgMSJXGNmlce5MiTQzoWAiIJtso30mjnfQCOKVH+kAQC/g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "undici-types": "~6.21.0"
+ }
+ },
+ "node_modules/@types/responselike": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.3.tgz",
+ "integrity": "sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/semver": {
+ "version": "7.7.0",
+ "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.7.0.tgz",
+ "integrity": "sha512-k107IF4+Xr7UHjwDc7Cfd6PRQfbdkiRabXGRjo07b4WyPahFBZCZ1sE+BNxYIJPPg73UkfOsVOLwqVc/6ETrIA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/yauzl": {
+ "version": "2.10.3",
+ "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz",
+ "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/boolean": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz",
+ "integrity": "sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==",
+ "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.",
+ "dev": true,
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/buffer-crc32": {
+ "version": "0.2.13",
+ "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
+ "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/cacheable-lookup": {
+ "version": "5.0.4",
+ "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz",
+ "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10.6.0"
+ }
+ },
+ "node_modules/cacheable-request": {
+ "version": "7.0.4",
+ "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.4.tgz",
+ "integrity": "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "clone-response": "^1.0.2",
+ "get-stream": "^5.1.0",
+ "http-cache-semantics": "^4.0.0",
+ "keyv": "^4.0.0",
+ "lowercase-keys": "^2.0.0",
+ "normalize-url": "^6.0.1",
+ "responselike": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/chokidar": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz",
+ "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==",
+ "license": "MIT",
+ "dependencies": {
+ "readdirp": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 14.16.0"
+ },
+ "funding": {
+ "url": "https://paulmillr.com/funding/"
+ }
+ },
+ "node_modules/clone-response": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz",
+ "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "mimic-response": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/debug": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
+ "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/decompress-response": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz",
+ "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "mimic-response": "^3.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/decompress-response/node_modules/mimic-response": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz",
+ "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/defer-to-connect": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz",
+ "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/define-data-property": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
+ "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "es-define-property": "^1.0.0",
+ "es-errors": "^1.3.0",
+ "gopd": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/define-properties": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz",
+ "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "define-data-property": "^1.0.1",
+ "has-property-descriptors": "^1.0.0",
+ "object-keys": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/detect-node": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz",
+ "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/electron": {
+ "version": "37.2.3",
+ "resolved": "https://registry.npmjs.org/electron/-/electron-37.2.3.tgz",
+ "integrity": "sha512-JRKKn8cRDXDfkC+oWISbYs+c+L6RA776JM0NiB9bn2yV8H/LnBUlVPzKKfsXgrUIokN4YcbCw694vfAdEJwtGw==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "dependencies": {
+ "@electron/get": "^2.0.0",
+ "@types/node": "^22.7.7",
+ "extract-zip": "^2.0.1"
+ },
+ "bin": {
+ "electron": "cli.js"
+ },
+ "engines": {
+ "node": ">= 12.20.55"
+ }
+ },
+ "node_modules/end-of-stream": {
+ "version": "1.4.4",
+ "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
+ "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "once": "^1.4.0"
+ }
+ },
+ "node_modules/env-paths": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz",
+ "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/es-define-property": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
+ "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-errors": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
+ "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es6-error": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz",
+ "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/escape-string-regexp": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/extract-zip": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz",
+ "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "debug": "^4.1.1",
+ "get-stream": "^5.1.0",
+ "yauzl": "^2.10.0"
+ },
+ "bin": {
+ "extract-zip": "cli.js"
+ },
+ "engines": {
+ "node": ">= 10.17.0"
+ },
+ "optionalDependencies": {
+ "@types/yauzl": "^2.9.1"
+ }
+ },
+ "node_modules/fd-slicer": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
+ "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "pend": "~1.2.0"
+ }
+ },
+ "node_modules/fs-extra": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
+ "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^4.0.0",
+ "universalify": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=6 <7 || >=8"
+ }
+ },
+ "node_modules/get-stream": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
+ "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "pump": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/global-agent": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/global-agent/-/global-agent-3.0.0.tgz",
+ "integrity": "sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "optional": true,
+ "dependencies": {
+ "boolean": "^3.0.1",
+ "es6-error": "^4.1.1",
+ "matcher": "^3.0.0",
+ "roarr": "^2.15.3",
+ "semver": "^7.3.2",
+ "serialize-error": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=10.0"
+ }
+ },
+ "node_modules/globalthis": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz",
+ "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "define-properties": "^1.2.1",
+ "gopd": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/gopd": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
+ "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/got": {
+ "version": "11.8.6",
+ "resolved": "https://registry.npmjs.org/got/-/got-11.8.6.tgz",
+ "integrity": "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@sindresorhus/is": "^4.0.0",
+ "@szmarczak/http-timer": "^4.0.5",
+ "@types/cacheable-request": "^6.0.1",
+ "@types/responselike": "^1.0.0",
+ "cacheable-lookup": "^5.0.3",
+ "cacheable-request": "^7.0.2",
+ "decompress-response": "^6.0.0",
+ "http2-wrapper": "^1.0.0-beta.5.2",
+ "lowercase-keys": "^2.0.0",
+ "p-cancelable": "^2.0.0",
+ "responselike": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10.19.0"
+ },
+ "funding": {
+ "url": "https://github.com/sindresorhus/got?sponsor=1"
+ }
+ },
+ "node_modules/graceful-fs": {
+ "version": "4.2.11",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
+ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/has-property-descriptors": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
+ "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "es-define-property": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/http-cache-semantics": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz",
+ "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==",
+ "dev": true,
+ "license": "BSD-2-Clause"
+ },
+ "node_modules/http2-wrapper": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz",
+ "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "quick-lru": "^5.1.1",
+ "resolve-alpn": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=10.19.0"
+ }
+ },
+ "node_modules/json-buffer": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
+ "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/json-stringify-safe": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
+ "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==",
+ "dev": true,
+ "license": "ISC",
+ "optional": true
+ },
+ "node_modules/jsonfile": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
+ "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==",
+ "dev": true,
+ "license": "MIT",
+ "optionalDependencies": {
+ "graceful-fs": "^4.1.6"
+ }
+ },
+ "node_modules/keyv": {
+ "version": "4.5.4",
+ "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
+ "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "json-buffer": "3.0.1"
+ }
+ },
+ "node_modules/lowercase-keys": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz",
+ "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/matcher": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz",
+ "integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "escape-string-regexp": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/mimic-response": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz",
+ "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/normalize-url": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz",
+ "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/object-keys": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
+ "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "wrappy": "1"
+ }
+ },
+ "node_modules/p-cancelable": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz",
+ "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/pend": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
+ "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/progress": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
+ "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/pump": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz",
+ "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "end-of-stream": "^1.1.0",
+ "once": "^1.3.1"
+ }
+ },
+ "node_modules/quick-lru": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz",
+ "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/readdirp": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz",
+ "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 14.18.0"
+ },
+ "funding": {
+ "type": "individual",
+ "url": "https://paulmillr.com/funding/"
+ }
+ },
+ "node_modules/resolve-alpn": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz",
+ "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/responselike": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz",
+ "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "lowercase-keys": "^2.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/roarr": {
+ "version": "2.15.4",
+ "resolved": "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz",
+ "integrity": "sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "optional": true,
+ "dependencies": {
+ "boolean": "^3.0.1",
+ "detect-node": "^2.0.4",
+ "globalthis": "^1.0.1",
+ "json-stringify-safe": "^5.0.1",
+ "semver-compare": "^1.0.0",
+ "sprintf-js": "^1.1.2"
+ },
+ "engines": {
+ "node": ">=8.0"
+ }
+ },
+ "node_modules/semver": {
+ "version": "7.7.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz",
+ "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==",
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/semver-compare": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz",
+ "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/serialize-error": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz",
+ "integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "type-fest": "^0.13.1"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/sprintf-js": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz",
+ "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "optional": true
+ },
+ "node_modules/sumchecker": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-3.0.1.tgz",
+ "integrity": "sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "debug": "^4.1.0"
+ },
+ "engines": {
+ "node": ">= 8.0"
+ }
+ },
+ "node_modules/type-fest": {
+ "version": "0.13.1",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz",
+ "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==",
+ "dev": true,
+ "license": "(MIT OR CC0-1.0)",
+ "optional": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/typescript": {
+ "version": "5.8.3",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz",
+ "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "bin": {
+ "tsc": "bin/tsc",
+ "tsserver": "bin/tsserver"
+ },
+ "engines": {
+ "node": ">=14.17"
+ }
+ },
+ "node_modules/undici-types": {
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
+ "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/universalify": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
+ "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4.0.0"
+ }
+ },
+ "node_modules/wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/yauzl": {
+ "version": "2.10.0",
+ "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz",
+ "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "buffer-crc32": "~0.2.3",
+ "fd-slicer": "~1.1.0"
+ }
+ },
+ "node_modules/zod": {
+ "version": "3.24.2",
+ "resolved": "https://registry.npmjs.org/zod/-/zod-3.24.2.tgz",
+ "integrity": "sha512-lY7CDW43ECgW9u1TcT3IoXHflywfVqDYze4waEz812jR/bZ8FHDsl7pFQoSZTz5N+2NqRXs8GBwnAwo3ZNxqhQ==",
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/colinhacks"
+ }
+ }
+ }
+}
diff --git a/electron/package.json b/electron/package.json
index 4ae171f8..5c17a55d 100644
--- a/electron/package.json
+++ b/electron/package.json
@@ -1,21 +1,21 @@
-{
- "name": "electron",
- "version": "1.0.0",
- "main": "index.js",
- "license": "MIT",
- "private": true,
- "scripts": {
- "startDev": "electron --disable-direct-composition --in-process-gpu . --dev --local",
- "startDevGpu": "electron --enable-gpu-rasterization --enable-accelerated-2d-canvas --num-raster-threads=8 --enable-zero-copy . --dev --local",
- "start": "electron --disable-direct-composition --in-process-gpu ."
- },
- "devDependencies": {},
- "optionalDependencies": {
- "shapez.io-private-artifacts": "github:tobspr/shapez.io-private-artifacts#abi-v99"
- },
- "dependencies": {
- "async-lock": "^1.2.8",
- "electron": "16.2.8",
- "electron-window-state": "^5.0.3"
- }
-}
+{
+ "name": "electron",
+ "version": "1.0.0",
+ "license": "MIT",
+ "type": "module",
+ "main": "dist/index.js",
+ "private": true,
+ "scripts": {
+ "start": "tsc && electron ."
+ },
+ "dependencies": {
+ "chokidar": "^4.0.3",
+ "semver": "^7.7.1",
+ "zod": "^3.24.2"
+ },
+ "devDependencies": {
+ "@types/semver": "^7.7.0",
+ "electron": "^37.2.3",
+ "typescript": "^5.8.2"
+ }
+}
diff --git a/electron/preload.js b/electron/preload.cjs
similarity index 100%
rename from electron/preload.js
rename to electron/preload.cjs
diff --git a/electron/src/config.ts b/electron/src/config.ts
new file mode 100644
index 00000000..aae058e9
--- /dev/null
+++ b/electron/src/config.ts
@@ -0,0 +1,22 @@
+import { app } from "electron";
+import path from "node:path";
+
+const disabledFeatures = ["HardwareMediaKeyHandling"];
+app.commandLine.appendSwitch("disable-features", disabledFeatures.join(","));
+
+export const defaultWindowTitle = "shapez CE";
+app.setName("shapez-ce");
+
+// This variable should be used to avoid situations where the app name
+// wasn't set yet.
+export const userData = app.getPath("userData");
+export const executableDir = path.dirname(app.getPath("exe"));
+
+export const pageUrl = app.isPackaged
+ ? new URL("../index.html", import.meta.url).href
+ : "http://localhost:3005/";
+
+export const switches = {
+ dev: app.commandLine.hasSwitch("dev"),
+ safeMode: app.commandLine.hasSwitch("safe-mode"),
+};
diff --git a/electron/src/fsjob.ts b/electron/src/fsjob.ts
new file mode 100644
index 00000000..fb759ac2
--- /dev/null
+++ b/electron/src/fsjob.ts
@@ -0,0 +1,132 @@
+import { BrowserWindow, dialog, FileFilter } from "electron";
+import fs from "fs/promises";
+import path from "path";
+import { userData } from "./config.js";
+
+interface GenericFsJob {
+ id: string;
+}
+
+export type InitializeFsJob = GenericFsJob & { type: "initialize" };
+type ListFsJob = GenericFsJob & { type: "list"; filename: string };
+type ReadFsJob = GenericFsJob & { type: "read"; filename: string };
+type WriteFsJob = GenericFsJob & { type: "write"; filename: string; contents: Uint8Array };
+type DeleteFsJob = GenericFsJob & { type: "delete"; filename: string };
+
+type OpenExternalFsJob = GenericFsJob & { type: "open-external"; extension: string };
+type SaveExternalFsJob = GenericFsJob & { type: "save-external"; filename: string; contents: Uint8Array };
+
+export type FsJob =
+ | InitializeFsJob
+ | ListFsJob
+ | ReadFsJob
+ | WriteFsJob
+ | DeleteFsJob
+ | OpenExternalFsJob
+ | SaveExternalFsJob;
+type FsJobResult = Uint8Array | string[] | void;
+
+export class FsJobHandler {
+ readonly rootDir: string;
+ private initialized = false;
+
+ constructor(subDir: string) {
+ this.rootDir = path.join(userData, subDir);
+ }
+
+ async initialize(): Promise {
+ if (this.initialized) {
+ return;
+ }
+
+ // Create the directory so that users know where to put files
+ await fs.mkdir(this.rootDir, { recursive: true });
+ this.initialized = true;
+ }
+
+ handleJob(job: FsJob): Promise {
+ switch (job.type) {
+ case "initialize":
+ return this.initialize();
+ case "open-external":
+ return this.openExternal(job.extension);
+ case "save-external":
+ return this.saveExternal(job.filename, job.contents);
+ }
+
+ const filename = this.safeFileName(job.filename);
+
+ switch (job.type) {
+ case "list":
+ return this.list(filename);
+ case "read":
+ return fs.readFile(filename);
+ case "write":
+ return this.write(filename, job.contents);
+ case "delete":
+ return fs.unlink(filename);
+ }
+
+ // @ts-expect-error this method can actually receive garbage
+ throw new Error(`Unknown FS job type: ${job.type}`);
+ }
+
+ private async openExternal(extension: string): Promise {
+ const filters = this.getFileDialogFilters(extension === "*" ? undefined : extension);
+ const window = BrowserWindow.getAllWindows()[0]!;
+
+ const result = await dialog.showOpenDialog(window, { filters, properties: ["openFile"] });
+ if (result.canceled) {
+ return undefined;
+ }
+
+ return await fs.readFile(result.filePaths[0]);
+ }
+
+ private async saveExternal(filename: string, contents: Uint8Array): Promise {
+ // Try to guess extension
+ const ext = filename.indexOf(".") < 1 ? filename.split(".").at(-1)! : undefined;
+ const filters = this.getFileDialogFilters(ext);
+ const window = BrowserWindow.getAllWindows()[0]!;
+
+ const result = await dialog.showSaveDialog(window, { defaultPath: filename, filters });
+ if (result.canceled) {
+ return;
+ }
+
+ return await fs.writeFile(result.filePath, contents);
+ }
+
+ private getFileDialogFilters(extension?: string): FileFilter[] {
+ const filters: FileFilter[] = [{ name: "All files", extensions: ["*"] }];
+
+ if (extension !== undefined) {
+ filters.unshift({
+ name: `${extension.toUpperCase()} files`,
+ extensions: [extension],
+ });
+ }
+
+ return filters;
+ }
+
+ private list(subdir: string): Promise {
+ // Bare-bones implementation
+ return fs.readdir(subdir);
+ }
+
+ private async write(file: string, contents: Uint8Array): Promise {
+ // The target directory might not exist, ensure it does
+ const parentDir = path.dirname(file);
+ await fs.mkdir(parentDir, { recursive: true });
+
+ await fs.writeFile(file, contents);
+ }
+
+ private safeFileName(name: string) {
+ // TODO: Rather than restricting file names, attempt to resolve everything
+ // relative to the data directory (i.e. normalize the file path, then join)
+ const relative = name.replace(/[^a-z.0-9_-]/gi, "_");
+ return path.join(this.rootDir, relative);
+ }
+}
diff --git a/electron/src/index.ts b/electron/src/index.ts
new file mode 100644
index 00000000..396d9cc9
--- /dev/null
+++ b/electron/src/index.ts
@@ -0,0 +1,95 @@
+import { BrowserWindow, app, shell } from "electron";
+import path from "path";
+import { defaultWindowTitle, pageUrl, switches } from "./config.js";
+import { IpcHandler } from "./ipc.js";
+import { ModLoader } from "./mods/loader.js";
+import { ModProtocolHandler } from "./mods/protocol_handler.js";
+
+let win: BrowserWindow | null = null;
+
+if (!app.requestSingleInstanceLock()) {
+ app.quit();
+} else {
+ app.on("second-instance", () => {
+ if (win?.isMinimized()) {
+ win.restore();
+ }
+
+ win?.focus();
+ });
+}
+
+const modLoader = new ModLoader();
+const modProtocol = new ModProtocolHandler(modLoader);
+const ipc = new IpcHandler(modLoader);
+
+function createWindow() {
+ // The protocol can only be handled after "ready" event
+ modProtocol.install();
+
+ const window = new BrowserWindow({
+ minWidth: 800,
+ minHeight: 600,
+ useContentSize: true,
+ autoHideMenuBar: !switches.dev,
+ show: false,
+ title: defaultWindowTitle,
+ webPreferences: {
+ preload: path.join(import.meta.dirname, "../preload.cjs"),
+ },
+ });
+
+ win = window;
+
+ if (!switches.dev) {
+ window.removeMenu();
+ }
+
+ window.on("ready-to-show", () => {
+ window.show();
+ });
+
+ ipc.install(window);
+ window.loadURL(pageUrl);
+
+ modLoader.on("forcereload", () => {
+ // TODO: Find a better way to manage cache when force
+ // reloading (use a non-persistent session?)
+ window.webContents.session.clearData({ dataTypes: ["cache"] }).then(() => window.reload());
+ });
+
+ // Redirect any kind of main frame navigation to external applications
+ window.webContents.on("will-navigate", (ev, url) => {
+ if (url === window.webContents.getURL()) {
+ // Avoid handling reloads externally
+ return;
+ }
+
+ ev.preventDefault();
+ openExternalUrl(url);
+ });
+
+ // Also redirect window.open
+ window.webContents.setWindowOpenHandler(({ url }) => {
+ openExternalUrl(url);
+ return { action: "deny" };
+ });
+}
+
+function openExternalUrl(urlString: string) {
+ try {
+ const url = new URL(urlString);
+
+ // TODO: Let the user explicitly allow other protocols
+ if (["http:", "https:"].includes(url.protocol)) {
+ shell.openExternal(urlString);
+ }
+ } catch {
+ // Ignore invalid URLs
+ }
+}
+
+app.on("ready", createWindow);
+app.on("window-all-closed", () => {
+ app.quit();
+});
diff --git a/electron/src/ipc.ts b/electron/src/ipc.ts
new file mode 100644
index 00000000..b3cd52a1
--- /dev/null
+++ b/electron/src/ipc.ts
@@ -0,0 +1,41 @@
+import { BrowserWindow, IpcMainInvokeEvent, ipcMain } from "electron";
+import { FsJob, FsJobHandler } from "./fsjob.js";
+import { ModLoader } from "./mods/loader.js";
+
+export class IpcHandler {
+ private readonly savesHandler = new FsJobHandler("saves");
+ private readonly modLoader: ModLoader;
+
+ constructor(modLoader: ModLoader) {
+ this.modLoader = modLoader;
+ }
+
+ install(window: BrowserWindow) {
+ ipcMain.handle("fs-job", this.handleFsJob.bind(this));
+ ipcMain.handle("get-mods", this.getMods.bind(this));
+ ipcMain.handle("set-fullscreen", this.setFullscreen.bind(this, window));
+
+ // Not implemented
+ // ipcMain.handle("open-mods-folder", ...)
+ }
+
+ private handleFsJob(_event: IpcMainInvokeEvent, job: FsJob) {
+ if (job.id !== "saves") {
+ throw new Error("Storages other than saves/ are not implemented yet");
+ }
+
+ return this.savesHandler.handleJob(job);
+ }
+
+ private async getMods() {
+ // TODO: Split mod reloads into a different IPC request
+ await this.modLoader.loadMods();
+ return this.modLoader.getAllMods();
+ }
+
+ private setFullscreen(window: BrowserWindow, _event: IpcMainInvokeEvent, flag: boolean) {
+ if (window.isFullScreen() != flag) {
+ window.setFullScreen(flag);
+ }
+ }
+}
diff --git a/electron/src/mods/loader.ts b/electron/src/mods/loader.ts
new file mode 100644
index 00000000..d18f571e
--- /dev/null
+++ b/electron/src/mods/loader.ts
@@ -0,0 +1,166 @@
+import EventEmitter from "node:events";
+import fs from "node:fs/promises";
+import path from "node:path";
+import { DevelopmentModLocator, DistroModLocator, ModLocator, UserModLocator } from "./locator.js";
+import { IpcModMetadata, ModMetadata } from "./metadata.js";
+
+type ModSource = "user" | "distro" | "dev";
+
+interface ModLocation {
+ source: ModSource;
+ file: string;
+}
+
+interface DisabledMod {
+ source: ModSource;
+ id: string;
+}
+
+interface IpcMod extends ModLocation {
+ disabled: boolean;
+ metadata: IpcModMetadata;
+}
+
+const METADATA_FILE = "mod.json";
+
+class Mod {
+ readonly source: ModSource;
+ readonly file: string;
+ readonly metadata: ModMetadata;
+
+ disabled = false;
+
+ constructor(source: ModSource, file: string, metadata: ModMetadata) {
+ this.source = source;
+ this.file = file;
+ this.metadata = metadata;
+ }
+
+ toJSON(): IpcMod {
+ return {
+ source: this.source,
+ file: this.file,
+ disabled: this.disabled,
+ metadata: {
+ ...this.metadata,
+ version: this.metadata.version.format(),
+ },
+ };
+ }
+}
+
+export class ModLoader extends EventEmitter {
+ private mods: Mod[] = [];
+ private readonly locators = new Map();
+
+ constructor() {
+ super();
+
+ this.locators.set("user", new UserModLocator());
+ this.locators.set("distro", new DistroModLocator());
+
+ const devLocator = new DevelopmentModLocator();
+ this.locators.set("dev", devLocator);
+
+ // If requested, restart automatically when dev mods are modified
+ devLocator.fsWatcher?.on("all", this.delayedForceReload());
+ }
+
+ /**
+ * Resets modloader state and reloads all mods, then triggers page reload.
+ */
+ async forceReload() {
+ await this.loadMods();
+ this.emit("forcereload");
+ }
+
+ async loadMods(): Promise {
+ const mods: Mod[] = [];
+ this.mods = mods;
+
+ const locations = await this.locateAllMods();
+ for (const location of locations) {
+ const metadata = await this.resolveMetadata(location);
+ if (metadata === null) {
+ continue;
+ }
+
+ // TODO: Only check this after applying disabled state
+ if (this.isModPresent(metadata.id)) {
+ console.warn(`Ignoring duplicate mod ${location.source}::${location.file}`);
+ continue;
+ }
+
+ mods.push(new Mod(location.source, location.file, metadata));
+ }
+
+ // Check for mods that should be disabled
+ for (const { source, id } of await this.collectDisabledMods()) {
+ const target = mods.find(m => m.source === source && m.metadata.id === id);
+ if (target !== undefined) {
+ target.disabled = true;
+ }
+ }
+ }
+
+ getAllMods(): IpcMod[] {
+ return this.mods.map(mod => mod.toJSON());
+ }
+
+ isModPresent(id: string): boolean {
+ return this.mods.some(mod => mod.metadata.id === id);
+ }
+
+ getModById(id: string): Mod | undefined {
+ return this.mods.find(mod => mod.metadata.id === id);
+ }
+
+ private delayedForceReload() {
+ // Debounce the force reload manually as chokidar won't aggregate events the way we want
+ // NOTE: The delay chosen here (250ms) is quite arbitrary!
+ let timeout: NodeJS.Timeout | undefined = undefined;
+ return () => {
+ clearTimeout(timeout);
+ timeout = setTimeout(() => this.forceReload(), 250);
+ };
+ }
+
+ private async locateAllMods(): Promise {
+ // Sort locators by priority, lowest number is highest priority
+ const locators = [...this.locators.entries()].sort(([, a], [, b]) => a.priority - b.priority);
+ const result: ModLocation[] = [];
+
+ for (const [source, locator] of locators) {
+ for (const file of await locator.locateMods()) {
+ result.push({ source, file });
+ }
+ }
+
+ return result;
+ }
+
+ private async resolveMetadata(mod: ModLocation): Promise {
+ // TODO: This function might call validation routines
+ const filePath = path.join(mod.file, METADATA_FILE);
+ try {
+ const contents = await fs.readFile(filePath, "utf-8");
+ return ModMetadata.parse(JSON.parse(contents));
+ } catch (err) {
+ // TODO: Collect mod errors, show to the user once all mods are loaded
+ console.error("Failed to read mod metadata", err);
+ return null;
+ }
+ }
+
+ private async collectDisabledMods(): Promise {
+ const result: DisabledMod[] = [];
+
+ for (const [source, locator] of this.locators.entries()) {
+ for (const id of await locator.getDisabledMods()) {
+ result.push({ source, id });
+ }
+ }
+
+ return result;
+ }
+}
diff --git a/electron/src/mods/locator.ts b/electron/src/mods/locator.ts
new file mode 100644
index 00000000..112468a6
--- /dev/null
+++ b/electron/src/mods/locator.ts
@@ -0,0 +1,213 @@
+import chokidar, { FSWatcher } from "chokidar";
+import { app } from "electron";
+import fs from "node:fs/promises";
+import path from "node:path";
+import { executableDir, switches, userData } from "../config.js";
+
+export const MOD_FILE_SUFFIX = ".asar";
+
+const DISABLED_MODS_FILE = "disabled-mods.json";
+const USER_MODS_DIR = path.join(userData, "mods");
+const DISTRO_MODS_DIR = path.join(executableDir, "mods");
+
+const DEV_SWITCH = "load-mod";
+const DEV_WATCH_SWITCH = "watch";
+const DEV_USER_MOD_PREFIX = "@/";
+
+export interface ModLocator {
+ readonly priority: number;
+
+ /**
+ * Asynchronously look for mod candidates.
+ *
+ * @returns absolute file paths of located mods
+ */
+ locateMods(): Promise;
+
+ /**
+ * Mark or unmark the specified mod as disabled.
+ *
+ * @param id ID of the mod to disable or enable
+ * @param flag whether to disable the mod
+ */
+ setModDisabled(id: string, flag: boolean): Promise;
+
+ /**
+ * Retrieve the list of mod IDs that should not be loaded.
+ *
+ * @returns IDs of the disabled mods
+ */
+ getDisabledMods(): Promise;
+}
+
+abstract class DirectoryModLocator implements ModLocator {
+ abstract readonly priority: number;
+
+ protected readonly directory: string;
+ private readonly disabledModsFile: string;
+ private disabledMods: Set | null = null;
+
+ constructor(directory: string) {
+ this.directory = directory;
+ this.disabledModsFile = path.join(directory, DISABLED_MODS_FILE);
+ }
+
+ async locateMods(): Promise {
+ if (switches.safeMode) {
+ return [];
+ }
+
+ try {
+ const dir = await fs.readdir(this.directory, { withFileTypes: true });
+ return dir
+ .filter(entry => entry.name.endsWith(MOD_FILE_SUFFIX))
+ .map(entry => path.join(entry.path, entry.name));
+ } catch (err) {
+ if ((err as NodeJS.ErrnoException).code === "ENOENT") {
+ // The directory does not exist
+ return [];
+ }
+
+ // Propagate all other errors
+ throw err;
+ }
+ }
+
+ setModDisabled(id: string, flag: boolean): Promise {
+ // Note: it is assumed that calling this before accessing
+ // getDisabledMods will overwrite the file.
+ this.disabledMods ??= new Set();
+
+ if (flag) {
+ this.disabledMods.add(id);
+ } else {
+ this.disabledMods.delete(id);
+ }
+
+ return this.writeDisabledModsFile();
+ }
+
+ async getDisabledMods(): Promise {
+ if (this.disabledMods === null) {
+ await this.readDisabledModsFile();
+ }
+
+ return [...this.disabledMods!];
+ }
+
+ private async readDisabledModsFile(): Promise {
+ // TODO: Validate internal structure (once something is added for
+ // mod metadata file validation)
+
+ try {
+ const contents = await fs.readFile(this.disabledModsFile, "utf-8");
+ this.disabledMods = new Set(JSON.parse(contents));
+ } catch (err) {
+ // Ensure we don't fail twice
+ this.disabledMods ??= new Set();
+
+ if ((err as NodeJS.ErrnoException).code == "ENOENT") {
+ // Ignore error entirely if the file is missing
+ return;
+ }
+
+ if (err instanceof SyntaxError) {
+ // Malformed JSON, replace the file
+ return this.writeDisabledModsFile();
+ }
+
+ console.warn(`Reading ${this.disabledModsFile} failed:`, err);
+ }
+ }
+
+ private async writeDisabledModsFile(): Promise {
+ try {
+ const contents = JSON.stringify([...(this.disabledMods ?? new Set())]);
+ await fs.writeFile(this.disabledModsFile, contents, "utf-8");
+ } catch (err: unknown) {
+ // Nothing we can do
+ console.warn(`Writing ${this.disabledModsFile} failed:`, err);
+ }
+ }
+}
+
+export class UserModLocator extends DirectoryModLocator {
+ readonly priority = 1;
+
+ constructor() {
+ super(USER_MODS_DIR);
+ }
+
+ async locateMods(): Promise {
+ // Ensure the directory exists
+ await fs.mkdir(this.directory, { recursive: true });
+ return super.locateMods();
+ }
+}
+
+export class DistroModLocator extends DirectoryModLocator {
+ readonly priority = 2;
+
+ constructor() {
+ super(DISTRO_MODS_DIR);
+ }
+}
+
+export class DevelopmentModLocator implements ModLocator {
+ readonly priority = 0;
+ readonly fsWatcher: FSWatcher | null = null;
+
+ private readonly modFiles: string[] = [];
+ private readonly disabledMods = new Set();
+
+ constructor() {
+ const switchValue = app.commandLine.getSwitchValue(DEV_SWITCH);
+ if (switchValue === "") {
+ // Empty string = switch not passed
+ return;
+ }
+
+ const resolved = switchValue.split(",").map(f => this.resolveFile(f));
+ this.modFiles.push(...resolved);
+
+ const watchMode = app.commandLine.hasSwitch(DEV_WATCH_SWITCH);
+ if (!watchMode || this.modFiles.length === 0) {
+ // Skip setting up chokidar
+ return;
+ }
+
+ this.fsWatcher = chokidar.watch(this.modFiles, {
+ persistent: false,
+ ignoreInitial: true,
+ });
+ }
+
+ locateMods(): Promise {
+ return Promise.resolve(this.modFiles);
+ }
+
+ setModDisabled(id: string, flag: boolean): Promise {
+ if (flag) {
+ this.disabledMods.add(id);
+ } else {
+ this.disabledMods.delete(id);
+ }
+
+ return Promise.resolve();
+ }
+
+ getDisabledMods(): Promise {
+ return Promise.resolve([...this.disabledMods]);
+ }
+
+ private resolveFile(file: string) {
+ // Allow using @/*.asar to reference user mods directory
+ if (file.startsWith(DEV_USER_MOD_PREFIX)) {
+ file = file.slice(DEV_USER_MOD_PREFIX.length);
+ return path.join(USER_MODS_DIR, file);
+ }
+
+ // Resolve mods relative to CWD, useful for development
+ return path.resolve(file);
+ }
+}
diff --git a/electron/src/mods/metadata.ts b/electron/src/mods/metadata.ts
new file mode 100644
index 00000000..623bd5be
--- /dev/null
+++ b/electron/src/mods/metadata.ts
@@ -0,0 +1,38 @@
+import SemVer from "semver/classes/semver.js";
+import { z } from "zod";
+
+const semver = z.string().transform((str, ctx) => {
+ try {
+ return new SemVer(str);
+ } catch {
+ ctx.addIssue({
+ code: z.ZodIssueCode.custom,
+ message: "Not a valid SemVer version string",
+ });
+ return z.NEVER;
+ }
+});
+
+// TBD: dependencies, icons, readme
+export const ModMetadata = z.object({
+ format: z.literal(1),
+ id: z.string().regex(/^[a-z0-9][a-z0-9_-]{0,48}[a-z0-9]$/g),
+ entry: z.string().nonempty(),
+ name: z.string().nonempty(),
+ description: z.ostring(),
+ authors: z
+ .object({
+ name: z.string().nonempty(),
+ website: z.string().url().optional(),
+ })
+ .array(),
+ version: semver,
+ savegameResident: z.boolean().default(true),
+ website: z.string().url().optional(),
+ source: z.string().url().optional(),
+});
+
+export type ModMetadata = z.infer;
+export type IpcModMetadata = Omit & {
+ version: string;
+};
diff --git a/electron/src/mods/protocol_handler.ts b/electron/src/mods/protocol_handler.ts
new file mode 100644
index 00000000..ba586632
--- /dev/null
+++ b/electron/src/mods/protocol_handler.ts
@@ -0,0 +1,98 @@
+import { net, protocol } from "electron";
+import { lstat, readdir } from "node:fs/promises";
+import path from "node:path";
+import { pathToFileURL } from "node:url";
+import { ModLoader } from "./loader.js";
+
+export const MOD_SCHEME = "mod";
+
+export class ModProtocolHandler {
+ private modLoader: ModLoader;
+
+ constructor(modLoader: ModLoader) {
+ this.modLoader = modLoader;
+
+ protocol.registerSchemesAsPrivileged([
+ {
+ scheme: MOD_SCHEME,
+ privileges: {
+ allowServiceWorkers: true,
+ bypassCSP: true,
+ secure: true,
+ standard: true,
+ stream: true,
+ supportFetchAPI: true,
+ },
+ },
+ ]);
+ }
+
+ install() {
+ protocol.handle(MOD_SCHEME, this.handler.bind(this));
+ }
+
+ private async handler(request: GlobalRequest): Promise {
+ const fileUrl = this.getFileUrlForRequest(request);
+ if (fileUrl === undefined) {
+ return Response.error();
+ }
+
+ try {
+ return await net.fetch(fileUrl.toString());
+ } catch (err) {
+ // Check if this is a directory request
+ const directoryIndex = await this.getDirectoryIndex(fileUrl);
+ if (directoryIndex !== null) {
+ return directoryIndex;
+ }
+
+ console.error("Failed to fetch:", err);
+ return Response.error();
+ }
+ }
+
+ private async getDirectoryIndex(fileUrl: URL): Promise {
+ if (!fileUrl.pathname.endsWith("/")) {
+ return null;
+ }
+
+ // Remove the trailing slash
+ fileUrl.pathname = fileUrl.pathname.slice(0, -1);
+
+ try {
+ const stats = await lstat(fileUrl);
+ if (!stats.isDirectory()) {
+ return null;
+ }
+
+ const dir = await readdir(fileUrl, { withFileTypes: true });
+ const result = dir.map(entry => entry.name + (entry.isDirectory() ? "/" : ""));
+
+ return Response.json(result);
+ } catch (err) {
+ console.error("Failed to get directory index:", err);
+ return null;
+ }
+ }
+
+ private getFileUrlForRequest(request: GlobalRequest): URL | undefined {
+ // mod://mod-id/path/to/file
+ const modUrl = new URL(request.url);
+ const mod = this.modLoader.getModById(modUrl.hostname);
+ if (mod === undefined) {
+ return undefined;
+ }
+
+ const bundle = mod.file;
+ const filePath = path.join(bundle, modUrl.pathname);
+
+ // Check if the path escapes the bundle as per Electron example
+ // NOTE: this means file names cannot start with ..
+ const relative = path.relative(bundle, filePath);
+ if (relative.startsWith("..") || path.isAbsolute(relative)) {
+ return undefined;
+ }
+
+ return pathToFileURL(filePath);
+ }
+}
diff --git a/electron/steam.js b/electron/steam.js
deleted file mode 100644
index cdda540b..00000000
--- a/electron/steam.js
+++ /dev/null
@@ -1,112 +0,0 @@
-const fs = require("fs");
-const path = require("path");
-const { ipcMain } = require("electron");
-
-let greenworks = null;
-let appId = null;
-let initialized = false;
-
-try {
- greenworks = require("shapez.io-private-artifacts/steam/greenworks");
- appId = parseInt(fs.readFileSync(path.join(__dirname, "steam_appid.txt"), "utf8"));
-} catch (err) {
- // greenworks is not installed
- console.warn("Failed to load steam api:", err);
-}
-
-console.log("App ID:", appId);
-
-function init(isDev) {
- if (!greenworks) {
- return;
- }
-
- if (!isDev) {
- if (greenworks.restartAppIfNecessary(appId)) {
- console.log("Restarting ...");
- process.exit(0);
- }
- }
-
- if (!greenworks.init()) {
- console.log("Failed to initialize greenworks");
- process.exit(1);
- }
-
- initialized = true;
-}
-
-function listen() {
- ipcMain.handle("steam:is-initialized", isInitialized);
-
- if (!initialized) {
- console.warn("Steam not initialized, won't be able to listen");
- return;
- }
-
- if (!greenworks) {
- console.warn("Greenworks not loaded, won't be able to listen");
- return;
- }
-
- console.log("Adding listeners");
-
- ipcMain.handle("steam:get-achievement-names", getAchievementNames);
- ipcMain.handle("steam:activate-achievement", activateAchievement);
-
- function bufferToHex(buffer) {
- return Array.from(new Uint8Array(buffer))
- .map(b => b.toString(16).padStart(2, "0"))
- .join("");
- }
-
- ipcMain.handle("steam:get-ticket", (event, arg) => {
- console.log("Requested steam ticket ...");
- return new Promise((resolve, reject) => {
- greenworks.getAuthSessionTicket(
- success => {
- const ticketHex = bufferToHex(success.ticket);
- resolve(ticketHex);
- },
- error => {
- console.error("Failed to get steam ticket:", error);
- reject(error);
- }
- );
- });
- });
-
- ipcMain.handle("steam:check-app-ownership", (event, appId) => {
- return Promise.resolve(greenworks.isDLCInstalled(appId));
- });
-}
-
-function isInitialized(event) {
- return Promise.resolve(initialized);
-}
-
-function getAchievementNames(event) {
- return new Promise((resolve, reject) => {
- try {
- const achievements = greenworks.getAchievementNames();
- resolve(achievements);
- } catch (err) {
- reject(err);
- }
- });
-}
-
-function activateAchievement(event, id) {
- return new Promise((resolve, reject) => {
- greenworks.activateAchievement(
- id,
- () => resolve(),
- err => reject(err)
- );
- });
-}
-
-module.exports = {
- init,
- listen,
-};
diff --git a/electron/steam_appid.txt b/electron/steam_appid.txt
deleted file mode 100644
index a8e9e809..00000000
--- a/electron/steam_appid.txt
+++ /dev/null
@@ -1 +0,0 @@
-1318690
diff --git a/electron/tsconfig.json b/electron/tsconfig.json
new file mode 100644
index 00000000..2ababc88
--- /dev/null
+++ b/electron/tsconfig.json
@@ -0,0 +1,9 @@
+{
+ "extends": "../tsconfig.json",
+ "include": ["./src/**/*"],
+ "compilerOptions": {
+ "noEmit": false,
+ "outDir": "./dist",
+ "strict": true
+ }
+}
diff --git a/electron/yarn.lock b/electron/yarn.lock
deleted file mode 100644
index f33e463b..00000000
--- a/electron/yarn.lock
+++ /dev/null
@@ -1,584 +0,0 @@
-# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
-# yarn lockfile v1
-
-
-"@electron/get@^1.13.0":
- version "1.13.1"
- resolved "https://registry.yarnpkg.com/@electron/get/-/get-1.13.1.tgz#42a0aa62fd1189638bd966e23effaebb16108368"
- integrity sha512-U5vkXDZ9DwXtkPqlB45tfYnnYBN8PePp1z/XDCupnSpdrxT8/ThCv9WCwPLf9oqiSGZTkH6dx2jDUPuoXpjkcA==
- dependencies:
- debug "^4.1.1"
- env-paths "^2.2.0"
- fs-extra "^8.1.0"
- got "^9.6.0"
- progress "^2.0.3"
- semver "^6.2.0"
- sumchecker "^3.0.1"
- optionalDependencies:
- global-agent "^3.0.0"
- global-tunnel-ng "^2.7.1"
-
-"@sindresorhus/is@^0.14.0":
- version "0.14.0"
- resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea"
- integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==
-
-"@szmarczak/http-timer@^1.1.2":
- version "1.1.2"
- resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421"
- integrity sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==
- dependencies:
- defer-to-connect "^1.0.1"
-
-"@types/node@^14.6.2":
- version "14.18.20"
- resolved "https://registry.yarnpkg.com/@types/node/-/node-14.18.20.tgz#268f028b36eaf51181c3300252f605488c4f0650"
- integrity sha512-Q8KKwm9YqEmUBRsqJ2GWJDtXltBDxTdC4m5vTdXBolu2PeQh8LX+f6BTwU+OuXPu37fLxoN6gidqBmnky36FXA==
-
-async-lock@^1.2.8:
- version "1.2.8"
- resolved "https://registry.yarnpkg.com/async-lock/-/async-lock-1.2.8.tgz#7b02bdfa2de603c0713acecd11184cf97bbc7c4c"
- integrity sha512-G+26B2jc0Gw0EG/WN2M6IczuGepBsfR1+DtqLnyFSH4p2C668qkOCtEkGNVEaaNAVlYwEMazy1+/jnLxltBkIQ==
-
-boolean@^3.0.1:
- version "3.0.2"
- resolved "https://registry.yarnpkg.com/boolean/-/boolean-3.0.2.tgz#df1baa18b6a2b0e70840475e1d93ec8fe75b2570"
- integrity sha512-RwywHlpCRc3/Wh81MiCKun4ydaIFyW5Ea6JbL6sRCVx5q5irDw7pMXBUFYF/jArQ6YrG36q0kpovc9P/Kd3I4g==
-
-buffer-crc32@~0.2.3:
- version "0.2.13"
- resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242"
- integrity sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=
-
-buffer-from@^1.0.0:
- version "1.1.1"
- resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef"
- integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==
-
-cacheable-request@^6.0.0:
- version "6.1.0"
- resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-6.1.0.tgz#20ffb8bd162ba4be11e9567d823db651052ca912"
- integrity sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==
- dependencies:
- clone-response "^1.0.2"
- get-stream "^5.1.0"
- http-cache-semantics "^4.0.0"
- keyv "^3.0.0"
- lowercase-keys "^2.0.0"
- normalize-url "^4.1.0"
- responselike "^1.0.2"
-
-clone-response@^1.0.2:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b"
- integrity sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=
- dependencies:
- mimic-response "^1.0.0"
-
-concat-stream@^1.6.2:
- version "1.6.2"
- resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34"
- integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==
- dependencies:
- buffer-from "^1.0.0"
- inherits "^2.0.3"
- readable-stream "^2.2.2"
- typedarray "^0.0.6"
-
-config-chain@^1.1.11:
- version "1.1.12"
- resolved "https://registry.yarnpkg.com/config-chain/-/config-chain-1.1.12.tgz#0fde8d091200eb5e808caf25fe618c02f48e4efa"
- integrity sha512-a1eOIcu8+7lUInge4Rpf/n4Krkf3Dd9lqhljRzII1/Zno/kRtUWnznPO3jOKBmTEktkt3fkxisUcivoj0ebzoA==
- dependencies:
- ini "^1.3.4"
- proto-list "~1.2.1"
-
-core-util-is@~1.0.0:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
- integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=
-
-debug@^2.6.9:
- version "2.6.9"
- resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
- integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==
- dependencies:
- ms "2.0.0"
-
-debug@^4.1.0, debug@^4.1.1:
- version "4.3.1"
- resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee"
- integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==
- dependencies:
- ms "2.1.2"
-
-decompress-response@^3.3.0:
- version "3.3.0"
- resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3"
- integrity sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=
- dependencies:
- mimic-response "^1.0.0"
-
-defer-to-connect@^1.0.1:
- version "1.1.3"
- resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-1.1.3.tgz#331ae050c08dcf789f8c83a7b81f0ed94f4ac591"
- integrity sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==
-
-define-properties@^1.1.3:
- version "1.1.3"
- resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1"
- integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==
- dependencies:
- object-keys "^1.0.12"
-
-detect-node@^2.0.4:
- version "2.0.4"
- resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.0.4.tgz#014ee8f8f669c5c58023da64b8179c083a28c46c"
- integrity sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==
-
-duplexer3@^0.1.4:
- version "0.1.4"
- resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2"
- integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=
-
-electron-window-state@^5.0.3:
- version "5.0.3"
- resolved "https://registry.yarnpkg.com/electron-window-state/-/electron-window-state-5.0.3.tgz#4f36d09e3f953d87aff103bf010f460056050aa8"
- integrity sha512-1mNTwCfkolXl3kMf50yW3vE2lZj0y92P/HYWFBrb+v2S/pCka5mdwN3cagKm458A7NjndSwijynXgcLWRodsVg==
- dependencies:
- jsonfile "^4.0.0"
- mkdirp "^0.5.1"
-
-electron@16.2.8:
- version "16.2.8"
- resolved "https://registry.yarnpkg.com/electron/-/electron-16.2.8.tgz#b7f2bd1184701e54a1bc902839d5a3ec95bb8982"
- integrity sha512-KSOytY6SPLsh3iCziztqa/WgJyfDOKzCvNqku9gGIqSdT8CqtV66dTU1SOrKZQjRFLxHaF8LbyxUL1vwe4taqw==
- dependencies:
- "@electron/get" "^1.13.0"
- "@types/node" "^14.6.2"
- extract-zip "^1.0.3"
-
-encodeurl@^1.0.2:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
- integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=
-
-end-of-stream@^1.1.0:
- version "1.4.4"
- resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0"
- integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==
- dependencies:
- once "^1.4.0"
-
-env-paths@^2.2.0:
- version "2.2.1"
- resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2"
- integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==
-
-es6-error@^4.1.1:
- version "4.1.1"
- resolved "https://registry.yarnpkg.com/es6-error/-/es6-error-4.1.1.tgz#9e3af407459deed47e9a91f9b885a84eb05c561d"
- integrity sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==
-
-escape-string-regexp@^4.0.0:
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34"
- integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==
-
-extract-zip@^1.0.3:
- version "1.7.0"
- resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-1.7.0.tgz#556cc3ae9df7f452c493a0cfb51cc30277940927"
- integrity sha512-xoh5G1W/PB0/27lXgMQyIhP5DSY/LhoCsOyZgb+6iMmRtCwVBo55uKaMoEYrDCKQhWvqEip5ZPKAc6eFNyf/MA==
- dependencies:
- concat-stream "^1.6.2"
- debug "^2.6.9"
- mkdirp "^0.5.4"
- yauzl "^2.10.0"
-
-fd-slicer@~1.1.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e"
- integrity sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=
- dependencies:
- pend "~1.2.0"
-
-fs-extra@^8.1.0:
- version "8.1.0"
- resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0"
- integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==
- dependencies:
- graceful-fs "^4.2.0"
- jsonfile "^4.0.0"
- universalify "^0.1.0"
-
-get-stream@^4.1.0:
- version "4.1.0"
- resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5"
- integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==
- dependencies:
- pump "^3.0.0"
-
-get-stream@^5.1.0:
- version "5.2.0"
- resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3"
- integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==
- dependencies:
- pump "^3.0.0"
-
-global-agent@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/global-agent/-/global-agent-3.0.0.tgz#ae7cd31bd3583b93c5a16437a1afe27cc33a1ab6"
- integrity sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==
- dependencies:
- boolean "^3.0.1"
- es6-error "^4.1.1"
- matcher "^3.0.0"
- roarr "^2.15.3"
- semver "^7.3.2"
- serialize-error "^7.0.1"
-
-global-tunnel-ng@^2.7.1:
- version "2.7.1"
- resolved "https://registry.yarnpkg.com/global-tunnel-ng/-/global-tunnel-ng-2.7.1.tgz#d03b5102dfde3a69914f5ee7d86761ca35d57d8f"
- integrity sha512-4s+DyciWBV0eK148wqXxcmVAbFVPqtc3sEtUE/GTQfuU80rySLcMhUmHKSHI7/LDj8q0gDYI1lIhRRB7ieRAqg==
- dependencies:
- encodeurl "^1.0.2"
- lodash "^4.17.10"
- npm-conf "^1.1.3"
- tunnel "^0.0.6"
-
-globalthis@^1.0.1:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.2.tgz#2a235d34f4d8036219f7e34929b5de9e18166b8b"
- integrity sha512-ZQnSFO1la8P7auIOQECnm0sSuoMeaSq0EEdXMBFF2QJO4uNcwbyhSgG3MruWNbFTqCLmxVwGOl7LZ9kASvHdeQ==
- dependencies:
- define-properties "^1.1.3"
-
-got@^9.6.0:
- version "9.6.0"
- resolved "https://registry.yarnpkg.com/got/-/got-9.6.0.tgz#edf45e7d67f99545705de1f7bbeeeb121765ed85"
- integrity sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==
- dependencies:
- "@sindresorhus/is" "^0.14.0"
- "@szmarczak/http-timer" "^1.1.2"
- cacheable-request "^6.0.0"
- decompress-response "^3.3.0"
- duplexer3 "^0.1.4"
- get-stream "^4.1.0"
- lowercase-keys "^1.0.1"
- mimic-response "^1.0.1"
- p-cancelable "^1.0.0"
- to-readable-stream "^1.0.0"
- url-parse-lax "^3.0.0"
-
-graceful-fs@^4.1.6, graceful-fs@^4.2.0:
- version "4.2.6"
- resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee"
- integrity sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==
-
-http-cache-semantics@^4.0.0:
- version "4.1.0"
- resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390"
- integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==
-
-inherits@^2.0.3, inherits@~2.0.3:
- version "2.0.4"
- resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
- integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
-
-ini@^1.3.4:
- version "1.3.8"
- resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c"
- integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==
-
-isarray@~1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
- integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=
-
-json-buffer@3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898"
- integrity sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=
-
-json-stringify-safe@^5.0.1:
- version "5.0.1"
- resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
- integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=
-
-jsonfile@^4.0.0:
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb"
- integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=
- optionalDependencies:
- graceful-fs "^4.1.6"
-
-keyv@^3.0.0:
- version "3.1.0"
- resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.1.0.tgz#ecc228486f69991e49e9476485a5be1e8fc5c4d9"
- integrity sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==
- dependencies:
- json-buffer "3.0.0"
-
-lodash@^4.17.10:
- version "4.17.21"
- resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
- integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
-
-lowercase-keys@^1.0.0, lowercase-keys@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f"
- integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==
-
-lowercase-keys@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479"
- integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==
-
-lru-cache@^6.0.0:
- version "6.0.0"
- resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94"
- integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==
- dependencies:
- yallist "^4.0.0"
-
-matcher@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/matcher/-/matcher-3.0.0.tgz#bd9060f4c5b70aa8041ccc6f80368760994f30ca"
- integrity sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==
- dependencies:
- escape-string-regexp "^4.0.0"
-
-mimic-response@^1.0.0, mimic-response@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b"
- integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==
-
-minimist@^1.2.5:
- version "1.2.5"
- resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
- integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
-
-mkdirp@^0.5.1, mkdirp@^0.5.4:
- version "0.5.5"
- resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def"
- integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==
- dependencies:
- minimist "^1.2.5"
-
-ms@2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
- integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=
-
-ms@2.1.2:
- version "2.1.2"
- resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
- integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
-
-normalize-url@^4.1.0:
- version "4.5.0"
- resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.0.tgz#453354087e6ca96957bd8f5baf753f5982142129"
- integrity sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==
-
-npm-conf@^1.1.3:
- version "1.1.3"
- resolved "https://registry.yarnpkg.com/npm-conf/-/npm-conf-1.1.3.tgz#256cc47bd0e218c259c4e9550bf413bc2192aff9"
- integrity sha512-Yic4bZHJOt9RCFbRP3GgpqhScOY4HH3V2P8yBj6CeYq118Qr+BLXqT2JvpJ00mryLESpgOxf5XlFv4ZjXxLScw==
- dependencies:
- config-chain "^1.1.11"
- pify "^3.0.0"
-
-object-keys@^1.0.12:
- version "1.1.1"
- resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e"
- integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==
-
-once@^1.3.1, once@^1.4.0:
- version "1.4.0"
- resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
- integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E=
- dependencies:
- wrappy "1"
-
-p-cancelable@^1.0.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-1.1.0.tgz#d078d15a3af409220c886f1d9a0ca2e441ab26cc"
- integrity sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==
-
-pend@~1.2.0:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50"
- integrity sha1-elfrVQpng/kRUzH89GY9XI4AelA=
-
-pify@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176"
- integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=
-
-prepend-http@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897"
- integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=
-
-process-nextick-args@~2.0.0:
- version "2.0.1"
- resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2"
- integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==
-
-progress@^2.0.3:
- version "2.0.3"
- resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8"
- integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==
-
-proto-list@~1.2.1:
- version "1.2.4"
- resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849"
- integrity sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk=
-
-pump@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64"
- integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==
- dependencies:
- end-of-stream "^1.1.0"
- once "^1.3.1"
-
-readable-stream@^2.2.2:
- version "2.3.7"
- resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57"
- integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==
- dependencies:
- core-util-is "~1.0.0"
- inherits "~2.0.3"
- isarray "~1.0.0"
- process-nextick-args "~2.0.0"
- safe-buffer "~5.1.1"
- string_decoder "~1.1.1"
- util-deprecate "~1.0.1"
-
-responselike@^1.0.2:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7"
- integrity sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=
- dependencies:
- lowercase-keys "^1.0.0"
-
-roarr@^2.15.3:
- version "2.15.4"
- resolved "https://registry.yarnpkg.com/roarr/-/roarr-2.15.4.tgz#f5fe795b7b838ccfe35dc608e0282b9eba2e7afd"
- integrity sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==
- dependencies:
- boolean "^3.0.1"
- detect-node "^2.0.4"
- globalthis "^1.0.1"
- json-stringify-safe "^5.0.1"
- semver-compare "^1.0.0"
- sprintf-js "^1.1.2"
-
-safe-buffer@~5.1.0, safe-buffer@~5.1.1:
- version "5.1.2"
- resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
- integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
-
-semver-compare@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc"
- integrity sha1-De4hahyUGrN+nvsXiPavxf9VN/w=
-
-semver@^6.2.0:
- version "6.3.0"
- resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d"
- integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==
-
-semver@^7.3.2:
- version "7.3.4"
- resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.4.tgz#27aaa7d2e4ca76452f98d3add093a72c943edc97"
- integrity sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==
- dependencies:
- lru-cache "^6.0.0"
-
-serialize-error@^7.0.1:
- version "7.0.1"
- resolved "https://registry.yarnpkg.com/serialize-error/-/serialize-error-7.0.1.tgz#f1360b0447f61ffb483ec4157c737fab7d778e18"
- integrity sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==
- dependencies:
- type-fest "^0.13.1"
-
-"shapez.io-private-artifacts@github:tobspr/shapez.io-private-artifacts#abi-v99":
- version "0.1.0"
- resolved "git+ssh://git@github.com/tobspr/shapez.io-private-artifacts.git#3293b20be26060fd36e9f00ded9ab5d0bdf57338"
-
-sprintf-js@^1.1.2:
- version "1.1.2"
- resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.1.2.tgz#da1765262bf8c0f571749f2ad6c26300207ae673"
- integrity sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==
-
-string_decoder@~1.1.1:
- version "1.1.1"
- resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8"
- integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==
- dependencies:
- safe-buffer "~5.1.0"
-
-sumchecker@^3.0.1:
- version "3.0.1"
- resolved "https://registry.yarnpkg.com/sumchecker/-/sumchecker-3.0.1.tgz#6377e996795abb0b6d348e9b3e1dfb24345a8e42"
- integrity sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==
- dependencies:
- debug "^4.1.0"
-
-to-readable-stream@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/to-readable-stream/-/to-readable-stream-1.0.0.tgz#ce0aa0c2f3df6adf852efb404a783e77c0475771"
- integrity sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==
-
-tunnel@^0.0.6:
- version "0.0.6"
- resolved "https://registry.yarnpkg.com/tunnel/-/tunnel-0.0.6.tgz#72f1314b34a5b192db012324df2cc587ca47f92c"
- integrity sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==
-
-type-fest@^0.13.1:
- version "0.13.1"
- resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.13.1.tgz#0172cb5bce80b0bd542ea348db50c7e21834d934"
- integrity sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==
-
-typedarray@^0.0.6:
- version "0.0.6"
- resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
- integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=
-
-universalify@^0.1.0:
- version "0.1.2"
- resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66"
- integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==
-
-url-parse-lax@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-3.0.0.tgz#16b5cafc07dbe3676c1b1999177823d6503acb0c"
- integrity sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=
- dependencies:
- prepend-http "^2.0.0"
-
-util-deprecate@~1.0.1:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
- integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=
-
-wrappy@1:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
- integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
-
-yallist@^4.0.0:
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"
- integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
-
-yauzl@^2.10.0:
- version "2.10.0"
- resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9"
- integrity sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=
- dependencies:
- buffer-crc32 "~0.2.3"
- fd-slicer "~1.1.0"
diff --git a/electron_gog/favicon.icns b/electron_gog/favicon.icns
deleted file mode 100644
index 79e141a5..00000000
Binary files a/electron_gog/favicon.icns and /dev/null differ
diff --git a/electron_gog/favicon.ico b/electron_gog/favicon.ico
deleted file mode 100644
index 81a9aa5c..00000000
Binary files a/electron_gog/favicon.ico and /dev/null differ
diff --git a/electron_gog/favicon.png b/electron_gog/favicon.png
deleted file mode 100644
index c837c787..00000000
Binary files a/electron_gog/favicon.png and /dev/null differ
diff --git a/electron_gog/index.js b/electron_gog/index.js
deleted file mode 100644
index 563f187d..00000000
--- a/electron_gog/index.js
+++ /dev/null
@@ -1,381 +0,0 @@
-/* eslint-disable quotes,no-undef */
-
-const { app, BrowserWindow, Menu, MenuItem, ipcMain, shell, dialog, session } = require("electron");
-const path = require("path");
-const url = require("url");
-const fs = require("fs");
-const asyncLock = require("async-lock");
-const windowStateKeeper = require("electron-window-state");
-
-// Disable hardware key handling, i.e. being able to pause/resume the game music
-// with hardware keys
-app.commandLine.appendSwitch("disable-features", "HardwareMediaKeyHandling");
-
-const isDev = app.commandLine.hasSwitch("dev");
-const isLocal = app.commandLine.hasSwitch("local");
-const safeMode = app.commandLine.hasSwitch("safe-mode");
-const externalMod = app.commandLine.getSwitchValue("load-mod");
-
-const roamingFolder =
- process.env.APPDATA ||
- (process.platform == "darwin"
- ? process.env.HOME + "/Library/Preferences"
- : process.env.HOME + "/.local/share");
-
-let storePath = path.join(roamingFolder, "shapez.io", "saves");
-let modsPath = path.join(roamingFolder, "shapez.io", "mods");
-
-if (!fs.existsSync(storePath)) {
- // No try-catch by design
- fs.mkdirSync(storePath, { recursive: true });
-}
-
-if (!fs.existsSync(modsPath)) {
- fs.mkdirSync(modsPath, { recursive: true });
-}
-
-/** @type {BrowserWindow} */
-let win = null;
-let menu = null;
-
-function createWindow() {
- let faviconExtension = ".png";
- if (process.platform === "win32") {
- faviconExtension = ".ico";
- }
-
- const mainWindowState = windowStateKeeper({
- defaultWidth: 1000,
- defaultHeight: 800,
- });
-
- win = new BrowserWindow({
- x: mainWindowState.x,
- y: mainWindowState.y,
- width: mainWindowState.width,
- height: mainWindowState.height,
- show: false,
- backgroundColor: "#222428",
- useContentSize: false,
- minWidth: 800,
- minHeight: 600,
- title: "shapez",
- transparent: false,
- icon: path.join(__dirname, "favicon" + faviconExtension),
- // fullscreen: true,
- autoHideMenuBar: !isDev,
- webPreferences: {
- nodeIntegration: false,
- nodeIntegrationInWorker: false,
- nodeIntegrationInSubFrames: false,
- contextIsolation: true,
- enableRemoteModule: false,
- disableBlinkFeatures: "Auxclick",
-
- webSecurity: true,
- sandbox: true,
- preload: path.join(__dirname, "preload.js"),
- experimentalFeatures: false,
- },
- allowRunningInsecureContent: false,
- });
-
- mainWindowState.manage(win);
-
- if (isLocal) {
- win.loadURL("http://localhost:3005");
- } else {
- win.loadURL(
- url.format({
- pathname: path.join(__dirname, "index.html"),
- protocol: "file:",
- slashes: true,
- })
- );
- }
- win.webContents.session.clearCache();
- win.webContents.session.clearStorageData();
-
- ////// SECURITY
-
- // Disable permission requests
- win.webContents.session.setPermissionRequestHandler((webContents, permission, callback) => {
- callback(false);
- });
- session.fromPartition("default").setPermissionRequestHandler((webContents, permission, callback) => {
- callback(false);
- });
-
- app.on("web-contents-created", (event, contents) => {
- // Disable vewbiew
- contents.on("will-attach-webview", (event, webPreferences, params) => {
- event.preventDefault();
- });
- // Disable navigation
- contents.on("will-navigate", (event, navigationUrl) => {
- event.preventDefault();
- });
- });
-
- win.webContents.on("will-redirect", (contentsEvent, navigationUrl) => {
- // Log and prevent the app from redirecting to a new page
- console.error(
- `The application tried to redirect to the following address: '${navigationUrl}'. This attempt was blocked.`
- );
- contentsEvent.preventDefault();
- });
-
- // Filter loading any module via remote;
- // you shouldn't be using remote at all, though
- // https://electronjs.org/docs/tutorial/security#16-filter-the-remote-module
- app.on("remote-require", (event, webContents, moduleName) => {
- event.preventDefault();
- });
-
- // built-ins are modules such as "app"
- app.on("remote-get-builtin", (event, webContents, moduleName) => {
- event.preventDefault();
- });
-
- app.on("remote-get-global", (event, webContents, globalName) => {
- event.preventDefault();
- });
-
- app.on("remote-get-current-window", (event, webContents) => {
- event.preventDefault();
- });
-
- app.on("remote-get-current-web-contents", (event, webContents) => {
- event.preventDefault();
- });
-
- //// END SECURITY
-
- win.webContents.on("new-window", (event, pth) => {
- event.preventDefault();
-
- if (pth.startsWith("https://")) {
- shell.openExternal(pth);
- }
- });
-
- win.on("closed", () => {
- console.log("Window closed");
- win = null;
- });
-
- if (isDev) {
- menu = new Menu();
-
- win.webContents.toggleDevTools();
-
- const mainItem = new MenuItem({
- label: "Toggle Dev Tools",
- click: () => win.webContents.toggleDevTools(),
- accelerator: "F12",
- });
- menu.append(mainItem);
-
- const reloadItem = new MenuItem({
- label: "Reload",
- click: () => win.reload(),
- accelerator: "F5",
- });
- menu.append(reloadItem);
-
- const fullscreenItem = new MenuItem({
- label: "Fullscreen",
- click: () => win.setFullScreen(!win.isFullScreen()),
- accelerator: "F11",
- });
- menu.append(fullscreenItem);
-
- const mainMenu = new Menu();
- mainMenu.append(
- new MenuItem({
- label: "shapez.io",
- submenu: menu,
- })
- );
-
- Menu.setApplicationMenu(mainMenu);
- } else {
- Menu.setApplicationMenu(null);
- }
-
- win.once("ready-to-show", () => {
- win.show();
- win.focus();
- });
-}
-
-if (!app.requestSingleInstanceLock()) {
- app.exit(0);
-} else {
- app.on("second-instance", () => {
- // Someone tried to run a second instance, we should focus
- if (win) {
- if (win.isMinimized()) {
- win.restore();
- }
- win.focus();
- }
- });
-}
-
-app.on("ready", createWindow);
-
-app.on("window-all-closed", () => {
- console.log("All windows closed");
- app.quit();
-});
-
-ipcMain.on("set-fullscreen", (event, flag) => {
- win.setFullScreen(flag);
-});
-
-ipcMain.on("exit-app", () => {
- win.close();
- app.quit();
-});
-
-let renameCounter = 1;
-
-const fileLock = new asyncLock({
- timeout: 30000,
- maxPending: 1000,
-});
-
-function niceFileName(filename) {
- return filename.replace(storePath, "@");
-}
-
-async function writeFileSafe(filename, contents) {
- ++renameCounter;
- const prefix = "[ " + renameCounter + ":" + niceFileName(filename) + " ] ";
- const transactionId = String(new Date().getTime()) + "." + renameCounter;
-
- if (fileLock.isBusy()) {
- console.warn(prefix, "Concurrent write process on", filename);
- }
-
- fileLock.acquire(filename, async () => {
- console.log(prefix, "Starting write on", niceFileName(filename), "in transaction", transactionId);
-
- if (!fs.existsSync(filename)) {
- // this one is easy
- console.log(prefix, "Writing file instantly because it does not exist:", niceFileName(filename));
- await fs.promises.writeFile(filename, contents, "utf8");
- return;
- }
-
- // first, write a temporary file (.tmp-XXX)
- const tempName = filename + ".tmp-" + transactionId;
- console.log(prefix, "Writing temporary file", niceFileName(tempName));
- await fs.promises.writeFile(tempName, contents, "utf8");
-
- // now, rename the original file to (.backup-XXX)
- const oldTemporaryName = filename + ".backup-" + transactionId;
- console.log(
- prefix,
- "Renaming old file",
- niceFileName(filename),
- "to",
- niceFileName(oldTemporaryName)
- );
- await fs.promises.rename(filename, oldTemporaryName);
-
- // now, rename the temporary file (.tmp-XXX) to the target
- console.log(
- prefix,
- "Renaming the temporary file",
- niceFileName(tempName),
- "to the original",
- niceFileName(filename)
- );
- await fs.promises.rename(tempName, filename);
-
- // we are done now, try to create a backup, but don't fail if the backup fails
- try {
- // check if there is an old backup file
- const backupFileName = filename + ".backup";
- if (fs.existsSync(backupFileName)) {
- console.log(prefix, "Deleting old backup file", niceFileName(backupFileName));
- // delete the old backup
- await fs.promises.unlink(backupFileName);
- }
-
- // rename the old file to the new backup file
- console.log(prefix, "Moving", niceFileName(oldTemporaryName), "to the backup file location");
- await fs.promises.rename(oldTemporaryName, backupFileName);
- } catch (ex) {
- console.error(prefix, "Failed to switch backup files:", ex);
- }
- });
-}
-
-ipcMain.handle("fs-job", async (event, job) => {
- const filenameSafe = job.filename.replace(/[^a-z\.\-_0-9]/gi, "_");
- const fname = path.join(storePath, filenameSafe);
- switch (job.type) {
- case "read": {
- if (!fs.existsSync(fname)) {
- // Special FILE_NOT_FOUND error code
- return { error: "file_not_found" };
- }
- return await fs.promises.readFile(fname, "utf8");
- }
- case "write": {
- await writeFileSafe(fname, job.contents);
- return job.contents;
- }
-
- case "delete": {
- await fs.promises.unlink(fname);
- return;
- }
-
- default:
- throw new Error("Unknown fs job: " + job.type);
- }
-});
-
-ipcMain.handle("open-mods-folder", async () => {
- shell.openPath(modsPath);
-});
-
-console.log("Loading mods ...");
-
-function loadMods() {
- if (safeMode) {
- console.log("Safe Mode enabled for mods, skipping mod search");
- }
- console.log("Loading mods from", modsPath);
- let modFiles = safeMode
- ? []
- : fs
- .readdirSync(modsPath)
- .filter(filename => filename.endsWith(".js"))
- .map(filename => path.join(modsPath, filename));
-
- if (externalMod) {
- console.log("Adding external mod source:", externalMod);
- const externalModPaths = externalMod.split(",");
- modFiles = modFiles.concat(externalModPaths);
- }
-
- return modFiles.map(filename => fs.readFileSync(filename, "utf8"));
-}
-
-let mods = [];
-try {
- mods = loadMods();
- console.log("Loaded", mods.length, "mods");
-} catch (ex) {
- console.error("Failed to load mods");
- dialog.showErrorBox("Failed to load mods:", ex);
-}
-
-ipcMain.handle("get-mods", async () => {
- return mods;
-});
diff --git a/electron_gog/package.json b/electron_gog/package.json
deleted file mode 100644
index 082055e4..00000000
--- a/electron_gog/package.json
+++ /dev/null
@@ -1,17 +0,0 @@
-{
- "name": "electron",
- "version": "1.0.0",
- "main": "index.js",
- "license": "MIT",
- "private": true,
- "scripts": {
- "startDev": "electron --disable-direct-composition --in-process-gpu . --dev --local",
- "startDevGpu": "electron --enable-gpu-rasterization --enable-accelerated-2d-canvas --num-raster-threads=8 --enable-zero-copy . --dev --local",
- "start": "electron --disable-direct-composition --in-process-gpu ."
- },
- "dependencies": {
- "async-lock": "^1.2.8",
- "electron": "16.2.8",
- "electron-window-state": "^5.0.3"
- }
-}
diff --git a/electron_gog/preload.js b/electron_gog/preload.js
deleted file mode 100644
index c6336230..00000000
--- a/electron_gog/preload.js
+++ /dev/null
@@ -1,7 +0,0 @@
-const { contextBridge, ipcRenderer } = require("electron");
-
-contextBridge.exposeInMainWorld("ipcRenderer", {
- invoke: ipcRenderer.invoke.bind(ipcRenderer),
- on: ipcRenderer.on.bind(ipcRenderer),
- send: ipcRenderer.send.bind(ipcRenderer),
-});
diff --git a/electron_gog/yarn.lock b/electron_gog/yarn.lock
deleted file mode 100644
index c9238b1f..00000000
--- a/electron_gog/yarn.lock
+++ /dev/null
@@ -1,580 +0,0 @@
-# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
-# yarn lockfile v1
-
-
-"@electron/get@^1.13.0":
- version "1.13.1"
- resolved "https://registry.yarnpkg.com/@electron/get/-/get-1.13.1.tgz#42a0aa62fd1189638bd966e23effaebb16108368"
- integrity sha512-U5vkXDZ9DwXtkPqlB45tfYnnYBN8PePp1z/XDCupnSpdrxT8/ThCv9WCwPLf9oqiSGZTkH6dx2jDUPuoXpjkcA==
- dependencies:
- debug "^4.1.1"
- env-paths "^2.2.0"
- fs-extra "^8.1.0"
- got "^9.6.0"
- progress "^2.0.3"
- semver "^6.2.0"
- sumchecker "^3.0.1"
- optionalDependencies:
- global-agent "^3.0.0"
- global-tunnel-ng "^2.7.1"
-
-"@sindresorhus/is@^0.14.0":
- version "0.14.0"
- resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea"
- integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==
-
-"@szmarczak/http-timer@^1.1.2":
- version "1.1.2"
- resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421"
- integrity sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==
- dependencies:
- defer-to-connect "^1.0.1"
-
-"@types/node@^14.6.2":
- version "14.18.20"
- resolved "https://registry.yarnpkg.com/@types/node/-/node-14.18.20.tgz#268f028b36eaf51181c3300252f605488c4f0650"
- integrity sha512-Q8KKwm9YqEmUBRsqJ2GWJDtXltBDxTdC4m5vTdXBolu2PeQh8LX+f6BTwU+OuXPu37fLxoN6gidqBmnky36FXA==
-
-async-lock@^1.2.8:
- version "1.2.8"
- resolved "https://registry.yarnpkg.com/async-lock/-/async-lock-1.2.8.tgz#7b02bdfa2de603c0713acecd11184cf97bbc7c4c"
- integrity sha512-G+26B2jc0Gw0EG/WN2M6IczuGepBsfR1+DtqLnyFSH4p2C668qkOCtEkGNVEaaNAVlYwEMazy1+/jnLxltBkIQ==
-
-boolean@^3.0.1:
- version "3.0.2"
- resolved "https://registry.yarnpkg.com/boolean/-/boolean-3.0.2.tgz#df1baa18b6a2b0e70840475e1d93ec8fe75b2570"
- integrity sha512-RwywHlpCRc3/Wh81MiCKun4ydaIFyW5Ea6JbL6sRCVx5q5irDw7pMXBUFYF/jArQ6YrG36q0kpovc9P/Kd3I4g==
-
-buffer-crc32@~0.2.3:
- version "0.2.13"
- resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242"
- integrity sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=
-
-buffer-from@^1.0.0:
- version "1.1.1"
- resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef"
- integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==
-
-cacheable-request@^6.0.0:
- version "6.1.0"
- resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-6.1.0.tgz#20ffb8bd162ba4be11e9567d823db651052ca912"
- integrity sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==
- dependencies:
- clone-response "^1.0.2"
- get-stream "^5.1.0"
- http-cache-semantics "^4.0.0"
- keyv "^3.0.0"
- lowercase-keys "^2.0.0"
- normalize-url "^4.1.0"
- responselike "^1.0.2"
-
-clone-response@^1.0.2:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b"
- integrity sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=
- dependencies:
- mimic-response "^1.0.0"
-
-concat-stream@^1.6.2:
- version "1.6.2"
- resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34"
- integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==
- dependencies:
- buffer-from "^1.0.0"
- inherits "^2.0.3"
- readable-stream "^2.2.2"
- typedarray "^0.0.6"
-
-config-chain@^1.1.11:
- version "1.1.12"
- resolved "https://registry.yarnpkg.com/config-chain/-/config-chain-1.1.12.tgz#0fde8d091200eb5e808caf25fe618c02f48e4efa"
- integrity sha512-a1eOIcu8+7lUInge4Rpf/n4Krkf3Dd9lqhljRzII1/Zno/kRtUWnznPO3jOKBmTEktkt3fkxisUcivoj0ebzoA==
- dependencies:
- ini "^1.3.4"
- proto-list "~1.2.1"
-
-core-util-is@~1.0.0:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
- integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=
-
-debug@^2.6.9:
- version "2.6.9"
- resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
- integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==
- dependencies:
- ms "2.0.0"
-
-debug@^4.1.0, debug@^4.1.1:
- version "4.3.1"
- resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee"
- integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==
- dependencies:
- ms "2.1.2"
-
-decompress-response@^3.3.0:
- version "3.3.0"
- resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3"
- integrity sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=
- dependencies:
- mimic-response "^1.0.0"
-
-defer-to-connect@^1.0.1:
- version "1.1.3"
- resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-1.1.3.tgz#331ae050c08dcf789f8c83a7b81f0ed94f4ac591"
- integrity sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==
-
-define-properties@^1.1.3:
- version "1.1.3"
- resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1"
- integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==
- dependencies:
- object-keys "^1.0.12"
-
-detect-node@^2.0.4:
- version "2.0.4"
- resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.0.4.tgz#014ee8f8f669c5c58023da64b8179c083a28c46c"
- integrity sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==
-
-duplexer3@^0.1.4:
- version "0.1.4"
- resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2"
- integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=
-
-electron-window-state@^5.0.3:
- version "5.0.3"
- resolved "https://registry.yarnpkg.com/electron-window-state/-/electron-window-state-5.0.3.tgz#4f36d09e3f953d87aff103bf010f460056050aa8"
- integrity sha512-1mNTwCfkolXl3kMf50yW3vE2lZj0y92P/HYWFBrb+v2S/pCka5mdwN3cagKm458A7NjndSwijynXgcLWRodsVg==
- dependencies:
- jsonfile "^4.0.0"
- mkdirp "^0.5.1"
-
-electron@16.2.8:
- version "16.2.8"
- resolved "https://registry.yarnpkg.com/electron/-/electron-16.2.8.tgz#b7f2bd1184701e54a1bc902839d5a3ec95bb8982"
- integrity sha512-KSOytY6SPLsh3iCziztqa/WgJyfDOKzCvNqku9gGIqSdT8CqtV66dTU1SOrKZQjRFLxHaF8LbyxUL1vwe4taqw==
- dependencies:
- "@electron/get" "^1.13.0"
- "@types/node" "^14.6.2"
- extract-zip "^1.0.3"
-
-encodeurl@^1.0.2:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
- integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=
-
-end-of-stream@^1.1.0:
- version "1.4.4"
- resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0"
- integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==
- dependencies:
- once "^1.4.0"
-
-env-paths@^2.2.0:
- version "2.2.1"
- resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2"
- integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==
-
-es6-error@^4.1.1:
- version "4.1.1"
- resolved "https://registry.yarnpkg.com/es6-error/-/es6-error-4.1.1.tgz#9e3af407459deed47e9a91f9b885a84eb05c561d"
- integrity sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==
-
-escape-string-regexp@^4.0.0:
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34"
- integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==
-
-extract-zip@^1.0.3:
- version "1.7.0"
- resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-1.7.0.tgz#556cc3ae9df7f452c493a0cfb51cc30277940927"
- integrity sha512-xoh5G1W/PB0/27lXgMQyIhP5DSY/LhoCsOyZgb+6iMmRtCwVBo55uKaMoEYrDCKQhWvqEip5ZPKAc6eFNyf/MA==
- dependencies:
- concat-stream "^1.6.2"
- debug "^2.6.9"
- mkdirp "^0.5.4"
- yauzl "^2.10.0"
-
-fd-slicer@~1.1.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e"
- integrity sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=
- dependencies:
- pend "~1.2.0"
-
-fs-extra@^8.1.0:
- version "8.1.0"
- resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0"
- integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==
- dependencies:
- graceful-fs "^4.2.0"
- jsonfile "^4.0.0"
- universalify "^0.1.0"
-
-get-stream@^4.1.0:
- version "4.1.0"
- resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5"
- integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==
- dependencies:
- pump "^3.0.0"
-
-get-stream@^5.1.0:
- version "5.2.0"
- resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3"
- integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==
- dependencies:
- pump "^3.0.0"
-
-global-agent@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/global-agent/-/global-agent-3.0.0.tgz#ae7cd31bd3583b93c5a16437a1afe27cc33a1ab6"
- integrity sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==
- dependencies:
- boolean "^3.0.1"
- es6-error "^4.1.1"
- matcher "^3.0.0"
- roarr "^2.15.3"
- semver "^7.3.2"
- serialize-error "^7.0.1"
-
-global-tunnel-ng@^2.7.1:
- version "2.7.1"
- resolved "https://registry.yarnpkg.com/global-tunnel-ng/-/global-tunnel-ng-2.7.1.tgz#d03b5102dfde3a69914f5ee7d86761ca35d57d8f"
- integrity sha512-4s+DyciWBV0eK148wqXxcmVAbFVPqtc3sEtUE/GTQfuU80rySLcMhUmHKSHI7/LDj8q0gDYI1lIhRRB7ieRAqg==
- dependencies:
- encodeurl "^1.0.2"
- lodash "^4.17.10"
- npm-conf "^1.1.3"
- tunnel "^0.0.6"
-
-globalthis@^1.0.1:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.2.tgz#2a235d34f4d8036219f7e34929b5de9e18166b8b"
- integrity sha512-ZQnSFO1la8P7auIOQECnm0sSuoMeaSq0EEdXMBFF2QJO4uNcwbyhSgG3MruWNbFTqCLmxVwGOl7LZ9kASvHdeQ==
- dependencies:
- define-properties "^1.1.3"
-
-got@^9.6.0:
- version "9.6.0"
- resolved "https://registry.yarnpkg.com/got/-/got-9.6.0.tgz#edf45e7d67f99545705de1f7bbeeeb121765ed85"
- integrity sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==
- dependencies:
- "@sindresorhus/is" "^0.14.0"
- "@szmarczak/http-timer" "^1.1.2"
- cacheable-request "^6.0.0"
- decompress-response "^3.3.0"
- duplexer3 "^0.1.4"
- get-stream "^4.1.0"
- lowercase-keys "^1.0.1"
- mimic-response "^1.0.1"
- p-cancelable "^1.0.0"
- to-readable-stream "^1.0.0"
- url-parse-lax "^3.0.0"
-
-graceful-fs@^4.1.6, graceful-fs@^4.2.0:
- version "4.2.6"
- resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee"
- integrity sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==
-
-http-cache-semantics@^4.0.0:
- version "4.1.0"
- resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390"
- integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==
-
-inherits@^2.0.3, inherits@~2.0.3:
- version "2.0.4"
- resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
- integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
-
-ini@^1.3.4:
- version "1.3.8"
- resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c"
- integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==
-
-isarray@~1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
- integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=
-
-json-buffer@3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898"
- integrity sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=
-
-json-stringify-safe@^5.0.1:
- version "5.0.1"
- resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
- integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=
-
-jsonfile@^4.0.0:
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb"
- integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=
- optionalDependencies:
- graceful-fs "^4.1.6"
-
-keyv@^3.0.0:
- version "3.1.0"
- resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.1.0.tgz#ecc228486f69991e49e9476485a5be1e8fc5c4d9"
- integrity sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==
- dependencies:
- json-buffer "3.0.0"
-
-lodash@^4.17.10:
- version "4.17.21"
- resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
- integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
-
-lowercase-keys@^1.0.0, lowercase-keys@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f"
- integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==
-
-lowercase-keys@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479"
- integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==
-
-lru-cache@^6.0.0:
- version "6.0.0"
- resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94"
- integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==
- dependencies:
- yallist "^4.0.0"
-
-matcher@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/matcher/-/matcher-3.0.0.tgz#bd9060f4c5b70aa8041ccc6f80368760994f30ca"
- integrity sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==
- dependencies:
- escape-string-regexp "^4.0.0"
-
-mimic-response@^1.0.0, mimic-response@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b"
- integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==
-
-minimist@^1.2.5:
- version "1.2.5"
- resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
- integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
-
-mkdirp@^0.5.1, mkdirp@^0.5.4:
- version "0.5.5"
- resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def"
- integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==
- dependencies:
- minimist "^1.2.5"
-
-ms@2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
- integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=
-
-ms@2.1.2:
- version "2.1.2"
- resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
- integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
-
-normalize-url@^4.1.0:
- version "4.5.0"
- resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.0.tgz#453354087e6ca96957bd8f5baf753f5982142129"
- integrity sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==
-
-npm-conf@^1.1.3:
- version "1.1.3"
- resolved "https://registry.yarnpkg.com/npm-conf/-/npm-conf-1.1.3.tgz#256cc47bd0e218c259c4e9550bf413bc2192aff9"
- integrity sha512-Yic4bZHJOt9RCFbRP3GgpqhScOY4HH3V2P8yBj6CeYq118Qr+BLXqT2JvpJ00mryLESpgOxf5XlFv4ZjXxLScw==
- dependencies:
- config-chain "^1.1.11"
- pify "^3.0.0"
-
-object-keys@^1.0.12:
- version "1.1.1"
- resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e"
- integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==
-
-once@^1.3.1, once@^1.4.0:
- version "1.4.0"
- resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
- integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E=
- dependencies:
- wrappy "1"
-
-p-cancelable@^1.0.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-1.1.0.tgz#d078d15a3af409220c886f1d9a0ca2e441ab26cc"
- integrity sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==
-
-pend@~1.2.0:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50"
- integrity sha1-elfrVQpng/kRUzH89GY9XI4AelA=
-
-pify@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176"
- integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=
-
-prepend-http@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897"
- integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=
-
-process-nextick-args@~2.0.0:
- version "2.0.1"
- resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2"
- integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==
-
-progress@^2.0.3:
- version "2.0.3"
- resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8"
- integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==
-
-proto-list@~1.2.1:
- version "1.2.4"
- resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849"
- integrity sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk=
-
-pump@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64"
- integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==
- dependencies:
- end-of-stream "^1.1.0"
- once "^1.3.1"
-
-readable-stream@^2.2.2:
- version "2.3.7"
- resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57"
- integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==
- dependencies:
- core-util-is "~1.0.0"
- inherits "~2.0.3"
- isarray "~1.0.0"
- process-nextick-args "~2.0.0"
- safe-buffer "~5.1.1"
- string_decoder "~1.1.1"
- util-deprecate "~1.0.1"
-
-responselike@^1.0.2:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7"
- integrity sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=
- dependencies:
- lowercase-keys "^1.0.0"
-
-roarr@^2.15.3:
- version "2.15.4"
- resolved "https://registry.yarnpkg.com/roarr/-/roarr-2.15.4.tgz#f5fe795b7b838ccfe35dc608e0282b9eba2e7afd"
- integrity sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==
- dependencies:
- boolean "^3.0.1"
- detect-node "^2.0.4"
- globalthis "^1.0.1"
- json-stringify-safe "^5.0.1"
- semver-compare "^1.0.0"
- sprintf-js "^1.1.2"
-
-safe-buffer@~5.1.0, safe-buffer@~5.1.1:
- version "5.1.2"
- resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
- integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
-
-semver-compare@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc"
- integrity sha1-De4hahyUGrN+nvsXiPavxf9VN/w=
-
-semver@^6.2.0:
- version "6.3.0"
- resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d"
- integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==
-
-semver@^7.3.2:
- version "7.3.4"
- resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.4.tgz#27aaa7d2e4ca76452f98d3add093a72c943edc97"
- integrity sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==
- dependencies:
- lru-cache "^6.0.0"
-
-serialize-error@^7.0.1:
- version "7.0.1"
- resolved "https://registry.yarnpkg.com/serialize-error/-/serialize-error-7.0.1.tgz#f1360b0447f61ffb483ec4157c737fab7d778e18"
- integrity sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==
- dependencies:
- type-fest "^0.13.1"
-
-sprintf-js@^1.1.2:
- version "1.1.2"
- resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.1.2.tgz#da1765262bf8c0f571749f2ad6c26300207ae673"
- integrity sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==
-
-string_decoder@~1.1.1:
- version "1.1.1"
- resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8"
- integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==
- dependencies:
- safe-buffer "~5.1.0"
-
-sumchecker@^3.0.1:
- version "3.0.1"
- resolved "https://registry.yarnpkg.com/sumchecker/-/sumchecker-3.0.1.tgz#6377e996795abb0b6d348e9b3e1dfb24345a8e42"
- integrity sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==
- dependencies:
- debug "^4.1.0"
-
-to-readable-stream@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/to-readable-stream/-/to-readable-stream-1.0.0.tgz#ce0aa0c2f3df6adf852efb404a783e77c0475771"
- integrity sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==
-
-tunnel@^0.0.6:
- version "0.0.6"
- resolved "https://registry.yarnpkg.com/tunnel/-/tunnel-0.0.6.tgz#72f1314b34a5b192db012324df2cc587ca47f92c"
- integrity sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==
-
-type-fest@^0.13.1:
- version "0.13.1"
- resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.13.1.tgz#0172cb5bce80b0bd542ea348db50c7e21834d934"
- integrity sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==
-
-typedarray@^0.0.6:
- version "0.0.6"
- resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
- integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=
-
-universalify@^0.1.0:
- version "0.1.2"
- resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66"
- integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==
-
-url-parse-lax@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-3.0.0.tgz#16b5cafc07dbe3676c1b1999177823d6503acb0c"
- integrity sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=
- dependencies:
- prepend-http "^2.0.0"
-
-util-deprecate@~1.0.1:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
- integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=
-
-wrappy@1:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
- integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
-
-yallist@^4.0.0:
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"
- integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
-
-yauzl@^2.10.0:
- version "2.10.0"
- resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9"
- integrity sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=
- dependencies:
- buffer-crc32 "~0.2.3"
- fd-slicer "~1.1.0"
diff --git a/electron_wegame/.gitignore b/electron_wegame/.gitignore
deleted file mode 100644
index 475a7c75..00000000
--- a/electron_wegame/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-wegame_sdk
diff --git a/electron_wegame/README.md b/electron_wegame/README.md
deleted file mode 100644
index 70736caf..00000000
--- a/electron_wegame/README.md
+++ /dev/null
@@ -1 +0,0 @@
-To build, place the lib64 folder from the wegame sdk for electron 13 in `wegame_sdk` and run the `wegame.main.standalone` gulp task.
diff --git a/electron_wegame/electron_wegame.code-workspace b/electron_wegame/electron_wegame.code-workspace
deleted file mode 100644
index fc9ab864..00000000
--- a/electron_wegame/electron_wegame.code-workspace
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "folders": [
- {
- "path": "."
- }
- ],
- "settings": {
- "files.exclude": {
- "**/node_modules": true,
- "**/typedefs_gen": true
- }
- }
-}
\ No newline at end of file
diff --git a/electron_wegame/favicon.icns b/electron_wegame/favicon.icns
deleted file mode 100644
index 79e141a5..00000000
Binary files a/electron_wegame/favicon.icns and /dev/null differ
diff --git a/electron_wegame/favicon.ico b/electron_wegame/favicon.ico
deleted file mode 100644
index 81a9aa5c..00000000
Binary files a/electron_wegame/favicon.ico and /dev/null differ
diff --git a/electron_wegame/favicon.png b/electron_wegame/favicon.png
deleted file mode 100644
index c837c787..00000000
Binary files a/electron_wegame/favicon.png and /dev/null differ
diff --git a/electron_wegame/index.js b/electron_wegame/index.js
deleted file mode 100644
index 2c183f15..00000000
--- a/electron_wegame/index.js
+++ /dev/null
@@ -1,253 +0,0 @@
-/* eslint-disable quotes,no-undef */
-
-const { app, BrowserWindow, Menu, MenuItem, ipcMain, shell } = require("electron");
-
-app.commandLine.appendSwitch("in-process-gpu");
-
-const path = require("path");
-const url = require("url");
-const fs = require("fs");
-const wegame = require("./wegame");
-const asyncLock = require("async-lock");
-
-const isDev = process.argv.indexOf("--dev") >= 0;
-const isLocal = process.argv.indexOf("--local") >= 0;
-
-const roamingFolder =
- process.env.APPDATA ||
- (process.platform == "darwin"
- ? process.env.HOME + "/Library/Preferences"
- : process.env.HOME + "/.local/share");
-let storePath = path.join(roamingFolder, "shapez.io", "saves");
-
-if (!fs.existsSync(storePath)) {
- // No try-catch by design
- fs.mkdirSync(storePath, { recursive: true });
-}
-
-/** @type {BrowserWindow} */
-let win = null;
-let menu = null;
-
-function createWindow() {
- let faviconExtension = ".png";
- if (process.platform === "win32") {
- faviconExtension = ".ico";
- }
-
- win = new BrowserWindow({
- width: 1280,
- height: 800,
- show: false,
- backgroundColor: "#222428",
- useContentSize: true,
- minWidth: 800,
- minHeight: 600,
- title: "图形工厂",
- transparent: false,
- icon: path.join(__dirname, "favicon" + faviconExtension),
- // fullscreen: true,
- autoHideMenuBar: true,
- webPreferences: {
- nodeIntegration: false,
- webSecurity: true,
- sandbox: true,
-
- contextIsolation: true,
- preload: path.join(__dirname, "preload.js"),
- },
- allowRunningInsecureContent: false,
- });
-
- if (isLocal) {
- win.loadURL("http://localhost:3005");
- } else {
- win.loadURL(
- url.format({
- pathname: path.join(__dirname, "index.html"),
- protocol: "file:",
- slashes: true,
- })
- );
- }
- win.webContents.session.clearCache(() => null);
- win.webContents.session.clearStorageData();
-
- win.webContents.on("new-window", (event, pth) => {
- event.preventDefault();
- shell.openExternal(pth);
- });
-
- win.on("closed", () => {
- console.log("Window closed");
- win = null;
- });
-
- if (isDev) {
- menu = new Menu();
-
- const mainItem = new MenuItem({
- label: "Toggle Dev Tools",
- click: () => win.webContents.toggleDevTools(),
- accelerator: "F12",
- });
- menu.append(mainItem);
-
- const reloadItem = new MenuItem({
- label: "Restart",
- click: () => win.reload(),
- accelerator: "F5",
- });
- menu.append(reloadItem);
-
- const fullscreenItem = new MenuItem({
- label: "Fullscreen",
- click: () => win.setFullScreen(!win.isFullScreen()),
- accelerator: "F11",
- });
- menu.append(fullscreenItem);
-
- Menu.setApplicationMenu(menu);
- } else {
- Menu.setApplicationMenu(null);
- }
-
- win.once("ready-to-show", () => {
- win.show();
- win.focus();
- });
-}
-
-if (!app.requestSingleInstanceLock()) {
- app.exit(0);
-} else {
- app.on("second-instance", (event, commandLine, workingDirectory) => {
- // Someone tried to run a second instance, we should focus
- if (win) {
- if (win.isMinimized()) {
- win.restore();
- }
- win.focus();
- }
- });
-}
-
-app.on("ready", createWindow);
-
-app.on("window-all-closed", () => {
- console.log("All windows closed");
- app.quit();
-});
-
-ipcMain.on("set-fullscreen", (event, flag) => {
- win.setFullScreen(flag);
-});
-
-ipcMain.on("exit-app", (event, flag) => {
- win.close();
- app.quit();
-});
-
-let renameCounter = 1;
-
-const fileLock = new asyncLock({
- timeout: 30000,
- maxPending: 1000,
-});
-
-function niceFileName(filename) {
- return filename.replace(storePath, "@");
-}
-
-async function writeFileSafe(filename, contents) {
- ++renameCounter;
- const prefix = "[ " + renameCounter + ":" + niceFileName(filename) + " ] ";
- const transactionId = String(new Date().getTime()) + "." + renameCounter;
-
- if (fileLock.isBusy()) {
- console.warn(prefix, "Concurrent write process on", filename);
- }
-
- fileLock.acquire(filename, async () => {
- console.log(prefix, "Starting write on", niceFileName(filename), "in transaction", transactionId);
-
- if (!fs.existsSync(filename)) {
- // this one is easy
- console.log(prefix, "Writing file instantly because it does not exist:", niceFileName(filename));
- await fs.promises.writeFile(filename, contents, "utf8");
- return;
- }
-
- // first, write a temporary file (.tmp-XXX)
- const tempName = filename + ".tmp-" + transactionId;
- console.log(prefix, "Writing temporary file", niceFileName(tempName));
- await fs.promises.writeFile(tempName, contents, "utf8");
-
- // now, rename the original file to (.backup-XXX)
- const oldTemporaryName = filename + ".backup-" + transactionId;
- console.log(
- prefix,
- "Renaming old file",
- niceFileName(filename),
- "to",
- niceFileName(oldTemporaryName)
- );
- await fs.promises.rename(filename, oldTemporaryName);
-
- // now, rename the temporary file (.tmp-XXX) to the target
- console.log(
- prefix,
- "Renaming the temporary file",
- niceFileName(tempName),
- "to the original",
- niceFileName(filename)
- );
- await fs.promises.rename(tempName, filename);
-
- // we are done now, try to create a backup, but don't fail if the backup fails
- try {
- // check if there is an old backup file
- const backupFileName = filename + ".backup";
- if (fs.existsSync(backupFileName)) {
- console.log(prefix, "Deleting old backup file", niceFileName(backupFileName));
- // delete the old backup
- await fs.promises.unlink(backupFileName);
- }
-
- // rename the old file to the new backup file
- console.log(prefix, "Moving", niceFileName(oldTemporaryName), "to the backup file location");
- await fs.promises.rename(oldTemporaryName, backupFileName);
- } catch (ex) {
- console.error(prefix, "Failed to switch backup files:", ex);
- }
- });
-}
-
-ipcMain.handle("fs-job", async (event, job) => {
- const filenameSafe = job.filename.replace(/[^a-z\.\-_0-9]/i, "");
- const fname = path.join(storePath, filenameSafe);
- switch (job.type) {
- case "read": {
- if (!fs.existsSync(fname)) {
- // Special FILE_NOT_FOUND error code
- return { error: "file_not_found" };
- }
- return await fs.promises.readFile(fname, "utf8");
- }
- case "write": {
- await writeFileSafe(fname, job.contents);
- return job.contents;
- }
-
- case "delete": {
- await fs.promises.unlink(fname);
- return;
- }
-
- default:
- throw new Error("Unknown fs job: " + job.type);
- }
-});
-
-wegame.init(isDev);
-wegame.listen();
diff --git a/electron_wegame/package.json b/electron_wegame/package.json
deleted file mode 100644
index aba5bb6a..00000000
--- a/electron_wegame/package.json
+++ /dev/null
@@ -1,18 +0,0 @@
-{
- "name": "electron",
- "version": "1.0.0",
- "main": "index.js",
- "license": "MIT",
- "private": true,
- "scripts": {
- "startDev": "electron --disable-direct-composition --in-process-gpu . --dev --local",
- "startDevGpu": "electron --enable-gpu-rasterization --enable-accelerated-2d-canvas --num-raster-threads=8 --enable-zero-copy . --dev --local",
- "start": "electron --disable-direct-composition --in-process-gpu ."
- },
- "devDependencies": {
- "electron": "^13.1.6"
- },
- "dependencies": {
- "async-lock": "^1.2.8"
- }
-}
diff --git a/electron_wegame/wegame.js b/electron_wegame/wegame.js
deleted file mode 100644
index 05a0e186..00000000
--- a/electron_wegame/wegame.js
+++ /dev/null
@@ -1,63 +0,0 @@
-const railsdk = require("./wegame_sdk/railsdk.js");
-const { dialog, app, remote, ipcMain } = require("electron");
-
-function init(isDev) {
- console.log("Step 1: wegame: init");
-
- try {
- console.log("Step 2: Calling need restart app");
- const need_restart = railsdk.RailNeedRestartAppForCheckingEnvironment(
- 2001639,
- [`--rail_render_pid=${process.pid}`] //,"--rail_debug_mode",
- );
- console.log("Step 3: Needs restart =", need_restart);
- if (need_restart) {
- console.error("Step 4: Need restart");
- dialog.showErrorBox("加载RailSDK失败", "请先运行WeGame开发者版本");
- return;
- }
- } catch (err) {
- console.error("Rail SDK error:", err);
- dialog.showErrorBox("加载RailSDK失败", err);
- return;
- }
-
- console.log("Step 5: starting rail sdk");
- if (railsdk.RailInitialize() === false) {
- console.error("RailInitialize() = false");
- dialog.showErrorBox("RailInitialize调用失败", "请先运行WeGame开发者版本");
- return;
- }
-
- console.log("Initialize RailSDK success!");
-
- railsdk.RailRegisterEvent(railsdk.RailEventID.kRailEventSystemStateChanged, event => {
- console.log(event);
- if (event.result === railsdk.RailResult.kSuccess) {
- if (
- event.state === railsdk.RailSystemState.kSystemStatePlatformOffline ||
- event.state === railsdk.RailSystemState.kSystemStatePlatformExit ||
- event.state === railsdk.RailSystemState.kSystemStateGameExitByAntiAddiction
- ) {
- app.exit();
- }
- }
- });
-}
-
-function listen() {
- console.log("wegame: listen");
- ipcMain.handle("profanity-check", async (event, data) => {
- if (data.length === 0) {
- return "";
- }
- const result = railsdk.RailUtils.DirtyWordsFilter(data, true);
- if (result.check_result.dirty_type !== 0 /** kRailDirtyWordsTypeNormalAllowWords */) {
- return result.check_result.replace_string;
- }
-
- return data;
- });
-}
-
-module.exports = { init, listen };
diff --git a/electron_wegame/yarn.lock b/electron_wegame/yarn.lock
deleted file mode 100644
index 69c595ea..00000000
--- a/electron_wegame/yarn.lock
+++ /dev/null
@@ -1,578 +0,0 @@
-# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
-# yarn lockfile v1
-
-
-"@electron/get@^1.0.1":
- version "1.12.4"
- resolved "https://registry.yarnpkg.com/@electron/get/-/get-1.12.4.tgz#a5971113fc1bf8fa12a8789dc20152a7359f06ab"
- integrity sha512-6nr9DbJPUR9Xujw6zD3y+rS95TyItEVM0NVjt1EehY2vUWfIgPiIPVHxCvaTS0xr2B+DRxovYVKbuOWqC35kjg==
- dependencies:
- debug "^4.1.1"
- env-paths "^2.2.0"
- fs-extra "^8.1.0"
- got "^9.6.0"
- progress "^2.0.3"
- semver "^6.2.0"
- sumchecker "^3.0.1"
- optionalDependencies:
- global-agent "^2.0.2"
- global-tunnel-ng "^2.7.1"
-
-"@sindresorhus/is@^0.14.0":
- version "0.14.0"
- resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea"
- integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==
-
-"@szmarczak/http-timer@^1.1.2":
- version "1.1.2"
- resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421"
- integrity sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==
- dependencies:
- defer-to-connect "^1.0.1"
-
-"@types/node@^14.6.2":
- version "14.17.4"
- resolved "https://registry.yarnpkg.com/@types/node/-/node-14.17.4.tgz#218712242446fc868d0e007af29a4408c7765bc0"
- integrity sha512-8kQ3+wKGRNN0ghtEn7EGps/B8CzuBz1nXZEIGGLP2GnwbqYn4dbTs7k+VKLTq1HvZLRCIDtN3Snx1Ege8B7L5A==
-
-async-lock@^1.2.8:
- version "1.2.8"
- resolved "https://registry.yarnpkg.com/async-lock/-/async-lock-1.2.8.tgz#7b02bdfa2de603c0713acecd11184cf97bbc7c4c"
- integrity sha512-G+26B2jc0Gw0EG/WN2M6IczuGepBsfR1+DtqLnyFSH4p2C668qkOCtEkGNVEaaNAVlYwEMazy1+/jnLxltBkIQ==
-
-boolean@^3.0.1:
- version "3.1.2"
- resolved "https://registry.yarnpkg.com/boolean/-/boolean-3.1.2.tgz#e30f210a26b02458482a8cc353ab06f262a780c2"
- integrity sha512-YN6UmV0FfLlBVvRvNPx3pz5W/mUoYB24J4WSXOKP/OOJpi+Oq6WYqPaNTHzjI0QzwWtnvEd5CGYyQPgp1jFxnw==
-
-buffer-crc32@~0.2.3:
- version "0.2.13"
- resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242"
- integrity sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=
-
-buffer-from@^1.0.0:
- version "1.1.1"
- resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef"
- integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==
-
-cacheable-request@^6.0.0:
- version "6.1.0"
- resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-6.1.0.tgz#20ffb8bd162ba4be11e9567d823db651052ca912"
- integrity sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==
- dependencies:
- clone-response "^1.0.2"
- get-stream "^5.1.0"
- http-cache-semantics "^4.0.0"
- keyv "^3.0.0"
- lowercase-keys "^2.0.0"
- normalize-url "^4.1.0"
- responselike "^1.0.2"
-
-clone-response@^1.0.2:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b"
- integrity sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=
- dependencies:
- mimic-response "^1.0.0"
-
-concat-stream@^1.6.2:
- version "1.6.2"
- resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34"
- integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==
- dependencies:
- buffer-from "^1.0.0"
- inherits "^2.0.3"
- readable-stream "^2.2.2"
- typedarray "^0.0.6"
-
-config-chain@^1.1.11:
- version "1.1.13"
- resolved "https://registry.yarnpkg.com/config-chain/-/config-chain-1.1.13.tgz#fad0795aa6a6cdaff9ed1b68e9dff94372c232f4"
- integrity sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==
- dependencies:
- ini "^1.3.4"
- proto-list "~1.2.1"
-
-core-js@^3.6.5:
- version "3.15.2"
- resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.15.2.tgz#740660d2ff55ef34ce664d7e2455119c5bdd3d61"
- integrity sha512-tKs41J7NJVuaya8DxIOCnl8QuPHx5/ZVbFo1oKgVl1qHFBBrDctzQGtuLjPpRdNTWmKPH6oEvgN/MUID+l485Q==
-
-core-util-is@~1.0.0:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
- integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=
-
-debug@^2.6.9:
- version "2.6.9"
- resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
- integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==
- dependencies:
- ms "2.0.0"
-
-debug@^4.1.0, debug@^4.1.1:
- version "4.3.2"
- resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b"
- integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==
- dependencies:
- ms "2.1.2"
-
-decompress-response@^3.3.0:
- version "3.3.0"
- resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3"
- integrity sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=
- dependencies:
- mimic-response "^1.0.0"
-
-defer-to-connect@^1.0.1:
- version "1.1.3"
- resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-1.1.3.tgz#331ae050c08dcf789f8c83a7b81f0ed94f4ac591"
- integrity sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==
-
-define-properties@^1.1.3:
- version "1.1.3"
- resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1"
- integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==
- dependencies:
- object-keys "^1.0.12"
-
-detect-node@^2.0.4:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.1.0.tgz#c9c70775a49c3d03bc2c06d9a73be550f978f8b1"
- integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==
-
-duplexer3@^0.1.4:
- version "0.1.4"
- resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2"
- integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=
-
-electron@^13.1.6:
- version "13.1.6"
- resolved "https://registry.yarnpkg.com/electron/-/electron-13.1.6.tgz#6ecaf969255d62ce82cc0b5c948bf26e7dfb489b"
- integrity sha512-XiB55/JTaQpDFQrD9pulYnOGwaWeMyRIub5ispvoE2bWBvM5zVMLptwMLb0m3KTMrfSkzhedZvOu7fwYvR7L7Q==
- dependencies:
- "@electron/get" "^1.0.1"
- "@types/node" "^14.6.2"
- extract-zip "^1.0.3"
-
-encodeurl@^1.0.2:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
- integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=
-
-end-of-stream@^1.1.0:
- version "1.4.4"
- resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0"
- integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==
- dependencies:
- once "^1.4.0"
-
-env-paths@^2.2.0:
- version "2.2.1"
- resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2"
- integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==
-
-es6-error@^4.1.1:
- version "4.1.1"
- resolved "https://registry.yarnpkg.com/es6-error/-/es6-error-4.1.1.tgz#9e3af407459deed47e9a91f9b885a84eb05c561d"
- integrity sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==
-
-escape-string-regexp@^4.0.0:
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34"
- integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==
-
-extract-zip@^1.0.3:
- version "1.7.0"
- resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-1.7.0.tgz#556cc3ae9df7f452c493a0cfb51cc30277940927"
- integrity sha512-xoh5G1W/PB0/27lXgMQyIhP5DSY/LhoCsOyZgb+6iMmRtCwVBo55uKaMoEYrDCKQhWvqEip5ZPKAc6eFNyf/MA==
- dependencies:
- concat-stream "^1.6.2"
- debug "^2.6.9"
- mkdirp "^0.5.4"
- yauzl "^2.10.0"
-
-fd-slicer@~1.1.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e"
- integrity sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=
- dependencies:
- pend "~1.2.0"
-
-fs-extra@^8.1.0:
- version "8.1.0"
- resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0"
- integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==
- dependencies:
- graceful-fs "^4.2.0"
- jsonfile "^4.0.0"
- universalify "^0.1.0"
-
-get-stream@^4.1.0:
- version "4.1.0"
- resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5"
- integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==
- dependencies:
- pump "^3.0.0"
-
-get-stream@^5.1.0:
- version "5.2.0"
- resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3"
- integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==
- dependencies:
- pump "^3.0.0"
-
-global-agent@^2.0.2:
- version "2.2.0"
- resolved "https://registry.yarnpkg.com/global-agent/-/global-agent-2.2.0.tgz#566331b0646e6bf79429a16877685c4a1fbf76dc"
- integrity sha512-+20KpaW6DDLqhG7JDiJpD1JvNvb8ts+TNl7BPOYcURqCrXqnN1Vf+XVOrkKJAFPqfX+oEhsdzOj1hLWkBTdNJg==
- dependencies:
- boolean "^3.0.1"
- core-js "^3.6.5"
- es6-error "^4.1.1"
- matcher "^3.0.0"
- roarr "^2.15.3"
- semver "^7.3.2"
- serialize-error "^7.0.1"
-
-global-tunnel-ng@^2.7.1:
- version "2.7.1"
- resolved "https://registry.yarnpkg.com/global-tunnel-ng/-/global-tunnel-ng-2.7.1.tgz#d03b5102dfde3a69914f5ee7d86761ca35d57d8f"
- integrity sha512-4s+DyciWBV0eK148wqXxcmVAbFVPqtc3sEtUE/GTQfuU80rySLcMhUmHKSHI7/LDj8q0gDYI1lIhRRB7ieRAqg==
- dependencies:
- encodeurl "^1.0.2"
- lodash "^4.17.10"
- npm-conf "^1.1.3"
- tunnel "^0.0.6"
-
-globalthis@^1.0.1:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.2.tgz#2a235d34f4d8036219f7e34929b5de9e18166b8b"
- integrity sha512-ZQnSFO1la8P7auIOQECnm0sSuoMeaSq0EEdXMBFF2QJO4uNcwbyhSgG3MruWNbFTqCLmxVwGOl7LZ9kASvHdeQ==
- dependencies:
- define-properties "^1.1.3"
-
-got@^9.6.0:
- version "9.6.0"
- resolved "https://registry.yarnpkg.com/got/-/got-9.6.0.tgz#edf45e7d67f99545705de1f7bbeeeb121765ed85"
- integrity sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==
- dependencies:
- "@sindresorhus/is" "^0.14.0"
- "@szmarczak/http-timer" "^1.1.2"
- cacheable-request "^6.0.0"
- decompress-response "^3.3.0"
- duplexer3 "^0.1.4"
- get-stream "^4.1.0"
- lowercase-keys "^1.0.1"
- mimic-response "^1.0.1"
- p-cancelable "^1.0.0"
- to-readable-stream "^1.0.0"
- url-parse-lax "^3.0.0"
-
-graceful-fs@^4.1.6, graceful-fs@^4.2.0:
- version "4.2.6"
- resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee"
- integrity sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==
-
-http-cache-semantics@^4.0.0:
- version "4.1.0"
- resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390"
- integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==
-
-inherits@^2.0.3, inherits@~2.0.3:
- version "2.0.4"
- resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
- integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
-
-ini@^1.3.4:
- version "1.3.8"
- resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c"
- integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==
-
-isarray@~1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
- integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=
-
-json-buffer@3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898"
- integrity sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=
-
-json-stringify-safe@^5.0.1:
- version "5.0.1"
- resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
- integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=
-
-jsonfile@^4.0.0:
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb"
- integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=
- optionalDependencies:
- graceful-fs "^4.1.6"
-
-keyv@^3.0.0:
- version "3.1.0"
- resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.1.0.tgz#ecc228486f69991e49e9476485a5be1e8fc5c4d9"
- integrity sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==
- dependencies:
- json-buffer "3.0.0"
-
-lodash@^4.17.10:
- version "4.17.21"
- resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
- integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
-
-lowercase-keys@^1.0.0, lowercase-keys@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f"
- integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==
-
-lowercase-keys@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479"
- integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==
-
-lru-cache@^6.0.0:
- version "6.0.0"
- resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94"
- integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==
- dependencies:
- yallist "^4.0.0"
-
-matcher@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/matcher/-/matcher-3.0.0.tgz#bd9060f4c5b70aa8041ccc6f80368760994f30ca"
- integrity sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==
- dependencies:
- escape-string-regexp "^4.0.0"
-
-mimic-response@^1.0.0, mimic-response@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b"
- integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==
-
-minimist@^1.2.5:
- version "1.2.5"
- resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
- integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
-
-mkdirp@^0.5.4:
- version "0.5.5"
- resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def"
- integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==
- dependencies:
- minimist "^1.2.5"
-
-ms@2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
- integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=
-
-ms@2.1.2:
- version "2.1.2"
- resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
- integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
-
-normalize-url@^4.1.0:
- version "4.5.1"
- resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.1.tgz#0dd90cf1288ee1d1313b87081c9a5932ee48518a"
- integrity sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==
-
-npm-conf@^1.1.3:
- version "1.1.3"
- resolved "https://registry.yarnpkg.com/npm-conf/-/npm-conf-1.1.3.tgz#256cc47bd0e218c259c4e9550bf413bc2192aff9"
- integrity sha512-Yic4bZHJOt9RCFbRP3GgpqhScOY4HH3V2P8yBj6CeYq118Qr+BLXqT2JvpJ00mryLESpgOxf5XlFv4ZjXxLScw==
- dependencies:
- config-chain "^1.1.11"
- pify "^3.0.0"
-
-object-keys@^1.0.12:
- version "1.1.1"
- resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e"
- integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==
-
-once@^1.3.1, once@^1.4.0:
- version "1.4.0"
- resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
- integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E=
- dependencies:
- wrappy "1"
-
-p-cancelable@^1.0.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-1.1.0.tgz#d078d15a3af409220c886f1d9a0ca2e441ab26cc"
- integrity sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==
-
-pend@~1.2.0:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50"
- integrity sha1-elfrVQpng/kRUzH89GY9XI4AelA=
-
-pify@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176"
- integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=
-
-prepend-http@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897"
- integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=
-
-process-nextick-args@~2.0.0:
- version "2.0.1"
- resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2"
- integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==
-
-progress@^2.0.3:
- version "2.0.3"
- resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8"
- integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==
-
-proto-list@~1.2.1:
- version "1.2.4"
- resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849"
- integrity sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk=
-
-pump@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64"
- integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==
- dependencies:
- end-of-stream "^1.1.0"
- once "^1.3.1"
-
-readable-stream@^2.2.2:
- version "2.3.7"
- resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57"
- integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==
- dependencies:
- core-util-is "~1.0.0"
- inherits "~2.0.3"
- isarray "~1.0.0"
- process-nextick-args "~2.0.0"
- safe-buffer "~5.1.1"
- string_decoder "~1.1.1"
- util-deprecate "~1.0.1"
-
-responselike@^1.0.2:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7"
- integrity sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=
- dependencies:
- lowercase-keys "^1.0.0"
-
-roarr@^2.15.3:
- version "2.15.4"
- resolved "https://registry.yarnpkg.com/roarr/-/roarr-2.15.4.tgz#f5fe795b7b838ccfe35dc608e0282b9eba2e7afd"
- integrity sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==
- dependencies:
- boolean "^3.0.1"
- detect-node "^2.0.4"
- globalthis "^1.0.1"
- json-stringify-safe "^5.0.1"
- semver-compare "^1.0.0"
- sprintf-js "^1.1.2"
-
-safe-buffer@~5.1.0, safe-buffer@~5.1.1:
- version "5.1.2"
- resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
- integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
-
-semver-compare@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc"
- integrity sha1-De4hahyUGrN+nvsXiPavxf9VN/w=
-
-semver@^6.2.0:
- version "6.3.0"
- resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d"
- integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==
-
-semver@^7.3.2:
- version "7.3.5"
- resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7"
- integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==
- dependencies:
- lru-cache "^6.0.0"
-
-serialize-error@^7.0.1:
- version "7.0.1"
- resolved "https://registry.yarnpkg.com/serialize-error/-/serialize-error-7.0.1.tgz#f1360b0447f61ffb483ec4157c737fab7d778e18"
- integrity sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==
- dependencies:
- type-fest "^0.13.1"
-
-sprintf-js@^1.1.2:
- version "1.1.2"
- resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.1.2.tgz#da1765262bf8c0f571749f2ad6c26300207ae673"
- integrity sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==
-
-string_decoder@~1.1.1:
- version "1.1.1"
- resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8"
- integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==
- dependencies:
- safe-buffer "~5.1.0"
-
-sumchecker@^3.0.1:
- version "3.0.1"
- resolved "https://registry.yarnpkg.com/sumchecker/-/sumchecker-3.0.1.tgz#6377e996795abb0b6d348e9b3e1dfb24345a8e42"
- integrity sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==
- dependencies:
- debug "^4.1.0"
-
-to-readable-stream@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/to-readable-stream/-/to-readable-stream-1.0.0.tgz#ce0aa0c2f3df6adf852efb404a783e77c0475771"
- integrity sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==
-
-tunnel@^0.0.6:
- version "0.0.6"
- resolved "https://registry.yarnpkg.com/tunnel/-/tunnel-0.0.6.tgz#72f1314b34a5b192db012324df2cc587ca47f92c"
- integrity sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==
-
-type-fest@^0.13.1:
- version "0.13.1"
- resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.13.1.tgz#0172cb5bce80b0bd542ea348db50c7e21834d934"
- integrity sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==
-
-typedarray@^0.0.6:
- version "0.0.6"
- resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
- integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=
-
-universalify@^0.1.0:
- version "0.1.2"
- resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66"
- integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==
-
-url-parse-lax@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-3.0.0.tgz#16b5cafc07dbe3676c1b1999177823d6503acb0c"
- integrity sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=
- dependencies:
- prepend-http "^2.0.0"
-
-util-deprecate@~1.0.1:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
- integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=
-
-wrappy@1:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
- integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
-
-yallist@^4.0.0:
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"
- integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
-
-yauzl@^2.10.0:
- version "2.10.0"
- resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9"
- integrity sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=
- dependencies:
- buffer-crc32 "~0.2.3"
- fd-slicer "~1.1.0"
diff --git a/eslint.config.js b/eslint.config.js
new file mode 100644
index 00000000..38c002cf
--- /dev/null
+++ b/eslint.config.js
@@ -0,0 +1,61 @@
+import eslint from "@eslint/js";
+import globals from "globals";
+import tseslint from "typescript-eslint";
+
+const baseConfig = tseslint.config(
+ eslint.configs.recommended,
+ ...tseslint.configs.recommendedTypeChecked,
+ // Enable type-aware linting
+ {
+ languageOptions: {
+ parserOptions: {
+ project: true,
+ tsconfigRootDir: import.meta.dirname,
+ },
+ },
+ },
+ // Disable type-aware linting for JS files as it causes issues
+ {
+ files: ["*.js"],
+ ...tseslint.configs.disableTypeChecked,
+ }
+);
+
+const nodeConfig = tseslint.config(...baseConfig, {
+ languageOptions: {
+ sourceType: "module",
+ globals: {
+ ...globals.node,
+ },
+ },
+});
+
+const runtimeConfig = tseslint.config(...baseConfig, {
+ languageOptions: {
+ sourceType: "module",
+ globals: {
+ ...globals.browser,
+ },
+ },
+ rules: {
+ // Mostly caused by JSDoc imports, disable for now
+ "@typescript-eslint/no-unused-vars": "off",
+ // FIXME: enforce when we're ready to
+ "prefer-const": "warn",
+ },
+});
+
+// I don't know what the ESLint devs were thinking about. This is just horrible
+export default [
+ {
+ ignores: ["build/*"],
+ },
+ ...nodeConfig.map(config => ({
+ ...config,
+ files: ["*.{ts,js}", "{gulp,electron}/**/*.{ts,js}"],
+ })),
+ ...runtimeConfig.map(config => ({
+ ...config,
+ files: ["src/**/*.{ts,js,tsx,jsx}"],
+ })),
+];
diff --git a/gulp/.babelrc b/gulp/.babelrc
deleted file mode 100644
index a0765e18..00000000
--- a/gulp/.babelrc
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "presets": ["es2015"]
-}
diff --git a/gulp/.gitignore b/gulp/.gitignore
deleted file mode 100644
index 80dc3c89..00000000
--- a/gulp/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-additional_build_files
diff --git a/gulp/atlas2json.js b/gulp/atlas2json.js
index b77a47f3..bd3fc72e 100644
--- a/gulp/atlas2json.js
+++ b/gulp/atlas2json.js
@@ -1,13 +1,13 @@
-const { join, resolve } = require("path");
-const { readFileSync, readdirSync, writeFileSync } = require("fs");
+import { join, resolve } from "path/posix";
+import { readFileSync, readdirSync, writeFileSync } from "fs";
const suffixToScale = {
lq: "0.25",
mq: "0.5",
- hq: "0.75"
+ hq: "0.75",
};
-function convert(srcDir) {
+export default function convert(srcDir) {
const full = resolve(srcDir);
const srcFiles = readdirSync(full)
.filter(n => n.endsWith(".atlas"))
@@ -65,7 +65,7 @@ function convert(srcDir) {
x: xy[0],
y: xy[1],
w: size[0],
- h: size[1]
+ h: size[1],
},
// Whether image was rotated
@@ -75,21 +75,21 @@ function convert(srcDir) {
// How is the image trimmed
spriteSourceSize: {
x: offset[0],
- y: (orig[1] - size[1]) - offset[1],
+ y: orig[1] - size[1] - offset[1],
w: size[0],
- h: size[1]
+ h: size[1],
},
-
+
sourceSize: {
w: orig[0],
- h: orig[1]
- }
- }
+ h: orig[1],
+ },
+ };
}
// Simple object that will hold other metadata
current = {
- name: line
+ name: line,
};
} else {
// Read and set current image metadata
@@ -108,20 +108,14 @@ function convert(srcDir) {
format: srcMeta.format,
size: {
w: atlasSize[0],
- h: atlasSize[1]
+ h: atlasSize[1],
},
- scale: atlasScale.toString()
- }
+ scale: atlasScale.toString(),
+ },
});
writeFileSync(atlas.replace(".atlas", ".json"), result, {
- encoding: "utf-8"
+ encoding: "utf-8",
});
}
}
-
-if (require.main == module) {
- convert(process.argv[2]);
-}
-
-module.exports = { convert };
diff --git a/gulp/babel-es6.config.js b/gulp/babel-es6.config.js
deleted file mode 100644
index b3f088f9..00000000
--- a/gulp/babel-es6.config.js
+++ /dev/null
@@ -1,47 +0,0 @@
-module.exports = function (api) {
- api.cache(true);
- const presets = [
- [
- "@babel/preset-env",
- {
- targets: "> 5%",
- useBuiltIns: "usage",
- corejs: 3,
- loose: true,
- spec: false,
- modules: "auto",
- },
- ],
- ];
- const plugins = [
- "closure-elimination",
- // var is faster than let and const!
- [
- "@babel/plugin-transform-block-scoping",
- {
- throwIfClosureRequired: false,
- },
- ],
- [
- "@babel/plugin-transform-classes",
- {
- loose: true,
- },
- ],
- ];
- return {
- presets,
- plugins,
- highlightCode: true,
- sourceType: "module",
- sourceMaps: false,
- parserOpts: {},
- only: ["../src/js"],
- generatorOpts: {
- retainLines: false,
- compact: true,
- minified: true,
- comments: true,
- },
- };
-};
diff --git a/gulp/babel.config.js b/gulp/babel.config.js
deleted file mode 100644
index 62839421..00000000
--- a/gulp/babel.config.js
+++ /dev/null
@@ -1,55 +0,0 @@
-module.exports = function (api) {
- api.cache(true);
- const presets = [
- [
- "@babel/preset-env",
- {
- // targets: ">0.01%",
- targets: {
- edge: 10,
- firefox: 37,
- chrome: 24,
- safari: 10,
- ie: 10,
- },
- useBuiltIns: "usage",
- corejs: 3,
- loose: true,
- spec: false,
- modules: "auto",
- },
- ],
- ];
- const plugins = [
- "@babel/plugin-transform-arrow-functions",
- "closure-elimination",
- // var is faster than let and const!
- // [
- // "@babel/plugin-transform-block-scoping",
- // {
- // throwIfClosureRequired: true,
- // },
- // ],
- [
- "@babel/plugin-transform-classes",
- {
- loose: true,
- },
- ],
- ];
- return {
- presets,
- plugins,
- highlightCode: true,
- sourceType: "unambiguous",
- sourceMaps: false,
- parserOpts: {},
- exclude: /(core-js|babel-core|babel-runtime)/,
- generatorOpts: {
- retainLines: false,
- compact: true,
- minified: true,
- comments: true,
- },
- };
-};
diff --git a/gulp/build_variants.js b/gulp/build_variants.js
index 4f67bf9e..aecb3ba7 100644
--- a/gulp/build_variants.js
+++ b/gulp/build_variants.js
@@ -1,74 +1,10 @@
/**
* @type {Record}
+ * standalone: boolean
+ * }>}
*/
-const BUILD_VARIANTS = {
- "web-localhost": {
- standalone: false,
- environment: "dev",
- buildArgs: {},
- },
- "web-shapezio-beta": {
- standalone: false,
- environment: "staging",
- buildArgs: {},
- },
- "web-shapezio": {
- standalone: false,
- environment: "prod",
- buildArgs: {},
- },
- "standalone-steam": {
+export const BUILD_VARIANTS = {
+ standalone: {
standalone: true,
- executableName: "shapez",
- steamAppId: 1318690,
- buildArgs: {},
- },
- "standalone-steam-china": {
- standalone: true,
- steamAppId: 1318690,
- buildArgs: {
- chineseVersion: true,
- },
- },
- "standalone-steam-demo": {
- standalone: true,
- steamAppId: 1930750,
- buildArgs: {
- steamDemo: true,
- },
- },
- "standalone-steam-china-demo": {
- standalone: true,
- steamAppId: 1930750,
- buildArgs: {
- steamDemo: true,
- chineseVersion: true,
- },
- },
- "standalone-wegame": {
- standalone: true,
- electronBaseDir: "electron_wegame",
- buildArgs: {
- wegameVersion: true,
- },
- },
- "standalone-gog": {
- standalone: true,
- electronBaseDir: "electron_gog",
- buildArgs: {
- gogVersion: true,
- },
},
};
-module.exports = { BUILD_VARIANTS };
diff --git a/gulp/buildutils.js b/gulp/buildutils.js
index 8b5e389b..f2900df1 100644
--- a/gulp/buildutils.js
+++ b/gulp/buildutils.js
@@ -1,47 +1,22 @@
-const glob = require("glob");
-const execSync = require("child_process").execSync;
-const trim = require("trim");
-const fs = require("fs");
-const path = require("path");
+import { execSync } from "child_process";
+import fs from "fs";
-module.exports = {
- getRevision: function (useLast = false) {
- const commitHash = execSync("git rev-parse --short " + (useLast ? "HEAD^1" : "HEAD")).toString(
- "ascii"
- );
- return commitHash.replace(/^\s+|\s+$/g, "");
- },
+export function getRevision(useLast = false) {
+ const commitHash = execSync("git rev-parse --short " + (useLast ? "HEAD^1" : "HEAD")).toString("ascii");
+ return commitHash.trim();
+}
- getAllResourceImages() {
- return glob
- .sync("res/**/*.@(png|svg|jpg)", { cwd: ".." })
- .map(f => f.replace(/^res\//gi, ""))
- .filter(f => {
- if (f.indexOf("ui") >= 0) {
- // We drop all ui images except for the noinline ones
- return f.indexOf("noinline") >= 0;
- }
- return true;
- });
- },
-
- getTag() {
- try {
- return execSync("git describe --tag --exact-match").toString("ascii");
- } catch (e) {
- throw new Error("Current git HEAD is not a version tag");
+export function getAllResourceImages() {
+ return fs.globSync("./**/*.@(png|svg|jpg)", { cwd: "../res" }).filter(f => {
+ if (f.indexOf("ui") >= 0) {
+ // We drop all ui images except for the noinline ones
+ return f.indexOf("noinline") >= 0;
}
- },
+ return true;
+ });
+}
- getVersion() {
- return trim(fs.readFileSync(path.join(__dirname, "..", "version")).toString());
- },
-
- /**
- * @param {string} url
- * @param {string} commitHash
- */
- cachebust(url, commitHash) {
- return "/v/" + commitHash + "/" + url;
- },
-};
+export function getVersion() {
+ // Use the version number specified in package.json
+ return JSON.parse(fs.readFileSync("../package.json", "utf-8")).version;
+}
diff --git a/gulp/config.js b/gulp/config.js
new file mode 100644
index 00000000..5555de69
--- /dev/null
+++ b/gulp/config.js
@@ -0,0 +1,23 @@
+import BrowserSync from "browser-sync";
+import path from "path/posix";
+
+export const baseDir = path.resolve("..");
+export const buildFolder = path.join(baseDir, "build");
+export const buildOutputFolder = path.join(baseDir, "build_output");
+export const generatedCodeFolder = path.join(baseDir, "src/js/built-temp");
+
+// Globs for atlas resources
+export const rawImageResourcesGlobs = ["../res_raw/atlas.json", "../res_raw/**/*.png"];
+
+// Globs for non-ui resources
+export const nonImageResourcesGlobs = ["../res/**/*.woff2", "../res/*.ico", "../res/**/*.webm"];
+
+// Globs for ui resources
+export const imageResourcesGlobs = [
+ "../res/**/*.png",
+ "../res/**/*.svg",
+ "../res/**/*.jpg",
+ "../res/**/*.gif",
+];
+
+export const browserSync = BrowserSync.create();
diff --git a/gulp/css.js b/gulp/css.js
index 46e44247..3b28ff50 100644
--- a/gulp/css.js
+++ b/gulp/css.js
@@ -1,136 +1,97 @@
-const path = require("path");
-const buildUtils = require("./buildutils");
-
-function gulptasksCSS($, gulp, buildFolder, browserSync) {
- // The assets plugin copies the files
- const commitHash = buildUtils.getRevision();
- const postcssAssetsPlugin = cachebust =>
- $.postcssAssets({
- loadPaths: [path.join(buildFolder, "res", "ui")],
- basePath: buildFolder,
- baseUrl: ".",
- cachebuster: cachebust
- ? (filePath, urlPathname) => ({
- pathname: buildUtils.cachebust(urlPathname, commitHash),
- })
- : "",
- });
-
- // Postcss configuration
- const postcssPlugins = (prod, { cachebust = false }) => {
- const plugins = [postcssAssetsPlugin(cachebust)];
- if (prod) {
- plugins.unshift(
- $.postcssPresetEnv({
- browsers: ["> 0.1%"],
- })
- );
-
- plugins.push(
- $.cssMqpacker({
- sort: true,
- }),
- $.cssnano({
- preset: [
- "advanced",
- {
- cssDeclarationSorter: false,
- discardUnused: true,
- mergeIdents: false,
- reduceIdents: true,
- zindex: true,
- },
- ],
- }),
- $.postcssRoundSubpixels()
- );
- }
- return plugins;
- };
-
- // Performs linting on css
- gulp.task("css.lint", () => {
- return gulp
- .src(["../src/css/**/*.scss"])
- .pipe($.sassLint({ configFile: ".sasslint.yml" }))
- .pipe($.sassLint.format())
- .pipe($.sassLint.failOnError());
- });
-
- function resourcesTask({ cachebust, isProd }) {
- return gulp
- .src("../src/css/main.scss", { cwd: __dirname })
- .pipe($.plumber())
- .pipe($.dartSass.sync().on("error", $.dartSass.logError))
- .pipe(
- $.postcss([
- $.postcssCriticalSplit({
- blockTag: "@load-async",
- }),
- ])
- )
- .pipe($.rename("async-resources.css"))
- .pipe($.postcss(postcssPlugins(isProd, { cachebust })))
- .pipe(gulp.dest(buildFolder))
- .pipe(browserSync.stream());
- }
-
- // Builds the css resources
- gulp.task("css.resources.dev", () => {
- return resourcesTask({ cachebust: false, isProd: false });
- });
-
- // Builds the css resources in prod (=minified)
- gulp.task("css.resources.prod", () => {
- return resourcesTask({ cachebust: true, isProd: true });
- });
-
- // Builds the css resources in prod (=minified), without cachebusting
- gulp.task("css.resources.prod-standalone", () => {
- return resourcesTask({ cachebust: false, isProd: true });
- });
-
- function mainTask({ cachebust, isProd }) {
- return gulp
- .src("../src/css/main.scss", { cwd: __dirname })
- .pipe($.plumber())
- .pipe($.dartSass.sync().on("error", $.dartSass.logError))
- .pipe(
- $.postcss([
- $.postcssCriticalSplit({
- blockTag: "@load-async",
- output: "rest",
- }),
- ])
- )
- .pipe($.postcss(postcssPlugins(isProd, { cachebust })))
- .pipe(gulp.dest(buildFolder))
- .pipe(browserSync.stream());
- }
-
- // Builds the css main
- gulp.task("css.main.dev", () => {
- return mainTask({ cachebust: false, isProd: false });
- });
-
- // Builds the css main in prod (=minified)
- gulp.task("css.main.prod", () => {
- return mainTask({ cachebust: true, isProd: true });
- });
-
- // Builds the css main in prod (=minified), without cachebusting
- gulp.task("css.main.prod-standalone", () => {
- return mainTask({ cachebust: false, isProd: true });
- });
-
- gulp.task("css.dev", gulp.parallel("css.main.dev", "css.resources.dev"));
- gulp.task("css.prod", gulp.parallel("css.main.prod", "css.resources.prod"));
- gulp.task(
- "css.prod-standalone",
- gulp.parallel("css.main.prod-standalone", "css.resources.prod-standalone")
- );
-}
-
-module.exports = {
- gulptasksCSS,
-};
+import gulp from "gulp";
+import path from "path/posix";
+import { buildFolder } from "./config.js";
+
+import cssMqpacker from "css-mqpacker";
+import cssnano from "cssnano";
+import gulpDartSass from "gulp-dart-sass";
+import gulpPlumber from "gulp-plumber";
+import gulpPostcss from "gulp-postcss";
+import gulpRename from "gulp-rename";
+import postcssAssets from "postcss-assets";
+import postcssCriticalSplit from "postcss-critical-split";
+
+// The assets plugin copies the files
+const postcssAssetsPlugin = postcssAssets({
+ loadPaths: [path.join(buildFolder, "res", "ui")],
+ basePath: buildFolder,
+ baseUrl: ".",
+});
+
+// Postcss configuration
+const postcssPlugins = prod => {
+ const plugins = [postcssAssetsPlugin];
+ if (prod) {
+ plugins.push(
+ cssMqpacker({
+ sort: true,
+ }),
+ cssnano({
+ preset: [
+ "advanced",
+ {
+ cssDeclarationSorter: false,
+ discardUnused: true,
+ mergeIdents: false,
+ reduceIdents: true,
+ zindex: true,
+ },
+ ],
+ })
+ );
+ }
+ return plugins;
+};
+
+function resourcesTask({ isProd }) {
+ return gulp
+ .src("../src/css/main.scss")
+ .pipe(gulpPlumber())
+ .pipe(gulpDartSass.sync().on("error", gulpDartSass.logError))
+ .pipe(
+ gulpPostcss([
+ postcssCriticalSplit({
+ blockTag: "@load-async",
+ }),
+ ])
+ )
+ .pipe(gulpRename("async-resources.css"))
+ .pipe(gulpPostcss(postcssPlugins(isProd)))
+ .pipe(gulp.dest(buildFolder));
+}
+
+export const resources = {
+ // Builds the css resources
+ dev: () => resourcesTask({ isProd: false }),
+
+ // Builds the css resources in prod (=minified)
+ prod: () => resourcesTask({ isProd: true }),
+};
+
+function mainTask({ isProd }) {
+ return gulp
+ .src("../src/css/main.scss")
+ .pipe(gulpPlumber())
+ .pipe(gulpDartSass.sync().on("error", gulpDartSass.logError))
+ .pipe(
+ gulpPostcss([
+ postcssCriticalSplit({
+ blockTag: "@load-async",
+ output: "rest",
+ }),
+ ])
+ )
+ .pipe(gulpPostcss(postcssPlugins(isProd)))
+ .pipe(gulp.dest(buildFolder));
+}
+
+export const main = {
+ // Builds the css main
+ dev: () => mainTask({ isProd: false }),
+
+ // Builds the css main in prod (=minified)
+ prod: () => mainTask({ isProd: true }),
+};
+
+export const dev = gulp.parallel(main.dev, resources.dev);
+export const prod = gulp.parallel(main.prod, resources.prod);
diff --git a/gulp/docs.js b/gulp/docs.js
deleted file mode 100644
index 399e0fa1..00000000
--- a/gulp/docs.js
+++ /dev/null
@@ -1,39 +0,0 @@
-const path = require("path");
-const fs = require("fs");
-
-function gulptasksDocs($, gulp, buildFolder) {
- gulp.task("docs.convertJsToTs", () => {
- return gulp
- .src(path.join("..", "src", "js", "**", "*.js"))
- .pipe(
- $.rename(path => {
- path.extname = ".ts";
- })
- )
- .pipe(gulp.dest(path.join("..", "tsc_temp")));
- });
-
- gulp.task("docs.copyTsconfigForHints", cb => {
- const src = fs.readFileSync(path.join("..", "src", "js", "tsconfig.json")).toString();
- const baseConfig = JSON.parse($.stripJsonComments(src));
-
- baseConfig.allowJs = false;
- baseConfig.checkJs = false;
- baseConfig.declaration = true;
- baseConfig.noEmit = false;
- baseConfig.strict = false;
- baseConfig.strictFunctionTypes = false;
- baseConfig.strictBindCallApply = false;
- baseConfig.alwaysStrict = false;
- baseConfig.composite = true;
- baseConfig.outFile = "bundled-ts.js";
- fs.writeFileSync(path.join("..", "tsc_temp", "tsconfig.json"), JSON.stringify(baseConfig));
- cb();
- });
-
- gulp.task("main.prepareDocs", gulp.series("docs.convertJsToTs", "docs.copyTsconfigForHints"));
-}
-
-module.exports = {
- gulptasksDocs,
-};
diff --git a/gulp/entitlements.plist b/gulp/entitlements.plist
deleted file mode 100644
index 51e30452..00000000
--- a/gulp/entitlements.plist
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
-
- com.apple.security.cs.allow-jit
-
- com.apple.security.cs.allow-unsigned-executable-memory
-
- com.apple.security.cs.debugger
-
- com.apple.security.cs.disable-library-validation
-
- com.apple.security.cs.allow-dyld-environment-variables
-
- com.apple.security.cs.disable-executable-page-protection
-
-
-
\ No newline at end of file
diff --git a/gulp/environment.js b/gulp/environment.js
new file mode 100644
index 00000000..f5ab22b0
--- /dev/null
+++ b/gulp/environment.js
@@ -0,0 +1,49 @@
+import { exec } from "child_process";
+import fs from "fs/promises";
+import gulp from "gulp";
+import { promisify } from "util";
+
+const texturePackerUrl =
+ "https://libgdx-nightlies.s3.amazonaws.com/libgdx-runnables/runnable-texturepacker.jar";
+
+const configTemplatePath = "../src/js/core/config.local.template.js";
+const configPath = "../src/js/core/config.local.js";
+
+export async function checkJava() {
+ try {
+ const { stderr } = await promisify(exec)("java -version");
+ console.log(`Found Java:`, stderr);
+ } catch {
+ throw new Error("Java is required to build the texture atlas, but was not found");
+ }
+}
+
+export async function downloadTexturePacker() {
+ const destination = "./runnable-texturepacker.jar";
+
+ try {
+ // If the file exists already, we're done
+ await fs.access(destination);
+ return;
+ } catch {
+ // File does not exist, need to download
+ }
+
+ console.log(`Downloading ${destination}...`);
+ const response = await fetch(texturePackerUrl);
+ if (!response.ok) {
+ throw new Error(`Failed to download Texture Packer: ${response.statusText}`);
+ }
+
+ await fs.writeFile(destination, response.body);
+}
+
+export async function createLocalConfig() {
+ try {
+ await fs.copyFile(configTemplatePath, configPath, fs.constants.COPYFILE_EXCL);
+ } catch {
+ // The file is already there
+ }
+}
+
+export const prepare = gulp.parallel(gulp.series(checkJava, downloadTexturePacker), createLocalConfig);
diff --git a/gulp/ftp.js b/gulp/ftp.js
deleted file mode 100644
index d41bccb6..00000000
--- a/gulp/ftp.js
+++ /dev/null
@@ -1,101 +0,0 @@
-const path = require("path");
-const fs = require("fs");
-
-const buildUtils = require("./buildutils");
-
-function gulptasksFTP($, gulp, buildFolder) {
- const commitHash = buildUtils.getRevision();
-
- const additionalFolder = path.join(__dirname, "additional_build_files");
-
- const additionalFiles = [
- path.join(additionalFolder, "*"),
- path.join(additionalFolder, "*.*"),
- path.join(additionalFolder, ".*"),
- ];
-
- const credentials = {
- alpha: {
- host: process.env.SHAPEZ_CLI_SERVER_HOST,
- user: process.env.SHAPEZ_CLI_ALPHA_FTP_USER,
- pass: process.env.SHAPEZ_CLI_ALPHA_FTP_PW,
- },
- staging: {
- host: process.env.SHAPEZ_CLI_SERVER_HOST,
- user: process.env.SHAPEZ_CLI_STAGING_FTP_USER,
- pass: process.env.SHAPEZ_CLI_STAGING_FTP_PW,
- },
- prod: {
- host: process.env.SHAPEZ_CLI_SERVER_HOST,
- user: process.env.SHAPEZ_CLI_LIVE_FTP_USER,
- pass: process.env.SHAPEZ_CLI_LIVE_FTP_PW,
- },
- };
-
- // Write the "commit.txt" file
- gulp.task("ftp.writeVersion", cb => {
- fs.writeFileSync(
- path.join(buildFolder, "version.json"),
- JSON.stringify(
- {
- commit: buildUtils.getRevision(),
- appVersion: buildUtils.getVersion(),
- buildTime: new Date().getTime(),
- },
- null,
- 4
- )
- );
- cb();
- });
-
- const gameSrcGlobs = [
- path.join(buildFolder, "**/*.*"),
- path.join(buildFolder, "**/.*"),
- path.join(buildFolder, "**/*"),
- path.join(buildFolder, "!**/index.html"),
- ];
-
- for (const deployEnv of ["alpha", "prod", "staging"]) {
- const deployCredentials = credentials[deployEnv];
-
- gulp.task(`ftp.upload.${deployEnv}.game`, () => {
- return gulp
- .src(gameSrcGlobs, { base: buildFolder })
- .pipe(
- $.rename(pth => {
- pth.dirname = path.join("v", commitHash, pth.dirname);
- })
- )
- .pipe($.sftp(deployCredentials));
- });
-
- gulp.task(`ftp.upload.${deployEnv}.indexHtml`, () => {
- return gulp
- .src([path.join(buildFolder, "index.html"), path.join(buildFolder, "version.json")], {
- base: buildFolder,
- })
- .pipe($.sftp(deployCredentials));
- });
-
- gulp.task(`ftp.upload.${deployEnv}.additionalFiles`, () => {
- return gulp
- .src(additionalFiles, { base: additionalFolder }) //
- .pipe($.sftp(deployCredentials));
- });
-
- gulp.task(
- `ftp.upload.${deployEnv}`,
- gulp.series(
- "ftp.writeVersion",
- `ftp.upload.${deployEnv}.game`,
- `ftp.upload.${deployEnv}.indexHtml`,
- `ftp.upload.${deployEnv}.additionalFiles`
- )
- );
- }
-}
-
-module.exports = {
- gulptasksFTP,
-};
diff --git a/gulp/gulpfile.js b/gulp/gulpfile.js
index 04d3c9c9..27b1107c 100644
--- a/gulp/gulpfile.js
+++ b/gulp/gulpfile.js
@@ -1,317 +1,23 @@
-/* eslint-disable */
-
-require("colors");
-
-const gulp = require("gulp");
-const browserSync = require("browser-sync").create({});
-const path = require("path");
-const deleteEmpty = require("delete-empty");
-const execSync = require("child_process").execSync;
-
-// Load other plugins dynamically
-const $ = require("gulp-load-plugins")({
- scope: ["devDependencies"],
- pattern: "*",
-});
-
-// Check environment variables
-
-const envVars = [
- "SHAPEZ_CLI_SERVER_HOST",
- "SHAPEZ_CLI_ALPHA_FTP_USER",
- "SHAPEZ_CLI_ALPHA_FTP_PW",
- "SHAPEZ_CLI_STAGING_FTP_USER",
- "SHAPEZ_CLI_STAGING_FTP_PW",
- "SHAPEZ_CLI_LIVE_FTP_USER",
- "SHAPEZ_CLI_LIVE_FTP_PW",
- "SHAPEZ_CLI_APPLE_ID",
- "SHAPEZ_CLI_APPLE_CERT_NAME",
- "SHAPEZ_CLI_GITHUB_USER",
- "SHAPEZ_CLI_GITHUB_TOKEN",
-];
-
-for (let i = 0; i < envVars.length; ++i) {
- if (!process.env[envVars[i]]) {
- console.warn("Unset environment variable, might cause issues:", envVars[i]);
- }
-}
-
-const baseDir = path.join(__dirname, "..");
-const buildFolder = path.join(baseDir, "build");
-const buildOuptutFolder = path.join(baseDir, "build_output");
-
-const imgres = require("./image-resources");
-imgres.gulptasksImageResources($, gulp, buildFolder);
-
-const css = require("./css");
-css.gulptasksCSS($, gulp, buildFolder, browserSync);
-
-const sounds = require("./sounds");
-sounds.gulptasksSounds($, gulp, buildFolder);
-
-const localConfig = require("./local-config");
-localConfig.gulptasksLocalConfig($, gulp);
-
-const js = require("./js");
-js.gulptasksJS($, gulp, buildFolder, browserSync);
-
-const html = require("./html");
-html.gulptasksHTML($, gulp, buildFolder);
-
-const ftp = require("./ftp");
-ftp.gulptasksFTP($, gulp, buildFolder);
-
-const docs = require("./docs");
-docs.gulptasksDocs($, gulp, buildFolder);
-
-const standalone = require("./standalone");
-standalone.gulptasksStandalone($, gulp);
-
-const translations = require("./translations");
-const { BUILD_VARIANTS } = require("./build_variants");
-translations.gulptasksTranslations($, gulp);
-
-///////////////////// BUILD TASKS /////////////////////
-
-// Cleans up everything
-gulp.task("utils.cleanBuildFolder", () => {
- return gulp.src(buildFolder, { read: false, allowEmpty: true }).pipe($.clean({ force: true }));
-});
-gulp.task("utils.cleanBuildOutputFolder", () => {
- return gulp.src(buildOuptutFolder, { read: false, allowEmpty: true }).pipe($.clean({ force: true }));
-});
-gulp.task("utils.cleanBuildTempFolder", () => {
- return gulp
- .src(path.join(__dirname, "..", "src", "js", "built-temp"), { read: false, allowEmpty: true })
- .pipe($.clean({ force: true }));
-});
-gulp.task("utils.cleanImageBuildFolder", () => {
- return gulp
- .src(path.join(__dirname, "res_built"), { read: false, allowEmpty: true })
- .pipe($.clean({ force: true }));
-});
-
-gulp.task(
- "utils.cleanup",
- gulp.series("utils.cleanBuildFolder", "utils.cleanImageBuildFolder", "utils.cleanBuildTempFolder")
-);
-
-// Requires no uncomitted files
-gulp.task("utils.requireCleanWorkingTree", cb => {
- let output = $.trim(execSync("git status -su").toString("ascii")).replace(/\r/gi, "").split("\n");
-
- // Filter files which are OK to be untracked
- output = output
- .map(x => x.replace(/[\r\n]+/gi, ""))
- .filter(x => x.indexOf(".local.js") < 0)
- .filter(x => x.length > 0);
- if (output.length > 0) {
- console.error("\n\nYou have unstaged changes, please commit everything first!");
- console.error("Unstaged files:");
- console.error(output.map(x => "'" + x + "'").join("\n"));
- process.exit(1);
- }
- cb();
-});
-
-gulp.task("utils.copyAdditionalBuildFiles", cb => {
- const additionalFolder = path.join("additional_build_files");
- const additionalSrcGlobs = [
- path.join(additionalFolder, "**/*.*"),
- path.join(additionalFolder, "**/.*"),
- path.join(additionalFolder, "**/*"),
- ];
-
- return gulp.src(additionalSrcGlobs).pipe(gulp.dest(buildFolder));
-});
-
-// Starts a webserver on the built directory (useful for testing prod build)
-gulp.task("main.webserver", () => {
- return gulp.src(buildFolder).pipe(
- $.webserver({
- livereload: {
- enable: true,
- },
- directoryListing: false,
- open: true,
- port: 3005,
- })
- );
-});
-
-/**
- *
- * @param {object} param0
- * @param {keyof typeof BUILD_VARIANTS} param0.version
- */
-function serveHTML({ version = "web-dev" }) {
- browserSync.init({
- server: [buildFolder, path.join(baseDir, "mod_examples")],
- port: 3005,
- ghostMode: {
- clicks: false,
- scroll: false,
- location: false,
- forms: false,
- },
- logLevel: "info",
- logPrefix: "BS",
- online: false,
- xip: false,
- notify: false,
- reloadDebounce: 100,
- reloadOnRestart: true,
- watchEvents: ["add", "change"],
- });
-
- // Watch .scss files, those trigger a css rebuild
- gulp.watch(["../src/**/*.scss"], gulp.series("css.dev"));
-
- // Watch .html files, those trigger a html rebuild
- gulp.watch("../src/**/*.html", gulp.series("html." + version + ".dev"));
- gulp.watch("./preloader/*.*", gulp.series("html." + version + ".dev"));
-
- // Watch translations
- gulp.watch("../translations/**/*.yaml", gulp.series("translations.convertToJson"));
-
- gulp.watch(
- ["../res_raw/sounds/sfx/*.mp3", "../res_raw/sounds/sfx/*.wav"],
- gulp.series("sounds.sfx", "sounds.copy")
- );
- gulp.watch(
- ["../res_raw/sounds/music/*.mp3", "../res_raw/sounds/music/*.wav"],
- gulp.series("sounds.music", "sounds.copy")
- );
-
- // Watch resource files and copy them on change
- gulp.watch(imgres.rawImageResourcesGlobs, gulp.series("imgres.buildAtlas"));
- gulp.watch(imgres.nonImageResourcesGlobs, gulp.series("imgres.copyNonImageResources"));
- gulp.watch(imgres.imageResourcesGlobs, gulp.series("imgres.copyImageResources"));
-
- // Watch .atlas files and recompile the atlas on change
- gulp.watch("../res_built/atlas/*.atlas", gulp.series("imgres.atlasToJson"));
- gulp.watch("../res_built/atlas/*.json", gulp.series("imgres.atlas"));
-
- // Watch the build folder and reload when anything changed
- const extensions = ["html", "js", "png", "gif", "jpg", "svg", "mp3", "ico", "woff2", "json"];
- gulp.watch(extensions.map(ext => path.join(buildFolder, "**", "*." + ext))).on("change", function (path) {
- return gulp.src(path).pipe(browserSync.reload({ stream: true }));
- });
-
- gulp.watch("../src/js/built-temp/*.json").on("change", function (path) {
- return gulp.src(path).pipe(browserSync.reload({ stream: true }));
- });
-
- gulp.series("js." + version + ".dev.watch")(() => true);
-}
-
-// Pre and postbuild
-gulp.task("step.baseResources", gulp.series("imgres.allOptimized"));
-gulp.task("step.deleteEmpty", cb => {
- deleteEmpty.sync(buildFolder);
- cb();
-});
-
-gulp.task("step.postbuild", gulp.series("imgres.cleanupUnusedCssInlineImages", "step.deleteEmpty"));
-
-///////////////////// RUNNABLE TASKS /////////////////////
-
-// Builds everything (dev)
-gulp.task(
- "build.prepare.dev",
- gulp.series(
- "utils.cleanup",
- "utils.copyAdditionalBuildFiles",
- "localConfig.findOrCreate",
- "imgres.buildAtlas",
- "imgres.atlasToJson",
- "imgres.atlas",
- "sounds.dev",
- "imgres.copyImageResources",
- "imgres.copyNonImageResources",
- "translations.fullBuild",
- "css.dev"
- )
-);
-
-// Builds everything for every variant
-for (const variant in BUILD_VARIANTS) {
- const data = BUILD_VARIANTS[variant];
- const buildName = "build." + variant;
-
- // build
- gulp.task(
- buildName + ".code",
- gulp.series(
- data.standalone ? "sounds.fullbuildHQ" : "sounds.fullbuild",
- "translations.fullBuild",
- "js." + variant + ".prod"
- )
- );
-
- gulp.task(buildName + ".resourcesAndCode", gulp.parallel("step.baseResources", buildName + ".code"));
-
- gulp.task(
- buildName + ".all",
- gulp.series(buildName + ".resourcesAndCode", "css.prod-standalone", "html." + variant + ".prod")
- );
-
- gulp.task(buildName, gulp.series("utils.cleanup", buildName + ".all", "step.postbuild"));
-
- // bundle
- if (data.standalone) {
- gulp.task(
- "bundle." + variant + ".from-windows",
- gulp.series(buildName, "standalone." + variant + ".build-from-windows")
- );
- gulp.task(
- "bundle." + variant + ".from-darwin",
- gulp.series(buildName, "standalone." + variant + ".build-from-darwin")
- );
- }
-
- // serve
- gulp.task(
- "serve." + variant,
- gulp.series("build.prepare.dev", "html." + variant + ".dev", () => serveHTML({ version: variant }))
- );
-}
-
-// Deploying!
-gulp.task(
- "deploy.staging",
- gulp.series("utils.requireCleanWorkingTree", "build.web-shapezio-beta", "ftp.upload.staging")
-);
-gulp.task(
- "deploy.prod",
- gulp.series("utils.requireCleanWorkingTree", "build.web-shapezio", "ftp.upload.prod")
-);
-
-// Bundling (pre upload)
-gulp.task(
- "bundle.steam.from-darwin",
- gulp.series("utils.cleanBuildOutputFolder", "bundle.standalone-steam.from-darwin")
-);
-gulp.task(
- "bundle.steam.from-windows",
- gulp.series(
- "utils.cleanBuildOutputFolder",
- "bundle.standalone-steam.from-windows",
- "bundle.standalone-steam-china.from-windows"
- )
-);
-gulp.task(
- "bundle.steam-demo.from-darwin",
- gulp.series("utils.cleanBuildOutputFolder", "bundle.standalone-steam-demo.from-darwin")
-);
-gulp.task(
- "bundle.steam-demo.from-windows",
- gulp.series(
- "utils.cleanBuildOutputFolder",
- "bundle.standalone-steam-demo.from-windows",
- "bundle.standalone-steam-china-demo.from-windows"
- )
-);
-
-// Default task (dev, localhost)
-gulp.task("default", gulp.series("serve.web-localhost"));
+import gulp from "gulp";
+import * as tasks from "./tasks.js";
+
+/**
+ * @typedef {import("gulp").TaskFunction} TaskFunction
+ * @typedef {TaskFunction | { [k: string]: Tasks }} Tasks
+ */
+
+/**
+ * @param {Tasks} tasks
+ * @param {string=} prefix
+ */
+function register(tasks, prefix) {
+ if (tasks instanceof Function) {
+ gulp.task(prefix, tasks);
+ return;
+ }
+ for (const [k, v] of Object.entries(tasks)) {
+ register(v, prefix == null ? k : `${prefix}.${k}`);
+ }
+}
+
+register(tasks);
diff --git a/gulp/html.js b/gulp/html.js
index a32451c7..62074891 100644
--- a/gulp/html.js
+++ b/gulp/html.js
@@ -1,205 +1,42 @@
-const buildUtils = require("./buildutils");
-const fs = require("fs");
-const path = require("path");
-const crypto = require("crypto");
-const { BUILD_VARIANTS } = require("./build_variants");
-
-function computeIntegrityHash(fullPath, algorithm = "sha256") {
- const file = fs.readFileSync(fullPath);
- const hash = crypto.createHash(algorithm).update(file).digest("base64");
- return algorithm + "-" + hash;
-}
-
-/**
- * PROVIDES (per )
- *
- * html..dev
- * html..prod
- */
-function gulptasksHTML($, gulp, buildFolder) {
- const commitHash = buildUtils.getRevision();
- async function buildHtml({
- googleAnalytics = false,
- standalone = false,
- integrity = true,
- enableCachebust = true,
- }) {
- function cachebust(url) {
- if (enableCachebust) {
- return buildUtils.cachebust(url, commitHash);
- }
- return url;
- }
-
- const hasLocalFiles = standalone;
-
- return gulp
- .src("../src/html/" + (standalone ? "index.standalone.html" : "index.html"))
- .pipe(
- $.dom(
- /** @this {Document} **/ function () {
- const document = this;
-
- // Append css
- const css = document.createElement("link");
- css.rel = "stylesheet";
- css.type = "text/css";
- css.media = "none";
- css.setAttribute("onload", "this.media='all'");
- css.href = cachebust("main.css");
- if (integrity) {
- css.setAttribute(
- "integrity",
- computeIntegrityHash(path.join(buildFolder, "main.css"))
- );
- }
- document.head.appendChild(css);
-
- // Google analytics
- if (googleAnalytics && false) {
- const tagManagerScript = document.createElement("script");
- tagManagerScript.src =
- "https://www.googletagmanager.com/gtag/js?id=UA-165342524-1";
- tagManagerScript.setAttribute("async", "");
- document.head.appendChild(tagManagerScript);
-
- const initScript = document.createElement("script");
- initScript.textContent = `
- window.dataLayer = window.dataLayer || [];
- function gtag(){dataLayer.push(arguments);}
- gtag('js', new Date());
- gtag('config', 'UA-165342524-1', { anonymize_ip: true });
- `;
- document.head.appendChild(initScript);
- }
-
- // Do not need to preload in app or standalone
- if (!hasLocalFiles) {
- // Preload essentials
- const preloads = [
- "res/fonts/GameFont.woff2",
- // "async-resources.css",
- // "res/sounds/music/theme-short.mp3",
- ];
-
- preloads.forEach(src => {
- const preloadLink = document.createElement("link");
- preloadLink.rel = "preload";
- preloadLink.href = cachebust(src);
- if (src.endsWith(".woff2")) {
- preloadLink.setAttribute("crossorigin", "anonymous");
- preloadLink.setAttribute("as", "font");
- } else if (src.endsWith(".css")) {
- preloadLink.setAttribute("as", "style");
- } else if (src.endsWith(".mp3")) {
- preloadLink.setAttribute("as", "audio");
- } else {
- preloadLink.setAttribute("as", "image");
- }
- document.head.appendChild(preloadLink);
- });
- }
-
- let fontCss = `
- @font-face {
- font-family: "GameFont";
- font-style: normal;
- font-weight: normal;
- font-display: swap;
- src: url('${cachebust("res/fonts/GameFont.woff2")}') format("woff2");
- }
- `;
- let loadingCss =
- fontCss +
- fs.readFileSync(path.join(__dirname, "preloader", "preloader.css")).toString();
-
- const style = document.createElement("style");
- style.setAttribute("type", "text/css");
- style.textContent = loadingCss;
- document.head.appendChild(style);
-
- let bodyContent = fs
- .readFileSync(path.join(__dirname, "preloader", "preloader.html"))
- .toString();
-
- // Append loader, but not in standalone (directly include bundle there)
- if (standalone) {
- const bundleScript = document.createElement("script");
- bundleScript.type = "text/javascript";
- bundleScript.src = "bundle.js";
- if (integrity) {
- bundleScript.setAttribute(
- "integrity",
- computeIntegrityHash(path.join(buildFolder, "bundle.js"))
- );
- }
- document.head.appendChild(bundleScript);
- } else {
- const loadJs = document.createElement("script");
- loadJs.type = "text/javascript";
- let scriptContent = "";
- scriptContent += `var bundleSrc = '${cachebust("bundle.js")}';\n`;
-
- if (integrity) {
- scriptContent +=
- "var bundleIntegrity = '" +
- computeIntegrityHash(path.join(buildFolder, "bundle.js")) +
- "';\n";
- } else {
- scriptContent += "var bundleIntegrity = null;\n";
- scriptContent += "var bundleIntegrityTranspiled = null;\n";
- }
-
- scriptContent += fs
- .readFileSync(path.join(__dirname, "preloader", "preloader.js"))
- .toString();
- loadJs.textContent = scriptContent;
- document.head.appendChild(loadJs);
- }
-
- document.body.innerHTML = bodyContent;
- }
- )
- )
- .pipe(
- $.htmlmin({
- caseSensitive: true,
- collapseBooleanAttributes: true,
- collapseInlineTagWhitespace: true,
- collapseWhitespace: true,
- preserveLineBreaks: true,
- minifyJS: true,
- minifyCSS: true,
- quoteCharacter: '"',
- useShortDoctype: true,
- })
- )
- .pipe($.htmlBeautify())
- .pipe($.rename("index.html"))
- .pipe(gulp.dest(buildFolder));
- }
-
- for (const variant in BUILD_VARIANTS) {
- const data = BUILD_VARIANTS[variant];
- gulp.task("html." + variant + ".dev", () => {
- return buildHtml({
- googleAnalytics: false,
- standalone: data.standalone,
- integrity: false,
- enableCachebust: false,
- });
- });
- gulp.task("html." + variant + ".prod", () => {
- return buildHtml({
- googleAnalytics: !data.standalone,
- standalone: data.standalone,
- integrity: true,
- enableCachebust: !data.standalone,
- });
- });
- }
-}
-
-module.exports = {
- gulptasksHTML,
-};
+import fs from "fs";
+import gulp from "gulp";
+import path from "path/posix";
+import { buildFolder } from "./config.js";
+
+import gulpDom from "gulp-dom";
+import gulpHtmlmin from "gulp-htmlmin";
+import gulpRename from "gulp-rename";
+
+/**
+ * PROVIDES
+ *
+ * html
+ */
+
+async function buildHtml() {
+ return gulp
+ .src("../src/html/index.html")
+ .pipe(
+ gulpDom(function () {
+ const style = this.createElement("style");
+ style.textContent = fs.readFileSync(path.join("preloader", "preloader.css"), "utf-8");
+ this.head.appendChild(style);
+ })
+ )
+ .pipe(
+ gulpHtmlmin({
+ caseSensitive: true,
+ collapseBooleanAttributes: true,
+ collapseInlineTagWhitespace: true,
+ collapseWhitespace: true,
+ preserveLineBreaks: true,
+ minifyJS: true,
+ minifyCSS: true,
+ quoteCharacter: '"',
+ })
+ )
+ .pipe(gulpRename("index.html"))
+ .pipe(gulp.dest(buildFolder));
+}
+
+export default buildHtml;
diff --git a/gulp/image-resources.js b/gulp/image-resources.js
index 61786883..507e1f94 100644
--- a/gulp/image-resources.js
+++ b/gulp/image-resources.js
@@ -1,205 +1,162 @@
-const { existsSync } = require("fs");
-// @ts-ignore
-const path = require("path");
-const atlasToJson = require("./atlas2json");
-
-const execute = command =>
- require("child_process").execSync(command, {
- encoding: "utf-8",
- });
-
-// Globs for atlas resources
-const rawImageResourcesGlobs = ["../res_raw/atlas.json", "../res_raw/**/*.png"];
-
-// Globs for non-ui resources
-const nonImageResourcesGlobs = ["../res/**/*.woff2", "../res/*.ico", "../res/**/*.webm"];
-
-// Globs for ui resources
-const imageResourcesGlobs = ["../res/**/*.png", "../res/**/*.svg", "../res/**/*.jpg", "../res/**/*.gif"];
-
-// Link to download LibGDX runnable-texturepacker.jar
-const runnableTPSource = "https://libgdx-nightlies.s3.eu-central-1.amazonaws.com/libgdx-runnables/runnable-texturepacker.jar";
-
-function gulptasksImageResources($, gulp, buildFolder) {
- // Lossless options
- const minifyImagesOptsLossless = () => [
- $.imageminJpegtran({
- progressive: true,
- }),
- $.imagemin.svgo({}),
- $.imagemin.optipng({
- optimizationLevel: 3,
- }),
- $.imageminGifsicle({
- optimizationLevel: 3,
- colors: 128,
- }),
- ];
-
- // Lossy options
- const minifyImagesOpts = () => [
- $.imagemin.mozjpeg({
- quality: 80,
- maxMemory: 1024 * 1024 * 8,
- }),
- $.imagemin.svgo({}),
- $.imageminPngquant({
- speed: 1,
- strip: true,
- quality: [0.65, 0.9],
- dithering: false,
- verbose: false,
- }),
- $.imagemin.optipng({
- optimizationLevel: 3,
- }),
- $.imageminGifsicle({
- optimizationLevel: 3,
- colors: 128,
- }),
- ];
-
- // Where the resources folder are
- const resourcesDestFolder = path.join(buildFolder, "res");
-
- /**
- * Determines if an atlas must use lossless compression
- * @param {string} fname
- */
- function fileMustBeLossless(fname) {
- return fname.indexOf("lossless") >= 0;
- }
-
- /////////////// ATLAS /////////////////////
-
- gulp.task("imgres.buildAtlas", cb => {
- const config = JSON.stringify("../res_raw/atlas.json");
- const source = JSON.stringify("../res_raw");
- const dest = JSON.stringify("../res_built/atlas");
-
- try {
- // First check whether Java is installed
- execute("java -version");
- // Now check and try downloading runnable-texturepacker.jar (22MB)
- if (!existsSync("./runnable-texturepacker.jar")) {
- const safeLink = JSON.stringify(runnableTPSource);
- const commands = [
- // linux/macos if installed
- `wget -O runnable-texturepacker.jar ${safeLink}`,
- // linux/macos, latest windows 10
- `curl -o runnable-texturepacker.jar ${safeLink}`,
- // windows 10 / updated windows 7+
- "powershell.exe -Command (new-object System.Net.WebClient)" +
- `.DownloadFile(${safeLink.replace(/"/g, "'")}, 'runnable-texturepacker.jar')`,
- // windows 7+, vulnerability exploit
- `certutil.exe -urlcache -split -f ${safeLink} runnable-texturepacker.jar`,
- ];
-
- while (commands.length) {
- try {
- execute(commands.shift());
- break;
- } catch {
- if (!commands.length) {
- throw new Error("Failed to download runnable-texturepacker.jar!");
- }
- }
- }
- }
-
- execute(`java -jar runnable-texturepacker.jar ${source} ${dest} atlas0 ${config}`);
- } catch {
- console.warn("Building atlas failed. Java not found / unsupported version?");
- }
- cb();
- });
-
- // Converts .atlas LibGDX files to JSON
- gulp.task("imgres.atlasToJson", cb => {
- atlasToJson.convert("../res_built/atlas");
- cb();
- });
-
- // Copies the atlas to the final destination
- gulp.task("imgres.atlas", () => {
- return gulp.src(["../res_built/atlas/*.png"]).pipe(gulp.dest(resourcesDestFolder));
- });
-
- // Copies the atlas to the final destination after optimizing it (lossy compression)
- gulp.task("imgres.atlasOptimized", () => {
- return gulp
- .src(["../res_built/atlas/*.png"])
- .pipe(
- $.if(
- fname => fileMustBeLossless(fname.history[0]),
- $.imagemin(minifyImagesOptsLossless()),
- $.imagemin(minifyImagesOpts())
- )
- )
- .pipe(gulp.dest(resourcesDestFolder));
- });
-
- //////////////////// RESOURCES //////////////////////
-
- // Copies all resources which are no ui resources
- gulp.task("imgres.copyNonImageResources", () => {
- return gulp.src(nonImageResourcesGlobs).pipe(gulp.dest(resourcesDestFolder));
- });
-
- // Copies all ui resources
- gulp.task("imgres.copyImageResources", () => {
- return gulp
- .src(imageResourcesGlobs)
-
- .pipe($.cached("imgres.copyImageResources"))
- .pipe(gulp.dest(path.join(resourcesDestFolder)));
- });
-
- // Copies all ui resources and optimizes them
- gulp.task("imgres.copyImageResourcesOptimized", () => {
- return gulp
- .src(imageResourcesGlobs)
- .pipe(
- $.if(
- fname => fileMustBeLossless(fname.history[0]),
- $.imagemin(minifyImagesOptsLossless()),
- $.imagemin(minifyImagesOpts())
- )
- )
- .pipe(gulp.dest(path.join(resourcesDestFolder)));
- });
-
- // Copies all resources and optimizes them
- gulp.task(
- "imgres.allOptimized",
- gulp.parallel(
- "imgres.buildAtlas",
- "imgres.atlasToJson",
- "imgres.atlasOptimized",
- "imgres.copyNonImageResources",
- "imgres.copyImageResourcesOptimized"
- )
- );
-
- // Cleans up unused images which are instead inline into the css
- gulp.task("imgres.cleanupUnusedCssInlineImages", () => {
- return gulp
- .src(
- [
- path.join(buildFolder, "res", "ui", "**", "*.png"),
- path.join(buildFolder, "res", "ui", "**", "*.jpg"),
- path.join(buildFolder, "res", "ui", "**", "*.svg"),
- path.join(buildFolder, "res", "ui", "**", "*.gif"),
- ],
- { read: false }
- )
- .pipe($.if(fname => fname.history[0].indexOf("noinline") < 0, $.clean({ force: true })));
- });
-}
-
-module.exports = {
- rawImageResourcesGlobs,
- nonImageResourcesGlobs,
- imageResourcesGlobs,
- gulptasksImageResources,
-};
+import gulp from "gulp";
+import path from "path/posix";
+import atlas2Json from "./atlas2json.js";
+import { buildFolder } from "./config.js";
+
+import childProcess from "child_process";
+import { promisify } from "util";
+const exec = promisify(childProcess.exec);
+const execute = command => {
+ const promise = exec(command, {
+ encoding: "utf-8",
+ });
+ promise.child.stderr.pipe(process.stderr);
+ return promise;
+};
+
+import gulpCached from "gulp-cached";
+import gulpClean from "gulp-clean";
+import gulpIf from "gulp-if";
+import gulpImagemin from "gulp-imagemin";
+import imageminGifsicle from "imagemin-gifsicle";
+import imageminJpegtran from "imagemin-jpegtran";
+import imageminPngquant from "imagemin-pngquant";
+import { imageResourcesGlobs, nonImageResourcesGlobs } from "./config.js";
+
+// Lossless options
+const minifyImagesOptsLossless = () => [
+ imageminJpegtran({
+ progressive: true,
+ }),
+ gulpImagemin.svgo({}),
+ gulpImagemin.optipng({
+ optimizationLevel: 3,
+ }),
+ imageminGifsicle({
+ optimizationLevel: 3,
+ colors: 128,
+ }),
+];
+
+// Lossy options
+const minifyImagesOpts = () => [
+ gulpImagemin.mozjpeg({
+ quality: 80,
+ maxMemory: 1024 * 1024 * 8,
+ }),
+ gulpImagemin.svgo({}),
+ imageminPngquant({
+ speed: 1,
+ strip: true,
+ quality: [0.65, 0.9],
+ dithering: false,
+ verbose: false,
+ }),
+ gulpImagemin.optipng({
+ optimizationLevel: 3,
+ }),
+ imageminGifsicle({
+ optimizationLevel: 3,
+ colors: 128,
+ }),
+];
+
+// Where the resources folder are
+const resourcesDestFolder = path.join(buildFolder, "res");
+
+/**
+ * Determines if an atlas must use lossless compression
+ * @param {string} fname
+ */
+function fileMustBeLossless(fname) {
+ return fname.indexOf("lossless") >= 0;
+}
+
+/////////////// ATLAS /////////////////////
+
+export async function buildAtlas() {
+ const config = JSON.stringify("../res_raw/atlas.json");
+ const source = JSON.stringify("../res_raw");
+ const dest = JSON.stringify("../res_built/atlas");
+
+ try {
+ await execute(`java -jar runnable-texturepacker.jar ${source} ${dest} atlas0 ${config}`);
+ } catch {
+ console.warn("Building atlas failed. Java not found / unsupported version?");
+ }
+}
+
+// Converts .atlas LibGDX files to JSON
+export async function atlasToJson() {
+ atlas2Json("../res_built/atlas");
+}
+
+// Copies the atlas to the final destination
+export function atlas() {
+ return gulp.src("../res_built/atlas/*.png").pipe(gulp.dest(resourcesDestFolder));
+}
+
+// Copies the atlas to the final destination after optimizing it (lossy compression)
+export function atlasOptimized() {
+ return gulp
+ .src(["../res_built/atlas/*.png"])
+ .pipe(
+ gulpIf(
+ fname => fileMustBeLossless(fname.history[0]),
+ gulpImagemin(minifyImagesOptsLossless()),
+ gulpImagemin(minifyImagesOpts())
+ )
+ )
+ .pipe(gulp.dest(resourcesDestFolder));
+}
+
+//////////////////// RESOURCES //////////////////////
+
+// Copies all resources which are no ui resources
+export function copyNonImageResources() {
+ return gulp.src(nonImageResourcesGlobs).pipe(gulp.dest(resourcesDestFolder));
+}
+
+// Copies all ui resources
+export function copyImageResources() {
+ return gulp
+ .src(imageResourcesGlobs)
+ .pipe(gulpCached("imgres.copyImageResources"))
+ .pipe(gulp.dest(path.join(resourcesDestFolder)));
+}
+
+// Copies all ui resources and optimizes them
+export function copyImageResourcesOptimized() {
+ return gulp
+ .src(imageResourcesGlobs)
+ .pipe(
+ gulpIf(
+ fname => fileMustBeLossless(fname.history[0]),
+ gulpImagemin(minifyImagesOptsLossless()),
+ gulpImagemin(minifyImagesOpts())
+ )
+ )
+ .pipe(gulp.dest(path.join(resourcesDestFolder)));
+}
+
+// Copies all resources and optimizes them
+export const allOptimized = gulp.parallel(
+ gulp.series(buildAtlas, atlasToJson, atlasOptimized),
+ copyNonImageResources,
+ copyImageResourcesOptimized
+);
+
+// Cleans up unused images which are instead inline into the css
+export function cleanupUnusedCssInlineImages() {
+ return gulp
+ .src(
+ [
+ path.join(buildFolder, "res", "ui", "**", "*.png"),
+ path.join(buildFolder, "res", "ui", "**", "*.jpg"),
+ path.join(buildFolder, "res", "ui", "**", "*.svg"),
+ path.join(buildFolder, "res", "ui", "**", "*.gif"),
+ ],
+ { read: false }
+ )
+ .pipe(gulpIf(fname => fname.history[0].indexOf("noinline") < 0, gulpClean({ force: true })));
+}
diff --git a/gulp/js.js b/gulp/js.js
index 085a9d74..06a4ae3d 100644
--- a/gulp/js.js
+++ b/gulp/js.js
@@ -1,10 +1,12 @@
-const path = require("path");
-const { BUILD_VARIANTS } = require("./build_variants");
+import gulp from "gulp";
+import webpack from "webpack";
+import { BUILD_VARIANTS } from "./build_variants.js";
+import { buildFolder } from "./config.js";
-function requireUncached(module) {
- delete require.cache[require.resolve(module)];
- return require(module);
-}
+import webpackConfig from "./webpack.config.js";
+import webpackProductionConfig from "./webpack.production.config.js";
+
+import webpackStream from "webpack-stream";
/**
* PROVIDES (per )
@@ -15,115 +17,28 @@ function requireUncached(module) {
*
*/
-function gulptasksJS($, gulp, buildFolder, browserSync) {
- //// DEV
-
- for (const variant in BUILD_VARIANTS) {
- const data = BUILD_VARIANTS[variant];
-
- gulp.task("js." + variant + ".dev.watch", () => {
- return gulp
- .src("../src/js/main.js")
- .pipe(
- $.webpackStream(
- requireUncached("./webpack.config.js")({
- ...data.buildArgs,
- standalone: data.standalone,
- watch: true,
- })
- )
- )
- .pipe(gulp.dest(buildFolder))
- .pipe(browserSync.stream());
- });
-
- if (!data.standalone) {
- // WEB
-
- gulp.task("js." + variant + ".dev", () => {
+// TODO: Move webpack config to build_variants.js and use a separate
+// build variant for development
+export default Object.fromEntries(
+ Object.entries(BUILD_VARIANTS).map(([variant, data]) => {
+ const dev = {
+ build() {
return gulp
.src("../src/js/main.js")
- .pipe(
- $.webpackStream(
- requireUncached("./webpack.config.js")({
- ...data.buildArgs,
- })
- )
- )
+ .pipe(webpackStream(webpackConfig, webpack))
.pipe(gulp.dest(buildFolder));
- });
+ },
+ };
- gulp.task("js." + variant + ".prod.transpiled", () => {
+ const prod = {
+ build() {
return gulp
.src("../src/js/main.js")
- .pipe(
- $.webpackStream(
- requireUncached("./webpack.production.config.js")({
- es6: false,
- environment: data.environment,
- ...data.buildArgs,
- })
- )
- )
- .pipe($.rename("bundle-transpiled.js"))
+ .pipe(webpackStream(webpackProductionConfig, webpack))
.pipe(gulp.dest(buildFolder));
- });
+ },
+ };
- gulp.task("js." + variant + ".prod.es6", () => {
- return gulp
- .src("../src/js/main.js")
- .pipe(
- $.webpackStream(
- requireUncached("./webpack.production.config.js")({
- es6: true,
- environment: data.environment,
- ...data.buildArgs,
- })
- )
- )
- .pipe(gulp.dest(buildFolder));
- });
- gulp.task(
- "js." + variant + ".prod",
-
- // transpiled currently not used
- // gulp.parallel("js." + variant + ".prod.transpiled", "js." + variant + ".prod.es6")
- gulp.parallel("js." + variant + ".prod.es6")
- );
- } else {
- // STANDALONE
- gulp.task("js." + variant + ".dev", () => {
- return gulp
- .src("../src/js/main.js")
- .pipe(
- $.webpackStream(
- requireUncached("./webpack.config.js")({
- ...data.buildArgs,
- standalone: true,
- })
- )
- )
- .pipe(gulp.dest(buildFolder));
- });
- gulp.task("js." + variant + ".prod", () => {
- return gulp
- .src("../src/js/main.js")
- .pipe(
- $.webpackStream(
- requireUncached("./webpack.production.config.js")({
- ...data.buildArgs,
- environment: "prod",
- es6: true,
- standalone: true,
- })
- )
- )
- .pipe(gulp.dest(buildFolder));
- });
- }
- }
-}
-
-module.exports = {
- gulptasksJS,
-};
+ return [variant, { dev, prod }];
+ })
+);
diff --git a/gulp/jsconfig.json b/gulp/jsconfig.json
deleted file mode 100644
index e28a1c04..00000000
--- a/gulp/jsconfig.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "compilerOptions": {
- "target": "es6",
- "checkJs": true
- }
-}
diff --git a/gulp/loader.compressjson.js b/gulp/loader.compressjson.js
deleted file mode 100644
index 9e80298f..00000000
--- a/gulp/loader.compressjson.js
+++ /dev/null
@@ -1,11 +0,0 @@
-"use strict";
-
-const lzString = require("lz-string");
-
-module.exports = function (source) {
- const compressed = lzString.compressToEncodedURIComponent(source);
- const sourcecode = `module.exports = (function() {
- return JSON.parse(require("global-compression").decompressX64("${compressed}"));
- })()`;
- return sourcecode;
-};
diff --git a/gulp/loader.strip_block.js b/gulp/loader.strip_block.js
deleted file mode 100644
index 31ae5432..00000000
--- a/gulp/loader.strip_block.js
+++ /dev/null
@@ -1,21 +0,0 @@
-/*jslint node:true */
-"use strict";
-
-const startComment = "typehints:start";
-const endComment = "typehints:end";
-const regexPattern = new RegExp(
- "[\\t ]*\\/\\* ?" + startComment + " ?\\*\\/[\\s\\S]*?\\/\\* ?" + endComment + " ?\\*\\/[\\t ]*\\n?",
- "g"
-);
-
-function StripBlockLoader(content) {
- if (content.indexOf(startComment) >= 0) {
- content = content.replace(regexPattern, "");
- }
- if (this.cacheable) {
- this.cacheable(true);
- }
- return content;
-}
-
-module.exports = StripBlockLoader;
diff --git a/gulp/local-config.js b/gulp/local-config.js
deleted file mode 100644
index 108749e0..00000000
--- a/gulp/local-config.js
+++ /dev/null
@@ -1,18 +0,0 @@
-const path = require("path");
-const fs = require("fs");
-const fse = require("fs-extra");
-
-const configTemplatePath = path.join(__dirname, "../src/js/core/config.local.template.js");
-const configPath = path.join(__dirname, "../src/js/core/config.local.js");
-
-function gulptasksLocalConfig($, gulp) {
- gulp.task("localConfig.findOrCreate", cb => {
- if (!fs.existsSync(configPath)) {
- fse.copySync(configTemplatePath, configPath);
- }
-
- cb();
- });
-}
-
-module.exports = { gulptasksLocalConfig };
diff --git a/gulp/mod.js b/gulp/mod.js
deleted file mode 100644
index ad6cd4ae..00000000
--- a/gulp/mod.js
+++ /dev/null
@@ -1,39 +0,0 @@
-const oneExport = exp => {
- return `${exp}=v`; // No checks needed
-};
-
-const twoExports = (exp1, exp2) => {
- return `n=="${exp1}"?${exp1}=v:${exp2}=v`;
-};
-
-const multiExports = exps => {
- exps = exps.map(exp => `case "${exp}":${exp}=v;break;`);
-
- return `switch(n){${exps.toString().replaceAll(";,", ";")} }`;
-};
-
-const defineFnBody = source => {
- const regex = /export (?:let|class) (?\w+)/g;
- let names = [...source.matchAll(regex)].map(n => n.groups.name);
- switch (names.length) {
- case 0:
- return false;
- case 1:
- return oneExport(names[0]);
- case 2:
- return twoExports(names[0], names[1]);
- default:
- return multiExports(names);
- }
-};
-/**
- *
- * @param {string} source
- * @param {*} map
- * @returns
- */
-module.exports = function (source, map) {
- const body = defineFnBody(source);
- if (!body) return source;
- return source + `\nexport const __$S__=(n,v)=>{${body}}`;
-};
diff --git a/gulp/package.json b/gulp/package.json
deleted file mode 100644
index 61dfcaf9..00000000
--- a/gulp/package.json
+++ /dev/null
@@ -1,124 +0,0 @@
-{
- "name": "builder",
- "version": "1.0.0",
- "description": "builder",
- "private": true,
- "scripts": {
- "gulp": "gulp"
- },
- "author": "tobspr",
- "license": "private",
- "browserslist": "> 0.01%",
- "dependencies": {
- "@babel/core": "^7.9.0",
- "@babel/plugin-transform-arrow-functions": "^7.17.12",
- "@babel/plugin-transform-block-scoping": "^7.4.4",
- "@babel/plugin-transform-classes": "^7.5.5",
- "@babel/preset-env": "^7.5.4",
- "@types/cordova": "^0.0.34",
- "@types/filesystem": "^0.0.29",
- "@types/node": "^12.7.5",
- "ajv": "^6.10.2",
- "are-you-es5": "^2.1.2",
- "audiosprite": "^0.7.2",
- "babel-core": "^6.26.3",
- "babel-loader": "^8.1.0",
- "browser-sync": "^2.26.10",
- "circular-dependency-plugin": "^5.0.2",
- "circular-json": "^0.5.9",
- "clipboard-copy": "^3.1.0",
- "colors": "^1.3.3",
- "core-js": "3",
- "crypto": "^1.0.1",
- "cssnano-preset-advanced": "^4.0.7",
- "delete-empty": "^3.0.0",
- "email-validator": "^2.0.4",
- "eslint": "^5.9.0",
- "fastdom": "^1.0.9",
- "flatted": "^2.0.1",
- "fs-extra": "^8.1.0",
- "gifsicle": "^5.2.0",
- "gulp-audiosprite": "^1.1.0",
- "howler": "^2.1.2",
- "html-loader": "^0.5.5",
- "ignore-loader": "^0.1.2",
- "lz-string": "^1.4.4",
- "markdown-loader": "^5.1.0",
- "node-sri": "^1.1.1",
- "phonegap-plugin-mobile-accessibility": "^1.0.5",
- "postcss": ">=5.0.0",
- "promise-polyfill": "^8.1.0",
- "query-string": "^6.8.1",
- "raw-loader": "^4.0.2",
- "rusha": "^0.8.13",
- "stream-browserify": "^3.0.0",
- "strictdom": "^1.0.1",
- "string-replace-webpack-plugin": "^0.1.3",
- "strip-indent": "^3.0.0",
- "terser-webpack-plugin": "^1.1.0",
- "through2": "^3.0.1",
- "uglify-template-string-loader": "^1.1.0",
- "unused-files-webpack-plugin": "^3.4.0",
- "webpack": "^4.43.0",
- "webpack-cli": "^3.1.0",
- "webpack-deep-scope-plugin": "^1.6.0",
- "webpack-plugin-replace": "^1.1.1",
- "webpack-strip-block": "^0.2.0",
- "whatwg-fetch": "^3.0.0",
- "worker-loader": "^2.0.0",
- "yaml": "^1.10.0"
- },
- "devDependencies": {
- "autoprefixer": "^9.4.3",
- "babel-plugin-closure-elimination": "^1.3.0",
- "babel-plugin-console-source": "^2.0.2",
- "babel-plugin-danger-remove-unused-import": "^1.1.2",
- "css-mqpacker": "^7.0.0",
- "cssnano": "^4.1.10",
- "electron-notarize": "^1.2.1",
- "electron-packager": "^15.4.0",
- "faster.js": "^1.1.0",
- "glob": "^7.1.3",
- "gulp": "^4.0.2",
- "gulp-cache": "^1.1.3",
- "gulp-cached": "^1.1.1",
- "gulp-clean": "^0.4.0",
- "gulp-dart-sass": "^1.0.2",
- "gulp-dom": "^1.0.0",
- "gulp-flatten": "^0.4.0",
- "gulp-fluent-ffmpeg": "^2.0.0",
- "gulp-html-beautify": "^1.0.1",
- "gulp-htmlmin": "^5.0.1",
- "gulp-if": "^3.0.0",
- "gulp-imagemin": "^7.1.0",
- "gulp-load-plugins": "^2.0.3",
- "gulp-phonegap-build": "^0.1.5",
- "gulp-plumber": "^1.2.1",
- "gulp-pngquant": "^1.0.13",
- "gulp-postcss": "^8.0.0",
- "gulp-rename": "^2.0.0",
- "gulp-sass-lint": "^1.4.0",
- "gulp-sftp": "git+https://git@github.com/webksde/gulp-sftp",
- "gulp-terser": "^1.2.0",
- "gulp-webserver": "^0.9.1",
- "gulp-yaml": "^2.0.4",
- "imagemin-gifsicle": "^7.0.0",
- "imagemin-jpegtran": "^7.0.0",
- "imagemin-pngquant": "^9.0.0",
- "jimp": "^0.6.1",
- "js-yaml": "^3.13.1",
- "postcss-assets": "^5.0.0",
- "postcss-critical-split": "^2.5.3",
- "postcss-preset-env": "^6.5.0",
- "postcss-round-subpixels": "^1.2.0",
- "postcss-unprefix": "^2.1.3",
- "sass-unused": "^0.3.0",
- "strip-json-comments": "^3.0.1",
- "trim": "^0.0.1",
- "webpack-stream": "^5.2.1",
- "yaml-loader": "^0.6.0"
- },
- "optionalDependencies": {
- "tobspr-osx-sign": "^1.0.1"
- }
-}
diff --git a/gulp/preloader/preloader.css b/gulp/preloader/preloader.css
index f6775f76..3faba330 100644
--- a/gulp/preloader/preloader.css
+++ b/gulp/preloader/preloader.css
@@ -1,16 +1,21 @@
+@font-face {
+ font-family: "GameFont";
+ font-style: normal;
+ font-weight: normal;
+ font-display: swap;
+ src: url("res/fonts/GameFont.woff2") format("woff2");
+}
+
* {
margin: 0;
padding: 0;
- touch-action: pan-x pan-y !important;
+ touch-action: pan-x pan-y;
pointer-events: none;
-webkit-tap-highlight-color: rgba(255, 255, 255, 0);
}
html {
position: fixed;
- -ms-touch-action: pan-x, pan-y;
- touch-action: pan-x, pan-y;
- -ms-content-zooming: none;
top: 0;
left: 0;
bottom: 0;
@@ -21,29 +26,10 @@ html {
body {
color: #555;
user-select: none;
- -moz-user-select: none;
- -ms-user-select: none;
- background: inherit !important;
- text-transform: none;
- white-space: normal;
- word-break: normal;
- word-spacing: normal;
- word-wrap: break-word;
- font-style: normal;
- line-break: auto;
- font-stretch: 100%;
+ background: inherit;
+ overflow-wrap: break-word;
text-rendering: optimizeLegibility;
- text-decoration: none;
- text-size-adjust: 100%;
- letter-spacing: normal;
- scrollbar-width: 6px;
-webkit-font-smoothing: antialiased;
- -webkit-touch-callout: none;
- /* prevent callout to copy image, etc when tap to hold */
- -webkit-text-size-adjust: none;
- /* prevent webkit from resizing text to fit */
- scrollbar-face-color: #888;
- scrollbar-track-color: rgba(255, 255, 255, 0.1);
}
#ll_fp {
@@ -65,8 +51,7 @@ body {
right: 0;
bottom: 0;
justify-content: center;
- justify-items: center;
- align-items: center;
+ place-items: center;
background: #d5d8de;
grid-template-rows: 1fr 200px;
grid-gap: 40px;
@@ -75,7 +60,7 @@ body {
}
#ll_p * {
- line-height: 1em;
+ line-height: 1;
}
#ll_loader {
@@ -92,7 +77,7 @@ body {
font-family: "GameFont", Arial, sans-serif;
font-size: 24px;
height: 30px;
- line-height: 1.2em;
+ line-height: 1.2;
}
#ll_progressbar {
@@ -134,62 +119,12 @@ body {
min-width: 4%;
}
-#ll_progressbar > #ll_loadinglabel {
- position: absolute;
- z-index: 20;
- top: 50%;
- text-transform: uppercase;
- border-radius: 7px;
- left: 50%;
- transform: translate(-50%, -50%);
- font-size: 16px;
- color: #33373f;
-}
-
-@keyframes ShowStandaloneBannerAfterDelay {
- 0% {
- opacity: 0;
- }
- 95% {
- opacity: 0;
- }
- 100% {
- opacity: 1;
- }
-}
-
-#ll_standalone {
- text-align: center;
- color: #777a7f;
- margin-top: 30px;
- display: block;
- font-size: 16px;
- animation: ShowStandaloneBannerAfterDelay 60s linear;
-}
-
-#ll_standalone a {
- color: #39f;
- margin-left: 5px;
- font-weight: bold;
-}
-
-#ll_logo {
-}
-
#ll_logo > img {
width: 40vw;
max-width: 700px;
min-width: 150px;
}
-#ll_loader > .ll_spinner {
- width: 80px;
- height: 80px;
- display: inline-flex;
- background: center center / contain no-repeat;
- display: none;
-}
-
#ll_preload_status {
position: absolute;
top: 40px;
@@ -204,59 +139,3 @@ body {
text-transform: uppercase;
text-align: center;
}
-
-#ll_preload_error {
- position: fixed;
- top: 0;
- right: 0;
- bottom: 0;
- left: 0;
- z-index: 999999;
- background: #d5d8de;
- display: flex;
- justify-content: center;
- align-items: center;
-}
-
-#ll_preload_error > .inner {
- color: #fff;
- font-family: Arial, "sans-serif";
- font-size: 15px;
- padding: 0;
- text-align: center;
-}
-
-#ll_preload_error > .inner > .heading {
- color: #ef5072;
- margin-bottom: 40px;
- font-size: 45px;
-}
-
-#ll_preload_error > .inner > .content {
- color: #55585f;
- font-family: monospace;
- text-align: left;
- background-color: #fff;
- padding: 20px;
- border-radius: 10px;
-
- box-shadow: 0 5px 10px rgba(0, 0, 0, 0.1);
-}
-
-#ll_preload_error > .inner .discordLink {
- color: #333;
- margin-top: 20px;
- margin-bottom: 20px;
- font-family: Arial;
-}
-
-#ll_preload_error > .inner .discordLink a {
- color: #39f;
-}
-#ll_preload_error > .inner .discordLink strong {
- font-weight: 900 !important;
-}
-
-#ll_preload_error > .inner .source {
- color: #777;
-}
diff --git a/gulp/preloader/preloader.html b/gulp/preloader/preloader.html
deleted file mode 100644
index 48d3579c..00000000
--- a/gulp/preloader/preloader.html
+++ /dev/null
@@ -1,21 +0,0 @@
-_
-
-
-
-
-
-
diff --git a/gulp/preloader/preloader.js b/gulp/preloader/preloader.js
deleted file mode 100644
index 7e2fe518..00000000
--- a/gulp/preloader/preloader.js
+++ /dev/null
@@ -1,165 +0,0 @@
-(function () {
- var loadTimeout = null;
- var callbackDone = false;
-
- var searchString = window.location.search;
- if (searchString.includes("steam_sso_auth_token=")) {
- var pos = searchString.indexOf("steam_sso_auth_token");
- const authToken = searchString.substring(pos + 21, pos + 57);
- try {
- window.localStorage.setItem("steam_sso_auth_token", authToken);
- window.location.replace(window.location.protocol + "//" + window.location.host);
- } catch (ex) {
- alert("Failed to login via Steam SSO: " + ex);
- window.location.replace("https://shapez.io");
- }
- return;
- }
-
- // Catch load errors
-
- function errorHandler(event, source, lineno, colno, error) {
- if (("" + event).indexOf("Script error.") >= 0) {
- console.warn("Thirdparty script error:", event);
- return;
- }
-
- if (("" + event).indexOf("NS_ERROR_FAILURE") >= 0) {
- console.warn("Firefox NS_ERROR_FAILURE error:", event);
- return;
- }
-
- if (("" + event).indexOf("Cannot read property 'postMessage' of null") >= 0) {
- console.warn("Safari can not read post message error:", event);
- return;
- }
-
- if (("" + event).indexOf("Possible side-effect in debug-evaluate") >= 0) {
- console.warn("Chrome debug-evaluate error:", event);
- return;
- }
-
- if (("" + source).indexOf("shapez.io") < 0) {
- console.warn("Thirdparty error:", event);
- return;
- }
-
- console.error("👀 App Error:", event, source, lineno, colno, error);
- var element = document.createElement("div");
- element.id = "ll_preload_error";
-
- var inner = document.createElement("div");
- inner.classList.add("inner");
- element.appendChild(inner);
-
- var heading = document.createElement("h3");
- heading.classList.add("heading");
- heading.innerText = "Fatal Error";
- inner.appendChild(heading);
-
- var content = document.createElement("p");
- content.classList.add("content");
- content.innerText = error || (event && event.message) || event || "Unknown Error";
- inner.appendChild(content);
-
- var discordLink = document.createElement("p");
- discordLink.classList.add("discordLink");
- discordLink.innerHTML =
- "Please report this error in the #bugs channel of the official discord !";
-
- inner.appendChild(discordLink);
-
- if (source) {
- var sourceElement = document.createElement("p");
- sourceElement.classList.add("source");
- sourceElement.innerText = source + ":" + lineno + ":" + colno;
- inner.appendChild(sourceElement);
- }
-
- document.documentElement.appendChild(element);
-
- window.APP_ERROR_OCCURED = true;
- }
-
- window.onerror = errorHandler;
-
- function expectJsParsed() {
- if (!callbackDone) {
- console.error("👀 Got no core callback");
- throw new Error("Core thread failed to respond within time.");
- }
- }
-
- function onJsLoaded() {
- console.log("👀 Core loaded at", Math.floor(performance.now()), "ms");
- loadTimeout = setTimeout(expectJsParsed, 120000);
- window.removeEventListener("unhandledrejection", errorHandler);
- }
-
- window.coreThreadLoadedCb = function () {
- console.log("👀 Core responded at", Math.floor(performance.now()), "ms");
- clearTimeout(loadTimeout);
- loadTimeout = null;
- callbackDone = true;
- };
-
- function progressHandler(progress) {
- var progressElement = document.querySelector("#ll_preload_status");
- if (progressElement) {
- progressElement.innerText = "Downloading Bundle (" + Math.round(progress * 1200) + " / 1200 KB)";
- }
- var barElement = document.querySelector("#ll_progressbar span");
- if (barElement) {
- barElement.style.width = (5 + progress * 75.0).toFixed(2) + "%";
- }
- }
-
- function startBundleDownload() {
- var xhr = new XMLHttpRequest();
- var notifiedNotComputable = false;
-
- xhr.open("GET", bundleSrc, true);
- xhr.responseType = "arraybuffer";
- xhr.onprogress = function (ev) {
- if (ev.lengthComputable) {
- progressHandler(ev.loaded / ev.total);
- } else {
- // Hardcoded length
- progressHandler(Math.min(1, ev.loaded / 2349009));
- }
- };
-
- xhr.onloadend = function () {
- if (!xhr.status.toString().match(/^2/)) {
- throw new Error("Failed to load bundle: " + xhr.status + " " + xhr.statusText);
- } else {
- if (!notifiedNotComputable) {
- progressHandler(1);
- }
-
- var options = {};
- var headers = xhr.getAllResponseHeaders();
- var m = headers.match(/^Content-Type\:\s*(.*?)$/im);
-
- if (m && m[1]) {
- options.type = m[1];
- }
-
- var blob = new Blob([this.response], options);
- var script = document.createElement("script");
- script.addEventListener("load", onJsLoaded);
- script.src = window.URL.createObjectURL(blob);
- script.type = "text/javascript";
- script.charset = "utf-8";
- if (bundleIntegrity) {
- script.setAttribute("integrity", bundleIntegrity);
- }
- document.head.appendChild(script);
- }
- };
- xhr.send();
- }
-
- console.log("Start bundle download ...");
- window.addEventListener("load", startBundleDownload);
-})();
diff --git a/gulp/sounds.js b/gulp/sounds.js
index 1cffd897..be0bd3ba 100644
--- a/gulp/sounds.js
+++ b/gulp/sounds.js
@@ -1,134 +1,130 @@
-const path = require("path");
-const audiosprite = require("gulp-audiosprite");
+import gulp from "gulp";
+import path from "path/posix";
+import { buildFolder, generatedCodeFolder } from "./config.js";
-function gulptasksSounds($, gulp, buildFolder) {
- // Gather some basic infos
- const soundsDir = path.join(__dirname, "..", "res_raw", "sounds");
- const builtSoundsDir = path.join(__dirname, "..", "res_built", "sounds");
+import gulpAudiosprite from "gulp-audiosprite";
+import gulpCache from "gulp-cache";
+import gulpClean from "gulp-clean";
+import gulpFluentFfmpeg from "gulp-fluent-ffmpeg";
+import gulpPlumber from "gulp-plumber";
- gulp.task("sounds.clear", () => {
- return gulp.src(builtSoundsDir, { read: false, allowEmpty: true }).pipe($.clean({ force: true }));
- });
+// Gather some basic infos
+const soundsDir = path.join("..", "res_raw", "sounds");
+const builtSoundsDir = path.join("..", "res_built", "sounds");
- const filters = ["volume=0.2"];
+export function clear() {
+ return gulp.src(builtSoundsDir, { read: false, allowEmpty: true }).pipe(gulpClean({ force: true }));
+}
- const fileCache = new $.cache.Cache({
- cacheDirName: "shapezio-precompiled-sounds",
- });
+const filters = ["volume=0.2"];
- function getFileCacheValue(file) {
- const { _isVinyl, base, cwd, contents, history, stat, path } = file;
- const encodedContents = Buffer.from(contents).toString("base64");
- return { _isVinyl, base, cwd, contents: encodedContents, history, stat, path };
- }
+const fileCache = new gulpCache.Cache({
+ cacheDirName: "shapezio-precompiled-sounds",
+});
- // Encodes the game music
- gulp.task("sounds.music", () => {
- return gulp
- .src([path.join(soundsDir, "music", "**", "*.wav"), path.join(soundsDir, "music", "**", "*.mp3")])
- .pipe($.plumber())
- .pipe(
- $.cache(
- $.fluentFfmpeg("mp3", function (cmd) {
- return cmd
- .audioBitrate(48)
- .audioChannels(1)
- .audioFrequency(22050)
- .audioCodec("libmp3lame")
- .audioFilters(["volume=0.15"]);
- }),
- {
- name: "music",
- fileCache,
- value: getFileCacheValue,
- }
- )
- )
- .pipe(gulp.dest(path.join(builtSoundsDir, "music")));
- });
+function getFileCacheValue(file) {
+ const { _isVinyl, base, cwd, contents, history, stat, path } = file;
+ const encodedContents = Buffer.from(contents).toString("base64");
+ return { _isVinyl, base, cwd, contents: encodedContents, history, stat, path };
+}
- // Encodes the game music in high quality for the standalone
- gulp.task("sounds.musicHQ", () => {
- return gulp
- .src([path.join(soundsDir, "music", "**", "*.wav"), path.join(soundsDir, "music", "**", "*.mp3")])
- .pipe($.plumber())
- .pipe(
- $.cache(
- $.fluentFfmpeg("mp3", function (cmd) {
- return cmd
- .audioBitrate(256)
- .audioChannels(2)
- .audioFrequency(44100)
- .audioCodec("libmp3lame")
- .audioFilters(["volume=0.15"]);
- }),
- {
- name: "music-high-quality",
- fileCache,
- value: getFileCacheValue,
- }
- )
- )
- .pipe(gulp.dest(path.join(builtSoundsDir, "music")));
- });
-
- // Encodes the ui sounds
- gulp.task("sounds.sfxGenerateSprites", () => {
- return gulp
- .src([path.join(soundsDir, "sfx", "**", "*.wav"), path.join(soundsDir, "sfx", "**", "*.mp3")])
- .pipe($.plumber())
- .pipe(
- audiosprite({
- format: "howler",
- output: "sfx",
- gap: 0.1,
- export: "mp3",
- })
- )
- .pipe(gulp.dest(path.join(builtSoundsDir)));
- });
- gulp.task("sounds.sfxOptimize", () => {
- return gulp
- .src([path.join(builtSoundsDir, "sfx.mp3")])
- .pipe($.plumber())
- .pipe(
- $.fluentFfmpeg("mp3", function (cmd) {
+// Encodes the game music
+export function music() {
+ return gulp
+ .src([path.join(soundsDir, "music", "**", "*.wav"), path.join(soundsDir, "music", "**", "*.mp3")])
+ .pipe(gulpPlumber())
+ .pipe(
+ gulpCache(
+ gulpFluentFfmpeg("mp3", function (cmd) {
return cmd
- .audioBitrate(128)
+ .audioBitrate(48)
.audioChannels(1)
.audioFrequency(22050)
.audioCodec("libmp3lame")
- .audioFilters(filters);
- })
+ .audioFilters(["volume=0.15"]);
+ }),
+ {
+ name: "music",
+ fileCache,
+ value: getFileCacheValue,
+ }
)
- .pipe(gulp.dest(path.join(builtSoundsDir)));
- });
- gulp.task("sounds.sfxCopyAtlas", () => {
- return gulp
- .src([path.join(builtSoundsDir, "sfx.json")])
- .pipe(gulp.dest(path.join(__dirname, "..", "src", "js", "built-temp")));
- });
-
- gulp.task(
- "sounds.sfx",
- gulp.series("sounds.sfxGenerateSprites", "sounds.sfxOptimize", "sounds.sfxCopyAtlas")
- );
-
- gulp.task("sounds.copy", () => {
- return gulp
- .src(path.join(builtSoundsDir, "**", "*.mp3"))
- .pipe($.plumber())
- .pipe(gulp.dest(path.join(buildFolder, "res", "sounds")));
- });
-
- gulp.task("sounds.buildall", gulp.parallel("sounds.music", "sounds.sfx"));
- gulp.task("sounds.buildallHQ", gulp.parallel("sounds.musicHQ", "sounds.sfx"));
-
- gulp.task("sounds.fullbuild", gulp.series("sounds.clear", "sounds.buildall", "sounds.copy"));
- gulp.task("sounds.fullbuildHQ", gulp.series("sounds.clear", "sounds.buildallHQ", "sounds.copy"));
- gulp.task("sounds.dev", gulp.series("sounds.buildall", "sounds.copy"));
+ )
+ .pipe(gulp.dest(path.join(builtSoundsDir, "music")));
}
-module.exports = {
- gulptasksSounds,
-};
+// Encodes the game music in high quality for the standalone
+export function musicHQ() {
+ return gulp
+ .src([path.join(soundsDir, "music", "**", "*.wav"), path.join(soundsDir, "music", "**", "*.mp3")])
+ .pipe(gulpPlumber())
+ .pipe(
+ gulpCache(
+ gulpFluentFfmpeg("mp3", function (cmd) {
+ return cmd
+ .audioBitrate(256)
+ .audioChannels(2)
+ .audioFrequency(44100)
+ .audioCodec("libmp3lame")
+ .audioFilters(["volume=0.15"]);
+ }),
+ {
+ name: "music-high-quality",
+ fileCache,
+ value: getFileCacheValue,
+ }
+ )
+ )
+ .pipe(gulp.dest(path.join(builtSoundsDir, "music")));
+}
+
+// Encodes the ui sounds
+export function sfxGenerateSprites() {
+ return gulp
+ .src([path.join(soundsDir, "sfx", "**", "*.wav"), path.join(soundsDir, "sfx", "**", "*.mp3")])
+ .pipe(gulpPlumber())
+ .pipe(
+ gulpAudiosprite({
+ format: "howler",
+ output: "sfx",
+ gap: 0.1,
+ export: "mp3",
+ })
+ )
+ .pipe(gulp.dest(path.join(builtSoundsDir)));
+}
+export function sfxOptimize() {
+ return gulp
+ .src([path.join(builtSoundsDir, "sfx.mp3")])
+ .pipe(gulpPlumber())
+ .pipe(
+ gulpFluentFfmpeg("mp3", function (cmd) {
+ return cmd
+ .audioBitrate(128)
+ .audioChannels(1)
+ .audioFrequency(22050)
+ .audioCodec("libmp3lame")
+ .audioFilters(filters);
+ })
+ )
+ .pipe(gulp.dest(path.join(builtSoundsDir)));
+}
+export function sfxCopyAtlas() {
+ return gulp.src([path.join(builtSoundsDir, "sfx.json")]).pipe(gulp.dest(generatedCodeFolder));
+}
+
+export const sfx = gulp.series(sfxGenerateSprites, sfxOptimize, sfxCopyAtlas);
+
+export function copy() {
+ return gulp
+ .src(path.join(builtSoundsDir, "**", "*.mp3"))
+ .pipe(gulpPlumber())
+ .pipe(gulp.dest(path.join(buildFolder, "res", "sounds")));
+}
+
+export const buildall = gulp.parallel(music, sfx);
+export const buildallHQ = gulp.parallel(musicHQ, sfx);
+
+export const fullbuild = gulp.series(clear, buildall, copy);
+export const fullbuildHQ = gulp.series(clear, buildallHQ, copy);
+export const dev = gulp.series(buildall, copy);
diff --git a/gulp/standalone.js b/gulp/standalone.js
index b70ef04c..9eabdc0d 100644
--- a/gulp/standalone.js
+++ b/gulp/standalone.js
@@ -1,339 +1,121 @@
-require("colors");
-const packager = require("electron-packager");
-const pj = require("../electron/package.json");
-const path = require("path");
-const { getVersion } = require("./buildutils");
-const fs = require("fs");
-const fse = require("fs-extra");
-const buildutils = require("./buildutils");
-const execSync = require("child_process").execSync;
-const electronNotarize = require("electron-notarize");
-const { BUILD_VARIANTS } = require("./build_variants");
+import { packager } from "@electron/packager";
+import fs from "fs/promises";
+import gulp from "gulp";
+import path from "path/posix";
+import electronPackageJson from "../electron/package.json" with { type: "json" };
+import { BUILD_VARIANTS } from "./build_variants.js";
+import { getVersion } from "./buildutils.js";
+import { buildProject } from "./typescript.js";
-let signAsync;
-try {
- signAsync = require("tobspr-osx-sign").signAsync;
-} catch (ex) {
- console.warn("tobspr-osx-sign not installed, can not create osx builds");
-}
+import gulpClean from "gulp-clean";
-function gulptasksStandalone($, gulp) {
- for (const variant in BUILD_VARIANTS) {
- const variantData = BUILD_VARIANTS[variant];
- if (!variantData.standalone) {
- continue;
- }
- const tempDestDir = path.join(__dirname, "..", "build_output", variant);
- const taskPrefix = "standalone." + variant;
- const electronBaseDir = path.join(__dirname, "..", variantData.electronBaseDir || "electron");
- const tempDestBuildDir = path.join(tempDestDir, "built");
+const platforms = /** @type {const} */ (["win32", "linux", "darwin"]);
+const architectures = /** @type {const} */ (["x64", "arm64"]);
- gulp.task(taskPrefix + ".prepare.cleanup", () => {
- return gulp.src(tempDestDir, { read: false, allowEmpty: true }).pipe($.clean({ force: true }));
- });
+export default Object.fromEntries(
+ Object.entries(BUILD_VARIANTS)
+ .filter(([variant, variantData]) => variantData.standalone)
+ .map(([variant, variantData]) => {
+ const tempDestDir = path.join("..", "build_output", variant);
+ const electronBaseDir = path.join("..", "electron");
+ const tempDestBuildDir = path.join(tempDestDir, "built");
- gulp.task(taskPrefix + ".prepare.copyPrefab", () => {
- const requiredFiles = [
- path.join(electronBaseDir, "node_modules", "**", "*.*"),
- path.join(electronBaseDir, "node_modules", "**", ".*"),
- path.join(electronBaseDir, "wegame_sdk", "**", "*.*"),
- path.join(electronBaseDir, "wegame_sdk", "**", ".*"),
- path.join(electronBaseDir, "favicon*"),
- ];
- return gulp.src(requiredFiles, { base: electronBaseDir }).pipe(gulp.dest(tempDestBuildDir));
- });
+ function cleanup() {
+ return gulp
+ .src(tempDestDir, { read: false, allowEmpty: true })
+ .pipe(gulpClean({ force: true }));
+ }
- gulp.task(taskPrefix + ".prepare.writeAppId", cb => {
- if (variantData.steamAppId) {
- fs.writeFileSync(
- path.join(tempDestBuildDir, "steam_appid.txt"),
- String(variantData.steamAppId)
+ function copyPrefab() {
+ const requiredFiles = ["preload.cjs", "node_modules/**/*", "favicon*"];
+ return gulp
+ .src(requiredFiles, { cwd: electronBaseDir, cwdbase: true, dot: true })
+ .pipe(gulp.dest(tempDestBuildDir));
+ }
+
+ async function transpileTypeScript() {
+ const tsconfigPath = path.join(electronBaseDir, "tsconfig.json");
+ const outDir = path.join(tempDestBuildDir, "dist");
+
+ buildProject(tsconfigPath, undefined, outDir);
+ return Promise.resolve();
+ }
+
+ async function writePackageJson() {
+ const pkgJson = structuredClone(electronPackageJson);
+ pkgJson.version = getVersion();
+ delete pkgJson.scripts;
+
+ const packageJsonString = JSON.stringify(pkgJson);
+ await fs.writeFile(path.join(tempDestBuildDir, "package.json"), packageJsonString);
+ }
+
+ function copyGamefiles() {
+ return gulp.src("../build/**/*.*", { base: "../build" }).pipe(gulp.dest(tempDestBuildDir));
+ }
+
+ const prepare = {
+ cleanup,
+ copyPrefab,
+ transpileTypeScript,
+ writePackageJson,
+ copyGamefiles,
+ all: gulp.series(cleanup, copyPrefab, transpileTypeScript, writePackageJson, copyGamefiles),
+ };
+
+ /**
+ *
+ * @param {typeof platforms[number] | (typeof platforms[number])[]} platform
+ * @param {typeof architectures[number] | (typeof architectures[number])[]} arch
+ */
+ async function packageStandalone(platform, arch) {
+ const appPaths = await packager({
+ dir: tempDestBuildDir,
+ appCopyright: "tobspr Games",
+ appVersion: getVersion(),
+ buildVersion: "1.0.0",
+ arch,
+ platform,
+ asar: true,
+ executableName: "shapezio",
+ icon: path.join(electronBaseDir, "favicon"),
+ name: "shapez",
+ out: tempDestDir,
+ overwrite: true,
+ appBundleId: "tobspr.shapezio." + variant,
+ appCategoryType: "public.app-category.games",
+ });
+
+ console.log("Packages created:", appPaths);
+ await Promise.all(
+ appPaths.map(async appPath => {
+ await fs.writeFile(
+ path.join(appPath, "LICENSE"),
+ await fs.readFile(path.join("..", "LICENSE"))
+ );
+ })
);
}
- cb();
- });
- gulp.task(taskPrefix + ".prepare.writePackageJson", cb => {
- const packageJsonString = JSON.stringify(
+ const pack = {
+ ...Object.fromEntries(
+ platforms.flatMap(platform =>
+ architectures.map(arch => [
+ `${platform}-${arch}`,
+ () => packageStandalone(platform, arch),
+ ])
+ )
+ ),
+ // TODO: Review this hack forced by readonly types
+ all: () => packageStandalone([...platforms], [...architectures]),
+ };
+
+ return [
+ variant,
{
- scripts: {
- start: pj.scripts.start,
- },
- devDependencies: pj.devDependencies,
- dependencies: pj.dependencies,
- optionalDependencies: pj.optionalDependencies,
+ prepare,
+ package: pack,
},
- null,
- 4
- );
-
- fs.writeFileSync(path.join(tempDestBuildDir, "package.json"), packageJsonString);
-
- cb();
- });
-
- gulp.task(taskPrefix + ".prepare.minifyCode", () => {
- return gulp.src(path.join(electronBaseDir, "*.js")).pipe(gulp.dest(tempDestBuildDir));
- });
-
- gulp.task(taskPrefix + ".prepare.copyGamefiles", () => {
- return gulp.src("../build/**/*.*", { base: "../build" }).pipe(gulp.dest(tempDestBuildDir));
- });
-
- gulp.task(taskPrefix + ".killRunningInstances", cb => {
- try {
- execSync("taskkill /F /IM shapezio.exe");
- } catch (ex) {
- console.warn("Failed to kill running instances, maybe none are up.");
- }
- cb();
- });
-
- gulp.task(
- taskPrefix + ".prepare",
- gulp.series(
- taskPrefix + ".killRunningInstances",
- taskPrefix + ".prepare.cleanup",
- taskPrefix + ".prepare.copyPrefab",
- taskPrefix + ".prepare.writePackageJson",
- taskPrefix + ".prepare.minifyCode",
- taskPrefix + ".prepare.copyGamefiles",
- taskPrefix + ".prepare.writeAppId"
- )
- );
-
- /**
- *
- * @param {'win32'|'linux'|'darwin'} platform
- * @param {'x64'|'ia32'} arch
- * @param {function():void} cb
- */
- function packageStandalone(platform, arch, cb, isRelease = true) {
- const privateArtifactsPath = "node_modules/shapez.io-private-artifacts";
-
- // Only use asar on steam builds (not supported by wegame)
- let asar = Boolean(variantData.steamAppId);
-
- // Unpack private artifacts though
- if (asar && fs.existsSync(path.join(tempDestBuildDir, privateArtifactsPath))) {
- // @ts-expect-error
- asar = { unpackDir: privateArtifactsPath };
- }
-
- packager({
- dir: tempDestBuildDir,
- appCopyright: "tobspr Games",
- appVersion: getVersion(),
- buildVersion: "1.0.0",
- arch,
- platform,
- asar: asar,
- executableName: "shapezio",
- icon: path.join(electronBaseDir, "favicon"),
- name: "shapez",
- out: tempDestDir,
- overwrite: true,
- appBundleId: "tobspr.shapezio." + variant,
- appCategoryType: "public.app-category.games",
- ...(isRelease &&
- platform === "darwin" && {
- osxSign: {
- "identity": process.env.SHAPEZ_CLI_APPLE_CERT_NAME,
- "hardenedRuntime": true,
- "entitlements": "entitlements.plist",
- "entitlements-inherit": "entitlements.plist",
- // @ts-ignore
- "signatureFlags": ["library"],
- "version": "16.0.7",
- },
- osxNotarize: {
- appleId: process.env.SHAPEZ_CLI_APPLE_ID,
- appleIdPassword: process.env.SHAPEZ_CLI_APPLE_APP_PW,
- },
- }),
- }).then(
- appPaths => {
- console.log("Packages created:", appPaths);
- appPaths.forEach(appPath => {
- if (!fs.existsSync(appPath)) {
- console.error("Bad app path:", appPath);
- return;
- }
-
- if (variantData.steamAppId) {
- fs.writeFileSync(
- path.join(appPath, "LICENSE"),
- fs.readFileSync(path.join(__dirname, "..", "LICENSE"))
- );
-
- fs.writeFileSync(
- path.join(appPath, "steam_appid.txt"),
- String(variantData.steamAppId)
- );
-
- if (platform === "linux") {
- // Write launcher script
- fs.writeFileSync(
- path.join(appPath, "play.sh"),
- '#!/usr/bin/env bash\n./shapezio --no-sandbox "$@"\n'
- );
- fs.chmodSync(path.join(appPath, "play.sh"), 0o775);
- }
-
- if (platform === "darwin") {
- if (!isRelease) {
- // Needs special location
- fs.writeFileSync(
- path.join(
- appPath,
- "shapez.app",
- "Contents",
- "MacOS",
- "steam_appid.txt"
- ),
- String(variantData.steamAppId)
- );
- }
- }
- }
- });
-
- cb();
- },
- err => {
- console.error("Packaging error:", err);
- cb();
- }
- );
- }
-
- // Manual signing with patched @electron/osx-sign (we need --no-strict)
- gulp.task(taskPrefix + ".package.darwin64", cb =>
- packageStandalone(
- "darwin",
- "x64",
- () => {
- const appFile = path.join(tempDestDir, "shapez-darwin-x64");
- const appFileInner = path.join(appFile, "shapez.app");
- console.warn("++ Signing ++");
-
- if (variantData.steamAppId) {
- const appIdDest = path.join(
- path.join(appFileInner, "Contents", "MacOS"),
- "steam_appid.txt"
- );
- // console.warn("++ Preparing ++");
- // fse.copySync(path.join(tempDestBuildDir, "steam_appid.txt"), appIdDest);
-
- console.warn("Signing steam_appid.txt");
-
- execSync(
- `codesign --force --verbose --options runtime --timestamp --no-strict --sign "${
- process.env.SHAPEZ_CLI_APPLE_CERT_NAME
- }" --entitlements "${path.join(__dirname, "entitlements.plist")}" ${appIdDest}`,
- {
- cwd: appFile,
- }
- );
- }
-
- console.warn("Base dir:", appFile);
-
- signAsync({
- app: appFileInner,
- hardenedRuntime: true,
- identity: process.env.SHAPEZ_CLI_APPLE_CERT_NAME,
- strictVerify: false,
-
- version: "16.0.7",
- type: "distribution",
- optionsForFile: f => {
- return {
- entitlements: path.join(__dirname, "entitlements.plist"),
- hardenedRuntime: true,
- signatureFlags: ["runtime"],
- };
- },
- }).then(() => {
- execSync(`codesign --verify --verbose ${path.join(appFile, "shapez.app")}`, {
- cwd: appFile,
- });
-
- console.warn("++ Notarizing ++");
- electronNotarize
- .notarize({
- appPath: path.join(appFile, "shapez.app"),
- tool: "legacy",
- appBundleId: "tobspr.shapezio.standalone",
-
- appleId: process.env.SHAPEZ_CLI_APPLE_ID,
- appleIdPassword: process.env.SHAPEZ_CLI_APPLE_APP_PW,
- teamId: process.env.SHAPEZ_CLI_APPLE_TEAM_ID,
- })
- .then(() => {
- console.warn("-> Notarized!");
- cb();
- });
- });
- },
- false
- )
- );
-
- gulp.task(taskPrefix + ".package.win64", cb => packageStandalone("win32", "x64", cb));
- gulp.task(taskPrefix + ".package.linux64", cb => packageStandalone("linux", "x64", cb));
- gulp.task(
- taskPrefix + ".build-from-windows",
- gulp.series(
- taskPrefix + ".prepare",
- gulp.parallel(taskPrefix + ".package.win64", taskPrefix + ".package.linux64")
- )
- );
- gulp.task(
- taskPrefix + ".build-from-darwin",
- gulp.series(taskPrefix + ".prepare", gulp.parallel(taskPrefix + ".package.darwin64"))
- );
- }
-
- // Steam helpers
- gulp.task("standalone.prepareVDF", cb => {
- const hash = buildutils.getRevision();
- const version = buildutils.getVersion();
-
- // for (const platform of ["steampipe", "steampipe-darwin"]) {
- const templatesSource = path.join(__dirname, "steampipe", "templates");
- const templatesDest = path.join(__dirname, "steampipe", "built_vdfs");
-
- const variables = {
- PROJECT_DIR: path.resolve(path.join(__dirname, "..")).replace(/\\/g, "/"),
- BUNDLE_DIR: path.resolve(path.join(__dirname, "..", "build_output")).replace(/\\/g, "/"),
-
- TMP_DIR: path.resolve(path.join(__dirname, "steampipe", "tmp")).replace(/\\/g, "/"),
- // BUILD_DESC: "v" + version + " @ " + hash,
- VDF_DIR: path.resolve(path.join(__dirname, "steampipe", "built_vdfs")).replace(/\\/g, "/"),
- };
-
- const files = fs.readdirSync(templatesSource);
- for (const file of files) {
- if (!file.endsWith(".vdf")) {
- continue;
- }
-
- variables.BUILD_DESC = file.replace(".vdf", "") + " - v" + version + " @ " + hash;
-
- let content = fs.readFileSync(path.join(templatesSource, file)).toString("utf-8");
- content = content.replace(/\$([^$]+)\$/gi, (_, variable) => {
- if (!variables[variable]) {
- throw new Error("Unknown variable " + variable + " in " + file);
- }
-
- return variables[variable];
- });
-
- fs.writeFileSync(path.join(templatesDest, file), content, { encoding: "utf8" });
- }
- cb();
- });
-}
-
-module.exports = { gulptasksStandalone };
+ ];
+ })
+);
diff --git a/gulp/steampipe/.gitignore b/gulp/steampipe/.gitignore
deleted file mode 100644
index 0fced5d4..00000000
--- a/gulp/steampipe/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-steamtemp
diff --git a/gulp/steampipe/templates/app-darwin-demo.vdf b/gulp/steampipe/templates/app-darwin-demo.vdf
deleted file mode 100644
index 4bdb46b1..00000000
--- a/gulp/steampipe/templates/app-darwin-demo.vdf
+++ /dev/null
@@ -1,14 +0,0 @@
-"appbuild"
-{
- "appid" "1930750"
- "desc" "$BUILD_DESC$"
- "buildoutput" "$TMP_DIR$"
- "contentroot" ""
- "setlive" ""
- "preview" "0"
- "local" ""
- "depots"
- {
- "1930756" "$VDF_DIR$/demo-darwin.vdf"
- }
-}
diff --git a/gulp/steampipe/templates/app-darwin.vdf b/gulp/steampipe/templates/app-darwin.vdf
deleted file mode 100644
index fa63b846..00000000
--- a/gulp/steampipe/templates/app-darwin.vdf
+++ /dev/null
@@ -1,14 +0,0 @@
-"appbuild"
-{
- "appid" "1318690"
- "desc" "$BUILD_DESC$"
- "buildoutput" "$TMP_DIR$"
- "contentroot" ""
- "setlive" ""
- "preview" "0"
- "local" ""
- "depots"
- {
- "1318693" "$VDF_DIR$/standalone-darwin.vdf"
- }
-}
diff --git a/gulp/steampipe/templates/app-winlinux-demo.vdf b/gulp/steampipe/templates/app-winlinux-demo.vdf
deleted file mode 100644
index b4859b8b..00000000
--- a/gulp/steampipe/templates/app-winlinux-demo.vdf
+++ /dev/null
@@ -1,17 +0,0 @@
-"appbuild"
-{
- "appid" "1930750"
- "desc" "$BUILD_DESC$"
- "buildoutput" "$TMP_DIR$"
- "contentroot" ""
- "setlive" ""
- "preview" "0"
- "local" ""
- "depots"
- {
- "1930753" "$VDF_DIR$/demo-windows.vdf"
- "1930754" "$VDF_DIR$/demo-china-windows.vdf"
- "1930752" "$VDF_DIR$/demo-linux.vdf"
- "1930755" "$VDF_DIR$/demo-china-linux.vdf"
- }
-}
diff --git a/gulp/steampipe/templates/app-winlinux.vdf b/gulp/steampipe/templates/app-winlinux.vdf
deleted file mode 100644
index 9fd7f9df..00000000
--- a/gulp/steampipe/templates/app-winlinux.vdf
+++ /dev/null
@@ -1,17 +0,0 @@
-"appbuild"
-{
- "appid" "1318690"
- "desc" "$BUILD_DESC$"
- "buildoutput" "$TMP_DIR$"
- "contentroot" ""
- "setlive" ""
- "preview" "0"
- "local" ""
- "depots"
- {
- "1318691" "$VDF_DIR$\standalone-windows.vdf"
- "1318694" "$VDF_DIR$\standalone-china-windows.vdf"
- "1318692" "$VDF_DIR$\standalone-linux.vdf"
- "1318695" "$VDF_DIR$\standalone-china-linux.vdf"
- }
-}
diff --git a/gulp/steampipe/templates/demo-china-linux.vdf b/gulp/steampipe/templates/demo-china-linux.vdf
deleted file mode 100644
index 2ec63419..00000000
--- a/gulp/steampipe/templates/demo-china-linux.vdf
+++ /dev/null
@@ -1,12 +0,0 @@
-"DepotBuildConfig"
-{
- "DepotID" "1930755"
- "contentroot" "$BUNDLE_DIR$\standalone-steam-china-demo\shapez-linux-x64"
- "FileMapping"
- {
- "LocalPath" "*"
- "DepotPath" "."
- "recursive" "1"
- }
- "FileExclusion" "*.pdb"
-}
\ No newline at end of file
diff --git a/gulp/steampipe/templates/demo-china-windows.vdf b/gulp/steampipe/templates/demo-china-windows.vdf
deleted file mode 100644
index a06b4e9e..00000000
--- a/gulp/steampipe/templates/demo-china-windows.vdf
+++ /dev/null
@@ -1,12 +0,0 @@
-"DepotBuildConfig"
-{
- "DepotID" "1930754"
- "contentroot" "$BUNDLE_DIR$\standalone-steam-china-demo\shapez-win32-x64"
- "FileMapping"
- {
- "LocalPath" "*"
- "DepotPath" "."
- "recursive" "1"
- }
- "FileExclusion" "*.pdb"
-}
\ No newline at end of file
diff --git a/gulp/steampipe/templates/demo-darwin.vdf b/gulp/steampipe/templates/demo-darwin.vdf
deleted file mode 100644
index d0e8f1e2..00000000
--- a/gulp/steampipe/templates/demo-darwin.vdf
+++ /dev/null
@@ -1,12 +0,0 @@
-"DepotBuildConfig"
-{
- "DepotID" "1930756"
- "contentroot" "$BUNDLE_DIR$\standalone-steam-demo\shapez-darwin-x64"
- "FileMapping"
- {
- "LocalPath" "*"
- "DepotPath" "."
- "recursive" "1"
- }
- "FileExclusion" "*.pdb"
-}
\ No newline at end of file
diff --git a/gulp/steampipe/templates/demo-linux.vdf b/gulp/steampipe/templates/demo-linux.vdf
deleted file mode 100644
index 4f2d274f..00000000
--- a/gulp/steampipe/templates/demo-linux.vdf
+++ /dev/null
@@ -1,12 +0,0 @@
-"DepotBuildConfig"
-{
- "DepotID" "1930752"
- "contentroot" "$BUNDLE_DIR$\standalone-steam-demo\shapez-linux-x64"
- "FileMapping"
- {
- "LocalPath" "*"
- "DepotPath" "."
- "recursive" "1"
- }
- "FileExclusion" "*.pdb"
-}
\ No newline at end of file
diff --git a/gulp/steampipe/templates/demo-windows.vdf b/gulp/steampipe/templates/demo-windows.vdf
deleted file mode 100644
index 1b6cdbc7..00000000
--- a/gulp/steampipe/templates/demo-windows.vdf
+++ /dev/null
@@ -1,12 +0,0 @@
-"DepotBuildConfig"
-{
- "DepotID" "1930753"
- "contentroot" "$BUNDLE_DIR$\standalone-steam-demo\shapez-win32-x64"
- "FileMapping"
- {
- "LocalPath" "*"
- "DepotPath" "."
- "recursive" "1"
- }
- "FileExclusion" "*.pdb"
-}
\ No newline at end of file
diff --git a/gulp/steampipe/templates/standalone-china-linux.vdf b/gulp/steampipe/templates/standalone-china-linux.vdf
deleted file mode 100644
index 56b9fe3c..00000000
--- a/gulp/steampipe/templates/standalone-china-linux.vdf
+++ /dev/null
@@ -1,12 +0,0 @@
-"DepotBuildConfig"
-{
- "DepotID" "1318695"
- "contentroot" "$BUNDLE_DIR$\standalone-steam-china\shapez-linux-x64"
- "FileMapping"
- {
- "LocalPath" "*"
- "DepotPath" "."
- "recursive" "1"
- }
- "FileExclusion" "*.pdb"
-}
\ No newline at end of file
diff --git a/gulp/steampipe/templates/standalone-china-windows.vdf b/gulp/steampipe/templates/standalone-china-windows.vdf
deleted file mode 100644
index 469158db..00000000
--- a/gulp/steampipe/templates/standalone-china-windows.vdf
+++ /dev/null
@@ -1,12 +0,0 @@
-"DepotBuildConfig"
-{
- "DepotID" "1318694"
- "contentroot" "$BUNDLE_DIR$\standalone-steam-china\shapez-win32-x64"
- "FileMapping"
- {
- "LocalPath" "*"
- "DepotPath" "."
- "recursive" "1"
- }
- "FileExclusion" "*.pdb"
-}
\ No newline at end of file
diff --git a/gulp/steampipe/templates/standalone-darwin.vdf b/gulp/steampipe/templates/standalone-darwin.vdf
deleted file mode 100644
index 026ab768..00000000
--- a/gulp/steampipe/templates/standalone-darwin.vdf
+++ /dev/null
@@ -1,12 +0,0 @@
-"DepotBuildConfig"
-{
- "DepotID" "1318693"
- "contentroot" "$BUNDLE_DIR$\standalone-steam\shapez-darwin-x64"
- "FileMapping"
- {
- "LocalPath" "*"
- "DepotPath" "."
- "recursive" "1"
- }
- "FileExclusion" "*.pdb"
-}
\ No newline at end of file
diff --git a/gulp/steampipe/templates/standalone-linux.vdf b/gulp/steampipe/templates/standalone-linux.vdf
deleted file mode 100644
index 9edb1963..00000000
--- a/gulp/steampipe/templates/standalone-linux.vdf
+++ /dev/null
@@ -1,12 +0,0 @@
-"DepotBuildConfig"
-{
- "DepotID" "1318692"
- "contentroot" "$BUNDLE_DIR$\standalone-steam\shapez-linux-x64"
- "FileMapping"
- {
- "LocalPath" "*"
- "DepotPath" "."
- "recursive" "1"
- }
- "FileExclusion" "*.pdb"
-}
\ No newline at end of file
diff --git a/gulp/steampipe/templates/standalone-windows.vdf b/gulp/steampipe/templates/standalone-windows.vdf
deleted file mode 100644
index 6f7cb408..00000000
--- a/gulp/steampipe/templates/standalone-windows.vdf
+++ /dev/null
@@ -1,12 +0,0 @@
-"DepotBuildConfig"
-{
- "DepotID" "1318691"
- "contentroot" "$BUNDLE_DIR$\standalone-steam\shapez-win32-x64"
- "FileMapping"
- {
- "LocalPath" "*"
- "DepotPath" "."
- "recursive" "1"
- }
- "FileExclusion" "*.pdb"
-}
\ No newline at end of file
diff --git a/gulp/steampipe/upload-darwin-demo.sh b/gulp/steampipe/upload-darwin-demo.sh
deleted file mode 100755
index 77bb29dc..00000000
--- a/gulp/steampipe/upload-darwin-demo.sh
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/sh
-yarn gulp standalone.prepareVDF
-steamcmd.sh +login $STEAM_UPLOAD_SHAPEZ_ID $STEAM_UPLOAD_SHAPEZ_USER +run_app_build $PWD/built_vdfs/app-darwin-demo.vdf +quit
diff --git a/gulp/steampipe/upload-darwin.sh b/gulp/steampipe/upload-darwin.sh
deleted file mode 100755
index 06412dcd..00000000
--- a/gulp/steampipe/upload-darwin.sh
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/sh
-yarn gulp standalone.prepareVDF
-steamcmd.sh +login $STEAM_UPLOAD_SHAPEZ_ID $STEAM_UPLOAD_SHAPEZ_USER +run_app_build $PWD/built_vdfs/app-darwin.vdf +quit
diff --git a/gulp/steampipe/upload-winlinux-demo.bat b/gulp/steampipe/upload-winlinux-demo.bat
deleted file mode 100644
index e19f7f55..00000000
--- a/gulp/steampipe/upload-winlinux-demo.bat
+++ /dev/null
@@ -1,3 +0,0 @@
-@echo off
-cmd /c yarn gulp standalone.prepareVDF
-steamcmd +login %STEAM_UPLOAD_SHAPEZ_ID% %STEAM_UPLOAD_SHAPEZ_USER% +run_app_build %cd%/built_vdfs/app-winlinux-demo.vdf +quit
diff --git a/gulp/steampipe/upload-winlinux.bat b/gulp/steampipe/upload-winlinux.bat
deleted file mode 100644
index 1c9bdfe7..00000000
--- a/gulp/steampipe/upload-winlinux.bat
+++ /dev/null
@@ -1,3 +0,0 @@
-@echo off
-cmd /c yarn gulp standalone.prepareVDF
-steamcmd +login %STEAM_UPLOAD_SHAPEZ_ID% %STEAM_UPLOAD_SHAPEZ_USER% +run_app_build %cd%/built_vdfs/app-winlinux.vdf +quit
diff --git a/gulp/tasks.js b/gulp/tasks.js
new file mode 100644
index 00000000..a378c68e
--- /dev/null
+++ b/gulp/tasks.js
@@ -0,0 +1,272 @@
+import childProcess from "child_process";
+import delEmpty from "delete-empty";
+import gulp from "gulp";
+import pathNative from "path";
+import path from "path/posix";
+import { promisify } from "util";
+import { BUILD_VARIANTS } from "./build_variants.js";
+import {
+ browserSync,
+ buildFolder,
+ buildOutputFolder,
+ generatedCodeFolder,
+ imageResourcesGlobs,
+ nonImageResourcesGlobs,
+ rawImageResourcesGlobs,
+} from "./config.js";
+const exec = promisify(childProcess.exec);
+
+// Load other plugins
+import gulpClean from "gulp-clean";
+import gulpWebserver from "gulp-webserver";
+
+import * as css from "./css.js";
+import * as environment from "./environment.js";
+import html from "./html.js";
+import * as imgres from "./image-resources.js";
+import js from "./js.js";
+import * as sounds from "./sounds.js";
+import standalone from "./standalone.js";
+import * as translations from "./translations.js";
+
+export { css, environment, html, imgres, js, sounds, standalone, translations };
+
+///////////////////// BUILD TASKS /////////////////////
+
+// Cleans up everything
+function cleanBuildFolder() {
+ return gulp.src(buildFolder, { read: false, allowEmpty: true }).pipe(gulpClean({ force: true }));
+}
+function cleanBuildOutputFolder() {
+ return gulp.src(buildOutputFolder, { read: false, allowEmpty: true }).pipe(gulpClean({ force: true }));
+}
+function cleanBuildTempFolder() {
+ return gulp.src(generatedCodeFolder, { read: false, allowEmpty: true }).pipe(gulpClean({ force: true }));
+}
+function cleanImageBuildFolder() {
+ return gulp
+ .src(path.join("res_built"), { read: false, allowEmpty: true })
+ .pipe(gulpClean({ force: true }));
+}
+
+const cleanup = gulp.parallel(cleanBuildFolder, cleanImageBuildFolder, cleanBuildTempFolder);
+
+// Requires no uncomitted files
+async function requireCleanWorkingTree() {
+ let output = (await exec("git status -su", { encoding: "buffer" })).stdout
+ .toString("ascii")
+ .trim()
+ .replace(/\r/gi, "")
+ .split("\n");
+
+ // Filter files which are OK to be untracked
+ output = output
+ .map(x => x.replace(/[\r\n]+/gi, ""))
+ .filter(x => x.indexOf(".local.js") < 0)
+ .filter(x => x.length > 0);
+ if (output.length > 0) {
+ console.error("\n\nYou have unstaged changes, please commit everything first!");
+ console.error("Unstaged files:");
+ console.error(output.map(x => "'" + x + "'").join("\n"));
+ process.exit(1);
+ }
+}
+
+function copyAdditionalBuildFiles() {
+ const additionalFolder = path.join("additional_build_files");
+ const additionalSrcGlobs = [
+ path.join(additionalFolder, "**/*.*"),
+ path.join(additionalFolder, "**/.*"),
+ path.join(additionalFolder, "**/*"),
+ ];
+
+ return gulp.src(additionalSrcGlobs).pipe(gulp.dest(buildFolder));
+}
+
+export const utils = {
+ cleanBuildFolder,
+ cleanBuildOutputFolder,
+ cleanBuildTempFolder,
+ cleanImageBuildFolder,
+ cleanup,
+ requireCleanWorkingTree,
+ copyAdditionalBuildFiles,
+};
+
+// Starts a webserver on the built directory (useful for testing prod build)
+function webserver() {
+ return gulp.src(buildFolder).pipe(
+ gulpWebserver({
+ livereload: {
+ enable: true,
+ },
+ directoryListing: false,
+ open: true,
+ port: 3005,
+ })
+ );
+}
+
+/**
+ *
+ * @param {object} param0
+ * @param {keyof typeof BUILD_VARIANTS} param0.version
+ */
+async function serveHTML({ version = "web-dev" }) {
+ browserSync.init({
+ server: buildFolder,
+ port: 3005,
+ ghostMode: false,
+ logLevel: "info",
+ logPrefix: "BS",
+ online: false,
+ notify: false,
+ reloadDebounce: 100,
+ watchEvents: ["add", "change"],
+ open: false,
+ });
+
+ gulp.watch("../src/js/**", js[version].dev.build);
+
+ // Watch .scss files, those trigger a css rebuild
+ gulp.watch("../src/css/**", css.dev);
+
+ // Watch .html files, those trigger a html rebuild
+ gulp.watch("../src/html/**", html);
+
+ // Watch translations
+ gulp.watch("../translations/*.yaml", translations.convertToJson);
+
+ gulp.watch(
+ ["../res_raw/sounds/sfx/**/*.mp3", "../res_raw/sounds/sfx/**/*.wav"],
+ gulp.series(sounds.sfx, sounds.copy)
+ );
+ gulp.watch(
+ ["../res_raw/sounds/music/**/*.mp3", "../res_raw/sounds/music/**/*.wav"],
+ gulp.series(sounds.music, sounds.copy)
+ );
+
+ // Watch resource files and copy them on change
+ gulp.watch(rawImageResourcesGlobs, imgres.buildAtlas);
+ gulp.watch(nonImageResourcesGlobs, imgres.copyNonImageResources);
+ gulp.watch(imageResourcesGlobs, imgres.copyImageResources);
+
+ // Watch .atlas files and recompile the atlas on change
+ gulp.watch("../res_built/atlas/*.atlas", imgres.atlasToJson);
+ gulp.watch("../res_built/atlas/*.json", imgres.atlas);
+
+ // Watch the build folder and reload when anything changed
+ gulp.watch(path.join(buildFolder, "**")).on("change", p =>
+ gulp.src(pathNative.resolve(p).replaceAll(pathNative.sep, path.sep)).pipe(browserSync.stream())
+ );
+}
+
+// Pre and postbuild
+const baseResources = imgres.allOptimized;
+async function deleteEmpty() {
+ await delEmpty(buildFolder);
+}
+
+const postbuild = gulp.series(imgres.cleanupUnusedCssInlineImages, deleteEmpty);
+
+export const step = {
+ baseResources,
+ deleteEmpty,
+ postbuild,
+};
+
+///////////////////// RUNNABLE TASKS /////////////////////
+
+// Builds everything (dev)
+const prepare = {
+ dev: variant =>
+ gulp.series(
+ utils.cleanup,
+ gulp.parallel(
+ utils.copyAdditionalBuildFiles,
+ gulp.series(imgres.buildAtlas, gulp.parallel(imgres.atlasToJson, imgres.atlas)),
+ gulp.series(imgres.copyImageResources, css.dev),
+ imgres.copyNonImageResources,
+ html,
+ gulp.series(gulp.parallel(sounds.dev, translations.fullBuild), js[variant].dev.build)
+ )
+ ),
+};
+
+/**
+ * @typedef {import("gulp").TaskFunction} TaskFunction
+ */
+
+export const build =
+ /**
+ * @type {Record & { prepare: typeof prepare }}
+ */
+ ({
+ prepare,
+ });
+/**
+ * @type {Record>}
+ */
+const pack = {};
+export { pack as package };
+/** @type {Record} */
+export const serve = {};
+
+// Builds everything for every variant
+for (const variant in BUILD_VARIANTS) {
+ const data = BUILD_VARIANTS[variant];
+
+ // build
+ const code = gulp.series(
+ data.standalone ? sounds.fullbuildHQ : sounds.fullbuild,
+ translations.fullBuild,
+ js[variant].prod.build
+ );
+
+ const resourcesAndCode = gulp.parallel(step.baseResources, code);
+
+ const all = gulp.series(resourcesAndCode, css.prod, html);
+
+ const full = gulp.series(utils.cleanup, all, step.postbuild);
+
+ build[variant] = { code, resourcesAndCode, all, full };
+
+ // Tasks for creating packages. These packages are already distributable, but usually can be further
+ // wrapped in a different format (an installer for Windows, tarball for Linux, DMG for macOS).
+ if (data.standalone) {
+ const packageTasks = [
+ "win32-x64",
+ "win32-arm64",
+ "linux-x64",
+ "linux-arm64",
+ "darwin-x64",
+ "darwin-arm64",
+ "all",
+ ];
+
+ pack[variant] = {};
+ for (const task of packageTasks) {
+ pack[variant][task] = gulp.series(
+ full,
+ utils.cleanBuildOutputFolder,
+ standalone[variant].prepare.all,
+ standalone[variant].package[task]
+ );
+ }
+ }
+
+ // serve
+ serve[variant] = gulp.series(build.prepare.dev(variant), () => serveHTML({ version: variant }));
+}
+
+export const main = {
+ webserver,
+};
+
+// Default task (dev, localhost)
+export default gulp.series(serve["standalone"]);
diff --git a/gulp/translations.js b/gulp/translations.js
index 88afa989..8813a069 100644
--- a/gulp/translations.js
+++ b/gulp/translations.js
@@ -1,64 +1,18 @@
-const path = require("path");
-const fs = require("fs");
-const gulpYaml = require("gulp-yaml");
-const YAML = require("yaml");
-const stripIndent = require("strip-indent");
-const trim = require("trim");
-
-const translationsSourceDir = path.join(__dirname, "..", "translations");
-const translationsJsonDir = path.join(__dirname, "..", "src", "js", "built-temp");
-
-function gulptasksTranslations($, gulp) {
- gulp.task("translations.convertToJson", () => {
- return gulp
- .src(path.join(translationsSourceDir, "*.yaml"))
- .pipe($.plumber())
- .pipe(gulpYaml({ space: 2, safe: true }))
- .pipe(gulp.dest(translationsJsonDir));
- });
-
- gulp.task("translations.fullBuild", gulp.series("translations.convertToJson"));
-
- gulp.task("translations.prepareSteamPage", cb => {
- const files = fs.readdirSync(translationsSourceDir);
-
- files
- .filter(name => name.endsWith(".yaml"))
- .forEach(fname => {
- console.log("Loading", fname);
- const languageName = fname.replace(".yaml", "");
- const abspath = path.join(translationsSourceDir, fname);
-
- const destpath = path.join(translationsSourceDir, "tmp", languageName + "-store.txt");
-
- const contents = fs.readFileSync(abspath, { encoding: "utf-8" });
- const data = YAML.parse(contents);
-
- const storePage = data.steamPage;
-
- const content = `
- [img]{STEAM_APP_IMAGE}/extras/store_page_gif.gif[/img]
-
- ${storePage.intro.replace(/\n/gi, "\n\n")}
-
- [h2]${storePage.what_others_say}[/h2]
-
- [list]
- [*] [i]${storePage.nothernlion_comment}[/i] [b]- Northernlion, YouTube[/b]
- [*] [i]${storePage.notch_comment}[/i] [b]- Notch[/b]
- [*] [i]${storePage.steam_review_comment}[/i] [b]- Steam User[/b]
- [/list]
- `;
-
- fs.writeFileSync(destpath, trim(content.replace(/(\n[ \t\r]*)/gi, "\n")), {
- encoding: "utf-8",
- });
- });
-
- cb();
- });
-}
-
-module.exports = {
- gulptasksTranslations,
-};
+import gulp from "gulp";
+import path from "path/posix";
+
+import gulpPlumber from "gulp-plumber";
+import gulpYaml from "gulp-yaml";
+import { generatedCodeFolder } from "./config.js";
+
+const translationsSourceDir = path.join("..", "translations");
+
+export function convertToJson() {
+ return gulp
+ .src(path.join(translationsSourceDir, "*.yaml"))
+ .pipe(gulpPlumber())
+ .pipe(gulpYaml({ space: 2, safe: true }))
+ .pipe(gulp.dest(generatedCodeFolder));
+}
+
+export const fullBuild = convertToJson;
diff --git a/gulp/tsconfig.json b/gulp/tsconfig.json
deleted file mode 100644
index 0de5c39f..00000000
--- a/gulp/tsconfig.json
+++ /dev/null
@@ -1,59 +0,0 @@
-{
- "compilerOptions": {
- /* Basic Options */
- "target": "es6" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */,
- "module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */,
- // "lib": [], /* Specify library files to be included in the compilation. */
- "allowJs": true /* Allow javascript files to be compiled. */,
- "checkJs": true /* Report errors in .js files. */,
- // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
- // "declaration": true, /* Generates corresponding '.d.ts' file. */
- // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
- // "sourceMap": true, /* Generates corresponding '.map' file. */
- // "outFile": "./typedefs_gen", /* Concatenate and emit output to single file. */
- // "outDir": "./typedefs_gen", /* Redirect output structure to the directory. */
- // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
- // "composite": true, /* Enable project compilation */
- // "incremental": true, /* Enable incremental compilation */
- // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */
- // "removeComments": true, /* Do not emit comments to output. */
- "noEmit": true /* Do not emit outputs. */,
- // "importHelpers": true, /* Import emit helpers from 'tslib'. */
- // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
- // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
- /* Strict Type-Checking Options */
- // "strict": true, /* Enable all strict type-checking options. */
- // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
- // "strictNullChecks": true, /* Enable strict null checks. */
- "strictFunctionTypes": true /* Enable strict checking of function types. */,
- "strictBindCallApply": true /* Enable strict 'bind', 'call', and 'apply' methods on functions. */,
- // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
- "noImplicitThis": true /* Raise error on 'this' expressions with an implied 'any' type. */,
- "alwaysStrict": true /* Parse in strict mode and emit "use strict" for each source file. */,
- /* Additional Checks */
- // "noUnusedLocals": true, /* Report errors on unused locals. */
- // "noUnusedParameters": true, /* Report errors on unused parameters. */
- // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
- "noFallthroughCasesInSwitch": true /* Report errors for fallthrough cases in switch statement. */,
- /* Module Resolution Options */
- "moduleResolution": "node" /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */,
- // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
- // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
- // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
- // "typeRoots": [], /* List of folders to include type definitions from. */
- // "types": [], /* Type declaration files to be included in compilation. */
- // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
- "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */,
- // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
- /* Source Map Options */
- // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */
- // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
- // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */
- // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
- /* Experimental Options */
- // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
- // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
- "resolveJsonModule": true
- },
- "exclude": ["backend/shared/gameserver_base_impl"]
-}
diff --git a/gulp/typescript.js b/gulp/typescript.js
new file mode 100644
index 00000000..48cb7f72
--- /dev/null
+++ b/gulp/typescript.js
@@ -0,0 +1,66 @@
+import * as path from "path";
+import ts from "typescript";
+
+/**
+ * @param {ts.Diagnostic} diagnostic
+ */
+function printDiagnostic(diagnostic) {
+ if (!diagnostic.file) {
+ console.log(ts.flattenDiagnosticMessageText(diagnostic.messageText, "\n"));
+ return;
+ }
+
+ const { line, character } = ts.getLineAndCharacterOfPosition(diagnostic.file, diagnostic.start);
+ const message = ts.flattenDiagnosticMessageText(diagnostic.messageText, "\n");
+ console.log(`${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`);
+}
+
+/**
+ * Reads the TypeScript compiler configuration from the specified path.
+ * @param {string} configPath Path to the tsconfig.json file
+ * @param {string} baseDir Directory used to resolve relative file paths
+ * @param {string?} outDir Optional override for output directory
+ */
+function readConfig(configPath, baseDir, outDir) {
+ // Please forgive me for this sin, copied from random parts of TS itself
+ const cfgSource = ts.sys.readFile(configPath);
+ const result = ts.parseJsonText(configPath, cfgSource);
+
+ return ts.parseJsonSourceFileConfigFileContent(
+ result,
+ ts.sys,
+ baseDir,
+ outDir ? { outDir } : undefined,
+ configPath
+ );
+}
+
+/**
+ * Builds a TypeScript project.
+ * Mostly based on https://github.com/microsoft/TypeScript/wiki/Using-the-Compiler-API
+ * @param {string} configPath Path to the tsconfig.json file
+ * @param {string?} baseDir Directory used to resolve relative file paths
+ * @param {string?} outDir Optional override for output directory
+ */
+export function buildProject(configPath, baseDir = undefined, outDir = undefined) {
+ configPath = path.resolve(configPath);
+
+ if (baseDir === undefined) {
+ baseDir = path.dirname(configPath);
+ }
+ baseDir = path.resolve(baseDir);
+
+ const config = readConfig(configPath, baseDir, outDir);
+ const program = ts.createProgram(config.fileNames, config.options);
+ const result = program.emit();
+
+ const diagnostics = ts.getPreEmitDiagnostics(program).concat(result.diagnostics);
+ for (const diagnostic of diagnostics) {
+ printDiagnostic(diagnostic);
+ }
+
+ const success = !result.emitSkipped;
+ if (!success) {
+ throw new Error("TypeScript compilation failed! Relevant errors may have been displayed above.");
+ }
+}
diff --git a/gulp/webpack.config.js b/gulp/webpack.config.js
index d0ee4d5f..90c19a4f 100644
--- a/gulp/webpack.config.js
+++ b/gulp/webpack.config.js
@@ -1,127 +1,89 @@
-// @ts-nocheck
+import CircularDependencyPlugin from "circular-dependency-plugin";
+import { resolve } from "path/posix";
+import webpack from "webpack";
+import { getAllResourceImages, getRevision, getVersion } from "./buildutils.js";
-const path = require("path");
-const webpack = require("webpack");
-const { getRevision, getVersion, getAllResourceImages } = require("./buildutils");
-const CircularDependencyPlugin = require("circular-dependency-plugin");
+const globalDefs = {
+ assert: "window.assert",
+ assertAlways: "window.assert",
+ abstract:
+ "window.assert(false, 'abstract method called of: ' + " +
+ "(this.name || (this.constructor && this.constructor.name)));",
+ G_IS_DEV: "true",
+ G_APP_ENVIRONMENT: JSON.stringify("development"),
+ G_BUILD_TIME: new Date().getTime().toString(),
+ G_BUILD_COMMIT_HASH: JSON.stringify(getRevision()),
+ G_BUILD_VERSION: JSON.stringify(getVersion()),
+ G_ALL_UI_IMAGES: JSON.stringify(getAllResourceImages()),
-module.exports = ({
- watch = false,
- standalone = false,
- chineseVersion = false,
- wegameVersion = false,
- steamDemo = false,
- gogVersion = false,
-}) => {
- return {
- mode: "development",
- devtool: "cheap-source-map",
- entry: {
- "bundle.js": [path.resolve(__dirname, "../src/js/main.js")],
- },
- watch,
- node: {
- fs: "empty",
- },
- resolve: {
- alias: {
- "global-compression": path.resolve(__dirname, "..", "src", "js", "core", "lzstring.js"),
- },
- },
- context: path.resolve(__dirname, ".."),
- plugins: [
- new webpack.DefinePlugin({
- assert: "window.assert",
- assertAlways: "window.assert",
- abstract:
- "window.assert(false, 'abstract method called of: ' + (this.name || (this.constructor && this.constructor.name)));",
- G_HAVE_ASSERT: "true",
- G_APP_ENVIRONMENT: JSON.stringify("dev"),
- G_CHINA_VERSION: JSON.stringify(chineseVersion),
- G_WEGAME_VERSION: JSON.stringify(wegameVersion),
- G_GOG_VERSION: JSON.stringify(gogVersion),
- G_IS_DEV: "true",
- G_IS_RELEASE: "false",
- G_IS_BROWSER: "true",
- G_IS_STANDALONE: JSON.stringify(standalone),
- G_IS_STEAM_DEMO: JSON.stringify(steamDemo),
- G_BUILD_TIME: "" + new Date().getTime(),
- G_BUILD_COMMIT_HASH: JSON.stringify(getRevision()),
- G_BUILD_VERSION: JSON.stringify(getVersion()),
- G_ALL_UI_IMAGES: JSON.stringify(getAllResourceImages()),
- }),
-
- new CircularDependencyPlugin({
- // exclude detection of files based on a RegExp
- exclude: /node_modules/,
-
- // add errors to webpack instead of warnings
- failOnError: true,
-
- // allow import cycles that include an asyncronous import,
- // e.g. via import(/* webpackMode: "weak" */ './file.js')
- allowAsyncCycles: false,
-
- // set the current working directory for displaying module paths
- cwd: path.join(__dirname, "..", "src", "js"),
- }),
- ],
- module: {
- rules: [
- {
- test: /\.json$/,
- enforce: "pre",
- use: ["./gulp/loader.compressjson"],
- type: "javascript/auto",
- },
- { test: /\.(png|jpe?g|svg)$/, loader: "ignore-loader" },
- { test: /\.nobuild/, loader: "ignore-loader" },
- {
- test: /\.md$/,
- use: [
- {
- loader: "html-loader",
- },
- "markdown-loader",
- ],
- },
- {
- test: /\.js$/,
- enforce: "pre",
- exclude: /node_modules/,
- use: [
- {
- loader: "webpack-strip-block",
- options: {
- start: "typehints:start",
- end: "typehints:end",
- },
- },
- {
- loader: path.resolve(__dirname, "mod.js"),
- },
- ],
- },
- {
- test: /\.worker\.js$/,
- use: {
- loader: "worker-loader",
- options: {
- fallback: false,
- inline: true,
- },
- },
- },
- {
- test: /\.ya?ml$/,
- type: "json", // Required by Webpack v4
- use: "yaml-loader",
- },
- ],
- },
- output: {
- filename: "bundle.js",
- path: path.resolve(__dirname, "..", "build"),
- },
- };
+ G_IS_RELEASE: "false",
+};
+
+/** @type {import("webpack").RuleSetRule[]} */
+const moduleRules = [
+ {
+ test: /\.jsx?$/,
+ enforce: "pre",
+ exclude: /node_modules/,
+ use: [
+ {
+ loader: "webpack-strip-block",
+ options: {
+ start: "typehints:start",
+ end: "typehints:end",
+ },
+ },
+ ],
+ },
+ {
+ test: /\.[jt]sx?$/,
+ use: [
+ {
+ loader: "ts-loader",
+
+ options: {
+ configFile: resolve("../src/tsconfig.json"),
+ onlyCompileBundledFiles: true,
+ transpileOnly: true,
+ experimentalWatchApi: true,
+ },
+ },
+ ],
+ resolve: {
+ fullySpecified: false,
+ },
+ },
+];
+
+/** @type {import("webpack").Configuration} */
+export default {
+ mode: "development",
+ entry: resolve("../src/js/main.js"),
+ context: resolve(".."),
+ output: {
+ path: resolve("../build"),
+ filename: "bundle.js",
+ },
+ resolve: {
+ fallback: { fs: false },
+ alias: {
+ "@": resolve("../src/js/"),
+ },
+ fullySpecified: false,
+ extensions: [".ts", ".js", ".tsx", ".jsx"],
+ },
+ devtool: "cheap-source-map",
+ cache: false,
+ plugins: [
+ new webpack.DefinePlugin(globalDefs),
+ new webpack.IgnorePlugin({ resourceRegExp: /\.(png|jpe?g|svg)$/ }),
+ new webpack.IgnorePlugin({ resourceRegExp: /\.nobuild/ }),
+ new CircularDependencyPlugin({
+ exclude: /node_modules/,
+ failOnError: true,
+ allowAsyncCycles: false,
+ cwd: resolve("../src/js"),
+ }),
+ ],
+ module: { rules: moduleRules },
};
diff --git a/gulp/webpack.production.config.js b/gulp/webpack.production.config.js
index e324d675..91dd3217 100644
--- a/gulp/webpack.production.config.js
+++ b/gulp/webpack.production.config.js
@@ -1,269 +1,139 @@
-// @ts-nocheck
+import { resolve } from "path/posix";
+import TerserPlugin from "terser-webpack-plugin";
+import webpack from "webpack";
+import DeadCodePlugin from "webpack-deadcode-plugin";
+import { getAllResourceImages, getRevision, getVersion } from "./buildutils.js";
+const { DefinePlugin, IgnorePlugin } = webpack;
-const path = require("path");
-const webpack = require("webpack");
-const { getRevision, getVersion, getAllResourceImages } = require("./buildutils");
+const globalDefs = {
+ "assert": "false && window.assert",
+ "assertAlways": "window.assert",
+ "abstract": "window.assert(false, 'abstract method called');",
+ "globalConfig.debug": "({})",
+ "G_IS_DEV": "false",
+ "G_APP_ENVIRONMENT": JSON.stringify("release"),
+ "G_BUILD_TIME": new Date().getTime().toString(),
+ "G_BUILD_COMMIT_HASH": JSON.stringify(getRevision()),
+ "G_BUILD_VERSION": JSON.stringify(getVersion()),
+ "G_ALL_UI_IMAGES": JSON.stringify(getAllResourceImages()),
-const TerserPlugin = require("terser-webpack-plugin");
-const StringReplacePlugin = require("string-replace-webpack-plugin");
-const UnusedFilesPlugin = require("unused-files-webpack-plugin").UnusedFilesWebpackPlugin;
+ "G_IS_RELEASE": "true",
+};
-module.exports = ({
- environment,
- es6 = false,
-
- standalone = false,
- isBrowser = true,
-
- chineseVersion = false,
- wegameVersion = false,
- steamDemo = false,
- gogVersion = false,
-}) => {
- const globalDefs = {
- assert: "false && window.assert",
- assertAlways: "window.assert",
- abstract: "window.assert(false, 'abstract method called');",
- G_IS_DEV: "false",
-
- G_CHINA_VERSION: JSON.stringify(chineseVersion),
- G_WEGAME_VERSION: JSON.stringify(wegameVersion),
- G_GOG_VERSION: JSON.stringify(gogVersion),
- G_IS_RELEASE: environment === "prod" ? "true" : "false",
- G_IS_STANDALONE: standalone ? "true" : "false",
- G_IS_STEAM_DEMO: JSON.stringify(steamDemo),
- G_IS_BROWSER: isBrowser ? "true" : "false",
- G_APP_ENVIRONMENT: JSON.stringify(environment),
- G_HAVE_ASSERT: "false",
- G_BUILD_TIME: "" + new Date().getTime(),
- G_BUILD_COMMIT_HASH: JSON.stringify(getRevision()),
- G_BUILD_VERSION: JSON.stringify(getVersion()),
- G_ALL_UI_IMAGES: JSON.stringify(getAllResourceImages()),
- };
-
- const minifyNames = false;
-
- return {
- mode: "production",
- entry: {
- "bundle.js": [path.resolve(__dirname, "..", "src", "js", "main.js")],
- },
- node: {
- fs: "empty",
- },
- output: {
- filename: "bundle.js",
- path: path.resolve(__dirname, "..", "build"),
- },
- context: path.resolve(__dirname, ".."),
- stats: {
- // Examine all modules
- maxModules: Infinity,
- // Display bailout reasons
- optimizationBailout: true,
- },
- devtool: false,
- resolve: {
- alias: {
- "global-compression": path.resolve(__dirname, "..", "src", "js", "core", "lzstring.js"),
+/** @type {import("webpack").RuleSetRule[]} */
+const moduleRules = [
+ {
+ test: /\.jsx?$/,
+ enforce: "pre",
+ exclude: /node_modules/,
+ use: [
+ {
+ loader: "webpack-strip-block",
+ options: {
+ start: "typehints:start",
+ end: "typehints:end",
+ },
},
+ {
+ // TODO: Consider removing this separation
+ loader: "webpack-strip-block",
+ options: {
+ start: "dev:start",
+ end: "dev:end",
+ },
+ },
+ ],
+ },
+ {
+ test: /\.[jt]sx?$/,
+ use: [
+ {
+ loader: "ts-loader",
+
+ options: {
+ configFile: resolve("../src/tsconfig.json"),
+ onlyCompileBundledFiles: true,
+ transpileOnly: true,
+ experimentalWatchApi: true,
+ },
+ },
+ ],
+ resolve: {
+ fullySpecified: false,
},
- optimization: {
- minimize: true,
- // namedModules: true,
+ },
+];
- noEmitOnErrors: true,
- removeAvailableModules: true,
- removeEmptyChunks: true,
- mergeDuplicateChunks: true,
- flagIncludedChunks: true,
- occurrenceOrder: true,
- providedExports: true,
- usedExports: true,
- concatenateModules: true,
- sideEffects: true,
-
- minimizer: [
- new TerserPlugin({
- parallel: true,
- sourceMap: false,
- cache: false,
- terserOptions: {
- ecma: es6 ? 6 : 5,
- parse: {},
- module: true,
- toplevel: true,
- keep_classnames: !minifyNames,
- keep_fnames: !minifyNames,
- keep_fargs: !minifyNames,
- safari10: true,
- compress: {
- arguments: false, // breaks
- drop_console: false,
- global_defs: globalDefs,
- keep_fargs: !minifyNames,
- keep_infinity: true,
- passes: 2,
- module: true,
- pure_funcs: [
- "Math.radians",
- "Math.degrees",
- "Math.round",
- "Math.ceil",
- "Math.floor",
- "Math.sqrt",
- "Math.hypot",
- "Math.abs",
- "Math.max",
- "Math.min",
- "Math.sin",
- "Math.cos",
- "Math.tan",
- "Math.sign",
- "Math.pow",
- "Math.atan2",
- ],
- toplevel: true,
- unsafe_math: true,
- unsafe_arrows: false,
- warnings: true,
- },
- mangle: {
- reserved: ["__$S__"],
- eval: true,
- keep_classnames: !minifyNames,
- keep_fnames: !minifyNames,
- module: true,
- toplevel: true,
- safari10: true,
- },
- output: {
- comments: false,
- ascii_only: true,
- beautify: false,
- braces: false,
- ecma: es6 ? 6 : 5,
- preamble:
- "/* shapez.io Codebase - Copyright 2022 tobspr Games - " +
- getVersion() +
- " @ " +
- getRevision() +
- " */",
- },
+/** @type {import("webpack").Configuration} */
+export default {
+ mode: "production",
+ entry: resolve("../src/js/main.js"),
+ context: resolve(".."),
+ output: {
+ path: resolve("../build"),
+ filename: "bundle.js",
+ },
+ resolve: {
+ fallback: { fs: false },
+ alias: {
+ "@": resolve("../src/js/"),
+ },
+ fullySpecified: false,
+ extensions: [".ts", ".js", ".tsx", ".jsx"],
+ },
+ stats: { optimizationBailout: true },
+ optimization: {
+ removeAvailableModules: true,
+ minimizer: [
+ new TerserPlugin({
+ parallel: true,
+ terserOptions: {
+ ecma: 2020,
+ module: true,
+ keep_fnames: true,
+ compress: {
+ global_defs: globalDefs,
+ keep_infinity: true,
+ passes: 2,
+ pure_funcs: [
+ "Math.radians",
+ "Math.degrees",
+ "Math.round",
+ "Math.ceil",
+ "Math.floor",
+ "Math.sqrt",
+ "Math.hypot",
+ "Math.abs",
+ "Math.max",
+ "Math.min",
+ "Math.sin",
+ "Math.cos",
+ "Math.tan",
+ "Math.sign",
+ "Math.pow",
+ "Math.atan2",
+ ],
+ unsafe_math: true,
},
- }),
- ],
- },
- performance: {
- maxEntrypointSize: 5120000,
- maxAssetSize: 5120000,
- },
- plugins: [
- new webpack.DefinePlugin(globalDefs),
-
- new UnusedFilesPlugin({
- failOnUnused: false,
- cwd: path.join(__dirname, "..", "src", "js"),
- patterns: ["../src/js/**/*.js"],
+ format: {
+ comments: false,
+ ascii_only: true,
+ },
+ },
}),
],
- module: {
- rules: [
- {
- test: /\.json$/,
- enforce: "pre",
- use: ["./gulp/loader.compressjson"],
- type: "javascript/auto",
- },
- { test: /\.(png|jpe?g|svg)$/, loader: "ignore-loader" },
- { test: /\.nobuild/, loader: "ignore-loader" },
- {
- test: /\.js$/,
- enforce: "pre",
- exclude: /node_modules/,
- use: [
- {
- loader: "webpack-strip-block",
- options: {
- start: "typehints:start",
- end: "typehints:end",
- },
- },
- {
- loader: "webpack-strip-block",
- options: {
- start: "dev:start",
- end: "dev:end",
- },
- },
- {
- loader: "webpack-strip-block",
- options: {
- start: "wires:start",
- end: "wires:end",
- },
- },
- ],
- },
- {
- test: /\.js$/,
- use: [
- // "thread-loader",
- {
- loader: path.resolve(__dirname, "mod.js"),
- },
- {
- loader: "babel-loader?cacheDirectory",
- options: {
- configFile: require.resolve(
- es6 ? "./babel-es6.config.js" : "./babel.config.js"
- ),
- },
- },
- "uglify-template-string-loader", // Finally found this plugin
- StringReplacePlugin.replace({
- replacements: [
- { pattern: /globalConfig\.tileSize/g, replacement: () => "32" },
- { pattern: /globalConfig\.halfTileSize/g, replacement: () => "16" },
- {
- pattern: /globalConfig\.beltSpeedItemsPerSecond/g,
- replacement: () => "2.0",
- },
- { pattern: /globalConfig\.debug/g, replacement: () => "''" },
- ],
- }),
- ],
- },
- {
- test: /\.worker\.js$/,
- use: [
- {
- loader: "worker-loader",
- options: {
- fallback: false,
- inline: true,
- },
- },
- {
- loader: "babel-loader?cacheDirectory",
- options: {
- configFile: require.resolve(
- es6 ? "./babel-es6.config.js" : "./babel.config.js"
- ),
- },
- },
- ],
- },
- {
- test: /\.md$/,
- use: ["html-loader", "markdown-loader"],
- },
- {
- test: /\.ya?ml$/,
- type: "json", // Required by Webpack v4
- use: "yaml-loader",
- },
- ],
- },
- };
+ },
+ plugins: [
+ new DefinePlugin(globalDefs),
+ new IgnorePlugin({ resourceRegExp: /\.(png|jpe?g|svg)$/ }),
+ new IgnorePlugin({ resourceRegExp: /\.nobuild/ }),
+ new DeadCodePlugin({
+ patterns: ["../src/js/**/*.js"],
+ }),
+ ],
+ module: { rules: moduleRules },
+ performance: {
+ maxEntrypointSize: 5120000,
+ maxAssetSize: 5120000,
+ },
};
diff --git a/gulp/yarn.lock b/gulp/yarn.lock
deleted file mode 100644
index 04f974f3..00000000
--- a/gulp/yarn.lock
+++ /dev/null
@@ -1,13476 +0,0 @@
-# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
-# yarn lockfile v1
-
-
-"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.8.3":
- version "7.8.3"
- resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz"
- integrity sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==
- dependencies:
- "@babel/highlight" "^7.8.3"
-
-"@babel/core@^7.9.0":
- version "7.9.0"
- resolved "https://registry.npmjs.org/@babel/core/-/core-7.9.0.tgz"
- integrity sha512-kWc7L0fw1xwvI0zi8OKVBuxRVefwGOrKSQMvrQ3dW+bIIavBY3/NpXmpjMy7bQnLgwgzWQZ8TlM57YHpHNHz4w==
- dependencies:
- "@babel/code-frame" "^7.8.3"
- "@babel/generator" "^7.9.0"
- "@babel/helper-module-transforms" "^7.9.0"
- "@babel/helpers" "^7.9.0"
- "@babel/parser" "^7.9.0"
- "@babel/template" "^7.8.6"
- "@babel/traverse" "^7.9.0"
- "@babel/types" "^7.9.0"
- convert-source-map "^1.7.0"
- debug "^4.1.0"
- gensync "^1.0.0-beta.1"
- json5 "^2.1.2"
- lodash "^4.17.13"
- resolve "^1.3.2"
- semver "^5.4.1"
- source-map "^0.5.0"
-
-"@babel/generator@^7.9.0", "@babel/generator@^7.9.5":
- version "7.9.5"
- resolved "https://registry.npmjs.org/@babel/generator/-/generator-7.9.5.tgz"
- integrity sha512-GbNIxVB3ZJe3tLeDm1HSn2AhuD/mVcyLDpgtLXa5tplmWrJdF/elxB56XNqCuD6szyNkDi6wuoKXln3QeBmCHQ==
- dependencies:
- "@babel/types" "^7.9.5"
- jsesc "^2.5.1"
- lodash "^4.17.13"
- source-map "^0.5.0"
-
-"@babel/helper-annotate-as-pure@^7.0.0":
- version "7.0.0"
- resolved "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0.tgz"
- integrity sha512-3UYcJUj9kvSLbLbUIfQTqzcy5VX7GRZ/CCDrnOaZorFFM01aXp1+GJwuFGV4NDDoAS+mOUyHcO6UD/RfqOks3Q==
- dependencies:
- "@babel/types" "^7.0.0"
-
-"@babel/helper-builder-binary-assignment-operator-visitor@^7.1.0":
- version "7.1.0"
- resolved "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.1.0.tgz"
- integrity sha512-qNSR4jrmJ8M1VMM9tibvyRAHXQs2PmaksQF7c1CGJNipfe3D8p+wgNwgso/P2A2r2mdgBWAXljNWR0QRZAMW8w==
- dependencies:
- "@babel/helper-explode-assignable-expression" "^7.1.0"
- "@babel/types" "^7.0.0"
-
-"@babel/helper-call-delegate@^7.4.4":
- version "7.4.4"
- resolved "https://registry.npmjs.org/@babel/helper-call-delegate/-/helper-call-delegate-7.4.4.tgz"
- integrity sha512-l79boDFJ8S1c5hvQvG+rc+wHw6IuH7YldmRKsYtpbawsxURu/paVy57FZMomGK22/JckepaikOkY0MoAmdyOlQ==
- dependencies:
- "@babel/helper-hoist-variables" "^7.4.4"
- "@babel/traverse" "^7.4.4"
- "@babel/types" "^7.4.4"
-
-"@babel/helper-define-map@^7.5.5":
- version "7.5.5"
- resolved "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.5.5.tgz"
- integrity sha512-fTfxx7i0B5NJqvUOBBGREnrqbTxRh7zinBANpZXAVDlsZxYdclDp467G1sQ8VZYMnAURY3RpBUAgOYT9GfzHBg==
- dependencies:
- "@babel/helper-function-name" "^7.1.0"
- "@babel/types" "^7.5.5"
- lodash "^4.17.13"
-
-"@babel/helper-explode-assignable-expression@^7.1.0":
- version "7.1.0"
- resolved "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.1.0.tgz"
- integrity sha512-NRQpfHrJ1msCHtKjbzs9YcMmJZOg6mQMmGRB+hbamEdG5PNpaSm95275VD92DvJKuyl0s2sFiDmMZ+EnnvufqA==
- dependencies:
- "@babel/traverse" "^7.1.0"
- "@babel/types" "^7.0.0"
-
-"@babel/helper-function-name@^7.1.0", "@babel/helper-function-name@^7.9.5":
- version "7.9.5"
- resolved "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz"
- integrity sha512-JVcQZeXM59Cd1qanDUxv9fgJpt3NeKUaqBqUEvfmQ+BCOKq2xUgaWZW2hr0dkbyJgezYuplEoh5knmrnS68efw==
- dependencies:
- "@babel/helper-get-function-arity" "^7.8.3"
- "@babel/template" "^7.8.3"
- "@babel/types" "^7.9.5"
-
-"@babel/helper-get-function-arity@^7.0.0", "@babel/helper-get-function-arity@^7.8.3":
- version "7.8.3"
- resolved "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz"
- integrity sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==
- dependencies:
- "@babel/types" "^7.8.3"
-
-"@babel/helper-hoist-variables@^7.4.4":
- version "7.4.4"
- resolved "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.4.4.tgz"
- integrity sha512-VYk2/H/BnYbZDDg39hr3t2kKyifAm1W6zHRfhx8jGjIHpQEBv9dry7oQ2f3+J703TLu69nYdxsovl0XYfcnK4w==
- dependencies:
- "@babel/types" "^7.4.4"
-
-"@babel/helper-member-expression-to-functions@^7.8.3":
- version "7.8.3"
- resolved "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.8.3.tgz"
- integrity sha512-fO4Egq88utkQFjbPrSHGmGLFqmrshs11d46WI+WZDESt7Wu7wN2G2Iu+NMMZJFDOVRHAMIkB5SNh30NtwCA7RA==
- dependencies:
- "@babel/types" "^7.8.3"
-
-"@babel/helper-module-imports@^7.0.0", "@babel/helper-module-imports@^7.8.3":
- version "7.8.3"
- resolved "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.8.3.tgz"
- integrity sha512-R0Bx3jippsbAEtzkpZ/6FIiuzOURPcMjHp+Z6xPe6DtApDJx+w7UYyOLanZqO8+wKR9G10s/FmHXvxaMd9s6Kg==
- dependencies:
- "@babel/types" "^7.8.3"
-
-"@babel/helper-module-transforms@^7.1.0", "@babel/helper-module-transforms@^7.4.4", "@babel/helper-module-transforms@^7.9.0":
- version "7.9.0"
- resolved "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.9.0.tgz"
- integrity sha512-0FvKyu0gpPfIQ8EkxlrAydOWROdHpBmiCiRwLkUiBGhCUPRRbVD2/tm3sFr/c/GWFrQ/ffutGUAnx7V0FzT2wA==
- dependencies:
- "@babel/helper-module-imports" "^7.8.3"
- "@babel/helper-replace-supers" "^7.8.6"
- "@babel/helper-simple-access" "^7.8.3"
- "@babel/helper-split-export-declaration" "^7.8.3"
- "@babel/template" "^7.8.6"
- "@babel/types" "^7.9.0"
- lodash "^4.17.13"
-
-"@babel/helper-optimise-call-expression@^7.0.0", "@babel/helper-optimise-call-expression@^7.8.3":
- version "7.8.3"
- resolved "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.8.3.tgz"
- integrity sha512-Kag20n86cbO2AvHca6EJsvqAd82gc6VMGule4HwebwMlwkpXuVqrNRj6CkCV2sKxgi9MyAUnZVnZ6lJ1/vKhHQ==
- dependencies:
- "@babel/types" "^7.8.3"
-
-"@babel/helper-plugin-utils@^7.0.0":
- version "7.0.0"
- resolved "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0.tgz"
- integrity sha512-CYAOUCARwExnEixLdB6sDm2dIJ/YgEAKDM1MOeMeZu9Ld/bDgVo8aiWrXwcY7OBh+1Ea2uUcVRcxKk0GJvW7QA==
-
-"@babel/helper-plugin-utils@^7.17.12":
- version "7.17.12"
- resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.17.12.tgz#86c2347da5acbf5583ba0a10aed4c9bf9da9cf96"
- integrity sha512-JDkf04mqtN3y4iAbO1hv9U2ARpPyPL1zqyWs/2WG1pgSq9llHFjStX5jdxb84himgJm+8Ng+x0oiWF/nw/XQKA==
-
-"@babel/helper-regex@^7.0.0", "@babel/helper-regex@^7.4.4":
- version "7.5.5"
- resolved "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.5.5.tgz"
- integrity sha512-CkCYQLkfkiugbRDO8eZn6lRuR8kzZoGXCg3149iTk5se7g6qykSpy3+hELSwquhu+TgHn8nkLiBwHvNX8Hofcw==
- dependencies:
- lodash "^4.17.13"
-
-"@babel/helper-remap-async-to-generator@^7.1.0":
- version "7.1.0"
- resolved "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.1.0.tgz"
- integrity sha512-3fOK0L+Fdlg8S5al8u/hWE6vhufGSn0bN09xm2LXMy//REAF8kDCrYoOBKYmA8m5Nom+sV9LyLCwrFynA8/slg==
- dependencies:
- "@babel/helper-annotate-as-pure" "^7.0.0"
- "@babel/helper-wrap-function" "^7.1.0"
- "@babel/template" "^7.1.0"
- "@babel/traverse" "^7.1.0"
- "@babel/types" "^7.0.0"
-
-"@babel/helper-replace-supers@^7.5.5", "@babel/helper-replace-supers@^7.8.6":
- version "7.8.6"
- resolved "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.8.6.tgz"
- integrity sha512-PeMArdA4Sv/Wf4zXwBKPqVj7n9UF/xg6slNRtZW84FM7JpE1CbG8B612FyM4cxrf4fMAMGO0kR7voy1ForHHFA==
- dependencies:
- "@babel/helper-member-expression-to-functions" "^7.8.3"
- "@babel/helper-optimise-call-expression" "^7.8.3"
- "@babel/traverse" "^7.8.6"
- "@babel/types" "^7.8.6"
-
-"@babel/helper-simple-access@^7.1.0", "@babel/helper-simple-access@^7.8.3":
- version "7.8.3"
- resolved "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.8.3.tgz"
- integrity sha512-VNGUDjx5cCWg4vvCTR8qQ7YJYZ+HBjxOgXEl7ounz+4Sn7+LMD3CFrCTEU6/qXKbA2nKg21CwhhBzO0RpRbdCw==
- dependencies:
- "@babel/template" "^7.8.3"
- "@babel/types" "^7.8.3"
-
-"@babel/helper-split-export-declaration@^7.4.4", "@babel/helper-split-export-declaration@^7.8.3":
- version "7.8.3"
- resolved "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz"
- integrity sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==
- dependencies:
- "@babel/types" "^7.8.3"
-
-"@babel/helper-validator-identifier@^7.9.0", "@babel/helper-validator-identifier@^7.9.5":
- version "7.9.5"
- resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.5.tgz"
- integrity sha512-/8arLKUFq882w4tWGj9JYzRpAlZgiWUJ+dtteNTDqrRBz9Iguck9Rn3ykuBDoUwh2TO4tSAJlrxDUOXWklJe4g==
-
-"@babel/helper-wrap-function@^7.1.0":
- version "7.2.0"
- resolved "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.2.0.tgz"
- integrity sha512-o9fP1BZLLSrYlxYEYyl2aS+Flun5gtjTIG8iln+XuEzQTs0PLagAGSXUcqruJwD5fM48jzIEggCKpIfWTcR7pQ==
- dependencies:
- "@babel/helper-function-name" "^7.1.0"
- "@babel/template" "^7.1.0"
- "@babel/traverse" "^7.1.0"
- "@babel/types" "^7.2.0"
-
-"@babel/helpers@^7.9.0":
- version "7.9.2"
- resolved "https://registry.npmjs.org/@babel/helpers/-/helpers-7.9.2.tgz"
- integrity sha512-JwLvzlXVPjO8eU9c/wF9/zOIN7X6h8DYf7mG4CiFRZRvZNKEF5dQ3H3V+ASkHoIB3mWhatgl5ONhyqHRI6MppA==
- dependencies:
- "@babel/template" "^7.8.3"
- "@babel/traverse" "^7.9.0"
- "@babel/types" "^7.9.0"
-
-"@babel/highlight@^7.8.3":
- version "7.9.0"
- resolved "https://registry.npmjs.org/@babel/highlight/-/highlight-7.9.0.tgz"
- integrity sha512-lJZPilxX7Op3Nv/2cvFdnlepPXDxi29wxteT57Q965oc5R9v86ztx0jfxVrTcBk8C2kcPkkDa2Z4T3ZsPPVWsQ==
- dependencies:
- "@babel/helper-validator-identifier" "^7.9.0"
- chalk "^2.0.0"
- js-tokens "^4.0.0"
-
-"@babel/parser@^7.8.6", "@babel/parser@^7.9.0":
- version "7.9.4"
- resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.9.4.tgz"
- integrity sha512-bC49otXX6N0/VYhgOMh4gnP26E9xnDZK3TmbNpxYzzz9BQLBosQwfyOe9/cXUU3txYhTzLCbcqd5c8y/OmCjHA==
-
-"@babel/plugin-proposal-async-generator-functions@^7.2.0":
- version "7.2.0"
- resolved "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.2.0.tgz"
- integrity sha512-+Dfo/SCQqrwx48ptLVGLdE39YtWRuKc/Y9I5Fy0P1DDBB9lsAHpjcEJQt+4IifuSOSTLBKJObJqMvaO1pIE8LQ==
- dependencies:
- "@babel/helper-plugin-utils" "^7.0.0"
- "@babel/helper-remap-async-to-generator" "^7.1.0"
- "@babel/plugin-syntax-async-generators" "^7.2.0"
-
-"@babel/plugin-proposal-dynamic-import@^7.5.0":
- version "7.5.0"
- resolved "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.5.0.tgz"
- integrity sha512-x/iMjggsKTFHYC6g11PL7Qy58IK8H5zqfm9e6hu4z1iH2IRyAp9u9dL80zA6R76yFovETFLKz2VJIC2iIPBuFw==
- dependencies:
- "@babel/helper-plugin-utils" "^7.0.0"
- "@babel/plugin-syntax-dynamic-import" "^7.2.0"
-
-"@babel/plugin-proposal-json-strings@^7.2.0":
- version "7.2.0"
- resolved "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.2.0.tgz"
- integrity sha512-MAFV1CA/YVmYwZG0fBQyXhmj0BHCB5egZHCKWIFVv/XCxAeVGIHfos3SwDck4LvCllENIAg7xMKOG5kH0dzyUg==
- dependencies:
- "@babel/helper-plugin-utils" "^7.0.0"
- "@babel/plugin-syntax-json-strings" "^7.2.0"
-
-"@babel/plugin-proposal-object-rest-spread@^7.5.5":
- version "7.5.5"
- resolved "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.5.5.tgz"
- integrity sha512-F2DxJJSQ7f64FyTVl5cw/9MWn6naXGdk3Q3UhDbFEEHv+EilCPoeRD3Zh/Utx1CJz4uyKlQ4uH+bJPbEhMV7Zw==
- dependencies:
- "@babel/helper-plugin-utils" "^7.0.0"
- "@babel/plugin-syntax-object-rest-spread" "^7.2.0"
-
-"@babel/plugin-proposal-optional-catch-binding@^7.2.0":
- version "7.2.0"
- resolved "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.2.0.tgz"
- integrity sha512-mgYj3jCcxug6KUcX4OBoOJz3CMrwRfQELPQ5560F70YQUBZB7uac9fqaWamKR1iWUzGiK2t0ygzjTScZnVz75g==
- dependencies:
- "@babel/helper-plugin-utils" "^7.0.0"
- "@babel/plugin-syntax-optional-catch-binding" "^7.2.0"
-
-"@babel/plugin-proposal-unicode-property-regex@^7.4.4":
- version "7.4.4"
- resolved "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.4.4.tgz"
- integrity sha512-j1NwnOqMG9mFUOH58JTFsA/+ZYzQLUZ/drqWUqxCYLGeu2JFZL8YrNC9hBxKmWtAuOCHPcRpgv7fhap09Fb4kA==
- dependencies:
- "@babel/helper-plugin-utils" "^7.0.0"
- "@babel/helper-regex" "^7.4.4"
- regexpu-core "^4.5.4"
-
-"@babel/plugin-syntax-async-generators@^7.2.0":
- version "7.2.0"
- resolved "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.2.0.tgz"
- integrity sha512-1ZrIRBv2t0GSlcwVoQ6VgSLpLgiN/FVQUzt9znxo7v2Ov4jJrs8RY8tv0wvDmFN3qIdMKWrmMMW6yZ0G19MfGg==
- dependencies:
- "@babel/helper-plugin-utils" "^7.0.0"
-
-"@babel/plugin-syntax-dynamic-import@^7.2.0":
- version "7.2.0"
- resolved "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.2.0.tgz"
- integrity sha512-mVxuJ0YroI/h/tbFTPGZR8cv6ai+STMKNBq0f8hFxsxWjl94qqhsb+wXbpNMDPU3cfR1TIsVFzU3nXyZMqyK4w==
- dependencies:
- "@babel/helper-plugin-utils" "^7.0.0"
-
-"@babel/plugin-syntax-json-strings@^7.2.0":
- version "7.2.0"
- resolved "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.2.0.tgz"
- integrity sha512-5UGYnMSLRE1dqqZwug+1LISpA403HzlSfsg6P9VXU6TBjcSHeNlw4DxDx7LgpF+iKZoOG/+uzqoRHTdcUpiZNg==
- dependencies:
- "@babel/helper-plugin-utils" "^7.0.0"
-
-"@babel/plugin-syntax-object-rest-spread@^7.2.0":
- version "7.2.0"
- resolved "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.2.0.tgz"
- integrity sha512-t0JKGgqk2We+9may3t0xDdmneaXmyxq0xieYcKHxIsrJO64n1OiMWNUtc5gQK1PA0NpdCRrtZp4z+IUaKugrSA==
- dependencies:
- "@babel/helper-plugin-utils" "^7.0.0"
-
-"@babel/plugin-syntax-optional-catch-binding@^7.2.0":
- version "7.2.0"
- resolved "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.2.0.tgz"
- integrity sha512-bDe4xKNhb0LI7IvZHiA13kff0KEfaGX/Hv4lMA9+7TEc63hMNvfKo6ZFpXhKuEp+II/q35Gc4NoMeDZyaUbj9w==
- dependencies:
- "@babel/helper-plugin-utils" "^7.0.0"
-
-"@babel/plugin-transform-arrow-functions@^7.17.12":
- version "7.17.12"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.17.12.tgz#dddd783b473b1b1537ef46423e3944ff24898c45"
- integrity sha512-PHln3CNi/49V+mza4xMwrg+WGYevSF1oaiXaC2EQfdp4HWlSjRsrDXWJiQBKpP7749u6vQ9mcry2uuFOv5CXvA==
- dependencies:
- "@babel/helper-plugin-utils" "^7.17.12"
-
-"@babel/plugin-transform-arrow-functions@^7.2.0":
- version "7.2.0"
- resolved "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.2.0.tgz"
- integrity sha512-ER77Cax1+8/8jCB9fo4Ud161OZzWN5qawi4GusDuRLcDbDG+bIGYY20zb2dfAFdTRGzrfq2xZPvF0R64EHnimg==
- dependencies:
- "@babel/helper-plugin-utils" "^7.0.0"
-
-"@babel/plugin-transform-async-to-generator@^7.5.0":
- version "7.5.0"
- resolved "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.5.0.tgz"
- integrity sha512-mqvkzwIGkq0bEF1zLRRiTdjfomZJDV33AH3oQzHVGkI2VzEmXLpKKOBvEVaFZBJdN0XTyH38s9j/Kiqr68dggg==
- dependencies:
- "@babel/helper-module-imports" "^7.0.0"
- "@babel/helper-plugin-utils" "^7.0.0"
- "@babel/helper-remap-async-to-generator" "^7.1.0"
-
-"@babel/plugin-transform-block-scoped-functions@^7.2.0":
- version "7.2.0"
- resolved "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.2.0.tgz"
- integrity sha512-ntQPR6q1/NKuphly49+QiQiTN0O63uOwjdD6dhIjSWBI5xlrbUFh720TIpzBhpnrLfv2tNH/BXvLIab1+BAI0w==
- dependencies:
- "@babel/helper-plugin-utils" "^7.0.0"
-
-"@babel/plugin-transform-block-scoping@^7.4.4", "@babel/plugin-transform-block-scoping@^7.6.0":
- version "7.6.0"
- resolved "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.6.0.tgz"
- integrity sha512-tIt4E23+kw6TgL/edACZwP1OUKrjOTyMrFMLoT5IOFrfMRabCgekjqFd5o6PaAMildBu46oFkekIdMuGkkPEpA==
- dependencies:
- "@babel/helper-plugin-utils" "^7.0.0"
- lodash "^4.17.13"
-
-"@babel/plugin-transform-classes@^7.5.5":
- version "7.5.5"
- resolved "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.5.5.tgz"
- integrity sha512-U2htCNK/6e9K7jGyJ++1p5XRU+LJjrwtoiVn9SzRlDT2KubcZ11OOwy3s24TjHxPgxNwonCYP7U2K51uVYCMDg==
- dependencies:
- "@babel/helper-annotate-as-pure" "^7.0.0"
- "@babel/helper-define-map" "^7.5.5"
- "@babel/helper-function-name" "^7.1.0"
- "@babel/helper-optimise-call-expression" "^7.0.0"
- "@babel/helper-plugin-utils" "^7.0.0"
- "@babel/helper-replace-supers" "^7.5.5"
- "@babel/helper-split-export-declaration" "^7.4.4"
- globals "^11.1.0"
-
-"@babel/plugin-transform-computed-properties@^7.2.0":
- version "7.2.0"
- resolved "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.2.0.tgz"
- integrity sha512-kP/drqTxY6Xt3NNpKiMomfgkNn4o7+vKxK2DDKcBG9sHj51vHqMBGy8wbDS/J4lMxnqs153/T3+DmCEAkC5cpA==
- dependencies:
- "@babel/helper-plugin-utils" "^7.0.0"
-
-"@babel/plugin-transform-destructuring@^7.6.0":
- version "7.6.0"
- resolved "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.6.0.tgz"
- integrity sha512-2bGIS5P1v4+sWTCnKNDZDxbGvEqi0ijeqM/YqHtVGrvG2y0ySgnEEhXErvE9dA0bnIzY9bIzdFK0jFA46ASIIQ==
- dependencies:
- "@babel/helper-plugin-utils" "^7.0.0"
-
-"@babel/plugin-transform-dotall-regex@^7.4.4":
- version "7.4.4"
- resolved "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.4.4.tgz"
- integrity sha512-P05YEhRc2h53lZDjRPk/OektxCVevFzZs2Gfjd545Wde3k+yFDbXORgl2e0xpbq8mLcKJ7Idss4fAg0zORN/zg==
- dependencies:
- "@babel/helper-plugin-utils" "^7.0.0"
- "@babel/helper-regex" "^7.4.4"
- regexpu-core "^4.5.4"
-
-"@babel/plugin-transform-duplicate-keys@^7.5.0":
- version "7.5.0"
- resolved "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.5.0.tgz"
- integrity sha512-igcziksHizyQPlX9gfSjHkE2wmoCH3evvD2qR5w29/Dk0SMKE/eOI7f1HhBdNhR/zxJDqrgpoDTq5YSLH/XMsQ==
- dependencies:
- "@babel/helper-plugin-utils" "^7.0.0"
-
-"@babel/plugin-transform-exponentiation-operator@^7.2.0":
- version "7.2.0"
- resolved "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.2.0.tgz"
- integrity sha512-umh4hR6N7mu4Elq9GG8TOu9M0bakvlsREEC+ialrQN6ABS4oDQ69qJv1VtR3uxlKMCQMCvzk7vr17RHKcjx68A==
- dependencies:
- "@babel/helper-builder-binary-assignment-operator-visitor" "^7.1.0"
- "@babel/helper-plugin-utils" "^7.0.0"
-
-"@babel/plugin-transform-for-of@^7.4.4":
- version "7.4.4"
- resolved "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.4.4.tgz"
- integrity sha512-9T/5Dlr14Z9TIEXLXkt8T1DU7F24cbhwhMNUziN3hB1AXoZcdzPcTiKGRn/6iOymDqtTKWnr/BtRKN9JwbKtdQ==
- dependencies:
- "@babel/helper-plugin-utils" "^7.0.0"
-
-"@babel/plugin-transform-function-name@^7.4.4":
- version "7.4.4"
- resolved "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.4.4.tgz"
- integrity sha512-iU9pv7U+2jC9ANQkKeNF6DrPy4GBa4NWQtl6dHB4Pb3izX2JOEvDTFarlNsBj/63ZEzNNIAMs3Qw4fNCcSOXJA==
- dependencies:
- "@babel/helper-function-name" "^7.1.0"
- "@babel/helper-plugin-utils" "^7.0.0"
-
-"@babel/plugin-transform-literals@^7.2.0":
- version "7.2.0"
- resolved "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.2.0.tgz"
- integrity sha512-2ThDhm4lI4oV7fVQ6pNNK+sx+c/GM5/SaML0w/r4ZB7sAneD/piDJtwdKlNckXeyGK7wlwg2E2w33C/Hh+VFCg==
- dependencies:
- "@babel/helper-plugin-utils" "^7.0.0"
-
-"@babel/plugin-transform-member-expression-literals@^7.2.0":
- version "7.2.0"
- resolved "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.2.0.tgz"
- integrity sha512-HiU3zKkSU6scTidmnFJ0bMX8hz5ixC93b4MHMiYebmk2lUVNGOboPsqQvx5LzooihijUoLR/v7Nc1rbBtnc7FA==
- dependencies:
- "@babel/helper-plugin-utils" "^7.0.0"
-
-"@babel/plugin-transform-modules-amd@^7.5.0":
- version "7.5.0"
- resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.5.0.tgz"
- integrity sha512-n20UsQMKnWrltocZZm24cRURxQnWIvsABPJlw/fvoy9c6AgHZzoelAIzajDHAQrDpuKFFPPcFGd7ChsYuIUMpg==
- dependencies:
- "@babel/helper-module-transforms" "^7.1.0"
- "@babel/helper-plugin-utils" "^7.0.0"
- babel-plugin-dynamic-import-node "^2.3.0"
-
-"@babel/plugin-transform-modules-commonjs@^7.6.0":
- version "7.6.0"
- resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.6.0.tgz"
- integrity sha512-Ma93Ix95PNSEngqomy5LSBMAQvYKVe3dy+JlVJSHEXZR5ASL9lQBedMiCyVtmTLraIDVRE3ZjTZvmXXD2Ozw3g==
- dependencies:
- "@babel/helper-module-transforms" "^7.4.4"
- "@babel/helper-plugin-utils" "^7.0.0"
- "@babel/helper-simple-access" "^7.1.0"
- babel-plugin-dynamic-import-node "^2.3.0"
-
-"@babel/plugin-transform-modules-systemjs@^7.5.0":
- version "7.5.0"
- resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.5.0.tgz"
- integrity sha512-Q2m56tyoQWmuNGxEtUyeEkm6qJYFqs4c+XyXH5RAuYxObRNz9Zgj/1g2GMnjYp2EUyEy7YTrxliGCXzecl/vJg==
- dependencies:
- "@babel/helper-hoist-variables" "^7.4.4"
- "@babel/helper-plugin-utils" "^7.0.0"
- babel-plugin-dynamic-import-node "^2.3.0"
-
-"@babel/plugin-transform-modules-umd@^7.2.0":
- version "7.2.0"
- resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.2.0.tgz"
- integrity sha512-BV3bw6MyUH1iIsGhXlOK6sXhmSarZjtJ/vMiD9dNmpY8QXFFQTj+6v92pcfy1iqa8DeAfJFwoxcrS/TUZda6sw==
- dependencies:
- "@babel/helper-module-transforms" "^7.1.0"
- "@babel/helper-plugin-utils" "^7.0.0"
-
-"@babel/plugin-transform-named-capturing-groups-regex@^7.6.0":
- version "7.6.0"
- resolved "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.6.0.tgz"
- integrity sha512-jem7uytlmrRl3iCAuQyw8BpB4c4LWvSpvIeXKpMb+7j84lkx4m4mYr5ErAcmN5KM7B6BqrAvRGjBIbbzqCczew==
- dependencies:
- regexp-tree "^0.1.13"
-
-"@babel/plugin-transform-new-target@^7.4.4":
- version "7.4.4"
- resolved "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.4.4.tgz"
- integrity sha512-r1z3T2DNGQwwe2vPGZMBNjioT2scgWzK9BCnDEh+46z8EEwXBq24uRzd65I7pjtugzPSj921aM15RpESgzsSuA==
- dependencies:
- "@babel/helper-plugin-utils" "^7.0.0"
-
-"@babel/plugin-transform-object-super@^7.5.5":
- version "7.5.5"
- resolved "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.5.5.tgz"
- integrity sha512-un1zJQAhSosGFBduPgN/YFNvWVpRuHKU7IHBglLoLZsGmruJPOo6pbInneflUdmq7YvSVqhpPs5zdBvLnteltQ==
- dependencies:
- "@babel/helper-plugin-utils" "^7.0.0"
- "@babel/helper-replace-supers" "^7.5.5"
-
-"@babel/plugin-transform-parameters@^7.4.4":
- version "7.4.4"
- resolved "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.4.4.tgz"
- integrity sha512-oMh5DUO1V63nZcu/ZVLQFqiihBGo4OpxJxR1otF50GMeCLiRx5nUdtokd+u9SuVJrvvuIh9OosRFPP4pIPnwmw==
- dependencies:
- "@babel/helper-call-delegate" "^7.4.4"
- "@babel/helper-get-function-arity" "^7.0.0"
- "@babel/helper-plugin-utils" "^7.0.0"
-
-"@babel/plugin-transform-property-literals@^7.2.0":
- version "7.2.0"
- resolved "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.2.0.tgz"
- integrity sha512-9q7Dbk4RhgcLp8ebduOpCbtjh7C0itoLYHXd9ueASKAG/is5PQtMR5VJGka9NKqGhYEGn5ITahd4h9QeBMylWQ==
- dependencies:
- "@babel/helper-plugin-utils" "^7.0.0"
-
-"@babel/plugin-transform-regenerator@^7.4.5":
- version "7.4.5"
- resolved "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.4.5.tgz"
- integrity sha512-gBKRh5qAaCWntnd09S8QC7r3auLCqq5DI6O0DlfoyDjslSBVqBibrMdsqO+Uhmx3+BlOmE/Kw1HFxmGbv0N9dA==
- dependencies:
- regenerator-transform "^0.14.0"
-
-"@babel/plugin-transform-reserved-words@^7.2.0":
- version "7.2.0"
- resolved "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.2.0.tgz"
- integrity sha512-fz43fqW8E1tAB3DKF19/vxbpib1fuyCwSPE418ge5ZxILnBhWyhtPgz8eh1RCGGJlwvksHkyxMxh0eenFi+kFw==
- dependencies:
- "@babel/helper-plugin-utils" "^7.0.0"
-
-"@babel/plugin-transform-shorthand-properties@^7.2.0":
- version "7.2.0"
- resolved "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.2.0.tgz"
- integrity sha512-QP4eUM83ha9zmYtpbnyjTLAGKQritA5XW/iG9cjtuOI8s1RuL/3V6a3DeSHfKutJQ+ayUfeZJPcnCYEQzaPQqg==
- dependencies:
- "@babel/helper-plugin-utils" "^7.0.0"
-
-"@babel/plugin-transform-spread@^7.2.0":
- version "7.2.2"
- resolved "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.2.2.tgz"
- integrity sha512-KWfky/58vubwtS0hLqEnrWJjsMGaOeSBn90Ezn5Jeg9Z8KKHmELbP1yGylMlm5N6TPKeY9A2+UaSYLdxahg01w==
- dependencies:
- "@babel/helper-plugin-utils" "^7.0.0"
-
-"@babel/plugin-transform-sticky-regex@^7.2.0":
- version "7.2.0"
- resolved "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.2.0.tgz"
- integrity sha512-KKYCoGaRAf+ckH8gEL3JHUaFVyNHKe3ASNsZ+AlktgHevvxGigoIttrEJb8iKN03Q7Eazlv1s6cx2B2cQ3Jabw==
- dependencies:
- "@babel/helper-plugin-utils" "^7.0.0"
- "@babel/helper-regex" "^7.0.0"
-
-"@babel/plugin-transform-template-literals@^7.4.4":
- version "7.4.4"
- resolved "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.4.4.tgz"
- integrity sha512-mQrEC4TWkhLN0z8ygIvEL9ZEToPhG5K7KDW3pzGqOfIGZ28Jb0POUkeWcoz8HnHvhFy6dwAT1j8OzqN8s804+g==
- dependencies:
- "@babel/helper-annotate-as-pure" "^7.0.0"
- "@babel/helper-plugin-utils" "^7.0.0"
-
-"@babel/plugin-transform-typeof-symbol@^7.2.0":
- version "7.2.0"
- resolved "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.2.0.tgz"
- integrity sha512-2LNhETWYxiYysBtrBTqL8+La0jIoQQnIScUJc74OYvUGRmkskNY4EzLCnjHBzdmb38wqtTaixpo1NctEcvMDZw==
- dependencies:
- "@babel/helper-plugin-utils" "^7.0.0"
-
-"@babel/plugin-transform-unicode-regex@^7.4.4":
- version "7.4.4"
- resolved "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.4.4.tgz"
- integrity sha512-il+/XdNw01i93+M9J9u4T7/e/Ue/vWfNZE4IRUQjplu2Mqb/AFTDimkw2tdEdSH50wuQXZAbXSql0UphQke+vA==
- dependencies:
- "@babel/helper-plugin-utils" "^7.0.0"
- "@babel/helper-regex" "^7.4.4"
- regexpu-core "^4.5.4"
-
-"@babel/preset-env@^7.5.4":
- version "7.6.0"
- resolved "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.6.0.tgz"
- integrity sha512-1efzxFv/TcPsNXlRhMzRnkBFMeIqBBgzwmZwlFDw5Ubj0AGLeufxugirwZmkkX/ayi3owsSqoQ4fw8LkfK9SYg==
- dependencies:
- "@babel/helper-module-imports" "^7.0.0"
- "@babel/helper-plugin-utils" "^7.0.0"
- "@babel/plugin-proposal-async-generator-functions" "^7.2.0"
- "@babel/plugin-proposal-dynamic-import" "^7.5.0"
- "@babel/plugin-proposal-json-strings" "^7.2.0"
- "@babel/plugin-proposal-object-rest-spread" "^7.5.5"
- "@babel/plugin-proposal-optional-catch-binding" "^7.2.0"
- "@babel/plugin-proposal-unicode-property-regex" "^7.4.4"
- "@babel/plugin-syntax-async-generators" "^7.2.0"
- "@babel/plugin-syntax-dynamic-import" "^7.2.0"
- "@babel/plugin-syntax-json-strings" "^7.2.0"
- "@babel/plugin-syntax-object-rest-spread" "^7.2.0"
- "@babel/plugin-syntax-optional-catch-binding" "^7.2.0"
- "@babel/plugin-transform-arrow-functions" "^7.2.0"
- "@babel/plugin-transform-async-to-generator" "^7.5.0"
- "@babel/plugin-transform-block-scoped-functions" "^7.2.0"
- "@babel/plugin-transform-block-scoping" "^7.6.0"
- "@babel/plugin-transform-classes" "^7.5.5"
- "@babel/plugin-transform-computed-properties" "^7.2.0"
- "@babel/plugin-transform-destructuring" "^7.6.0"
- "@babel/plugin-transform-dotall-regex" "^7.4.4"
- "@babel/plugin-transform-duplicate-keys" "^7.5.0"
- "@babel/plugin-transform-exponentiation-operator" "^7.2.0"
- "@babel/plugin-transform-for-of" "^7.4.4"
- "@babel/plugin-transform-function-name" "^7.4.4"
- "@babel/plugin-transform-literals" "^7.2.0"
- "@babel/plugin-transform-member-expression-literals" "^7.2.0"
- "@babel/plugin-transform-modules-amd" "^7.5.0"
- "@babel/plugin-transform-modules-commonjs" "^7.6.0"
- "@babel/plugin-transform-modules-systemjs" "^7.5.0"
- "@babel/plugin-transform-modules-umd" "^7.2.0"
- "@babel/plugin-transform-named-capturing-groups-regex" "^7.6.0"
- "@babel/plugin-transform-new-target" "^7.4.4"
- "@babel/plugin-transform-object-super" "^7.5.5"
- "@babel/plugin-transform-parameters" "^7.4.4"
- "@babel/plugin-transform-property-literals" "^7.2.0"
- "@babel/plugin-transform-regenerator" "^7.4.5"
- "@babel/plugin-transform-reserved-words" "^7.2.0"
- "@babel/plugin-transform-shorthand-properties" "^7.2.0"
- "@babel/plugin-transform-spread" "^7.2.0"
- "@babel/plugin-transform-sticky-regex" "^7.2.0"
- "@babel/plugin-transform-template-literals" "^7.4.4"
- "@babel/plugin-transform-typeof-symbol" "^7.2.0"
- "@babel/plugin-transform-unicode-regex" "^7.4.4"
- "@babel/types" "^7.6.0"
- browserslist "^4.6.0"
- core-js-compat "^3.1.1"
- invariant "^2.2.2"
- js-levenshtein "^1.1.3"
- semver "^5.5.0"
-
-"@babel/runtime@^7.5.5":
- version "7.9.2"
- resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.9.2.tgz"
- integrity sha512-NE2DtOdufG7R5vnfQUTehdTfNycfUANEtCa9PssN9O/xmTzP4E08UI797ixaei6hBEVL9BI/PsdJS5x7mWoB9Q==
- dependencies:
- regenerator-runtime "^0.13.4"
-
-"@babel/template@^7.1.0", "@babel/template@^7.8.3", "@babel/template@^7.8.6":
- version "7.8.6"
- resolved "https://registry.npmjs.org/@babel/template/-/template-7.8.6.tgz"
- integrity sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg==
- dependencies:
- "@babel/code-frame" "^7.8.3"
- "@babel/parser" "^7.8.6"
- "@babel/types" "^7.8.6"
-
-"@babel/traverse@^7.1.0", "@babel/traverse@^7.4.4", "@babel/traverse@^7.8.6", "@babel/traverse@^7.9.0":
- version "7.9.5"
- resolved "https://registry.npmjs.org/@babel/traverse/-/traverse-7.9.5.tgz"
- integrity sha512-c4gH3jsvSuGUezlP6rzSJ6jf8fYjLj3hsMZRx/nX0h+fmHN0w+ekubRrHPqnMec0meycA2nwCsJ7dC8IPem2FQ==
- dependencies:
- "@babel/code-frame" "^7.8.3"
- "@babel/generator" "^7.9.5"
- "@babel/helper-function-name" "^7.9.5"
- "@babel/helper-split-export-declaration" "^7.8.3"
- "@babel/parser" "^7.9.0"
- "@babel/types" "^7.9.5"
- debug "^4.1.0"
- globals "^11.1.0"
- lodash "^4.17.13"
-
-"@babel/types@^7.0.0", "@babel/types@^7.2.0", "@babel/types@^7.4.4", "@babel/types@^7.5.5", "@babel/types@^7.6.0", "@babel/types@^7.8.3", "@babel/types@^7.8.6", "@babel/types@^7.9.0", "@babel/types@^7.9.5":
- version "7.9.5"
- resolved "https://registry.npmjs.org/@babel/types/-/types-7.9.5.tgz"
- integrity sha512-XjnvNqenk818r5zMaba+sLQjnbda31UfUURv3ei0qPQw4u+j2jMyJ5b11y8ZHYTRSI3NnInQkkkRT4fLqqPdHg==
- dependencies:
- "@babel/helper-validator-identifier" "^7.9.5"
- lodash "^4.17.13"
- to-fast-properties "^2.0.0"
-
-"@csstools/convert-colors@^1.4.0":
- version "1.4.0"
- resolved "https://registry.npmjs.org/@csstools/convert-colors/-/convert-colors-1.4.0.tgz"
- integrity sha512-5a6wqoJV/xEdbRNKVo6I4hO3VjyDq//8q2f9I6PBAvMesJHFauXDorcNCsr9RzvsZnaWi5NYCcfyqP1QeFHFbw==
-
-"@electron/get@^1.6.0":
- version "1.14.1"
- resolved "https://registry.yarnpkg.com/@electron/get/-/get-1.14.1.tgz#16ba75f02dffb74c23965e72d617adc721d27f40"
- integrity sha512-BrZYyL/6m0ZXz/lDxy/nlVhQz+WF+iPS6qXolEU8atw7h6v1aYkjwJZ63m+bJMBTxDE66X+r2tPS4a/8C82sZw==
- dependencies:
- debug "^4.1.1"
- env-paths "^2.2.0"
- fs-extra "^8.1.0"
- got "^9.6.0"
- progress "^2.0.3"
- semver "^6.2.0"
- sumchecker "^3.0.1"
- optionalDependencies:
- global-agent "^3.0.0"
- global-tunnel-ng "^2.7.1"
-
-"@jimp/bmp@^0.6.8":
- version "0.6.8"
- resolved "https://registry.npmjs.org/@jimp/bmp/-/bmp-0.6.8.tgz"
- integrity sha512-uxVgSkI62uAzk5ZazYHEHBehow590WAkLKmDXLzkr/XP/Hv2Fx1T4DKwJ/15IY5ktq5VAhAUWGXTyd8KWFsx7w==
- dependencies:
- "@jimp/utils" "^0.6.8"
- bmp-js "^0.1.0"
- core-js "^2.5.7"
-
-"@jimp/core@^0.6.8":
- version "0.6.8"
- resolved "https://registry.npmjs.org/@jimp/core/-/core-0.6.8.tgz"
- integrity sha512-JOFqBBcSNiDiMZJFr6OJqC6viXj5NVBQISua0eacoYvo4YJtTajOIxC4MqWyUmGrDpRMZBR8QhSsIOwsFrdROA==
- dependencies:
- "@jimp/utils" "^0.6.8"
- any-base "^1.1.0"
- buffer "^5.2.0"
- core-js "^2.5.7"
- exif-parser "^0.1.12"
- file-type "^9.0.0"
- load-bmfont "^1.3.1"
- mkdirp "0.5.1"
- phin "^2.9.1"
- pixelmatch "^4.0.2"
- tinycolor2 "^1.4.1"
-
-"@jimp/custom@^0.6.8":
- version "0.6.8"
- resolved "https://registry.npmjs.org/@jimp/custom/-/custom-0.6.8.tgz"
- integrity sha512-FrYlzZRVXP2vuVwd7Nc2dlK+iZk4g6IaT1Ib8Z6vU5Kkwlt83FJIPJ2UUFABf3bF5big0wkk8ZUihWxE4Nzdng==
- dependencies:
- "@jimp/core" "^0.6.8"
- core-js "^2.5.7"
-
-"@jimp/gif@^0.6.8":
- version "0.6.8"
- resolved "https://registry.npmjs.org/@jimp/gif/-/gif-0.6.8.tgz"
- integrity sha512-yyOlujjQcgz9zkjM5ihZDEppn9d1brJ7jQHP5rAKmqep0G7FU1D0AKcV+Ql18RhuI/CgWs10wAVcrQpmLnu4Yw==
- dependencies:
- "@jimp/utils" "^0.6.8"
- core-js "^2.5.7"
- omggif "^1.0.9"
-
-"@jimp/jpeg@^0.6.8":
- version "0.6.8"
- resolved "https://registry.npmjs.org/@jimp/jpeg/-/jpeg-0.6.8.tgz"
- integrity sha512-rGtXbYpFXAn471qLpTGvhbBMNHJo5KiufN+vC5AWyufntmkt5f0Ox2Cx4ijuBMDtirZchxbMLtrfGjznS4L/ew==
- dependencies:
- "@jimp/utils" "^0.6.8"
- core-js "^2.5.7"
- jpeg-js "^0.3.4"
-
-"@jimp/plugin-blit@^0.6.8":
- version "0.6.8"
- resolved "https://registry.npmjs.org/@jimp/plugin-blit/-/plugin-blit-0.6.8.tgz"
- integrity sha512-7Tl6YpKTSpvwQbnGNhsfX2zyl3jRVVopd276Y2hF2zpDz9Bycow7NdfNU/4Nx1jaf96X6uWOtSVINcQ7rGd47w==
- dependencies:
- "@jimp/utils" "^0.6.8"
- core-js "^2.5.7"
-
-"@jimp/plugin-blur@^0.6.8":
- version "0.6.8"
- resolved "https://registry.npmjs.org/@jimp/plugin-blur/-/plugin-blur-0.6.8.tgz"
- integrity sha512-NpZCMKxXHLDQsX9zPlWtpMA660DQStY6/z8ZetyxCDbqrLe9YCXpeR4MNhdJdABIiwTm1W5FyFF4kp81PHJx3Q==
- dependencies:
- "@jimp/utils" "^0.6.8"
- core-js "^2.5.7"
-
-"@jimp/plugin-color@^0.6.8":
- version "0.6.8"
- resolved "https://registry.npmjs.org/@jimp/plugin-color/-/plugin-color-0.6.8.tgz"
- integrity sha512-jjFyU0zNmGOH2rjzHuOMU4kaia0oo82s/7UYfn5h7OUkmUZTd6Do3ZSK1PiXA7KR+s4B76/Omm6Doh/0SGb7BQ==
- dependencies:
- "@jimp/utils" "^0.6.8"
- core-js "^2.5.7"
- tinycolor2 "^1.4.1"
-
-"@jimp/plugin-contain@^0.6.8":
- version "0.6.8"
- resolved "https://registry.npmjs.org/@jimp/plugin-contain/-/plugin-contain-0.6.8.tgz"
- integrity sha512-p/P2wCXhAzbmEgXvGsvmxLmbz45feF6VpR4m9suPSOr8PC/i/XvTklTqYEUidYYAft4vHgsYJdS74HKSMnH8lw==
- dependencies:
- "@jimp/utils" "^0.6.8"
- core-js "^2.5.7"
-
-"@jimp/plugin-cover@^0.6.8":
- version "0.6.8"
- resolved "https://registry.npmjs.org/@jimp/plugin-cover/-/plugin-cover-0.6.8.tgz"
- integrity sha512-2PvWgk+PJfRsfWDI1G8Fpjrsu0ZlpNyZxO2+fqWlVo6y/y2gP4v08FqvbkcqSjNlOu2IDWIFXpgyU0sTINWZLg==
- dependencies:
- "@jimp/utils" "^0.6.8"
- core-js "^2.5.7"
-
-"@jimp/plugin-crop@^0.6.8":
- version "0.6.8"
- resolved "https://registry.npmjs.org/@jimp/plugin-crop/-/plugin-crop-0.6.8.tgz"
- integrity sha512-CbrcpWE2xxPK1n/JoTXzhRUhP4mO07mTWaSavenCg664oQl/9XCtL+A0FekuNHzIvn4myEqvkiTwN7FsbunS/Q==
- dependencies:
- "@jimp/utils" "^0.6.8"
- core-js "^2.5.7"
-
-"@jimp/plugin-displace@^0.6.8":
- version "0.6.8"
- resolved "https://registry.npmjs.org/@jimp/plugin-displace/-/plugin-displace-0.6.8.tgz"
- integrity sha512-RmV2bPxoPE6mrPxtYSPtHxm2cGwBQr5a2p+9gH6SPy+eUMrbGjbvjwKNfXWUYD0leML+Pt5XOmAS9pIROmuruQ==
- dependencies:
- "@jimp/utils" "^0.6.8"
- core-js "^2.5.7"
-
-"@jimp/plugin-dither@^0.6.8":
- version "0.6.8"
- resolved "https://registry.npmjs.org/@jimp/plugin-dither/-/plugin-dither-0.6.8.tgz"
- integrity sha512-x6V/qjxe+xypjpQm7GbiMNqci1EW5UizrcebOhHr8AHijOEqHd2hjXh5f6QIGfrkTFelc4/jzq1UyCsYntqz9Q==
- dependencies:
- "@jimp/utils" "^0.6.8"
- core-js "^2.5.7"
-
-"@jimp/plugin-flip@^0.6.8":
- version "0.6.8"
- resolved "https://registry.npmjs.org/@jimp/plugin-flip/-/plugin-flip-0.6.8.tgz"
- integrity sha512-4il6Da6G39s9MyWBEee4jztEOUGJ40E6OlPjkMrdpDNvge6hYEAB31BczTYBP/CEY74j4LDSoY5LbcU4kv06yA==
- dependencies:
- "@jimp/utils" "^0.6.8"
- core-js "^2.5.7"
-
-"@jimp/plugin-gaussian@^0.6.8":
- version "0.6.8"
- resolved "https://registry.npmjs.org/@jimp/plugin-gaussian/-/plugin-gaussian-0.6.8.tgz"
- integrity sha512-pVOblmjv7stZjsqloi4YzHVwAPXKGdNaHPhp4KP4vj41qtc6Hxd9z/+VWGYRTunMFac84gUToe0UKIXd6GhoKw==
- dependencies:
- "@jimp/utils" "^0.6.8"
- core-js "^2.5.7"
-
-"@jimp/plugin-invert@^0.6.8":
- version "0.6.8"
- resolved "https://registry.npmjs.org/@jimp/plugin-invert/-/plugin-invert-0.6.8.tgz"
- integrity sha512-11zuLiXDHr6tFv4U8aieXqNXQEKbDbSBG/h+X62gGTNFpyn8EVPpncHhOqrAFtZUaPibBqMFlNJ15SzwC7ExsQ==
- dependencies:
- "@jimp/utils" "^0.6.8"
- core-js "^2.5.7"
-
-"@jimp/plugin-mask@^0.6.8":
- version "0.6.8"
- resolved "https://registry.npmjs.org/@jimp/plugin-mask/-/plugin-mask-0.6.8.tgz"
- integrity sha512-hZJ0OiKGJyv7hDSATwJDkunB1Ie80xJnONMgpUuUseteK45YeYNBOiZVUe8vum8QI1UwavgBzcvQ9u4fcgXc9g==
- dependencies:
- "@jimp/utils" "^0.6.8"
- core-js "^2.5.7"
-
-"@jimp/plugin-normalize@^0.6.8":
- version "0.6.8"
- resolved "https://registry.npmjs.org/@jimp/plugin-normalize/-/plugin-normalize-0.6.8.tgz"
- integrity sha512-Q4oYhU+sSyTJI7pMZlg9/mYh68ujLfOxXzQGEXuw0sHGoGQs3B0Jw7jmzGa6pIS06Hup5hD2Zuh1ppvMdjJBfQ==
- dependencies:
- "@jimp/utils" "^0.6.8"
- core-js "^2.5.7"
-
-"@jimp/plugin-print@^0.6.8":
- version "0.6.8"
- resolved "https://registry.npmjs.org/@jimp/plugin-print/-/plugin-print-0.6.8.tgz"
- integrity sha512-2aokejGn4Drv1FesnZGqh5KEq0FQtR0drlmtyZrBH+r9cx7hh0Qgf4D1BOTDEgXkfSSngjGRjKKRW/fwOrVXYw==
- dependencies:
- "@jimp/utils" "^0.6.8"
- core-js "^2.5.7"
- load-bmfont "^1.4.0"
-
-"@jimp/plugin-resize@^0.6.8":
- version "0.6.8"
- resolved "https://registry.npmjs.org/@jimp/plugin-resize/-/plugin-resize-0.6.8.tgz"
- integrity sha512-27nPh8L1YWsxtfmV/+Ub5dOTpXyC0HMF2cu52RQSCYxr+Lm1+23dJF70AF1poUbUe+FWXphwuUxQzjBJza9UoA==
- dependencies:
- "@jimp/utils" "^0.6.8"
- core-js "^2.5.7"
-
-"@jimp/plugin-rotate@^0.6.8":
- version "0.6.8"
- resolved "https://registry.npmjs.org/@jimp/plugin-rotate/-/plugin-rotate-0.6.8.tgz"
- integrity sha512-GbjETvL05BDoLdszNUV4Y0yLkHf177MnqGqilA113LIvx9aD0FtUopGXYfRGVvmtTOTouoaGJUc+K6qngvKxww==
- dependencies:
- "@jimp/utils" "^0.6.8"
- core-js "^2.5.7"
-
-"@jimp/plugin-scale@^0.6.8":
- version "0.6.8"
- resolved "https://registry.npmjs.org/@jimp/plugin-scale/-/plugin-scale-0.6.8.tgz"
- integrity sha512-GzIYWR/oCUK2jAwku23zt19V1ssaEU4pL0x2XsLNKuuJEU6DvEytJyTMXCE7OLG/MpDBQcQclJKHgiyQm5gIOQ==
- dependencies:
- "@jimp/utils" "^0.6.8"
- core-js "^2.5.7"
-
-"@jimp/plugins@^0.6.8":
- version "0.6.8"
- resolved "https://registry.npmjs.org/@jimp/plugins/-/plugins-0.6.8.tgz"
- integrity sha512-fMcTI72Vn/Lz6JftezTURmyP5ml/xGMe0Ljx2KRJ85IWyP33vDmGIUuutFiBEbh2+y7lRT+aTSmjs0QGa/xTmQ==
- dependencies:
- "@jimp/plugin-blit" "^0.6.8"
- "@jimp/plugin-blur" "^0.6.8"
- "@jimp/plugin-color" "^0.6.8"
- "@jimp/plugin-contain" "^0.6.8"
- "@jimp/plugin-cover" "^0.6.8"
- "@jimp/plugin-crop" "^0.6.8"
- "@jimp/plugin-displace" "^0.6.8"
- "@jimp/plugin-dither" "^0.6.8"
- "@jimp/plugin-flip" "^0.6.8"
- "@jimp/plugin-gaussian" "^0.6.8"
- "@jimp/plugin-invert" "^0.6.8"
- "@jimp/plugin-mask" "^0.6.8"
- "@jimp/plugin-normalize" "^0.6.8"
- "@jimp/plugin-print" "^0.6.8"
- "@jimp/plugin-resize" "^0.6.8"
- "@jimp/plugin-rotate" "^0.6.8"
- "@jimp/plugin-scale" "^0.6.8"
- core-js "^2.5.7"
- timm "^1.6.1"
-
-"@jimp/png@^0.6.8":
- version "0.6.8"
- resolved "https://registry.npmjs.org/@jimp/png/-/png-0.6.8.tgz"
- integrity sha512-JHHg/BZ7KDtHQrcG+a7fztw45rdf7okL/YwkN4qU5FH7Fcrp41nX5QnRviDtD9hN+GaNC7kvjvcqRAxW25qjew==
- dependencies:
- "@jimp/utils" "^0.6.8"
- core-js "^2.5.7"
- pngjs "^3.3.3"
-
-"@jimp/tiff@^0.6.8":
- version "0.6.8"
- resolved "https://registry.npmjs.org/@jimp/tiff/-/tiff-0.6.8.tgz"
- integrity sha512-iWHbxd+0IKWdJyJ0HhoJCGYmtjPBOusz1z1HT/DnpePs/Lo3TO4d9ALXqYfUkyG74ZK5jULZ69KLtwuhuJz1bg==
- dependencies:
- core-js "^2.5.7"
- utif "^2.0.1"
-
-"@jimp/types@^0.6.8":
- version "0.6.8"
- resolved "https://registry.npmjs.org/@jimp/types/-/types-0.6.8.tgz"
- integrity sha512-vCZ/Cp2osy69VP21XOBACfHI5HeR60Rfd4Jidj4W73UL+HrFWOtyQiJ7hlToyu1vI5mR/NsUQpzyQvz56ADm5A==
- dependencies:
- "@jimp/bmp" "^0.6.8"
- "@jimp/gif" "^0.6.8"
- "@jimp/jpeg" "^0.6.8"
- "@jimp/png" "^0.6.8"
- "@jimp/tiff" "^0.6.8"
- core-js "^2.5.7"
- timm "^1.6.1"
-
-"@jimp/utils@^0.6.8":
- version "0.6.8"
- resolved "https://registry.npmjs.org/@jimp/utils/-/utils-0.6.8.tgz"
- integrity sha512-7RDfxQ2C/rarNG9iso5vmnKQbcvlQjBIlF/p7/uYj72WeZgVCB+5t1fFBKJSU4WhniHX4jUMijK+wYGE3Y3bGw==
- dependencies:
- core-js "^2.5.7"
-
-"@malept/cross-spawn-promise@^1.1.0":
- version "1.1.1"
- resolved "https://registry.yarnpkg.com/@malept/cross-spawn-promise/-/cross-spawn-promise-1.1.1.tgz#504af200af6b98e198bce768bc1730c6936ae01d"
- integrity sha512-RTBGWL5FWQcg9orDOCcp4LvItNzUPcyEU9bwaeJX0rJ1IQxzucC48Y0/sQLp/g6t99IQgAlGIaesJS+gTn7tVQ==
- dependencies:
- cross-spawn "^7.0.1"
-
-"@nodelib/fs.scandir@2.1.3":
- version "2.1.3"
- resolved "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz"
- integrity sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==
- dependencies:
- "@nodelib/fs.stat" "2.0.3"
- run-parallel "^1.1.9"
-
-"@nodelib/fs.stat@2.0.3", "@nodelib/fs.stat@^2.0.2":
- version "2.0.3"
- resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz"
- integrity sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==
-
-"@nodelib/fs.walk@^1.2.3":
- version "1.2.4"
- resolved "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz"
- integrity sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==
- dependencies:
- "@nodelib/fs.scandir" "2.1.3"
- fastq "^1.6.0"
-
-"@sindresorhus/is@^0.14.0":
- version "0.14.0"
- resolved "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz"
- integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==
-
-"@sindresorhus/is@^0.7.0":
- version "0.7.0"
- resolved "https://registry.npmjs.org/@sindresorhus/is/-/is-0.7.0.tgz"
- integrity sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow==
-
-"@szmarczak/http-timer@^1.1.2":
- version "1.1.2"
- resolved "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz"
- integrity sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==
- dependencies:
- defer-to-connect "^1.0.1"
-
-"@types/color-name@^1.1.1":
- version "1.1.1"
- resolved "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz"
- integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==
-
-"@types/cordova@^0.0.34":
- version "0.0.34"
- resolved "https://registry.npmjs.org/@types/cordova/-/cordova-0.0.34.tgz"
- integrity sha1-6nrd907Ow9dimCegw54smt3HPQQ=
-
-"@types/filesystem@^0.0.29":
- version "0.0.29"
- resolved "https://registry.npmjs.org/@types/filesystem/-/filesystem-0.0.29.tgz"
- integrity sha512-85/1KfRedmfPGsbK8YzeaQUyV1FQAvMPMTuWFQ5EkLd2w7szhNO96bk3Rh/SKmOfd9co2rCLf0Voy4o7ECBOvw==
- dependencies:
- "@types/filewriter" "*"
-
-"@types/filewriter@*":
- version "0.0.28"
- resolved "https://registry.npmjs.org/@types/filewriter/-/filewriter-0.0.28.tgz"
- integrity sha1-wFTor02d11205jq8dviFFocU1LM=
-
-"@types/glob@^7.1.1":
- version "7.1.2"
- resolved "https://registry.npmjs.org/@types/glob/-/glob-7.1.2.tgz"
- integrity sha512-VgNIkxK+j7Nz5P7jvUZlRvhuPSmsEfS03b0alKcq5V/STUKAa3Plemsn5mrQUO7am6OErJ4rhGEGJbACclrtRA==
- dependencies:
- "@types/minimatch" "*"
- "@types/node" "*"
-
-"@types/json-schema@^7.0.8":
- version "7.0.9"
- resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.9.tgz#97edc9037ea0c38585320b28964dde3b39e4660d"
- integrity sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==
-
-"@types/minimatch@*":
- version "3.0.3"
- resolved "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz"
- integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==
-
-"@types/node@*", "@types/node@^12.7.5":
- version "12.7.5"
- resolved "https://registry.npmjs.org/@types/node/-/node-12.7.5.tgz"
- integrity sha512-9fq4jZVhPNW8r+UYKnxF1e2HkDWOWKM5bC2/7c9wPV835I0aOrVbS/Hw/pWPk2uKrNXQqg9Z959Kz+IYDd5p3w==
-
-"@types/q@^1.5.1":
- version "1.5.2"
- resolved "https://registry.npmjs.org/@types/q/-/q-1.5.2.tgz"
- integrity sha512-ce5d3q03Ex0sy4R14722Rmt6MT07Ua+k4FwDfdcToYJcMKNtRVQvJ6JCAPdAmAnbRb6CsX6aYb9m96NGod9uTw==
-
-"@types/yauzl@^2.9.1":
- version "2.10.0"
- resolved "https://registry.yarnpkg.com/@types/yauzl/-/yauzl-2.10.0.tgz#b3248295276cf8c6f153ebe6a9aba0c988cb2599"
- integrity sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==
- dependencies:
- "@types/node" "*"
-
-"@webassemblyjs/ast@1.9.0":
- version "1.9.0"
- resolved "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz"
- integrity sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA==
- dependencies:
- "@webassemblyjs/helper-module-context" "1.9.0"
- "@webassemblyjs/helper-wasm-bytecode" "1.9.0"
- "@webassemblyjs/wast-parser" "1.9.0"
-
-"@webassemblyjs/floating-point-hex-parser@1.9.0":
- version "1.9.0"
- resolved "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.0.tgz"
- integrity sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA==
-
-"@webassemblyjs/helper-api-error@1.9.0":
- version "1.9.0"
- resolved "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.0.tgz"
- integrity sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw==
-
-"@webassemblyjs/helper-buffer@1.9.0":
- version "1.9.0"
- resolved "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.0.tgz"
- integrity sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA==
-
-"@webassemblyjs/helper-code-frame@1.9.0":
- version "1.9.0"
- resolved "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.0.tgz"
- integrity sha512-ERCYdJBkD9Vu4vtjUYe8LZruWuNIToYq/ME22igL+2vj2dQ2OOujIZr3MEFvfEaqKoVqpsFKAGsRdBSBjrIvZA==
- dependencies:
- "@webassemblyjs/wast-printer" "1.9.0"
-
-"@webassemblyjs/helper-fsm@1.9.0":
- version "1.9.0"
- resolved "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.0.tgz"
- integrity sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw==
-
-"@webassemblyjs/helper-module-context@1.9.0":
- version "1.9.0"
- resolved "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.0.tgz"
- integrity sha512-MJCW8iGC08tMk2enck1aPW+BE5Cw8/7ph/VGZxwyvGbJwjktKkDK7vy7gAmMDx88D7mhDTCNKAW5tED+gZ0W8g==
- dependencies:
- "@webassemblyjs/ast" "1.9.0"
-
-"@webassemblyjs/helper-wasm-bytecode@1.9.0":
- version "1.9.0"
- resolved "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.0.tgz"
- integrity sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw==
-
-"@webassemblyjs/helper-wasm-section@1.9.0":
- version "1.9.0"
- resolved "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.0.tgz"
- integrity sha512-XnMB8l3ek4tvrKUUku+IVaXNHz2YsJyOOmz+MMkZvh8h1uSJpSen6vYnw3IoQ7WwEuAhL8Efjms1ZWjqh2agvw==
- dependencies:
- "@webassemblyjs/ast" "1.9.0"
- "@webassemblyjs/helper-buffer" "1.9.0"
- "@webassemblyjs/helper-wasm-bytecode" "1.9.0"
- "@webassemblyjs/wasm-gen" "1.9.0"
-
-"@webassemblyjs/ieee754@1.9.0":
- version "1.9.0"
- resolved "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.9.0.tgz"
- integrity sha512-dcX8JuYU/gvymzIHc9DgxTzUUTLexWwt8uCTWP3otys596io0L5aW02Gb1RjYpx2+0Jus1h4ZFqjla7umFniTg==
- dependencies:
- "@xtuc/ieee754" "^1.2.0"
-
-"@webassemblyjs/leb128@1.9.0":
- version "1.9.0"
- resolved "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.9.0.tgz"
- integrity sha512-ENVzM5VwV1ojs9jam6vPys97B/S65YQtv/aanqnU7D8aSoHFX8GyhGg0CMfyKNIHBuAVjy3tlzd5QMMINa7wpw==
- dependencies:
- "@xtuc/long" "4.2.2"
-
-"@webassemblyjs/utf8@1.9.0":
- version "1.9.0"
- resolved "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.9.0.tgz"
- integrity sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w==
-
-"@webassemblyjs/wasm-edit@1.9.0":
- version "1.9.0"
- resolved "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.0.tgz"
- integrity sha512-FgHzBm80uwz5M8WKnMTn6j/sVbqilPdQXTWraSjBwFXSYGirpkSWE2R9Qvz9tNiTKQvoKILpCuTjBKzOIm0nxw==
- dependencies:
- "@webassemblyjs/ast" "1.9.0"
- "@webassemblyjs/helper-buffer" "1.9.0"
- "@webassemblyjs/helper-wasm-bytecode" "1.9.0"
- "@webassemblyjs/helper-wasm-section" "1.9.0"
- "@webassemblyjs/wasm-gen" "1.9.0"
- "@webassemblyjs/wasm-opt" "1.9.0"
- "@webassemblyjs/wasm-parser" "1.9.0"
- "@webassemblyjs/wast-printer" "1.9.0"
-
-"@webassemblyjs/wasm-gen@1.9.0":
- version "1.9.0"
- resolved "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.0.tgz"
- integrity sha512-cPE3o44YzOOHvlsb4+E9qSqjc9Qf9Na1OO/BHFy4OI91XDE14MjFN4lTMezzaIWdPqHnsTodGGNP+iRSYfGkjA==
- dependencies:
- "@webassemblyjs/ast" "1.9.0"
- "@webassemblyjs/helper-wasm-bytecode" "1.9.0"
- "@webassemblyjs/ieee754" "1.9.0"
- "@webassemblyjs/leb128" "1.9.0"
- "@webassemblyjs/utf8" "1.9.0"
-
-"@webassemblyjs/wasm-opt@1.9.0":
- version "1.9.0"
- resolved "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.0.tgz"
- integrity sha512-Qkjgm6Anhm+OMbIL0iokO7meajkzQD71ioelnfPEj6r4eOFuqm4YC3VBPqXjFyyNwowzbMD+hizmprP/Fwkl2A==
- dependencies:
- "@webassemblyjs/ast" "1.9.0"
- "@webassemblyjs/helper-buffer" "1.9.0"
- "@webassemblyjs/wasm-gen" "1.9.0"
- "@webassemblyjs/wasm-parser" "1.9.0"
-
-"@webassemblyjs/wasm-parser@1.9.0":
- version "1.9.0"
- resolved "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.0.tgz"
- integrity sha512-9+wkMowR2AmdSWQzsPEjFU7njh8HTO5MqO8vjwEHuM+AMHioNqSBONRdr0NQQ3dVQrzp0s8lTcYqzUdb7YgELA==
- dependencies:
- "@webassemblyjs/ast" "1.9.0"
- "@webassemblyjs/helper-api-error" "1.9.0"
- "@webassemblyjs/helper-wasm-bytecode" "1.9.0"
- "@webassemblyjs/ieee754" "1.9.0"
- "@webassemblyjs/leb128" "1.9.0"
- "@webassemblyjs/utf8" "1.9.0"
-
-"@webassemblyjs/wast-parser@1.9.0":
- version "1.9.0"
- resolved "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.9.0.tgz"
- integrity sha512-qsqSAP3QQ3LyZjNC/0jBJ/ToSxfYJ8kYyuiGvtn/8MK89VrNEfwj7BPQzJVHi0jGTRK2dGdJ5PRqhtjzoww+bw==
- dependencies:
- "@webassemblyjs/ast" "1.9.0"
- "@webassemblyjs/floating-point-hex-parser" "1.9.0"
- "@webassemblyjs/helper-api-error" "1.9.0"
- "@webassemblyjs/helper-code-frame" "1.9.0"
- "@webassemblyjs/helper-fsm" "1.9.0"
- "@xtuc/long" "4.2.2"
-
-"@webassemblyjs/wast-printer@1.9.0":
- version "1.9.0"
- resolved "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.9.0.tgz"
- integrity sha512-2J0nE95rHXHyQ24cWjMKJ1tqB/ds8z/cyeOZxJhcb+rW+SQASVjuznUSmdz5GpVJTzU8JkhYut0D3siFDD6wsA==
- dependencies:
- "@webassemblyjs/ast" "1.9.0"
- "@webassemblyjs/wast-parser" "1.9.0"
- "@xtuc/long" "4.2.2"
-
-"@xtuc/ieee754@^1.2.0":
- version "1.2.0"
- resolved "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz"
- integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==
-
-"@xtuc/long@4.2.2":
- version "4.2.2"
- resolved "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz"
- integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==
-
-abab@^2.0.0:
- version "2.0.1"
- resolved "https://registry.npmjs.org/abab/-/abab-2.0.1.tgz"
- integrity sha512-1zSbbCuoIjafKZ3mblY5ikvAb0ODUbqBnFuUb7f6uLeQhhGJ0vEV4ntmtxKLT2WgXCO94E07BjunsIw1jOMPZw==
-
-abbrev@1:
- version "1.1.1"
- resolved "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz"
- integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==
-
-accepts@~1.3.4:
- version "1.3.7"
- resolved "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz"
- integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==
- dependencies:
- mime-types "~2.1.24"
- negotiator "0.6.2"
-
-acorn-globals@^4.3.0:
- version "4.3.4"
- resolved "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.4.tgz"
- integrity sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A==
- dependencies:
- acorn "^6.0.1"
- acorn-walk "^6.0.1"
-
-acorn-jsx@^3.0.0:
- version "3.0.1"
- resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz"
- integrity sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=
- dependencies:
- acorn "^3.0.4"
-
-acorn-jsx@^5.0.0:
- version "5.0.2"
- resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.0.2.tgz"
- integrity sha512-tiNTrP1MP0QrChmD2DdupCr6HWSFeKVw5d/dHTu4Y7rkAkRhU/Dt7dphAfIUyxtHpl/eBVip5uTNSpQJHylpAw==
-
-acorn-walk@^6.0.1:
- version "6.2.0"
- resolved "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.2.0.tgz"
- integrity sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==
-
-acorn@^3.0.4:
- version "3.3.0"
- resolved "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz"
- integrity sha1-ReN/s56No/JbruP/U2niu18iAXo=
-
-acorn@^5.5.0:
- version "5.7.3"
- resolved "https://registry.npmjs.org/acorn/-/acorn-5.7.3.tgz"
- integrity sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==
-
-acorn@^6.0.1, acorn@^6.0.2, acorn@^6.0.7, acorn@^6.4.1:
- version "6.4.1"
- resolved "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz"
- integrity sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==
-
-acorn@^6.0.6:
- version "6.4.2"
- resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.2.tgz#35866fd710528e92de10cf06016498e47e39e1e6"
- integrity sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==
-
-after@0.8.2:
- version "0.8.2"
- resolved "https://registry.npmjs.org/after/-/after-0.8.2.tgz"
- integrity sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=
-
-ajv-errors@^1.0.0:
- version "1.0.1"
- resolved "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz"
- integrity sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==
-
-ajv-keywords@^1.0.0:
- version "1.5.1"
- resolved "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-1.5.1.tgz"
- integrity sha1-MU3QpLM2j609/NxU7eYXG4htrzw=
-
-ajv-keywords@^3.1.0, ajv-keywords@^3.4.1:
- version "3.4.1"
- resolved "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.1.tgz"
- integrity sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==
-
-ajv-keywords@^3.5.2:
- version "3.5.2"
- resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d"
- integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==
-
-ajv@^4.7.0:
- version "4.11.8"
- resolved "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz"
- integrity sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=
- dependencies:
- co "^4.6.0"
- json-stable-stringify "^1.0.1"
-
-ajv@^6.1.0, ajv@^6.10.2, ajv@^6.12.0, ajv@^6.5.5, ajv@^6.9.1:
- version "6.12.0"
- resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.0.tgz"
- integrity sha512-D6gFiFA0RRLyUbvijN74DWAjXSFxWKaWP7mldxkVhyhAV3+SWA9HEJPHQ2c9soIeTFJqcSdFDGFgdqs1iUU2Hw==
- dependencies:
- fast-deep-equal "^3.1.1"
- fast-json-stable-stringify "^2.0.0"
- json-schema-traverse "^0.4.1"
- uri-js "^4.2.2"
-
-ajv@^6.12.5:
- version "6.12.6"
- resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4"
- integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==
- dependencies:
- fast-deep-equal "^3.1.1"
- fast-json-stable-stringify "^2.0.0"
- json-schema-traverse "^0.4.1"
- uri-js "^4.2.2"
-
-alphanum-sort@^1.0.0:
- version "1.0.2"
- resolved "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz"
- integrity sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=
-
-amdefine@>=0.0.4:
- version "1.0.1"
- resolved "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz"
- integrity sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=
-
-ansi-colors@^1.0.1:
- version "1.1.0"
- resolved "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz"
- integrity sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA==
- dependencies:
- ansi-wrap "^0.1.0"
-
-ansi-colors@^4.1.0:
- version "4.1.1"
- resolved "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz"
- integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==
-
-ansi-cyan@^0.1.1:
- version "0.1.1"
- resolved "https://registry.npmjs.org/ansi-cyan/-/ansi-cyan-0.1.1.tgz"
- integrity sha1-U4rlKK+JgvKK4w2G8vF0VtJgmHM=
- dependencies:
- ansi-wrap "0.1.0"
-
-ansi-escapes@^1.1.0:
- version "1.4.0"
- resolved "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz"
- integrity sha1-06ioOzGapneTZisT52HHkRQiMG4=
-
-ansi-escapes@^3.2.0:
- version "3.2.0"
- resolved "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz"
- integrity sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==
-
-ansi-gray@^0.1.1:
- version "0.1.1"
- resolved "https://registry.npmjs.org/ansi-gray/-/ansi-gray-0.1.1.tgz"
- integrity sha1-KWLPVOyXksSFEKPetSRDaGHvclE=
- dependencies:
- ansi-wrap "0.1.0"
-
-ansi-red@^0.1.1:
- version "0.1.1"
- resolved "https://registry.npmjs.org/ansi-red/-/ansi-red-0.1.1.tgz"
- integrity sha1-jGOPnRCAgAo1PJwoyKgcpHBdlGw=
- dependencies:
- ansi-wrap "0.1.0"
-
-ansi-regex@^0.2.0, ansi-regex@^0.2.1:
- version "0.2.1"
- resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz"
- integrity sha1-DY6UaWej2BQ/k+JOKYUl/BsiNfk=
-
-ansi-regex@^2.0.0:
- version "2.1.1"
- resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz"
- integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8=
-
-ansi-regex@^3.0.0:
- version "3.0.0"
- resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz"
- integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=
-
-ansi-regex@^4.1.0:
- version "4.1.0"
- resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz"
- integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==
-
-ansi-regex@^5.0.0:
- version "5.0.0"
- resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz"
- integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==
-
-ansi-styles@^1.1.0:
- version "1.1.0"
- resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.1.0.tgz"
- integrity sha1-6uy/Zs1waIJ2Cy9GkVgrj1XXp94=
-
-ansi-styles@^2.2.1:
- version "2.2.1"
- resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz"
- integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=
-
-ansi-styles@^3.2.0, ansi-styles@^3.2.1:
- version "3.2.1"
- resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz"
- integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==
- dependencies:
- color-convert "^1.9.0"
-
-ansi-styles@^4.0.0, ansi-styles@^4.1.0:
- version "4.2.1"
- resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz"
- integrity sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==
- dependencies:
- "@types/color-name" "^1.1.1"
- color-convert "^2.0.1"
-
-ansi-wrap@0.1.0, ansi-wrap@^0.1.0:
- version "0.1.0"
- resolved "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz"
- integrity sha1-qCJQ3bABXponyoLoLqYDu/pF768=
-
-any-base@^1.1.0:
- version "1.1.0"
- resolved "https://registry.npmjs.org/any-base/-/any-base-1.1.0.tgz"
- integrity sha512-uMgjozySS8adZZYePpaWs8cxB9/kdzmpX6SgJZ+wbz1K5eYk5QMYDVJaZKhxyIHUdnnJkfR7SVgStgH7LkGUyg==
-
-anymatch@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz"
- integrity sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==
- dependencies:
- micromatch "^3.1.4"
- normalize-path "^2.1.1"
-
-anymatch@~3.1.1:
- version "3.1.1"
- resolved "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz"
- integrity sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==
- dependencies:
- normalize-path "^3.0.0"
- picomatch "^2.0.4"
-
-append-buffer@^1.0.2:
- version "1.0.2"
- resolved "https://registry.npmjs.org/append-buffer/-/append-buffer-1.0.2.tgz"
- integrity sha1-2CIM9GYIFSXv6lBhTz3mUU36WPE=
- dependencies:
- buffer-equal "^1.0.0"
-
-aproba@^1.1.1:
- version "1.2.0"
- resolved "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz"
- integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==
-
-arch@^2.1.0:
- version "2.1.1"
- resolved "https://registry.npmjs.org/arch/-/arch-2.1.1.tgz"
- integrity sha512-BLM56aPo9vLLFVa8+/+pJLnrZ7QGGTVHWsCwieAWT9o9K8UeGaQbzZbGoabWLOo2ksBCztoXdqBZBplqLDDCSg==
-
-archive-type@^4.0.0:
- version "4.0.0"
- resolved "https://registry.npmjs.org/archive-type/-/archive-type-4.0.0.tgz"
- integrity sha1-+S5yIzBW38aWlHJ0nCZ72wRrHXA=
- dependencies:
- file-type "^4.2.0"
-
-archiver@~0.11.0:
- version "0.11.0"
- resolved "https://registry.npmjs.org/archiver/-/archiver-0.11.0.tgz"
- integrity sha1-mBd9p6bAGSt/J5jzDNbquKvXZpA=
- dependencies:
- async "~0.9.0"
- buffer-crc32 "~0.2.1"
- glob "~3.2.6"
- lazystream "~0.1.0"
- lodash "~2.4.1"
- readable-stream "~1.0.26"
- tar-stream "~0.4.0"
- zip-stream "~0.4.0"
-
-archy@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz"
- integrity sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=
-
-are-you-es5@^2.1.2:
- version "2.1.2"
- resolved "https://registry.yarnpkg.com/are-you-es5/-/are-you-es5-2.1.2.tgz#d75511a174a3f842d70cc784aec0bcaff5a57547"
- integrity sha512-gkT2bLCfzyJJr3lYoxZKScdD/Yp5zzghi+3KawONTvH/7rrgU3RMXYvGQnOTlqEFVgZFpEGj/6bZ6sF/9YtddA==
- dependencies:
- acorn "^6.0.6"
- array-flatten "^2.1.0"
- commander "^2.19.0"
- find-up "^4.1.0"
-
-argparse@^1.0.7:
- version "1.0.10"
- resolved "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz"
- integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==
- dependencies:
- sprintf-js "~1.0.2"
-
-arr-diff@^1.0.1:
- version "1.1.0"
- resolved "https://registry.npmjs.org/arr-diff/-/arr-diff-1.1.0.tgz"
- integrity sha1-aHwydYFjWI/vfeezb6vklesaOZo=
- dependencies:
- arr-flatten "^1.0.1"
- array-slice "^0.2.3"
-
-arr-diff@^4.0.0:
- version "4.0.0"
- resolved "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz"
- integrity sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=
-
-arr-filter@^1.1.1:
- version "1.1.2"
- resolved "https://registry.npmjs.org/arr-filter/-/arr-filter-1.1.2.tgz"
- integrity sha1-Q/3d0JHo7xGqTEXZzcGOLf8XEe4=
- dependencies:
- make-iterator "^1.0.0"
-
-arr-flatten@^1.0.1, arr-flatten@^1.1.0:
- version "1.1.0"
- resolved "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz"
- integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==
-
-arr-map@^2.0.0, arr-map@^2.0.2:
- version "2.0.2"
- resolved "https://registry.npmjs.org/arr-map/-/arr-map-2.0.2.tgz"
- integrity sha1-Onc0X/wc814qkYJWAfnljy4kysQ=
- dependencies:
- make-iterator "^1.0.0"
-
-arr-union@^2.0.1:
- version "2.1.0"
- resolved "https://registry.npmjs.org/arr-union/-/arr-union-2.1.0.tgz"
- integrity sha1-IPnqtexw9cfSFbEHexw5Fh0pLH0=
-
-arr-union@^3.1.0:
- version "3.1.0"
- resolved "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz"
- integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=
-
-array-differ@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz"
- integrity sha1-7/UuN1gknTO+QCuLuOVkuytdQDE=
-
-array-each@^1.0.0, array-each@^1.0.1:
- version "1.0.1"
- resolved "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz"
- integrity sha1-p5SvDAWrF1KEbudTofIRoFugxE8=
-
-array-equal@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz"
- integrity sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=
-
-array-find-index@^1.0.1:
- version "1.0.2"
- resolved "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz"
- integrity sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=
-
-array-flatten@^2.1.0:
- version "2.1.2"
- resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.2.tgz#24ef80a28c1a893617e2149b0c6d0d788293b099"
- integrity sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==
-
-array-initial@^1.0.0:
- version "1.1.0"
- resolved "https://registry.npmjs.org/array-initial/-/array-initial-1.1.0.tgz"
- integrity sha1-L6dLJnOTccOUe9enrcc74zSz15U=
- dependencies:
- array-slice "^1.0.0"
- is-number "^4.0.0"
-
-array-last@^1.1.1:
- version "1.3.0"
- resolved "https://registry.npmjs.org/array-last/-/array-last-1.3.0.tgz"
- integrity sha512-eOCut5rXlI6aCOS7Z7kCplKRKyiFQ6dHFBem4PwlwKeNFk2/XxTrhRh5T9PyaEWGy/NHTZWbY+nsZlNFJu9rYg==
- dependencies:
- is-number "^4.0.0"
-
-array-slice@^0.2.3:
- version "0.2.3"
- resolved "https://registry.npmjs.org/array-slice/-/array-slice-0.2.3.tgz"
- integrity sha1-3Tz7gO15c6dRF82sabC5nshhhvU=
-
-array-slice@^1.0.0:
- version "1.1.0"
- resolved "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz"
- integrity sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==
-
-array-sort@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/array-sort/-/array-sort-1.0.0.tgz"
- integrity sha512-ihLeJkonmdiAsD7vpgN3CRcx2J2S0TiYW+IS/5zHBI7mKUq3ySvBdzzBfD236ubDBQFiiyG3SWCPc+msQ9KoYg==
- dependencies:
- default-compare "^1.0.0"
- get-value "^2.0.6"
- kind-of "^5.0.2"
-
-array-union@^2.1.0:
- version "2.1.0"
- resolved "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz"
- integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==
-
-array-uniq@^1.0.2:
- version "1.0.3"
- resolved "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz"
- integrity sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=
-
-array-uniq@^2.1.0:
- version "2.1.0"
- resolved "https://registry.npmjs.org/array-uniq/-/array-uniq-2.1.0.tgz"
- integrity sha512-bdHxtev7FN6+MXI1YFW0Q8mQ8dTJc2S8AMfju+ZR77pbg2yAdVyDlwkaUI7Har0LyOMRFPHrJ9lYdyjZZswdlQ==
-
-array-unique@^0.3.2:
- version "0.3.2"
- resolved "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz"
- integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=
-
-arraybuffer.slice@~0.0.7:
- version "0.0.7"
- resolved "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz"
- integrity sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==
-
-asar@^3.1.0:
- version "3.1.0"
- resolved "https://registry.yarnpkg.com/asar/-/asar-3.1.0.tgz#70b0509449fe3daccc63beb4d3c7d2e24d3c6473"
- integrity sha512-vyxPxP5arcAqN4F/ebHd/HhwnAiZtwhglvdmc7BR2f0ywbVNTOpSeyhLDbGXtE/y58hv1oC75TaNIXutnsOZsQ==
- dependencies:
- chromium-pickle-js "^0.2.0"
- commander "^5.0.0"
- glob "^7.1.6"
- minimatch "^3.0.4"
- optionalDependencies:
- "@types/glob" "^7.1.1"
-
-asn1.js@^4.0.0:
- version "4.10.1"
- resolved "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz"
- integrity sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==
- dependencies:
- bn.js "^4.0.0"
- inherits "^2.0.1"
- minimalistic-assert "^1.0.0"
-
-asn1@~0.2.0, asn1@~0.2.3:
- version "0.2.4"
- resolved "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz"
- integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==
- dependencies:
- safer-buffer "~2.1.0"
-
-assert-plus@1.0.0, assert-plus@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz"
- integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=
-
-assert@^1.1.1:
- version "1.5.0"
- resolved "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz"
- integrity sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==
- dependencies:
- object-assign "^4.1.1"
- util "0.10.3"
-
-assets@^3.0.0:
- version "3.0.1"
- resolved "https://registry.npmjs.org/assets/-/assets-3.0.1.tgz"
- integrity sha512-fTyLNf/9V24y5zO83f4DAEuvaKj7MWBixbnqdZneAhsv1r21yQ/6ogZfvXHmphJAHsz4DhuOwHeJKVbGqqvk0Q==
- dependencies:
- async "^2.5.0"
- bluebird "^3.4.6"
- calipers "^2.0.0"
- calipers-gif "^2.0.0"
- calipers-jpeg "^2.0.0"
- calipers-png "^2.0.0"
- calipers-svg "^2.0.0"
- calipers-webp "^2.0.0"
- glob "^7.0.6"
- lodash "^4.15.0"
- mime "^2.4.0"
-
-assign-symbols@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz"
- integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=
-
-ast-types@0.9.6:
- version "0.9.6"
- resolved "https://registry.npmjs.org/ast-types/-/ast-types-0.9.6.tgz"
- integrity sha1-ECyenpAF0+fjgpvwxPok7oYu6bk=
-
-astral-regex@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz"
- integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==
-
-async-done@^1.2.0, async-done@^1.2.2:
- version "1.3.2"
- resolved "https://registry.npmjs.org/async-done/-/async-done-1.3.2.tgz"
- integrity sha512-uYkTP8dw2og1tu1nmza1n1CMW0qb8gWWlwqMmLb7MhBVs4BXrFziT6HXUd+/RlRA/i4H9AkofYloUbs1fwMqlw==
- dependencies:
- end-of-stream "^1.1.0"
- once "^1.3.2"
- process-nextick-args "^2.0.0"
- stream-exhaust "^1.0.1"
-
-async-each-series@0.1.1:
- version "0.1.1"
- resolved "https://registry.npmjs.org/async-each-series/-/async-each-series-0.1.1.tgz"
- integrity sha1-dhfBkXQB/Yykooqtzj266Yr+tDI=
-
-async-each@^1.0.1:
- version "1.0.3"
- resolved "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz"
- integrity sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==
-
-async-limiter@~1.0.0:
- version "1.0.1"
- resolved "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz"
- integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==
-
-async-settle@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/async-settle/-/async-settle-1.0.0.tgz"
- integrity sha1-HQqRS7Aldb7IqPOnTlCA9yssDGs=
- dependencies:
- async-done "^1.2.2"
-
-async@1.5.2:
- version "1.5.2"
- resolved "https://registry.npmjs.org/async/-/async-1.5.2.tgz"
- integrity sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=
-
-async@>=0.2.9, async@~0.9.0:
- version "0.9.2"
- resolved "https://registry.npmjs.org/async/-/async-0.9.2.tgz"
- integrity sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=
-
-async@^2.5.0:
- version "2.6.3"
- resolved "https://registry.npmjs.org/async/-/async-2.6.3.tgz"
- integrity sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==
- dependencies:
- lodash "^4.17.14"
-
-async@~0.2.10:
- version "0.2.10"
- resolved "https://registry.npmjs.org/async/-/async-0.2.10.tgz"
- integrity sha1-trvgsGdLnXGXCMo43owjfLUmw9E=
-
-async@~1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/async/-/async-1.0.0.tgz"
- integrity sha1-+PwEyjoTeErenhZBr5hXjPvWR6k=
-
-asynckit@^0.4.0:
- version "0.4.0"
- resolved "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz"
- integrity sha1-x57Zf380y48robyXkLzDZkdLS3k=
-
-at-least-node@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2"
- integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==
-
-atob@^2.1.1:
- version "2.1.2"
- resolved "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz"
- integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==
-
-audiosprite@*, audiosprite@^0.7.2:
- version "0.7.2"
- resolved "https://registry.npmjs.org/audiosprite/-/audiosprite-0.7.2.tgz"
- integrity sha512-9Z6UwUuv4To5nUQNRIw5/Q3qA7HYm0ANzoW5EDGPEsU2oIRVgmIlLlm9YZfpPKoeUxt54vMStl2/762189VmJw==
- dependencies:
- async "~0.9.0"
- glob "^6.0.4"
- mkdirp "^0.5.0"
- optimist "~0.6.1"
- underscore "~1.8.3"
- winston "~1.0.0"
-
-author-regex@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/author-regex/-/author-regex-1.0.0.tgz"
- integrity sha1-0IiFvmubv5Q5/gh8dihyRfCoFFA=
-
-autoprefixer@^9.4.3, autoprefixer@^9.4.7, autoprefixer@^9.6.1:
- version "9.6.1"
- resolved "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.6.1.tgz"
- integrity sha512-aVo5WxR3VyvyJxcJC3h4FKfwCQvQWb1tSI5VHNibddCVWrcD1NvlxEweg3TSgiPztMnWfjpy2FURKA2kvDE+Tw==
- dependencies:
- browserslist "^4.6.3"
- caniuse-lite "^1.0.30000980"
- chalk "^2.4.2"
- normalize-range "^0.1.2"
- num2fraction "^1.2.2"
- postcss "^7.0.17"
- postcss-value-parser "^4.0.0"
-
-aws-sign2@~0.7.0:
- version "0.7.0"
- resolved "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz"
- integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=
-
-aws4@^1.8.0:
- version "1.8.0"
- resolved "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz"
- integrity sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==
-
-axios@0.19.0:
- version "0.19.0"
- resolved "https://registry.npmjs.org/axios/-/axios-0.19.0.tgz"
- integrity sha512-1uvKqKQta3KBxIz14F2v06AEHZ/dIoeKfbTRkK1E5oqjDnuEerLmYTgJB5AiQZHJcljpg1TuRzdjDR06qNk0DQ==
- dependencies:
- follow-redirects "1.5.10"
- is-buffer "^2.0.2"
-
-babel-code-frame@^6.26.0:
- version "6.26.0"
- resolved "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz"
- integrity sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=
- dependencies:
- chalk "^1.1.3"
- esutils "^2.0.2"
- js-tokens "^3.0.2"
-
-babel-core@^6.26.0, babel-core@^6.26.3:
- version "6.26.3"
- resolved "https://registry.npmjs.org/babel-core/-/babel-core-6.26.3.tgz"
- integrity sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA==
- dependencies:
- babel-code-frame "^6.26.0"
- babel-generator "^6.26.0"
- babel-helpers "^6.24.1"
- babel-messages "^6.23.0"
- babel-register "^6.26.0"
- babel-runtime "^6.26.0"
- babel-template "^6.26.0"
- babel-traverse "^6.26.0"
- babel-types "^6.26.0"
- babylon "^6.18.0"
- convert-source-map "^1.5.1"
- debug "^2.6.9"
- json5 "^0.5.1"
- lodash "^4.17.4"
- minimatch "^3.0.4"
- path-is-absolute "^1.0.1"
- private "^0.1.8"
- slash "^1.0.0"
- source-map "^0.5.7"
-
-babel-generator@^6.26.0:
- version "6.26.1"
- resolved "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.1.tgz"
- integrity sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==
- dependencies:
- babel-messages "^6.23.0"
- babel-runtime "^6.26.0"
- babel-types "^6.26.0"
- detect-indent "^4.0.0"
- jsesc "^1.3.0"
- lodash "^4.17.4"
- source-map "^0.5.7"
- trim-right "^1.0.1"
-
-babel-helpers@^6.24.1:
- version "6.24.1"
- resolved "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz"
- integrity sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=
- dependencies:
- babel-runtime "^6.22.0"
- babel-template "^6.24.1"
-
-babel-loader@^8.1.0:
- version "8.1.0"
- resolved "https://registry.npmjs.org/babel-loader/-/babel-loader-8.1.0.tgz"
- integrity sha512-7q7nC1tYOrqvUrN3LQK4GwSk/TQorZSOlO9C+RZDZpODgyN4ZlCqE5q9cDsyWOliN+aU9B4JX01xK9eJXowJLw==
- dependencies:
- find-cache-dir "^2.1.0"
- loader-utils "^1.4.0"
- mkdirp "^0.5.3"
- pify "^4.0.1"
- schema-utils "^2.6.5"
-
-babel-messages@^6.23.0:
- version "6.23.0"
- resolved "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz"
- integrity sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=
- dependencies:
- babel-runtime "^6.22.0"
-
-babel-plugin-closure-elimination@^1.3.0:
- version "1.3.0"
- resolved "https://registry.npmjs.org/babel-plugin-closure-elimination/-/babel-plugin-closure-elimination-1.3.0.tgz"
- integrity sha512-ClKuSxKLLNhe69bvTMuONDI0dQDW49lXB2qtQyyKCzvwegRGel/q4/e+1EoDNDN97Hf1QkxGMbzpAGPmU4Tfjw==
-
-babel-plugin-console-source@^2.0.2:
- version "2.0.4"
- resolved "https://registry.npmjs.org/babel-plugin-console-source/-/babel-plugin-console-source-2.0.4.tgz"
- integrity sha512-OGhrdhuMjiEW0Ma0P9e2B4dFddCpJ/xN/RRaM/4wwDLl+6ZKf+Xd77FtVjpNeDzNRNk8wjRdStA4hpZizXzl1g==
-
-babel-plugin-danger-remove-unused-import@^1.1.2:
- version "1.1.2"
- resolved "https://registry.npmjs.org/babel-plugin-danger-remove-unused-import/-/babel-plugin-danger-remove-unused-import-1.1.2.tgz"
- integrity sha512-3bNmVAaakP3b1aROj7O3bOWj2kBa85sZR5naZ3Rn8L9buiZaAyZLgjfrPDL3zhX4wySOA5jrTm/wSmJPsMm3cg==
-
-babel-plugin-dynamic-import-node@^2.3.0:
- version "2.3.0"
- resolved "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.0.tgz"
- integrity sha512-o6qFkpeQEBxcqt0XYlWzAVxNCSCZdUgcR8IRlhD/8DylxjjO4foPcvTW0GGKa/cVt3rvxZ7o5ippJ+/0nvLhlQ==
- dependencies:
- object.assign "^4.1.0"
-
-babel-register@^6.26.0:
- version "6.26.0"
- resolved "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz"
- integrity sha1-btAhFz4vy0htestFxgCahW9kcHE=
- dependencies:
- babel-core "^6.26.0"
- babel-runtime "^6.26.0"
- core-js "^2.5.0"
- home-or-tmp "^2.0.0"
- lodash "^4.17.4"
- mkdirp "^0.5.1"
- source-map-support "^0.4.15"
-
-babel-runtime@^6.22.0, babel-runtime@^6.26.0:
- version "6.26.0"
- resolved "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz"
- integrity sha1-llxwWGaOgrVde/4E/yM3vItWR/4=
- dependencies:
- core-js "^2.4.0"
- regenerator-runtime "^0.11.0"
-
-babel-runtime@^7.0.0-beta.3:
- version "7.0.0-beta.3"
- resolved "https://registry.npmjs.org/babel-runtime/-/babel-runtime-7.0.0-beta.3.tgz"
- integrity sha512-jlzZ8RACjt0QGxq+wqsw5bCQE9RcUyWpw987mDY3GYxTpOQT2xoyNoG++oVCHzr/nACLBIprfVBNvv/If1ZYcg==
- dependencies:
- core-js "^2.4.0"
- regenerator-runtime "^0.11.0"
-
-babel-template@^6.24.1, babel-template@^6.26.0:
- version "6.26.0"
- resolved "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz"
- integrity sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=
- dependencies:
- babel-runtime "^6.26.0"
- babel-traverse "^6.26.0"
- babel-types "^6.26.0"
- babylon "^6.18.0"
- lodash "^4.17.4"
-
-babel-traverse@^6.26.0:
- version "6.26.0"
- resolved "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz"
- integrity sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=
- dependencies:
- babel-code-frame "^6.26.0"
- babel-messages "^6.23.0"
- babel-runtime "^6.26.0"
- babel-types "^6.26.0"
- babylon "^6.18.0"
- debug "^2.6.8"
- globals "^9.18.0"
- invariant "^2.2.2"
- lodash "^4.17.4"
-
-babel-types@^6.26.0:
- version "6.26.0"
- resolved "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz"
- integrity sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=
- dependencies:
- babel-runtime "^6.26.0"
- esutils "^2.0.2"
- lodash "^4.17.4"
- to-fast-properties "^1.0.3"
-
-babylon@^6.18.0:
- version "6.18.0"
- resolved "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz"
- integrity sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==
-
-bach@^1.0.0:
- version "1.2.0"
- resolved "https://registry.npmjs.org/bach/-/bach-1.2.0.tgz"
- integrity sha1-Szzpa/JxNPeaG0FKUcFONMO9mIA=
- dependencies:
- arr-filter "^1.1.1"
- arr-flatten "^1.0.1"
- arr-map "^2.0.0"
- array-each "^1.0.0"
- array-initial "^1.0.0"
- array-last "^1.1.1"
- async-done "^1.2.2"
- async-settle "^1.0.0"
- now-and-later "^2.0.0"
-
-backo2@1.0.2:
- version "1.0.2"
- resolved "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz"
- integrity sha1-MasayLEpNjRj41s+u2n038+6eUc=
-
-balanced-match@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz"
- integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c=
-
-base64-arraybuffer@0.1.5:
- version "0.1.5"
- resolved "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz"
- integrity sha1-c5JncZI7Whl0etZmqlzUv5xunOg=
-
-base64-js@^1.0.2, base64-js@^1.2.3:
- version "1.3.1"
- resolved "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz"
- integrity sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==
-
-base64-js@^1.5.1:
- version "1.5.1"
- resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a"
- integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==
-
-base64id@1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/base64id/-/base64id-1.0.0.tgz"
- integrity sha1-R2iMuZu2gE8OBtPnY7HDLlfY5rY=
-
-base@^0.11.1:
- version "0.11.2"
- resolved "https://registry.npmjs.org/base/-/base-0.11.2.tgz"
- integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==
- dependencies:
- cache-base "^1.0.1"
- class-utils "^0.3.5"
- component-emitter "^1.2.1"
- define-property "^1.0.0"
- isobject "^3.0.1"
- mixin-deep "^1.2.0"
- pascalcase "^0.1.1"
-
-batch@0.6.1:
- version "0.6.1"
- resolved "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz"
- integrity sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=
-
-bcrypt-pbkdf@^1.0.0:
- version "1.0.2"
- resolved "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz"
- integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=
- dependencies:
- tweetnacl "^0.14.3"
-
-beeper@^1.0.0:
- version "1.1.1"
- resolved "https://registry.npmjs.org/beeper/-/beeper-1.1.1.tgz"
- integrity sha1-5tXqjF2tABMEpwsiY4RH9pyy+Ak=
-
-better-assert@~1.0.0:
- version "1.0.2"
- resolved "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz"
- integrity sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI=
- dependencies:
- callsite "1.0.0"
-
-big.js@^3.1.3:
- version "3.2.0"
- resolved "https://registry.npmjs.org/big.js/-/big.js-3.2.0.tgz"
- integrity sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==
-
-big.js@^5.2.2:
- version "5.2.2"
- resolved "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz"
- integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==
-
-bin-build@^3.0.0:
- version "3.0.0"
- resolved "https://registry.npmjs.org/bin-build/-/bin-build-3.0.0.tgz"
- integrity sha512-jcUOof71/TNAI2uM5uoUaDq2ePcVBQ3R/qhxAz1rX7UfvduAL/RXD3jXzvn8cVcDJdGVkiR1shal3OH0ImpuhA==
- dependencies:
- decompress "^4.0.0"
- download "^6.2.2"
- execa "^0.7.0"
- p-map-series "^1.0.0"
- tempfile "^2.0.0"
-
-bin-check@^4.1.0:
- version "4.1.0"
- resolved "https://registry.npmjs.org/bin-check/-/bin-check-4.1.0.tgz"
- integrity sha512-b6weQyEUKsDGFlACWSIOfveEnImkJyK/FGW6FAG42loyoquvjdtOIqO6yBFzHyqyVVhNgNkQxxx09SFLK28YnA==
- dependencies:
- execa "^0.7.0"
- executable "^4.1.0"
-
-bin-version-check@^4.0.0:
- version "4.0.0"
- resolved "https://registry.npmjs.org/bin-version-check/-/bin-version-check-4.0.0.tgz"
- integrity sha512-sR631OrhC+1f8Cvs8WyVWOA33Y8tgwjETNPyyD/myRBXLkfS/vl74FmH/lFcRl9KY3zwGh7jFhvyk9vV3/3ilQ==
- dependencies:
- bin-version "^3.0.0"
- semver "^5.6.0"
- semver-truncate "^1.1.2"
-
-bin-version@^3.0.0:
- version "3.1.0"
- resolved "https://registry.npmjs.org/bin-version/-/bin-version-3.1.0.tgz"
- integrity sha512-Mkfm4iE1VFt4xd4vH+gx+0/71esbfus2LsnCGe8Pi4mndSPyT+NGES/Eg99jx8/lUGWfu3z2yuB/bt5UB+iVbQ==
- dependencies:
- execa "^1.0.0"
- find-versions "^3.0.0"
-
-bin-wrapper@^4.0.0, bin-wrapper@^4.0.1:
- version "4.1.0"
- resolved "https://registry.npmjs.org/bin-wrapper/-/bin-wrapper-4.1.0.tgz"
- integrity sha512-hfRmo7hWIXPkbpi0ZltboCMVrU+0ClXR/JgbCKKjlDjQf6igXa7OwdqNcFWQZPZTgiY7ZpzE3+LjjkLiTN2T7Q==
- dependencies:
- bin-check "^4.1.0"
- bin-version-check "^4.0.0"
- download "^7.1.0"
- import-lazy "^3.1.0"
- os-filter-obj "^2.0.0"
- pify "^4.0.1"
-
-binary-extensions@^1.0.0:
- version "1.13.1"
- resolved "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz"
- integrity sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==
-
-binary-extensions@^2.0.0:
- version "2.1.0"
- resolved "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz"
- integrity sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==
-
-bindings@^1.5.0:
- version "1.5.0"
- resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df"
- integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==
- dependencies:
- file-uri-to-path "1.0.0"
-
-bl@^0.7.0:
- version "0.7.0"
- resolved "https://registry.npmjs.org/bl/-/bl-0.7.0.tgz"
- integrity sha1-P7BnBgKsKHjrdw3CA58YNr5irls=
- dependencies:
- readable-stream "~1.0.2"
-
-bl@^0.9.0:
- version "0.9.5"
- resolved "https://registry.npmjs.org/bl/-/bl-0.9.5.tgz"
- integrity sha1-wGt5evCF6gC8Unr8jvzxHeIjIFQ=
- dependencies:
- readable-stream "~1.0.26"
-
-bl@^1.0.0:
- version "1.2.2"
- resolved "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz"
- integrity sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==
- dependencies:
- readable-stream "^2.3.5"
- safe-buffer "^5.1.1"
-
-blob@0.0.5:
- version "0.0.5"
- resolved "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz"
- integrity sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig==
-
-bluebird@3.x.x, bluebird@^3.1.1, bluebird@^3.4.6, bluebird@^3.5.0, bluebird@^3.5.5:
- version "3.5.5"
- resolved "https://registry.npmjs.org/bluebird/-/bluebird-3.5.5.tgz"
- integrity sha512-5am6HnnfN+urzt4yfg7IgTbotDjIT/u8AJpEt0sIU9FtXfVeezXAPKswrG+xKUCOYAINpSdgZVDU6QFh+cuH3w==
-
-bmp-js@^0.1.0:
- version "0.1.0"
- resolved "https://registry.npmjs.org/bmp-js/-/bmp-js-0.1.0.tgz"
- integrity sha1-4Fpj95amwf8l9Hcex62twUjAcjM=
-
-bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.4.0:
- version "4.11.8"
- resolved "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz"
- integrity sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==
-
-body-parser@~1.8.0:
- version "1.8.4"
- resolved "https://registry.npmjs.org/body-parser/-/body-parser-1.8.4.tgz"
- integrity sha1-1JfgS8E7P5qL2McLsM3Bby4CiJg=
- dependencies:
- bytes "1.0.0"
- depd "0.4.5"
- iconv-lite "0.4.4"
- media-typer "0.3.0"
- on-finished "2.1.0"
- qs "2.2.4"
- raw-body "1.3.0"
- type-is "~1.5.1"
-
-boolbase@^1.0.0, boolbase@~1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz"
- integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24=
-
-boolean@^3.0.1:
- version "3.2.0"
- resolved "https://registry.yarnpkg.com/boolean/-/boolean-3.2.0.tgz#9e5294af4e98314494cbb17979fa54ca159f116b"
- integrity sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==
-
-brace-expansion@^1.0.0, brace-expansion@^1.1.7:
- version "1.1.11"
- resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz"
- integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==
- dependencies:
- balanced-match "^1.0.0"
- concat-map "0.0.1"
-
-braces@^2.3.1, braces@^2.3.2:
- version "2.3.2"
- resolved "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz"
- integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==
- dependencies:
- arr-flatten "^1.1.0"
- array-unique "^0.3.2"
- extend-shallow "^2.0.1"
- fill-range "^4.0.0"
- isobject "^3.0.1"
- repeat-element "^1.1.2"
- snapdragon "^0.8.1"
- snapdragon-node "^2.0.1"
- split-string "^3.0.2"
- to-regex "^3.0.1"
-
-braces@^3.0.1, braces@~3.0.2:
- version "3.0.2"
- resolved "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz"
- integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==
- dependencies:
- fill-range "^7.0.1"
-
-brorand@^1.0.1:
- version "1.1.0"
- resolved "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz"
- integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=
-
-browser-process-hrtime@^0.1.2:
- version "0.1.3"
- resolved "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-0.1.3.tgz"
- integrity sha512-bRFnI4NnjO6cnyLmOV/7PVoDEMJChlcfN0z4s1YMBY989/SvlfMI1lgCnkFUs53e9gQF+w7qu7XdllSTiSl8Aw==
-
-browser-sync-client@^2.26.10:
- version "2.26.10"
- resolved "https://registry.npmjs.org/browser-sync-client/-/browser-sync-client-2.26.10.tgz"
- integrity sha512-8pYitKwpVva7hzXJI8lTljNDbA9fjMEobHSxWqegIUon/GjJAG3UgHB/+lBWnOLzTY8rGX66MvGqL1Aknyrj7g==
- dependencies:
- etag "1.8.1"
- fresh "0.5.2"
- mitt "^1.1.3"
- rxjs "^5.5.6"
-
-browser-sync-ui@^2.26.10:
- version "2.26.10"
- resolved "https://registry.npmjs.org/browser-sync-ui/-/browser-sync-ui-2.26.10.tgz"
- integrity sha512-UfNSBItlXcmEvJ9RE4JooNtIsiIfHowp+7/52Jz4VFfQD4v78QK5/NV9DVrG41oMM3zLyhW4f/RliOb4ysStZg==
- dependencies:
- async-each-series "0.1.1"
- connect-history-api-fallback "^1"
- immutable "^3"
- server-destroy "1.0.1"
- socket.io-client "^2.0.4"
- stream-throttle "^0.1.3"
-
-browser-sync@^2.26.10:
- version "2.26.10"
- resolved "https://registry.npmjs.org/browser-sync/-/browser-sync-2.26.10.tgz"
- integrity sha512-JeVQP3CARvNA1DELj+ZGWj+/0pzE8+Omvq1WNgzaTXVdP3lNEbGxZbkjvLK7hHpQywjQ1sDJWlJQZT6V59XDTg==
- dependencies:
- browser-sync-client "^2.26.10"
- browser-sync-ui "^2.26.10"
- bs-recipes "1.3.4"
- bs-snippet-injector "^2.0.1"
- chokidar "^3.4.1"
- connect "3.6.6"
- connect-history-api-fallback "^1"
- dev-ip "^1.0.1"
- easy-extender "^2.3.4"
- eazy-logger "^3"
- etag "^1.8.1"
- fresh "^0.5.2"
- fs-extra "3.0.1"
- http-proxy "^1.18.1"
- immutable "^3"
- localtunnel "^2.0.0"
- micromatch "^4.0.2"
- opn "5.3.0"
- portscanner "2.1.1"
- qs "6.2.3"
- raw-body "^2.3.2"
- resp-modifier "6.0.2"
- rx "4.1.0"
- send "0.16.2"
- serve-index "1.9.1"
- serve-static "1.13.2"
- server-destroy "1.0.1"
- socket.io "2.1.1"
- ua-parser-js "^0.7.18"
- yargs "^15.4.1"
-
-browserify-aes@^1.0.0, browserify-aes@^1.0.4:
- version "1.2.0"
- resolved "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz"
- integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==
- dependencies:
- buffer-xor "^1.0.3"
- cipher-base "^1.0.0"
- create-hash "^1.1.0"
- evp_bytestokey "^1.0.3"
- inherits "^2.0.1"
- safe-buffer "^5.0.1"
-
-browserify-cipher@^1.0.0:
- version "1.0.1"
- resolved "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz"
- integrity sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==
- dependencies:
- browserify-aes "^1.0.4"
- browserify-des "^1.0.0"
- evp_bytestokey "^1.0.0"
-
-browserify-des@^1.0.0:
- version "1.0.2"
- resolved "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz"
- integrity sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==
- dependencies:
- cipher-base "^1.0.1"
- des.js "^1.0.0"
- inherits "^2.0.1"
- safe-buffer "^5.1.2"
-
-browserify-rsa@^4.0.0:
- version "4.0.1"
- resolved "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz"
- integrity sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=
- dependencies:
- bn.js "^4.1.0"
- randombytes "^2.0.1"
-
-browserify-sign@^4.0.0:
- version "4.0.4"
- resolved "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz"
- integrity sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=
- dependencies:
- bn.js "^4.1.1"
- browserify-rsa "^4.0.0"
- create-hash "^1.1.0"
- create-hmac "^1.1.2"
- elliptic "^6.0.0"
- inherits "^2.0.1"
- parse-asn1 "^5.0.0"
-
-browserify-zlib@^0.2.0:
- version "0.2.0"
- resolved "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz"
- integrity sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==
- dependencies:
- pako "~1.0.5"
-
-browserslist@^4.0.0, browserslist@^4.6.0, browserslist@^4.6.3, browserslist@^4.6.4, browserslist@^4.6.6:
- version "4.7.0"
- resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.7.0.tgz"
- integrity sha512-9rGNDtnj+HaahxiVV38Gn8n8Lr8REKsel68v1sPFfIGEK6uSXTY3h9acgiT1dZVtOOUtifo/Dn8daDQ5dUgVsA==
- dependencies:
- caniuse-lite "^1.0.30000989"
- electron-to-chromium "^1.3.247"
- node-releases "^1.1.29"
-
-bs-recipes@1.3.4:
- version "1.3.4"
- resolved "https://registry.npmjs.org/bs-recipes/-/bs-recipes-1.3.4.tgz"
- integrity sha1-DS1NSKcYyMBEdp/cT4lZLci2lYU=
-
-bs-snippet-injector@^2.0.1:
- version "2.0.1"
- resolved "https://registry.npmjs.org/bs-snippet-injector/-/bs-snippet-injector-2.0.1.tgz"
- integrity sha1-YbU5PxH1JVntEgaTEANDtu2wTdU=
-
-buffer-alloc-unsafe@^1.1.0:
- version "1.1.0"
- resolved "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz"
- integrity sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==
-
-buffer-alloc@^1.2.0:
- version "1.2.0"
- resolved "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz"
- integrity sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==
- dependencies:
- buffer-alloc-unsafe "^1.1.0"
- buffer-fill "^1.0.0"
-
-buffer-crc32@~0.2.1, buffer-crc32@~0.2.3:
- version "0.2.13"
- resolved "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz"
- integrity sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=
-
-buffer-equal@0.0.1:
- version "0.0.1"
- resolved "https://registry.npmjs.org/buffer-equal/-/buffer-equal-0.0.1.tgz"
- integrity sha1-kbx0sR6kBbyRa8aqkI+q+ltKrEs=
-
-buffer-equal@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.0.tgz"
- integrity sha1-WWFrSYME1Var1GaWayLu2j7KX74=
-
-buffer-fill@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz"
- integrity sha1-+PeLdniYiO858gXNY39o5wISKyw=
-
-buffer-from@^1.0.0:
- version "1.1.1"
- resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz"
- integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==
-
-buffer-xor@^1.0.3:
- version "1.0.3"
- resolved "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz"
- integrity sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=
-
-buffer@^4.3.0:
- version "4.9.1"
- resolved "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz"
- integrity sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=
- dependencies:
- base64-js "^1.0.2"
- ieee754 "^1.1.4"
- isarray "^1.0.0"
-
-buffer@^5.2.0, buffer@^5.2.1:
- version "5.4.3"
- resolved "https://registry.npmjs.org/buffer/-/buffer-5.4.3.tgz"
- integrity sha512-zvj65TkFeIt3i6aj5bIvJDzjjQQGs4o/sNoezg1F1kYap9Nu2jcUdpwzRSJTHMMzG0H7bZkn4rNQpImhuxWX2A==
- dependencies:
- base64-js "^1.0.2"
- ieee754 "^1.1.4"
-
-bufferstreams@^2.0.1:
- version "2.0.1"
- resolved "https://registry.npmjs.org/bufferstreams/-/bufferstreams-2.0.1.tgz"
- integrity sha512-ZswyIoBfFb3cVDsnZLLj2IDJ/0ppYdil/v2EGlZXvoefO689FokEmFEldhN5dV7R2QBxFneqTJOMIpfqhj+n0g==
- dependencies:
- readable-stream "^2.3.6"
-
-builtin-status-codes@^3.0.0:
- version "3.0.0"
- resolved "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz"
- integrity sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=
-
-bytes@1, bytes@1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/bytes/-/bytes-1.0.0.tgz"
- integrity sha1-NWnt6Lo0MV+rmcPpLLBMciDeH6g=
-
-bytes@3.1.0:
- version "3.1.0"
- resolved "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz"
- integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==
-
-cacache@^12.0.2:
- version "12.0.3"
- resolved "https://registry.npmjs.org/cacache/-/cacache-12.0.3.tgz"
- integrity sha512-kqdmfXEGFepesTuROHMs3MpFLWrPkSSpRqOw80RCflZXy/khxaArvFrQ7uJxSUduzAufc6G0g1VUCOZXxWavPw==
- dependencies:
- bluebird "^3.5.5"
- chownr "^1.1.1"
- figgy-pudding "^3.5.1"
- glob "^7.1.4"
- graceful-fs "^4.1.15"
- infer-owner "^1.0.3"
- lru-cache "^5.1.1"
- mississippi "^3.0.0"
- mkdirp "^0.5.1"
- move-concurrently "^1.0.1"
- promise-inflight "^1.0.1"
- rimraf "^2.6.3"
- ssri "^6.0.1"
- unique-filename "^1.1.1"
- y18n "^4.0.0"
-
-cache-base@^1.0.1:
- version "1.0.1"
- resolved "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz"
- integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==
- dependencies:
- collection-visit "^1.0.0"
- component-emitter "^1.2.1"
- get-value "^2.0.6"
- has-value "^1.0.0"
- isobject "^3.0.1"
- set-value "^2.0.0"
- to-object-path "^0.3.0"
- union-value "^1.0.0"
- unset-value "^1.0.0"
-
-cache-swap@^0.3.0:
- version "0.3.0"
- resolved "https://registry.npmjs.org/cache-swap/-/cache-swap-0.3.0.tgz"
- integrity sha1-HFQaoQilAQb2ML3Zj+HeyLoTP1E=
- dependencies:
- graceful-fs "^4.1.2"
- mkdirp "^0.5.1"
- object-assign "^4.0.1"
- rimraf "^2.4.0"
-
-cacheable-request@^2.1.1:
- version "2.1.4"
- resolved "https://registry.npmjs.org/cacheable-request/-/cacheable-request-2.1.4.tgz"
- integrity sha1-DYCIAbY0KtM8kd+dC0TcCbkeXD0=
- dependencies:
- clone-response "1.0.2"
- get-stream "3.0.0"
- http-cache-semantics "3.8.1"
- keyv "3.0.0"
- lowercase-keys "1.0.0"
- normalize-url "2.0.1"
- responselike "1.0.2"
-
-cacheable-request@^6.0.0:
- version "6.1.0"
- resolved "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz"
- integrity sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==
- dependencies:
- clone-response "^1.0.2"
- get-stream "^5.1.0"
- http-cache-semantics "^4.0.0"
- keyv "^3.0.0"
- lowercase-keys "^2.0.0"
- normalize-url "^4.1.0"
- responselike "^1.0.2"
-
-calipers-gif@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/calipers-gif/-/calipers-gif-2.0.0.tgz"
- integrity sha1-te7+wwZKd8bc29W9xRc1oBuv3Dc=
- dependencies:
- bluebird "3.x.x"
-
-calipers-jpeg@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/calipers-jpeg/-/calipers-jpeg-2.0.0.tgz"
- integrity sha1-BtVqU/YnF92AnLlWz2RCPOaTRls=
- dependencies:
- bluebird "3.x.x"
-
-calipers-png@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/calipers-png/-/calipers-png-2.0.0.tgz"
- integrity sha1-HQ0g5cGuX3m3TVKGoul/Wbtwtlg=
- dependencies:
- bluebird "3.x.x"
-
-calipers-svg@^2.0.0:
- version "2.0.1"
- resolved "https://registry.npmjs.org/calipers-svg/-/calipers-svg-2.0.1.tgz"
- integrity sha512-3PROqHARmj8wWudUC7DzXm1+mSocqgY7jNuehFNHgrUVrKf8o7MqDjS92vJz5LvZsAofJsoAFMajkqwbxBROSQ==
- dependencies:
- bluebird "3.x.x"
-
-calipers-webp@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/calipers-webp/-/calipers-webp-2.0.0.tgz"
- integrity sha1-4Sbs4vhM1xd5YSv6KyZTzZXOp3o=
- dependencies:
- bluebird "3.x.x"
-
-calipers@^2.0.0:
- version "2.0.1"
- resolved "https://registry.npmjs.org/calipers/-/calipers-2.0.1.tgz"
- integrity sha512-AP4Ui2Z8fZf69d8Dx4cfJgPjQHY3m+QXGFCaAGu8pfNQjyajkosS+Kkf1n6pQDMZcelN5h3MdcjweUqxcsS4pg==
- dependencies:
- bluebird "3.x.x"
-
-caller-callsite@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz"
- integrity sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=
- dependencies:
- callsites "^2.0.0"
-
-caller-path@^0.1.0:
- version "0.1.0"
- resolved "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz"
- integrity sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=
- dependencies:
- callsites "^0.2.0"
-
-caller-path@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz"
- integrity sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=
- dependencies:
- caller-callsite "^2.0.0"
-
-callsite@1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz"
- integrity sha1-KAOY5dZkvXQDi28JBRU+borxvCA=
-
-callsites@^0.2.0:
- version "0.2.0"
- resolved "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz"
- integrity sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=
-
-callsites@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz"
- integrity sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=
-
-callsites@^3.0.0:
- version "3.1.0"
- resolved "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz"
- integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==
-
-camel-case@3.0.x:
- version "3.0.0"
- resolved "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz"
- integrity sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M=
- dependencies:
- no-case "^2.2.0"
- upper-case "^1.1.1"
-
-camelcase-keys@^2.0.0:
- version "2.1.0"
- resolved "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz"
- integrity sha1-MIvur/3ygRkFHvodkyITyRuPkuc=
- dependencies:
- camelcase "^2.0.0"
- map-obj "^1.0.0"
-
-camelcase@^2.0.0:
- version "2.1.1"
- resolved "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz"
- integrity sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=
-
-camelcase@^3.0.0:
- version "3.0.0"
- resolved "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz"
- integrity sha1-MvxLn82vhF/N9+c7uXysImHwqwo=
-
-camelcase@^5.0.0:
- version "5.3.1"
- resolved "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz"
- integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==
-
-caniuse-api@^3.0.0:
- version "3.0.0"
- resolved "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz"
- integrity sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==
- dependencies:
- browserslist "^4.0.0"
- caniuse-lite "^1.0.0"
- lodash.memoize "^4.1.2"
- lodash.uniq "^4.5.0"
-
-caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000980, caniuse-lite@^1.0.30000981, caniuse-lite@^1.0.30000989:
- version "1.0.30000989"
- resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000989.tgz"
- integrity sha512-vrMcvSuMz16YY6GSVZ0dWDTJP8jqk3iFQ/Aq5iqblPwxSVVZI+zxDyTX0VPqtQsDnfdrBDcsmhgTEOh5R8Lbpw==
-
-caseless@~0.12.0:
- version "0.12.0"
- resolved "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz"
- integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=
-
-caw@^2.0.0, caw@^2.0.1:
- version "2.0.1"
- resolved "https://registry.npmjs.org/caw/-/caw-2.0.1.tgz"
- integrity sha512-Cg8/ZSBEa8ZVY9HspcGUYaK63d/bN7rqS3CYCzEGUxuYv6UlmcjzDUz2fCFFHyTvUW5Pk0I+3hkA3iXlIj6guA==
- dependencies:
- get-proxy "^2.0.0"
- isurl "^1.0.0-alpha5"
- tunnel-agent "^0.6.0"
- url-to-options "^1.0.1"
-
-chalk@2.4.2, chalk@^2.0.0, chalk@^2.1.0, chalk@^2.3.0, chalk@^2.4.1, chalk@^2.4.2:
- version "2.4.2"
- resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz"
- integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
- dependencies:
- ansi-styles "^3.2.1"
- escape-string-regexp "^1.0.5"
- supports-color "^5.3.0"
-
-chalk@^0.5.0:
- version "0.5.1"
- resolved "https://registry.npmjs.org/chalk/-/chalk-0.5.1.tgz"
- integrity sha1-Zjs6ZItotV0EaQ1JFnqoN4WPIXQ=
- dependencies:
- ansi-styles "^1.1.0"
- escape-string-regexp "^1.0.0"
- has-ansi "^0.1.0"
- strip-ansi "^0.3.0"
- supports-color "^0.2.0"
-
-chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3:
- version "1.1.3"
- resolved "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz"
- integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=
- dependencies:
- ansi-styles "^2.2.1"
- escape-string-regexp "^1.0.2"
- has-ansi "^2.0.0"
- strip-ansi "^3.0.0"
- supports-color "^2.0.0"
-
-chalk@^3.0.0:
- version "3.0.0"
- resolved "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz"
- integrity sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==
- dependencies:
- ansi-styles "^4.1.0"
- supports-color "^7.1.0"
-
-chardet@^0.7.0:
- version "0.7.0"
- resolved "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz"
- integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==
-
-"chokidar@>=2.0.0 <4.0.0", chokidar@^3.4.0, chokidar@^3.4.1:
- version "3.4.1"
- resolved "https://registry.npmjs.org/chokidar/-/chokidar-3.4.1.tgz"
- integrity sha512-TQTJyr2stihpC4Sya9hs2Xh+O2wf+igjL36Y75xx2WdHuiICcn/XJza46Jwt0eT5hVpQOzo3FpY3cj3RVYLX0g==
- dependencies:
- anymatch "~3.1.1"
- braces "~3.0.2"
- glob-parent "~5.1.0"
- is-binary-path "~2.1.0"
- is-glob "~4.0.1"
- normalize-path "~3.0.0"
- readdirp "~3.4.0"
- optionalDependencies:
- fsevents "~2.1.2"
-
-chokidar@^2.0.0, chokidar@^2.1.8:
- version "2.1.8"
- resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917"
- integrity sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==
- dependencies:
- anymatch "^2.0.0"
- async-each "^1.0.1"
- braces "^2.3.2"
- glob-parent "^3.1.0"
- inherits "^2.0.3"
- is-binary-path "^1.0.0"
- is-glob "^4.0.0"
- normalize-path "^3.0.0"
- path-is-absolute "^1.0.0"
- readdirp "^2.2.1"
- upath "^1.1.1"
- optionalDependencies:
- fsevents "^1.2.7"
-
-chownr@^1.1.1:
- version "1.1.2"
- resolved "https://registry.npmjs.org/chownr/-/chownr-1.1.2.tgz"
- integrity sha512-GkfeAQh+QNy3wquu9oIZr6SS5x7wGdSgNQvD10X3r+AZr1Oys22HW8kAmDMvNg2+Dm0TeGaEuO8gFwdBXxwO8A==
-
-chrome-trace-event@^1.0.2:
- version "1.0.2"
- resolved "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz"
- integrity sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==
- dependencies:
- tslib "^1.9.0"
-
-chromium-pickle-js@^0.2.0:
- version "0.2.0"
- resolved "https://registry.npmjs.org/chromium-pickle-js/-/chromium-pickle-js-0.2.0.tgz"
- integrity sha1-BKEGZywYsIWrd02YPfo+oTjyIgU=
-
-cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3:
- version "1.0.4"
- resolved "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz"
- integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==
- dependencies:
- inherits "^2.0.1"
- safe-buffer "^5.0.1"
-
-circular-dependency-plugin@^5.0.2:
- version "5.2.0"
- resolved "https://registry.npmjs.org/circular-dependency-plugin/-/circular-dependency-plugin-5.2.0.tgz"
- integrity sha512-7p4Kn/gffhQaavNfyDFg7LS5S/UT1JAjyGd4UqR2+jzoYF02eDkj0Ec3+48TsIa4zghjLY87nQHIh/ecK9qLdw==
-
-circular-json@^0.3.1:
- version "0.3.3"
- resolved "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz"
- integrity sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==
-
-circular-json@^0.5.9:
- version "0.5.9"
- resolved "https://registry.npmjs.org/circular-json/-/circular-json-0.5.9.tgz"
- integrity sha512-4ivwqHpIFJZBuhN3g/pEcdbnGUywkBblloGbkglyloVjjR3uT6tieI89MVOfbP2tHX5sgb01FuLgAOzebNlJNQ==
-
-class-utils@^0.3.5:
- version "0.3.6"
- resolved "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz"
- integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==
- dependencies:
- arr-union "^3.1.0"
- define-property "^0.2.5"
- isobject "^3.0.0"
- static-extend "^0.1.1"
-
-clean-css@4.2.x:
- version "4.2.1"
- resolved "https://registry.npmjs.org/clean-css/-/clean-css-4.2.1.tgz"
- integrity sha512-4ZxI6dy4lrY6FHzfiy1aEOXgu4LIsW2MhwG0VBKdcoGoH/XLFgaHSdLTGr4O8Be6A8r3MOphEiI8Gc1n0ecf3g==
- dependencies:
- source-map "~0.6.0"
-
-cli-cursor@^1.0.1:
- version "1.0.2"
- resolved "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz"
- integrity sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=
- dependencies:
- restore-cursor "^1.0.1"
-
-cli-cursor@^2.1.0:
- version "2.1.0"
- resolved "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz"
- integrity sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=
- dependencies:
- restore-cursor "^2.0.0"
-
-cli-width@^2.0.0:
- version "2.2.0"
- resolved "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz"
- integrity sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=
-
-clipboard-copy@^3.1.0:
- version "3.1.0"
- resolved "https://registry.npmjs.org/clipboard-copy/-/clipboard-copy-3.1.0.tgz"
- integrity sha512-Xsu1NddBXB89IUauda5BIq3Zq73UWkjkaQlPQbLNvNsd5WBMnTWPNKYR6HGaySOxGYZ+BKxP2E9X4ElnI3yiPA==
-
-cliui@^3.2.0:
- version "3.2.0"
- resolved "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz"
- integrity sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=
- dependencies:
- string-width "^1.0.1"
- strip-ansi "^3.0.1"
- wrap-ansi "^2.0.0"
-
-cliui@^5.0.0:
- version "5.0.0"
- resolved "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz"
- integrity sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==
- dependencies:
- string-width "^3.1.0"
- strip-ansi "^5.2.0"
- wrap-ansi "^5.1.0"
-
-cliui@^6.0.0:
- version "6.0.0"
- resolved "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz"
- integrity sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==
- dependencies:
- string-width "^4.2.0"
- strip-ansi "^6.0.0"
- wrap-ansi "^6.2.0"
-
-clone-buffer@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz"
- integrity sha1-4+JbIHrE5wGvch4staFnksrD3Fg=
-
-clone-response@1.0.2, clone-response@^1.0.2:
- version "1.0.2"
- resolved "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz"
- integrity sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=
- dependencies:
- mimic-response "^1.0.0"
-
-clone-stats@^0.0.1, clone-stats@~0.0.1:
- version "0.0.1"
- resolved "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz"
- integrity sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE=
-
-clone-stats@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz"
- integrity sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=
-
-clone@^0.2.0:
- version "0.2.0"
- resolved "https://registry.npmjs.org/clone/-/clone-0.2.0.tgz"
- integrity sha1-xhJqkK1Pctv1rNskPMN3JP6T/B8=
-
-clone@^1.0.0, clone@^1.0.2:
- version "1.0.4"
- resolved "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz"
- integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4=
-
-clone@^2.1.1:
- version "2.1.2"
- resolved "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz"
- integrity sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=
-
-cloneable-readable@^1.0.0:
- version "1.1.3"
- resolved "https://registry.npmjs.org/cloneable-readable/-/cloneable-readable-1.1.3.tgz"
- integrity sha512-2EF8zTQOxYq70Y4XKtorQupqF0m49MBz2/yf5Bj+MHjvpG3Hy7sImifnqD6UA+TKYxeSV+u6qqQPawN5UvnpKQ==
- dependencies:
- inherits "^2.0.1"
- process-nextick-args "^2.0.0"
- readable-stream "^2.3.5"
-
-co@^4.6.0:
- version "4.6.0"
- resolved "https://registry.npmjs.org/co/-/co-4.6.0.tgz"
- integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=
-
-coa@^2.0.2:
- version "2.0.2"
- resolved "https://registry.npmjs.org/coa/-/coa-2.0.2.tgz"
- integrity sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA==
- dependencies:
- "@types/q" "^1.5.1"
- chalk "^2.4.1"
- q "^1.1.2"
-
-code-point-at@^1.0.0:
- version "1.1.0"
- resolved "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz"
- integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=
-
-collection-map@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/collection-map/-/collection-map-1.0.0.tgz"
- integrity sha1-rqDwb40mx4DCt1SUOFVEsiVa8Yw=
- dependencies:
- arr-map "^2.0.2"
- for-own "^1.0.0"
- make-iterator "^1.0.0"
-
-collection-visit@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz"
- integrity sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=
- dependencies:
- map-visit "^1.0.0"
- object-visit "^1.0.0"
-
-color-convert@^1.9.0, color-convert@^1.9.1:
- version "1.9.3"
- resolved "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz"
- integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==
- dependencies:
- color-name "1.1.3"
-
-color-convert@^2.0.1:
- version "2.0.1"
- resolved "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz"
- integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==
- dependencies:
- color-name "~1.1.4"
-
-color-name@1.1.3, color-name@^1.0.0:
- version "1.1.3"
- resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz"
- integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=
-
-color-name@~1.1.4:
- version "1.1.4"
- resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz"
- integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
-
-color-string@^1.5.2:
- version "1.5.3"
- resolved "https://registry.npmjs.org/color-string/-/color-string-1.5.3.tgz"
- integrity sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw==
- dependencies:
- color-name "^1.0.0"
- simple-swizzle "^0.2.2"
-
-color-support@^1.1.3:
- version "1.1.3"
- resolved "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz"
- integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==
-
-color@^3.0.0:
- version "3.1.2"
- resolved "https://registry.npmjs.org/color/-/color-3.1.2.tgz"
- integrity sha512-vXTJhHebByxZn3lDvDJYw4lR5+uB3vuoHsuYA5AKuxRVn5wzzIfQKGLBmgdVRHKTJYeK5rvJcHnrd0Li49CFpg==
- dependencies:
- color-convert "^1.9.1"
- color-string "^1.5.2"
-
-colorette@^1.2.1:
- version "1.2.1"
- resolved "https://registry.npmjs.org/colorette/-/colorette-1.2.1.tgz"
- integrity sha512-puCDz0CzydiSYOrnXpz/PKd69zRrribezjtE9yd4zvytoRc8+RY/KJPvtPFKZS3E3wP6neGyMe0vOTlHO5L3Pw==
-
-colors@1.0.x:
- version "1.0.3"
- resolved "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz"
- integrity sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=
-
-colors@^1.3.3:
- version "1.3.3"
- resolved "https://registry.npmjs.org/colors/-/colors-1.3.3.tgz"
- integrity sha512-mmGt/1pZqYRjMxB1axhTo16/snVZ5krrKkcmMeVKxzECMMXoCgnvTPp10QgHfcbQZw8Dq2jMNG6je4JlWU0gWg==
-
-combined-stream@^1.0.6, combined-stream@~1.0.6:
- version "1.0.8"
- resolved "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz"
- integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==
- dependencies:
- delayed-stream "~1.0.0"
-
-commander@2.17.x:
- version "2.17.1"
- resolved "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz"
- integrity sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==
-
-commander@^2.19.0, commander@^2.2.0, commander@^2.20.0, commander@^2.8.1:
- version "2.20.0"
- resolved "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz"
- integrity sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==
-
-commander@^5.0.0:
- version "5.1.0"
- resolved "https://registry.yarnpkg.com/commander/-/commander-5.1.0.tgz#46abbd1652f8e059bddaef99bbdcb2ad9cf179ae"
- integrity sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==
-
-commander@~2.19.0:
- version "2.19.0"
- resolved "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz"
- integrity sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==
-
-commander@~2.8.1:
- version "2.8.1"
- resolved "https://registry.npmjs.org/commander/-/commander-2.8.1.tgz"
- integrity sha1-Br42f+v9oMMwqh4qBy09yXYkJdQ=
- dependencies:
- graceful-readlink ">= 1.0.0"
-
-commondir@^1.0.1:
- version "1.0.1"
- resolved "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz"
- integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=
-
-compare-version@^0.1.2:
- version "0.1.2"
- resolved "https://registry.npmjs.org/compare-version/-/compare-version-0.1.2.tgz"
- integrity sha1-AWLsLZNR9d3VmpICy6k1NmpyUIA=
-
-component-bind@1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz"
- integrity sha1-AMYIq33Nk4l8AAllGx06jh5zu9E=
-
-component-emitter@1.2.1, component-emitter@^1.2.1:
- version "1.2.1"
- resolved "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz"
- integrity sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=
-
-component-inherit@0.0.3:
- version "0.0.3"
- resolved "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz"
- integrity sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM=
-
-compress-commons@~0.1.0:
- version "0.1.6"
- resolved "https://registry.npmjs.org/compress-commons/-/compress-commons-0.1.6.tgz"
- integrity sha1-DHQIcP3ljLpRbwrAyCLjOguF36M=
- dependencies:
- buffer-crc32 "~0.2.1"
- crc32-stream "~0.3.1"
- readable-stream "~1.0.26"
-
-concat-map@0.0.1:
- version "0.0.1"
- resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz"
- integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
-
-concat-stream@^1.4.6, concat-stream@^1.5.0, concat-stream@^1.6.0:
- version "1.6.2"
- resolved "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz"
- integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==
- dependencies:
- buffer-from "^1.0.0"
- inherits "^2.0.3"
- readable-stream "^2.2.2"
- typedarray "^0.0.6"
-
-concat-stream@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz"
- integrity sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==
- dependencies:
- buffer-from "^1.0.0"
- inherits "^2.0.3"
- readable-stream "^3.0.2"
- typedarray "^0.0.6"
-
-config-chain@^1.1.11, config-chain@^1.1.12:
- version "1.1.12"
- resolved "https://registry.npmjs.org/config-chain/-/config-chain-1.1.12.tgz"
- integrity sha512-a1eOIcu8+7lUInge4Rpf/n4Krkf3Dd9lqhljRzII1/Zno/kRtUWnznPO3jOKBmTEktkt3fkxisUcivoj0ebzoA==
- dependencies:
- ini "^1.3.4"
- proto-list "~1.2.1"
-
-connect-history-api-fallback@^1:
- version "1.6.0"
- resolved "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz"
- integrity sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==
-
-connect-livereload@^0.4.0:
- version "0.4.1"
- resolved "https://registry.npmjs.org/connect-livereload/-/connect-livereload-0.4.1.tgz"
- integrity sha1-D4oagWvJuv+uRjfM6pF0Yv41kXo=
-
-connect@3.6.6, connect@^3.0.1:
- version "3.6.6"
- resolved "https://registry.npmjs.org/connect/-/connect-3.6.6.tgz"
- integrity sha1-Ce/2xVr3I24TcTWnJXSFi2eG9SQ=
- dependencies:
- debug "2.6.9"
- finalhandler "1.1.0"
- parseurl "~1.3.2"
- utils-merge "1.0.1"
-
-console-browserify@^1.1.0:
- version "1.1.0"
- resolved "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz"
- integrity sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=
- dependencies:
- date-now "^0.1.4"
-
-console-stream@^0.1.1:
- version "0.1.1"
- resolved "https://registry.npmjs.org/console-stream/-/console-stream-0.1.1.tgz"
- integrity sha1-oJX+B7IEZZVfL6/Si11yvM2UnUQ=
-
-constants-browserify@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz"
- integrity sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=
-
-content-disposition@^0.5.2:
- version "0.5.3"
- resolved "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz"
- integrity sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==
- dependencies:
- safe-buffer "5.1.2"
-
-convert-source-map@^1.5.0, convert-source-map@^1.5.1, convert-source-map@^1.7.0:
- version "1.7.0"
- resolved "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz"
- integrity sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==
- dependencies:
- safe-buffer "~5.1.1"
-
-cookie@0.3.1:
- version "0.3.1"
- resolved "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz"
- integrity sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=
-
-copy-concurrently@^1.0.0:
- version "1.0.5"
- resolved "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz"
- integrity sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==
- dependencies:
- aproba "^1.1.1"
- fs-write-stream-atomic "^1.0.8"
- iferr "^0.1.5"
- mkdirp "^0.5.1"
- rimraf "^2.5.4"
- run-queue "^1.0.0"
-
-copy-descriptor@^0.1.0:
- version "0.1.1"
- resolved "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz"
- integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=
-
-copy-props@^2.0.1:
- version "2.0.4"
- resolved "https://registry.npmjs.org/copy-props/-/copy-props-2.0.4.tgz"
- integrity sha512-7cjuUME+p+S3HZlbllgsn2CDwS+5eCCX16qBgNC4jgSTf49qR1VKy/Zhl400m0IQXl/bPGEVqncgUUMjrr4s8A==
- dependencies:
- each-props "^1.3.0"
- is-plain-object "^2.0.1"
-
-core-js-compat@^3.1.1:
- version "3.2.1"
- resolved "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.2.1.tgz"
- integrity sha512-MwPZle5CF9dEaMYdDeWm73ao/IflDH+FjeJCWEADcEgFSE9TLimFKwJsfmkwzI8eC0Aj0mgvMDjeQjrElkz4/A==
- dependencies:
- browserslist "^4.6.6"
- semver "^6.3.0"
-
-core-js@3:
- version "3.2.1"
- resolved "https://registry.npmjs.org/core-js/-/core-js-3.2.1.tgz"
- integrity sha512-Qa5XSVefSVPRxy2XfUC13WbvqkxhkwB3ve+pgCQveNgYzbM/UxZeu1dcOX/xr4UmfUd+muuvsaxilQzCyUurMw==
-
-core-js@^2.4.0, core-js@^2.5.7:
- version "2.6.9"
- resolved "https://registry.npmjs.org/core-js/-/core-js-2.6.9.tgz"
- integrity sha512-HOpZf6eXmnl7la+cUdMnLvUxKNqLUzJvgIziQ0DiF3JwSImNphIqdGqzj6hIKyX04MmV0poclQ7+wjWvxQyR2A==
-
-core-js@^2.5.0:
- version "2.6.11"
- resolved "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz"
- integrity sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==
-
-core-util-is@1.0.2, core-util-is@~1.0.0:
- version "1.0.2"
- resolved "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz"
- integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=
-
-cosmiconfig@^5.0.0:
- version "5.2.1"
- resolved "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz"
- integrity sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==
- dependencies:
- import-fresh "^2.0.0"
- is-directory "^0.3.1"
- js-yaml "^3.13.1"
- parse-json "^4.0.0"
-
-crc32-stream@~0.3.1:
- version "0.3.4"
- resolved "https://registry.npmjs.org/crc32-stream/-/crc32-stream-0.3.4.tgz"
- integrity sha1-c7wltF+sHbZjIjGnv86JJ+nwZVI=
- dependencies:
- buffer-crc32 "~0.2.1"
- readable-stream "~1.0.24"
-
-create-ecdh@^4.0.0:
- version "4.0.3"
- resolved "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz"
- integrity sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==
- dependencies:
- bn.js "^4.1.0"
- elliptic "^6.0.0"
-
-create-hash@^1.1.0, create-hash@^1.1.2:
- version "1.2.0"
- resolved "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz"
- integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==
- dependencies:
- cipher-base "^1.0.1"
- inherits "^2.0.1"
- md5.js "^1.3.4"
- ripemd160 "^2.0.1"
- sha.js "^2.4.0"
-
-create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4:
- version "1.1.7"
- resolved "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz"
- integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==
- dependencies:
- cipher-base "^1.0.3"
- create-hash "^1.1.0"
- inherits "^2.0.1"
- ripemd160 "^2.0.0"
- safe-buffer "^5.0.1"
- sha.js "^2.4.8"
-
-cross-spawn-windows-exe@^1.1.0, cross-spawn-windows-exe@^1.2.0:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/cross-spawn-windows-exe/-/cross-spawn-windows-exe-1.2.0.tgz#46253b0f497676e766faf4a7061004618b5ac5ec"
- integrity sha512-mkLtJJcYbDCxEG7Js6eUnUNndWjyUZwJ3H7bErmmtOYU/Zb99DyUkpamuIZE0b3bhmJyZ7D90uS6f+CGxRRjOw==
- dependencies:
- "@malept/cross-spawn-promise" "^1.1.0"
- is-wsl "^2.2.0"
- which "^2.0.2"
-
-cross-spawn@6.0.5, cross-spawn@^6.0.0, cross-spawn@^6.0.5:
- version "6.0.5"
- resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz"
- integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==
- dependencies:
- nice-try "^1.0.4"
- path-key "^2.0.1"
- semver "^5.5.0"
- shebang-command "^1.2.0"
- which "^1.2.9"
-
-cross-spawn@^5.0.1:
- version "5.1.0"
- resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz"
- integrity sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=
- dependencies:
- lru-cache "^4.0.1"
- shebang-command "^1.2.0"
- which "^1.2.9"
-
-cross-spawn@^7.0.0, cross-spawn@^7.0.1, cross-spawn@^7.0.3:
- version "7.0.3"
- resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz"
- integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==
- dependencies:
- path-key "^3.1.0"
- shebang-command "^2.0.0"
- which "^2.0.1"
-
-crypto-browserify@^3.11.0:
- version "3.12.0"
- resolved "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz"
- integrity sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==
- dependencies:
- browserify-cipher "^1.0.0"
- browserify-sign "^4.0.0"
- create-ecdh "^4.0.0"
- create-hash "^1.1.0"
- create-hmac "^1.1.0"
- diffie-hellman "^5.0.0"
- inherits "^2.0.1"
- pbkdf2 "^3.0.3"
- public-encrypt "^4.0.0"
- randombytes "^2.0.0"
- randomfill "^1.0.3"
-
-crypto@^1.0.1:
- version "1.0.1"
- resolved "https://registry.npmjs.org/crypto/-/crypto-1.0.1.tgz"
- integrity sha512-VxBKmeNcqQdiUQUW2Tzq0t377b54N2bMtXO/qiLa+6eRRmmC4qT3D4OnTGoT/U6O9aklQ/jTwbOtRMTTY8G0Ig==
-
-css-blank-pseudo@^0.1.4:
- version "0.1.4"
- resolved "https://registry.npmjs.org/css-blank-pseudo/-/css-blank-pseudo-0.1.4.tgz"
- integrity sha512-LHz35Hr83dnFeipc7oqFDmsjHdljj3TQtxGGiNWSOsTLIAubSm4TEz8qCaKFpk7idaQ1GfWscF4E6mgpBysA1w==
- dependencies:
- postcss "^7.0.5"
-
-css-color-names@0.0.4, css-color-names@^0.0.4:
- version "0.0.4"
- resolved "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz"
- integrity sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=
-
-css-declaration-sorter@^4.0.1:
- version "4.0.1"
- resolved "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-4.0.1.tgz"
- integrity sha512-BcxQSKTSEEQUftYpBVnsH4SF05NTuBokb19/sBt6asXGKZ/6VP7PLG1CBCkFDYOnhXhPh0jMhO6xZ71oYHXHBA==
- dependencies:
- postcss "^7.0.1"
- timsort "^0.3.0"
-
-css-has-pseudo@^0.10.0:
- version "0.10.0"
- resolved "https://registry.npmjs.org/css-has-pseudo/-/css-has-pseudo-0.10.0.tgz"
- integrity sha512-Z8hnfsZu4o/kt+AuFzeGpLVhFOGO9mluyHBaA2bA8aCGTwah5sT3WV/fTHH8UNZUytOIImuGPrl/prlb4oX4qQ==
- dependencies:
- postcss "^7.0.6"
- postcss-selector-parser "^5.0.0-rc.4"
-
-css-loader@^0.9.1:
- version "0.9.1"
- resolved "https://registry.npmjs.org/css-loader/-/css-loader-0.9.1.tgz"
- integrity sha1-LhqgDOfjDvLGp6SzAKCAp8l54Nw=
- dependencies:
- csso "1.3.x"
- loader-utils "~0.2.2"
- source-map "~0.1.38"
-
-css-mqpacker@^7.0.0:
- version "7.0.0"
- resolved "https://registry.npmjs.org/css-mqpacker/-/css-mqpacker-7.0.0.tgz"
- integrity sha512-temVrWS+sB4uocE2quhW8ru/KguDmGhCU7zN213KxtDvWOH3WS/ZUStfpF4fdCT7W8fPpFrQdWRFqtFtPPfBLA==
- dependencies:
- minimist "^1.2.0"
- postcss "^7.0.0"
-
-css-prefers-color-scheme@^3.1.1:
- version "3.1.1"
- resolved "https://registry.npmjs.org/css-prefers-color-scheme/-/css-prefers-color-scheme-3.1.1.tgz"
- integrity sha512-MTu6+tMs9S3EUqzmqLXEcgNRbNkkD/TGFvowpeoWJn5Vfq7FMgsmRQs9X5NXAURiOBmOxm/lLjsDNXDE6k9bhg==
- dependencies:
- postcss "^7.0.5"
-
-css-select-base-adapter@^0.1.1:
- version "0.1.1"
- resolved "https://registry.npmjs.org/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz"
- integrity sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==
-
-css-select@^2.0.0:
- version "2.0.2"
- resolved "https://registry.npmjs.org/css-select/-/css-select-2.0.2.tgz"
- integrity sha512-dSpYaDVoWaELjvZ3mS6IKZM/y2PMPa/XYoEfYNZePL4U/XgyxZNroHEHReDx/d+VgXh9VbCTtFqLkFbmeqeaRQ==
- dependencies:
- boolbase "^1.0.0"
- css-what "^2.1.2"
- domutils "^1.7.0"
- nth-check "^1.0.2"
-
-css-tree@1.0.0-alpha.29:
- version "1.0.0-alpha.29"
- resolved "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.29.tgz"
- integrity sha512-sRNb1XydwkW9IOci6iB2xmy8IGCj6r/fr+JWitvJ2JxQRPzN3T4AGGVWCMlVmVwM1gtgALJRmGIlWv5ppnGGkg==
- dependencies:
- mdn-data "~1.1.0"
- source-map "^0.5.3"
-
-css-tree@1.0.0-alpha.33:
- version "1.0.0-alpha.33"
- resolved "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.33.tgz"
- integrity sha512-SPt57bh5nQnpsTBsx/IXbO14sRc9xXu5MtMAVuo0BaQQmyf0NupNPPSoMaqiAF5tDFafYsTkfeH4Q/HCKXkg4w==
- dependencies:
- mdn-data "2.0.4"
- source-map "^0.5.3"
-
-css-unit-converter@^1.1.1:
- version "1.1.1"
- resolved "https://registry.npmjs.org/css-unit-converter/-/css-unit-converter-1.1.1.tgz"
- integrity sha1-2bkoGtz9jO2TW9urqDeGiX9k6ZY=
-
-css-what@^2.1.2:
- version "2.1.3"
- resolved "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz"
- integrity sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==
-
-cssdb@^4.4.0:
- version "4.4.0"
- resolved "https://registry.npmjs.org/cssdb/-/cssdb-4.4.0.tgz"
- integrity sha512-LsTAR1JPEM9TpGhl/0p3nQecC2LJ0kD8X5YARu1hk/9I1gril5vDtMZyNxcEpxxDj34YNck/ucjuoUd66K03oQ==
-
-cssesc@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/cssesc/-/cssesc-2.0.0.tgz"
- integrity sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg==
-
-cssnano-preset-advanced@^4.0.7:
- version "4.0.7"
- resolved "https://registry.npmjs.org/cssnano-preset-advanced/-/cssnano-preset-advanced-4.0.7.tgz"
- integrity sha512-j1O5/DQnaAqEyFFQfC+Z/vRlLXL3LxJHN+lvsfYqr7KgPH74t69+Rsy2yXkovWNaJjZYBpdz2Fj8ab2nH7pZXw==
- dependencies:
- autoprefixer "^9.4.7"
- cssnano-preset-default "^4.0.7"
- postcss-discard-unused "^4.0.1"
- postcss-merge-idents "^4.0.1"
- postcss-reduce-idents "^4.0.2"
- postcss-zindex "^4.0.1"
-
-cssnano-preset-default@^4.0.7:
- version "4.0.7"
- resolved "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-4.0.7.tgz"
- integrity sha512-x0YHHx2h6p0fCl1zY9L9roD7rnlltugGu7zXSKQx6k2rYw0Hi3IqxcoAGF7u9Q5w1nt7vK0ulxV8Lo+EvllGsA==
- dependencies:
- css-declaration-sorter "^4.0.1"
- cssnano-util-raw-cache "^4.0.1"
- postcss "^7.0.0"
- postcss-calc "^7.0.1"
- postcss-colormin "^4.0.3"
- postcss-convert-values "^4.0.1"
- postcss-discard-comments "^4.0.2"
- postcss-discard-duplicates "^4.0.2"
- postcss-discard-empty "^4.0.1"
- postcss-discard-overridden "^4.0.1"
- postcss-merge-longhand "^4.0.11"
- postcss-merge-rules "^4.0.3"
- postcss-minify-font-values "^4.0.2"
- postcss-minify-gradients "^4.0.2"
- postcss-minify-params "^4.0.2"
- postcss-minify-selectors "^4.0.2"
- postcss-normalize-charset "^4.0.1"
- postcss-normalize-display-values "^4.0.2"
- postcss-normalize-positions "^4.0.2"
- postcss-normalize-repeat-style "^4.0.2"
- postcss-normalize-string "^4.0.2"
- postcss-normalize-timing-functions "^4.0.2"
- postcss-normalize-unicode "^4.0.1"
- postcss-normalize-url "^4.0.1"
- postcss-normalize-whitespace "^4.0.2"
- postcss-ordered-values "^4.1.2"
- postcss-reduce-initial "^4.0.3"
- postcss-reduce-transforms "^4.0.2"
- postcss-svgo "^4.0.2"
- postcss-unique-selectors "^4.0.1"
-
-cssnano-util-get-arguments@^4.0.0:
- version "4.0.0"
- resolved "https://registry.npmjs.org/cssnano-util-get-arguments/-/cssnano-util-get-arguments-4.0.0.tgz"
- integrity sha1-7ToIKZ8h11dBsg87gfGU7UnMFQ8=
-
-cssnano-util-get-match@^4.0.0:
- version "4.0.0"
- resolved "https://registry.npmjs.org/cssnano-util-get-match/-/cssnano-util-get-match-4.0.0.tgz"
- integrity sha1-wOTKB/U4a7F+xeUiULT1lhNlFW0=
-
-cssnano-util-raw-cache@^4.0.1:
- version "4.0.1"
- resolved "https://registry.npmjs.org/cssnano-util-raw-cache/-/cssnano-util-raw-cache-4.0.1.tgz"
- integrity sha512-qLuYtWK2b2Dy55I8ZX3ky1Z16WYsx544Q0UWViebptpwn/xDBmog2TLg4f+DBMg1rJ6JDWtn96WHbOKDWt1WQA==
- dependencies:
- postcss "^7.0.0"
-
-cssnano-util-same-parent@^4.0.0:
- version "4.0.1"
- resolved "https://registry.npmjs.org/cssnano-util-same-parent/-/cssnano-util-same-parent-4.0.1.tgz"
- integrity sha512-WcKx5OY+KoSIAxBW6UBBRay1U6vkYheCdjyVNDm85zt5K9mHoGOfsOsqIszfAqrQQFIIKgjh2+FDgIj/zsl21Q==
-
-cssnano@^4.1.10:
- version "4.1.10"
- resolved "https://registry.npmjs.org/cssnano/-/cssnano-4.1.10.tgz"
- integrity sha512-5wny+F6H4/8RgNlaqab4ktc3e0/blKutmq8yNlBFXA//nSFFAqAngjNVRzUvCgYROULmZZUoosL/KSoZo5aUaQ==
- dependencies:
- cosmiconfig "^5.0.0"
- cssnano-preset-default "^4.0.7"
- is-resolvable "^1.0.0"
- postcss "^7.0.0"
-
-csso@1.3.x:
- version "1.3.12"
- resolved "https://registry.npmjs.org/csso/-/csso-1.3.12.tgz"
- integrity sha1-/GKGlKLTiTiqrEmWdTIY/TEc254=
-
-csso@^3.5.1:
- version "3.5.1"
- resolved "https://registry.npmjs.org/csso/-/csso-3.5.1.tgz"
- integrity sha512-vrqULLffYU1Q2tLdJvaCYbONStnfkfimRxXNaGjxMldI0C7JPBC4rB1RyjhfdZ4m1frm8pM9uRPKH3d2knZ8gg==
- dependencies:
- css-tree "1.0.0-alpha.29"
-
-cssom@0.3.x, cssom@^0.3.4:
- version "0.3.8"
- resolved "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz"
- integrity sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==
-
-cssstyle@^1.1.1:
- version "1.4.0"
- resolved "https://registry.npmjs.org/cssstyle/-/cssstyle-1.4.0.tgz"
- integrity sha512-GBrLZYZ4X4x6/QEoBnIrqb8B/f5l4+8me2dkom/j1Gtbxy0kBv6OGzKuAsGM75bkGwGAFkt56Iwg28S3XTZgSA==
- dependencies:
- cssom "0.3.x"
-
-currently-unhandled@^0.4.1:
- version "0.4.1"
- resolved "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz"
- integrity sha1-mI3zP+qxke95mmE2nddsF635V+o=
- dependencies:
- array-find-index "^1.0.1"
-
-cycle@1.0.x:
- version "1.0.3"
- resolved "https://registry.npmjs.org/cycle/-/cycle-1.0.3.tgz"
- integrity sha1-IegLK+hYD5i0aPN5QwZisEbDStI=
-
-cyclist@^1.0.1:
- version "1.0.1"
- resolved "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz"
- integrity sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=
-
-d@1, d@^1.0.1:
- version "1.0.1"
- resolved "https://registry.npmjs.org/d/-/d-1.0.1.tgz"
- integrity sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==
- dependencies:
- es5-ext "^0.10.50"
- type "^1.0.1"
-
-dashdash@^1.12.0:
- version "1.14.1"
- resolved "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz"
- integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=
- dependencies:
- assert-plus "^1.0.0"
-
-data-urls@^1.0.1:
- version "1.1.0"
- resolved "https://registry.npmjs.org/data-urls/-/data-urls-1.1.0.tgz"
- integrity sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ==
- dependencies:
- abab "^2.0.0"
- whatwg-mimetype "^2.2.0"
- whatwg-url "^7.0.0"
-
-date-now@^0.1.4:
- version "0.1.4"
- resolved "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz"
- integrity sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=
-
-dateformat@^1.0.7-1.2.3:
- version "1.0.12"
- resolved "https://registry.npmjs.org/dateformat/-/dateformat-1.0.12.tgz"
- integrity sha1-nxJLZ1lMk3/3BpMuSmQsyo27/uk=
- dependencies:
- get-stdin "^4.0.1"
- meow "^3.3.0"
-
-dateformat@^2.0.0:
- version "2.2.0"
- resolved "https://registry.npmjs.org/dateformat/-/dateformat-2.2.0.tgz"
- integrity sha1-QGXiATz5+5Ft39gu+1Bq1MZ2kGI=
-
-debug@2.6.9, debug@^2.1.1, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9:
- version "2.6.9"
- resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz"
- integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==
- dependencies:
- ms "2.0.0"
-
-debug@4.1.1, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@~4.1.0:
- version "4.1.1"
- resolved "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz"
- integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==
- dependencies:
- ms "^2.1.1"
-
-debug@=3.1.0, debug@~3.1.0:
- version "3.1.0"
- resolved "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz"
- integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==
- dependencies:
- ms "2.0.0"
-
-debug@^3.1.0, debug@^3.2.6:
- version "3.2.6"
- resolved "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz"
- integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==
- dependencies:
- ms "^2.1.1"
-
-debug@^4.3.4:
- version "4.3.4"
- resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865"
- integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==
- dependencies:
- ms "2.1.2"
-
-debug@~0.8.1:
- version "0.8.1"
- resolved "https://registry.npmjs.org/debug/-/debug-0.8.1.tgz"
- integrity sha1-IP9NJvXkIstoobrLu2EDmtjBwTA=
-
-decamelize@^1.1.1, decamelize@^1.1.2, decamelize@^1.2.0:
- version "1.2.0"
- resolved "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz"
- integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=
-
-decode-uri-component@^0.2.0:
- version "0.2.0"
- resolved "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz"
- integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=
-
-decompress-response@^3.2.0, decompress-response@^3.3.0:
- version "3.3.0"
- resolved "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz"
- integrity sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=
- dependencies:
- mimic-response "^1.0.0"
-
-decompress-tar@^4.0.0, decompress-tar@^4.1.0, decompress-tar@^4.1.1:
- version "4.1.1"
- resolved "https://registry.npmjs.org/decompress-tar/-/decompress-tar-4.1.1.tgz"
- integrity sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ==
- dependencies:
- file-type "^5.2.0"
- is-stream "^1.1.0"
- tar-stream "^1.5.2"
-
-decompress-tarbz2@^4.0.0:
- version "4.1.1"
- resolved "https://registry.npmjs.org/decompress-tarbz2/-/decompress-tarbz2-4.1.1.tgz"
- integrity sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A==
- dependencies:
- decompress-tar "^4.1.0"
- file-type "^6.1.0"
- is-stream "^1.1.0"
- seek-bzip "^1.0.5"
- unbzip2-stream "^1.0.9"
-
-decompress-targz@^4.0.0:
- version "4.1.1"
- resolved "https://registry.npmjs.org/decompress-targz/-/decompress-targz-4.1.1.tgz"
- integrity sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w==
- dependencies:
- decompress-tar "^4.1.1"
- file-type "^5.2.0"
- is-stream "^1.1.0"
-
-decompress-unzip@^4.0.1:
- version "4.0.1"
- resolved "https://registry.npmjs.org/decompress-unzip/-/decompress-unzip-4.0.1.tgz"
- integrity sha1-3qrM39FK6vhVePczroIQ+bSEj2k=
- dependencies:
- file-type "^3.8.0"
- get-stream "^2.2.0"
- pify "^2.3.0"
- yauzl "^2.4.2"
-
-decompress@^4.0.0, decompress@^4.2.0:
- version "4.2.0"
- resolved "https://registry.npmjs.org/decompress/-/decompress-4.2.0.tgz"
- integrity sha1-eu3YVCflqS2s/lVnSnxQXpbQH50=
- dependencies:
- decompress-tar "^4.0.0"
- decompress-tarbz2 "^4.0.0"
- decompress-targz "^4.0.0"
- decompress-unzip "^4.0.1"
- graceful-fs "^4.1.10"
- make-dir "^1.0.0"
- pify "^2.3.0"
- strip-dirs "^2.0.0"
-
-deep-is@~0.1.3:
- version "0.1.3"
- resolved "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz"
- integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=
-
-deep-scope-analyser@^1.7.0:
- version "1.7.0"
- resolved "https://registry.npmjs.org/deep-scope-analyser/-/deep-scope-analyser-1.7.0.tgz"
- integrity sha512-rl5Dmt2IZkFpZo6XbEY1zG8st2Wpq8Pi/dV2gz8ZF6BDYt3fnor2JNxHwdO1WLo0k6JbmYp0x8MNy8kE4l1NtA==
- dependencies:
- esrecurse "^4.2.1"
- estraverse "^4.2.0"
-
-default-compare@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/default-compare/-/default-compare-1.0.0.tgz"
- integrity sha512-QWfXlM0EkAbqOCbD/6HjdwT19j7WCkMyiRhWilc4H9/5h/RzTF9gv5LYh1+CmDV5d1rki6KAWLtQale0xt20eQ==
- dependencies:
- kind-of "^5.0.2"
-
-default-resolution@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/default-resolution/-/default-resolution-2.0.0.tgz"
- integrity sha1-vLgrqnKtebQmp2cy8aga1t8m1oQ=
-
-defaults@^1.0.0:
- version "1.0.3"
- resolved "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz"
- integrity sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=
- dependencies:
- clone "^1.0.2"
-
-defer-to-connect@^1.0.1:
- version "1.0.2"
- resolved "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.0.2.tgz"
- integrity sha512-k09hcQcTDY+cwgiwa6PYKLm3jlagNzQ+RSvhjzESOGOx+MNOuXkxTfEvPrO1IOQ81tArCFYQgi631clB70RpQw==
-
-define-properties@^1.1.2, define-properties@^1.1.3:
- version "1.1.3"
- resolved "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz"
- integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==
- dependencies:
- object-keys "^1.0.12"
-
-define-property@^0.2.5:
- version "0.2.5"
- resolved "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz"
- integrity sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=
- dependencies:
- is-descriptor "^0.1.0"
-
-define-property@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz"
- integrity sha1-dp66rz9KY6rTr56NMEybvnm/sOY=
- dependencies:
- is-descriptor "^1.0.0"
-
-define-property@^2.0.2:
- version "2.0.2"
- resolved "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz"
- integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==
- dependencies:
- is-descriptor "^1.0.2"
- isobject "^3.0.1"
-
-delayed-stream@~1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz"
- integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk=
-
-delete-empty@^3.0.0:
- version "3.0.0"
- resolved "https://registry.npmjs.org/delete-empty/-/delete-empty-3.0.0.tgz"
- integrity sha512-ZUyiwo76W+DYnKsL3Kim6M/UOavPdBJgDYWOmuQhYaZvJH0AXAHbUNyEDtRbBra8wqqr686+63/0azfEk1ebUQ==
- dependencies:
- ansi-colors "^4.1.0"
- minimist "^1.2.0"
- path-starts-with "^2.0.0"
- rimraf "^2.6.2"
-
-depd@0.4.5:
- version "0.4.5"
- resolved "https://registry.npmjs.org/depd/-/depd-0.4.5.tgz"
- integrity sha1-GmZLUziLSmVz6K5ntfdnxpPKl/E=
-
-depd@~1.1.2:
- version "1.1.2"
- resolved "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz"
- integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=
-
-deprecated@^0.0.1:
- version "0.0.1"
- resolved "https://registry.npmjs.org/deprecated/-/deprecated-0.0.1.tgz"
- integrity sha1-+cmvVGSvoeepcUWKi97yqpTVuxk=
-
-des.js@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz"
- integrity sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=
- dependencies:
- inherits "^2.0.1"
- minimalistic-assert "^1.0.0"
-
-destroy@~1.0.4:
- version "1.0.4"
- resolved "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz"
- integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=
-
-detect-file@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz"
- integrity sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=
-
-detect-indent@^4.0.0:
- version "4.0.0"
- resolved "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz"
- integrity sha1-920GQ1LN9Docts5hnE7jqUdd4gg=
- dependencies:
- repeating "^2.0.0"
-
-detect-node@^2.0.4:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.1.0.tgz#c9c70775a49c3d03bc2c06d9a73be550f978f8b1"
- integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==
-
-dev-ip@^1.0.1:
- version "1.0.1"
- resolved "https://registry.npmjs.org/dev-ip/-/dev-ip-1.0.1.tgz"
- integrity sha1-p2o+0YVb56ASu4rBbLgPPADcKPA=
-
-diffie-hellman@^5.0.0:
- version "5.0.3"
- resolved "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz"
- integrity sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==
- dependencies:
- bn.js "^4.1.0"
- miller-rabin "^4.0.0"
- randombytes "^2.0.0"
-
-dir-glob@^3.0.1:
- version "3.0.1"
- resolved "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz"
- integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==
- dependencies:
- path-type "^4.0.0"
-
-doctrine@^1.2.2:
- version "1.5.0"
- resolved "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz"
- integrity sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=
- dependencies:
- esutils "^2.0.2"
- isarray "^1.0.0"
-
-doctrine@^3.0.0:
- version "3.0.0"
- resolved "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz"
- integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==
- dependencies:
- esutils "^2.0.2"
-
-dom-serializer@0:
- version "0.2.1"
- resolved "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.1.tgz"
- integrity sha512-sK3ujri04WyjwQXVoK4PU3y8ula1stq10GJZpqHIUgoGZdsGzAGu65BnU3d08aTVSvO7mGPZUc0wTEDL+qGE0Q==
- dependencies:
- domelementtype "^2.0.1"
- entities "^2.0.0"
-
-dom-walk@^0.1.0:
- version "0.1.1"
- resolved "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.1.tgz"
- integrity sha1-ZyIm3HTI95mtNTB9+TaroRrNYBg=
-
-domain-browser@^1.1.1:
- version "1.2.0"
- resolved "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz"
- integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==
-
-domelementtype@1:
- version "1.3.1"
- resolved "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz"
- integrity sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==
-
-domelementtype@^2.0.1:
- version "2.0.1"
- resolved "https://registry.npmjs.org/domelementtype/-/domelementtype-2.0.1.tgz"
- integrity sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ==
-
-domexception@^1.0.1:
- version "1.0.1"
- resolved "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz"
- integrity sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==
- dependencies:
- webidl-conversions "^4.0.2"
-
-domutils@^1.7.0:
- version "1.7.0"
- resolved "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz"
- integrity sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==
- dependencies:
- dom-serializer "0"
- domelementtype "1"
-
-dot-prop@^4.1.1:
- version "4.2.0"
- resolved "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz"
- integrity sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==
- dependencies:
- is-obj "^1.0.0"
-
-download@^6.2.2:
- version "6.2.5"
- resolved "https://registry.npmjs.org/download/-/download-6.2.5.tgz"
- integrity sha512-DpO9K1sXAST8Cpzb7kmEhogJxymyVUd5qz/vCOSyvwtp2Klj2XcDt5YUuasgxka44SxF0q5RriKIwJmQHG2AuA==
- dependencies:
- caw "^2.0.0"
- content-disposition "^0.5.2"
- decompress "^4.0.0"
- ext-name "^5.0.0"
- file-type "5.2.0"
- filenamify "^2.0.0"
- get-stream "^3.0.0"
- got "^7.0.0"
- make-dir "^1.0.0"
- p-event "^1.0.0"
- pify "^3.0.0"
-
-download@^7.1.0:
- version "7.1.0"
- resolved "https://registry.npmjs.org/download/-/download-7.1.0.tgz"
- integrity sha512-xqnBTVd/E+GxJVrX5/eUJiLYjCGPwMpdL+jGhGU57BvtcA7wwhtHVbXBeUk51kOpW3S7Jn3BQbN9Q1R1Km2qDQ==
- dependencies:
- archive-type "^4.0.0"
- caw "^2.0.1"
- content-disposition "^0.5.2"
- decompress "^4.2.0"
- ext-name "^5.0.0"
- file-type "^8.1.0"
- filenamify "^2.0.0"
- get-stream "^3.0.0"
- got "^8.3.1"
- make-dir "^1.2.0"
- p-event "^2.1.0"
- pify "^3.0.0"
-
-duplexer2@0.0.2:
- version "0.0.2"
- resolved "https://registry.npmjs.org/duplexer2/-/duplexer2-0.0.2.tgz"
- integrity sha1-xhTc9n4vsUmVqRcR5aYX6KYKMds=
- dependencies:
- readable-stream "~1.1.9"
-
-duplexer3@^0.1.4:
- version "0.1.4"
- resolved "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz"
- integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=
-
-duplexify@^3.4.2, duplexify@^3.6.0:
- version "3.7.1"
- resolved "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz"
- integrity sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==
- dependencies:
- end-of-stream "^1.0.0"
- inherits "^2.0.1"
- readable-stream "^2.0.0"
- stream-shift "^1.0.0"
-
-duplexify@^4.1.1:
- version "4.1.1"
- resolved "https://registry.npmjs.org/duplexify/-/duplexify-4.1.1.tgz"
- integrity sha512-DY3xVEmVHTv1wSzKNbwoU6nVjzI369Y6sPoqfYr0/xlx3IdX2n94xIszTcjPO8W8ZIv0Wb0PXNcjuZyT4wiICA==
- dependencies:
- end-of-stream "^1.4.1"
- inherits "^2.0.3"
- readable-stream "^3.1.1"
- stream-shift "^1.0.0"
-
-each-props@^1.3.0:
- version "1.3.2"
- resolved "https://registry.npmjs.org/each-props/-/each-props-1.3.2.tgz"
- integrity sha512-vV0Hem3zAGkJAyU7JSjixeU66rwdynTAa1vofCrSA5fEln+m67Az9CcnkVD776/fsN/UjIWmBDoNRS6t6G9RfA==
- dependencies:
- is-plain-object "^2.0.1"
- object.defaults "^1.1.0"
-
-easy-extender@^2.3.4:
- version "2.3.4"
- resolved "https://registry.npmjs.org/easy-extender/-/easy-extender-2.3.4.tgz"
- integrity sha512-8cAwm6md1YTiPpOvDULYJL4ZS6WfM5/cTeVVh4JsvyYZAoqlRVUpHL9Gr5Fy7HA6xcSZicUia3DeAgO3Us8E+Q==
- dependencies:
- lodash "^4.17.10"
-
-eazy-logger@^3:
- version "3.0.2"
- resolved "https://registry.npmjs.org/eazy-logger/-/eazy-logger-3.0.2.tgz"
- integrity sha1-oyWqXlPROiIliJsqxBE7K5Y29Pw=
- dependencies:
- tfunk "^3.0.1"
-
-ecc-jsbn@~0.1.1:
- version "0.1.2"
- resolved "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz"
- integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=
- dependencies:
- jsbn "~0.1.0"
- safer-buffer "^2.1.0"
-
-editorconfig@^0.15.3:
- version "0.15.3"
- resolved "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.3.tgz"
- integrity sha512-M9wIMFx96vq0R4F+gRpY3o2exzb8hEj/n9S8unZtHSvYjibBp/iMufSzvmOcV/laG0ZtuTVGtiJggPOSW2r93g==
- dependencies:
- commander "^2.19.0"
- lru-cache "^4.1.5"
- semver "^5.6.0"
- sigmund "^1.0.1"
-
-ee-first@1.0.5:
- version "1.0.5"
- resolved "https://registry.npmjs.org/ee-first/-/ee-first-1.0.5.tgz"
- integrity sha1-jJshKJjYzZ8alDZlDOe+ICyen/A=
-
-ee-first@1.1.1:
- version "1.1.1"
- resolved "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz"
- integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=
-
-electron-notarize@^1.1.1, electron-notarize@^1.2.1:
- version "1.2.1"
- resolved "https://registry.yarnpkg.com/electron-notarize/-/electron-notarize-1.2.1.tgz#347c18eca8e29dddadadee511b870c13d4008baf"
- integrity sha512-u/ECWhIrhkSQpZM4cJzVZ5TsmkaqrRo5LDC/KMbGF0sPkm53Ng59+M0zp8QVaql0obfJy9vlVT+4iOkAi2UDlA==
- dependencies:
- debug "^4.1.1"
- fs-extra "^9.0.1"
-
-electron-osx-sign@^0.5.0:
- version "0.5.0"
- resolved "https://registry.yarnpkg.com/electron-osx-sign/-/electron-osx-sign-0.5.0.tgz#fc258c5e896859904bbe3d01da06902c04b51c3a"
- integrity sha512-icoRLHzFz/qxzDh/N4Pi2z4yVHurlsCAYQvsCSG7fCedJ4UJXBS6PoQyGH71IfcqKupcKeK7HX/NkyfG+v6vlQ==
- dependencies:
- bluebird "^3.5.0"
- compare-version "^0.1.2"
- debug "^2.6.8"
- isbinaryfile "^3.0.2"
- minimist "^1.2.0"
- plist "^3.0.1"
-
-electron-packager@^15.4.0:
- version "15.4.0"
- resolved "https://registry.yarnpkg.com/electron-packager/-/electron-packager-15.4.0.tgz#07ea036b70cde2062d4c8dce4d907d793b303998"
- integrity sha512-JrrLcBP15KGrPj0cZ/ALKGmaQ4gJkn3mocf0E3bRKdR3kxKWYcDRpCvdhksYDXw/r3I6tMEcZ7XzyApWFXdVpw==
- dependencies:
- "@electron/get" "^1.6.0"
- asar "^3.1.0"
- cross-spawn-windows-exe "^1.2.0"
- debug "^4.0.1"
- electron-notarize "^1.1.1"
- electron-osx-sign "^0.5.0"
- extract-zip "^2.0.0"
- filenamify "^4.1.0"
- fs-extra "^9.0.0"
- galactus "^0.2.1"
- get-package-info "^1.0.0"
- junk "^3.1.0"
- parse-author "^2.0.0"
- plist "^3.0.0"
- rcedit "^3.0.1"
- resolve "^1.1.6"
- semver "^7.1.3"
- yargs-parser "^20.0.0"
-
-electron-to-chromium@^1.3.247:
- version "1.3.264"
- resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.264.tgz"
- integrity sha512-z8E7WkrrquCuGYv+kKyybuZIbdms+4PeHp7Zm2uIgEhAigP0bOwqXILItwj0YO73o+QyHY/7XtEfP5DsHOWQgQ==
-
-elliptic@^6.0.0:
- version "6.5.1"
- resolved "https://registry.npmjs.org/elliptic/-/elliptic-6.5.1.tgz"
- integrity sha512-xvJINNLbTeWQjrl6X+7eQCrIy/YPv5XCpKW6kB5mKvtnGILoLDcySuwomfdzt0BMdLNVnuRNTuzKNHj0bva1Cg==
- dependencies:
- bn.js "^4.4.0"
- brorand "^1.0.1"
- hash.js "^1.0.0"
- hmac-drbg "^1.0.0"
- inherits "^2.0.1"
- minimalistic-assert "^1.0.0"
- minimalistic-crypto-utils "^1.0.0"
-
-email-validator@^2.0.4:
- version "2.0.4"
- resolved "https://registry.npmjs.org/email-validator/-/email-validator-2.0.4.tgz"
- integrity sha512-gYCwo7kh5S3IDyZPLZf6hSS0MnZT8QmJFqYvbqlDZSbwdZlY6QZWxJ4i/6UhITOJ4XzyI647Bm2MXKCLqnJ4nQ==
-
-emoji-regex@^7.0.1:
- version "7.0.3"
- resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz"
- integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==
-
-emoji-regex@^8.0.0:
- version "8.0.0"
- resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz"
- integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==
-
-emojis-list@^2.0.0:
- version "2.1.0"
- resolved "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz"
- integrity sha1-TapNnbAPmBmIDHn6RXrlsJof04k=
-
-emojis-list@^3.0.0:
- version "3.0.0"
- resolved "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz"
- integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==
-
-encodeurl@^1.0.2, encodeurl@~1.0.1, encodeurl@~1.0.2:
- version "1.0.2"
- resolved "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz"
- integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=
-
-end-of-stream@^1.0.0, end-of-stream@^1.1.0, end-of-stream@^1.4.1:
- version "1.4.1"
- resolved "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz"
- integrity sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==
- dependencies:
- once "^1.4.0"
-
-end-of-stream@~0.1.5:
- version "0.1.5"
- resolved "https://registry.npmjs.org/end-of-stream/-/end-of-stream-0.1.5.tgz"
- integrity sha1-jhdyBsPICDfYVjLouTWd/osvbq8=
- dependencies:
- once "~1.3.0"
-
-engine.io-client@~3.2.0:
- version "3.2.1"
- resolved "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.2.1.tgz"
- integrity sha512-y5AbkytWeM4jQr7m/koQLc5AxpRKC1hEVUb/s1FUAWEJq5AzJJ4NLvzuKPuxtDi5Mq755WuDvZ6Iv2rXj4PTzw==
- dependencies:
- component-emitter "1.2.1"
- component-inherit "0.0.3"
- debug "~3.1.0"
- engine.io-parser "~2.1.1"
- has-cors "1.1.0"
- indexof "0.0.1"
- parseqs "0.0.5"
- parseuri "0.0.5"
- ws "~3.3.1"
- xmlhttprequest-ssl "~1.5.4"
- yeast "0.1.2"
-
-engine.io-client@~3.4.0:
- version "3.4.0"
- resolved "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.4.0.tgz"
- integrity sha512-a4J5QO2k99CM2a0b12IznnyQndoEvtA4UAldhGzKqnHf42I3Qs2W5SPnDvatZRcMaNZs4IevVicBPayxYt6FwA==
- dependencies:
- component-emitter "1.2.1"
- component-inherit "0.0.3"
- debug "~4.1.0"
- engine.io-parser "~2.2.0"
- has-cors "1.1.0"
- indexof "0.0.1"
- parseqs "0.0.5"
- parseuri "0.0.5"
- ws "~6.1.0"
- xmlhttprequest-ssl "~1.5.4"
- yeast "0.1.2"
-
-engine.io-parser@~2.1.0, engine.io-parser@~2.1.1:
- version "2.1.3"
- resolved "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.1.3.tgz"
- integrity sha512-6HXPre2O4Houl7c4g7Ic/XzPnHBvaEmN90vtRO9uLmwtRqQmTOw0QMevL1TOfL2Cpu1VzsaTmMotQgMdkzGkVA==
- dependencies:
- after "0.8.2"
- arraybuffer.slice "~0.0.7"
- base64-arraybuffer "0.1.5"
- blob "0.0.5"
- has-binary2 "~1.0.2"
-
-engine.io-parser@~2.2.0:
- version "2.2.0"
- resolved "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.2.0.tgz"
- integrity sha512-6I3qD9iUxotsC5HEMuuGsKA0cXerGz+4uGcXQEkfBidgKf0amsjrrtwcbwK/nzpZBxclXlV7gGl9dgWvu4LF6w==
- dependencies:
- after "0.8.2"
- arraybuffer.slice "~0.0.7"
- base64-arraybuffer "0.1.5"
- blob "0.0.5"
- has-binary2 "~1.0.2"
-
-engine.io@~3.2.0:
- version "3.2.1"
- resolved "https://registry.npmjs.org/engine.io/-/engine.io-3.2.1.tgz"
- integrity sha512-+VlKzHzMhaU+GsCIg4AoXF1UdDFjHHwMmMKqMJNDNLlUlejz58FCy4LBqB2YVJskHGYl06BatYWKP2TVdVXE5w==
- dependencies:
- accepts "~1.3.4"
- base64id "1.0.0"
- cookie "0.3.1"
- debug "~3.1.0"
- engine.io-parser "~2.1.0"
- ws "~3.3.1"
-
-enhanced-resolve@4.1.0, enhanced-resolve@^4.1.0:
- version "4.1.0"
- resolved "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.0.tgz"
- integrity sha512-F/7vkyTtyc/llOIn8oWclcB25KdRaiPBpZYDgJHgh/UHtpgT2p2eldQgtQnLtUvfMKPKxbRaQM/hHkvLHt1Vng==
- dependencies:
- graceful-fs "^4.1.2"
- memory-fs "^0.4.0"
- tapable "^1.0.0"
-
-entities@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/entities/-/entities-2.0.0.tgz"
- integrity sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw==
-
-env-paths@^2.2.0:
- version "2.2.0"
- resolved "https://registry.npmjs.org/env-paths/-/env-paths-2.2.0.tgz"
- integrity sha512-6u0VYSCo/OW6IoD5WCLLy9JUGARbamfSavcNXry/eu8aHVFei6CD3Sw+VGX5alea1i9pgPHW0mbu6Xj0uBh7gA==
-
-errno@^0.1.3, errno@~0.1.7:
- version "0.1.7"
- resolved "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz"
- integrity sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==
- dependencies:
- prr "~1.0.1"
-
-error-ex@^1.2.0, error-ex@^1.3.1:
- version "1.3.2"
- resolved "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz"
- integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==
- dependencies:
- is-arrayish "^0.2.1"
-
-es-abstract@^1.12.0, es-abstract@^1.13.0, es-abstract@^1.5.1:
- version "1.14.2"
- resolved "https://registry.npmjs.org/es-abstract/-/es-abstract-1.14.2.tgz"
- integrity sha512-DgoQmbpFNOofkjJtKwr87Ma5EW4Dc8fWhD0R+ndq7Oc456ivUfGOOP6oAZTTKl5/CcNMP+EN+e3/iUzgE0veZg==
- dependencies:
- es-to-primitive "^1.2.0"
- function-bind "^1.1.1"
- has "^1.0.3"
- has-symbols "^1.0.0"
- is-callable "^1.1.4"
- is-regex "^1.0.4"
- object-inspect "^1.6.0"
- object-keys "^1.1.1"
- string.prototype.trimleft "^2.0.0"
- string.prototype.trimright "^2.0.0"
-
-es-to-primitive@^1.2.0:
- version "1.2.0"
- resolved "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz"
- integrity sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==
- dependencies:
- is-callable "^1.1.4"
- is-date-object "^1.0.1"
- is-symbol "^1.0.2"
-
-es5-ext@^0.10.35, es5-ext@^0.10.46, es5-ext@^0.10.50, es5-ext@^0.10.51, es5-ext@~0.10.14:
- version "0.10.51"
- resolved "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.51.tgz"
- integrity sha512-oRpWzM2WcLHVKpnrcyB7OW8j/s67Ba04JCm0WnNv3RiABSvs7mrQlutB8DBv793gKcp0XENR8Il8WxGTlZ73gQ==
- dependencies:
- es6-iterator "~2.0.3"
- es6-symbol "~3.1.1"
- next-tick "^1.0.0"
-
-es6-error@^4.1.1:
- version "4.1.1"
- resolved "https://registry.yarnpkg.com/es6-error/-/es6-error-4.1.1.tgz#9e3af407459deed47e9a91f9b885a84eb05c561d"
- integrity sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==
-
-es6-iterator@^2.0.1, es6-iterator@^2.0.3, es6-iterator@~2.0.1, es6-iterator@~2.0.3:
- version "2.0.3"
- resolved "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz"
- integrity sha1-p96IkUGgWpSwhUQDstCg+/qY87c=
- dependencies:
- d "1"
- es5-ext "^0.10.35"
- es6-symbol "^3.1.1"
-
-es6-map@^0.1.3:
- version "0.1.5"
- resolved "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz"
- integrity sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=
- dependencies:
- d "1"
- es5-ext "~0.10.14"
- es6-iterator "~2.0.1"
- es6-set "~0.1.5"
- es6-symbol "~3.1.1"
- event-emitter "~0.3.5"
-
-es6-set@~0.1.5:
- version "0.1.5"
- resolved "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz"
- integrity sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=
- dependencies:
- d "1"
- es5-ext "~0.10.14"
- es6-iterator "~2.0.1"
- es6-symbol "3.1.1"
- event-emitter "~0.3.5"
-
-es6-symbol@3.1.1:
- version "3.1.1"
- resolved "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz"
- integrity sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=
- dependencies:
- d "1"
- es5-ext "~0.10.14"
-
-es6-symbol@^3.1.1, es6-symbol@~3.1.1:
- version "3.1.2"
- resolved "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.2.tgz"
- integrity sha512-/ZypxQsArlv+KHpGvng52/Iz8by3EQPxhmbuz8yFG89N/caTFBSbcXONDw0aMjy827gQg26XAjP4uXFvnfINmQ==
- dependencies:
- d "^1.0.1"
- es5-ext "^0.10.51"
-
-es6-templates@^0.2.3:
- version "0.2.3"
- resolved "https://registry.npmjs.org/es6-templates/-/es6-templates-0.2.3.tgz"
- integrity sha1-XLmsn7He1usSOTQrgdeSu7QHjuQ=
- dependencies:
- recast "~0.11.12"
- through "~2.3.6"
-
-es6-weak-map@^2.0.1:
- version "2.0.3"
- resolved "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz"
- integrity sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==
- dependencies:
- d "1"
- es5-ext "^0.10.46"
- es6-iterator "^2.0.3"
- es6-symbol "^3.1.1"
-
-escape-html@~1.0.3:
- version "1.0.3"
- resolved "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz"
- integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=
-
-escape-string-regexp@^1.0.0, escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5:
- version "1.0.5"
- resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz"
- integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=
-
-escape-string-regexp@^4.0.0:
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34"
- integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==
-
-escodegen@^1.11.0:
- version "1.12.0"
- resolved "https://registry.npmjs.org/escodegen/-/escodegen-1.12.0.tgz"
- integrity sha512-TuA+EhsanGcme5T3R0L80u4t8CpbXQjegRmf7+FPTJrtCTErXFeelblRgHQa1FofEzqYYJmJ/OqjTwREp9qgmg==
- dependencies:
- esprima "^3.1.3"
- estraverse "^4.2.0"
- esutils "^2.0.2"
- optionator "^0.8.1"
- optionalDependencies:
- source-map "~0.6.1"
-
-escope@^3.6.0:
- version "3.6.0"
- resolved "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz"
- integrity sha1-4Bl16BJ4GhY6ba392AOY3GTIicM=
- dependencies:
- es6-map "^0.1.3"
- es6-weak-map "^2.0.1"
- esrecurse "^4.1.0"
- estraverse "^4.1.1"
-
-eslint-scope@^4.0.3:
- version "4.0.3"
- resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz"
- integrity sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==
- dependencies:
- esrecurse "^4.1.0"
- estraverse "^4.1.1"
-
-eslint-utils@^1.3.1:
- version "1.4.2"
- resolved "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.2.tgz"
- integrity sha512-eAZS2sEUMlIeCjBeubdj45dmBHQwPHWyBcT1VSYB7o9x9WRRqKxyUoiXlRjyAwzN7YEzHJlYg0NmzDRWx6GP4Q==
- dependencies:
- eslint-visitor-keys "^1.0.0"
-
-eslint-visitor-keys@^1.0.0:
- version "1.1.0"
- resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz"
- integrity sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==
-
-eslint@^2.7.0:
- version "2.13.1"
- resolved "https://registry.npmjs.org/eslint/-/eslint-2.13.1.tgz"
- integrity sha1-5MyPoPAJ+4KaquI4VaKTYL4fbBE=
- dependencies:
- chalk "^1.1.3"
- concat-stream "^1.4.6"
- debug "^2.1.1"
- doctrine "^1.2.2"
- es6-map "^0.1.3"
- escope "^3.6.0"
- espree "^3.1.6"
- estraverse "^4.2.0"
- esutils "^2.0.2"
- file-entry-cache "^1.1.1"
- glob "^7.0.3"
- globals "^9.2.0"
- ignore "^3.1.2"
- imurmurhash "^0.1.4"
- inquirer "^0.12.0"
- is-my-json-valid "^2.10.0"
- is-resolvable "^1.0.0"
- js-yaml "^3.5.1"
- json-stable-stringify "^1.0.0"
- levn "^0.3.0"
- lodash "^4.0.0"
- mkdirp "^0.5.0"
- optionator "^0.8.1"
- path-is-absolute "^1.0.0"
- path-is-inside "^1.0.1"
- pluralize "^1.2.1"
- progress "^1.1.8"
- require-uncached "^1.0.2"
- shelljs "^0.6.0"
- strip-json-comments "~1.0.1"
- table "^3.7.8"
- text-table "~0.2.0"
- user-home "^2.0.0"
-
-eslint@^5.9.0:
- version "5.16.0"
- resolved "https://registry.npmjs.org/eslint/-/eslint-5.16.0.tgz"
- integrity sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg==
- dependencies:
- "@babel/code-frame" "^7.0.0"
- ajv "^6.9.1"
- chalk "^2.1.0"
- cross-spawn "^6.0.5"
- debug "^4.0.1"
- doctrine "^3.0.0"
- eslint-scope "^4.0.3"
- eslint-utils "^1.3.1"
- eslint-visitor-keys "^1.0.0"
- espree "^5.0.1"
- esquery "^1.0.1"
- esutils "^2.0.2"
- file-entry-cache "^5.0.1"
- functional-red-black-tree "^1.0.1"
- glob "^7.1.2"
- globals "^11.7.0"
- ignore "^4.0.6"
- import-fresh "^3.0.0"
- imurmurhash "^0.1.4"
- inquirer "^6.2.2"
- js-yaml "^3.13.0"
- json-stable-stringify-without-jsonify "^1.0.1"
- levn "^0.3.0"
- lodash "^4.17.11"
- minimatch "^3.0.4"
- mkdirp "^0.5.1"
- natural-compare "^1.4.0"
- optionator "^0.8.2"
- path-is-inside "^1.0.2"
- progress "^2.0.0"
- regexpp "^2.0.1"
- semver "^5.5.1"
- strip-ansi "^4.0.0"
- strip-json-comments "^2.0.1"
- table "^5.2.3"
- text-table "^0.2.0"
-
-espree@^3.1.6:
- version "3.5.4"
- resolved "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz"
- integrity sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==
- dependencies:
- acorn "^5.5.0"
- acorn-jsx "^3.0.0"
-
-espree@^5.0.1:
- version "5.0.1"
- resolved "https://registry.npmjs.org/espree/-/espree-5.0.1.tgz"
- integrity sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A==
- dependencies:
- acorn "^6.0.7"
- acorn-jsx "^5.0.0"
- eslint-visitor-keys "^1.0.0"
-
-esprima@^3.1.3, esprima@~3.1.0:
- version "3.1.3"
- resolved "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz"
- integrity sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=
-
-esprima@^4.0.0:
- version "4.0.1"
- resolved "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz"
- integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==
-
-esquery@^1.0.1:
- version "1.0.1"
- resolved "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz"
- integrity sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==
- dependencies:
- estraverse "^4.0.0"
-
-esrecurse@^4.1.0, esrecurse@^4.2.1:
- version "4.2.1"
- resolved "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz"
- integrity sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==
- dependencies:
- estraverse "^4.1.0"
-
-estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0:
- version "4.3.0"
- resolved "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz"
- integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==
-
-esutils@^2.0.2:
- version "2.0.3"
- resolved "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz"
- integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==
-
-etag@1.8.1, etag@^1.8.1, etag@~1.8.1:
- version "1.8.1"
- resolved "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz"
- integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=
-
-event-emitter@~0.3.5:
- version "0.3.5"
- resolved "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz"
- integrity sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=
- dependencies:
- d "1"
- es5-ext "~0.10.14"
-
-eventemitter3@^4.0.0:
- version "4.0.4"
- resolved "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.4.tgz"
- integrity sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ==
-
-events@^3.0.0:
- version "3.0.0"
- resolved "https://registry.npmjs.org/events/-/events-3.0.0.tgz"
- integrity sha512-Dc381HFWJzEOhQ+d8pkNon++bk9h6cdAoAj4iE6Q4y6xgTzySWXlKn05/TVNpjnfRqi/X0EpJEJohPjNI3zpVA==
-
-evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3:
- version "1.0.3"
- resolved "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz"
- integrity sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==
- dependencies:
- md5.js "^1.3.4"
- safe-buffer "^5.1.1"
-
-exec-buffer@^3.0.0:
- version "3.2.0"
- resolved "https://registry.npmjs.org/exec-buffer/-/exec-buffer-3.2.0.tgz"
- integrity sha512-wsiD+2Tp6BWHoVv3B+5Dcx6E7u5zky+hUwOHjuH2hKSLR3dvRmX8fk8UD8uqQixHs4Wk6eDmiegVrMPjKj7wpA==
- dependencies:
- execa "^0.7.0"
- p-finally "^1.0.0"
- pify "^3.0.0"
- rimraf "^2.5.4"
- tempfile "^2.0.0"
-
-execa@^0.10.0:
- version "0.10.0"
- resolved "https://registry.npmjs.org/execa/-/execa-0.10.0.tgz"
- integrity sha512-7XOMnz8Ynx1gGo/3hyV9loYNPWM94jG3+3T3Y8tsfSstFmETmENCMU/A/zj8Lyaj1lkgEepKepvd6240tBRvlw==
- dependencies:
- cross-spawn "^6.0.0"
- get-stream "^3.0.0"
- is-stream "^1.1.0"
- npm-run-path "^2.0.0"
- p-finally "^1.0.0"
- signal-exit "^3.0.0"
- strip-eof "^1.0.0"
-
-execa@^0.7.0:
- version "0.7.0"
- resolved "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz"
- integrity sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=
- dependencies:
- cross-spawn "^5.0.1"
- get-stream "^3.0.0"
- is-stream "^1.1.0"
- npm-run-path "^2.0.0"
- p-finally "^1.0.0"
- signal-exit "^3.0.0"
- strip-eof "^1.0.0"
-
-execa@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz"
- integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==
- dependencies:
- cross-spawn "^6.0.0"
- get-stream "^4.0.0"
- is-stream "^1.1.0"
- npm-run-path "^2.0.0"
- p-finally "^1.0.0"
- signal-exit "^3.0.0"
- strip-eof "^1.0.0"
-
-execa@^4.0.0:
- version "4.0.2"
- resolved "https://registry.npmjs.org/execa/-/execa-4.0.2.tgz"
- integrity sha512-QI2zLa6CjGWdiQsmSkZoGtDx2N+cQIGb3yNolGTdjSQzydzLgYYf8LRuagp7S7fPimjcrzUDSUFd/MgzELMi4Q==
- dependencies:
- cross-spawn "^7.0.0"
- get-stream "^5.0.0"
- human-signals "^1.1.1"
- is-stream "^2.0.0"
- merge-stream "^2.0.0"
- npm-run-path "^4.0.0"
- onetime "^5.1.0"
- signal-exit "^3.0.2"
- strip-final-newline "^2.0.0"
-
-execa@^5.0.0:
- version "5.0.0"
- resolved "https://registry.npmjs.org/execa/-/execa-5.0.0.tgz"
- integrity sha512-ov6w/2LCiuyO4RLYGdpFGjkcs0wMTgGE8PrkTHikeUy5iJekXyPIKUjifk5CsE0pt7sMCrMZ3YNqoCj6idQOnQ==
- dependencies:
- cross-spawn "^7.0.3"
- get-stream "^6.0.0"
- human-signals "^2.1.0"
- is-stream "^2.0.0"
- merge-stream "^2.0.0"
- npm-run-path "^4.0.1"
- onetime "^5.1.2"
- signal-exit "^3.0.3"
- strip-final-newline "^2.0.0"
-
-executable@^4.1.0:
- version "4.1.1"
- resolved "https://registry.npmjs.org/executable/-/executable-4.1.1.tgz"
- integrity sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg==
- dependencies:
- pify "^2.2.0"
-
-exif-parser@^0.1.12:
- version "0.1.12"
- resolved "https://registry.npmjs.org/exif-parser/-/exif-parser-0.1.12.tgz"
- integrity sha1-WKnS1ywCwfbwKg70qRZicrd2CSI=
-
-exit-hook@^1.0.0:
- version "1.1.1"
- resolved "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz"
- integrity sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g=
-
-expand-brackets@^2.1.4:
- version "2.1.4"
- resolved "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz"
- integrity sha1-t3c14xXOMPa27/D4OwQVGiJEliI=
- dependencies:
- debug "^2.3.3"
- define-property "^0.2.5"
- extend-shallow "^2.0.1"
- posix-character-classes "^0.1.0"
- regex-not "^1.0.0"
- snapdragon "^0.8.1"
- to-regex "^3.0.1"
-
-expand-tilde@^2.0.0, expand-tilde@^2.0.2:
- version "2.0.2"
- resolved "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz"
- integrity sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=
- dependencies:
- homedir-polyfill "^1.0.1"
-
-ext-list@^2.0.0:
- version "2.2.2"
- resolved "https://registry.npmjs.org/ext-list/-/ext-list-2.2.2.tgz"
- integrity sha512-u+SQgsubraE6zItfVA0tBuCBhfU9ogSRnsvygI7wht9TS510oLkBRXBsqopeUG/GBOIQyKZO9wjTqIu/sf5zFA==
- dependencies:
- mime-db "^1.28.0"
-
-ext-name@^5.0.0:
- version "5.0.0"
- resolved "https://registry.npmjs.org/ext-name/-/ext-name-5.0.0.tgz"
- integrity sha512-yblEwXAbGv1VQDmow7s38W77hzAgJAO50ztBLMcUyUBfxv1HC+LGwtiEN+Co6LtlqT/5uwVOxsD4TNIilWhwdQ==
- dependencies:
- ext-list "^2.0.0"
- sort-keys-length "^1.0.0"
-
-extend-shallow@^1.1.2:
- version "1.1.4"
- resolved "https://registry.npmjs.org/extend-shallow/-/extend-shallow-1.1.4.tgz"
- integrity sha1-Gda/lN/AnXa6cR85uHLSH/TdkHE=
- dependencies:
- kind-of "^1.1.0"
-
-extend-shallow@^2.0.1:
- version "2.0.1"
- resolved "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz"
- integrity sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=
- dependencies:
- is-extendable "^0.1.0"
-
-extend-shallow@^3.0.0, extend-shallow@^3.0.2:
- version "3.0.2"
- resolved "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz"
- integrity sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=
- dependencies:
- assign-symbols "^1.0.0"
- is-extendable "^1.0.1"
-
-extend@^3.0.0, extend@~3.0.2:
- version "3.0.2"
- resolved "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz"
- integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==
-
-external-editor@^3.0.3:
- version "3.1.0"
- resolved "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz"
- integrity sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==
- dependencies:
- chardet "^0.7.0"
- iconv-lite "^0.4.24"
- tmp "^0.0.33"
-
-extglob@^2.0.4:
- version "2.0.4"
- resolved "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz"
- integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==
- dependencies:
- array-unique "^0.3.2"
- define-property "^1.0.0"
- expand-brackets "^2.1.4"
- extend-shallow "^2.0.1"
- fragment-cache "^0.2.1"
- regex-not "^1.0.0"
- snapdragon "^0.8.1"
- to-regex "^3.0.1"
-
-extract-zip@^2.0.0:
- version "2.0.1"
- resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-2.0.1.tgz#663dca56fe46df890d5f131ef4a06d22bb8ba13a"
- integrity sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==
- dependencies:
- debug "^4.1.1"
- get-stream "^5.1.0"
- yauzl "^2.10.0"
- optionalDependencies:
- "@types/yauzl" "^2.9.1"
-
-extsprintf@1.3.0, extsprintf@^1.2.0:
- version "1.3.0"
- resolved "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz"
- integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=
-
-eyes@0.1.x:
- version "0.1.8"
- resolved "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz"
- integrity sha1-Ys8SAjTGg3hdkCNIqADvPgzCC8A=
-
-fancy-log@^1.1.0, fancy-log@^1.2.0, fancy-log@^1.3.2, fancy-log@^1.3.3:
- version "1.3.3"
- resolved "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.3.tgz"
- integrity sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw==
- dependencies:
- ansi-gray "^0.1.1"
- color-support "^1.1.3"
- parse-node-version "^1.0.0"
- time-stamp "^1.0.0"
-
-fast-deep-equal@^3.1.1:
- version "3.1.1"
- resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz"
- integrity sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==
-
-fast-glob@^3.0.3:
- version "3.2.2"
- resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.2.tgz"
- integrity sha512-UDV82o4uQyljznxwMxyVRJgZZt3O5wENYojjzbaGEGZgeOxkLFf+V4cnUD+krzb2F72E18RhamkMZ7AdeggF7A==
- dependencies:
- "@nodelib/fs.stat" "^2.0.2"
- "@nodelib/fs.walk" "^1.2.3"
- glob-parent "^5.1.0"
- merge2 "^1.3.0"
- micromatch "^4.0.2"
- picomatch "^2.2.1"
-
-fast-json-stable-stringify@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz"
- integrity sha1-1RQsDK7msRifh9OnYREGT4bIu/I=
-
-fast-levenshtein@~2.0.4:
- version "2.0.6"
- resolved "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz"
- integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=
-
-fastdom@^1.0.9:
- version "1.0.9"
- resolved "https://registry.npmjs.org/fastdom/-/fastdom-1.0.9.tgz"
- integrity sha512-SSp4fbVzu8JkkG01NUX+0iOwe9M5PN3MGIQ84txLf4TkkJG4q30khkzumKgi4hUqO1+jX6wLHfnCPoZ6eSZ6Tg==
- dependencies:
- strictdom "^1.0.1"
-
-faster.js@^1.1.0:
- version "1.1.1"
- resolved "https://registry.npmjs.org/faster.js/-/faster.js-1.1.1.tgz"
- integrity sha512-vPThNSLL/E1f7cLHd9yuayxZR82o/Iic4S5ZY45iY5AgBLNIlr3b3c+VpDjoYqjY9a9C/FQVUQy9oTILVP7X0g==
-
-fastparse@^1.1.1:
- version "1.1.2"
- resolved "https://registry.npmjs.org/fastparse/-/fastparse-1.1.2.tgz"
- integrity sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==
-
-fastq@^1.6.0:
- version "1.8.0"
- resolved "https://registry.npmjs.org/fastq/-/fastq-1.8.0.tgz"
- integrity sha512-SMIZoZdLh/fgofivvIkmknUXyPnvxRE3DhtZ5Me3Mrsk5gyPL42F0xr51TdRXskBxHfMp+07bcYzfsYEsSQA9Q==
- dependencies:
- reusify "^1.0.4"
-
-faye-websocket@~0.7.2:
- version "0.7.3"
- resolved "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.7.3.tgz"
- integrity sha1-zEB0x/Sk39A69U3WXDVLE1EyzhE=
- dependencies:
- websocket-driver ">=0.3.6"
-
-fd-slicer@~1.1.0:
- version "1.1.0"
- resolved "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz"
- integrity sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=
- dependencies:
- pend "~1.2.0"
-
-figgy-pudding@^3.5.1:
- version "3.5.1"
- resolved "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.1.tgz"
- integrity sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w==
-
-figures@^1.3.5:
- version "1.7.0"
- resolved "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz"
- integrity sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=
- dependencies:
- escape-string-regexp "^1.0.5"
- object-assign "^4.1.0"
-
-figures@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz"
- integrity sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=
- dependencies:
- escape-string-regexp "^1.0.5"
-
-file-entry-cache@^1.1.1:
- version "1.3.1"
- resolved "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-1.3.1.tgz"
- integrity sha1-RMYepgeuS+nBQC9B9EJwy/4zT/g=
- dependencies:
- flat-cache "^1.2.1"
- object-assign "^4.0.1"
-
-file-entry-cache@^5.0.1:
- version "5.0.1"
- resolved "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz"
- integrity sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==
- dependencies:
- flat-cache "^2.0.1"
-
-file-loader@^0.8.1:
- version "0.8.5"
- resolved "https://registry.npmjs.org/file-loader/-/file-loader-0.8.5.tgz"
- integrity sha1-knXQMf54DyfUf19K8CvUNxPMFRs=
- dependencies:
- loader-utils "~0.2.5"
-
-file-type@5.2.0, file-type@^5.2.0:
- version "5.2.0"
- resolved "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz"
- integrity sha1-LdvqfHP/42No365J3DOMBYwritY=
-
-file-type@^10.4.0:
- version "10.11.0"
- resolved "https://registry.npmjs.org/file-type/-/file-type-10.11.0.tgz"
- integrity sha512-uzk64HRpUZyTGZtVuvrjP0FYxzQrBf4rojot6J65YMEbwBLB0CWm0CLojVpwpmFmxcE/lkvYICgfcGozbBq6rw==
-
-file-type@^12.0.0:
- version "12.4.2"
- resolved "https://registry.npmjs.org/file-type/-/file-type-12.4.2.tgz"
- integrity sha512-UssQP5ZgIOKelfsaB5CuGAL+Y+q7EmONuiwF3N5HAH0t27rvrttgi6Ra9k/+DVaY9UF6+ybxu5pOXLUdA8N7Vg==
-
-file-type@^3.8.0:
- version "3.9.0"
- resolved "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz"
- integrity sha1-JXoHg4TR24CHvESdEH1SpSZyuek=
-
-file-type@^4.2.0:
- version "4.4.0"
- resolved "https://registry.npmjs.org/file-type/-/file-type-4.4.0.tgz"
- integrity sha1-G2AOX8ofvcboDApwxxyNul95BsU=
-
-file-type@^6.1.0:
- version "6.2.0"
- resolved "https://registry.npmjs.org/file-type/-/file-type-6.2.0.tgz"
- integrity sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg==
-
-file-type@^8.1.0:
- version "8.1.0"
- resolved "https://registry.npmjs.org/file-type/-/file-type-8.1.0.tgz"
- integrity sha512-qyQ0pzAy78gVoJsmYeNgl8uH8yKhr1lVhW7JbzJmnlRi0I4R2eEDEJZVKG8agpDnLpacwNbDhLNG/LMdxHD2YQ==
-
-file-type@^9.0.0:
- version "9.0.0"
- resolved "https://registry.npmjs.org/file-type/-/file-type-9.0.0.tgz"
- integrity sha512-Qe/5NJrgIOlwijpq3B7BEpzPFcgzggOTagZmkXQY4LA6bsXKTUstK7Wp12lEJ/mLKTpvIZxmIuRcLYWT6ov9lw==
-
-file-uri-to-path@1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz"
- integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==
-
-filename-reserved-regex@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz"
- integrity sha1-q/c9+rc10EVECr/qLZHzieu/oik=
-
-filenamify@^2.0.0:
- version "2.1.0"
- resolved "https://registry.npmjs.org/filenamify/-/filenamify-2.1.0.tgz"
- integrity sha512-ICw7NTT6RsDp2rnYKVd8Fu4cr6ITzGy3+u4vUujPkabyaz+03F24NWEX7fs5fp+kBonlaqPH8fAO2NM+SXt/JA==
- dependencies:
- filename-reserved-regex "^2.0.0"
- strip-outer "^1.0.0"
- trim-repeated "^1.0.0"
-
-filenamify@^4.1.0:
- version "4.3.0"
- resolved "https://registry.yarnpkg.com/filenamify/-/filenamify-4.3.0.tgz#62391cb58f02b09971c9d4f9d63b3cf9aba03106"
- integrity sha512-hcFKyUG57yWGAzu1CMt/dPzYZuv+jAJUT85bL8mrXvNe6hWj6yEHEc4EdcgiA6Z3oi1/9wXJdZPXF2dZNgwgOg==
- dependencies:
- filename-reserved-regex "^2.0.0"
- strip-outer "^1.0.1"
- trim-repeated "^1.0.0"
-
-fill-range@^4.0.0:
- version "4.0.0"
- resolved "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz"
- integrity sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=
- dependencies:
- extend-shallow "^2.0.1"
- is-number "^3.0.0"
- repeat-string "^1.6.1"
- to-regex-range "^2.1.0"
-
-fill-range@^7.0.1:
- version "7.0.1"
- resolved "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz"
- integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==
- dependencies:
- to-regex-range "^5.0.1"
-
-finalhandler@1.1.0:
- version "1.1.0"
- resolved "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.0.tgz"
- integrity sha1-zgtoVbRYU+eRsvzGgARtiCU91/U=
- dependencies:
- debug "2.6.9"
- encodeurl "~1.0.1"
- escape-html "~1.0.3"
- on-finished "~2.3.0"
- parseurl "~1.3.2"
- statuses "~1.3.1"
- unpipe "~1.0.0"
-
-find-cache-dir@^2.1.0:
- version "2.1.0"
- resolved "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz"
- integrity sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==
- dependencies:
- commondir "^1.0.1"
- make-dir "^2.0.0"
- pkg-dir "^3.0.0"
-
-find-index@^0.1.1:
- version "0.1.1"
- resolved "https://registry.npmjs.org/find-index/-/find-index-0.1.1.tgz"
- integrity sha1-Z101iyyjiS15Whq0cjL4tuLg3eQ=
-
-find-up@^1.0.0:
- version "1.1.2"
- resolved "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz"
- integrity sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=
- dependencies:
- path-exists "^2.0.0"
- pinkie-promise "^2.0.0"
-
-find-up@^2.0.0:
- version "2.1.0"
- resolved "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz"
- integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c=
- dependencies:
- locate-path "^2.0.0"
-
-find-up@^3.0.0:
- version "3.0.0"
- resolved "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz"
- integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==
- dependencies:
- locate-path "^3.0.0"
-
-find-up@^4.1.0:
- version "4.1.0"
- resolved "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz"
- integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==
- dependencies:
- locate-path "^5.0.0"
- path-exists "^4.0.0"
-
-find-versions@^3.0.0:
- version "3.1.0"
- resolved "https://registry.npmjs.org/find-versions/-/find-versions-3.1.0.tgz"
- integrity sha512-NCTfNiVzeE/xL+roNDffGuRbrWI6atI18lTJ22vKp7rs2OhYzMK3W1dIdO2TUndH/QMcacM4d1uWwgcZcHK69Q==
- dependencies:
- array-uniq "^2.1.0"
- semver-regex "^2.0.0"
-
-findup-sync@3.0.0, findup-sync@^3.0.0:
- version "3.0.0"
- resolved "https://registry.npmjs.org/findup-sync/-/findup-sync-3.0.0.tgz"
- integrity sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==
- dependencies:
- detect-file "^1.0.0"
- is-glob "^4.0.0"
- micromatch "^3.0.4"
- resolve-dir "^1.0.1"
-
-findup-sync@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/findup-sync/-/findup-sync-2.0.0.tgz"
- integrity sha1-kyaxSIwi0aYIhlCoaQGy2akKLLw=
- dependencies:
- detect-file "^1.0.0"
- is-glob "^3.1.0"
- micromatch "^3.0.4"
- resolve-dir "^1.0.1"
-
-findup-sync@^4.0.0:
- version "4.0.0"
- resolved "https://registry.npmjs.org/findup-sync/-/findup-sync-4.0.0.tgz"
- integrity sha512-6jvvn/12IC4quLBL1KNokxC7wWTvYncaVUYSoxWw7YykPLuRrnv4qdHcSOywOI5RpkOVGeQRtWM8/q+G6W6qfQ==
- dependencies:
- detect-file "^1.0.0"
- is-glob "^4.0.0"
- micromatch "^4.0.2"
- resolve-dir "^1.0.1"
-
-fined@^1.0.1:
- version "1.2.0"
- resolved "https://registry.npmjs.org/fined/-/fined-1.2.0.tgz"
- integrity sha512-ZYDqPLGxDkDhDZBjZBb+oD1+j0rA4E0pXY50eplAAOPg2N/gUBSSk5IM1/QhPfyVo19lJ+CvXpqfvk+b2p/8Ng==
- dependencies:
- expand-tilde "^2.0.2"
- is-plain-object "^2.0.3"
- object.defaults "^1.1.0"
- object.pick "^1.2.0"
- parse-filepath "^1.0.1"
-
-first-chunk-stream@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/first-chunk-stream/-/first-chunk-stream-1.0.0.tgz"
- integrity sha1-Wb+1DNkF9g18OUzT2ayqtOatk04=
-
-flagged-respawn@^1.0.0:
- version "1.0.1"
- resolved "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.1.tgz"
- integrity sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q==
-
-flat-cache@^1.2.1:
- version "1.3.4"
- resolved "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.4.tgz"
- integrity sha512-VwyB3Lkgacfik2vhqR4uv2rvebqmDvFu4jlN/C1RzWoJEo8I7z4Q404oiqYCkq41mni8EzQnm95emU9seckwtg==
- dependencies:
- circular-json "^0.3.1"
- graceful-fs "^4.1.2"
- rimraf "~2.6.2"
- write "^0.2.1"
-
-flat-cache@^2.0.1:
- version "2.0.1"
- resolved "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz"
- integrity sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==
- dependencies:
- flatted "^2.0.0"
- rimraf "2.6.3"
- write "1.0.3"
-
-flatted@^2.0.0, flatted@^2.0.1:
- version "2.0.1"
- resolved "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz"
- integrity sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==
-
-flatten@^1.0.2:
- version "1.0.2"
- resolved "https://registry.npmjs.org/flatten/-/flatten-1.0.2.tgz"
- integrity sha1-2uRqnXj74lKSJYzB54CkHZXAN4I=
-
-flora-colossus@^1.0.0:
- version "1.0.1"
- resolved "https://registry.npmjs.org/flora-colossus/-/flora-colossus-1.0.1.tgz"
- integrity sha512-d+9na7t9FyH8gBJoNDSi28mE4NgQVGGvxQ4aHtFRetjyh5SXjuus+V5EZaxFmFdXVemSOrx0lsgEl/ZMjnOWJA==
- dependencies:
- debug "^4.1.1"
- fs-extra "^7.0.0"
-
-fluent-ffmpeg@^2.1.2:
- version "2.1.2"
- resolved "https://registry.npmjs.org/fluent-ffmpeg/-/fluent-ffmpeg-2.1.2.tgz"
- integrity sha1-yVLeIkD4EuvaCqgAbXd27irPfXQ=
- dependencies:
- async ">=0.2.9"
- which "^1.1.1"
-
-flush-write-stream@^1.0.0, flush-write-stream@^1.0.2:
- version "1.1.1"
- resolved "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz"
- integrity sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==
- dependencies:
- inherits "^2.0.3"
- readable-stream "^2.3.6"
-
-follow-redirects@1.5.10:
- version "1.5.10"
- resolved "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz"
- integrity sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==
- dependencies:
- debug "=3.1.0"
-
-follow-redirects@^1.0.0:
- version "1.12.1"
- resolved "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.12.1.tgz"
- integrity sha512-tmRv0AVuR7ZyouUHLeNSiO6pqulF7dYa3s19c6t+wz9LD69/uSzdMxJ2S91nTI9U3rt/IldxpzMOFejp6f0hjg==
-
-for-each@^0.3.3:
- version "0.3.3"
- resolved "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz"
- integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==
- dependencies:
- is-callable "^1.1.3"
-
-for-in@^1.0.1, for-in@^1.0.2:
- version "1.0.2"
- resolved "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz"
- integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=
-
-for-own@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz"
- integrity sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=
- dependencies:
- for-in "^1.0.1"
-
-forever-agent@~0.6.1:
- version "0.6.1"
- resolved "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz"
- integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=
-
-fork-stream@^0.0.4:
- version "0.0.4"
- resolved "https://registry.npmjs.org/fork-stream/-/fork-stream-0.0.4.tgz"
- integrity sha1-24Sfznf2cIpfjzhq5TOgkHtUrnA=
-
-form-data@~2.3.2:
- version "2.3.3"
- resolved "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz"
- integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==
- dependencies:
- asynckit "^0.4.0"
- combined-stream "^1.0.6"
- mime-types "^2.1.12"
-
-fragment-cache@^0.2.1:
- version "0.2.1"
- resolved "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz"
- integrity sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=
- dependencies:
- map-cache "^0.2.2"
-
-fresh@0.5.2, fresh@^0.5.2:
- version "0.5.2"
- resolved "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz"
- integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=
-
-from2@^2.1.0, from2@^2.1.1:
- version "2.3.0"
- resolved "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz"
- integrity sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=
- dependencies:
- inherits "^2.0.1"
- readable-stream "^2.0.0"
-
-front-matter@2.1.2:
- version "2.1.2"
- resolved "https://registry.npmjs.org/front-matter/-/front-matter-2.1.2.tgz"
- integrity sha1-91mDufL0E75ljJPf172M5AePXNs=
- dependencies:
- js-yaml "^3.4.6"
-
-fs-constants@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz"
- integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==
-
-fs-extra@3.0.1, fs-extra@^3.0.1:
- version "3.0.1"
- resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-3.0.1.tgz"
- integrity sha1-N5TzeMWLNC6n27sjCVEJxLO2IpE=
- dependencies:
- graceful-fs "^4.1.2"
- jsonfile "^3.0.0"
- universalify "^0.1.0"
-
-fs-extra@^10.0.0:
- version "10.0.1"
- resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.0.1.tgz#27de43b4320e833f6867cc044bfce29fdf0ef3b8"
- integrity sha512-NbdoVMZso2Lsrn/QwLXOy6rm0ufY2zEOKCDzJR/0kBsb0E6qed0P3iYK+Ath3BfvXEeu4JhEtXLgILx5psUfag==
- dependencies:
- graceful-fs "^4.2.0"
- jsonfile "^6.0.1"
- universalify "^2.0.0"
-
-fs-extra@^4.0.0:
- version "4.0.3"
- resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz"
- integrity sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==
- dependencies:
- graceful-fs "^4.1.2"
- jsonfile "^4.0.0"
- universalify "^0.1.0"
-
-fs-extra@^7.0.0:
- version "7.0.1"
- resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz"
- integrity sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==
- dependencies:
- graceful-fs "^4.1.2"
- jsonfile "^4.0.0"
- universalify "^0.1.0"
-
-fs-extra@^8.1.0:
- version "8.1.0"
- resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz"
- integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==
- dependencies:
- graceful-fs "^4.2.0"
- jsonfile "^4.0.0"
- universalify "^0.1.0"
-
-fs-extra@^9.0.0, fs-extra@^9.0.1:
- version "9.1.0"
- resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d"
- integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==
- dependencies:
- at-least-node "^1.0.0"
- graceful-fs "^4.2.0"
- jsonfile "^6.0.1"
- universalify "^2.0.0"
-
-fs-mkdirp-stream@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz"
- integrity sha1-C3gV/DIBxqaeFNuYzgmMFpNSWes=
- dependencies:
- graceful-fs "^4.1.11"
- through2 "^2.0.3"
-
-fs-write-stream-atomic@^1.0.8:
- version "1.0.10"
- resolved "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz"
- integrity sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=
- dependencies:
- graceful-fs "^4.1.2"
- iferr "^0.1.5"
- imurmurhash "^0.1.4"
- readable-stream "1 || 2"
-
-fs.realpath@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz"
- integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8=
-
-fsevents@^1.2.7:
- version "1.2.13"
- resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.13.tgz#f325cb0455592428bcf11b383370ef70e3bfcc38"
- integrity sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==
- dependencies:
- bindings "^1.5.0"
- nan "^2.12.1"
-
-fsevents@~2.1.2:
- version "2.1.3"
- resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.3.tgz#fb738703ae8d2f9fe900c33836ddebee8b97f23e"
- integrity sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==
-
-function-bind@^1.1.1:
- version "1.1.1"
- resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz"
- integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==
-
-functional-red-black-tree@^1.0.1:
- version "1.0.1"
- resolved "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz"
- integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=
-
-galactus@^0.2.1:
- version "0.2.1"
- resolved "https://registry.npmjs.org/galactus/-/galactus-0.2.1.tgz"
- integrity sha1-y+0tIKQMH1Z5o1kI4rlBVzPnjbk=
- dependencies:
- debug "^3.1.0"
- flora-colossus "^1.0.0"
- fs-extra "^4.0.0"
-
-gaze@^0.5.1:
- version "0.5.2"
- resolved "https://registry.npmjs.org/gaze/-/gaze-0.5.2.tgz"
- integrity sha1-QLcJU30k0dRXZ9takIaJ3+aaxE8=
- dependencies:
- globule "~0.1.0"
-
-generate-function@^2.0.0:
- version "2.3.1"
- resolved "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz"
- integrity sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==
- dependencies:
- is-property "^1.0.2"
-
-generate-object-property@^1.1.0:
- version "1.2.0"
- resolved "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz"
- integrity sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=
- dependencies:
- is-property "^1.0.0"
-
-gensync@^1.0.0-beta.1:
- version "1.0.0-beta.1"
- resolved "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz"
- integrity sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg==
-
-get-caller-file@^1.0.1:
- version "1.0.3"
- resolved "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz"
- integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==
-
-get-caller-file@^2.0.1:
- version "2.0.5"
- resolved "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz"
- integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==
-
-get-package-info@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/get-package-info/-/get-package-info-1.0.0.tgz"
- integrity sha1-ZDJ5ZWPigRPNlHTbvQAFKYWkmZw=
- dependencies:
- bluebird "^3.1.1"
- debug "^2.2.0"
- lodash.get "^4.0.0"
- read-pkg-up "^2.0.0"
-
-get-proxy@^2.0.0:
- version "2.1.0"
- resolved "https://registry.npmjs.org/get-proxy/-/get-proxy-2.1.0.tgz"
- integrity sha512-zmZIaQTWnNQb4R4fJUEp/FC51eZsc6EkErspy3xtIYStaq8EB/hDIWipxsal+E8rz0qD7f2sL/NA9Xee4RInJw==
- dependencies:
- npm-conf "^1.1.0"
-
-get-stdin@^4.0.1:
- version "4.0.1"
- resolved "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz"
- integrity sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=
-
-get-stream@3.0.0, get-stream@^3.0.0:
- version "3.0.0"
- resolved "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz"
- integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=
-
-get-stream@^2.2.0:
- version "2.3.1"
- resolved "https://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz"
- integrity sha1-Xzj5PzRgCWZu4BUKBUFn+Rvdld4=
- dependencies:
- object-assign "^4.0.1"
- pinkie-promise "^2.0.0"
-
-get-stream@^4.0.0, get-stream@^4.1.0:
- version "4.1.0"
- resolved "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz"
- integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==
- dependencies:
- pump "^3.0.0"
-
-get-stream@^5.0.0, get-stream@^5.1.0:
- version "5.1.0"
- resolved "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz"
- integrity sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==
- dependencies:
- pump "^3.0.0"
-
-get-stream@^6.0.0:
- version "6.0.0"
- resolved "https://registry.npmjs.org/get-stream/-/get-stream-6.0.0.tgz"
- integrity sha512-A1B3Bh1UmL0bidM/YX2NsCOTnGJePL9rO/M+Mw3m9f2gUpfokS0hi5Eah0WSUEWZdZhIZtMjkIYS7mDfOqNHbg==
-
-get-value@^2.0.3, get-value@^2.0.6:
- version "2.0.6"
- resolved "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz"
- integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=
-
-getpass@^0.1.1:
- version "0.1.7"
- resolved "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz"
- integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=
- dependencies:
- assert-plus "^1.0.0"
-
-gifsicle@^5.0.0, gifsicle@^5.2.0:
- version "5.2.0"
- resolved "https://registry.npmjs.org/gifsicle/-/gifsicle-5.2.0.tgz"
- integrity sha512-vOIS3j0XoTCxq9pkGj43gEix82RkI5FveNgaFZutjbaui/HH+4fR8Y56dwXDuxYo8hR4xOo6/j2h1WHoQW6XLw==
- dependencies:
- bin-build "^3.0.0"
- bin-wrapper "^4.0.0"
- execa "^5.0.0"
- logalot "^2.0.0"
-
-glob-all@^3.1.0:
- version "3.1.0"
- resolved "https://registry.npmjs.org/glob-all/-/glob-all-3.1.0.tgz"
- integrity sha1-iRPd+17hrHgSZWJBsD1SF8ZLAqs=
- dependencies:
- glob "^7.0.5"
- yargs "~1.2.6"
-
-glob-parent@^3.1.0:
- version "3.1.0"
- resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz"
- integrity sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=
- dependencies:
- is-glob "^3.1.0"
- path-dirname "^1.0.0"
-
-glob-parent@^5.1.0, glob-parent@~5.1.0:
- version "5.1.1"
- resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz"
- integrity sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==
- dependencies:
- is-glob "^4.0.1"
-
-glob-stream@^3.1.5:
- version "3.1.18"
- resolved "https://registry.npmjs.org/glob-stream/-/glob-stream-3.1.18.tgz"
- integrity sha1-kXCl8St5Awb9/lmPMT+PeVT9FDs=
- dependencies:
- glob "^4.3.1"
- glob2base "^0.0.12"
- minimatch "^2.0.1"
- ordered-read-streams "^0.1.0"
- through2 "^0.6.1"
- unique-stream "^1.0.0"
-
-glob-stream@^6.1.0:
- version "6.1.0"
- resolved "https://registry.npmjs.org/glob-stream/-/glob-stream-6.1.0.tgz"
- integrity sha1-cEXJlBOz65SIjYOrRtC0BMx73eQ=
- dependencies:
- extend "^3.0.0"
- glob "^7.1.1"
- glob-parent "^3.1.0"
- is-negated-glob "^1.0.0"
- ordered-read-streams "^1.0.0"
- pumpify "^1.3.5"
- readable-stream "^2.1.5"
- remove-trailing-separator "^1.0.1"
- to-absolute-glob "^2.0.0"
- unique-stream "^2.0.2"
-
-glob-watcher@^0.0.6:
- version "0.0.6"
- resolved "https://registry.npmjs.org/glob-watcher/-/glob-watcher-0.0.6.tgz"
- integrity sha1-uVtKjfdLOcgymLDAXJeLTZo7cQs=
- dependencies:
- gaze "^0.5.1"
-
-glob-watcher@^5.0.3:
- version "5.0.3"
- resolved "https://registry.npmjs.org/glob-watcher/-/glob-watcher-5.0.3.tgz"
- integrity sha512-8tWsULNEPHKQ2MR4zXuzSmqbdyV5PtwwCaWSGQ1WwHsJ07ilNeN1JB8ntxhckbnpSHaf9dXFUHzIWvm1I13dsg==
- dependencies:
- anymatch "^2.0.0"
- async-done "^1.2.0"
- chokidar "^2.0.0"
- is-negated-glob "^1.0.0"
- just-debounce "^1.0.0"
- object.defaults "^1.1.0"
-
-glob2base@^0.0.12:
- version "0.0.12"
- resolved "https://registry.npmjs.org/glob2base/-/glob2base-0.0.12.tgz"
- integrity sha1-nUGbPijxLoOjYhZKJ3BVkiycDVY=
- dependencies:
- find-index "^0.1.1"
-
-glob@^4.3.1:
- version "4.5.3"
- resolved "https://registry.npmjs.org/glob/-/glob-4.5.3.tgz"
- integrity sha1-xstz0yJsHv7wTePFbQEvAzd+4V8=
- dependencies:
- inflight "^1.0.4"
- inherits "2"
- minimatch "^2.0.1"
- once "^1.3.0"
-
-glob@^6.0.4:
- version "6.0.4"
- resolved "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz"
- integrity sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=
- dependencies:
- inflight "^1.0.4"
- inherits "2"
- minimatch "2 || 3"
- once "^1.3.0"
- path-is-absolute "^1.0.0"
-
-glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.0.6, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@~7.1.1:
- version "7.1.4"
- resolved "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz"
- integrity sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==
- dependencies:
- fs.realpath "^1.0.0"
- inflight "^1.0.4"
- inherits "2"
- minimatch "^3.0.4"
- once "^1.3.0"
- path-is-absolute "^1.0.0"
-
-glob@^7.1.6:
- version "7.2.0"
- resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023"
- integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==
- dependencies:
- fs.realpath "^1.0.0"
- inflight "^1.0.4"
- inherits "2"
- minimatch "^3.0.4"
- once "^1.3.0"
- path-is-absolute "^1.0.0"
-
-glob@~3.1.21:
- version "3.1.21"
- resolved "https://registry.npmjs.org/glob/-/glob-3.1.21.tgz"
- integrity sha1-0p4KBV3qUTj00H7UDomC6DwgZs0=
- dependencies:
- graceful-fs "~1.2.0"
- inherits "1"
- minimatch "~0.2.11"
-
-glob@~3.2.6:
- version "3.2.11"
- resolved "https://registry.npmjs.org/glob/-/glob-3.2.11.tgz"
- integrity sha1-Spc/Y1uRkPcV0QmH1cAP0oFevj0=
- dependencies:
- inherits "2"
- minimatch "0.3"
-
-global-agent@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/global-agent/-/global-agent-3.0.0.tgz#ae7cd31bd3583b93c5a16437a1afe27cc33a1ab6"
- integrity sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==
- dependencies:
- boolean "^3.0.1"
- es6-error "^4.1.1"
- matcher "^3.0.0"
- roarr "^2.15.3"
- semver "^7.3.2"
- serialize-error "^7.0.1"
-
-global-modules@2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz"
- integrity sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==
- dependencies:
- global-prefix "^3.0.0"
-
-global-modules@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz"
- integrity sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==
- dependencies:
- global-prefix "^1.0.1"
- is-windows "^1.0.1"
- resolve-dir "^1.0.0"
-
-global-prefix@^1.0.1:
- version "1.0.2"
- resolved "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz"
- integrity sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=
- dependencies:
- expand-tilde "^2.0.2"
- homedir-polyfill "^1.0.1"
- ini "^1.3.4"
- is-windows "^1.0.1"
- which "^1.2.14"
-
-global-prefix@^3.0.0:
- version "3.0.0"
- resolved "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz"
- integrity sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==
- dependencies:
- ini "^1.3.5"
- kind-of "^6.0.2"
- which "^1.3.1"
-
-global-tunnel-ng@^2.7.1:
- version "2.7.1"
- resolved "https://registry.yarnpkg.com/global-tunnel-ng/-/global-tunnel-ng-2.7.1.tgz#d03b5102dfde3a69914f5ee7d86761ca35d57d8f"
- integrity sha512-4s+DyciWBV0eK148wqXxcmVAbFVPqtc3sEtUE/GTQfuU80rySLcMhUmHKSHI7/LDj8q0gDYI1lIhRRB7ieRAqg==
- dependencies:
- encodeurl "^1.0.2"
- lodash "^4.17.10"
- npm-conf "^1.1.3"
- tunnel "^0.0.6"
-
-global@~4.3.0:
- version "4.3.2"
- resolved "https://registry.npmjs.org/global/-/global-4.3.2.tgz"
- integrity sha1-52mJJopsdMOJCLEwWxD8DjlOnQ8=
- dependencies:
- min-document "^2.19.0"
- process "~0.5.1"
-
-globals@^11.1.0, globals@^11.7.0:
- version "11.12.0"
- resolved "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz"
- integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==
-
-globals@^9.18.0, globals@^9.2.0:
- version "9.18.0"
- resolved "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz"
- integrity sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==
-
-globalthis@^1.0.1:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.2.tgz#2a235d34f4d8036219f7e34929b5de9e18166b8b"
- integrity sha512-ZQnSFO1la8P7auIOQECnm0sSuoMeaSq0EEdXMBFF2QJO4uNcwbyhSgG3MruWNbFTqCLmxVwGOl7LZ9kASvHdeQ==
- dependencies:
- define-properties "^1.1.3"
-
-globby@^10.0.0:
- version "10.0.2"
- resolved "https://registry.npmjs.org/globby/-/globby-10.0.2.tgz"
- integrity sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==
- dependencies:
- "@types/glob" "^7.1.1"
- array-union "^2.1.0"
- dir-glob "^3.0.1"
- fast-glob "^3.0.3"
- glob "^7.1.3"
- ignore "^5.1.1"
- merge2 "^1.2.3"
- slash "^3.0.0"
-
-globule@^1.0.0:
- version "1.2.1"
- resolved "https://registry.npmjs.org/globule/-/globule-1.2.1.tgz"
- integrity sha512-g7QtgWF4uYSL5/dn71WxubOrS7JVGCnFPEnoeChJmBnyR9Mw8nGoEwOgJL/RC2Te0WhbsEUCejfH8SZNJ+adYQ==
- dependencies:
- glob "~7.1.1"
- lodash "~4.17.10"
- minimatch "~3.0.2"
-
-globule@~0.1.0:
- version "0.1.0"
- resolved "https://registry.npmjs.org/globule/-/globule-0.1.0.tgz"
- integrity sha1-2cjt3h2nnRJaFRt5UzuXhnY0auU=
- dependencies:
- glob "~3.1.21"
- lodash "~1.0.1"
- minimatch "~0.2.11"
-
-glogg@^1.0.0:
- version "1.0.2"
- resolved "https://registry.npmjs.org/glogg/-/glogg-1.0.2.tgz"
- integrity sha512-5mwUoSuBk44Y4EshyiqcH95ZntbDdTQqA3QYSrxmzj28Ai0vXBGMH1ApSANH14j2sIRtqCEyg6PfsuP7ElOEDA==
- dependencies:
- sparkles "^1.0.0"
-
-gonzales-pe-sl@^4.2.3:
- version "4.2.3"
- resolved "https://registry.npmjs.org/gonzales-pe-sl/-/gonzales-pe-sl-4.2.3.tgz"
- integrity sha1-aoaLw4BkXxQf7rBCxvl/zHG1n+Y=
- dependencies:
- minimist "1.1.x"
-
-gonzales-pe@^4.2.3:
- version "4.2.4"
- resolved "https://registry.npmjs.org/gonzales-pe/-/gonzales-pe-4.2.4.tgz"
- integrity sha512-v0Ts/8IsSbh9n1OJRnSfa7Nlxi4AkXIsWB6vPept8FDbL4bXn3FNuxjYtO/nmBGu7GDkL9MFeGebeSu6l55EPQ==
- dependencies:
- minimist "1.1.x"
-
-got@^7.0.0:
- version "7.1.0"
- resolved "https://registry.npmjs.org/got/-/got-7.1.0.tgz"
- integrity sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw==
- dependencies:
- decompress-response "^3.2.0"
- duplexer3 "^0.1.4"
- get-stream "^3.0.0"
- is-plain-obj "^1.1.0"
- is-retry-allowed "^1.0.0"
- is-stream "^1.0.0"
- isurl "^1.0.0-alpha5"
- lowercase-keys "^1.0.0"
- p-cancelable "^0.3.0"
- p-timeout "^1.1.1"
- safe-buffer "^5.0.1"
- timed-out "^4.0.0"
- url-parse-lax "^1.0.0"
- url-to-options "^1.0.1"
-
-got@^8.3.1:
- version "8.3.2"
- resolved "https://registry.npmjs.org/got/-/got-8.3.2.tgz"
- integrity sha512-qjUJ5U/hawxosMryILofZCkm3C84PLJS/0grRIpjAwu+Lkxxj5cxeCU25BG0/3mDSpXKTyZr8oh8wIgLaH0QCw==
- dependencies:
- "@sindresorhus/is" "^0.7.0"
- cacheable-request "^2.1.1"
- decompress-response "^3.3.0"
- duplexer3 "^0.1.4"
- get-stream "^3.0.0"
- into-stream "^3.1.0"
- is-retry-allowed "^1.1.0"
- isurl "^1.0.0-alpha5"
- lowercase-keys "^1.0.0"
- mimic-response "^1.0.0"
- p-cancelable "^0.4.0"
- p-timeout "^2.0.1"
- pify "^3.0.0"
- safe-buffer "^5.1.1"
- timed-out "^4.0.1"
- url-parse-lax "^3.0.0"
- url-to-options "^1.0.1"
-
-got@^9.6.0:
- version "9.6.0"
- resolved "https://registry.npmjs.org/got/-/got-9.6.0.tgz"
- integrity sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==
- dependencies:
- "@sindresorhus/is" "^0.14.0"
- "@szmarczak/http-timer" "^1.1.2"
- cacheable-request "^6.0.0"
- decompress-response "^3.3.0"
- duplexer3 "^0.1.4"
- get-stream "^4.1.0"
- lowercase-keys "^1.0.1"
- mimic-response "^1.0.1"
- p-cancelable "^1.0.0"
- to-readable-stream "^1.0.0"
- url-parse-lax "^3.0.0"
-
-graceful-fs@^3.0.0:
- version "3.0.12"
- resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-3.0.12.tgz"
- integrity sha512-J55gaCS4iTTJfTXIxSVw3EMQckcqkpdRv3IR7gu6sq0+tbC363Zx6KH/SEwXASK9JRbhyZmVjJEVJIOxYsB3Qg==
- dependencies:
- natives "^1.1.3"
-
-graceful-fs@^4.0.0, graceful-fs@^4.1.10, graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.2:
- version "4.2.2"
- resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz"
- integrity sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==
-
-graceful-fs@~1.2.0:
- version "1.2.3"
- resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-1.2.3.tgz"
- integrity sha1-FaSAaldUfLLS2/J/QuiajDRRs2Q=
-
-"graceful-readlink@>= 1.0.0":
- version "1.0.1"
- resolved "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz"
- integrity sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=
-
-gulp-audiosprite@^1.1.0:
- version "1.1.0"
- resolved "https://registry.npmjs.org/gulp-audiosprite/-/gulp-audiosprite-1.1.0.tgz"
- integrity sha512-CwSfZjmNPlTyzcAFaE8RiKzh1dQFDLPPZMHshKwvGqNeTB86s30K8hMXGrrjFqHNF9xb0SUnXfbYT32MO4aNog==
- dependencies:
- audiosprite "*"
- through2 "*"
- vinyl "*"
-
-gulp-cache@^1.1.3:
- version "1.1.3"
- resolved "https://registry.npmjs.org/gulp-cache/-/gulp-cache-1.1.3.tgz"
- integrity sha512-NE814LdX1NWQn2sMzn+Rf673o4mqlgg7OyLf92oQ4KEl6DdPfduEGLNH+HexLVcFZXH93DBuxFOvpv4/Js5VaA==
- dependencies:
- "@babel/runtime" "^7.5.5"
- cache-swap "^0.3.0"
- core-js "3"
- object.pick "^1.3.0"
- plugin-error "^1.0.1"
- through2 "3.0.1"
- vinyl "^2.2.0"
-
-gulp-cached@^1.1.1:
- version "1.1.1"
- resolved "https://registry.npmjs.org/gulp-cached/-/gulp-cached-1.1.1.tgz"
- integrity sha1-/nzU+H83YB5gc8/t7lwr2vi2rM4=
- dependencies:
- lodash.defaults "^4.2.0"
- through2 "^2.0.1"
-
-gulp-clean@^0.4.0:
- version "0.4.0"
- resolved "https://registry.npmjs.org/gulp-clean/-/gulp-clean-0.4.0.tgz"
- integrity sha512-DARK8rNMo4lHOFLGTiHEJdf19GuoBDHqGUaypz+fOhrvOs3iFO7ntdYtdpNxv+AzSJBx/JfypF0yEj9ks1IStQ==
- dependencies:
- fancy-log "^1.3.2"
- plugin-error "^0.1.2"
- rimraf "^2.6.2"
- through2 "^2.0.3"
- vinyl "^2.1.0"
-
-gulp-cli@^2.2.0:
- version "2.3.0"
- resolved "https://registry.npmjs.org/gulp-cli/-/gulp-cli-2.3.0.tgz"
- integrity sha512-zzGBl5fHo0EKSXsHzjspp3y5CONegCm8ErO5Qh0UzFzk2y4tMvzLWhoDokADbarfZRL2pGpRp7yt6gfJX4ph7A==
- dependencies:
- ansi-colors "^1.0.1"
- archy "^1.0.0"
- array-sort "^1.0.0"
- color-support "^1.1.3"
- concat-stream "^1.6.0"
- copy-props "^2.0.1"
- fancy-log "^1.3.2"
- gulplog "^1.0.0"
- interpret "^1.4.0"
- isobject "^3.0.1"
- liftoff "^3.1.0"
- matchdep "^2.0.0"
- mute-stdout "^1.0.0"
- pretty-hrtime "^1.0.0"
- replace-homedir "^1.0.0"
- semver-greatest-satisfied-range "^1.1.0"
- v8flags "^3.2.0"
- yargs "^7.1.0"
-
-gulp-dart-sass@^1.0.2:
- version "1.0.2"
- resolved "https://registry.npmjs.org/gulp-dart-sass/-/gulp-dart-sass-1.0.2.tgz"
- integrity sha512-8fLttA824mbuc0jRVlGs00zWYZXBckat6INawx5kp66Eqsz5srNWTA51t0mbfB4C8a/a/GZ9muYLwXGklgAHlw==
- dependencies:
- chalk "^2.3.0"
- lodash.clonedeep "^4.3.2"
- plugin-error "^1.0.1"
- replace-ext "^1.0.0"
- sass "^1.26.3"
- strip-ansi "^4.0.0"
- through2 "^2.0.0"
- vinyl-sourcemaps-apply "^0.2.0"
-
-gulp-dom@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/gulp-dom/-/gulp-dom-1.0.0.tgz"
- integrity sha512-hD2w2t3fsjPicX2mT6MFFb+eP3FyCVtEHdejGMMH4+w9EBFxA2xIZadqlzYdAEdE+39dP1aGatuhdHJteUvn1A==
- dependencies:
- jsdom "12.2.0"
- plugin-error "1.0.1"
- through2 "2.0.3"
-
-gulp-flatten@^0.4.0:
- version "0.4.0"
- resolved "https://registry.npmjs.org/gulp-flatten/-/gulp-flatten-0.4.0.tgz"
- integrity sha512-eg4spVTAiv1xXmugyaCxWne1oPtNG0UHEtABx5W8ScLiqAYceyYm6GYA36x0Qh8KOIXmAZV97L2aYGnKREG3Sg==
- dependencies:
- plugin-error "^0.1.2"
- through2 "^2.0.0"
-
-gulp-fluent-ffmpeg@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/gulp-fluent-ffmpeg/-/gulp-fluent-ffmpeg-2.0.0.tgz"
- integrity sha512-pwG6N+NKwLzO/0ybzgcwiADKZ4OzpFjNR4drqCvbvluYcSh/yvsAW7wm63jFzpJIjfFnanYGPNWiUn8+TuTR/g==
- dependencies:
- concat-stream "^2.0.0"
- fluent-ffmpeg "^2.1.2"
- plugin-error "^1.0.1"
- through2 "^3.0.1"
-
-gulp-html-beautify@^1.0.1:
- version "1.0.1"
- resolved "https://registry.npmjs.org/gulp-html-beautify/-/gulp-html-beautify-1.0.1.tgz"
- integrity sha1-KDTG93ZpYFcm7uVeMgX2MHS3oVI=
- dependencies:
- js-beautify "^1.5.10"
- rcloader "^0.1.4"
- through2 "^2.0.0"
-
-gulp-htmlmin@^5.0.1:
- version "5.0.1"
- resolved "https://registry.npmjs.org/gulp-htmlmin/-/gulp-htmlmin-5.0.1.tgz"
- integrity sha512-ASlyDPZOSKjHYUifYV0rf9JPDflN9IRIb8lw2vRqtYMC4ljU3zAmnnaVXwFQ3H+CfXxZSUesZ2x7jrnPJu93jA==
- dependencies:
- html-minifier "^3.5.20"
- plugin-error "^1.0.1"
- through2 "^2.0.3"
-
-gulp-if@^3.0.0:
- version "3.0.0"
- resolved "https://registry.npmjs.org/gulp-if/-/gulp-if-3.0.0.tgz"
- integrity sha512-fCUEngzNiEZEK2YuPm+sdMpO6ukb8+/qzbGfJBXyNOXz85bCG7yBI+pPSl+N90d7gnLvMsarthsAImx0qy7BAw==
- dependencies:
- gulp-match "^1.1.0"
- ternary-stream "^3.0.0"
- through2 "^3.0.1"
-
-gulp-imagemin@^7.1.0:
- version "7.1.0"
- resolved "https://registry.npmjs.org/gulp-imagemin/-/gulp-imagemin-7.1.0.tgz"
- integrity sha512-6xBTNybmPY2YrvrhhlS8Mxi0zn0ypusLon63p9XXxDtIf7U7c6KcViz94K7Skosucr3378A6IY2kJSjJyuwylQ==
- dependencies:
- chalk "^3.0.0"
- fancy-log "^1.3.2"
- imagemin "^7.0.0"
- plugin-error "^1.0.1"
- plur "^3.0.1"
- pretty-bytes "^5.3.0"
- through2-concurrent "^2.0.0"
- optionalDependencies:
- imagemin-gifsicle "^7.0.0"
- imagemin-mozjpeg "^8.0.0"
- imagemin-optipng "^7.0.0"
- imagemin-svgo "^7.0.0"
-
-gulp-load-plugins@^2.0.3:
- version "2.0.3"
- resolved "https://registry.npmjs.org/gulp-load-plugins/-/gulp-load-plugins-2.0.3.tgz"
- integrity sha512-U/1Sml7UbyOu2kH6Fbpo+ka2xyp4DRH6+oDtHgC8oKsnlQRuiBQYQ/LS4k6HxBv1HJlucaNV/SdwZXtLBuvSqg==
- dependencies:
- array-unique "^0.3.2"
- fancy-log "^1.2.0"
- findup-sync "^4.0.0"
- gulplog "^1.0.0"
- has-gulplog "^0.1.0"
- micromatch "^4.0.2"
- resolve "^1.15.1"
-
-gulp-match@^1.1.0:
- version "1.1.0"
- resolved "https://registry.npmjs.org/gulp-match/-/gulp-match-1.1.0.tgz"
- integrity sha512-DlyVxa1Gj24DitY2OjEsS+X6tDpretuxD6wTfhXE/Rw2hweqc1f6D/XtsJmoiCwLWfXgR87W9ozEityPCVzGtQ==
- dependencies:
- minimatch "^3.0.3"
-
-gulp-phonegap-build@^0.1.5:
- version "0.1.5"
- resolved "https://registry.npmjs.org/gulp-phonegap-build/-/gulp-phonegap-build-0.1.5.tgz"
- integrity sha1-NsFF5jzSBHAr4PO5m+GeCWcSvK8=
- dependencies:
- archiver "~0.11.0"
- gulp "~3.8.7"
- gulp-util "~3.0.0"
- lodash "~2.4.1"
- needle ""
- read "~1.0.4"
- through2 "~0.6.1"
- vinyl-buffer "0.0.0"
- vinyl-source-stream "^0.1.1"
-
-gulp-plumber@^1.2.1:
- version "1.2.1"
- resolved "https://registry.npmjs.org/gulp-plumber/-/gulp-plumber-1.2.1.tgz"
- integrity sha512-mctAi9msEAG7XzW5ytDVZ9PxWMzzi1pS2rBH7lA095DhMa6KEXjm+St0GOCc567pJKJ/oCvosVAZEpAey0q2eQ==
- dependencies:
- chalk "^1.1.3"
- fancy-log "^1.3.2"
- plugin-error "^0.1.2"
- through2 "^2.0.3"
-
-gulp-pngquant@^1.0.13:
- version "1.0.13"
- resolved "https://registry.npmjs.org/gulp-pngquant/-/gulp-pngquant-1.0.13.tgz"
- integrity sha512-oSo5Rw2Rb10eyGhc8XKbghq6yteMmxvsSAKGOZU0ssbylMHk3WoTWcEpNg0YWMyRjrY913y+B+PA4wHM1AL2wA==
- dependencies:
- chalk "^3.0.0"
- fancy-log "^1.3.3"
- plugin-error "^1.0.1"
- pngquant-bin "^5.0.2"
- through2 "^3.0.1"
-
-gulp-postcss@^8.0.0:
- version "8.0.0"
- resolved "https://registry.npmjs.org/gulp-postcss/-/gulp-postcss-8.0.0.tgz"
- integrity sha512-Wtl6vH7a+8IS/fU5W9IbOpcaLqKxd5L1DUOzaPmlnCbX1CrG0aWdwVnC3Spn8th0m8D59YbysV5zPUe1n/GJYg==
- dependencies:
- fancy-log "^1.3.2"
- plugin-error "^1.0.1"
- postcss "^7.0.2"
- postcss-load-config "^2.0.0"
- vinyl-sourcemaps-apply "^0.2.1"
-
-gulp-rename@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/gulp-rename/-/gulp-rename-2.0.0.tgz"
- integrity sha512-97Vba4KBzbYmR5VBs9mWmK+HwIf5mj+/zioxfZhOKeXtx5ZjBk57KFlePf5nxq9QsTtFl0ejnHE3zTC9MHXqyQ==
-
-gulp-sass-lint@^1.4.0:
- version "1.4.0"
- resolved "https://registry.npmjs.org/gulp-sass-lint/-/gulp-sass-lint-1.4.0.tgz"
- integrity sha512-XerYvHx7rznInkedMw5Ayif+p8EhysOVHUBvlgUa0FSl88H2cjNjaRZ3NGn5Efmp+2HxpXp4NHqMIbOSdwef3A==
- dependencies:
- plugin-error "^0.1.2"
- sass-lint "^1.12.0"
- through2 "^2.0.2"
-
-"gulp-sftp@git+https://git@github.com/webksde/gulp-sftp":
- version "0.1.6"
- resolved "git+https://git@github.com/webksde/gulp-sftp.git#c8dfb20e290477eeed66a867406576d0c3d4fc6b"
- dependencies:
- async "~0.9.0"
- gulp-util "~3.0.0"
- object-assign "~0.3.1"
- parents "~1.0.0"
- ssh2 "~0.6.1"
- through2 "~0.4.2"
-
-gulp-terser@^1.2.0:
- version "1.2.0"
- resolved "https://registry.npmjs.org/gulp-terser/-/gulp-terser-1.2.0.tgz"
- integrity sha512-lf+jE2DALg2w32p0HRiYMlFYRYelKZPNunHp2pZccCYrrdCLOs0ItbZcN63yr2pbz116IyhUG9mD/QbtRO1FKA==
- dependencies:
- plugin-error "^1.0.1"
- terser "^4.0.0"
- through2 "^3.0.1"
- vinyl-sourcemaps-apply "^0.2.1"
-
-gulp-util@^2.2.19:
- version "2.2.20"
- resolved "https://registry.npmjs.org/gulp-util/-/gulp-util-2.2.20.tgz"
- integrity sha1-1xRuVyiRC9jwR6awseVJvCLb1kw=
- dependencies:
- chalk "^0.5.0"
- dateformat "^1.0.7-1.2.3"
- lodash._reinterpolate "^2.4.1"
- lodash.template "^2.4.1"
- minimist "^0.2.0"
- multipipe "^0.1.0"
- through2 "^0.5.0"
- vinyl "^0.2.1"
-
-gulp-util@^3.0.0, gulp-util@~3.0.0:
- version "3.0.8"
- resolved "https://registry.npmjs.org/gulp-util/-/gulp-util-3.0.8.tgz"
- integrity sha1-AFTh50RQLifATBh8PsxQXdVLu08=
- dependencies:
- array-differ "^1.0.0"
- array-uniq "^1.0.2"
- beeper "^1.0.0"
- chalk "^1.0.0"
- dateformat "^2.0.0"
- fancy-log "^1.1.0"
- gulplog "^1.0.0"
- has-gulplog "^0.1.0"
- lodash._reescape "^3.0.0"
- lodash._reevaluate "^3.0.0"
- lodash._reinterpolate "^3.0.0"
- lodash.template "^3.0.0"
- minimist "^1.1.0"
- multipipe "^0.1.2"
- object-assign "^3.0.0"
- replace-ext "0.0.1"
- through2 "^2.0.0"
- vinyl "^0.5.0"
-
-gulp-webserver@^0.9.1:
- version "0.9.1"
- resolved "https://registry.npmjs.org/gulp-webserver/-/gulp-webserver-0.9.1.tgz"
- integrity sha1-4JmSFl2XxYZWFtZCoWAVKbA2cGQ=
- dependencies:
- connect "^3.0.1"
- connect-livereload "^0.4.0"
- gulp-util "^2.2.19"
- isarray "0.0.1"
- node.extend "^1.0.10"
- open "^0.0.5"
- proxy-middleware "^0.5.0"
- serve-index "^1.1.4"
- serve-static "^1.3.0"
- through2 "^0.5.1"
- tiny-lr "0.1.4"
- watch "^0.11.0"
-
-gulp-yaml@^2.0.4:
- version "2.0.4"
- resolved "https://registry.npmjs.org/gulp-yaml/-/gulp-yaml-2.0.4.tgz"
- integrity sha512-S/9Ib8PO+jGkCvWDwBUkmFkeW7QM0pp4PO8NNrMEfWo5Sk30P+KqpyXc4055L/vOX326T/b9MhM4nw5EenyX9g==
- dependencies:
- bufferstreams "^2.0.1"
- js-yaml "^3.13.1"
- object-assign "^4.1.1"
- plugin-error "^1.0.1"
- replace-ext "^1.0.0"
- through2 "^3.0.0"
-
-gulp@^4.0.2:
- version "4.0.2"
- resolved "https://registry.npmjs.org/gulp/-/gulp-4.0.2.tgz"
- integrity sha512-dvEs27SCZt2ibF29xYgmnwwCYZxdxhQ/+LFWlbAW8y7jt68L/65402Lz3+CKy0Ov4rOs+NERmDq7YlZaDqUIfA==
- dependencies:
- glob-watcher "^5.0.3"
- gulp-cli "^2.2.0"
- undertaker "^1.2.1"
- vinyl-fs "^3.0.0"
-
-gulp@~3.8.7:
- version "3.8.11"
- resolved "https://registry.npmjs.org/gulp/-/gulp-3.8.11.tgz"
- integrity sha1-1Vfgpyg+tBNkkZabBJd2eXLx0oo=
- dependencies:
- archy "^1.0.0"
- chalk "^0.5.0"
- deprecated "^0.0.1"
- gulp-util "^3.0.0"
- interpret "^0.3.2"
- liftoff "^2.0.1"
- minimist "^1.1.0"
- orchestrator "^0.3.0"
- pretty-hrtime "^0.2.0"
- semver "^4.1.0"
- tildify "^1.0.0"
- v8flags "^2.0.2"
- vinyl-fs "^0.3.0"
-
-gulplog@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/gulplog/-/gulplog-1.0.0.tgz"
- integrity sha1-4oxNRdBey77YGDY86PnFkmIp/+U=
- dependencies:
- glogg "^1.0.0"
-
-har-schema@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz"
- integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=
-
-har-validator@~5.1.0:
- version "5.1.3"
- resolved "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz"
- integrity sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==
- dependencies:
- ajv "^6.5.5"
- har-schema "^2.0.0"
-
-has-ansi@^0.1.0:
- version "0.1.0"
- resolved "https://registry.npmjs.org/has-ansi/-/has-ansi-0.1.0.tgz"
- integrity sha1-hPJlqujA5qiKEtcCKJS3VoiUxi4=
- dependencies:
- ansi-regex "^0.2.0"
-
-has-ansi@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz"
- integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=
- dependencies:
- ansi-regex "^2.0.0"
-
-has-binary2@~1.0.2:
- version "1.0.3"
- resolved "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.3.tgz"
- integrity sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw==
- dependencies:
- isarray "2.0.1"
-
-has-cors@1.1.0:
- version "1.1.0"
- resolved "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz"
- integrity sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=
-
-has-flag@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz"
- integrity sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=
-
-has-flag@^3.0.0:
- version "3.0.0"
- resolved "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz"
- integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0=
-
-has-flag@^4.0.0:
- version "4.0.0"
- resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz"
- integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==
-
-has-gulplog@^0.1.0:
- version "0.1.0"
- resolved "https://registry.npmjs.org/has-gulplog/-/has-gulplog-0.1.0.tgz"
- integrity sha1-ZBTIKRNpfaUVkDl9r7EvIpZ4Ec4=
- dependencies:
- sparkles "^1.0.0"
-
-has-symbol-support-x@^1.4.1:
- version "1.4.2"
- resolved "https://registry.npmjs.org/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz"
- integrity sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==
-
-has-symbols@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz"
- integrity sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=
-
-has-to-string-tag-x@^1.2.0:
- version "1.4.1"
- resolved "https://registry.npmjs.org/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz"
- integrity sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==
- dependencies:
- has-symbol-support-x "^1.4.1"
-
-has-value@^0.3.1:
- version "0.3.1"
- resolved "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz"
- integrity sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=
- dependencies:
- get-value "^2.0.3"
- has-values "^0.1.4"
- isobject "^2.0.0"
-
-has-value@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz"
- integrity sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=
- dependencies:
- get-value "^2.0.6"
- has-values "^1.0.0"
- isobject "^3.0.0"
-
-has-values@^0.1.4:
- version "0.1.4"
- resolved "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz"
- integrity sha1-bWHeldkd/Km5oCCJrThL/49it3E=
-
-has-values@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz"
- integrity sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=
- dependencies:
- is-number "^3.0.0"
- kind-of "^4.0.0"
-
-has@^1.0.0, has@^1.0.1, has@^1.0.3:
- version "1.0.3"
- resolved "https://registry.npmjs.org/has/-/has-1.0.3.tgz"
- integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==
- dependencies:
- function-bind "^1.1.1"
-
-hash-base@^3.0.0:
- version "3.0.4"
- resolved "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz"
- integrity sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=
- dependencies:
- inherits "^2.0.1"
- safe-buffer "^5.0.1"
-
-hash.js@^1.0.0, hash.js@^1.0.3:
- version "1.1.7"
- resolved "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz"
- integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==
- dependencies:
- inherits "^2.0.3"
- minimalistic-assert "^1.0.1"
-
-he@1.2.x:
- version "1.2.0"
- resolved "https://registry.npmjs.org/he/-/he-1.2.0.tgz"
- integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==
-
-hex-color-regex@^1.1.0:
- version "1.1.0"
- resolved "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz"
- integrity sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==
-
-hmac-drbg@^1.0.0:
- version "1.0.1"
- resolved "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz"
- integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=
- dependencies:
- hash.js "^1.0.3"
- minimalistic-assert "^1.0.0"
- minimalistic-crypto-utils "^1.0.1"
-
-home-or-tmp@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz"
- integrity sha1-42w/LSyufXRqhX440Y1fMqeILbg=
- dependencies:
- os-homedir "^1.0.0"
- os-tmpdir "^1.0.1"
-
-homedir-polyfill@^1.0.1:
- version "1.0.3"
- resolved "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz"
- integrity sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==
- dependencies:
- parse-passwd "^1.0.0"
-
-hosted-git-info@^2.1.4:
- version "2.8.4"
- resolved "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.4.tgz"
- integrity sha512-pzXIvANXEFrc5oFFXRMkbLPQ2rXRoDERwDLyrcUxGhaZhgP54BBSl9Oheh7Vv0T090cszWBxPjkQQ5Sq1PbBRQ==
-
-howler@^2.1.2:
- version "2.1.2"
- resolved "https://registry.npmjs.org/howler/-/howler-2.1.2.tgz"
- integrity sha512-oKrTFaVXsDRoB/jik7cEpWKTj7VieoiuzMYJ7E/EU5ayvmpRhumCv3YQ3823zi9VTJkSWAhbryHnlZAionGAJg==
-
-hsl-regex@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/hsl-regex/-/hsl-regex-1.0.0.tgz"
- integrity sha1-1JMwx4ntgZ4nakwNJy3/owsY/m4=
-
-hsla-regex@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/hsla-regex/-/hsla-regex-1.0.0.tgz"
- integrity sha1-wc56MWjIxmFAM6S194d/OyJfnDg=
-
-html-comment-regex@^1.1.0:
- version "1.1.2"
- resolved "https://registry.npmjs.org/html-comment-regex/-/html-comment-regex-1.1.2.tgz"
- integrity sha512-P+M65QY2JQ5Y0G9KKdlDpo0zK+/OHptU5AaBwUfAIDJZk1MYf32Frm84EcOytfJE0t5JvkAnKlmjsXDnWzCJmQ==
-
-html-encoding-sniffer@^1.0.2:
- version "1.0.2"
- resolved "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz"
- integrity sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==
- dependencies:
- whatwg-encoding "^1.0.1"
-
-html-loader@^0.5.5:
- version "0.5.5"
- resolved "https://registry.npmjs.org/html-loader/-/html-loader-0.5.5.tgz"
- integrity sha512-7hIW7YinOYUpo//kSYcPB6dCKoceKLmOwjEMmhIobHuWGDVl0Nwe4l68mdG/Ru0wcUxQjVMEoZpkalZ/SE7zog==
- dependencies:
- es6-templates "^0.2.3"
- fastparse "^1.1.1"
- html-minifier "^3.5.8"
- loader-utils "^1.1.0"
- object-assign "^4.1.1"
-
-html-minifier@^3.5.20, html-minifier@^3.5.8:
- version "3.5.21"
- resolved "https://registry.npmjs.org/html-minifier/-/html-minifier-3.5.21.tgz"
- integrity sha512-LKUKwuJDhxNa3uf/LPR/KVjm/l3rBqtYeCOAekvG8F1vItxMUpueGd94i/asDDr8/1u7InxzFA5EeGjhhG5mMA==
- dependencies:
- camel-case "3.0.x"
- clean-css "4.2.x"
- commander "2.17.x"
- he "1.2.x"
- param-case "2.1.x"
- relateurl "0.2.x"
- uglify-js "3.4.x"
-
-http-cache-semantics@3.8.1:
- version "3.8.1"
- resolved "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz"
- integrity sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w==
-
-http-cache-semantics@^4.0.0:
- version "4.0.3"
- resolved "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.0.3.tgz"
- integrity sha512-TcIMG3qeVLgDr1TEd2XvHaTnMPwYQUQMIBLy+5pLSDKYFc7UIqj39w8EGzZkaxoLv/l2K8HaI0t5AVA+YYgUew==
-
-http-errors@1.7.3:
- version "1.7.3"
- resolved "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz"
- integrity sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==
- dependencies:
- depd "~1.1.2"
- inherits "2.0.4"
- setprototypeof "1.1.1"
- statuses ">= 1.5.0 < 2"
- toidentifier "1.0.0"
-
-http-errors@~1.6.2:
- version "1.6.3"
- resolved "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz"
- integrity sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=
- dependencies:
- depd "~1.1.2"
- inherits "2.0.3"
- setprototypeof "1.1.0"
- statuses ">= 1.4.0 < 2"
-
-"http-parser-js@>=0.4.0 <0.4.11":
- version "0.4.10"
- resolved "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.4.10.tgz"
- integrity sha1-ksnBN0w1CF912zWexWzCV8u5P6Q=
-
-http-proxy@^1.18.1:
- version "1.18.1"
- resolved "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz"
- integrity sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==
- dependencies:
- eventemitter3 "^4.0.0"
- follow-redirects "^1.0.0"
- requires-port "^1.0.0"
-
-http-signature@~1.2.0:
- version "1.2.0"
- resolved "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz"
- integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=
- dependencies:
- assert-plus "^1.0.0"
- jsprim "^1.2.2"
- sshpk "^1.7.0"
-
-https-browserify@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz"
- integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=
-
-human-signals@^1.1.1:
- version "1.1.1"
- resolved "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz"
- integrity sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==
-
-human-signals@^2.1.0:
- version "2.1.0"
- resolved "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz"
- integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==
-
-iconv-lite@0.4.24, iconv-lite@^0.4.24, iconv-lite@^0.4.4:
- version "0.4.24"
- resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz"
- integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==
- dependencies:
- safer-buffer ">= 2.1.2 < 3"
-
-iconv-lite@0.4.4:
- version "0.4.4"
- resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.4.tgz"
- integrity sha1-6V8uQdsHNfwhZS94J6XuMuY8g6g=
-
-ieee754@^1.1.4:
- version "1.1.13"
- resolved "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz"
- integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==
-
-iferr@^0.1.5:
- version "0.1.5"
- resolved "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz"
- integrity sha1-xg7taebY/bazEEofy8ocGS3FtQE=
-
-ignore-loader@^0.1.2:
- version "0.1.2"
- resolved "https://registry.npmjs.org/ignore-loader/-/ignore-loader-0.1.2.tgz"
- integrity sha1-2B8kA3bQuk8Nd4lyw60lh0EXpGM=
-
-ignore@^3.1.2:
- version "3.3.10"
- resolved "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz"
- integrity sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==
-
-ignore@^4.0.6:
- version "4.0.6"
- resolved "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz"
- integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==
-
-ignore@^5.1.1:
- version "5.1.8"
- resolved "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz"
- integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==
-
-imagemin-gifsicle@^7.0.0:
- version "7.0.0"
- resolved "https://registry.npmjs.org/imagemin-gifsicle/-/imagemin-gifsicle-7.0.0.tgz"
- integrity sha512-LaP38xhxAwS3W8PFh4y5iQ6feoTSF+dTAXFRUEYQWYst6Xd+9L/iPk34QGgK/VO/objmIlmq9TStGfVY2IcHIA==
- dependencies:
- execa "^1.0.0"
- gifsicle "^5.0.0"
- is-gif "^3.0.0"
-
-imagemin-jpegtran@^7.0.0:
- version "7.0.0"
- resolved "https://registry.npmjs.org/imagemin-jpegtran/-/imagemin-jpegtran-7.0.0.tgz"
- integrity sha512-MJoyTCW8YjMJf56NorFE41SR/WkaGA3IYk4JgvMlRwguJEEd3PnP9UxA8Y2UWjquz8d+On3Ds/03ZfiiLS8xTQ==
- dependencies:
- exec-buffer "^3.0.0"
- is-jpg "^2.0.0"
- jpegtran-bin "^5.0.0"
-
-imagemin-mozjpeg@^8.0.0:
- version "8.0.0"
- resolved "https://registry.npmjs.org/imagemin-mozjpeg/-/imagemin-mozjpeg-8.0.0.tgz"
- integrity sha512-+EciPiIjCb8JWjQNr1q8sYWYf7GDCNDxPYnkD11TNIjjWNzaV+oTg4DpOPQjl5ZX/KRCPMEgS79zLYAQzLitIA==
- dependencies:
- execa "^1.0.0"
- is-jpg "^2.0.0"
- mozjpeg "^6.0.0"
-
-imagemin-optipng@^7.0.0:
- version "7.1.0"
- resolved "https://registry.npmjs.org/imagemin-optipng/-/imagemin-optipng-7.1.0.tgz"
- integrity sha512-JNORTZ6j6untH7e5gF4aWdhDCxe3ODsSLKs/f7Grewy3ebZpl1ZsU+VUTPY4rzeHgaFA8GSWOoA8V2M3OixWZQ==
- dependencies:
- exec-buffer "^3.0.0"
- is-png "^2.0.0"
- optipng-bin "^6.0.0"
-
-imagemin-pngquant@^9.0.0:
- version "9.0.0"
- resolved "https://registry.npmjs.org/imagemin-pngquant/-/imagemin-pngquant-9.0.0.tgz"
- integrity sha512-9cqnTEaJwAHWUi+8EMTB3NUouWToCWxtL+QnoYr8bfVwuKilHvRVWKsa9lt+0c3aWaGxCAkHs++j8qINvSqomA==
- dependencies:
- execa "^4.0.0"
- is-png "^2.0.0"
- is-stream "^2.0.0"
- ow "^0.17.0"
- pngquant-bin "^6.0.0"
-
-imagemin-svgo@^7.0.0:
- version "7.0.0"
- resolved "https://registry.npmjs.org/imagemin-svgo/-/imagemin-svgo-7.0.0.tgz"
- integrity sha512-+iGJFaPIMx8TjFW6zN+EkOhlqcemdL7F3N3Y0wODvV2kCUBuUtZK7DRZc1+Zfu4U2W/lTMUyx2G8YMOrZntIWg==
- dependencies:
- is-svg "^3.0.0"
- svgo "^1.0.5"
-
-imagemin@^7.0.0:
- version "7.0.1"
- resolved "https://registry.npmjs.org/imagemin/-/imagemin-7.0.1.tgz"
- integrity sha512-33AmZ+xjZhg2JMCe+vDf6a9mzWukE7l+wAtesjE7KyteqqKjzxv7aVQeWnul1Ve26mWvEQqyPwl0OctNBfSR9w==
- dependencies:
- file-type "^12.0.0"
- globby "^10.0.0"
- graceful-fs "^4.2.2"
- junk "^3.1.0"
- make-dir "^3.0.0"
- p-pipe "^3.0.0"
- replace-ext "^1.0.0"
-
-immutable@^3:
- version "3.8.2"
- resolved "https://registry.npmjs.org/immutable/-/immutable-3.8.2.tgz"
- integrity sha1-wkOZUUVbs5kT2vKBN28VMOEErfM=
-
-import-cwd@^2.0.0:
- version "2.1.0"
- resolved "https://registry.npmjs.org/import-cwd/-/import-cwd-2.1.0.tgz"
- integrity sha1-qmzzbnInYShcs3HsZRn1PiQ1sKk=
- dependencies:
- import-from "^2.1.0"
-
-import-fresh@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz"
- integrity sha1-2BNVwVYS04bGH53dOSLUMEgipUY=
- dependencies:
- caller-path "^2.0.0"
- resolve-from "^3.0.0"
-
-import-fresh@^3.0.0:
- version "3.1.0"
- resolved "https://registry.npmjs.org/import-fresh/-/import-fresh-3.1.0.tgz"
- integrity sha512-PpuksHKGt8rXfWEr9m9EHIpgyyaltBy8+eF6GJM0QCAxMgxCfucMF3mjecK2QsJr0amJW7gTqh5/wht0z2UhEQ==
- dependencies:
- parent-module "^1.0.0"
- resolve-from "^4.0.0"
-
-import-from@^2.1.0:
- version "2.1.0"
- resolved "https://registry.npmjs.org/import-from/-/import-from-2.1.0.tgz"
- integrity sha1-M1238qev/VOqpHHUuAId7ja387E=
- dependencies:
- resolve-from "^3.0.0"
-
-import-lazy@^3.1.0:
- version "3.1.0"
- resolved "https://registry.npmjs.org/import-lazy/-/import-lazy-3.1.0.tgz"
- integrity sha512-8/gvXvX2JMn0F+CDlSC4l6kOmVaLOO3XLkksI7CI3Ud95KDYJuYur2b9P/PUt/i/pDAMd/DulQsNbbbmRRsDIQ==
-
-import-local@2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz"
- integrity sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==
- dependencies:
- pkg-dir "^3.0.0"
- resolve-cwd "^2.0.0"
-
-imurmurhash@^0.1.4:
- version "0.1.4"
- resolved "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz"
- integrity sha1-khi5srkoojixPcT7a21XbyMUU+o=
-
-indent-string@^2.1.0:
- version "2.1.0"
- resolved "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz"
- integrity sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=
- dependencies:
- repeating "^2.0.0"
-
-indexes-of@^1.0.1:
- version "1.0.1"
- resolved "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz"
- integrity sha1-8w9xbI4r00bHtn0985FVZqfAVgc=
-
-indexof@0.0.1:
- version "0.0.1"
- resolved "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz"
- integrity sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=
-
-infer-owner@^1.0.3:
- version "1.0.4"
- resolved "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz"
- integrity sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==
-
-inflight@^1.0.4:
- version "1.0.6"
- resolved "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz"
- integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=
- dependencies:
- once "^1.3.0"
- wrappy "1"
-
-inherits@1:
- version "1.0.2"
- resolved "https://registry.npmjs.org/inherits/-/inherits-1.0.2.tgz"
- integrity sha1-ykMJ2t7mtUzAuNJH6NfHoJdb3Js=
-
-inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.1, inherits@~2.0.3, inherits@~2.0.4:
- version "2.0.4"
- resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz"
- integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
-
-inherits@2.0.1:
- version "2.0.1"
- resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz"
- integrity sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=
-
-inherits@2.0.3:
- version "2.0.3"
- resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz"
- integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=
-
-ini@^1.3.4, ini@^1.3.5:
- version "1.3.5"
- resolved "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz"
- integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==
-
-inquirer@^0.12.0:
- version "0.12.0"
- resolved "https://registry.npmjs.org/inquirer/-/inquirer-0.12.0.tgz"
- integrity sha1-HvK/1jUE3wvHV4X/+MLEHfEvB34=
- dependencies:
- ansi-escapes "^1.1.0"
- ansi-regex "^2.0.0"
- chalk "^1.0.0"
- cli-cursor "^1.0.1"
- cli-width "^2.0.0"
- figures "^1.3.5"
- lodash "^4.3.0"
- readline2 "^1.0.1"
- run-async "^0.1.0"
- rx-lite "^3.1.2"
- string-width "^1.0.1"
- strip-ansi "^3.0.0"
- through "^2.3.6"
-
-inquirer@^6.2.2:
- version "6.5.2"
- resolved "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz"
- integrity sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==
- dependencies:
- ansi-escapes "^3.2.0"
- chalk "^2.4.2"
- cli-cursor "^2.1.0"
- cli-width "^2.0.0"
- external-editor "^3.0.3"
- figures "^2.0.0"
- lodash "^4.17.12"
- mute-stream "0.0.7"
- run-async "^2.2.0"
- rxjs "^6.4.0"
- string-width "^2.1.0"
- strip-ansi "^5.1.0"
- through "^2.3.6"
-
-interpret@1.2.0:
- version "1.2.0"
- resolved "https://registry.npmjs.org/interpret/-/interpret-1.2.0.tgz"
- integrity sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw==
-
-interpret@^0.3.2:
- version "0.3.10"
- resolved "https://registry.npmjs.org/interpret/-/interpret-0.3.10.tgz"
- integrity sha1-CIwl3nMcbFsRKpDwBxz69Fnlp7s=
-
-interpret@^1.4.0:
- version "1.4.0"
- resolved "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz"
- integrity sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==
-
-into-stream@^3.1.0:
- version "3.1.0"
- resolved "https://registry.npmjs.org/into-stream/-/into-stream-3.1.0.tgz"
- integrity sha1-lvsKk2wSur1v8XUqF9BWFqvQlMY=
- dependencies:
- from2 "^2.1.1"
- p-is-promise "^1.1.0"
-
-invariant@^2.2.2:
- version "2.2.4"
- resolved "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz"
- integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==
- dependencies:
- loose-envify "^1.0.0"
-
-invert-kv@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz"
- integrity sha1-EEqOSqym09jNFXqO+L+rLXo//bY=
-
-invert-kv@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz"
- integrity sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==
-
-irregular-plurals@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-2.0.0.tgz"
- integrity sha512-Y75zBYLkh0lJ9qxeHlMjQ7bSbyiSqNW/UOPWDmzC7cXskL1hekSITh1Oc6JV0XCWWZ9DE8VYSB71xocLk3gmGw==
-
-is-absolute-url@^2.0.0:
- version "2.1.0"
- resolved "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-2.1.0.tgz"
- integrity sha1-UFMN+4T8yap9vnhS6Do3uTufKqY=
-
-is-absolute@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz"
- integrity sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==
- dependencies:
- is-relative "^1.0.0"
- is-windows "^1.0.1"
-
-is-accessor-descriptor@^0.1.6:
- version "0.1.6"
- resolved "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz"
- integrity sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=
- dependencies:
- kind-of "^3.0.2"
-
-is-accessor-descriptor@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz"
- integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==
- dependencies:
- kind-of "^6.0.0"
-
-is-arrayish@^0.2.1:
- version "0.2.1"
- resolved "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz"
- integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=
-
-is-arrayish@^0.3.1:
- version "0.3.2"
- resolved "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz"
- integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==
-
-is-binary-path@^1.0.0:
- version "1.0.1"
- resolved "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz"
- integrity sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=
- dependencies:
- binary-extensions "^1.0.0"
-
-is-binary-path@~2.1.0:
- version "2.1.0"
- resolved "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz"
- integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==
- dependencies:
- binary-extensions "^2.0.0"
-
-is-buffer@^1.1.5:
- version "1.1.6"
- resolved "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz"
- integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==
-
-is-buffer@^2.0.2:
- version "2.0.3"
- resolved "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.3.tgz"
- integrity sha512-U15Q7MXTuZlrbymiz95PJpZxu8IlipAp4dtS3wOdgPXx3mqBnslrWU14kxfHB+Py/+2PVKSr37dMAgM2A4uArw==
-
-is-callable@^1.1.3, is-callable@^1.1.4:
- version "1.1.4"
- resolved "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz"
- integrity sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==
-
-is-color-stop@^1.0.0:
- version "1.1.0"
- resolved "https://registry.npmjs.org/is-color-stop/-/is-color-stop-1.1.0.tgz"
- integrity sha1-z/9HGu5N1cnhWFmPvhKWe1za00U=
- dependencies:
- css-color-names "^0.0.4"
- hex-color-regex "^1.1.0"
- hsl-regex "^1.0.0"
- hsla-regex "^1.0.0"
- rgb-regex "^1.0.1"
- rgba-regex "^1.0.0"
-
-is-data-descriptor@^0.1.4:
- version "0.1.4"
- resolved "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz"
- integrity sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=
- dependencies:
- kind-of "^3.0.2"
-
-is-data-descriptor@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz"
- integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==
- dependencies:
- kind-of "^6.0.0"
-
-is-date-object@^1.0.1:
- version "1.0.1"
- resolved "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz"
- integrity sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=
-
-is-descriptor@^0.1.0:
- version "0.1.6"
- resolved "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz"
- integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==
- dependencies:
- is-accessor-descriptor "^0.1.6"
- is-data-descriptor "^0.1.4"
- kind-of "^5.0.0"
-
-is-descriptor@^1.0.0, is-descriptor@^1.0.2:
- version "1.0.2"
- resolved "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz"
- integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==
- dependencies:
- is-accessor-descriptor "^1.0.0"
- is-data-descriptor "^1.0.0"
- kind-of "^6.0.2"
-
-is-directory@^0.3.1:
- version "0.3.1"
- resolved "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz"
- integrity sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=
-
-is-docker@^2.0.0:
- version "2.2.1"
- resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa"
- integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==
-
-is-extendable@^0.1.0, is-extendable@^0.1.1:
- version "0.1.1"
- resolved "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz"
- integrity sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=
-
-is-extendable@^1.0.1:
- version "1.0.1"
- resolved "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz"
- integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==
- dependencies:
- is-plain-object "^2.0.4"
-
-is-extglob@^2.1.0, is-extglob@^2.1.1:
- version "2.1.1"
- resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz"
- integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=
-
-is-finite@^1.0.0:
- version "1.0.2"
- resolved "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz"
- integrity sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=
- dependencies:
- number-is-nan "^1.0.0"
-
-is-fullwidth-code-point@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz"
- integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs=
- dependencies:
- number-is-nan "^1.0.0"
-
-is-fullwidth-code-point@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz"
- integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=
-
-is-fullwidth-code-point@^3.0.0:
- version "3.0.0"
- resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz"
- integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==
-
-is-function@^1.0.1:
- version "1.0.1"
- resolved "https://registry.npmjs.org/is-function/-/is-function-1.0.1.tgz"
- integrity sha1-Es+5i2W1fdPRk6MSH19uL0N2ArU=
-
-is-gif@^3.0.0:
- version "3.0.0"
- resolved "https://registry.npmjs.org/is-gif/-/is-gif-3.0.0.tgz"
- integrity sha512-IqJ/jlbw5WJSNfwQ/lHEDXF8rxhRgF6ythk2oiEvhpG29F704eX9NO6TvPfMiq9DrbwgcEDnETYNcZDPewQoVw==
- dependencies:
- file-type "^10.4.0"
-
-is-glob@^3.1.0:
- version "3.1.0"
- resolved "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz"
- integrity sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=
- dependencies:
- is-extglob "^2.1.0"
-
-is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1:
- version "4.0.1"
- resolved "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz"
- integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==
- dependencies:
- is-extglob "^2.1.1"
-
-is-jpg@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/is-jpg/-/is-jpg-2.0.0.tgz"
- integrity sha1-LhmX+m6RZuqsAkLarkQ0A+TvHZc=
-
-is-my-ip-valid@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/is-my-ip-valid/-/is-my-ip-valid-1.0.0.tgz"
- integrity sha512-gmh/eWXROncUzRnIa1Ubrt5b8ep/MGSnfAUI3aRp+sqTCs1tv1Isl8d8F6JmkN3dXKc3ehZMrtiPN9eL03NuaQ==
-
-is-my-json-valid@^2.10.0:
- version "2.20.0"
- resolved "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.20.0.tgz"
- integrity sha512-XTHBZSIIxNsIsZXg7XB5l8z/OBFosl1Wao4tXLpeC7eKU4Vm/kdop2azkPqULwnfGQjmeDIyey9g7afMMtdWAA==
- dependencies:
- generate-function "^2.0.0"
- generate-object-property "^1.1.0"
- is-my-ip-valid "^1.0.0"
- jsonpointer "^4.0.0"
- xtend "^4.0.0"
-
-is-natural-number@^4.0.1:
- version "4.0.1"
- resolved "https://registry.npmjs.org/is-natural-number/-/is-natural-number-4.0.1.tgz"
- integrity sha1-q5124dtM7VHjXeDHLr7PCfc0zeg=
-
-is-negated-glob@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz"
- integrity sha1-aRC8pdqMleeEtXUbl2z1oQ/uNtI=
-
-is-number-like@^1.0.3:
- version "1.0.8"
- resolved "https://registry.npmjs.org/is-number-like/-/is-number-like-1.0.8.tgz"
- integrity sha512-6rZi3ezCyFcn5L71ywzz2bS5b2Igl1En3eTlZlvKjpz1n3IZLAYMbKYAIQgFmEu0GENg92ziU/faEOA/aixjbA==
- dependencies:
- lodash.isfinite "^3.3.2"
-
-is-number@^3.0.0:
- version "3.0.0"
- resolved "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz"
- integrity sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=
- dependencies:
- kind-of "^3.0.2"
-
-is-number@^4.0.0:
- version "4.0.0"
- resolved "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz"
- integrity sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==
-
-is-number@^7.0.0:
- version "7.0.0"
- resolved "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz"
- integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==
-
-is-obj@^1.0.0:
- version "1.0.1"
- resolved "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz"
- integrity sha1-PkcprB9f3gJc19g6iW2rn09n2w8=
-
-is-object@^1.0.1:
- version "1.0.1"
- resolved "https://registry.npmjs.org/is-object/-/is-object-1.0.1.tgz"
- integrity sha1-iVJojF7C/9awPsyF52ngKQMINHA=
-
-is-plain-obj@^1.0.0, is-plain-obj@^1.1.0:
- version "1.1.0"
- resolved "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz"
- integrity sha1-caUMhCnfync8kqOQpKA7OfzVHT4=
-
-is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4:
- version "2.0.4"
- resolved "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz"
- integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==
- dependencies:
- isobject "^3.0.1"
-
-is-png@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/is-png/-/is-png-2.0.0.tgz"
- integrity sha512-4KPGizaVGj2LK7xwJIz8o5B2ubu1D/vcQsgOGFEDlpcvgZHto4gBnyd0ig7Ws+67ixmwKoNmu0hYnpo6AaKb5g==
-
-is-promise@^2.1.0:
- version "2.1.0"
- resolved "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz"
- integrity sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=
-
-is-property@^1.0.0, is-property@^1.0.2:
- version "1.0.2"
- resolved "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz"
- integrity sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=
-
-is-regex@^1.0.4:
- version "1.0.4"
- resolved "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz"
- integrity sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=
- dependencies:
- has "^1.0.1"
-
-is-relative@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz"
- integrity sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==
- dependencies:
- is-unc-path "^1.0.0"
-
-is-resolvable@^1.0.0:
- version "1.1.0"
- resolved "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz"
- integrity sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==
-
-is-retry-allowed@^1.0.0, is-retry-allowed@^1.1.0:
- version "1.2.0"
- resolved "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz"
- integrity sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==
-
-is-stream@^1.0.0, is-stream@^1.1.0:
- version "1.1.0"
- resolved "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz"
- integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ=
-
-is-stream@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz"
- integrity sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==
-
-is-svg@^3.0.0:
- version "3.0.0"
- resolved "https://registry.npmjs.org/is-svg/-/is-svg-3.0.0.tgz"
- integrity sha512-gi4iHK53LR2ujhLVVj+37Ykh9GLqYHX6JOVXbLAucaG/Cqw9xwdFOjDM2qeifLs1sF1npXXFvDu0r5HNgCMrzQ==
- dependencies:
- html-comment-regex "^1.1.0"
-
-is-symbol@^1.0.2:
- version "1.0.2"
- resolved "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz"
- integrity sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==
- dependencies:
- has-symbols "^1.0.0"
-
-is-typedarray@~1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz"
- integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=
-
-is-unc-path@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz"
- integrity sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==
- dependencies:
- unc-path-regex "^0.1.2"
-
-is-utf8@^0.2.0, is-utf8@^0.2.1:
- version "0.2.1"
- resolved "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz"
- integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=
-
-is-valid-glob@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-1.0.0.tgz"
- integrity sha1-Kb8+/3Ab4tTTFdusw5vDn+j2Aao=
-
-is-windows@^1.0.1, is-windows@^1.0.2:
- version "1.0.2"
- resolved "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz"
- integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==
-
-is-wsl@^1.1.0:
- version "1.1.0"
- resolved "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz"
- integrity sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=
-
-is-wsl@^2.2.0:
- version "2.2.0"
- resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271"
- integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==
- dependencies:
- is-docker "^2.0.0"
-
-is@^3.2.1:
- version "3.3.0"
- resolved "https://registry.npmjs.org/is/-/is-3.3.0.tgz"
- integrity sha512-nW24QBoPcFGGHJGUwnfpI7Yc5CdqWNdsyHQszVE/z2pKHXzh7FZ5GWhJqSyaQ9wMkQnsTx+kAI8bHlCX4tKdbg==
-
-isarray@0.0.1:
- version "0.0.1"
- resolved "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz"
- integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=
-
-isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz"
- integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=
-
-isarray@2.0.1:
- version "2.0.1"
- resolved "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz"
- integrity sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=
-
-isbinaryfile@^3.0.2:
- version "3.0.3"
- resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-3.0.3.tgz#5d6def3edebf6e8ca8cae9c30183a804b5f8be80"
- integrity sha512-8cJBL5tTd2OS0dM4jz07wQd5g0dCCqIhUxPIGtZfa5L6hWlvV5MHTITy/DBAsF+Oe2LS1X3krBUhNwaGUWpWxw==
- dependencies:
- buffer-alloc "^1.2.0"
-
-isbinaryfile@^4.0.8:
- version "4.0.10"
- resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-4.0.10.tgz#0c5b5e30c2557a2f06febd37b7322946aaee42b3"
- integrity sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==
-
-isexe@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz"
- integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=
-
-isobject@^2.0.0:
- version "2.1.0"
- resolved "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz"
- integrity sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=
- dependencies:
- isarray "1.0.0"
-
-isobject@^3.0.0, isobject@^3.0.1:
- version "3.0.1"
- resolved "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz"
- integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8=
-
-isstream@0.1.x, isstream@~0.1.2:
- version "0.1.2"
- resolved "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz"
- integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=
-
-isurl@^1.0.0-alpha5:
- version "1.0.0"
- resolved "https://registry.npmjs.org/isurl/-/isurl-1.0.0.tgz"
- integrity sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==
- dependencies:
- has-to-string-tag-x "^1.2.0"
- is-object "^1.0.1"
-
-jimp@^0.6.1:
- version "0.6.8"
- resolved "https://registry.npmjs.org/jimp/-/jimp-0.6.8.tgz"
- integrity sha512-F7emeG7Hp61IM8VFbNvWENLTuHe0ghizWPuP4JS9ujx2r5mCVYEd/zdaz6M2M42ZdN41blxPajLWl9FXo7Mr2Q==
- dependencies:
- "@jimp/custom" "^0.6.8"
- "@jimp/plugins" "^0.6.8"
- "@jimp/types" "^0.6.8"
- core-js "^2.5.7"
- regenerator-runtime "^0.13.3"
-
-jpeg-js@^0.3.4:
- version "0.3.6"
- resolved "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.3.6.tgz"
- integrity sha512-MUj2XlMB8kpe+8DJUGH/3UJm4XpI8XEgZQ+CiHDeyrGoKPdW/8FJv6ku+3UiYm5Fz3CWaL+iXmD8Q4Ap6aC1Jw==
-
-jpegtran-bin@^5.0.0:
- version "5.0.1"
- resolved "https://registry.npmjs.org/jpegtran-bin/-/jpegtran-bin-5.0.1.tgz"
- integrity sha512-xQoXWkIEt4ckmvcHd9xG3RcCIn00sf2TshDyFMOAE+46EspEqwqoPWotVI3e55FGWafMa9cEqaoIyrCeWDnFPw==
- dependencies:
- bin-build "^3.0.0"
- bin-wrapper "^4.0.0"
- logalot "^2.0.0"
-
-js-base64@^2.1.9:
- version "2.5.1"
- resolved "https://registry.npmjs.org/js-base64/-/js-base64-2.5.1.tgz"
- integrity sha512-M7kLczedRMYX4L8Mdh4MzyAMM9O5osx+4FcOQuTvr3A9F2D9S5JXheN0ewNbrvK2UatkTRhL5ejGmGSjNMiZuw==
-
-js-beautify@^1.5.10:
- version "1.10.2"
- resolved "https://registry.npmjs.org/js-beautify/-/js-beautify-1.10.2.tgz"
- integrity sha512-ZtBYyNUYJIsBWERnQP0rPN9KjkrDfJcMjuVGcvXOUJrD1zmOGwhRwQ4msG+HJ+Ni/FA7+sRQEMYVzdTQDvnzvQ==
- dependencies:
- config-chain "^1.1.12"
- editorconfig "^0.15.3"
- glob "^7.1.3"
- mkdirp "~0.5.1"
- nopt "~4.0.1"
-
-js-levenshtein@^1.1.3:
- version "1.1.6"
- resolved "https://registry.npmjs.org/js-levenshtein/-/js-levenshtein-1.1.6.tgz"
- integrity sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==
-
-"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0:
- version "4.0.0"
- resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz"
- integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
-
-js-tokens@^3.0.2:
- version "3.0.2"
- resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz"
- integrity sha1-mGbfOVECEw449/mWvOtlRDIJwls=
-
-js-yaml@^3.13.0, js-yaml@^3.13.1, js-yaml@^3.4.6, js-yaml@^3.5.1, js-yaml@^3.5.4:
- version "3.13.1"
- resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz"
- integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==
- dependencies:
- argparse "^1.0.7"
- esprima "^4.0.0"
-
-jsbn@~0.1.0:
- version "0.1.1"
- resolved "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz"
- integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM=
-
-jsdom@12.2.0:
- version "12.2.0"
- resolved "https://registry.npmjs.org/jsdom/-/jsdom-12.2.0.tgz"
- integrity sha512-QPOggIJ8fquWPLaYYMoh+zqUmdphDtu1ju0QGTitZT1Yd8I5qenPpXM1etzUegu3MjVp8XPzgZxdn8Yj7e40ig==
- dependencies:
- abab "^2.0.0"
- acorn "^6.0.2"
- acorn-globals "^4.3.0"
- array-equal "^1.0.0"
- cssom "^0.3.4"
- cssstyle "^1.1.1"
- data-urls "^1.0.1"
- domexception "^1.0.1"
- escodegen "^1.11.0"
- html-encoding-sniffer "^1.0.2"
- nwsapi "^2.0.9"
- parse5 "5.1.0"
- pn "^1.1.0"
- request "^2.88.0"
- request-promise-native "^1.0.5"
- saxes "^3.1.3"
- symbol-tree "^3.2.2"
- tough-cookie "^2.4.3"
- w3c-hr-time "^1.0.1"
- webidl-conversions "^4.0.2"
- whatwg-encoding "^1.0.5"
- whatwg-mimetype "^2.2.0"
- whatwg-url "^7.0.0"
- ws "^6.1.0"
- xml-name-validator "^3.0.0"
-
-jsesc@^1.3.0:
- version "1.3.0"
- resolved "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz"
- integrity sha1-RsP+yMGJKxKwgz25vHYiF226s0s=
-
-jsesc@^2.5.1:
- version "2.5.2"
- resolved "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz"
- integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==
-
-jsesc@~0.5.0:
- version "0.5.0"
- resolved "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz"
- integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=
-
-json-buffer@3.0.0:
- version "3.0.0"
- resolved "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz"
- integrity sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=
-
-json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2:
- version "1.0.2"
- resolved "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz"
- integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==
-
-json-schema-traverse@^0.4.1:
- version "0.4.1"
- resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz"
- integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==
-
-json-schema@0.2.3:
- version "0.2.3"
- resolved "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz"
- integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=
-
-json-stable-stringify-without-jsonify@^1.0.1:
- version "1.0.1"
- resolved "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz"
- integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=
-
-json-stable-stringify@^1.0.0, json-stable-stringify@^1.0.1:
- version "1.0.1"
- resolved "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz"
- integrity sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=
- dependencies:
- jsonify "~0.0.0"
-
-json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1:
- version "5.0.1"
- resolved "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz"
- integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=
-
-json5@^0.5.0, json5@^0.5.1:
- version "0.5.1"
- resolved "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz"
- integrity sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=
-
-json5@^1.0.1:
- version "1.0.1"
- resolved "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz"
- integrity sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==
- dependencies:
- minimist "^1.2.0"
-
-json5@^2.1.2:
- version "2.1.3"
- resolved "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz"
- integrity sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==
- dependencies:
- minimist "^1.2.5"
-
-jsonfile@^3.0.0:
- version "3.0.1"
- resolved "https://registry.npmjs.org/jsonfile/-/jsonfile-3.0.1.tgz"
- integrity sha1-pezG9l9T9mLEQVx2daAzHQmS7GY=
- optionalDependencies:
- graceful-fs "^4.1.6"
-
-jsonfile@^4.0.0:
- version "4.0.0"
- resolved "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz"
- integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=
- optionalDependencies:
- graceful-fs "^4.1.6"
-
-jsonfile@^6.0.1:
- version "6.1.0"
- resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae"
- integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==
- dependencies:
- universalify "^2.0.0"
- optionalDependencies:
- graceful-fs "^4.1.6"
-
-jsonify@~0.0.0:
- version "0.0.0"
- resolved "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz"
- integrity sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=
-
-jsonpointer@^4.0.0:
- version "4.0.1"
- resolved "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz"
- integrity sha1-T9kss04OnbPInIYi7PUfm5eMbLk=
-
-jsprim@^1.2.2:
- version "1.4.1"
- resolved "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz"
- integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=
- dependencies:
- assert-plus "1.0.0"
- extsprintf "1.3.0"
- json-schema "0.2.3"
- verror "1.10.0"
-
-junk@^3.1.0:
- version "3.1.0"
- resolved "https://registry.npmjs.org/junk/-/junk-3.1.0.tgz"
- integrity sha512-pBxcB3LFc8QVgdggvZWyeys+hnrNWg4OcZIU/1X59k5jQdLBlCsYGRQaz234SqoRLTCgMH00fY0xRJH+F9METQ==
-
-just-debounce@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/just-debounce/-/just-debounce-1.0.0.tgz"
- integrity sha1-h/zPrv/AtozRnVX2cilD+SnqNeo=
-
-keyv@3.0.0:
- version "3.0.0"
- resolved "https://registry.npmjs.org/keyv/-/keyv-3.0.0.tgz"
- integrity sha512-eguHnq22OE3uVoSYG0LVWNP+4ppamWr9+zWBe1bsNcovIMy6huUJFPgy4mGwCd/rnl3vOLGW1MTlu4c57CT1xA==
- dependencies:
- json-buffer "3.0.0"
-
-keyv@^3.0.0:
- version "3.1.0"
- resolved "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz"
- integrity sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==
- dependencies:
- json-buffer "3.0.0"
-
-kind-of@^1.1.0:
- version "1.1.0"
- resolved "https://registry.npmjs.org/kind-of/-/kind-of-1.1.0.tgz"
- integrity sha1-FAo9LUGjbS78+pN3tiwk+ElaXEQ=
-
-kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0:
- version "3.2.2"
- resolved "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz"
- integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=
- dependencies:
- is-buffer "^1.1.5"
-
-kind-of@^4.0.0:
- version "4.0.0"
- resolved "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz"
- integrity sha1-IIE989cSkosgc3hpGkUGb65y3Vc=
- dependencies:
- is-buffer "^1.1.5"
-
-kind-of@^5.0.0, kind-of@^5.0.2:
- version "5.1.0"
- resolved "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz"
- integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==
-
-kind-of@^6.0.0, kind-of@^6.0.2:
- version "6.0.2"
- resolved "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz"
- integrity sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==
-
-known-css-properties@^0.11.0:
- version "0.11.0"
- resolved "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.11.0.tgz"
- integrity sha512-bEZlJzXo5V/ApNNa5z375mJC6Nrz4vG43UgcSCrg2OHC+yuB6j0iDSrY7RQ/+PRofFB03wNIIt9iXIVLr4wc7w==
-
-known-css-properties@^0.3.0:
- version "0.3.0"
- resolved "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.3.0.tgz"
- integrity sha512-QMQcnKAiQccfQTqtBh/qwquGZ2XK/DXND1jrcN9M8gMMy99Gwla7GQjndVUsEqIaRyP6bsFRuhwRj5poafBGJQ==
-
-last-run@^1.1.0:
- version "1.1.1"
- resolved "https://registry.npmjs.org/last-run/-/last-run-1.1.1.tgz"
- integrity sha1-RblpQsF7HHnHchmCWbqUO+v4yls=
- dependencies:
- default-resolution "^2.0.0"
- es6-weak-map "^2.0.1"
-
-lazystream@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz"
- integrity sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=
- dependencies:
- readable-stream "^2.0.5"
-
-lazystream@~0.1.0:
- version "0.1.0"
- resolved "https://registry.npmjs.org/lazystream/-/lazystream-0.1.0.tgz"
- integrity sha1-GyXWPHcqTCDwpe0KnXf0hLbhaSA=
- dependencies:
- readable-stream "~1.0.2"
-
-lcid@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz"
- integrity sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=
- dependencies:
- invert-kv "^1.0.0"
-
-lcid@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz"
- integrity sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==
- dependencies:
- invert-kv "^2.0.0"
-
-lead@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/lead/-/lead-1.0.0.tgz"
- integrity sha1-bxT5mje+Op3XhPVJVpDlkDRm7kI=
- dependencies:
- flush-write-stream "^1.0.2"
-
-levn@^0.3.0, levn@~0.3.0:
- version "0.3.0"
- resolved "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz"
- integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=
- dependencies:
- prelude-ls "~1.1.2"
- type-check "~0.3.2"
-
-liftoff@^2.0.1:
- version "2.5.0"
- resolved "https://registry.npmjs.org/liftoff/-/liftoff-2.5.0.tgz"
- integrity sha1-IAkpG7Mc6oYbvxCnwVooyvdcMew=
- dependencies:
- extend "^3.0.0"
- findup-sync "^2.0.0"
- fined "^1.0.1"
- flagged-respawn "^1.0.0"
- is-plain-object "^2.0.4"
- object.map "^1.0.0"
- rechoir "^0.6.2"
- resolve "^1.1.7"
-
-liftoff@^3.1.0:
- version "3.1.0"
- resolved "https://registry.npmjs.org/liftoff/-/liftoff-3.1.0.tgz"
- integrity sha512-DlIPlJUkCV0Ips2zf2pJP0unEoT1kwYhiiPUGF3s/jtxTCjziNLoiVVh+jqWOWeFi6mmwQ5fNxvAUyPad4Dfog==
- dependencies:
- extend "^3.0.0"
- findup-sync "^3.0.0"
- fined "^1.0.1"
- flagged-respawn "^1.0.0"
- is-plain-object "^2.0.4"
- object.map "^1.0.0"
- rechoir "^0.6.2"
- resolve "^1.1.7"
-
-limiter@^1.0.5:
- version "1.1.4"
- resolved "https://registry.npmjs.org/limiter/-/limiter-1.1.4.tgz"
- integrity sha512-XCpr5bElgDI65vVgstP8TWjv6/QKWm9GU5UG0Pr5sLQ3QLo8NVKsioe+Jed5/3vFOe3IQuqE7DKwTvKQkjTHvg==
-
-line-column@^1.0.2:
- version "1.0.2"
- resolved "https://registry.npmjs.org/line-column/-/line-column-1.0.2.tgz"
- integrity sha1-0lryk2tvSEkXKzEuR5LR2Ye8NKI=
- dependencies:
- isarray "^1.0.0"
- isobject "^2.0.0"
-
-load-bmfont@^1.3.1, load-bmfont@^1.4.0:
- version "1.4.0"
- resolved "https://registry.npmjs.org/load-bmfont/-/load-bmfont-1.4.0.tgz"
- integrity sha512-kT63aTAlNhZARowaNYcY29Fn/QYkc52M3l6V1ifRcPewg2lvUZDAj7R6dXjOL9D0sict76op3T5+odumDSF81g==
- dependencies:
- buffer-equal "0.0.1"
- mime "^1.3.4"
- parse-bmfont-ascii "^1.0.3"
- parse-bmfont-binary "^1.0.5"
- parse-bmfont-xml "^1.1.4"
- phin "^2.9.1"
- xhr "^2.0.1"
- xtend "^4.0.0"
-
-load-json-file@^1.0.0:
- version "1.1.0"
- resolved "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz"
- integrity sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=
- dependencies:
- graceful-fs "^4.1.2"
- parse-json "^2.2.0"
- pify "^2.0.0"
- pinkie-promise "^2.0.0"
- strip-bom "^2.0.0"
-
-load-json-file@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz"
- integrity sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=
- dependencies:
- graceful-fs "^4.1.2"
- parse-json "^2.2.0"
- pify "^2.0.0"
- strip-bom "^3.0.0"
-
-loader-runner@^2.4.0:
- version "2.4.0"
- resolved "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz"
- integrity sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==
-
-loader-utils@1.2.3:
- version "1.2.3"
- resolved "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz"
- integrity sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==
- dependencies:
- big.js "^5.2.2"
- emojis-list "^2.0.0"
- json5 "^1.0.1"
-
-loader-utils@^0.2.5, loader-utils@~0.2.2, loader-utils@~0.2.3, loader-utils@~0.2.5:
- version "0.2.17"
- resolved "https://registry.npmjs.org/loader-utils/-/loader-utils-0.2.17.tgz"
- integrity sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g=
- dependencies:
- big.js "^3.1.3"
- emojis-list "^2.0.0"
- json5 "^0.5.0"
- object-assign "^4.0.1"
-
-loader-utils@^1.0.0, loader-utils@^1.1.0, loader-utils@^1.2.3, loader-utils@^1.4.0:
- version "1.4.0"
- resolved "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz"
- integrity sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==
- dependencies:
- big.js "^5.2.2"
- emojis-list "^3.0.0"
- json5 "^1.0.1"
-
-loader-utils@^2.0.0:
- version "2.0.2"
- resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.2.tgz#d6e3b4fb81870721ae4e0868ab11dd638368c129"
- integrity sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==
- dependencies:
- big.js "^5.2.2"
- emojis-list "^3.0.0"
- json5 "^2.1.2"
-
-localtunnel@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/localtunnel/-/localtunnel-2.0.0.tgz"
- integrity sha512-g6E0aLgYYDvQDxIjIXkgJo2+pHj3sGg4Wz/XP3h2KtZnRsWPbOQY+hw1H8Z91jep998fkcVE9l+kghO+97vllg==
- dependencies:
- axios "0.19.0"
- debug "4.1.1"
- openurl "1.1.1"
- yargs "13.3.0"
-
-locate-path@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz"
- integrity sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=
- dependencies:
- p-locate "^2.0.0"
- path-exists "^3.0.0"
-
-locate-path@^3.0.0:
- version "3.0.0"
- resolved "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz"
- integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==
- dependencies:
- p-locate "^3.0.0"
- path-exists "^3.0.0"
-
-locate-path@^5.0.0:
- version "5.0.0"
- resolved "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz"
- integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==
- dependencies:
- p-locate "^4.1.0"
-
-lodash._basecopy@^3.0.0:
- version "3.0.1"
- resolved "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz"
- integrity sha1-jaDmqHbPNEwK2KVIghEd08XHyjY=
-
-lodash._basetostring@^3.0.0:
- version "3.0.1"
- resolved "https://registry.npmjs.org/lodash._basetostring/-/lodash._basetostring-3.0.1.tgz"
- integrity sha1-0YYdh3+CSlL2aYMtyvPuFVZqB9U=
-
-lodash._basevalues@^3.0.0:
- version "3.0.0"
- resolved "https://registry.npmjs.org/lodash._basevalues/-/lodash._basevalues-3.0.0.tgz"
- integrity sha1-W3dXYoAr3j0yl1A+JjAIIP32Ybc=
-
-lodash._escapehtmlchar@~2.4.1:
- version "2.4.1"
- resolved "https://registry.npmjs.org/lodash._escapehtmlchar/-/lodash._escapehtmlchar-2.4.1.tgz"
- integrity sha1-32fDu2t+jh6DGrSL+geVuSr+iZ0=
- dependencies:
- lodash._htmlescapes "~2.4.1"
-
-lodash._escapestringchar@~2.4.1:
- version "2.4.1"
- resolved "https://registry.npmjs.org/lodash._escapestringchar/-/lodash._escapestringchar-2.4.1.tgz"
- integrity sha1-7P4iYYoq3lC/7qQ5N+Ud9m8O23I=
-
-lodash._getnative@^3.0.0:
- version "3.9.1"
- resolved "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz"
- integrity sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=
-
-lodash._htmlescapes@~2.4.1:
- version "2.4.1"
- resolved "https://registry.npmjs.org/lodash._htmlescapes/-/lodash._htmlescapes-2.4.1.tgz"
- integrity sha1-MtFL8IRLbeb4tioFG09nwii2JMs=
-
-lodash._isiterateecall@^3.0.0:
- version "3.0.9"
- resolved "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz"
- integrity sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw=
-
-lodash._isnative@~2.4.1:
- version "2.4.1"
- resolved "https://registry.npmjs.org/lodash._isnative/-/lodash._isnative-2.4.1.tgz"
- integrity sha1-PqZAS3hKe+g2x7V1gOHN95sUgyw=
-
-lodash._objecttypes@~2.4.1:
- version "2.4.1"
- resolved "https://registry.npmjs.org/lodash._objecttypes/-/lodash._objecttypes-2.4.1.tgz"
- integrity sha1-fAt/admKH3ZSn4kLDNsbTf7BHBE=
-
-lodash._reescape@^3.0.0:
- version "3.0.0"
- resolved "https://registry.npmjs.org/lodash._reescape/-/lodash._reescape-3.0.0.tgz"
- integrity sha1-Kx1vXf4HyKNVdT5fJ/rH8c3hYWo=
-
-lodash._reevaluate@^3.0.0:
- version "3.0.0"
- resolved "https://registry.npmjs.org/lodash._reevaluate/-/lodash._reevaluate-3.0.0.tgz"
- integrity sha1-WLx0xAZklTrgsSTYBpltrKQx4u0=
-
-lodash._reinterpolate@^2.4.1, lodash._reinterpolate@~2.4.1:
- version "2.4.1"
- resolved "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-2.4.1.tgz"
- integrity sha1-TxInqlqHEfxjL1sHofRgequLMiI=
-
-lodash._reinterpolate@^3.0.0:
- version "3.0.0"
- resolved "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz"
- integrity sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=
-
-lodash._reunescapedhtml@~2.4.1:
- version "2.4.1"
- resolved "https://registry.npmjs.org/lodash._reunescapedhtml/-/lodash._reunescapedhtml-2.4.1.tgz"
- integrity sha1-dHxPxAED6zu4oJduVx96JlnpO6c=
- dependencies:
- lodash._htmlescapes "~2.4.1"
- lodash.keys "~2.4.1"
-
-lodash._root@^3.0.0:
- version "3.0.1"
- resolved "https://registry.npmjs.org/lodash._root/-/lodash._root-3.0.1.tgz"
- integrity sha1-+6HEUkwZ7ppfgTa0YJ8BfPTe1pI=
-
-lodash._shimkeys@~2.4.1:
- version "2.4.1"
- resolved "https://registry.npmjs.org/lodash._shimkeys/-/lodash._shimkeys-2.4.1.tgz"
- integrity sha1-bpzJZm/wgfC1psl4uD4kLmlJ0gM=
- dependencies:
- lodash._objecttypes "~2.4.1"
-
-lodash.capitalize@^4.1.0:
- version "4.2.1"
- resolved "https://registry.npmjs.org/lodash.capitalize/-/lodash.capitalize-4.2.1.tgz"
- integrity sha1-+CbJtOKoUR2E46yinbBeGk87cqk=
-
-lodash.clone@^4.3.2:
- version "4.5.0"
- resolved "https://registry.npmjs.org/lodash.clone/-/lodash.clone-4.5.0.tgz"
- integrity sha1-GVhwRQ9aExkkeN9Lw9I9LeoZB7Y=
-
-lodash.clonedeep@^4.3.2:
- version "4.5.0"
- resolved "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz"
- integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=
-
-lodash.defaults@^4.2.0:
- version "4.2.0"
- resolved "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz"
- integrity sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=
-
-lodash.defaults@~2.4.1:
- version "2.4.1"
- resolved "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-2.4.1.tgz"
- integrity sha1-p+iIXwXmiFEUS24SqPNngCa8TFQ=
- dependencies:
- lodash._objecttypes "~2.4.1"
- lodash.keys "~2.4.1"
-
-lodash.escape@^3.0.0:
- version "3.2.0"
- resolved "https://registry.npmjs.org/lodash.escape/-/lodash.escape-3.2.0.tgz"
- integrity sha1-mV7g3BjBtIzJLv+ucaEKq1tIdpg=
- dependencies:
- lodash._root "^3.0.0"
-
-lodash.escape@~2.4.1:
- version "2.4.1"
- resolved "https://registry.npmjs.org/lodash.escape/-/lodash.escape-2.4.1.tgz"
- integrity sha1-LOEsXghNsKV92l5dHu659dF1o7Q=
- dependencies:
- lodash._escapehtmlchar "~2.4.1"
- lodash._reunescapedhtml "~2.4.1"
- lodash.keys "~2.4.1"
-
-lodash.get@^4.0.0:
- version "4.4.2"
- resolved "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz"
- integrity sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=
-
-lodash.isarguments@^3.0.0:
- version "3.1.0"
- resolved "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz"
- integrity sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=
-
-lodash.isarray@^3.0.0:
- version "3.0.4"
- resolved "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz"
- integrity sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=
-
-lodash.isfinite@^3.3.2:
- version "3.3.2"
- resolved "https://registry.npmjs.org/lodash.isfinite/-/lodash.isfinite-3.3.2.tgz"
- integrity sha1-+4m2WpqAKBgz8LdHizpRBPiY67M=
-
-lodash.isobject@~2.4.1:
- version "2.4.1"
- resolved "https://registry.npmjs.org/lodash.isobject/-/lodash.isobject-2.4.1.tgz"
- integrity sha1-Wi5H/mmVPx7mMafrof5k0tBlWPU=
- dependencies:
- lodash._objecttypes "~2.4.1"
-
-lodash.kebabcase@^4.0.0:
- version "4.1.1"
- resolved "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz"
- integrity sha1-hImxyw0p/4gZXM7KRI/21swpXDY=
-
-lodash.keys@^3.0.0:
- version "3.1.2"
- resolved "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz"
- integrity sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=
- dependencies:
- lodash._getnative "^3.0.0"
- lodash.isarguments "^3.0.0"
- lodash.isarray "^3.0.0"
-
-lodash.keys@~2.4.1:
- version "2.4.1"
- resolved "https://registry.npmjs.org/lodash.keys/-/lodash.keys-2.4.1.tgz"
- integrity sha1-SN6kbfj/djKxDXBrissmWR4rNyc=
- dependencies:
- lodash._isnative "~2.4.1"
- lodash._shimkeys "~2.4.1"
- lodash.isobject "~2.4.1"
-
-lodash.memoize@^4.1.2:
- version "4.1.2"
- resolved "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz"
- integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=
-
-lodash.restparam@^3.0.0:
- version "3.6.1"
- resolved "https://registry.npmjs.org/lodash.restparam/-/lodash.restparam-3.6.1.tgz"
- integrity sha1-k2pOMJ7zMKdkXtQUWYbIWuWyCAU=
-
-lodash.some@^4.2.2:
- version "4.6.0"
- resolved "https://registry.npmjs.org/lodash.some/-/lodash.some-4.6.0.tgz"
- integrity sha1-G7nzFO9ri63tE7VJFpsqlF62jk0=
-
-lodash.sortby@^4.7.0:
- version "4.7.0"
- resolved "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz"
- integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=
-
-lodash.template@^2.4.1:
- version "2.4.1"
- resolved "https://registry.npmjs.org/lodash.template/-/lodash.template-2.4.1.tgz"
- integrity sha1-nmEQB+32KRKal0qzxIuBez4c8g0=
- dependencies:
- lodash._escapestringchar "~2.4.1"
- lodash._reinterpolate "~2.4.1"
- lodash.defaults "~2.4.1"
- lodash.escape "~2.4.1"
- lodash.keys "~2.4.1"
- lodash.templatesettings "~2.4.1"
- lodash.values "~2.4.1"
-
-lodash.template@^3.0.0:
- version "3.6.2"
- resolved "https://registry.npmjs.org/lodash.template/-/lodash.template-3.6.2.tgz"
- integrity sha1-+M3sxhaaJVvpCYrosMU9N4kx0U8=
- dependencies:
- lodash._basecopy "^3.0.0"
- lodash._basetostring "^3.0.0"
- lodash._basevalues "^3.0.0"
- lodash._isiterateecall "^3.0.0"
- lodash._reinterpolate "^3.0.0"
- lodash.escape "^3.0.0"
- lodash.keys "^3.0.0"
- lodash.restparam "^3.0.0"
- lodash.templatesettings "^3.0.0"
-
-lodash.template@^4.5.0:
- version "4.5.0"
- resolved "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz"
- integrity sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==
- dependencies:
- lodash._reinterpolate "^3.0.0"
- lodash.templatesettings "^4.0.0"
-
-lodash.templatesettings@^3.0.0:
- version "3.1.1"
- resolved "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-3.1.1.tgz"
- integrity sha1-+zB4RHU7Zrnxr6VOJix0UwfbqOU=
- dependencies:
- lodash._reinterpolate "^3.0.0"
- lodash.escape "^3.0.0"
-
-lodash.templatesettings@^4.0.0:
- version "4.2.0"
- resolved "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz"
- integrity sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==
- dependencies:
- lodash._reinterpolate "^3.0.0"
-
-lodash.templatesettings@~2.4.1:
- version "2.4.1"
- resolved "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-2.4.1.tgz"
- integrity sha1-6nbHXRHrhtTb6JqDiTu4YZKaxpk=
- dependencies:
- lodash._reinterpolate "~2.4.1"
- lodash.escape "~2.4.1"
-
-lodash.uniq@^4.5.0:
- version "4.5.0"
- resolved "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz"
- integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=
-
-lodash.values@~2.4.1:
- version "2.4.1"
- resolved "https://registry.npmjs.org/lodash.values/-/lodash.values-2.4.1.tgz"
- integrity sha1-q/UUQ2s8twUAFieXjLzzCxKA7qQ=
- dependencies:
- lodash.keys "~2.4.1"
-
-lodash@^3.0.1:
- version "3.10.1"
- resolved "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz"
- integrity sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=
-
-lodash@^4.0.0, lodash@^4.15.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.4, lodash@^4.3.0, lodash@~4.17.10:
- version "4.17.15"
- resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz"
- integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==
-
-lodash@~1.0.1:
- version "1.0.2"
- resolved "https://registry.npmjs.org/lodash/-/lodash-1.0.2.tgz"
- integrity sha1-j1dWDIO1n8JwvT1WG2kAQ0MOJVE=
-
-lodash@~2.4.1:
- version "2.4.2"
- resolved "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz"
- integrity sha1-+t2DS5aDBz2hebPq5tnA0VBT9z4=
-
-logalot@^2.0.0, logalot@^2.1.0:
- version "2.1.0"
- resolved "https://registry.npmjs.org/logalot/-/logalot-2.1.0.tgz"
- integrity sha1-X46MkNME7fElMJUaVVSruMXj9VI=
- dependencies:
- figures "^1.3.5"
- squeak "^1.0.0"
-
-longest@^1.0.0:
- version "1.0.1"
- resolved "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz"
- integrity sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=
-
-loose-envify@^1.0.0:
- version "1.4.0"
- resolved "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz"
- integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==
- dependencies:
- js-tokens "^3.0.0 || ^4.0.0"
-
-loud-rejection@^1.0.0:
- version "1.6.0"
- resolved "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz"
- integrity sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=
- dependencies:
- currently-unhandled "^0.4.1"
- signal-exit "^3.0.0"
-
-lower-case@^1.1.1:
- version "1.1.4"
- resolved "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz"
- integrity sha1-miyr0bno4K6ZOkv31YdcOcQujqw=
-
-lowercase-keys@1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.0.tgz"
- integrity sha1-TjNms55/VFfjXxMkvfb4jQv8cwY=
-
-lowercase-keys@^1.0.0, lowercase-keys@^1.0.1:
- version "1.0.1"
- resolved "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz"
- integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==
-
-lowercase-keys@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz"
- integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==
-
-lpad-align@^1.0.1:
- version "1.1.2"
- resolved "https://registry.npmjs.org/lpad-align/-/lpad-align-1.1.2.tgz"
- integrity sha1-IfYArBwwlcPG5JfuZyce4ISB/p4=
- dependencies:
- get-stdin "^4.0.1"
- indent-string "^2.1.0"
- longest "^1.0.0"
- meow "^3.3.0"
-
-lru-cache@2:
- version "2.7.3"
- resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz"
- integrity sha1-bUUk6LlV+V1PW1iFHOId1y+06VI=
-
-lru-cache@^4.0.1, lru-cache@^4.1.5:
- version "4.1.5"
- resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz"
- integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==
- dependencies:
- pseudomap "^1.0.2"
- yallist "^2.1.2"
-
-lru-cache@^5.1.1:
- version "5.1.1"
- resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz"
- integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==
- dependencies:
- yallist "^3.0.2"
-
-lru-cache@^6.0.0:
- version "6.0.0"
- resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94"
- integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==
- dependencies:
- yallist "^4.0.0"
-
-lz-string@^1.4.4:
- version "1.4.4"
- resolved "https://registry.npmjs.org/lz-string/-/lz-string-1.4.4.tgz"
- integrity sha1-wNjq82BZ9wV5bh40SBHPTEmNOiY=
-
-make-dir@^1.0.0, make-dir@^1.2.0:
- version "1.3.0"
- resolved "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz"
- integrity sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==
- dependencies:
- pify "^3.0.0"
-
-make-dir@^2.0.0:
- version "2.1.0"
- resolved "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz"
- integrity sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==
- dependencies:
- pify "^4.0.1"
- semver "^5.6.0"
-
-make-dir@^3.0.0:
- version "3.1.0"
- resolved "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz"
- integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==
- dependencies:
- semver "^6.0.0"
-
-make-iterator@^1.0.0:
- version "1.0.1"
- resolved "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz"
- integrity sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==
- dependencies:
- kind-of "^6.0.2"
-
-map-age-cleaner@^0.1.1:
- version "0.1.3"
- resolved "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz"
- integrity sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==
- dependencies:
- p-defer "^1.0.0"
-
-map-cache@^0.2.0, map-cache@^0.2.2:
- version "0.2.2"
- resolved "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz"
- integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=
-
-map-obj@^1.0.0, map-obj@^1.0.1:
- version "1.0.1"
- resolved "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz"
- integrity sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=
-
-map-visit@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz"
- integrity sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=
- dependencies:
- object-visit "^1.0.0"
-
-markdown-loader@^5.1.0:
- version "5.1.0"
- resolved "https://registry.npmjs.org/markdown-loader/-/markdown-loader-5.1.0.tgz"
- integrity sha512-xtQNozLEL+55ZSPTNwro8epZqf1h7HjAZd/69zNe8lbckDiGVHeLQm849bXzocln2pwRK2A/GrW/7MAmwjcFog==
- dependencies:
- loader-utils "^1.2.3"
- marked "^0.7.0"
-
-marked@^0.7.0:
- version "0.7.0"
- resolved "https://registry.npmjs.org/marked/-/marked-0.7.0.tgz"
- integrity sha512-c+yYdCZJQrsRjTPhUx7VKkApw9bwDkNbHUKo1ovgcfDjb2kc8rLuRbIFyXL5WOEUwzSSKo3IXpph2K6DqB/KZg==
-
-matchdep@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/matchdep/-/matchdep-2.0.0.tgz"
- integrity sha1-xvNINKDY28OzfCfui7yyfHd1WC4=
- dependencies:
- findup-sync "^2.0.0"
- micromatch "^3.0.4"
- resolve "^1.4.0"
- stack-trace "0.0.10"
-
-matcher@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/matcher/-/matcher-3.0.0.tgz#bd9060f4c5b70aa8041ccc6f80368760994f30ca"
- integrity sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==
- dependencies:
- escape-string-regexp "^4.0.0"
-
-md5.js@^1.3.4:
- version "1.3.5"
- resolved "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz"
- integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==
- dependencies:
- hash-base "^3.0.0"
- inherits "^2.0.1"
- safe-buffer "^5.1.2"
-
-mdn-data@2.0.4:
- version "2.0.4"
- resolved "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz"
- integrity sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==
-
-mdn-data@~1.1.0:
- version "1.1.4"
- resolved "https://registry.npmjs.org/mdn-data/-/mdn-data-1.1.4.tgz"
- integrity sha512-FSYbp3lyKjyj3E7fMl6rYvUdX0FBXaluGqlFoYESWQlyUTq8R+wp0rkFxoYFqZlHCvsUXGjyJmLQSnXToYhOSA==
-
-media-typer@0.3.0:
- version "0.3.0"
- resolved "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz"
- integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=
-
-mem@^4.0.0:
- version "4.3.0"
- resolved "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz"
- integrity sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==
- dependencies:
- map-age-cleaner "^0.1.1"
- mimic-fn "^2.0.0"
- p-is-promise "^2.0.0"
-
-memory-fs@^0.4.0, memory-fs@^0.4.1:
- version "0.4.1"
- resolved "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz"
- integrity sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=
- dependencies:
- errno "^0.1.3"
- readable-stream "^2.0.1"
-
-meow@^3.3.0:
- version "3.7.0"
- resolved "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz"
- integrity sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=
- dependencies:
- camelcase-keys "^2.0.0"
- decamelize "^1.1.2"
- loud-rejection "^1.0.0"
- map-obj "^1.0.1"
- minimist "^1.1.3"
- normalize-package-data "^2.3.4"
- object-assign "^4.0.1"
- read-pkg-up "^1.0.1"
- redent "^1.0.0"
- trim-newlines "^1.0.0"
-
-merge-stream@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz"
- integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==
-
-merge2@^1.2.3, merge2@^1.3.0:
- version "1.3.0"
- resolved "https://registry.npmjs.org/merge2/-/merge2-1.3.0.tgz"
- integrity sha512-2j4DAdlBOkiSZIsaXk4mTE3sRS02yBHAtfy127xRV3bQUFqXkjHCHLW6Scv7DwNRbIWNHH8zpnz9zMaKXIdvYw==
-
-merge@^1.2.0:
- version "1.2.1"
- resolved "https://registry.npmjs.org/merge/-/merge-1.2.1.tgz"
- integrity sha512-VjFo4P5Whtj4vsLzsYBu5ayHhoHJ0UqNm7ibvShmbmoz7tGi0vXaoJbGdB+GmDMLUdg8DpQXEIeVDAe8MaABvQ==
-
-micromatch@^3.0.4, micromatch@^3.1.10, micromatch@^3.1.4:
- version "3.1.10"
- resolved "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz"
- integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==
- dependencies:
- arr-diff "^4.0.0"
- array-unique "^0.3.2"
- braces "^2.3.1"
- define-property "^2.0.2"
- extend-shallow "^3.0.2"
- extglob "^2.0.4"
- fragment-cache "^0.2.1"
- kind-of "^6.0.2"
- nanomatch "^1.2.9"
- object.pick "^1.3.0"
- regex-not "^1.0.0"
- snapdragon "^0.8.1"
- to-regex "^3.0.2"
-
-micromatch@^4.0.2:
- version "4.0.2"
- resolved "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz"
- integrity sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==
- dependencies:
- braces "^3.0.1"
- picomatch "^2.0.5"
-
-miller-rabin@^4.0.0:
- version "4.0.1"
- resolved "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz"
- integrity sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==
- dependencies:
- bn.js "^4.0.0"
- brorand "^1.0.1"
-
-mime-db@1.40.0:
- version "1.40.0"
- resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz"
- integrity sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==
-
-mime-db@^1.28.0:
- version "1.41.0"
- resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.41.0.tgz"
- integrity sha512-B5gxBI+2K431XW8C2rcc/lhppbuji67nf9v39eH8pkWoZDxnAL0PxdpH32KYRScniF8qDHBDlI+ipgg5WrCUYw==
-
-mime-db@~1.12.0:
- version "1.12.0"
- resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.12.0.tgz"
- integrity sha1-PQxjGA9FjrENMlqqN9fFiuMS6dc=
-
-mime-types@^2.1.12, mime-types@~2.1.17, mime-types@~2.1.19, mime-types@~2.1.24:
- version "2.1.24"
- resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz"
- integrity sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==
- dependencies:
- mime-db "1.40.0"
-
-mime-types@~2.0.9:
- version "2.0.14"
- resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.0.14.tgz"
- integrity sha1-MQ4VnbI+B3+Lsit0jav6SVcUCqY=
- dependencies:
- mime-db "~1.12.0"
-
-mime@1.4.1:
- version "1.4.1"
- resolved "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz"
- integrity sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==
-
-mime@^1.3.4:
- version "1.6.0"
- resolved "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz"
- integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==
-
-mime@^2.4.0:
- version "2.4.4"
- resolved "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz"
- integrity sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==
-
-mimic-fn@^1.0.0:
- version "1.2.0"
- resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz"
- integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==
-
-mimic-fn@^2.0.0, mimic-fn@^2.1.0:
- version "2.1.0"
- resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz"
- integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==
-
-mimic-response@^1.0.0, mimic-response@^1.0.1:
- version "1.0.1"
- resolved "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz"
- integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==
-
-min-document@^2.19.0:
- version "2.19.0"
- resolved "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz"
- integrity sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=
- dependencies:
- dom-walk "^0.1.0"
-
-min-indent@^1.0.0:
- version "1.0.1"
- resolved "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz"
- integrity sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==
-
-minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1:
- version "1.0.1"
- resolved "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz"
- integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==
-
-minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1:
- version "1.0.1"
- resolved "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz"
- integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=
-
-minimatch@0.3:
- version "0.3.0"
- resolved "https://registry.npmjs.org/minimatch/-/minimatch-0.3.0.tgz"
- integrity sha1-J12O2qxPG7MyZHIInnlJyDlGmd0=
- dependencies:
- lru-cache "2"
- sigmund "~1.0.0"
-
-"minimatch@2 || 3", minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4, minimatch@~3.0.2:
- version "3.0.4"
- resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz"
- integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==
- dependencies:
- brace-expansion "^1.1.7"
-
-minimatch@^2.0.1:
- version "2.0.10"
- resolved "https://registry.npmjs.org/minimatch/-/minimatch-2.0.10.tgz"
- integrity sha1-jQh8OcazjAAbl/ynzm0OHoCvusc=
- dependencies:
- brace-expansion "^1.0.0"
-
-minimatch@~0.2.11:
- version "0.2.14"
- resolved "https://registry.npmjs.org/minimatch/-/minimatch-0.2.14.tgz"
- integrity sha1-x054BXT2PG+aCQ6Q775u9TpqdWo=
- dependencies:
- lru-cache "2"
- sigmund "~1.0.0"
-
-minimist@0.0.8:
- version "0.0.8"
- resolved "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz"
- integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=
-
-minimist@1.1.x:
- version "1.1.3"
- resolved "https://registry.npmjs.org/minimist/-/minimist-1.1.3.tgz"
- integrity sha1-O+39kaktOQFvz6ocaB6Pqhoe/ag=
-
-minimist@^0.1.0:
- version "0.1.0"
- resolved "https://registry.npmjs.org/minimist/-/minimist-0.1.0.tgz"
- integrity sha1-md9lelJXTCHJBXSX33QnkLK0wN4=
-
-minimist@^0.2.0:
- version "0.2.0"
- resolved "https://registry.npmjs.org/minimist/-/minimist-0.2.0.tgz"
- integrity sha1-Tf/lJdriuGTGbC4jxicdev3s784=
-
-minimist@^1.1.0, minimist@^1.1.3, minimist@^1.2.0:
- version "1.2.0"
- resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz"
- integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=
-
-minimist@^1.2.5:
- version "1.2.5"
- resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz"
- integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
-
-minimist@^1.2.6:
- version "1.2.6"
- resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44"
- integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==
-
-minimist@~0.0.1:
- version "0.0.10"
- resolved "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz"
- integrity sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=
-
-mississippi@^3.0.0:
- version "3.0.0"
- resolved "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz"
- integrity sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==
- dependencies:
- concat-stream "^1.5.0"
- duplexify "^3.4.2"
- end-of-stream "^1.1.0"
- flush-write-stream "^1.0.0"
- from2 "^2.1.0"
- parallel-transform "^1.1.0"
- pump "^3.0.0"
- pumpify "^1.3.3"
- stream-each "^1.1.0"
- through2 "^2.0.0"
-
-mitt@^1.1.3:
- version "1.1.3"
- resolved "https://registry.npmjs.org/mitt/-/mitt-1.1.3.tgz"
- integrity sha512-mUDCnVNsAi+eD6qA0HkRkwYczbLHJ49z17BGe2PYRhZL4wpZUFZGJHU7/5tmvohoma+Hdn0Vh/oJTiPEmgSruA==
-
-mixin-deep@^1.2.0:
- version "1.3.2"
- resolved "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz"
- integrity sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==
- dependencies:
- for-in "^1.0.2"
- is-extendable "^1.0.1"
-
-mkdirp@0.5.1:
- version "0.5.1"
- resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz"
- integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=
- dependencies:
- minimist "0.0.8"
-
-mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@~0.5.1:
- version "0.5.5"
- resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz"
- integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==
- dependencies:
- minimist "^1.2.5"
-
-move-concurrently@^1.0.1:
- version "1.0.1"
- resolved "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz"
- integrity sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=
- dependencies:
- aproba "^1.1.1"
- copy-concurrently "^1.0.0"
- fs-write-stream-atomic "^1.0.8"
- mkdirp "^0.5.1"
- rimraf "^2.5.4"
- run-queue "^1.0.3"
-
-mozjpeg@^6.0.0:
- version "6.0.1"
- resolved "https://registry.npmjs.org/mozjpeg/-/mozjpeg-6.0.1.tgz"
- integrity sha512-9Z59pJMi8ni+IUvSH5xQwK5tNLw7p3dwDNCZ3o1xE+of3G5Hc/yOz6Ue/YuLiBXU3ZB5oaHPURyPdqfBX/QYJA==
- dependencies:
- bin-build "^3.0.0"
- bin-wrapper "^4.0.0"
- logalot "^2.1.0"
-
-ms@2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz"
- integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=
-
-ms@2.1.2, ms@^2.1.1:
- version "2.1.2"
- resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
- integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
-
-multipipe@^0.1.0, multipipe@^0.1.2:
- version "0.1.2"
- resolved "https://registry.npmjs.org/multipipe/-/multipipe-0.1.2.tgz"
- integrity sha1-Ko8t33Du1WTf8tV/HhoTfZ8FB4s=
- dependencies:
- duplexer2 "0.0.2"
-
-mute-stdout@^1.0.0:
- version "1.0.1"
- resolved "https://registry.npmjs.org/mute-stdout/-/mute-stdout-1.0.1.tgz"
- integrity sha512-kDcwXR4PS7caBpuRYYBUz9iVixUk3anO3f5OYFiIPwK/20vCzKCHyKoulbiDY1S53zD2bxUpxN/IJ+TnXjfvxg==
-
-mute-stream@0.0.5:
- version "0.0.5"
- resolved "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz"
- integrity sha1-j7+rsKmKJT0xhDMfno3rc3L6xsA=
-
-mute-stream@0.0.7, mute-stream@~0.0.4:
- version "0.0.7"
- resolved "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz"
- integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=
-
-nan@^2.12.1:
- version "2.14.2"
- resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.2.tgz#f5376400695168f4cc694ac9393d0c9585eeea19"
- integrity sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==
-
-nanoid@^3.1.16:
- version "3.1.16"
- resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.1.16.tgz"
- integrity sha512-+AK8MN0WHji40lj8AEuwLOvLSbWYApQpre/aFJZD71r43wVRLrOYS4FmJOPQYon1TqB462RzrrxlfA74XRES8w==
-
-nanomatch@^1.2.9:
- version "1.2.13"
- resolved "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz"
- integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==
- dependencies:
- arr-diff "^4.0.0"
- array-unique "^0.3.2"
- define-property "^2.0.2"
- extend-shallow "^3.0.2"
- fragment-cache "^0.2.1"
- is-windows "^1.0.2"
- kind-of "^6.0.2"
- object.pick "^1.3.0"
- regex-not "^1.0.0"
- snapdragon "^0.8.1"
- to-regex "^3.0.1"
-
-natives@^1.1.3:
- version "1.1.6"
- resolved "https://registry.npmjs.org/natives/-/natives-1.1.6.tgz"
- integrity sha512-6+TDFewD4yxY14ptjKaS63GVdtKiES1pTPyxn9Jb0rBqPMZ7VcCiooEhPNsr+mqHtMGxa/5c/HhcC4uPEUw/nA==
-
-natural-compare@^1.4.0:
- version "1.4.0"
- resolved "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz"
- integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=
-
-needle@:
- version "2.4.0"
- resolved "https://registry.npmjs.org/needle/-/needle-2.4.0.tgz"
- integrity sha512-4Hnwzr3mi5L97hMYeNl8wRW/Onhy4nUKR/lVemJ8gJedxxUyBLm9kkrDColJvoSfwi0jCNhD+xCdOtiGDQiRZg==
- dependencies:
- debug "^3.2.6"
- iconv-lite "^0.4.4"
- sax "^1.2.4"
-
-negotiator@0.6.2:
- version "0.6.2"
- resolved "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz"
- integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==
-
-neo-async@^2.5.0, neo-async@^2.6.1:
- version "2.6.1"
- resolved "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz"
- integrity sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==
-
-next-tick@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz"
- integrity sha1-yobR/ogoFpsBICCOPchCS524NCw=
-
-nice-try@^1.0.4:
- version "1.0.5"
- resolved "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz"
- integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==
-
-no-case@^2.2.0:
- version "2.3.2"
- resolved "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz"
- integrity sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==
- dependencies:
- lower-case "^1.1.1"
-
-node-libs-browser@^2.2.1:
- version "2.2.1"
- resolved "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz"
- integrity sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==
- dependencies:
- assert "^1.1.1"
- browserify-zlib "^0.2.0"
- buffer "^4.3.0"
- console-browserify "^1.1.0"
- constants-browserify "^1.0.0"
- crypto-browserify "^3.11.0"
- domain-browser "^1.1.1"
- events "^3.0.0"
- https-browserify "^1.0.0"
- os-browserify "^0.3.0"
- path-browserify "0.0.1"
- process "^0.11.10"
- punycode "^1.2.4"
- querystring-es3 "^0.2.0"
- readable-stream "^2.3.3"
- stream-browserify "^2.0.1"
- stream-http "^2.7.2"
- string_decoder "^1.0.0"
- timers-browserify "^2.0.4"
- tty-browserify "0.0.0"
- url "^0.11.0"
- util "^0.11.0"
- vm-browserify "^1.0.1"
-
-node-releases@^1.1.29:
- version "1.1.32"
- resolved "https://registry.npmjs.org/node-releases/-/node-releases-1.1.32.tgz"
- integrity sha512-VhVknkitq8dqtWoluagsGPn3dxTvN9fwgR59fV3D7sLBHe0JfDramsMI8n8mY//ccq/Kkrf8ZRHRpsyVZ3qw1A==
- dependencies:
- semver "^5.3.0"
-
-node-sri@^1.1.1:
- version "1.1.1"
- resolved "https://registry.npmjs.org/node-sri/-/node-sri-1.1.1.tgz"
- integrity sha1-BBCW0rEfIytl3txMOuHLYrq7VLA=
-
-node.extend@^1.0.10:
- version "1.1.8"
- resolved "https://registry.npmjs.org/node.extend/-/node.extend-1.1.8.tgz"
- integrity sha512-L/dvEBwyg3UowwqOUTyDsGBU6kjBQOpOhshio9V3i3BMPv5YUb9+mWNN8MK0IbWqT0AqaTSONZf0aTuMMahWgA==
- dependencies:
- has "^1.0.3"
- is "^3.2.1"
-
-nopt@~4.0.1:
- version "4.0.1"
- resolved "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz"
- integrity sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=
- dependencies:
- abbrev "1"
- osenv "^0.1.4"
-
-normalize-package-data@^2.3.2, normalize-package-data@^2.3.4:
- version "2.5.0"
- resolved "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz"
- integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==
- dependencies:
- hosted-git-info "^2.1.4"
- resolve "^1.10.0"
- semver "2 || 3 || 4 || 5"
- validate-npm-package-license "^3.0.1"
-
-normalize-path@^2.1.1:
- version "2.1.1"
- resolved "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz"
- integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=
- dependencies:
- remove-trailing-separator "^1.0.1"
-
-normalize-path@^3.0.0, normalize-path@~3.0.0:
- version "3.0.0"
- resolved "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz"
- integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==
-
-normalize-range@^0.1.2:
- version "0.1.2"
- resolved "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz"
- integrity sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=
-
-normalize-url@2.0.1:
- version "2.0.1"
- resolved "https://registry.npmjs.org/normalize-url/-/normalize-url-2.0.1.tgz"
- integrity sha512-D6MUW4K/VzoJ4rJ01JFKxDrtY1v9wrgzCX5f2qj/lzH1m/lW6MhUZFKerVsnyjOhOsYzI9Kqqak+10l4LvLpMw==
- dependencies:
- prepend-http "^2.0.0"
- query-string "^5.0.1"
- sort-keys "^2.0.0"
-
-normalize-url@^3.0.0:
- version "3.3.0"
- resolved "https://registry.npmjs.org/normalize-url/-/normalize-url-3.3.0.tgz"
- integrity sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg==
-
-normalize-url@^4.1.0:
- version "4.4.1"
- resolved "https://registry.npmjs.org/normalize-url/-/normalize-url-4.4.1.tgz"
- integrity sha512-rjH3yRt0Ssx19mUwS0hrDUOdG9VI+oRLpLHJ7tXRdjcuQ7v7wo6qPvOZppHRrqfslTKr0L2yBhjj4UXd7c3cQg==
-
-now-and-later@^2.0.0:
- version "2.0.1"
- resolved "https://registry.npmjs.org/now-and-later/-/now-and-later-2.0.1.tgz"
- integrity sha512-KGvQ0cB70AQfg107Xvs/Fbu+dGmZoTRJp2TaPwcwQm3/7PteUyN2BCgk8KBMPGBUXZdVwyWS8fDCGFygBm19UQ==
- dependencies:
- once "^1.3.2"
-
-npm-conf@^1.1.0, npm-conf@^1.1.3:
- version "1.1.3"
- resolved "https://registry.npmjs.org/npm-conf/-/npm-conf-1.1.3.tgz"
- integrity sha512-Yic4bZHJOt9RCFbRP3GgpqhScOY4HH3V2P8yBj6CeYq118Qr+BLXqT2JvpJ00mryLESpgOxf5XlFv4ZjXxLScw==
- dependencies:
- config-chain "^1.1.11"
- pify "^3.0.0"
-
-npm-run-path@^2.0.0:
- version "2.0.2"
- resolved "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz"
- integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=
- dependencies:
- path-key "^2.0.0"
-
-npm-run-path@^4.0.0, npm-run-path@^4.0.1:
- version "4.0.1"
- resolved "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz"
- integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==
- dependencies:
- path-key "^3.0.0"
-
-nth-check@^1.0.2:
- version "1.0.2"
- resolved "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz"
- integrity sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==
- dependencies:
- boolbase "~1.0.0"
-
-num2fraction@^1.2.2:
- version "1.2.2"
- resolved "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz"
- integrity sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=
-
-number-is-nan@^1.0.0:
- version "1.0.1"
- resolved "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz"
- integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=
-
-nwsapi@^2.0.9:
- version "2.1.4"
- resolved "https://registry.npmjs.org/nwsapi/-/nwsapi-2.1.4.tgz"
- integrity sha512-iGfd9Y6SFdTNldEy2L0GUhcarIutFmk+MPWIn9dmj8NMIup03G08uUF2KGbbmv/Ux4RT0VZJoP/sVbWA6d/VIw==
-
-oauth-sign@~0.9.0:
- version "0.9.0"
- resolved "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz"
- integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==
-
-object-assign@^3.0.0:
- version "3.0.0"
- resolved "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz"
- integrity sha1-m+3VygiXlJvKR+f/QIBi1Un1h/I=
-
-object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1:
- version "4.1.1"
- resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz"
- integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=
-
-object-assign@~0.3.1:
- version "0.3.1"
- resolved "https://registry.npmjs.org/object-assign/-/object-assign-0.3.1.tgz"
- integrity sha1-Bg4qKifXwNd+x3t48Rqkf9iACNI=
-
-object-component@0.0.3:
- version "0.0.3"
- resolved "https://registry.npmjs.org/object-component/-/object-component-0.0.3.tgz"
- integrity sha1-8MaapQ78lbhmwYb0AKM3acsvEpE=
-
-object-copy@^0.1.0:
- version "0.1.0"
- resolved "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz"
- integrity sha1-fn2Fi3gb18mRpBupde04EnVOmYw=
- dependencies:
- copy-descriptor "^0.1.0"
- define-property "^0.2.5"
- kind-of "^3.0.3"
-
-object-inspect@^1.6.0:
- version "1.6.0"
- resolved "https://registry.npmjs.org/object-inspect/-/object-inspect-1.6.0.tgz"
- integrity sha512-GJzfBZ6DgDAmnuaM3104jR4s1Myxr3Y3zfIyN4z3UdqN69oSRacNK8UhnobDdC+7J2AHCjGwxQubNJfE70SXXQ==
-
-object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.1.1:
- version "1.1.1"
- resolved "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz"
- integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==
-
-object-keys@~0.4.0:
- version "0.4.0"
- resolved "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz"
- integrity sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=
-
-object-path@^0.9.0:
- version "0.9.2"
- resolved "https://registry.npmjs.org/object-path/-/object-path-0.9.2.tgz"
- integrity sha1-D9mnT8X60a45aLWGvaXGMr1sBaU=
-
-object-visit@^1.0.0:
- version "1.0.1"
- resolved "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz"
- integrity sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=
- dependencies:
- isobject "^3.0.0"
-
-object.assign@^4.0.4, object.assign@^4.1.0:
- version "4.1.0"
- resolved "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz"
- integrity sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==
- dependencies:
- define-properties "^1.1.2"
- function-bind "^1.1.1"
- has-symbols "^1.0.0"
- object-keys "^1.0.11"
-
-object.defaults@^1.0.0, object.defaults@^1.1.0:
- version "1.1.0"
- resolved "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz"
- integrity sha1-On+GgzS0B96gbaFtiNXNKeQ1/s8=
- dependencies:
- array-each "^1.0.1"
- array-slice "^1.0.0"
- for-own "^1.0.0"
- isobject "^3.0.0"
-
-object.getownpropertydescriptors@^2.0.3:
- version "2.0.3"
- resolved "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz"
- integrity sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY=
- dependencies:
- define-properties "^1.1.2"
- es-abstract "^1.5.1"
-
-object.map@^1.0.0:
- version "1.0.1"
- resolved "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz"
- integrity sha1-z4Plncj8wK1fQlDh94s7gb2AHTc=
- dependencies:
- for-own "^1.0.0"
- make-iterator "^1.0.0"
-
-object.pick@^1.2.0, object.pick@^1.3.0:
- version "1.3.0"
- resolved "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz"
- integrity sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=
- dependencies:
- isobject "^3.0.1"
-
-object.reduce@^1.0.0:
- version "1.0.1"
- resolved "https://registry.npmjs.org/object.reduce/-/object.reduce-1.0.1.tgz"
- integrity sha1-b+NI8qx/oPlcpiEiZZkJaCW7A60=
- dependencies:
- for-own "^1.0.0"
- make-iterator "^1.0.0"
-
-object.values@^1.1.0:
- version "1.1.0"
- resolved "https://registry.npmjs.org/object.values/-/object.values-1.1.0.tgz"
- integrity sha512-8mf0nKLAoFX6VlNVdhGj31SVYpaNFtUnuoOXWyFEstsWRgU837AK+JYM0iAxwkSzGRbwn8cbFmgbyxj1j4VbXg==
- dependencies:
- define-properties "^1.1.3"
- es-abstract "^1.12.0"
- function-bind "^1.1.1"
- has "^1.0.3"
-
-omggif@^1.0.9:
- version "1.0.10"
- resolved "https://registry.npmjs.org/omggif/-/omggif-1.0.10.tgz"
- integrity sha512-LMJTtvgc/nugXj0Vcrrs68Mn2D1r0zf630VNtqtpI1FEO7e+O9FP4gqs9AcnBaSEeoHIPm28u6qgPR0oyEpGSw==
-
-on-finished@2.1.0:
- version "2.1.0"
- resolved "https://registry.npmjs.org/on-finished/-/on-finished-2.1.0.tgz"
- integrity sha1-DFOfCSkej/rd4MiiWFD7LO3HAi0=
- dependencies:
- ee-first "1.0.5"
-
-on-finished@~2.3.0:
- version "2.3.0"
- resolved "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz"
- integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=
- dependencies:
- ee-first "1.1.1"
-
-once@^1.3.0, once@^1.3.1, once@^1.3.2, once@^1.4.0:
- version "1.4.0"
- resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz"
- integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E=
- dependencies:
- wrappy "1"
-
-once@~1.3.0:
- version "1.3.3"
- resolved "https://registry.npmjs.org/once/-/once-1.3.3.tgz"
- integrity sha1-suJhVXzkwxTsgwTz+oJmPkKXyiA=
- dependencies:
- wrappy "1"
-
-onetime@^1.0.0:
- version "1.1.0"
- resolved "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz"
- integrity sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=
-
-onetime@^2.0.0:
- version "2.0.1"
- resolved "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz"
- integrity sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=
- dependencies:
- mimic-fn "^1.0.0"
-
-onetime@^5.1.0, onetime@^5.1.2:
- version "5.1.2"
- resolved "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz"
- integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==
- dependencies:
- mimic-fn "^2.1.0"
-
-open@^0.0.5:
- version "0.0.5"
- resolved "https://registry.npmjs.org/open/-/open-0.0.5.tgz"
- integrity sha1-QsPhjslUZra/DcQvOilFw/DK2Pw=
-
-openurl@1.1.1:
- version "1.1.1"
- resolved "https://registry.npmjs.org/openurl/-/openurl-1.1.1.tgz"
- integrity sha1-OHW0sO96UsFW8NtB1GCduw+Us4c=
-
-opn@5.3.0:
- version "5.3.0"
- resolved "https://registry.npmjs.org/opn/-/opn-5.3.0.tgz"
- integrity sha512-bYJHo/LOmoTd+pfiYhfZDnf9zekVJrY+cnS2a5F2x+w5ppvTqObojTP7WiFG+kVZs9Inw+qQ/lw7TroWwhdd2g==
- dependencies:
- is-wsl "^1.1.0"
-
-optimist@~0.6.1:
- version "0.6.1"
- resolved "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz"
- integrity sha1-2j6nRob6IaGaERwybpDrFaAZZoY=
- dependencies:
- minimist "~0.0.1"
- wordwrap "~0.0.2"
-
-optionator@^0.8.1, optionator@^0.8.2:
- version "0.8.2"
- resolved "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz"
- integrity sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=
- dependencies:
- deep-is "~0.1.3"
- fast-levenshtein "~2.0.4"
- levn "~0.3.0"
- prelude-ls "~1.1.2"
- type-check "~0.3.2"
- wordwrap "~1.0.0"
-
-optipng-bin@^6.0.0:
- version "6.0.0"
- resolved "https://registry.npmjs.org/optipng-bin/-/optipng-bin-6.0.0.tgz"
- integrity sha512-95bB4y8IaTsa/8x6QH4bLUuyvyOoGBCLDA7wOgDL8UFqJpSUh1Hob8JRJhit+wC1ZLN3tQ7mFt7KuBj0x8F2Wg==
- dependencies:
- bin-build "^3.0.0"
- bin-wrapper "^4.0.0"
- logalot "^2.0.0"
-
-orchestrator@^0.3.0:
- version "0.3.8"
- resolved "https://registry.npmjs.org/orchestrator/-/orchestrator-0.3.8.tgz"
- integrity sha1-FOfp4nZPcxX7rBhOUGx6pt+UrX4=
- dependencies:
- end-of-stream "~0.1.5"
- sequencify "~0.0.7"
- stream-consume "~0.1.0"
-
-ordered-read-streams@^0.1.0:
- version "0.1.0"
- resolved "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-0.1.0.tgz"
- integrity sha1-/VZamvjrRHO6abbtijQ1LLVS8SY=
-
-ordered-read-streams@^1.0.0:
- version "1.0.1"
- resolved "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz"
- integrity sha1-d8DLN8QVJdZBZtmQ/61+xqDhNj4=
- dependencies:
- readable-stream "^2.0.1"
-
-os-browserify@^0.3.0:
- version "0.3.0"
- resolved "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz"
- integrity sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=
-
-os-filter-obj@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/os-filter-obj/-/os-filter-obj-2.0.0.tgz"
- integrity sha512-uksVLsqG3pVdzzPvmAHpBK0wKxYItuzZr7SziusRPoz67tGV8rL1szZ6IdeUrbqLjGDwApBtN29eEE3IqGHOjg==
- dependencies:
- arch "^2.1.0"
-
-os-homedir@^1.0.0:
- version "1.0.2"
- resolved "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz"
- integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M=
-
-os-locale@^1.4.0:
- version "1.4.0"
- resolved "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz"
- integrity sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=
- dependencies:
- lcid "^1.0.0"
-
-os-locale@^3.1.0:
- version "3.1.0"
- resolved "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz"
- integrity sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==
- dependencies:
- execa "^1.0.0"
- lcid "^2.0.0"
- mem "^4.0.0"
-
-os-tmpdir@^1.0.0, os-tmpdir@^1.0.1, os-tmpdir@~1.0.2:
- version "1.0.2"
- resolved "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz"
- integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=
-
-osenv@^0.1.4:
- version "0.1.5"
- resolved "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz"
- integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==
- dependencies:
- os-homedir "^1.0.0"
- os-tmpdir "^1.0.0"
-
-ow@^0.17.0:
- version "0.17.0"
- resolved "https://registry.npmjs.org/ow/-/ow-0.17.0.tgz"
- integrity sha512-i3keDzDQP5lWIe4oODyDFey1qVrq2hXKTuTH2VpqwpYtzPiKZt2ziRI4NBQmgW40AnV5Euz17OyWweCb+bNEQA==
- dependencies:
- type-fest "^0.11.0"
-
-p-cancelable@^0.3.0:
- version "0.3.0"
- resolved "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.3.0.tgz"
- integrity sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw==
-
-p-cancelable@^0.4.0:
- version "0.4.1"
- resolved "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.4.1.tgz"
- integrity sha512-HNa1A8LvB1kie7cERyy21VNeHb2CWJJYqyyC2o3klWFfMGlFmWv2Z7sFgZH8ZiaYL95ydToKTFVXgMV/Os0bBQ==
-
-p-cancelable@^1.0.0:
- version "1.1.0"
- resolved "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz"
- integrity sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==
-
-p-defer@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz"
- integrity sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=
-
-p-event@^1.0.0:
- version "1.3.0"
- resolved "https://registry.npmjs.org/p-event/-/p-event-1.3.0.tgz"
- integrity sha1-jmtPT2XHK8W2/ii3XtqHT5akoIU=
- dependencies:
- p-timeout "^1.1.1"
-
-p-event@^2.1.0:
- version "2.3.1"
- resolved "https://registry.npmjs.org/p-event/-/p-event-2.3.1.tgz"
- integrity sha512-NQCqOFhbpVTMX4qMe8PF8lbGtzZ+LCiN7pcNrb/413Na7+TRoe1xkKUzuWa/YEJdGQ0FvKtj35EEbDoVPO2kbA==
- dependencies:
- p-timeout "^2.0.1"
-
-p-finally@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz"
- integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=
-
-p-is-promise@^1.1.0:
- version "1.1.0"
- resolved "https://registry.npmjs.org/p-is-promise/-/p-is-promise-1.1.0.tgz"
- integrity sha1-nJRWmJ6fZYgBewQ01WCXZ1w9oF4=
-
-p-is-promise@^2.0.0:
- version "2.1.0"
- resolved "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz"
- integrity sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==
-
-p-limit@^1.1.0:
- version "1.3.0"
- resolved "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz"
- integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==
- dependencies:
- p-try "^1.0.0"
-
-p-limit@^2.0.0, p-limit@^2.2.0:
- version "2.2.1"
- resolved "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz"
- integrity sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==
- dependencies:
- p-try "^2.0.0"
-
-p-locate@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz"
- integrity sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=
- dependencies:
- p-limit "^1.1.0"
-
-p-locate@^3.0.0:
- version "3.0.0"
- resolved "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz"
- integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==
- dependencies:
- p-limit "^2.0.0"
-
-p-locate@^4.1.0:
- version "4.1.0"
- resolved "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz"
- integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==
- dependencies:
- p-limit "^2.2.0"
-
-p-map-series@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/p-map-series/-/p-map-series-1.0.0.tgz"
- integrity sha1-v5j+V1cFZYqeE1G++4WuTB8Hvco=
- dependencies:
- p-reduce "^1.0.0"
-
-p-pipe@^3.0.0:
- version "3.1.0"
- resolved "https://registry.npmjs.org/p-pipe/-/p-pipe-3.1.0.tgz"
- integrity sha512-08pj8ATpzMR0Y80x50yJHn37NF6vjrqHutASaX5LiH5npS9XPvrUmscd9MF5R4fuYRHOxQR1FfMIlF7AzwoPqw==
-
-p-reduce@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/p-reduce/-/p-reduce-1.0.0.tgz"
- integrity sha1-GMKw3ZNqRpClKfgjH1ig/bakffo=
-
-p-timeout@^1.1.1:
- version "1.2.1"
- resolved "https://registry.npmjs.org/p-timeout/-/p-timeout-1.2.1.tgz"
- integrity sha1-XrOzU7f86Z8QGhA4iAuwVOu+o4Y=
- dependencies:
- p-finally "^1.0.0"
-
-p-timeout@^2.0.1:
- version "2.0.1"
- resolved "https://registry.npmjs.org/p-timeout/-/p-timeout-2.0.1.tgz"
- integrity sha512-88em58dDVB/KzPEx1X0N3LwFfYZPyDc4B6eF38M1rk9VTZMbxXXgjugz8mmwpS9Ox4BDZ+t6t3QP5+/gazweIA==
- dependencies:
- p-finally "^1.0.0"
-
-p-try@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz"
- integrity sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=
-
-p-try@^2.0.0:
- version "2.2.0"
- resolved "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz"
- integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==
-
-pako@^1.0.5, pako@~1.0.5:
- version "1.0.10"
- resolved "https://registry.npmjs.org/pako/-/pako-1.0.10.tgz"
- integrity sha512-0DTvPVU3ed8+HNXOu5Bs+o//Mbdj9VNQMUOe9oKCwh8l0GNwpTDMKCWbRjgtD291AWnkAgkqA/LOnQS8AmS1tw==
-
-parallel-transform@^1.1.0:
- version "1.2.0"
- resolved "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz"
- integrity sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==
- dependencies:
- cyclist "^1.0.1"
- inherits "^2.0.3"
- readable-stream "^2.1.5"
-
-param-case@2.1.x:
- version "2.1.1"
- resolved "https://registry.npmjs.org/param-case/-/param-case-2.1.1.tgz"
- integrity sha1-35T9jPZTHs915r75oIWPvHK+Ikc=
- dependencies:
- no-case "^2.2.0"
-
-parent-module@^1.0.0:
- version "1.0.1"
- resolved "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz"
- integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==
- dependencies:
- callsites "^3.0.0"
-
-parents@~1.0.0:
- version "1.0.1"
- resolved "https://registry.npmjs.org/parents/-/parents-1.0.1.tgz"
- integrity sha1-/t1NK/GTp3dF/nHjcdc8MwfZx1E=
- dependencies:
- path-platform "~0.11.15"
-
-parse-asn1@^5.0.0:
- version "5.1.5"
- resolved "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.5.tgz"
- integrity sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ==
- dependencies:
- asn1.js "^4.0.0"
- browserify-aes "^1.0.0"
- create-hash "^1.1.0"
- evp_bytestokey "^1.0.0"
- pbkdf2 "^3.0.3"
- safe-buffer "^5.1.1"
-
-parse-author@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/parse-author/-/parse-author-2.0.0.tgz"
- integrity sha1-00YL8d3Q367tQtp1QkLmX7aEqB8=
- dependencies:
- author-regex "^1.0.0"
-
-parse-bmfont-ascii@^1.0.3:
- version "1.0.6"
- resolved "https://registry.npmjs.org/parse-bmfont-ascii/-/parse-bmfont-ascii-1.0.6.tgz"
- integrity sha1-Eaw8P/WPfCAgqyJ2kHkQjU36AoU=
-
-parse-bmfont-binary@^1.0.5:
- version "1.0.6"
- resolved "https://registry.npmjs.org/parse-bmfont-binary/-/parse-bmfont-binary-1.0.6.tgz"
- integrity sha1-0Di0dtPp3Z2x4RoLDlOiJ5K2kAY=
-
-parse-bmfont-xml@^1.1.4:
- version "1.1.4"
- resolved "https://registry.npmjs.org/parse-bmfont-xml/-/parse-bmfont-xml-1.1.4.tgz"
- integrity sha512-bjnliEOmGv3y1aMEfREMBJ9tfL3WR0i0CKPj61DnSLaoxWR3nLrsQrEbCId/8rF4NyRF0cCqisSVXyQYWM+mCQ==
- dependencies:
- xml-parse-from-string "^1.0.0"
- xml2js "^0.4.5"
-
-parse-filepath@^1.0.1:
- version "1.0.2"
- resolved "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz"
- integrity sha1-pjISf1Oq89FYdvWHLz/6x2PWyJE=
- dependencies:
- is-absolute "^1.0.0"
- map-cache "^0.2.0"
- path-root "^0.1.1"
-
-parse-headers@^2.0.0:
- version "2.0.2"
- resolved "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.2.tgz"
- integrity sha512-/LypJhzFmyBIDYP9aDVgeyEb5sQfbfY5mnDq4hVhlQ69js87wXfmEI5V3xI6vvXasqebp0oCytYFLxsBVfCzSg==
- dependencies:
- for-each "^0.3.3"
- string.prototype.trim "^1.1.2"
-
-parse-json@^2.2.0:
- version "2.2.0"
- resolved "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz"
- integrity sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=
- dependencies:
- error-ex "^1.2.0"
-
-parse-json@^4.0.0:
- version "4.0.0"
- resolved "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz"
- integrity sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=
- dependencies:
- error-ex "^1.3.1"
- json-parse-better-errors "^1.0.1"
-
-parse-node-version@^1.0.0:
- version "1.0.1"
- resolved "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz"
- integrity sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==
-
-parse-passwd@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz"
- integrity sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=
-
-parse5@5.1.0:
- version "5.1.0"
- resolved "https://registry.npmjs.org/parse5/-/parse5-5.1.0.tgz"
- integrity sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==
-
-parseqs@0.0.5:
- version "0.0.5"
- resolved "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz"
- integrity sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=
- dependencies:
- better-assert "~1.0.0"
-
-parseuri@0.0.5:
- version "0.0.5"
- resolved "https://registry.npmjs.org/parseuri/-/parseuri-0.0.5.tgz"
- integrity sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=
- dependencies:
- better-assert "~1.0.0"
-
-parseurl@~1.3.0, parseurl@~1.3.2:
- version "1.3.3"
- resolved "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz"
- integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==
-
-pascalcase@^0.1.1:
- version "0.1.1"
- resolved "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz"
- integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=
-
-path-browserify@0.0.1:
- version "0.0.1"
- resolved "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz"
- integrity sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==
-
-path-dirname@^1.0.0:
- version "1.0.2"
- resolved "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz"
- integrity sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=
-
-path-exists@^2.0.0:
- version "2.1.0"
- resolved "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz"
- integrity sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=
- dependencies:
- pinkie-promise "^2.0.0"
-
-path-exists@^3.0.0:
- version "3.0.0"
- resolved "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz"
- integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=
-
-path-exists@^4.0.0:
- version "4.0.0"
- resolved "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz"
- integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==
-
-path-is-absolute@^1.0.0, path-is-absolute@^1.0.1:
- version "1.0.1"
- resolved "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz"
- integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18=
-
-path-is-inside@^1.0.1, path-is-inside@^1.0.2:
- version "1.0.2"
- resolved "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz"
- integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=
-
-path-key@^2.0.0, path-key@^2.0.1:
- version "2.0.1"
- resolved "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz"
- integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=
-
-path-key@^3.0.0, path-key@^3.1.0:
- version "3.1.1"
- resolved "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz"
- integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==
-
-path-parse@^1.0.6:
- version "1.0.6"
- resolved "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz"
- integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==
-
-path-platform@~0.11.15:
- version "0.11.15"
- resolved "https://registry.npmjs.org/path-platform/-/path-platform-0.11.15.tgz"
- integrity sha1-6GQhf3TDaFDwhSt43Hv31KVyG/I=
-
-path-root-regex@^0.1.0:
- version "0.1.2"
- resolved "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz"
- integrity sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=
-
-path-root@^0.1.1:
- version "0.1.1"
- resolved "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz"
- integrity sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc=
- dependencies:
- path-root-regex "^0.1.0"
-
-path-starts-with@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/path-starts-with/-/path-starts-with-2.0.0.tgz"
- integrity sha512-3UHTHbJz5+NLkPafFR+2ycJOjoc4WV2e9qCZCnm71zHiWaFrm1XniLVTkZXvaRgxr1xFh9JsTdicpH2yM03nLA==
-
-path-type@^1.0.0:
- version "1.1.0"
- resolved "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz"
- integrity sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=
- dependencies:
- graceful-fs "^4.1.2"
- pify "^2.0.0"
- pinkie-promise "^2.0.0"
-
-path-type@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz"
- integrity sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=
- dependencies:
- pify "^2.0.0"
-
-path-type@^4.0.0:
- version "4.0.0"
- resolved "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz"
- integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==
-
-pbkdf2@^3.0.3:
- version "3.0.17"
- resolved "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz"
- integrity sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==
- dependencies:
- create-hash "^1.1.2"
- create-hmac "^1.1.4"
- ripemd160 "^2.0.1"
- safe-buffer "^5.0.1"
- sha.js "^2.4.8"
-
-pend@~1.2.0:
- version "1.2.0"
- resolved "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz"
- integrity sha1-elfrVQpng/kRUzH89GY9XI4AelA=
-
-performance-now@^2.1.0:
- version "2.1.0"
- resolved "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz"
- integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=
-
-phin@^2.9.1:
- version "2.9.3"
- resolved "https://registry.npmjs.org/phin/-/phin-2.9.3.tgz"
- integrity sha512-CzFr90qM24ju5f88quFC/6qohjC144rehe5n6DH900lgXmUe86+xCKc10ev56gRKC4/BkHUoG4uSiQgBiIXwDA==
-
-phonegap-plugin-mobile-accessibility@^1.0.5:
- version "1.0.5"
- resolved "https://registry.npmjs.org/phonegap-plugin-mobile-accessibility/-/phonegap-plugin-mobile-accessibility-1.0.5.tgz"
- integrity sha1-lah1TRJ1CLxuGuJZpTznZYNurAM=
-
-picomatch@^2.0.4, picomatch@^2.0.5, picomatch@^2.2.1:
- version "2.2.2"
- resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz"
- integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==
-
-pify@^2.0.0, pify@^2.2.0, pify@^2.3.0:
- version "2.3.0"
- resolved "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz"
- integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw=
-
-pify@^3.0.0:
- version "3.0.0"
- resolved "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz"
- integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=
-
-pify@^4.0.1:
- version "4.0.1"
- resolved "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz"
- integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==
-
-pinkie-promise@^2.0.0:
- version "2.0.1"
- resolved "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz"
- integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o=
- dependencies:
- pinkie "^2.0.0"
-
-pinkie@^2.0.0:
- version "2.0.4"
- resolved "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz"
- integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA=
-
-pixelmatch@^4.0.2:
- version "4.0.2"
- resolved "https://registry.npmjs.org/pixelmatch/-/pixelmatch-4.0.2.tgz"
- integrity sha1-j0fc7FARtHe2fbA8JDvB8wheiFQ=
- dependencies:
- pngjs "^3.0.0"
-
-pkg-dir@^3.0.0:
- version "3.0.0"
- resolved "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz"
- integrity sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==
- dependencies:
- find-up "^3.0.0"
-
-pkginfo@0.3.x:
- version "0.3.1"
- resolved "https://registry.npmjs.org/pkginfo/-/pkginfo-0.3.1.tgz"
- integrity sha1-Wyn2qB9wcXFC4J52W76rl7T4HiE=
-
-plist@^3.0.0:
- version "3.0.1"
- resolved "https://registry.npmjs.org/plist/-/plist-3.0.1.tgz"
- integrity sha512-GpgvHHocGRyQm74b6FWEZZVRroHKE1I0/BTjAmySaohK+cUn+hZpbqXkc3KWgW3gQYkqcQej35FohcT0FRlkRQ==
- dependencies:
- base64-js "^1.2.3"
- xmlbuilder "^9.0.7"
- xmldom "0.1.x"
-
-plist@^3.0.1, plist@^3.0.5:
- version "3.0.5"
- resolved "https://registry.yarnpkg.com/plist/-/plist-3.0.5.tgz#2cbeb52d10e3cdccccf0c11a63a85d830970a987"
- integrity sha512-83vX4eYdQp3vP9SxuYgEM/G/pJQqLUz/V/xzPrzruLs7fz7jxGQ1msZ/mg1nwZxUSuOp4sb+/bEIbRrbzZRxDA==
- dependencies:
- base64-js "^1.5.1"
- xmlbuilder "^9.0.7"
-
-plugin-error@1.0.1, plugin-error@^1.0.1:
- version "1.0.1"
- resolved "https://registry.npmjs.org/plugin-error/-/plugin-error-1.0.1.tgz"
- integrity sha512-L1zP0dk7vGweZME2i+EeakvUNqSrdiI3F91TwEoYiGrAfUXmVv6fJIq4g82PAXxNsWOp0J7ZqQy/3Szz0ajTxA==
- dependencies:
- ansi-colors "^1.0.1"
- arr-diff "^4.0.0"
- arr-union "^3.1.0"
- extend-shallow "^3.0.2"
-
-plugin-error@^0.1.2:
- version "0.1.2"
- resolved "https://registry.npmjs.org/plugin-error/-/plugin-error-0.1.2.tgz"
- integrity sha1-O5uzM1zPAPQl4HQ34ZJ2ln2kes4=
- dependencies:
- ansi-cyan "^0.1.1"
- ansi-red "^0.1.1"
- arr-diff "^1.0.1"
- arr-union "^2.0.1"
- extend-shallow "^1.1.2"
-
-plur@^3.0.1:
- version "3.1.1"
- resolved "https://registry.npmjs.org/plur/-/plur-3.1.1.tgz"
- integrity sha512-t1Ax8KUvV3FFII8ltczPn2tJdjqbd1sIzu6t4JL7nQ3EyeL/lTrj5PWKb06ic5/6XYDr65rQ4uzQEGN70/6X5w==
- dependencies:
- irregular-plurals "^2.0.0"
-
-pluralize@^1.2.1:
- version "1.2.1"
- resolved "https://registry.npmjs.org/pluralize/-/pluralize-1.2.1.tgz"
- integrity sha1-0aIUg/0iu0HlihL6NCGCMUCJfEU=
-
-pn@^1.1.0:
- version "1.1.0"
- resolved "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz"
- integrity sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==
-
-pngjs@^3.0.0, pngjs@^3.3.3:
- version "3.4.0"
- resolved "https://registry.npmjs.org/pngjs/-/pngjs-3.4.0.tgz"
- integrity sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==
-
-pngquant-bin@^5.0.2:
- version "5.0.2"
- resolved "https://registry.npmjs.org/pngquant-bin/-/pngquant-bin-5.0.2.tgz"
- integrity sha512-OLdT+4JZx5BqE1CFJkrvomYV0aSsv6x2Bba+aWaVc0PMfWlE+ZByNKYAdKeIqsM4uvW1HOSEHnf8KcOnykPNxA==
- dependencies:
- bin-build "^3.0.0"
- bin-wrapper "^4.0.1"
- execa "^0.10.0"
- logalot "^2.0.0"
-
-pngquant-bin@^6.0.0:
- version "6.0.0"
- resolved "https://registry.npmjs.org/pngquant-bin/-/pngquant-bin-6.0.0.tgz"
- integrity sha512-oXWAS9MQ9iiDAJRdAZ9KO1mC5UwhzKkJsmetiu0iqIjJuW7JsuLhmc4JdRm7uJkIWRzIAou/Vq2VcjfJwz30Ow==
- dependencies:
- bin-build "^3.0.0"
- bin-wrapper "^4.0.1"
- execa "^4.0.0"
- logalot "^2.0.0"
-
-portscanner@2.1.1:
- version "2.1.1"
- resolved "https://registry.npmjs.org/portscanner/-/portscanner-2.1.1.tgz"
- integrity sha1-6rtAnk3iSVD1oqUW01rnaTQ/u5Y=
- dependencies:
- async "1.5.2"
- is-number-like "^1.0.3"
-
-posix-character-classes@^0.1.0:
- version "0.1.1"
- resolved "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz"
- integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=
-
-postcss-assets@^5.0.0:
- version "5.0.0"
- resolved "https://registry.npmjs.org/postcss-assets/-/postcss-assets-5.0.0.tgz"
- integrity sha1-9yHQfTOWBftYQU6fac8FQBxU5wk=
- dependencies:
- assets "^3.0.0"
- bluebird "^3.5.0"
- postcss "^6.0.10"
- postcss-functions "^3.0.0"
-
-postcss-attribute-case-insensitive@^4.0.1:
- version "4.0.1"
- resolved "https://registry.npmjs.org/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-4.0.1.tgz"
- integrity sha512-L2YKB3vF4PetdTIthQVeT+7YiSzMoNMLLYxPXXppOOP7NoazEAy45sh2LvJ8leCQjfBcfkYQs8TtCcQjeZTp8A==
- dependencies:
- postcss "^7.0.2"
- postcss-selector-parser "^5.0.0"
-
-postcss-calc@^7.0.1:
- version "7.0.1"
- resolved "https://registry.npmjs.org/postcss-calc/-/postcss-calc-7.0.1.tgz"
- integrity sha512-oXqx0m6tb4N3JGdmeMSc/i91KppbYsFZKdH0xMOqK8V1rJlzrKlTdokz8ozUXLVejydRN6u2IddxpcijRj2FqQ==
- dependencies:
- css-unit-converter "^1.1.1"
- postcss "^7.0.5"
- postcss-selector-parser "^5.0.0-rc.4"
- postcss-value-parser "^3.3.1"
-
-postcss-color-functional-notation@^2.0.1:
- version "2.0.1"
- resolved "https://registry.npmjs.org/postcss-color-functional-notation/-/postcss-color-functional-notation-2.0.1.tgz"
- integrity sha512-ZBARCypjEDofW4P6IdPVTLhDNXPRn8T2s1zHbZidW6rPaaZvcnCS2soYFIQJrMZSxiePJ2XIYTlcb2ztr/eT2g==
- dependencies:
- postcss "^7.0.2"
- postcss-values-parser "^2.0.0"
-
-postcss-color-gray@^5.0.0:
- version "5.0.0"
- resolved "https://registry.npmjs.org/postcss-color-gray/-/postcss-color-gray-5.0.0.tgz"
- integrity sha512-q6BuRnAGKM/ZRpfDascZlIZPjvwsRye7UDNalqVz3s7GDxMtqPY6+Q871liNxsonUw8oC61OG+PSaysYpl1bnw==
- dependencies:
- "@csstools/convert-colors" "^1.4.0"
- postcss "^7.0.5"
- postcss-values-parser "^2.0.0"
-
-postcss-color-hex-alpha@^5.0.3:
- version "5.0.3"
- resolved "https://registry.npmjs.org/postcss-color-hex-alpha/-/postcss-color-hex-alpha-5.0.3.tgz"
- integrity sha512-PF4GDel8q3kkreVXKLAGNpHKilXsZ6xuu+mOQMHWHLPNyjiUBOr75sp5ZKJfmv1MCus5/DWUGcK9hm6qHEnXYw==
- dependencies:
- postcss "^7.0.14"
- postcss-values-parser "^2.0.1"
-
-postcss-color-mod-function@^3.0.3:
- version "3.0.3"
- resolved "https://registry.npmjs.org/postcss-color-mod-function/-/postcss-color-mod-function-3.0.3.tgz"
- integrity sha512-YP4VG+xufxaVtzV6ZmhEtc+/aTXH3d0JLpnYfxqTvwZPbJhWqp8bSY3nfNzNRFLgB4XSaBA82OE4VjOOKpCdVQ==
- dependencies:
- "@csstools/convert-colors" "^1.4.0"
- postcss "^7.0.2"
- postcss-values-parser "^2.0.0"
-
-postcss-color-rebeccapurple@^4.0.1:
- version "4.0.1"
- resolved "https://registry.npmjs.org/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-4.0.1.tgz"
- integrity sha512-aAe3OhkS6qJXBbqzvZth2Au4V3KieR5sRQ4ptb2b2O8wgvB3SJBsdG+jsn2BZbbwekDG8nTfcCNKcSfe/lEy8g==
- dependencies:
- postcss "^7.0.2"
- postcss-values-parser "^2.0.0"
-
-postcss-colormin@^4.0.3:
- version "4.0.3"
- resolved "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-4.0.3.tgz"
- integrity sha512-WyQFAdDZpExQh32j0U0feWisZ0dmOtPl44qYmJKkq9xFWY3p+4qnRzCHeNrkeRhwPHz9bQ3mo0/yVkaply0MNw==
- dependencies:
- browserslist "^4.0.0"
- color "^3.0.0"
- has "^1.0.0"
- postcss "^7.0.0"
- postcss-value-parser "^3.0.0"
-
-postcss-convert-values@^4.0.1:
- version "4.0.1"
- resolved "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-4.0.1.tgz"
- integrity sha512-Kisdo1y77KUC0Jmn0OXU/COOJbzM8cImvw1ZFsBgBgMgb1iL23Zs/LXRe3r+EZqM3vGYKdQ2YJVQ5VkJI+zEJQ==
- dependencies:
- postcss "^7.0.0"
- postcss-value-parser "^3.0.0"
-
-postcss-critical-split@^2.5.3:
- version "2.5.3"
- resolved "https://registry.npmjs.org/postcss-critical-split/-/postcss-critical-split-2.5.3.tgz"
- integrity sha512-FDG+evU4RBGM9/LQ5nCktzFKjYH2O/SLollJwtrdGagXXbMvk620Bc9o8WpqHJnu573uxVkx9lhob1HZvSWhZg==
- dependencies:
- merge "^1.2.0"
- postcss "^6.0.1"
-
-postcss-custom-media@^7.0.8:
- version "7.0.8"
- resolved "https://registry.npmjs.org/postcss-custom-media/-/postcss-custom-media-7.0.8.tgz"
- integrity sha512-c9s5iX0Ge15o00HKbuRuTqNndsJUbaXdiNsksnVH8H4gdc+zbLzr/UasOwNG6CTDpLFekVY4672eWdiiWu2GUg==
- dependencies:
- postcss "^7.0.14"
-
-postcss-custom-properties@^8.0.11:
- version "8.0.11"
- resolved "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-8.0.11.tgz"
- integrity sha512-nm+o0eLdYqdnJ5abAJeXp4CEU1c1k+eB2yMCvhgzsds/e0umabFrN6HoTy/8Q4K5ilxERdl/JD1LO5ANoYBeMA==
- dependencies:
- postcss "^7.0.17"
- postcss-values-parser "^2.0.1"
-
-postcss-custom-selectors@^5.1.2:
- version "5.1.2"
- resolved "https://registry.npmjs.org/postcss-custom-selectors/-/postcss-custom-selectors-5.1.2.tgz"
- integrity sha512-DSGDhqinCqXqlS4R7KGxL1OSycd1lydugJ1ky4iRXPHdBRiozyMHrdu0H3o7qNOCiZwySZTUI5MV0T8QhCLu+w==
- dependencies:
- postcss "^7.0.2"
- postcss-selector-parser "^5.0.0-rc.3"
-
-postcss-dir-pseudo-class@^5.0.0:
- version "5.0.0"
- resolved "https://registry.npmjs.org/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-5.0.0.tgz"
- integrity sha512-3pm4oq8HYWMZePJY+5ANriPs3P07q+LW6FAdTlkFH2XqDdP4HeeJYMOzn0HYLhRSjBO3fhiqSwwU9xEULSrPgw==
- dependencies:
- postcss "^7.0.2"
- postcss-selector-parser "^5.0.0-rc.3"
-
-postcss-discard-comments@^4.0.2:
- version "4.0.2"
- resolved "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-4.0.2.tgz"
- integrity sha512-RJutN259iuRf3IW7GZyLM5Sw4GLTOH8FmsXBnv8Ab/Tc2k4SR4qbV4DNbyyY4+Sjo362SyDmW2DQ7lBSChrpkg==
- dependencies:
- postcss "^7.0.0"
-
-postcss-discard-duplicates@^4.0.2:
- version "4.0.2"
- resolved "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-4.0.2.tgz"
- integrity sha512-ZNQfR1gPNAiXZhgENFfEglF93pciw0WxMkJeVmw8eF+JZBbMD7jp6C67GqJAXVZP2BWbOztKfbsdmMp/k8c6oQ==
- dependencies:
- postcss "^7.0.0"
-
-postcss-discard-empty@^4.0.1:
- version "4.0.1"
- resolved "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-4.0.1.tgz"
- integrity sha512-B9miTzbznhDjTfjvipfHoqbWKwd0Mj+/fL5s1QOz06wufguil+Xheo4XpOnc4NqKYBCNqqEzgPv2aPBIJLox0w==
- dependencies:
- postcss "^7.0.0"
-
-postcss-discard-overridden@^4.0.1:
- version "4.0.1"
- resolved "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-4.0.1.tgz"
- integrity sha512-IYY2bEDD7g1XM1IDEsUT4//iEYCxAmP5oDSFMVU/JVvT7gh+l4fmjciLqGgwjdWpQIdb0Che2VX00QObS5+cTg==
- dependencies:
- postcss "^7.0.0"
-
-postcss-discard-unused@^4.0.1:
- version "4.0.1"
- resolved "https://registry.npmjs.org/postcss-discard-unused/-/postcss-discard-unused-4.0.1.tgz"
- integrity sha512-/3vq4LU0bLH2Lj4NYN7BTf2caly0flUB7Xtrk9a5K3yLuXMkHMqMO/x3sDq8W2b1eQFSCyY0IVz2L+0HP8kUUA==
- dependencies:
- postcss "^7.0.0"
- postcss-selector-parser "^3.0.0"
- uniqs "^2.0.0"
-
-postcss-double-position-gradients@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/postcss-double-position-gradients/-/postcss-double-position-gradients-1.0.0.tgz"
- integrity sha512-G+nV8EnQq25fOI8CH/B6krEohGWnF5+3A6H/+JEpOncu5dCnkS1QQ6+ct3Jkaepw1NGVqqOZH6lqrm244mCftA==
- dependencies:
- postcss "^7.0.5"
- postcss-values-parser "^2.0.0"
-
-postcss-env-function@^2.0.2:
- version "2.0.2"
- resolved "https://registry.npmjs.org/postcss-env-function/-/postcss-env-function-2.0.2.tgz"
- integrity sha512-rwac4BuZlITeUbiBq60h/xbLzXY43qOsIErngWa4l7Mt+RaSkT7QBjXVGTcBHupykkblHMDrBFh30zchYPaOUw==
- dependencies:
- postcss "^7.0.2"
- postcss-values-parser "^2.0.0"
-
-postcss-focus-visible@^4.0.0:
- version "4.0.0"
- resolved "https://registry.npmjs.org/postcss-focus-visible/-/postcss-focus-visible-4.0.0.tgz"
- integrity sha512-Z5CkWBw0+idJHSV6+Bgf2peDOFf/x4o+vX/pwcNYrWpXFrSfTkQ3JQ1ojrq9yS+upnAlNRHeg8uEwFTgorjI8g==
- dependencies:
- postcss "^7.0.2"
-
-postcss-focus-within@^3.0.0:
- version "3.0.0"
- resolved "https://registry.npmjs.org/postcss-focus-within/-/postcss-focus-within-3.0.0.tgz"
- integrity sha512-W0APui8jQeBKbCGZudW37EeMCjDeVxKgiYfIIEo8Bdh5SpB9sxds/Iq8SEuzS0Q4YFOlG7EPFulbbxujpkrV2w==
- dependencies:
- postcss "^7.0.2"
-
-postcss-font-variant@^4.0.0:
- version "4.0.0"
- resolved "https://registry.npmjs.org/postcss-font-variant/-/postcss-font-variant-4.0.0.tgz"
- integrity sha512-M8BFYKOvCrI2aITzDad7kWuXXTm0YhGdP9Q8HanmN4EF1Hmcgs1KK5rSHylt/lUJe8yLxiSwWAHdScoEiIxztg==
- dependencies:
- postcss "^7.0.2"
-
-postcss-functions@^3.0.0:
- version "3.0.0"
- resolved "https://registry.npmjs.org/postcss-functions/-/postcss-functions-3.0.0.tgz"
- integrity sha1-DpTQFERwCkgd4g3k1V+yZAVkJQ4=
- dependencies:
- glob "^7.1.2"
- object-assign "^4.1.1"
- postcss "^6.0.9"
- postcss-value-parser "^3.3.0"
-
-postcss-gap-properties@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/postcss-gap-properties/-/postcss-gap-properties-2.0.0.tgz"
- integrity sha512-QZSqDaMgXCHuHTEzMsS2KfVDOq7ZFiknSpkrPJY6jmxbugUPTuSzs/vuE5I3zv0WAS+3vhrlqhijiprnuQfzmg==
- dependencies:
- postcss "^7.0.2"
-
-postcss-image-set-function@^3.0.1:
- version "3.0.1"
- resolved "https://registry.npmjs.org/postcss-image-set-function/-/postcss-image-set-function-3.0.1.tgz"
- integrity sha512-oPTcFFip5LZy8Y/whto91L9xdRHCWEMs3e1MdJxhgt4jy2WYXfhkng59fH5qLXSCPN8k4n94p1Czrfe5IOkKUw==
- dependencies:
- postcss "^7.0.2"
- postcss-values-parser "^2.0.0"
-
-postcss-initial@^3.0.0:
- version "3.0.1"
- resolved "https://registry.npmjs.org/postcss-initial/-/postcss-initial-3.0.1.tgz"
- integrity sha512-I2Sz83ZSHybMNh02xQDK609lZ1/QOyYeuizCjzEhlMgeV/HcDJapQiH4yTqLjZss0X6/6VvKFXUeObaHpJoINw==
- dependencies:
- lodash.template "^4.5.0"
- postcss "^7.0.2"
-
-postcss-lab-function@^2.0.1:
- version "2.0.1"
- resolved "https://registry.npmjs.org/postcss-lab-function/-/postcss-lab-function-2.0.1.tgz"
- integrity sha512-whLy1IeZKY+3fYdqQFuDBf8Auw+qFuVnChWjmxm/UhHWqNHZx+B99EwxTvGYmUBqe3Fjxs4L1BoZTJmPu6usVg==
- dependencies:
- "@csstools/convert-colors" "^1.4.0"
- postcss "^7.0.2"
- postcss-values-parser "^2.0.0"
-
-postcss-load-config@^2.0.0:
- version "2.1.0"
- resolved "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-2.1.0.tgz"
- integrity sha512-4pV3JJVPLd5+RueiVVB+gFOAa7GWc25XQcMp86Zexzke69mKf6Nx9LRcQywdz7yZI9n1udOxmLuAwTBypypF8Q==
- dependencies:
- cosmiconfig "^5.0.0"
- import-cwd "^2.0.0"
-
-postcss-logical@^3.0.0:
- version "3.0.0"
- resolved "https://registry.npmjs.org/postcss-logical/-/postcss-logical-3.0.0.tgz"
- integrity sha512-1SUKdJc2vuMOmeItqGuNaC+N8MzBWFWEkAnRnLpFYj1tGGa7NqyVBujfRtgNa2gXR+6RkGUiB2O5Vmh7E2RmiA==
- dependencies:
- postcss "^7.0.2"
-
-postcss-media-minmax@^4.0.0:
- version "4.0.0"
- resolved "https://registry.npmjs.org/postcss-media-minmax/-/postcss-media-minmax-4.0.0.tgz"
- integrity sha512-fo9moya6qyxsjbFAYl97qKO9gyre3qvbMnkOZeZwlsW6XYFsvs2DMGDlchVLfAd8LHPZDxivu/+qW2SMQeTHBw==
- dependencies:
- postcss "^7.0.2"
-
-postcss-merge-idents@^4.0.1:
- version "4.0.1"
- resolved "https://registry.npmjs.org/postcss-merge-idents/-/postcss-merge-idents-4.0.1.tgz"
- integrity sha512-43S/VNdF6II0NZ31YxcvNYq4gfURlPAAsJW/z84avBXQCaP4I4qRHUH18slW/SOlJbcxxCobflPNUApYDddS7A==
- dependencies:
- cssnano-util-same-parent "^4.0.0"
- has "^1.0.0"
- postcss "^7.0.0"
- postcss-value-parser "^3.0.0"
-
-postcss-merge-longhand@^4.0.11:
- version "4.0.11"
- resolved "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-4.0.11.tgz"
- integrity sha512-alx/zmoeXvJjp7L4mxEMjh8lxVlDFX1gqWHzaaQewwMZiVhLo42TEClKaeHbRf6J7j82ZOdTJ808RtN0ZOZwvw==
- dependencies:
- css-color-names "0.0.4"
- postcss "^7.0.0"
- postcss-value-parser "^3.0.0"
- stylehacks "^4.0.0"
-
-postcss-merge-rules@^4.0.3:
- version "4.0.3"
- resolved "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-4.0.3.tgz"
- integrity sha512-U7e3r1SbvYzO0Jr3UT/zKBVgYYyhAz0aitvGIYOYK5CPmkNih+WDSsS5tvPrJ8YMQYlEMvsZIiqmn7HdFUaeEQ==
- dependencies:
- browserslist "^4.0.0"
- caniuse-api "^3.0.0"
- cssnano-util-same-parent "^4.0.0"
- postcss "^7.0.0"
- postcss-selector-parser "^3.0.0"
- vendors "^1.0.0"
-
-postcss-minify-font-values@^4.0.2:
- version "4.0.2"
- resolved "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-4.0.2.tgz"
- integrity sha512-j85oO6OnRU9zPf04+PZv1LYIYOprWm6IA6zkXkrJXyRveDEuQggG6tvoy8ir8ZwjLxLuGfNkCZEQG7zan+Hbtg==
- dependencies:
- postcss "^7.0.0"
- postcss-value-parser "^3.0.0"
-
-postcss-minify-gradients@^4.0.2:
- version "4.0.2"
- resolved "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-4.0.2.tgz"
- integrity sha512-qKPfwlONdcf/AndP1U8SJ/uzIJtowHlMaSioKzebAXSG4iJthlWC9iSWznQcX4f66gIWX44RSA841HTHj3wK+Q==
- dependencies:
- cssnano-util-get-arguments "^4.0.0"
- is-color-stop "^1.0.0"
- postcss "^7.0.0"
- postcss-value-parser "^3.0.0"
-
-postcss-minify-params@^4.0.2:
- version "4.0.2"
- resolved "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-4.0.2.tgz"
- integrity sha512-G7eWyzEx0xL4/wiBBJxJOz48zAKV2WG3iZOqVhPet/9geefm/Px5uo1fzlHu+DOjT+m0Mmiz3jkQzVHe6wxAWg==
- dependencies:
- alphanum-sort "^1.0.0"
- browserslist "^4.0.0"
- cssnano-util-get-arguments "^4.0.0"
- postcss "^7.0.0"
- postcss-value-parser "^3.0.0"
- uniqs "^2.0.0"
-
-postcss-minify-selectors@^4.0.2:
- version "4.0.2"
- resolved "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-4.0.2.tgz"
- integrity sha512-D5S1iViljXBj9kflQo4YutWnJmwm8VvIsU1GeXJGiG9j8CIg9zs4voPMdQDUmIxetUOh60VilsNzCiAFTOqu3g==
- dependencies:
- alphanum-sort "^1.0.0"
- has "^1.0.0"
- postcss "^7.0.0"
- postcss-selector-parser "^3.0.0"
-
-postcss-nesting@^7.0.0:
- version "7.0.1"
- resolved "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-7.0.1.tgz"
- integrity sha512-FrorPb0H3nuVq0Sff7W2rnc3SmIcruVC6YwpcS+k687VxyxO33iE1amna7wHuRVzM8vfiYofXSBHNAZ3QhLvYg==
- dependencies:
- postcss "^7.0.2"
-
-postcss-normalize-charset@^4.0.1:
- version "4.0.1"
- resolved "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-4.0.1.tgz"
- integrity sha512-gMXCrrlWh6G27U0hF3vNvR3w8I1s2wOBILvA87iNXaPvSNo5uZAMYsZG7XjCUf1eVxuPfyL4TJ7++SGZLc9A3g==
- dependencies:
- postcss "^7.0.0"
-
-postcss-normalize-display-values@^4.0.2:
- version "4.0.2"
- resolved "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-4.0.2.tgz"
- integrity sha512-3F2jcsaMW7+VtRMAqf/3m4cPFhPD3EFRgNs18u+k3lTJJlVe7d0YPO+bnwqo2xg8YiRpDXJI2u8A0wqJxMsQuQ==
- dependencies:
- cssnano-util-get-match "^4.0.0"
- postcss "^7.0.0"
- postcss-value-parser "^3.0.0"
-
-postcss-normalize-positions@^4.0.2:
- version "4.0.2"
- resolved "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-4.0.2.tgz"
- integrity sha512-Dlf3/9AxpxE+NF1fJxYDeggi5WwV35MXGFnnoccP/9qDtFrTArZ0D0R+iKcg5WsUd8nUYMIl8yXDCtcrT8JrdA==
- dependencies:
- cssnano-util-get-arguments "^4.0.0"
- has "^1.0.0"
- postcss "^7.0.0"
- postcss-value-parser "^3.0.0"
-
-postcss-normalize-repeat-style@^4.0.2:
- version "4.0.2"
- resolved "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-4.0.2.tgz"
- integrity sha512-qvigdYYMpSuoFs3Is/f5nHdRLJN/ITA7huIoCyqqENJe9PvPmLhNLMu7QTjPdtnVf6OcYYO5SHonx4+fbJE1+Q==
- dependencies:
- cssnano-util-get-arguments "^4.0.0"
- cssnano-util-get-match "^4.0.0"
- postcss "^7.0.0"
- postcss-value-parser "^3.0.0"
-
-postcss-normalize-string@^4.0.2:
- version "4.0.2"
- resolved "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-4.0.2.tgz"
- integrity sha512-RrERod97Dnwqq49WNz8qo66ps0swYZDSb6rM57kN2J+aoyEAJfZ6bMx0sx/F9TIEX0xthPGCmeyiam/jXif0eA==
- dependencies:
- has "^1.0.0"
- postcss "^7.0.0"
- postcss-value-parser "^3.0.0"
-
-postcss-normalize-timing-functions@^4.0.2:
- version "4.0.2"
- resolved "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-4.0.2.tgz"
- integrity sha512-acwJY95edP762e++00Ehq9L4sZCEcOPyaHwoaFOhIwWCDfik6YvqsYNxckee65JHLKzuNSSmAdxwD2Cud1Z54A==
- dependencies:
- cssnano-util-get-match "^4.0.0"
- postcss "^7.0.0"
- postcss-value-parser "^3.0.0"
-
-postcss-normalize-unicode@^4.0.1:
- version "4.0.1"
- resolved "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-4.0.1.tgz"
- integrity sha512-od18Uq2wCYn+vZ/qCOeutvHjB5jm57ToxRaMeNuf0nWVHaP9Hua56QyMF6fs/4FSUnVIw0CBPsU0K4LnBPwYwg==
- dependencies:
- browserslist "^4.0.0"
- postcss "^7.0.0"
- postcss-value-parser "^3.0.0"
-
-postcss-normalize-url@^4.0.1:
- version "4.0.1"
- resolved "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-4.0.1.tgz"
- integrity sha512-p5oVaF4+IHwu7VpMan/SSpmpYxcJMtkGppYf0VbdH5B6hN8YNmVyJLuY9FmLQTzY3fag5ESUUHDqM+heid0UVA==
- dependencies:
- is-absolute-url "^2.0.0"
- normalize-url "^3.0.0"
- postcss "^7.0.0"
- postcss-value-parser "^3.0.0"
-
-postcss-normalize-whitespace@^4.0.2:
- version "4.0.2"
- resolved "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-4.0.2.tgz"
- integrity sha512-tO8QIgrsI3p95r8fyqKV+ufKlSHh9hMJqACqbv2XknufqEDhDvbguXGBBqxw9nsQoXWf0qOqppziKJKHMD4GtA==
- dependencies:
- postcss "^7.0.0"
- postcss-value-parser "^3.0.0"
-
-postcss-ordered-values@^4.1.2:
- version "4.1.2"
- resolved "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-4.1.2.tgz"
- integrity sha512-2fCObh5UanxvSxeXrtLtlwVThBvHn6MQcu4ksNT2tsaV2Fg76R2CV98W7wNSlX+5/pFwEyaDwKLLoEV7uRybAw==
- dependencies:
- cssnano-util-get-arguments "^4.0.0"
- postcss "^7.0.0"
- postcss-value-parser "^3.0.0"
-
-postcss-overflow-shorthand@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/postcss-overflow-shorthand/-/postcss-overflow-shorthand-2.0.0.tgz"
- integrity sha512-aK0fHc9CBNx8jbzMYhshZcEv8LtYnBIRYQD5i7w/K/wS9c2+0NSR6B3OVMu5y0hBHYLcMGjfU+dmWYNKH0I85g==
- dependencies:
- postcss "^7.0.2"
-
-postcss-page-break@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/postcss-page-break/-/postcss-page-break-2.0.0.tgz"
- integrity sha512-tkpTSrLpfLfD9HvgOlJuigLuk39wVTbbd8RKcy8/ugV2bNBUW3xU+AIqyxhDrQr1VUj1RmyJrBn1YWrqUm9zAQ==
- dependencies:
- postcss "^7.0.2"
-
-postcss-place@^4.0.1:
- version "4.0.1"
- resolved "https://registry.npmjs.org/postcss-place/-/postcss-place-4.0.1.tgz"
- integrity sha512-Zb6byCSLkgRKLODj/5mQugyuj9bvAAw9LqJJjgwz5cYryGeXfFZfSXoP1UfveccFmeq0b/2xxwcTEVScnqGxBg==
- dependencies:
- postcss "^7.0.2"
- postcss-values-parser "^2.0.0"
-
-postcss-preset-env@^6.5.0:
- version "6.7.0"
- resolved "https://registry.npmjs.org/postcss-preset-env/-/postcss-preset-env-6.7.0.tgz"
- integrity sha512-eU4/K5xzSFwUFJ8hTdTQzo2RBLbDVt83QZrAvI07TULOkmyQlnYlpwep+2yIK+K+0KlZO4BvFcleOCCcUtwchg==
- dependencies:
- autoprefixer "^9.6.1"
- browserslist "^4.6.4"
- caniuse-lite "^1.0.30000981"
- css-blank-pseudo "^0.1.4"
- css-has-pseudo "^0.10.0"
- css-prefers-color-scheme "^3.1.1"
- cssdb "^4.4.0"
- postcss "^7.0.17"
- postcss-attribute-case-insensitive "^4.0.1"
- postcss-color-functional-notation "^2.0.1"
- postcss-color-gray "^5.0.0"
- postcss-color-hex-alpha "^5.0.3"
- postcss-color-mod-function "^3.0.3"
- postcss-color-rebeccapurple "^4.0.1"
- postcss-custom-media "^7.0.8"
- postcss-custom-properties "^8.0.11"
- postcss-custom-selectors "^5.1.2"
- postcss-dir-pseudo-class "^5.0.0"
- postcss-double-position-gradients "^1.0.0"
- postcss-env-function "^2.0.2"
- postcss-focus-visible "^4.0.0"
- postcss-focus-within "^3.0.0"
- postcss-font-variant "^4.0.0"
- postcss-gap-properties "^2.0.0"
- postcss-image-set-function "^3.0.1"
- postcss-initial "^3.0.0"
- postcss-lab-function "^2.0.1"
- postcss-logical "^3.0.0"
- postcss-media-minmax "^4.0.0"
- postcss-nesting "^7.0.0"
- postcss-overflow-shorthand "^2.0.0"
- postcss-page-break "^2.0.0"
- postcss-place "^4.0.1"
- postcss-pseudo-class-any-link "^6.0.0"
- postcss-replace-overflow-wrap "^3.0.0"
- postcss-selector-matches "^4.0.0"
- postcss-selector-not "^4.0.0"
-
-postcss-pseudo-class-any-link@^6.0.0:
- version "6.0.0"
- resolved "https://registry.npmjs.org/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-6.0.0.tgz"
- integrity sha512-lgXW9sYJdLqtmw23otOzrtbDXofUdfYzNm4PIpNE322/swES3VU9XlXHeJS46zT2onFO7V1QFdD4Q9LiZj8mew==
- dependencies:
- postcss "^7.0.2"
- postcss-selector-parser "^5.0.0-rc.3"
-
-postcss-reduce-idents@^4.0.2:
- version "4.0.2"
- resolved "https://registry.npmjs.org/postcss-reduce-idents/-/postcss-reduce-idents-4.0.2.tgz"
- integrity sha512-Tz70Ri10TclPoCtFfftjFVddx3fZGUkr0dEDbIEfbYhFUOFQZZ77TEqRrU0e6TvAvF+Wa5VVzYTpFpq0uwFFzw==
- dependencies:
- postcss "^7.0.0"
- postcss-value-parser "^3.0.0"
-
-postcss-reduce-initial@^4.0.3:
- version "4.0.3"
- resolved "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-4.0.3.tgz"
- integrity sha512-gKWmR5aUulSjbzOfD9AlJiHCGH6AEVLaM0AV+aSioxUDd16qXP1PCh8d1/BGVvpdWn8k/HiK7n6TjeoXN1F7DA==
- dependencies:
- browserslist "^4.0.0"
- caniuse-api "^3.0.0"
- has "^1.0.0"
- postcss "^7.0.0"
-
-postcss-reduce-transforms@^4.0.2:
- version "4.0.2"
- resolved "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-4.0.2.tgz"
- integrity sha512-EEVig1Q2QJ4ELpJXMZR8Vt5DQx8/mo+dGWSR7vWXqcob2gQLyQGsionYcGKATXvQzMPn6DSN1vTN7yFximdIAg==
- dependencies:
- cssnano-util-get-match "^4.0.0"
- has "^1.0.0"
- postcss "^7.0.0"
- postcss-value-parser "^3.0.0"
-
-postcss-replace-overflow-wrap@^3.0.0:
- version "3.0.0"
- resolved "https://registry.npmjs.org/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-3.0.0.tgz"
- integrity sha512-2T5hcEHArDT6X9+9dVSPQdo7QHzG4XKclFT8rU5TzJPDN7RIRTbO9c4drUISOVemLj03aezStHCR2AIcr8XLpw==
- dependencies:
- postcss "^7.0.2"
-
-postcss-round-subpixels@^1.2.0:
- version "1.2.0"
- resolved "https://registry.npmjs.org/postcss-round-subpixels/-/postcss-round-subpixels-1.2.0.tgz"
- integrity sha1-4h1qxZUuGF+b3ACLlPAE/lCdChE=
- dependencies:
- postcss "^5.0.2"
- postcss-value-parser "^3.1.2"
-
-postcss-selector-matches@^4.0.0:
- version "4.0.0"
- resolved "https://registry.npmjs.org/postcss-selector-matches/-/postcss-selector-matches-4.0.0.tgz"
- integrity sha512-LgsHwQR/EsRYSqlwdGzeaPKVT0Ml7LAT6E75T8W8xLJY62CE4S/l03BWIt3jT8Taq22kXP08s2SfTSzaraoPww==
- dependencies:
- balanced-match "^1.0.0"
- postcss "^7.0.2"
-
-postcss-selector-not@^4.0.0:
- version "4.0.0"
- resolved "https://registry.npmjs.org/postcss-selector-not/-/postcss-selector-not-4.0.0.tgz"
- integrity sha512-W+bkBZRhqJaYN8XAnbbZPLWMvZD1wKTu0UxtFKdhtGjWYmxhkUneoeOhRJKdAE5V7ZTlnbHfCR+6bNwK9e1dTQ==
- dependencies:
- balanced-match "^1.0.0"
- postcss "^7.0.2"
-
-postcss-selector-parser@^3.0.0:
- version "3.1.1"
- resolved "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.1.tgz"
- integrity sha1-T4dfSvsMllc9XPTXQBGu4lCn6GU=
- dependencies:
- dot-prop "^4.1.1"
- indexes-of "^1.0.1"
- uniq "^1.0.1"
-
-postcss-selector-parser@^5.0.0, postcss-selector-parser@^5.0.0-rc.3, postcss-selector-parser@^5.0.0-rc.4:
- version "5.0.0"
- resolved "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz"
- integrity sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ==
- dependencies:
- cssesc "^2.0.0"
- indexes-of "^1.0.1"
- uniq "^1.0.1"
-
-postcss-svgo@^4.0.2:
- version "4.0.2"
- resolved "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-4.0.2.tgz"
- integrity sha512-C6wyjo3VwFm0QgBy+Fu7gCYOkCmgmClghO+pjcxvrcBKtiKt0uCF+hvbMO1fyv5BMImRK90SMb+dwUnfbGd+jw==
- dependencies:
- is-svg "^3.0.0"
- postcss "^7.0.0"
- postcss-value-parser "^3.0.0"
- svgo "^1.0.0"
-
-postcss-unique-selectors@^4.0.1:
- version "4.0.1"
- resolved "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-4.0.1.tgz"
- integrity sha512-+JanVaryLo9QwZjKrmJgkI4Fn8SBgRO6WXQBJi7KiAVPlmxikB5Jzc4EvXMT2H0/m0RjrVVm9rGNhZddm/8Spg==
- dependencies:
- alphanum-sort "^1.0.0"
- postcss "^7.0.0"
- uniqs "^2.0.0"
-
-postcss-unprefix@^2.1.3:
- version "2.1.4"
- resolved "https://registry.npmjs.org/postcss-unprefix/-/postcss-unprefix-2.1.4.tgz"
- integrity sha512-s+muBiGIMx3RvgPTtPBnSrfvIBHJ2Zx16QZf/VDB/sAxdYP6FIzci8d1gLh0+9psu5W6zVtCbU5micNt6Zh3cg==
- dependencies:
- autoprefixer "^9.4.3"
- known-css-properties "^0.11.0"
- normalize-range "^0.1.2"
- postcss-selector-parser "^5.0.0"
- postcss-value-parser "^3.3.1"
- pseudo-classes "^1.0.0"
- pseudo-elements "^1.1.0"
-
-postcss-value-parser@^3.0.0, postcss-value-parser@^3.1.2, postcss-value-parser@^3.3.0, postcss-value-parser@^3.3.1:
- version "3.3.1"
- resolved "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz"
- integrity sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==
-
-postcss-value-parser@^4.0.0:
- version "4.0.2"
- resolved "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.0.2.tgz"
- integrity sha512-LmeoohTpp/K4UiyQCwuGWlONxXamGzCMtFxLq4W1nZVGIQLYvMCJx3yAF9qyyuFpflABI9yVdtJAqbihOsCsJQ==
-
-postcss-values-parser@^2.0.0, postcss-values-parser@^2.0.1:
- version "2.0.1"
- resolved "https://registry.npmjs.org/postcss-values-parser/-/postcss-values-parser-2.0.1.tgz"
- integrity sha512-2tLuBsA6P4rYTNKCXYG/71C7j1pU6pK503suYOmn4xYrQIzW+opD+7FAFNuGSdZC/3Qfy334QbeMu7MEb8gOxg==
- dependencies:
- flatten "^1.0.2"
- indexes-of "^1.0.1"
- uniq "^1.0.1"
-
-postcss-zindex@^4.0.1:
- version "4.0.1"
- resolved "https://registry.npmjs.org/postcss-zindex/-/postcss-zindex-4.0.1.tgz"
- integrity sha512-d/8BlQcUdEugZNRM9AdCA2V4fqREUtn/wcixLN3L6ITgc2P/FMcVVYz8QZkhItWT9NB5qr8wuN2dJCE4/+dlrA==
- dependencies:
- has "^1.0.0"
- postcss "^7.0.0"
- uniqs "^2.0.0"
-
-postcss@>=5.0.0:
- version "8.1.7"
- resolved "https://registry.npmjs.org/postcss/-/postcss-8.1.7.tgz"
- integrity sha512-llCQW1Pz4MOPwbZLmOddGM9eIJ8Bh7SZ2Oj5sxZva77uVaotYDsYTch1WBTNu7fUY0fpWp0fdt7uW40D4sRiiQ==
- dependencies:
- colorette "^1.2.1"
- line-column "^1.0.2"
- nanoid "^3.1.16"
- source-map "^0.6.1"
-
-postcss@^5.0.2:
- version "5.2.18"
- resolved "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz"
- integrity sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==
- dependencies:
- chalk "^1.1.3"
- js-base64 "^2.1.9"
- source-map "^0.5.6"
- supports-color "^3.2.3"
-
-postcss@^6.0.1, postcss@^6.0.10, postcss@^6.0.9:
- version "6.0.23"
- resolved "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz"
- integrity sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==
- dependencies:
- chalk "^2.4.1"
- source-map "^0.6.1"
- supports-color "^5.4.0"
-
-postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.14, postcss@^7.0.17, postcss@^7.0.2, postcss@^7.0.5, postcss@^7.0.6:
- version "7.0.18"
- resolved "https://registry.npmjs.org/postcss/-/postcss-7.0.18.tgz"
- integrity sha512-/7g1QXXgegpF+9GJj4iN7ChGF40sYuGYJ8WZu8DZWnmhQ/G36hfdk3q9LBJmoK+lZ+yzZ5KYpOoxq7LF1BxE8g==
- dependencies:
- chalk "^2.4.2"
- source-map "^0.6.1"
- supports-color "^6.1.0"
-
-prelude-ls@~1.1.2:
- version "1.1.2"
- resolved "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz"
- integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=
-
-prepend-http@^1.0.1:
- version "1.0.4"
- resolved "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz"
- integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=
-
-prepend-http@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz"
- integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=
-
-pretty-bytes@^5.3.0:
- version "5.3.0"
- resolved "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.3.0.tgz"
- integrity sha512-hjGrh+P926p4R4WbaB6OckyRtO0F0/lQBiT+0gnxjV+5kjPBrfVBFCsCLbMqVQeydvIoouYTCmmEURiH3R1Bdg==
-
-pretty-hrtime@^0.2.0:
- version "0.2.2"
- resolved "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-0.2.2.tgz"
- integrity sha1-1P2INR46R0H4Fzr31qS4RvmJXAA=
-
-pretty-hrtime@^1.0.0:
- version "1.0.3"
- resolved "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz"
- integrity sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=
-
-private@^0.1.6, private@^0.1.8, private@~0.1.5:
- version "0.1.8"
- resolved "https://registry.npmjs.org/private/-/private-0.1.8.tgz"
- integrity sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==
-
-process-nextick-args@^2.0.0, process-nextick-args@~2.0.0:
- version "2.0.1"
- resolved "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz"
- integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==
-
-process@^0.11.10:
- version "0.11.10"
- resolved "https://registry.npmjs.org/process/-/process-0.11.10.tgz"
- integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI=
-
-process@~0.5.1:
- version "0.5.2"
- resolved "https://registry.npmjs.org/process/-/process-0.5.2.tgz"
- integrity sha1-FjjYqONML0QKkduVq5rrZ3/Bhc8=
-
-progress@^1.1.8:
- version "1.1.8"
- resolved "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz"
- integrity sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=
-
-progress@^2.0.0, progress@^2.0.3:
- version "2.0.3"
- resolved "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz"
- integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==
-
-promise-inflight@^1.0.1:
- version "1.0.1"
- resolved "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz"
- integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM=
-
-promise-polyfill@^8.1.0:
- version "8.1.3"
- resolved "https://registry.npmjs.org/promise-polyfill/-/promise-polyfill-8.1.3.tgz"
- integrity sha512-MG5r82wBzh7pSKDRa9y+vllNHz3e3d4CNj1PQE4BQYxLme0gKYYBm9YENq+UkEikyZ0XbiGWxYlVw3Rl9O/U8g==
-
-proto-list@~1.2.1:
- version "1.2.4"
- resolved "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz"
- integrity sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk=
-
-proxy-middleware@^0.5.0:
- version "0.5.1"
- resolved "https://registry.npmjs.org/proxy-middleware/-/proxy-middleware-0.5.1.tgz"
- integrity sha1-2iTV1Ywd3xPa0jfH7KUDhJ6uqQM=
-
-prr@~1.0.1:
- version "1.0.1"
- resolved "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz"
- integrity sha1-0/wRS6BplaRexok/SEzrHXj19HY=
-
-pseudo-classes@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/pseudo-classes/-/pseudo-classes-1.0.0.tgz"
- integrity sha1-YKabZzlcNv8RnE0chuGYF4Uga5Y=
-
-pseudo-elements@^1.1.0:
- version "1.1.0"
- resolved "https://registry.npmjs.org/pseudo-elements/-/pseudo-elements-1.1.0.tgz"
- integrity sha1-m6bdisPOHz19NtQ1WqPijQg5Hyg=
-
-pseudomap@^1.0.2:
- version "1.0.2"
- resolved "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz"
- integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM=
-
-psl@^1.1.24, psl@^1.1.28:
- version "1.4.0"
- resolved "https://registry.npmjs.org/psl/-/psl-1.4.0.tgz"
- integrity sha512-HZzqCGPecFLyoRj5HLfuDSKYTJkAfB5thKBIkRHtGjWwY7p1dAyveIbXIq4tO0KYfDF2tHqPUgY9SDnGm00uFw==
-
-public-encrypt@^4.0.0:
- version "4.0.3"
- resolved "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz"
- integrity sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==
- dependencies:
- bn.js "^4.1.0"
- browserify-rsa "^4.0.0"
- create-hash "^1.1.0"
- parse-asn1 "^5.0.0"
- randombytes "^2.0.1"
- safe-buffer "^5.1.2"
-
-pump@^2.0.0:
- version "2.0.1"
- resolved "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz"
- integrity sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==
- dependencies:
- end-of-stream "^1.1.0"
- once "^1.3.1"
-
-pump@^3.0.0:
- version "3.0.0"
- resolved "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz"
- integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==
- dependencies:
- end-of-stream "^1.1.0"
- once "^1.3.1"
-
-pumpify@^1.3.3, pumpify@^1.3.5:
- version "1.5.1"
- resolved "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz"
- integrity sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==
- dependencies:
- duplexify "^3.6.0"
- inherits "^2.0.3"
- pump "^2.0.0"
-
-punycode@1.3.2:
- version "1.3.2"
- resolved "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz"
- integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=
-
-punycode@^1.2.4, punycode@^1.4.1:
- version "1.4.1"
- resolved "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz"
- integrity sha1-wNWmOycYgArY4esPpSachN1BhF4=
-
-punycode@^2.1.0, punycode@^2.1.1:
- version "2.1.1"
- resolved "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz"
- integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==
-
-q@^1.1.2:
- version "1.5.1"
- resolved "https://registry.npmjs.org/q/-/q-1.5.1.tgz"
- integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=
-
-qs@2.2.4:
- version "2.2.4"
- resolved "https://registry.npmjs.org/qs/-/qs-2.2.4.tgz"
- integrity sha1-Lp+800tUDjQhySTs0B6QqpdTGcg=
-
-qs@6.2.3:
- version "6.2.3"
- resolved "https://registry.npmjs.org/qs/-/qs-6.2.3.tgz"
- integrity sha1-HPyyXBCpsrSDBT/zn138kjOQjP4=
-
-qs@~2.2.3:
- version "2.2.5"
- resolved "https://registry.npmjs.org/qs/-/qs-2.2.5.tgz"
- integrity sha1-EIirr53MCuWuRbcJ5sa1iIsjkjw=
-
-qs@~6.5.2:
- version "6.5.2"
- resolved "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz"
- integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==
-
-query-string@^5.0.1:
- version "5.1.1"
- resolved "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz"
- integrity sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==
- dependencies:
- decode-uri-component "^0.2.0"
- object-assign "^4.1.0"
- strict-uri-encode "^1.0.0"
-
-query-string@^6.8.1:
- version "6.8.3"
- resolved "https://registry.npmjs.org/query-string/-/query-string-6.8.3.tgz"
- integrity sha512-llcxWccnyaWlODe7A9hRjkvdCKamEKTh+wH8ITdTc3OhchaqUZteiSCX/2ablWHVrkVIe04dntnaZJ7BdyW0lQ==
- dependencies:
- decode-uri-component "^0.2.0"
- split-on-first "^1.0.0"
- strict-uri-encode "^2.0.0"
-
-querystring-es3@^0.2.0:
- version "0.2.1"
- resolved "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz"
- integrity sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=
-
-querystring@0.2.0:
- version "0.2.0"
- resolved "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz"
- integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=
-
-randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5, randombytes@^2.1.0:
- version "2.1.0"
- resolved "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz"
- integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==
- dependencies:
- safe-buffer "^5.1.0"
-
-randomfill@^1.0.3:
- version "1.0.4"
- resolved "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz"
- integrity sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==
- dependencies:
- randombytes "^2.0.5"
- safe-buffer "^5.1.0"
-
-range-parser@~1.2.0:
- version "1.2.1"
- resolved "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz"
- integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==
-
-raw-body@1.3.0:
- version "1.3.0"
- resolved "https://registry.npmjs.org/raw-body/-/raw-body-1.3.0.tgz"
- integrity sha1-l4IwoValVI9C7vFN4i0PT2EAg9E=
- dependencies:
- bytes "1"
- iconv-lite "0.4.4"
-
-raw-body@^2.3.2:
- version "2.4.1"
- resolved "https://registry.npmjs.org/raw-body/-/raw-body-2.4.1.tgz"
- integrity sha512-9WmIKF6mkvA0SLmA2Knm9+qj89e+j1zqgyn8aXGd7+nAduPoqgI9lO57SAZNn/Byzo5P7JhXTyg9PzaJbH73bA==
- dependencies:
- bytes "3.1.0"
- http-errors "1.7.3"
- iconv-lite "0.4.24"
- unpipe "1.0.0"
-
-raw-loader@^4.0.2:
- version "4.0.2"
- resolved "https://registry.yarnpkg.com/raw-loader/-/raw-loader-4.0.2.tgz#1aac6b7d1ad1501e66efdac1522c73e59a584eb6"
- integrity sha512-ZnScIV3ag9A4wPX/ZayxL/jZH+euYb6FcUinPcgiQW0+UBtEv0O6Q3lGd3cqJ+GHH+rksEv3Pj99oxJ3u3VIKA==
- dependencies:
- loader-utils "^2.0.0"
- schema-utils "^3.0.0"
-
-rcedit@^3.0.1:
- version "3.0.1"
- resolved "https://registry.yarnpkg.com/rcedit/-/rcedit-3.0.1.tgz#ae21b43e49c075f4d84df1929832a12c302f3c90"
- integrity sha512-XM0Jv40/y4hVAqj/MO70o/IWs4uOsaSoo2mLyk3klFDW+SStLnCtzuQu+1OBTIMGlM8CvaK9ftlYCp6DJ+cMsw==
- dependencies:
- cross-spawn-windows-exe "^1.1.0"
-
-rcfinder@^0.1.6:
- version "0.1.9"
- resolved "https://registry.npmjs.org/rcfinder/-/rcfinder-0.1.9.tgz"
- integrity sha1-8+gPOH3fmugK4wpBADKWQuroERU=
- dependencies:
- lodash.clonedeep "^4.3.2"
-
-rcloader@^0.1.4:
- version "0.1.4"
- resolved "https://registry.npmjs.org/rcloader/-/rcloader-0.1.4.tgz"
- integrity sha1-0MkC8ERJg6LuWmkHk3xqecpwRQk=
- dependencies:
- lodash "^3.0.1"
- rcfinder "^0.1.6"
-
-read-pkg-up@^1.0.1:
- version "1.0.1"
- resolved "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz"
- integrity sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=
- dependencies:
- find-up "^1.0.0"
- read-pkg "^1.0.0"
-
-read-pkg-up@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz"
- integrity sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=
- dependencies:
- find-up "^2.0.0"
- read-pkg "^2.0.0"
-
-read-pkg@^1.0.0:
- version "1.1.0"
- resolved "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz"
- integrity sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=
- dependencies:
- load-json-file "^1.0.0"
- normalize-package-data "^2.3.2"
- path-type "^1.0.0"
-
-read-pkg@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz"
- integrity sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=
- dependencies:
- load-json-file "^2.0.0"
- normalize-package-data "^2.3.2"
- path-type "^2.0.0"
-
-read@~1.0.4:
- version "1.0.7"
- resolved "https://registry.npmjs.org/read/-/read-1.0.7.tgz"
- integrity sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ=
- dependencies:
- mute-stream "~0.0.4"
-
-"readable-stream@1 || 2", "readable-stream@2 || 3", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.0, readable-stream@^2.3.3, readable-stream@^2.3.5, readable-stream@^2.3.6, readable-stream@~2.3.6:
- version "2.3.6"
- resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz"
- integrity sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==
- dependencies:
- core-util-is "~1.0.0"
- inherits "~2.0.3"
- isarray "~1.0.0"
- process-nextick-args "~2.0.0"
- safe-buffer "~5.1.1"
- string_decoder "~1.1.1"
- util-deprecate "~1.0.1"
-
-"readable-stream@>=1.0.33-1 <1.1.0-0", readable-stream@^1.0.27-1, readable-stream@~1.0.17, readable-stream@~1.0.2, readable-stream@~1.0.24, readable-stream@~1.0.26:
- version "1.0.34"
- resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz"
- integrity sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=
- dependencies:
- core-util-is "~1.0.0"
- inherits "~2.0.1"
- isarray "0.0.1"
- string_decoder "~0.10.x"
-
-readable-stream@^3.0.2, readable-stream@^3.1.1, readable-stream@^3.5.0:
- version "3.6.0"
- resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz"
- integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==
- dependencies:
- inherits "^2.0.3"
- string_decoder "^1.1.1"
- util-deprecate "^1.0.1"
-
-readable-stream@~1.1.9:
- version "1.1.14"
- resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz"
- integrity sha1-fPTFTvZI44EwhMY23SB54WbAgdk=
- dependencies:
- core-util-is "~1.0.0"
- inherits "~2.0.1"
- isarray "0.0.1"
- string_decoder "~0.10.x"
-
-readdirp@^2.2.1:
- version "2.2.1"
- resolved "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz"
- integrity sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==
- dependencies:
- graceful-fs "^4.1.11"
- micromatch "^3.1.10"
- readable-stream "^2.0.2"
-
-readdirp@~3.4.0:
- version "3.4.0"
- resolved "https://registry.npmjs.org/readdirp/-/readdirp-3.4.0.tgz"
- integrity sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ==
- dependencies:
- picomatch "^2.2.1"
-
-readline2@^1.0.1:
- version "1.0.1"
- resolved "https://registry.npmjs.org/readline2/-/readline2-1.0.1.tgz"
- integrity sha1-QQWWCP/BVHV7cV2ZidGZ/783LjU=
- dependencies:
- code-point-at "^1.0.0"
- is-fullwidth-code-point "^1.0.0"
- mute-stream "0.0.5"
-
-recast@~0.11.12:
- version "0.11.23"
- resolved "https://registry.npmjs.org/recast/-/recast-0.11.23.tgz"
- integrity sha1-RR/TAEqx5N+bTktmN2sqIZEkYtM=
- dependencies:
- ast-types "0.9.6"
- esprima "~3.1.0"
- private "~0.1.5"
- source-map "~0.5.0"
-
-rechoir@^0.6.2:
- version "0.6.2"
- resolved "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz"
- integrity sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=
- dependencies:
- resolve "^1.1.6"
-
-redent@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz"
- integrity sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=
- dependencies:
- indent-string "^2.1.0"
- strip-indent "^1.0.1"
-
-regenerate-unicode-properties@^8.1.0:
- version "8.1.0"
- resolved "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.1.0.tgz"
- integrity sha512-LGZzkgtLY79GeXLm8Dp0BVLdQlWICzBnJz/ipWUgo59qBaZ+BHtq51P2q1uVZlppMuUAT37SDk39qUbjTWB7bA==
- dependencies:
- regenerate "^1.4.0"
-
-regenerate@^1.4.0:
- version "1.4.0"
- resolved "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz"
- integrity sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==
-
-regenerator-runtime@^0.11.0:
- version "0.11.1"
- resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz"
- integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==
-
-regenerator-runtime@^0.13.3:
- version "0.13.3"
- resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz"
- integrity sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw==
-
-regenerator-runtime@^0.13.4:
- version "0.13.5"
- resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz"
- integrity sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==
-
-regenerator-transform@^0.14.0:
- version "0.14.1"
- resolved "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.1.tgz"
- integrity sha512-flVuee02C3FKRISbxhXl9mGzdbWUVHubl1SMaknjxkFB1/iqpJhArQUvRxOOPEc/9tAiX0BaQ28FJH10E4isSQ==
- dependencies:
- private "^0.1.6"
-
-regex-not@^1.0.0, regex-not@^1.0.2:
- version "1.0.2"
- resolved "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz"
- integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==
- dependencies:
- extend-shallow "^3.0.2"
- safe-regex "^1.1.0"
-
-regexp-tree@^0.1.13:
- version "0.1.13"
- resolved "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.13.tgz"
- integrity sha512-hwdV/GQY5F8ReLZWO+W1SRoN5YfpOKY6852+tBFcma72DKBIcHjPRIlIvQN35bCOljuAfP2G2iB0FC/w236mUw==
-
-regexpp@^2.0.1:
- version "2.0.1"
- resolved "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz"
- integrity sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==
-
-regexpu-core@^4.5.4:
- version "4.6.0"
- resolved "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.6.0.tgz"
- integrity sha512-YlVaefl8P5BnFYOITTNzDvan1ulLOiXJzCNZxduTIosN17b87h3bvG9yHMoHaRuo88H4mQ06Aodj5VtYGGGiTg==
- dependencies:
- regenerate "^1.4.0"
- regenerate-unicode-properties "^8.1.0"
- regjsgen "^0.5.0"
- regjsparser "^0.6.0"
- unicode-match-property-ecmascript "^1.0.4"
- unicode-match-property-value-ecmascript "^1.1.0"
-
-regjsgen@^0.5.0:
- version "0.5.0"
- resolved "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.0.tgz"
- integrity sha512-RnIrLhrXCX5ow/E5/Mh2O4e/oa1/jW0eaBKTSy3LaCj+M3Bqvm97GWDp2yUtzIs4LEn65zR2yiYGFqb2ApnzDA==
-
-regjsparser@^0.6.0:
- version "0.6.0"
- resolved "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.0.tgz"
- integrity sha512-RQ7YyokLiQBomUJuUG8iGVvkgOLxwyZM8k6d3q5SAXpg4r5TZJZigKFvC6PpD+qQ98bCDC5YelPeA3EucDoNeQ==
- dependencies:
- jsesc "~0.5.0"
-
-relateurl@0.2.x:
- version "0.2.7"
- resolved "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz"
- integrity sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=
-
-remove-bom-buffer@^3.0.0:
- version "3.0.0"
- resolved "https://registry.npmjs.org/remove-bom-buffer/-/remove-bom-buffer-3.0.0.tgz"
- integrity sha512-8v2rWhaakv18qcvNeli2mZ/TMTL2nEyAKRvzo1WtnZBl15SHyEhrCu2/xKlJyUFKHiHgfXIyuY6g2dObJJycXQ==
- dependencies:
- is-buffer "^1.1.5"
- is-utf8 "^0.2.1"
-
-remove-bom-stream@^1.2.0:
- version "1.2.0"
- resolved "https://registry.npmjs.org/remove-bom-stream/-/remove-bom-stream-1.2.0.tgz"
- integrity sha1-BfGlk/FuQuH7kOv1nejlaVJflSM=
- dependencies:
- remove-bom-buffer "^3.0.0"
- safe-buffer "^5.1.0"
- through2 "^2.0.3"
-
-remove-trailing-separator@^1.0.1, remove-trailing-separator@^1.1.0:
- version "1.1.0"
- resolved "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz"
- integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8=
-
-repeat-element@^1.1.2:
- version "1.1.3"
- resolved "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz"
- integrity sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==
-
-repeat-string@^1.6.1:
- version "1.6.1"
- resolved "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz"
- integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc=
-
-repeating@^2.0.0:
- version "2.0.1"
- resolved "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz"
- integrity sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=
- dependencies:
- is-finite "^1.0.0"
-
-replace-ext@0.0.1:
- version "0.0.1"
- resolved "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz"
- integrity sha1-KbvZIHinOfC8zitO5B6DeVNSKSQ=
-
-replace-ext@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz"
- integrity sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=
-
-replace-homedir@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/replace-homedir/-/replace-homedir-1.0.0.tgz"
- integrity sha1-6H9tUTuSjd6AgmDBK+f+xv9ueYw=
- dependencies:
- homedir-polyfill "^1.0.1"
- is-absolute "^1.0.0"
- remove-trailing-separator "^1.1.0"
-
-request-promise-core@1.1.2:
- version "1.1.2"
- resolved "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.2.tgz"
- integrity sha512-UHYyq1MO8GsefGEt7EprS8UrXsm1TxEvFUX1IMTuSLU2Rh7fTIdFtl8xD7JiEYiWU2dl+NYAjCTksTehQUxPag==
- dependencies:
- lodash "^4.17.11"
-
-request-promise-native@^1.0.5:
- version "1.0.7"
- resolved "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.7.tgz"
- integrity sha512-rIMnbBdgNViL37nZ1b3L/VfPOpSi0TqVDQPAvO6U14lMzOLrt5nilxCQqtDKhZeDiW0/hkCXGoQjhgJd/tCh6w==
- dependencies:
- request-promise-core "1.1.2"
- stealthy-require "^1.1.1"
- tough-cookie "^2.3.3"
-
-request@^2.88.0:
- version "2.88.0"
- resolved "https://registry.npmjs.org/request/-/request-2.88.0.tgz"
- integrity sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==
- dependencies:
- aws-sign2 "~0.7.0"
- aws4 "^1.8.0"
- caseless "~0.12.0"
- combined-stream "~1.0.6"
- extend "~3.0.2"
- forever-agent "~0.6.1"
- form-data "~2.3.2"
- har-validator "~5.1.0"
- http-signature "~1.2.0"
- is-typedarray "~1.0.0"
- isstream "~0.1.2"
- json-stringify-safe "~5.0.1"
- mime-types "~2.1.19"
- oauth-sign "~0.9.0"
- performance-now "^2.1.0"
- qs "~6.5.2"
- safe-buffer "^5.1.2"
- tough-cookie "~2.4.3"
- tunnel-agent "^0.6.0"
- uuid "^3.3.2"
-
-require-directory@^2.1.1:
- version "2.1.1"
- resolved "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz"
- integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I=
-
-require-main-filename@^1.0.1:
- version "1.0.1"
- resolved "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz"
- integrity sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=
-
-require-main-filename@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz"
- integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==
-
-require-uncached@^1.0.2:
- version "1.0.3"
- resolved "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz"
- integrity sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=
- dependencies:
- caller-path "^0.1.0"
- resolve-from "^1.0.0"
-
-requires-port@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz"
- integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=
-
-resolve-cwd@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz"
- integrity sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=
- dependencies:
- resolve-from "^3.0.0"
-
-resolve-dir@^1.0.0, resolve-dir@^1.0.1:
- version "1.0.1"
- resolved "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz"
- integrity sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=
- dependencies:
- expand-tilde "^2.0.0"
- global-modules "^1.0.0"
-
-resolve-from@^1.0.0:
- version "1.0.1"
- resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz"
- integrity sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=
-
-resolve-from@^3.0.0:
- version "3.0.0"
- resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz"
- integrity sha1-six699nWiBvItuZTM17rywoYh0g=
-
-resolve-from@^4.0.0:
- version "4.0.0"
- resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz"
- integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==
-
-resolve-options@^1.1.0:
- version "1.1.0"
- resolved "https://registry.npmjs.org/resolve-options/-/resolve-options-1.1.0.tgz"
- integrity sha1-MrueOcBtZzONyTeMDW1gdFZq0TE=
- dependencies:
- value-or-function "^3.0.0"
-
-resolve-url@^0.2.1:
- version "0.2.1"
- resolved "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz"
- integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=
-
-resolve@^1.1.6, resolve@^1.1.7, resolve@^1.10.0, resolve@^1.15.1, resolve@^1.3.2, resolve@^1.4.0:
- version "1.17.0"
- resolved "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz"
- integrity sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==
- dependencies:
- path-parse "^1.0.6"
-
-resp-modifier@6.0.2:
- version "6.0.2"
- resolved "https://registry.npmjs.org/resp-modifier/-/resp-modifier-6.0.2.tgz"
- integrity sha1-sSTeXE+6/LpUH0j/pzlw9KpFa08=
- dependencies:
- debug "^2.2.0"
- minimatch "^3.0.2"
-
-responselike@1.0.2, responselike@^1.0.2:
- version "1.0.2"
- resolved "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz"
- integrity sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=
- dependencies:
- lowercase-keys "^1.0.0"
-
-restore-cursor@^1.0.1:
- version "1.0.1"
- resolved "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz"
- integrity sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=
- dependencies:
- exit-hook "^1.0.0"
- onetime "^1.0.0"
-
-restore-cursor@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz"
- integrity sha1-n37ih/gv0ybU/RYpI9YhKe7g368=
- dependencies:
- onetime "^2.0.0"
- signal-exit "^3.0.2"
-
-ret@~0.1.10:
- version "0.1.15"
- resolved "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz"
- integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==
-
-reusify@^1.0.4:
- version "1.0.4"
- resolved "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz"
- integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==
-
-rgb-regex@^1.0.1:
- version "1.0.1"
- resolved "https://registry.npmjs.org/rgb-regex/-/rgb-regex-1.0.1.tgz"
- integrity sha1-wODWiC3w4jviVKR16O3UGRX+rrE=
-
-rgba-regex@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/rgba-regex/-/rgba-regex-1.0.0.tgz"
- integrity sha1-QzdOLiyglosO8VI0YLfXMP8i7rM=
-
-rimraf@2.6.3, rimraf@~2.6.2:
- version "2.6.3"
- resolved "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz"
- integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==
- dependencies:
- glob "^7.1.3"
-
-rimraf@^2.4.0, rimraf@^2.5.4, rimraf@^2.6.2, rimraf@^2.6.3:
- version "2.7.1"
- resolved "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz"
- integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==
- dependencies:
- glob "^7.1.3"
-
-ripemd160@^2.0.0, ripemd160@^2.0.1:
- version "2.0.2"
- resolved "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz"
- integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==
- dependencies:
- hash-base "^3.0.0"
- inherits "^2.0.1"
-
-roarr@^2.15.3:
- version "2.15.4"
- resolved "https://registry.yarnpkg.com/roarr/-/roarr-2.15.4.tgz#f5fe795b7b838ccfe35dc608e0282b9eba2e7afd"
- integrity sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==
- dependencies:
- boolean "^3.0.1"
- detect-node "^2.0.4"
- globalthis "^1.0.1"
- json-stringify-safe "^5.0.1"
- semver-compare "^1.0.0"
- sprintf-js "^1.1.2"
-
-run-async@^0.1.0:
- version "0.1.0"
- resolved "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz"
- integrity sha1-yK1KXhEGYeQCp9IbUw4AnyX444k=
- dependencies:
- once "^1.3.0"
-
-run-async@^2.2.0:
- version "2.3.0"
- resolved "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz"
- integrity sha1-A3GrSuC91yDUFm19/aZP96RFpsA=
- dependencies:
- is-promise "^2.1.0"
-
-run-parallel@^1.1.9:
- version "1.1.9"
- resolved "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz"
- integrity sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==
-
-run-queue@^1.0.0, run-queue@^1.0.3:
- version "1.0.3"
- resolved "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz"
- integrity sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=
- dependencies:
- aproba "^1.1.1"
-
-rusha@^0.8.13:
- version "0.8.13"
- resolved "https://registry.npmjs.org/rusha/-/rusha-0.8.13.tgz"
- integrity sha1-mghOe4YLF7/zAVuSxnpqM2GRUTo=
-
-rx-lite@^3.1.2:
- version "3.1.2"
- resolved "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz"
- integrity sha1-Gc5QLKVyZl87ZHsQk5+X/RYV8QI=
-
-rx@4.1.0:
- version "4.1.0"
- resolved "https://registry.npmjs.org/rx/-/rx-4.1.0.tgz"
- integrity sha1-pfE/957zt0D+MKqAP7CfmIBdR4I=
-
-rxjs@^5.5.6:
- version "5.5.12"
- resolved "https://registry.npmjs.org/rxjs/-/rxjs-5.5.12.tgz"
- integrity sha512-xx2itnL5sBbqeeiVgNPVuQQ1nC8Jp2WfNJhXWHmElW9YmrpS9UVnNzhP3EH3HFqexO5Tlp8GhYY+WEcqcVMvGw==
- dependencies:
- symbol-observable "1.0.1"
-
-rxjs@^6.4.0:
- version "6.5.3"
- resolved "https://registry.npmjs.org/rxjs/-/rxjs-6.5.3.tgz"
- integrity sha512-wuYsAYYFdWTAnAaPoKGNhfpWwKZbJW+HgAJ+mImp+Epl7BG8oNWBCTyRM8gba9k4lk8BgWdoYm21Mo/RYhhbgA==
- dependencies:
- tslib "^1.9.0"
-
-safe-buffer@5.1.2, safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1:
- version "5.1.2"
- resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz"
- integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
-
-safe-regex@^1.1.0:
- version "1.1.0"
- resolved "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz"
- integrity sha1-QKNmnzsHfR6UPURinhV91IAjvy4=
- dependencies:
- ret "~0.1.10"
-
-"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0:
- version "2.1.2"
- resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz"
- integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
-
-sass-lint@^1.12.0:
- version "1.13.1"
- resolved "https://registry.npmjs.org/sass-lint/-/sass-lint-1.13.1.tgz"
- integrity sha512-DSyah8/MyjzW2BWYmQWekYEKir44BpLqrCFsgs9iaWiVTcwZfwXHF586hh3D1n+/9ihUNMfd8iHAyb9KkGgs7Q==
- dependencies:
- commander "^2.8.1"
- eslint "^2.7.0"
- front-matter "2.1.2"
- fs-extra "^3.0.1"
- glob "^7.0.0"
- globule "^1.0.0"
- gonzales-pe-sl "^4.2.3"
- js-yaml "^3.5.4"
- known-css-properties "^0.3.0"
- lodash.capitalize "^4.1.0"
- lodash.kebabcase "^4.0.0"
- merge "^1.2.0"
- path-is-absolute "^1.0.0"
- util "^0.10.3"
-
-sass-unused@^0.3.0:
- version "0.3.0"
- resolved "https://registry.npmjs.org/sass-unused/-/sass-unused-0.3.0.tgz"
- integrity sha512-fGNcUpDeSFwnN+BTQ251iM77Py8awPXc96vSE3TpvMcgbC90IrohonRb4oxWX/KzHpezkmUddS8/t04R+yIB8w==
- dependencies:
- glob "^7.0.5"
- gonzales-pe "^4.2.3"
-
-sass@^1.26.3:
- version "1.30.0"
- resolved "https://registry.npmjs.org/sass/-/sass-1.30.0.tgz"
- integrity sha512-26EUhOXRLaUY7+mWuRFqGeGGNmhB1vblpTENO1Z7mAzzIZeVxZr9EZoaY1kyGLFWdSOZxRMAufiN2mkbO6dAlw==
- dependencies:
- chokidar ">=2.0.0 <4.0.0"
-
-sax@>=0.6.0, sax@^1.2.4, sax@~1.2.4:
- version "1.2.4"
- resolved "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz"
- integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==
-
-saxes@^3.1.3:
- version "3.1.11"
- resolved "https://registry.npmjs.org/saxes/-/saxes-3.1.11.tgz"
- integrity sha512-Ydydq3zC+WYDJK1+gRxRapLIED9PWeSuuS41wqyoRmzvhhh9nc+QQrVMKJYzJFULazeGhzSV0QleN2wD3boh2g==
- dependencies:
- xmlchars "^2.1.1"
-
-schema-utils@^0.4.0:
- version "0.4.7"
- resolved "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.7.tgz"
- integrity sha512-v/iwU6wvwGK8HbU9yi3/nhGzP0yGSuhQMzL6ySiec1FSrZZDkhm4noOSWzrNFo/jEc+SJY6jRTwuwbSXJPDUnQ==
- dependencies:
- ajv "^6.1.0"
- ajv-keywords "^3.1.0"
-
-schema-utils@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz"
- integrity sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==
- dependencies:
- ajv "^6.1.0"
- ajv-errors "^1.0.0"
- ajv-keywords "^3.1.0"
-
-schema-utils@^2.6.5:
- version "2.6.5"
- resolved "https://registry.npmjs.org/schema-utils/-/schema-utils-2.6.5.tgz"
- integrity sha512-5KXuwKziQrTVHh8j/Uxz+QUbxkaLW9X/86NBlx/gnKgtsZA2GIVMUn17qWhRFwF8jdYb3Dig5hRO/W5mZqy6SQ==
- dependencies:
- ajv "^6.12.0"
- ajv-keywords "^3.4.1"
-
-schema-utils@^3.0.0:
- version "3.1.1"
- resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.1.1.tgz#bc74c4b6b6995c1d88f76a8b77bea7219e0c8281"
- integrity sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==
- dependencies:
- "@types/json-schema" "^7.0.8"
- ajv "^6.12.5"
- ajv-keywords "^3.5.2"
-
-seek-bzip@^1.0.5:
- version "1.0.5"
- resolved "https://registry.npmjs.org/seek-bzip/-/seek-bzip-1.0.5.tgz"
- integrity sha1-z+kXyz0nS8/6x5J1ivUxc+sfq9w=
- dependencies:
- commander "~2.8.1"
-
-semver-compare@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc"
- integrity sha1-De4hahyUGrN+nvsXiPavxf9VN/w=
-
-semver-greatest-satisfied-range@^1.1.0:
- version "1.1.0"
- resolved "https://registry.npmjs.org/semver-greatest-satisfied-range/-/semver-greatest-satisfied-range-1.1.0.tgz"
- integrity sha1-E+jCZYq5aRywzXEJMkAoDTb3els=
- dependencies:
- sver-compat "^1.5.0"
-
-semver-regex@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/semver-regex/-/semver-regex-2.0.0.tgz"
- integrity sha512-mUdIBBvdn0PLOeP3TEkMH7HHeUP3GjsXCwKarjv/kGmUFOYg1VqEemKhoQpWMu6X2I8kHeuVdGibLGkVK+/5Qw==
-
-semver-truncate@^1.1.2:
- version "1.1.2"
- resolved "https://registry.npmjs.org/semver-truncate/-/semver-truncate-1.1.2.tgz"
- integrity sha1-V/Qd5pcHpicJp+AQS6IRcQnqR+g=
- dependencies:
- semver "^5.3.0"
-
-"semver@2 || 3 || 4 || 5", semver@^5.1.0, semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0:
- version "5.7.1"
- resolved "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz"
- integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
-
-semver@^4.1.0:
- version "4.3.6"
- resolved "https://registry.npmjs.org/semver/-/semver-4.3.6.tgz"
- integrity sha1-MAvG4OhjdPe6YQaLWx7NV/xlMto=
-
-semver@^6.0.0, semver@^6.2.0, semver@^6.3.0:
- version "6.3.0"
- resolved "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz"
- integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==
-
-semver@^7.1.3, semver@^7.3.2:
- version "7.3.7"
- resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f"
- integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==
- dependencies:
- lru-cache "^6.0.0"
-
-send@0.16.2:
- version "0.16.2"
- resolved "https://registry.npmjs.org/send/-/send-0.16.2.tgz"
- integrity sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==
- dependencies:
- debug "2.6.9"
- depd "~1.1.2"
- destroy "~1.0.4"
- encodeurl "~1.0.2"
- escape-html "~1.0.3"
- etag "~1.8.1"
- fresh "0.5.2"
- http-errors "~1.6.2"
- mime "1.4.1"
- ms "2.0.0"
- on-finished "~2.3.0"
- range-parser "~1.2.0"
- statuses "~1.4.0"
-
-sequencify@~0.0.7:
- version "0.0.7"
- resolved "https://registry.npmjs.org/sequencify/-/sequencify-0.0.7.tgz"
- integrity sha1-kM/xnQLgcCf9dn9erT57ldHnOAw=
-
-serialize-error@^7.0.1:
- version "7.0.1"
- resolved "https://registry.yarnpkg.com/serialize-error/-/serialize-error-7.0.1.tgz#f1360b0447f61ffb483ec4157c737fab7d778e18"
- integrity sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==
- dependencies:
- type-fest "^0.13.1"
-
-serialize-javascript@^3.1.0:
- version "3.1.0"
- resolved "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-3.1.0.tgz"
- integrity sha512-JIJT1DGiWmIKhzRsG91aS6Ze4sFUrYbltlkg2onR5OrnNM02Kl/hnY/T4FN2omvyeBbQmMJv+K4cPOpGzOTFBg==
- dependencies:
- randombytes "^2.1.0"
-
-serve-index@1.9.1, serve-index@^1.1.4:
- version "1.9.1"
- resolved "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz"
- integrity sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=
- dependencies:
- accepts "~1.3.4"
- batch "0.6.1"
- debug "2.6.9"
- escape-html "~1.0.3"
- http-errors "~1.6.2"
- mime-types "~2.1.17"
- parseurl "~1.3.2"
-
-serve-static@1.13.2, serve-static@^1.3.0:
- version "1.13.2"
- resolved "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz"
- integrity sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==
- dependencies:
- encodeurl "~1.0.2"
- escape-html "~1.0.3"
- parseurl "~1.3.2"
- send "0.16.2"
-
-server-destroy@1.0.1:
- version "1.0.1"
- resolved "https://registry.npmjs.org/server-destroy/-/server-destroy-1.0.1.tgz"
- integrity sha1-8Tv5KOQrnD55OD5hzDmYtdFObN0=
-
-set-blocking@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz"
- integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc=
-
-set-value@^2.0.0, set-value@^2.0.1:
- version "2.0.1"
- resolved "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz"
- integrity sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==
- dependencies:
- extend-shallow "^2.0.1"
- is-extendable "^0.1.1"
- is-plain-object "^2.0.3"
- split-string "^3.0.1"
-
-setimmediate@^1.0.4:
- version "1.0.5"
- resolved "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz"
- integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=
-
-setprototypeof@1.1.0:
- version "1.1.0"
- resolved "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz"
- integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==
-
-setprototypeof@1.1.1:
- version "1.1.1"
- resolved "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz"
- integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==
-
-sha.js@^2.4.0, sha.js@^2.4.8:
- version "2.4.11"
- resolved "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz"
- integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==
- dependencies:
- inherits "^2.0.1"
- safe-buffer "^5.0.1"
-
-shebang-command@^1.2.0:
- version "1.2.0"
- resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz"
- integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=
- dependencies:
- shebang-regex "^1.0.0"
-
-shebang-command@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz"
- integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==
- dependencies:
- shebang-regex "^3.0.0"
-
-shebang-regex@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz"
- integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=
-
-shebang-regex@^3.0.0:
- version "3.0.0"
- resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz"
- integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==
-
-shelljs@^0.6.0:
- version "0.6.1"
- resolved "https://registry.npmjs.org/shelljs/-/shelljs-0.6.1.tgz"
- integrity sha1-7GIRvtGSBEIIj+D3Cyg3Iy7SyKg=
-
-sigmund@^1.0.1, sigmund@~1.0.0:
- version "1.0.1"
- resolved "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz"
- integrity sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=
-
-signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3:
- version "3.0.3"
- resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz"
- integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==
-
-simple-swizzle@^0.2.2:
- version "0.2.2"
- resolved "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz"
- integrity sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=
- dependencies:
- is-arrayish "^0.3.1"
-
-slash@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz"
- integrity sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=
-
-slash@^3.0.0:
- version "3.0.0"
- resolved "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz"
- integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==
-
-slice-ansi@0.0.4:
- version "0.0.4"
- resolved "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz"
- integrity sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=
-
-slice-ansi@^2.1.0:
- version "2.1.0"
- resolved "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz"
- integrity sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==
- dependencies:
- ansi-styles "^3.2.0"
- astral-regex "^1.0.0"
- is-fullwidth-code-point "^2.0.0"
-
-snapdragon-node@^2.0.1:
- version "2.1.1"
- resolved "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz"
- integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==
- dependencies:
- define-property "^1.0.0"
- isobject "^3.0.0"
- snapdragon-util "^3.0.1"
-
-snapdragon-util@^3.0.1:
- version "3.0.1"
- resolved "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz"
- integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==
- dependencies:
- kind-of "^3.2.0"
-
-snapdragon@^0.8.1:
- version "0.8.2"
- resolved "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz"
- integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==
- dependencies:
- base "^0.11.1"
- debug "^2.2.0"
- define-property "^0.2.5"
- extend-shallow "^2.0.1"
- map-cache "^0.2.2"
- source-map "^0.5.6"
- source-map-resolve "^0.5.0"
- use "^3.1.0"
-
-socket.io-adapter@~1.1.0:
- version "1.1.1"
- resolved "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-1.1.1.tgz"
- integrity sha1-KoBeihTWNyEk3ZFZrUUC+MsH8Gs=
-
-socket.io-client@2.1.1:
- version "2.1.1"
- resolved "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.1.1.tgz"
- integrity sha512-jxnFyhAuFxYfjqIgduQlhzqTcOEQSn+OHKVfAxWaNWa7ecP7xSNk2Dx/3UEsDcY7NcFafxvNvKPmmO7HTwTxGQ==
- dependencies:
- backo2 "1.0.2"
- base64-arraybuffer "0.1.5"
- component-bind "1.0.0"
- component-emitter "1.2.1"
- debug "~3.1.0"
- engine.io-client "~3.2.0"
- has-binary2 "~1.0.2"
- has-cors "1.1.0"
- indexof "0.0.1"
- object-component "0.0.3"
- parseqs "0.0.5"
- parseuri "0.0.5"
- socket.io-parser "~3.2.0"
- to-array "0.1.4"
-
-socket.io-client@^2.0.4:
- version "2.3.0"
- resolved "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.3.0.tgz"
- integrity sha512-cEQQf24gET3rfhxZ2jJ5xzAOo/xhZwK+mOqtGRg5IowZsMgwvHwnf/mCRapAAkadhM26y+iydgwsXGObBB5ZdA==
- dependencies:
- backo2 "1.0.2"
- base64-arraybuffer "0.1.5"
- component-bind "1.0.0"
- component-emitter "1.2.1"
- debug "~4.1.0"
- engine.io-client "~3.4.0"
- has-binary2 "~1.0.2"
- has-cors "1.1.0"
- indexof "0.0.1"
- object-component "0.0.3"
- parseqs "0.0.5"
- parseuri "0.0.5"
- socket.io-parser "~3.3.0"
- to-array "0.1.4"
-
-socket.io-parser@~3.2.0:
- version "3.2.0"
- resolved "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.2.0.tgz"
- integrity sha512-FYiBx7rc/KORMJlgsXysflWx/RIvtqZbyGLlHZvjfmPTPeuD/I8MaW7cfFrj5tRltICJdgwflhfZ3NVVbVLFQA==
- dependencies:
- component-emitter "1.2.1"
- debug "~3.1.0"
- isarray "2.0.1"
-
-socket.io-parser@~3.3.0:
- version "3.3.0"
- resolved "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.3.0.tgz"
- integrity sha512-hczmV6bDgdaEbVqhAeVMM/jfUfzuEZHsQg6eOmLgJht6G3mPKMxYm75w2+qhAQZ+4X+1+ATZ+QFKeOZD5riHng==
- dependencies:
- component-emitter "1.2.1"
- debug "~3.1.0"
- isarray "2.0.1"
-
-socket.io@2.1.1:
- version "2.1.1"
- resolved "https://registry.npmjs.org/socket.io/-/socket.io-2.1.1.tgz"
- integrity sha512-rORqq9c+7W0DAK3cleWNSyfv/qKXV99hV4tZe+gGLfBECw3XEhBy7x85F3wypA9688LKjtwO9pX9L33/xQI8yA==
- dependencies:
- debug "~3.1.0"
- engine.io "~3.2.0"
- has-binary2 "~1.0.2"
- socket.io-adapter "~1.1.0"
- socket.io-client "2.1.1"
- socket.io-parser "~3.2.0"
-
-sort-keys-length@^1.0.0:
- version "1.0.1"
- resolved "https://registry.npmjs.org/sort-keys-length/-/sort-keys-length-1.0.1.tgz"
- integrity sha1-nLb09OnkgVWmqgZx7dM2/xR5oYg=
- dependencies:
- sort-keys "^1.0.0"
-
-sort-keys@^1.0.0:
- version "1.1.2"
- resolved "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz"
- integrity sha1-RBttTTRnmPG05J6JIK37oOVD+a0=
- dependencies:
- is-plain-obj "^1.0.0"
-
-sort-keys@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/sort-keys/-/sort-keys-2.0.0.tgz"
- integrity sha1-ZYU1WEhh7JfXMNbPQYIuH1ZoQSg=
- dependencies:
- is-plain-obj "^1.0.0"
-
-source-list-map@^2.0.0:
- version "2.0.1"
- resolved "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz"
- integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==
-
-source-map-resolve@^0.5.0:
- version "0.5.2"
- resolved "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz"
- integrity sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==
- dependencies:
- atob "^2.1.1"
- decode-uri-component "^0.2.0"
- resolve-url "^0.2.1"
- source-map-url "^0.4.0"
- urix "^0.1.0"
-
-source-map-support@^0.4.15:
- version "0.4.18"
- resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz"
- integrity sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==
- dependencies:
- source-map "^0.5.6"
-
-source-map-support@~0.5.12:
- version "0.5.13"
- resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz"
- integrity sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==
- dependencies:
- buffer-from "^1.0.0"
- source-map "^0.6.0"
-
-source-map-url@^0.4.0:
- version "0.4.0"
- resolved "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz"
- integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=
-
-source-map@^0.5.0, source-map@^0.5.1, source-map@^0.5.3, source-map@^0.5.6, source-map@^0.5.7, source-map@~0.5.0:
- version "0.5.7"
- resolved "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz"
- integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=
-
-source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1:
- version "0.6.1"
- resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz"
- integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
-
-source-map@~0.1.38:
- version "0.1.43"
- resolved "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz"
- integrity sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y=
- dependencies:
- amdefine ">=0.0.4"
-
-sparkles@^1.0.0:
- version "1.0.1"
- resolved "https://registry.npmjs.org/sparkles/-/sparkles-1.0.1.tgz"
- integrity sha512-dSO0DDYUahUt/0/pD/Is3VIm5TGJjludZ0HVymmhYF6eNA53PVLhnUk0znSYbH8IYBuJdCE+1luR22jNLMaQdw==
-
-spdx-correct@^3.0.0:
- version "3.1.0"
- resolved "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz"
- integrity sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==
- dependencies:
- spdx-expression-parse "^3.0.0"
- spdx-license-ids "^3.0.0"
-
-spdx-exceptions@^2.1.0:
- version "2.2.0"
- resolved "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz"
- integrity sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==
-
-spdx-expression-parse@^3.0.0:
- version "3.0.0"
- resolved "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz"
- integrity sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==
- dependencies:
- spdx-exceptions "^2.1.0"
- spdx-license-ids "^3.0.0"
-
-spdx-license-ids@^3.0.0:
- version "3.0.5"
- resolved "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz"
- integrity sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==
-
-split-on-first@^1.0.0:
- version "1.1.0"
- resolved "https://registry.npmjs.org/split-on-first/-/split-on-first-1.1.0.tgz"
- integrity sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==
-
-split-string@^3.0.1, split-string@^3.0.2:
- version "3.1.0"
- resolved "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz"
- integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==
- dependencies:
- extend-shallow "^3.0.0"
-
-sprintf-js@^1.1.2:
- version "1.1.2"
- resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.1.2.tgz#da1765262bf8c0f571749f2ad6c26300207ae673"
- integrity sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==
-
-sprintf-js@~1.0.2:
- version "1.0.3"
- resolved "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz"
- integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=
-
-squeak@^1.0.0:
- version "1.3.0"
- resolved "https://registry.npmjs.org/squeak/-/squeak-1.3.0.tgz"
- integrity sha1-MwRQN7ZDiLVnZ0uEMiplIQc5FsM=
- dependencies:
- chalk "^1.0.0"
- console-stream "^0.1.1"
- lpad-align "^1.0.1"
-
-ssh2-streams@~0.2.0:
- version "0.2.1"
- resolved "https://registry.npmjs.org/ssh2-streams/-/ssh2-streams-0.2.1.tgz"
- integrity sha512-3zCOsmunh1JWgPshfhKmBCL3lUtHPoh+a/cyQ49Ft0Q0aF7xgN06b76L+oKtFi0fgO57FLjFztb1GlJcEZ4a3Q==
- dependencies:
- asn1 "~0.2.0"
- semver "^5.1.0"
- streamsearch "~0.1.2"
-
-ssh2@~0.6.1:
- version "0.6.2"
- resolved "https://registry.npmjs.org/ssh2/-/ssh2-0.6.2.tgz"
- integrity sha512-DJ+dOhXEEsmNpcQTI0x69FS++JH6qqL/ltEHf01pI1SSLMAcmD+hL4jRwvHjPwynPsmSUbHJ/WIZYzROfqZWjA==
- dependencies:
- ssh2-streams "~0.2.0"
-
-sshpk@^1.7.0:
- version "1.16.1"
- resolved "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz"
- integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==
- dependencies:
- asn1 "~0.2.3"
- assert-plus "^1.0.0"
- bcrypt-pbkdf "^1.0.0"
- dashdash "^1.12.0"
- ecc-jsbn "~0.1.1"
- getpass "^0.1.1"
- jsbn "~0.1.0"
- safer-buffer "^2.0.2"
- tweetnacl "~0.14.0"
-
-ssri@^6.0.1:
- version "6.0.1"
- resolved "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz"
- integrity sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==
- dependencies:
- figgy-pudding "^3.5.1"
-
-stable@^0.1.8:
- version "0.1.8"
- resolved "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz"
- integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==
-
-stack-trace@0.0.10, stack-trace@0.0.x:
- version "0.0.10"
- resolved "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz"
- integrity sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=
-
-static-extend@^0.1.1:
- version "0.1.2"
- resolved "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz"
- integrity sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=
- dependencies:
- define-property "^0.2.5"
- object-copy "^0.1.0"
-
-"statuses@>= 1.4.0 < 2", statuses@~1.4.0:
- version "1.4.0"
- resolved "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz"
- integrity sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==
-
-"statuses@>= 1.5.0 < 2":
- version "1.5.0"
- resolved "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz"
- integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=
-
-statuses@~1.3.1:
- version "1.3.1"
- resolved "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz"
- integrity sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=
-
-stealthy-require@^1.1.1:
- version "1.1.1"
- resolved "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz"
- integrity sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=
-
-stream-browserify@^2.0.1:
- version "2.0.2"
- resolved "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz"
- integrity sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==
- dependencies:
- inherits "~2.0.1"
- readable-stream "^2.0.2"
-
-stream-browserify@^3.0.0:
- version "3.0.0"
- resolved "https://registry.npmjs.org/stream-browserify/-/stream-browserify-3.0.0.tgz"
- integrity sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==
- dependencies:
- inherits "~2.0.4"
- readable-stream "^3.5.0"
-
-stream-consume@~0.1.0:
- version "0.1.1"
- resolved "https://registry.npmjs.org/stream-consume/-/stream-consume-0.1.1.tgz"
- integrity sha512-tNa3hzgkjEP7XbCkbRXe1jpg+ievoa0O4SCFlMOYEscGSS4JJsckGL8swUyAa/ApGU3Ae4t6Honor4HhL+tRyg==
-
-stream-each@^1.1.0:
- version "1.2.3"
- resolved "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz"
- integrity sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==
- dependencies:
- end-of-stream "^1.1.0"
- stream-shift "^1.0.0"
-
-stream-exhaust@^1.0.1:
- version "1.0.2"
- resolved "https://registry.npmjs.org/stream-exhaust/-/stream-exhaust-1.0.2.tgz"
- integrity sha512-b/qaq/GlBK5xaq1yrK9/zFcyRSTNxmcZwFLGSTG0mXgZl/4Z6GgiyYOXOvY7N3eEvFRAG1bkDRz5EPGSvPYQlw==
-
-stream-http@^2.7.2:
- version "2.8.3"
- resolved "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz"
- integrity sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==
- dependencies:
- builtin-status-codes "^3.0.0"
- inherits "^2.0.1"
- readable-stream "^2.3.6"
- to-arraybuffer "^1.0.0"
- xtend "^4.0.0"
-
-stream-shift@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz"
- integrity sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=
-
-stream-throttle@^0.1.3:
- version "0.1.3"
- resolved "https://registry.npmjs.org/stream-throttle/-/stream-throttle-0.1.3.tgz"
- integrity sha1-rdV8jXzHOoFjDTHNVdOWHPr7qcM=
- dependencies:
- commander "^2.2.0"
- limiter "^1.0.5"
-
-streamsearch@~0.1.2:
- version "0.1.2"
- resolved "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz"
- integrity sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=
-
-strict-uri-encode@^1.0.0:
- version "1.1.0"
- resolved "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz"
- integrity sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=
-
-strict-uri-encode@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz"
- integrity sha1-ucczDHBChi9rFC3CdLvMWGbONUY=
-
-strictdom@^1.0.1:
- version "1.0.1"
- resolved "https://registry.npmjs.org/strictdom/-/strictdom-1.0.1.tgz"
- integrity sha1-GJ3pFkn3PUTVm4Qy76aO+dJllGA=
-
-string-replace-webpack-plugin@^0.1.3:
- version "0.1.3"
- resolved "https://registry.npmjs.org/string-replace-webpack-plugin/-/string-replace-webpack-plugin-0.1.3.tgz"
- integrity sha1-c8ZX51nWbP6Arh4M8JGqJW0OcVw=
- dependencies:
- async "~0.2.10"
- loader-utils "~0.2.3"
- optionalDependencies:
- css-loader "^0.9.1"
- file-loader "^0.8.1"
- style-loader "^0.8.3"
-
-string-width@^1.0.1, string-width@^1.0.2:
- version "1.0.2"
- resolved "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz"
- integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=
- dependencies:
- code-point-at "^1.0.0"
- is-fullwidth-code-point "^1.0.0"
- strip-ansi "^3.0.0"
-
-string-width@^2.0.0, string-width@^2.1.0:
- version "2.1.1"
- resolved "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz"
- integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==
- dependencies:
- is-fullwidth-code-point "^2.0.0"
- strip-ansi "^4.0.0"
-
-string-width@^3.0.0, string-width@^3.1.0:
- version "3.1.0"
- resolved "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz"
- integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==
- dependencies:
- emoji-regex "^7.0.1"
- is-fullwidth-code-point "^2.0.0"
- strip-ansi "^5.1.0"
-
-string-width@^4.1.0, string-width@^4.2.0:
- version "4.2.0"
- resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz"
- integrity sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==
- dependencies:
- emoji-regex "^8.0.0"
- is-fullwidth-code-point "^3.0.0"
- strip-ansi "^6.0.0"
-
-string.prototype.trim@^1.1.2:
- version "1.2.0"
- resolved "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.0.tgz"
- integrity sha512-9EIjYD/WdlvLpn987+ctkLf0FfvBefOCuiEr2henD8X+7jfwPnyvTdmW8OJhj5p+M0/96mBdynLWkxUr+rHlpg==
- dependencies:
- define-properties "^1.1.3"
- es-abstract "^1.13.0"
- function-bind "^1.1.1"
-
-string.prototype.trimleft@^2.0.0:
- version "2.1.0"
- resolved "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.0.tgz"
- integrity sha512-FJ6b7EgdKxxbDxc79cOlok6Afd++TTs5szo+zJTUyow3ycrRfJVE2pq3vcN53XexvKZu/DJMDfeI/qMiZTrjTw==
- dependencies:
- define-properties "^1.1.3"
- function-bind "^1.1.1"
-
-string.prototype.trimright@^2.0.0:
- version "2.1.0"
- resolved "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.0.tgz"
- integrity sha512-fXZTSV55dNBwv16uw+hh5jkghxSnc5oHq+5K/gXgizHwAvMetdAJlHqqoFC1FSDVPYWLkAKl2cxpUT41sV7nSg==
- dependencies:
- define-properties "^1.1.3"
- function-bind "^1.1.1"
-
-string_decoder@^1.0.0, string_decoder@^1.1.1, string_decoder@~1.1.1:
- version "1.1.1"
- resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz"
- integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==
- dependencies:
- safe-buffer "~5.1.0"
-
-string_decoder@~0.10.x:
- version "0.10.31"
- resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz"
- integrity sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=
-
-strip-ansi@^0.3.0:
- version "0.3.0"
- resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.3.0.tgz"
- integrity sha1-JfSOoiynkYfzF0pNuHWTR7sSYiA=
- dependencies:
- ansi-regex "^0.2.1"
-
-strip-ansi@^3.0.0, strip-ansi@^3.0.1:
- version "3.0.1"
- resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz"
- integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=
- dependencies:
- ansi-regex "^2.0.0"
-
-strip-ansi@^4.0.0:
- version "4.0.0"
- resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz"
- integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8=
- dependencies:
- ansi-regex "^3.0.0"
-
-strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0:
- version "5.2.0"
- resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz"
- integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==
- dependencies:
- ansi-regex "^4.1.0"
-
-strip-ansi@^6.0.0:
- version "6.0.0"
- resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz"
- integrity sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==
- dependencies:
- ansi-regex "^5.0.0"
-
-strip-bom@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/strip-bom/-/strip-bom-1.0.0.tgz"
- integrity sha1-hbiGLzhEtabV7IRnqTWYFzo295Q=
- dependencies:
- first-chunk-stream "^1.0.0"
- is-utf8 "^0.2.0"
-
-strip-bom@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz"
- integrity sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=
- dependencies:
- is-utf8 "^0.2.0"
-
-strip-bom@^3.0.0:
- version "3.0.0"
- resolved "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz"
- integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=
-
-strip-dirs@^2.0.0:
- version "2.1.0"
- resolved "https://registry.npmjs.org/strip-dirs/-/strip-dirs-2.1.0.tgz"
- integrity sha512-JOCxOeKLm2CAS73y/U4ZeZPTkE+gNVCzKt7Eox84Iej1LT/2pTWYpZKJuxwQpvX1LiZb1xokNR7RLfuBAa7T3g==
- dependencies:
- is-natural-number "^4.0.1"
-
-strip-eof@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz"
- integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=
-
-strip-final-newline@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz"
- integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==
-
-strip-indent@^1.0.1:
- version "1.0.1"
- resolved "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz"
- integrity sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=
- dependencies:
- get-stdin "^4.0.1"
-
-strip-indent@^3.0.0:
- version "3.0.0"
- resolved "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz"
- integrity sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==
- dependencies:
- min-indent "^1.0.0"
-
-strip-json-comments@^2.0.1:
- version "2.0.1"
- resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz"
- integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo=
-
-strip-json-comments@^3.0.1:
- version "3.0.1"
- resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz"
- integrity sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==
-
-strip-json-comments@~1.0.1:
- version "1.0.4"
- resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-1.0.4.tgz"
- integrity sha1-HhX7ysl9Pumb8tc7TGVrCCu6+5E=
-
-strip-outer@^1.0.0, strip-outer@^1.0.1:
- version "1.0.1"
- resolved "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz"
- integrity sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==
- dependencies:
- escape-string-regexp "^1.0.2"
-
-style-loader@^0.8.3:
- version "0.8.3"
- resolved "https://registry.npmjs.org/style-loader/-/style-loader-0.8.3.tgz"
- integrity sha1-9Pkut9tjdodI8VBlzWcA9aHIU1c=
- dependencies:
- loader-utils "^0.2.5"
-
-stylehacks@^4.0.0:
- version "4.0.3"
- resolved "https://registry.npmjs.org/stylehacks/-/stylehacks-4.0.3.tgz"
- integrity sha512-7GlLk9JwlElY4Y6a/rmbH2MhVlTyVmiJd1PfTCqFaIBEGMYNsrO/v3SeGTdhBThLg4Z+NbOk/qFMwCa+J+3p/g==
- dependencies:
- browserslist "^4.0.0"
- postcss "^7.0.0"
- postcss-selector-parser "^3.0.0"
-
-sumchecker@^3.0.1:
- version "3.0.1"
- resolved "https://registry.yarnpkg.com/sumchecker/-/sumchecker-3.0.1.tgz#6377e996795abb0b6d348e9b3e1dfb24345a8e42"
- integrity sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==
- dependencies:
- debug "^4.1.0"
-
-supports-color@6.1.0, supports-color@^6.1.0:
- version "6.1.0"
- resolved "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz"
- integrity sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==
- dependencies:
- has-flag "^3.0.0"
-
-supports-color@^0.2.0:
- version "0.2.0"
- resolved "https://registry.npmjs.org/supports-color/-/supports-color-0.2.0.tgz"
- integrity sha1-2S3iaU6z9nMjlz1649i1W0wiGQo=
-
-supports-color@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz"
- integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=
-
-supports-color@^3.2.3:
- version "3.2.3"
- resolved "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz"
- integrity sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=
- dependencies:
- has-flag "^1.0.0"
-
-supports-color@^5.3.0, supports-color@^5.4.0, supports-color@^5.5.0:
- version "5.5.0"
- resolved "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz"
- integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==
- dependencies:
- has-flag "^3.0.0"
-
-supports-color@^7.1.0:
- version "7.1.0"
- resolved "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz"
- integrity sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==
- dependencies:
- has-flag "^4.0.0"
-
-sver-compat@^1.5.0:
- version "1.5.0"
- resolved "https://registry.npmjs.org/sver-compat/-/sver-compat-1.5.0.tgz"
- integrity sha1-PPh9/rTQe0o/FIJ7wYaz/QxkXNg=
- dependencies:
- es6-iterator "^2.0.1"
- es6-symbol "^3.1.1"
-
-svgo@^1.0.0, svgo@^1.0.5:
- version "1.3.0"
- resolved "https://registry.npmjs.org/svgo/-/svgo-1.3.0.tgz"
- integrity sha512-MLfUA6O+qauLDbym+mMZgtXCGRfIxyQoeH6IKVcFslyODEe/ElJNwr0FohQ3xG4C6HK6bk3KYPPXwHVJk3V5NQ==
- dependencies:
- chalk "^2.4.1"
- coa "^2.0.2"
- css-select "^2.0.0"
- css-select-base-adapter "^0.1.1"
- css-tree "1.0.0-alpha.33"
- csso "^3.5.1"
- js-yaml "^3.13.1"
- mkdirp "~0.5.1"
- object.values "^1.1.0"
- sax "~1.2.4"
- stable "^0.1.8"
- unquote "~1.1.1"
- util.promisify "~1.0.0"
-
-symbol-observable@1.0.1:
- version "1.0.1"
- resolved "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.0.1.tgz"
- integrity sha1-g0D8RwLDEi310iKI+IKD9RPT/dQ=
-
-symbol-tree@^3.2.2:
- version "3.2.4"
- resolved "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz"
- integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==
-
-table@^3.7.8:
- version "3.8.3"
- resolved "https://registry.npmjs.org/table/-/table-3.8.3.tgz"
- integrity sha1-K7xULw/amGGnVdOUf+/Ys/UThV8=
- dependencies:
- ajv "^4.7.0"
- ajv-keywords "^1.0.0"
- chalk "^1.1.1"
- lodash "^4.0.0"
- slice-ansi "0.0.4"
- string-width "^2.0.0"
-
-table@^5.2.3:
- version "5.4.6"
- resolved "https://registry.npmjs.org/table/-/table-5.4.6.tgz"
- integrity sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==
- dependencies:
- ajv "^6.10.2"
- lodash "^4.17.14"
- slice-ansi "^2.1.0"
- string-width "^3.0.0"
-
-tapable@^1.0.0, tapable@^1.1.3:
- version "1.1.3"
- resolved "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz"
- integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==
-
-tar-stream@^1.5.2:
- version "1.6.2"
- resolved "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz"
- integrity sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==
- dependencies:
- bl "^1.0.0"
- buffer-alloc "^1.2.0"
- end-of-stream "^1.0.0"
- fs-constants "^1.0.0"
- readable-stream "^2.3.0"
- to-buffer "^1.1.1"
- xtend "^4.0.0"
-
-tar-stream@~0.4.0:
- version "0.4.7"
- resolved "https://registry.npmjs.org/tar-stream/-/tar-stream-0.4.7.tgz"
- integrity sha1-Hx0s6evHtCdlJDyg6PG3v9oKrc0=
- dependencies:
- bl "^0.9.0"
- end-of-stream "^1.0.0"
- readable-stream "^1.0.27-1"
- xtend "^4.0.0"
-
-temp-dir@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/temp-dir/-/temp-dir-1.0.0.tgz"
- integrity sha1-CnwOom06Oa+n4OvqnB/AvE2qAR0=
-
-tempfile@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/tempfile/-/tempfile-2.0.0.tgz"
- integrity sha1-awRGhWqbERTRhW/8vlCczLCXcmU=
- dependencies:
- temp-dir "^1.0.0"
- uuid "^3.0.1"
-
-ternary-stream@^3.0.0:
- version "3.0.0"
- resolved "https://registry.npmjs.org/ternary-stream/-/ternary-stream-3.0.0.tgz"
- integrity sha512-oIzdi+UL/JdktkT+7KU5tSIQjj8pbShj3OASuvDEhm0NT5lppsm7aXWAmAq4/QMaBIyfuEcNLbAQA+HpaISobQ==
- dependencies:
- duplexify "^4.1.1"
- fork-stream "^0.0.4"
- merge-stream "^2.0.0"
- through2 "^3.0.1"
-
-terser-webpack-plugin@^1.1.0, terser-webpack-plugin@^1.4.3:
- version "1.4.4"
- resolved "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.4.tgz"
- integrity sha512-U4mACBHIegmfoEe5fdongHESNJWqsGU+W0S/9+BmYGVQDw1+c2Ow05TpMhxjPK1sRb7cuYq1BPl1e5YHJMTCqA==
- dependencies:
- cacache "^12.0.2"
- find-cache-dir "^2.1.0"
- is-wsl "^1.1.0"
- schema-utils "^1.0.0"
- serialize-javascript "^3.1.0"
- source-map "^0.6.1"
- terser "^4.1.2"
- webpack-sources "^1.4.0"
- worker-farm "^1.7.0"
-
-terser@^4.0.0, terser@^4.1.2:
- version "4.3.1"
- resolved "https://registry.npmjs.org/terser/-/terser-4.3.1.tgz"
- integrity sha512-pnzH6dnFEsR2aa2SJaKb1uSCl3QmIsJ8dEkj0Fky+2AwMMcC9doMqLOQIH6wVTEKaVfKVvLSk5qxPBEZT9mywg==
- dependencies:
- commander "^2.20.0"
- source-map "~0.6.1"
- source-map-support "~0.5.12"
-
-text-table@^0.2.0, text-table@~0.2.0:
- version "0.2.0"
- resolved "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz"
- integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=
-
-tfunk@^3.0.1:
- version "3.1.0"
- resolved "https://registry.npmjs.org/tfunk/-/tfunk-3.1.0.tgz"
- integrity sha1-OORBT8ZJd9h6/apy+sttKfgve1s=
- dependencies:
- chalk "^1.1.1"
- object-path "^0.9.0"
-
-through2-concurrent@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/through2-concurrent/-/through2-concurrent-2.0.0.tgz"
- integrity sha512-R5/jLkfMvdmDD+seLwN7vB+mhbqzWop5fAjx5IX8/yQq7VhBhzDmhXgaHAOnhnWkCpRMM7gToYHycB0CS/pd+A==
- dependencies:
- through2 "^2.0.0"
-
-through2-filter@^3.0.0:
- version "3.0.0"
- resolved "https://registry.npmjs.org/through2-filter/-/through2-filter-3.0.0.tgz"
- integrity sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA==
- dependencies:
- through2 "~2.0.0"
- xtend "~4.0.0"
-
-through2@*, through2@3.0.1, through2@^3.0.0, through2@^3.0.1:
- version "3.0.1"
- resolved "https://registry.npmjs.org/through2/-/through2-3.0.1.tgz"
- integrity sha512-M96dvTalPT3YbYLaKaCuwu+j06D/8Jfib0o/PxbVt6Amhv3dUAtW6rTV1jPgJSBG83I/e04Y6xkVdVhSRhi0ww==
- dependencies:
- readable-stream "2 || 3"
-
-through2@2.0.3:
- version "2.0.3"
- resolved "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz"
- integrity sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=
- dependencies:
- readable-stream "^2.1.5"
- xtend "~4.0.1"
-
-through2@^0.4.1, through2@~0.4.2:
- version "0.4.2"
- resolved "https://registry.npmjs.org/through2/-/through2-0.4.2.tgz"
- integrity sha1-2/WGYDEVHsg1K7bE22SiKSqEC5s=
- dependencies:
- readable-stream "~1.0.17"
- xtend "~2.1.1"
-
-through2@^0.5.0, through2@^0.5.1:
- version "0.5.1"
- resolved "https://registry.npmjs.org/through2/-/through2-0.5.1.tgz"
- integrity sha1-390BLrnHAOIyP9M084rGIqs3Lac=
- dependencies:
- readable-stream "~1.0.17"
- xtend "~3.0.0"
-
-through2@^0.6.1, through2@~0.6.1:
- version "0.6.5"
- resolved "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz"
- integrity sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=
- dependencies:
- readable-stream ">=1.0.33-1 <1.1.0-0"
- xtend ">=4.0.0 <4.1.0-0"
-
-through2@^2.0.0, through2@^2.0.1, through2@^2.0.2, through2@^2.0.3, through2@~2.0.0:
- version "2.0.5"
- resolved "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz"
- integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==
- dependencies:
- readable-stream "~2.3.6"
- xtend "~4.0.1"
-
-through2@~0.3.0:
- version "0.3.0"
- resolved "https://registry.npmjs.org/through2/-/through2-0.3.0.tgz"
- integrity sha1-LR0oyNHa+NnFy3jwppNDxrhkLZc=
- dependencies:
- readable-stream "~1.0.17"
- xtend "~2.1.1"
-
-through@^2.3.6, through@^2.3.8, through@~2.3.6:
- version "2.3.8"
- resolved "https://registry.npmjs.org/through/-/through-2.3.8.tgz"
- integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=
-
-tildify@^1.0.0:
- version "1.2.0"
- resolved "https://registry.npmjs.org/tildify/-/tildify-1.2.0.tgz"
- integrity sha1-3OwD9V3Km3qj5bBPIYF+tW5jWIo=
- dependencies:
- os-homedir "^1.0.0"
-
-time-stamp@^1.0.0:
- version "1.1.0"
- resolved "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz"
- integrity sha1-dkpaEa9QVhkhsTPztE5hhofg9cM=
-
-timed-out@^4.0.0, timed-out@^4.0.1:
- version "4.0.1"
- resolved "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz"
- integrity sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=
-
-timers-browserify@^2.0.4:
- version "2.0.11"
- resolved "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.11.tgz"
- integrity sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ==
- dependencies:
- setimmediate "^1.0.4"
-
-timm@^1.6.1:
- version "1.6.2"
- resolved "https://registry.npmjs.org/timm/-/timm-1.6.2.tgz"
- integrity sha512-IH3DYDL1wMUwmIlVmMrmesw5lZD6N+ZOAFWEyLrtpoL9Bcrs9u7M/vyOnHzDD2SMs4irLkVjqxZbHrXStS/Nmw==
-
-timsort@^0.3.0:
- version "0.3.0"
- resolved "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz"
- integrity sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=
-
-tiny-lr@0.1.4:
- version "0.1.4"
- resolved "https://registry.npmjs.org/tiny-lr/-/tiny-lr-0.1.4.tgz"
- integrity sha1-bkHX5n39CHjl4LN+N6BtZ+MJ/00=
- dependencies:
- body-parser "~1.8.0"
- debug "~0.8.1"
- faye-websocket "~0.7.2"
- parseurl "~1.3.0"
- qs "~2.2.3"
-
-tinycolor2@^1.4.1:
- version "1.4.1"
- resolved "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.4.1.tgz"
- integrity sha1-9PrTM0R7wLB9TcjpIJ2POaisd+g=
-
-tmp@^0.0.33:
- version "0.0.33"
- resolved "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz"
- integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==
- dependencies:
- os-tmpdir "~1.0.2"
-
-to-absolute-glob@^2.0.0:
- version "2.0.2"
- resolved "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz"
- integrity sha1-GGX0PZ50sIItufFFt4z/fQ98hJs=
- dependencies:
- is-absolute "^1.0.0"
- is-negated-glob "^1.0.0"
-
-to-array@0.1.4:
- version "0.1.4"
- resolved "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz"
- integrity sha1-F+bBH3PdTz10zaek/zI46a2b+JA=
-
-to-arraybuffer@^1.0.0:
- version "1.0.1"
- resolved "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz"
- integrity sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=
-
-to-buffer@^1.1.1:
- version "1.1.1"
- resolved "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz"
- integrity sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==
-
-to-fast-properties@^1.0.3:
- version "1.0.3"
- resolved "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz"
- integrity sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=
-
-to-fast-properties@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz"
- integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=
-
-to-object-path@^0.3.0:
- version "0.3.0"
- resolved "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz"
- integrity sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=
- dependencies:
- kind-of "^3.0.2"
-
-to-readable-stream@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz"
- integrity sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==
-
-to-regex-range@^2.1.0:
- version "2.1.1"
- resolved "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz"
- integrity sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=
- dependencies:
- is-number "^3.0.0"
- repeat-string "^1.6.1"
-
-to-regex-range@^5.0.1:
- version "5.0.1"
- resolved "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz"
- integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==
- dependencies:
- is-number "^7.0.0"
-
-to-regex@^3.0.1, to-regex@^3.0.2:
- version "3.0.2"
- resolved "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz"
- integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==
- dependencies:
- define-property "^2.0.2"
- extend-shallow "^3.0.2"
- regex-not "^1.0.2"
- safe-regex "^1.1.0"
-
-to-through@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/to-through/-/to-through-2.0.0.tgz"
- integrity sha1-/JKtq6ByZHvAtn1rA2ZKoZUJOvY=
- dependencies:
- through2 "^2.0.3"
-
-tobspr-osx-sign@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/tobspr-osx-sign/-/tobspr-osx-sign-1.0.1.tgz#5cca32185d813357b556a6a839305558656c45d5"
- integrity sha512-jXSw9n/ivAnHwwpImvHnTkhbeI06ZDvLKLP3rryZLBoAt1nfljoIEgdPz7vNlOUBGwVEYOl2VauViNOmZPNZ7A==
- dependencies:
- compare-version "^0.1.2"
- debug "^4.3.4"
- fs-extra "^10.0.0"
- isbinaryfile "^4.0.8"
- minimist "^1.2.6"
- plist "^3.0.5"
-
-toidentifier@1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz"
- integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==
-
-tough-cookie@^2.3.3, tough-cookie@^2.4.3:
- version "2.5.0"
- resolved "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz"
- integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==
- dependencies:
- psl "^1.1.28"
- punycode "^2.1.1"
-
-tough-cookie@~2.4.3:
- version "2.4.3"
- resolved "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz"
- integrity sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==
- dependencies:
- psl "^1.1.24"
- punycode "^1.4.1"
-
-tr46@^1.0.1:
- version "1.0.1"
- resolved "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz"
- integrity sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=
- dependencies:
- punycode "^2.1.0"
-
-trim-newlines@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz"
- integrity sha1-WIeWa7WCpFA6QetST301ARgVphM=
-
-trim-repeated@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz"
- integrity sha1-42RqLqTokTEr9+rObPsFOAvAHCE=
- dependencies:
- escape-string-regexp "^1.0.2"
-
-trim-right@^1.0.1:
- version "1.0.1"
- resolved "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz"
- integrity sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=
-
-trim@^0.0.1:
- version "0.0.1"
- resolved "https://registry.npmjs.org/trim/-/trim-0.0.1.tgz"
- integrity sha1-WFhUf2spB1fulczMZm+1AITEYN0=
-
-tslib@^1.9.0:
- version "1.10.0"
- resolved "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz"
- integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==
-
-tty-browserify@0.0.0:
- version "0.0.0"
- resolved "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz"
- integrity sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=
-
-tunnel-agent@^0.6.0:
- version "0.6.0"
- resolved "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz"
- integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=
- dependencies:
- safe-buffer "^5.0.1"
-
-tunnel@^0.0.6:
- version "0.0.6"
- resolved "https://registry.yarnpkg.com/tunnel/-/tunnel-0.0.6.tgz#72f1314b34a5b192db012324df2cc587ca47f92c"
- integrity sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==
-
-tweetnacl@^0.14.3, tweetnacl@~0.14.0:
- version "0.14.5"
- resolved "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz"
- integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=
-
-type-check@~0.3.2:
- version "0.3.2"
- resolved "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz"
- integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=
- dependencies:
- prelude-ls "~1.1.2"
-
-type-fest@^0.11.0:
- version "0.11.0"
- resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz"
- integrity sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==
-
-type-fest@^0.13.1:
- version "0.13.1"
- resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.13.1.tgz#0172cb5bce80b0bd542ea348db50c7e21834d934"
- integrity sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==
-
-type-is@~1.5.1:
- version "1.5.7"
- resolved "https://registry.npmjs.org/type-is/-/type-is-1.5.7.tgz"
- integrity sha1-uTaKWTzG730GReeLL0xky+zQXpA=
- dependencies:
- media-typer "0.3.0"
- mime-types "~2.0.9"
-
-type@^1.0.1:
- version "1.2.0"
- resolved "https://registry.npmjs.org/type/-/type-1.2.0.tgz"
- integrity sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==
-
-typedarray@^0.0.6:
- version "0.0.6"
- resolved "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz"
- integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=
-
-ua-parser-js@^0.7.18:
- version "0.7.21"
- resolved "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.21.tgz"
- integrity sha512-+O8/qh/Qj8CgC6eYBVBykMrNtp5Gebn4dlGD/kKXVkJNDwyrAwSIqwz8CDf+tsAIWVycKcku6gIXJ0qwx/ZXaQ==
-
-uglify-js@3.4.x:
- version "3.4.10"
- resolved "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.10.tgz"
- integrity sha512-Y2VsbPVs0FIshJztycsO2SfPk7/KAF/T72qzv9u5EpQ4kB2hQoHlhNQTsNyy6ul7lQtqJN/AoWeS23OzEiEFxw==
- dependencies:
- commander "~2.19.0"
- source-map "~0.6.1"
-
-uglify-template-string-loader@^1.1.0:
- version "1.1.1"
- resolved "https://registry.npmjs.org/uglify-template-string-loader/-/uglify-template-string-loader-1.1.1.tgz"
- integrity sha512-EHJx8m0aIHlwX5xlJd2xPYIFvLrPkVK5X8zpVxSNTmu7KoT2eSg1TNlwZS+JS65+dwJXC4rC5mc+F4UVe2rckw==
-
-ultron@~1.1.0:
- version "1.1.1"
- resolved "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz"
- integrity sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==
-
-unbzip2-stream@^1.0.9:
- version "1.3.3"
- resolved "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.3.3.tgz"
- integrity sha512-fUlAF7U9Ah1Q6EieQ4x4zLNejrRvDWUYmxXUpN3uziFYCHapjWFaCAnreY9bGgxzaMCFAPPpYNng57CypwJVhg==
- dependencies:
- buffer "^5.2.1"
- through "^2.3.8"
-
-unc-path-regex@^0.1.2:
- version "0.1.2"
- resolved "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz"
- integrity sha1-5z3T17DXxe2G+6xrCufYxqadUPo=
-
-underscore@~1.8.3:
- version "1.8.3"
- resolved "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz"
- integrity sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=
-
-undertaker-registry@^1.0.0:
- version "1.0.1"
- resolved "https://registry.npmjs.org/undertaker-registry/-/undertaker-registry-1.0.1.tgz"
- integrity sha1-XkvaMI5KiirlhPm5pDWaSZglzFA=
-
-undertaker@^1.2.1:
- version "1.2.1"
- resolved "https://registry.npmjs.org/undertaker/-/undertaker-1.2.1.tgz"
- integrity sha512-71WxIzDkgYk9ZS+spIB8iZXchFhAdEo2YU8xYqBYJ39DIUIqziK78ftm26eecoIY49X0J2MLhG4hr18Yp6/CMA==
- dependencies:
- arr-flatten "^1.0.1"
- arr-map "^2.0.0"
- bach "^1.0.0"
- collection-map "^1.0.0"
- es6-weak-map "^2.0.1"
- last-run "^1.1.0"
- object.defaults "^1.0.0"
- object.reduce "^1.0.0"
- undertaker-registry "^1.0.0"
-
-unicode-canonical-property-names-ecmascript@^1.0.4:
- version "1.0.4"
- resolved "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz"
- integrity sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ==
-
-unicode-match-property-ecmascript@^1.0.4:
- version "1.0.4"
- resolved "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz"
- integrity sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg==
- dependencies:
- unicode-canonical-property-names-ecmascript "^1.0.4"
- unicode-property-aliases-ecmascript "^1.0.4"
-
-unicode-match-property-value-ecmascript@^1.1.0:
- version "1.1.0"
- resolved "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.1.0.tgz"
- integrity sha512-hDTHvaBk3RmFzvSl0UVrUmC3PuW9wKVnpoUDYH0JDkSIovzw+J5viQmeYHxVSBptubnr7PbH2e0fnpDRQnQl5g==
-
-unicode-property-aliases-ecmascript@^1.0.4:
- version "1.0.5"
- resolved "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.0.5.tgz"
- integrity sha512-L5RAqCfXqAwR3RriF8pM0lU0w4Ryf/GgzONwi6KnL1taJQa7x1TCxdJnILX59WIGOwR57IVxn7Nej0fz1Ny6fw==
-
-union-value@^1.0.0:
- version "1.0.1"
- resolved "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz"
- integrity sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==
- dependencies:
- arr-union "^3.1.0"
- get-value "^2.0.6"
- is-extendable "^0.1.1"
- set-value "^2.0.1"
-
-uniq@^1.0.1:
- version "1.0.1"
- resolved "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz"
- integrity sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=
-
-uniqs@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/uniqs/-/uniqs-2.0.0.tgz"
- integrity sha1-/+3ks2slKQaW5uFl1KWe25mOawI=
-
-unique-filename@^1.1.1:
- version "1.1.1"
- resolved "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz"
- integrity sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==
- dependencies:
- unique-slug "^2.0.0"
-
-unique-slug@^2.0.0:
- version "2.0.2"
- resolved "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz"
- integrity sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==
- dependencies:
- imurmurhash "^0.1.4"
-
-unique-stream@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/unique-stream/-/unique-stream-1.0.0.tgz"
- integrity sha1-1ZpKdUJ0R9mqbJHnAmP40mpLEEs=
-
-unique-stream@^2.0.2:
- version "2.3.1"
- resolved "https://registry.npmjs.org/unique-stream/-/unique-stream-2.3.1.tgz"
- integrity sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A==
- dependencies:
- json-stable-stringify-without-jsonify "^1.0.1"
- through2-filter "^3.0.0"
-
-universalify@^0.1.0:
- version "0.1.2"
- resolved "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz"
- integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==
-
-universalify@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717"
- integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==
-
-unpipe@1.0.0, unpipe@~1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz"
- integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=
-
-unquote@~1.1.1:
- version "1.1.1"
- resolved "https://registry.npmjs.org/unquote/-/unquote-1.1.1.tgz"
- integrity sha1-j97XMk7G6IoP+LkF58CYzcCG1UQ=
-
-unset-value@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz"
- integrity sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=
- dependencies:
- has-value "^0.3.1"
- isobject "^3.0.0"
-
-unused-files-webpack-plugin@^3.4.0:
- version "3.4.0"
- resolved "https://registry.npmjs.org/unused-files-webpack-plugin/-/unused-files-webpack-plugin-3.4.0.tgz"
- integrity sha512-cmukKOBdIqaM1pqThY0+jp+mYgCVyzrD8uRbKEucQwIGZcLIRn+gSRiQ7uLjcDd3Zba9NUxVGyYa7lWM4UCGeg==
- dependencies:
- babel-runtime "^7.0.0-beta.3"
- glob-all "^3.1.0"
- semver "^5.5.0"
- util.promisify "^1.0.0"
- warning "^3.0.0"
-
-upath@^1.1.1:
- version "1.2.0"
- resolved "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz"
- integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==
-
-upper-case@^1.1.1:
- version "1.1.3"
- resolved "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz"
- integrity sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg=
-
-uri-js@^4.2.2:
- version "4.2.2"
- resolved "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz"
- integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==
- dependencies:
- punycode "^2.1.0"
-
-urix@^0.1.0:
- version "0.1.0"
- resolved "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz"
- integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=
-
-url-parse-lax@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz"
- integrity sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=
- dependencies:
- prepend-http "^1.0.1"
-
-url-parse-lax@^3.0.0:
- version "3.0.0"
- resolved "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz"
- integrity sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=
- dependencies:
- prepend-http "^2.0.0"
-
-url-to-options@^1.0.1:
- version "1.0.1"
- resolved "https://registry.npmjs.org/url-to-options/-/url-to-options-1.0.1.tgz"
- integrity sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k=
-
-url@^0.11.0:
- version "0.11.0"
- resolved "https://registry.npmjs.org/url/-/url-0.11.0.tgz"
- integrity sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=
- dependencies:
- punycode "1.3.2"
- querystring "0.2.0"
-
-use@^3.1.0:
- version "3.1.1"
- resolved "https://registry.npmjs.org/use/-/use-3.1.1.tgz"
- integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==
-
-user-home@^1.1.1:
- version "1.1.1"
- resolved "https://registry.npmjs.org/user-home/-/user-home-1.1.1.tgz"
- integrity sha1-K1viOjK2Onyd640PKNSFcko98ZA=
-
-user-home@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/user-home/-/user-home-2.0.0.tgz"
- integrity sha1-nHC/2Babwdy/SGBODwS4tJzenp8=
- dependencies:
- os-homedir "^1.0.0"
-
-utif@^2.0.1:
- version "2.0.1"
- resolved "https://registry.npmjs.org/utif/-/utif-2.0.1.tgz"
- integrity sha512-Z/S1fNKCicQTf375lIP9G8Sa1H/phcysstNrrSdZKj1f9g58J4NMgb5IgiEZN9/nLMPDwF0W7hdOe9Qq2IYoLg==
- dependencies:
- pako "^1.0.5"
-
-util-deprecate@^1.0.1, util-deprecate@~1.0.1:
- version "1.0.2"
- resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz"
- integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=
-
-util.promisify@^1.0.0, util.promisify@~1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.0.tgz"
- integrity sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA==
- dependencies:
- define-properties "^1.1.2"
- object.getownpropertydescriptors "^2.0.3"
-
-util@0.10.3:
- version "0.10.3"
- resolved "https://registry.npmjs.org/util/-/util-0.10.3.tgz"
- integrity sha1-evsa/lCAUkZInj23/g7TeTNqwPk=
- dependencies:
- inherits "2.0.1"
-
-util@^0.10.3:
- version "0.10.4"
- resolved "https://registry.npmjs.org/util/-/util-0.10.4.tgz"
- integrity sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==
- dependencies:
- inherits "2.0.3"
-
-util@^0.11.0:
- version "0.11.1"
- resolved "https://registry.npmjs.org/util/-/util-0.11.1.tgz"
- integrity sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==
- dependencies:
- inherits "2.0.3"
-
-utils-merge@1.0.1:
- version "1.0.1"
- resolved "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz"
- integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=
-
-uuid@^3.0.1, uuid@^3.3.2:
- version "3.3.3"
- resolved "https://registry.npmjs.org/uuid/-/uuid-3.3.3.tgz"
- integrity sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ==
-
-v8-compile-cache@2.0.3:
- version "2.0.3"
- resolved "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.0.3.tgz"
- integrity sha512-CNmdbwQMBjwr9Gsmohvm0pbL954tJrNzf6gWL3K+QMQf00PF7ERGrEiLgjuU3mKreLC2MeGhUsNV9ybTbLgd3w==
-
-v8flags@^2.0.2:
- version "2.1.1"
- resolved "https://registry.npmjs.org/v8flags/-/v8flags-2.1.1.tgz"
- integrity sha1-qrGh+jDUX4jdMhFIh1rALAtV5bQ=
- dependencies:
- user-home "^1.1.1"
-
-v8flags@^3.2.0:
- version "3.2.0"
- resolved "https://registry.npmjs.org/v8flags/-/v8flags-3.2.0.tgz"
- integrity sha512-mH8etigqMfiGWdeXpaaqGfs6BndypxusHHcv2qSHyZkGEznCd/qAXCWWRzeowtL54147cktFOC4P5y+kl8d8Jg==
- dependencies:
- homedir-polyfill "^1.0.1"
-
-validate-npm-package-license@^3.0.1:
- version "3.0.4"
- resolved "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz"
- integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==
- dependencies:
- spdx-correct "^3.0.0"
- spdx-expression-parse "^3.0.0"
-
-value-or-function@^3.0.0:
- version "3.0.0"
- resolved "https://registry.npmjs.org/value-or-function/-/value-or-function-3.0.0.tgz"
- integrity sha1-HCQ6ULWVwb5Up1S/7OhWO5/42BM=
-
-vendors@^1.0.0:
- version "1.0.3"
- resolved "https://registry.npmjs.org/vendors/-/vendors-1.0.3.tgz"
- integrity sha512-fOi47nsJP5Wqefa43kyWSg80qF+Q3XA6MUkgi7Hp1HQaKDQW4cQrK2D0P7mmbFtsV1N89am55Yru/nyEwRubcw==
-
-verror@1.10.0:
- version "1.10.0"
- resolved "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz"
- integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=
- dependencies:
- assert-plus "^1.0.0"
- core-util-is "1.0.2"
- extsprintf "^1.2.0"
-
-vinyl-buffer@0.0.0:
- version "0.0.0"
- resolved "https://registry.npmjs.org/vinyl-buffer/-/vinyl-buffer-0.0.0.tgz"
- integrity sha1-0ZeoJLrcsRzM+WQ6yRviTUPtqNs=
- dependencies:
- bl "^0.7.0"
- through2 "^0.4.1"
-
-vinyl-fs@^0.3.0:
- version "0.3.14"
- resolved "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-0.3.14.tgz"
- integrity sha1-mmhRzhysHBzqX+hsCTHWIMLPqeY=
- dependencies:
- defaults "^1.0.0"
- glob-stream "^3.1.5"
- glob-watcher "^0.0.6"
- graceful-fs "^3.0.0"
- mkdirp "^0.5.0"
- strip-bom "^1.0.0"
- through2 "^0.6.1"
- vinyl "^0.4.0"
-
-vinyl-fs@^3.0.0:
- version "3.0.3"
- resolved "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-3.0.3.tgz"
- integrity sha512-vIu34EkyNyJxmP0jscNzWBSygh7VWhqun6RmqVfXePrOwi9lhvRs//dOaGOTRUQr4tx7/zd26Tk5WeSVZitgng==
- dependencies:
- fs-mkdirp-stream "^1.0.0"
- glob-stream "^6.1.0"
- graceful-fs "^4.0.0"
- is-valid-glob "^1.0.0"
- lazystream "^1.0.0"
- lead "^1.0.0"
- object.assign "^4.0.4"
- pumpify "^1.3.5"
- readable-stream "^2.3.3"
- remove-bom-buffer "^3.0.0"
- remove-bom-stream "^1.2.0"
- resolve-options "^1.1.0"
- through2 "^2.0.0"
- to-through "^2.0.0"
- value-or-function "^3.0.0"
- vinyl "^2.0.0"
- vinyl-sourcemap "^1.1.0"
-
-vinyl-source-stream@^0.1.1:
- version "0.1.1"
- resolved "https://registry.npmjs.org/vinyl-source-stream/-/vinyl-source-stream-0.1.1.tgz"
- integrity sha1-pTpPIaB6I0aV4EwnA/nxtbkIRZU=
- dependencies:
- through2 "~0.3.0"
- vinyl "~0.2.2"
-
-vinyl-sourcemap@^1.1.0:
- version "1.1.0"
- resolved "https://registry.npmjs.org/vinyl-sourcemap/-/vinyl-sourcemap-1.1.0.tgz"
- integrity sha1-kqgAWTo4cDqM2xHYswCtS+Y7PhY=
- dependencies:
- append-buffer "^1.0.2"
- convert-source-map "^1.5.0"
- graceful-fs "^4.1.6"
- normalize-path "^2.1.1"
- now-and-later "^2.0.0"
- remove-bom-buffer "^3.0.0"
- vinyl "^2.0.0"
-
-vinyl-sourcemaps-apply@^0.2.0, vinyl-sourcemaps-apply@^0.2.1:
- version "0.2.1"
- resolved "https://registry.npmjs.org/vinyl-sourcemaps-apply/-/vinyl-sourcemaps-apply-0.2.1.tgz"
- integrity sha1-q2VJ1h0XLCsbh75cUI0jnI74dwU=
- dependencies:
- source-map "^0.5.1"
-
-vinyl@*, vinyl@^2.0.0, vinyl@^2.1.0, vinyl@^2.2.0:
- version "2.2.0"
- resolved "https://registry.npmjs.org/vinyl/-/vinyl-2.2.0.tgz"
- integrity sha512-MBH+yP0kC/GQ5GwBqrTPTzEfiiLjta7hTtvQtbxBgTeSXsmKQRQecjibMbxIXzVT3Y9KJK+drOz1/k+vsu8Nkg==
- dependencies:
- clone "^2.1.1"
- clone-buffer "^1.0.0"
- clone-stats "^1.0.0"
- cloneable-readable "^1.0.0"
- remove-trailing-separator "^1.0.1"
- replace-ext "^1.0.0"
-
-vinyl@^0.2.1, vinyl@~0.2.2:
- version "0.2.3"
- resolved "https://registry.npmjs.org/vinyl/-/vinyl-0.2.3.tgz"
- integrity sha1-vKk4IJWC7FpJrVOKAPofEl5RMlI=
- dependencies:
- clone-stats "~0.0.1"
-
-vinyl@^0.4.0:
- version "0.4.6"
- resolved "https://registry.npmjs.org/vinyl/-/vinyl-0.4.6.tgz"
- integrity sha1-LzVsh6VQolVGHza76ypbqL94SEc=
- dependencies:
- clone "^0.2.0"
- clone-stats "^0.0.1"
-
-vinyl@^0.5.0:
- version "0.5.3"
- resolved "https://registry.npmjs.org/vinyl/-/vinyl-0.5.3.tgz"
- integrity sha1-sEVbOPxeDPMNQyUTLkYZcMIJHN4=
- dependencies:
- clone "^1.0.0"
- clone-stats "^0.0.1"
- replace-ext "0.0.1"
-
-vm-browserify@^1.0.1:
- version "1.1.0"
- resolved "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.0.tgz"
- integrity sha512-iq+S7vZJE60yejDYM0ek6zg308+UZsdtPExWP9VZoCFCz1zkJoXFnAX7aZfd/ZwrkidzdUZL0C/ryW+JwAiIGw==
-
-w3c-hr-time@^1.0.1:
- version "1.0.1"
- resolved "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz"
- integrity sha1-gqwr/2PZUOqeMYmlimViX+3xkEU=
- dependencies:
- browser-process-hrtime "^0.1.2"
-
-warning@^3.0.0:
- version "3.0.0"
- resolved "https://registry.npmjs.org/warning/-/warning-3.0.0.tgz"
- integrity sha1-MuU3fLVy3kqwR1O9+IIcAe1gW3w=
- dependencies:
- loose-envify "^1.0.0"
-
-watch@^0.11.0:
- version "0.11.0"
- resolved "https://registry.npmjs.org/watch/-/watch-0.11.0.tgz"
- integrity sha1-6NugkbdFZ5mjr1eXi5hud+EyBAY=
-
-watchpack-chokidar2@^2.0.0:
- version "2.0.1"
- resolved "https://registry.yarnpkg.com/watchpack-chokidar2/-/watchpack-chokidar2-2.0.1.tgz#38500072ee6ece66f3769936950ea1771be1c957"
- integrity sha512-nCFfBIPKr5Sh61s4LPpy1Wtfi0HE8isJ3d2Yb5/Ppw2P2B/3eVSEBjKfN0fmHJSK14+31KwMKmcrzs2GM4P0Ww==
- dependencies:
- chokidar "^2.1.8"
-
-watchpack@^1.6.1:
- version "1.7.2"
- resolved "https://registry.npmjs.org/watchpack/-/watchpack-1.7.2.tgz"
- integrity sha512-ymVbbQP40MFTp+cNMvpyBpBtygHnPzPkHqoIwRRj/0B8KhqQwV8LaKjtbaxF2lK4vl8zN9wCxS46IFCU5K4W0g==
- dependencies:
- graceful-fs "^4.1.2"
- neo-async "^2.5.0"
- optionalDependencies:
- chokidar "^3.4.0"
- watchpack-chokidar2 "^2.0.0"
-
-webidl-conversions@^4.0.2:
- version "4.0.2"
- resolved "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz"
- integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==
-
-webpack-cli@^3.1.0:
- version "3.3.9"
- resolved "https://registry.npmjs.org/webpack-cli/-/webpack-cli-3.3.9.tgz"
- integrity sha512-xwnSxWl8nZtBl/AFJCOn9pG7s5CYUYdZxmmukv+fAHLcBIHM36dImfpQg3WfShZXeArkWlf6QRw24Klcsv8a5A==
- dependencies:
- chalk "2.4.2"
- cross-spawn "6.0.5"
- enhanced-resolve "4.1.0"
- findup-sync "3.0.0"
- global-modules "2.0.0"
- import-local "2.0.0"
- interpret "1.2.0"
- loader-utils "1.2.3"
- supports-color "6.1.0"
- v8-compile-cache "2.0.3"
- yargs "13.2.4"
-
-webpack-deep-scope-plugin@^1.6.0:
- version "1.6.2"
- resolved "https://registry.npmjs.org/webpack-deep-scope-plugin/-/webpack-deep-scope-plugin-1.6.2.tgz"
- integrity sha512-S5ZM1i7oTIVPIS1z/Fu41tqFzaXpy8vZnwEDC9I7NLj5XD8GGrDZbDXtG5FCGkHPGxtAzF4O21DKZZ76vpBGzw==
- dependencies:
- deep-scope-analyser "^1.7.0"
-
-webpack-plugin-replace@^1.1.1:
- version "1.2.0"
- resolved "https://registry.npmjs.org/webpack-plugin-replace/-/webpack-plugin-replace-1.2.0.tgz"
- integrity sha512-1HA3etHpJW55qonJqv84o5w5GY7iqF8fqSHpTWdNwarj1llkkt4jT4QSvYs1hoaU8Lu5akDnq/spHHO5mXwo1w==
-
-webpack-sources@^1.4.0, webpack-sources@^1.4.1:
- version "1.4.3"
- resolved "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz"
- integrity sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==
- dependencies:
- source-list-map "^2.0.0"
- source-map "~0.6.1"
-
-webpack-stream@^5.2.1:
- version "5.2.1"
- resolved "https://registry.npmjs.org/webpack-stream/-/webpack-stream-5.2.1.tgz"
- integrity sha512-WvyVU0K1/VB1NZ7JfsaemVdG0PXAQUqbjUNW4A58th4pULvKMQxG+y33HXTL02JvD56ko2Cub+E2NyPwrLBT/A==
- dependencies:
- fancy-log "^1.3.3"
- lodash.clone "^4.3.2"
- lodash.some "^4.2.2"
- memory-fs "^0.4.1"
- plugin-error "^1.0.1"
- supports-color "^5.5.0"
- through "^2.3.8"
- vinyl "^2.1.0"
- webpack "^4.26.1"
-
-webpack-strip-block@^0.2.0:
- version "0.2.0"
- resolved "https://registry.npmjs.org/webpack-strip-block/-/webpack-strip-block-0.2.0.tgz"
- integrity sha1-xg1KcD4O7uiJXn8avptf6RRoFHA=
- dependencies:
- loader-utils "^1.1.0"
-
-webpack@^4.26.1, webpack@^4.43.0:
- version "4.43.0"
- resolved "https://registry.npmjs.org/webpack/-/webpack-4.43.0.tgz"
- integrity sha512-GW1LjnPipFW2Y78OOab8NJlCflB7EFskMih2AHdvjbpKMeDJqEgSx24cXXXiPS65+WSwVyxtDsJH6jGX2czy+g==
- dependencies:
- "@webassemblyjs/ast" "1.9.0"
- "@webassemblyjs/helper-module-context" "1.9.0"
- "@webassemblyjs/wasm-edit" "1.9.0"
- "@webassemblyjs/wasm-parser" "1.9.0"
- acorn "^6.4.1"
- ajv "^6.10.2"
- ajv-keywords "^3.4.1"
- chrome-trace-event "^1.0.2"
- enhanced-resolve "^4.1.0"
- eslint-scope "^4.0.3"
- json-parse-better-errors "^1.0.2"
- loader-runner "^2.4.0"
- loader-utils "^1.2.3"
- memory-fs "^0.4.1"
- micromatch "^3.1.10"
- mkdirp "^0.5.3"
- neo-async "^2.6.1"
- node-libs-browser "^2.2.1"
- schema-utils "^1.0.0"
- tapable "^1.1.3"
- terser-webpack-plugin "^1.4.3"
- watchpack "^1.6.1"
- webpack-sources "^1.4.1"
-
-websocket-driver@>=0.3.6:
- version "0.7.3"
- resolved "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.3.tgz"
- integrity sha512-bpxWlvbbB459Mlipc5GBzzZwhoZgGEZLuqPaR0INBGnPAY1vdBX6hPnoFXiw+3yWxDuHyQjO2oXTMyS8A5haFg==
- dependencies:
- http-parser-js ">=0.4.0 <0.4.11"
- safe-buffer ">=5.1.0"
- websocket-extensions ">=0.1.1"
-
-websocket-extensions@>=0.1.1:
- version "0.1.3"
- resolved "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.3.tgz"
- integrity sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==
-
-whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.5:
- version "1.0.5"
- resolved "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz"
- integrity sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==
- dependencies:
- iconv-lite "0.4.24"
-
-whatwg-fetch@^3.0.0:
- version "3.0.0"
- resolved "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz"
- integrity sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q==
-
-whatwg-mimetype@^2.2.0:
- version "2.3.0"
- resolved "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz"
- integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==
-
-whatwg-url@^7.0.0:
- version "7.0.0"
- resolved "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.0.0.tgz"
- integrity sha512-37GeVSIJ3kn1JgKyjiYNmSLP1yzbpb29jdmwBSgkD9h40/hyrR/OifpVUndji3tmwGgD8qpw7iQu3RSbCrBpsQ==
- dependencies:
- lodash.sortby "^4.7.0"
- tr46 "^1.0.1"
- webidl-conversions "^4.0.2"
-
-which-module@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz"
- integrity sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=
-
-which-module@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz"
- integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=
-
-which@^1.1.1, which@^1.2.14, which@^1.2.9, which@^1.3.1:
- version "1.3.1"
- resolved "https://registry.npmjs.org/which/-/which-1.3.1.tgz"
- integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==
- dependencies:
- isexe "^2.0.0"
-
-which@^2.0.1, which@^2.0.2:
- version "2.0.2"
- resolved "https://registry.npmjs.org/which/-/which-2.0.2.tgz"
- integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==
- dependencies:
- isexe "^2.0.0"
-
-winston@~1.0.0:
- version "1.0.2"
- resolved "https://registry.npmjs.org/winston/-/winston-1.0.2.tgz"
- integrity sha1-NRxY4jI/ikyimkUZWqmqO0w1128=
- dependencies:
- async "~1.0.0"
- colors "1.0.x"
- cycle "1.0.x"
- eyes "0.1.x"
- isstream "0.1.x"
- pkginfo "0.3.x"
- stack-trace "0.0.x"
-
-wordwrap@~0.0.2:
- version "0.0.3"
- resolved "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz"
- integrity sha1-o9XabNXAvAAI03I0u68b7WMFkQc=
-
-wordwrap@~1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz"
- integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=
-
-worker-farm@^1.7.0:
- version "1.7.0"
- resolved "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz"
- integrity sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==
- dependencies:
- errno "~0.1.7"
-
-worker-loader@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/worker-loader/-/worker-loader-2.0.0.tgz"
- integrity sha512-tnvNp4K3KQOpfRnD20m8xltE3eWh89Ye+5oj7wXEEHKac1P4oZ6p9oTj8/8ExqoSBnk9nu5Pr4nKfQ1hn2APJw==
- dependencies:
- loader-utils "^1.0.0"
- schema-utils "^0.4.0"
-
-wrap-ansi@^2.0.0:
- version "2.1.0"
- resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz"
- integrity sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=
- dependencies:
- string-width "^1.0.1"
- strip-ansi "^3.0.1"
-
-wrap-ansi@^5.1.0:
- version "5.1.0"
- resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz"
- integrity sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==
- dependencies:
- ansi-styles "^3.2.0"
- string-width "^3.0.0"
- strip-ansi "^5.0.0"
-
-wrap-ansi@^6.2.0:
- version "6.2.0"
- resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz"
- integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==
- dependencies:
- ansi-styles "^4.0.0"
- string-width "^4.1.0"
- strip-ansi "^6.0.0"
-
-wrappy@1:
- version "1.0.2"
- resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz"
- integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
-
-write@1.0.3:
- version "1.0.3"
- resolved "https://registry.npmjs.org/write/-/write-1.0.3.tgz"
- integrity sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==
- dependencies:
- mkdirp "^0.5.1"
-
-write@^0.2.1:
- version "0.2.1"
- resolved "https://registry.npmjs.org/write/-/write-0.2.1.tgz"
- integrity sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=
- dependencies:
- mkdirp "^0.5.1"
-
-ws@^6.1.0:
- version "6.2.1"
- resolved "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz"
- integrity sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==
- dependencies:
- async-limiter "~1.0.0"
-
-ws@~3.3.1:
- version "3.3.3"
- resolved "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz"
- integrity sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==
- dependencies:
- async-limiter "~1.0.0"
- safe-buffer "~5.1.0"
- ultron "~1.1.0"
-
-ws@~6.1.0:
- version "6.1.4"
- resolved "https://registry.npmjs.org/ws/-/ws-6.1.4.tgz"
- integrity sha512-eqZfL+NE/YQc1/ZynhojeV8q+H050oR8AZ2uIev7RU10svA9ZnJUddHcOUZTJLinZ9yEfdA2kSATS2qZK5fhJA==
- dependencies:
- async-limiter "~1.0.0"
-
-xhr@^2.0.1:
- version "2.5.0"
- resolved "https://registry.npmjs.org/xhr/-/xhr-2.5.0.tgz"
- integrity sha512-4nlO/14t3BNUZRXIXfXe+3N6w3s1KoxcJUUURctd64BLRe67E4gRwp4PjywtDY72fXpZ1y6Ch0VZQRY/gMPzzQ==
- dependencies:
- global "~4.3.0"
- is-function "^1.0.1"
- parse-headers "^2.0.0"
- xtend "^4.0.0"
-
-xml-name-validator@^3.0.0:
- version "3.0.0"
- resolved "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz"
- integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==
-
-xml-parse-from-string@^1.0.0:
- version "1.0.1"
- resolved "https://registry.npmjs.org/xml-parse-from-string/-/xml-parse-from-string-1.0.1.tgz"
- integrity sha1-qQKekp09vN7RafPG4oI42VpdWig=
-
-xml2js@^0.4.5:
- version "0.4.22"
- resolved "https://registry.npmjs.org/xml2js/-/xml2js-0.4.22.tgz"
- integrity sha512-MWTbxAQqclRSTnehWWe5nMKzI3VmJ8ltiJEco8akcC6j3miOhjjfzKum5sId+CWhfxdOs/1xauYr8/ZDBtQiRw==
- dependencies:
- sax ">=0.6.0"
- util.promisify "~1.0.0"
- xmlbuilder "~11.0.0"
-
-xmlbuilder@^9.0.7:
- version "9.0.7"
- resolved "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz"
- integrity sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=
-
-xmlbuilder@~11.0.0:
- version "11.0.1"
- resolved "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz"
- integrity sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==
-
-xmlchars@^2.1.1:
- version "2.2.0"
- resolved "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz"
- integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==
-
-xmldom@0.1.x:
- version "0.1.27"
- resolved "https://registry.npmjs.org/xmldom/-/xmldom-0.1.27.tgz"
- integrity sha1-1QH5ezvbQDr4757MIFcxh6rawOk=
-
-xmlhttprequest-ssl@~1.5.4:
- version "1.5.5"
- resolved "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz"
- integrity sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4=
-
-"xtend@>=4.0.0 <4.1.0-0", xtend@^4.0.0, xtend@~4.0.0, xtend@~4.0.1:
- version "4.0.2"
- resolved "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz"
- integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==
-
-xtend@~2.1.1:
- version "2.1.2"
- resolved "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz"
- integrity sha1-bv7MKk2tjmlixJAbM3znuoe10os=
- dependencies:
- object-keys "~0.4.0"
-
-xtend@~3.0.0:
- version "3.0.0"
- resolved "https://registry.npmjs.org/xtend/-/xtend-3.0.0.tgz"
- integrity sha1-XM50B7r2Qsunvs2laBEcST9ZZlo=
-
-y18n@^3.2.1:
- version "3.2.1"
- resolved "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz"
- integrity sha1-bRX7qITAhnnA136I53WegR4H+kE=
-
-y18n@^4.0.0:
- version "4.0.0"
- resolved "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz"
- integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==
-
-yallist@^2.1.2:
- version "2.1.2"
- resolved "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz"
- integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=
-
-yallist@^3.0.2:
- version "3.0.3"
- resolved "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz"
- integrity sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==
-
-yallist@^4.0.0:
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"
- integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
-
-yaml-loader@^0.6.0:
- version "0.6.0"
- resolved "https://registry.npmjs.org/yaml-loader/-/yaml-loader-0.6.0.tgz"
- integrity sha512-1bNiLelumURyj+zvVHOv8Y3dpCri0F2S+DCcmps0pA1zWRLjS+FhZQg4o3aUUDYESh73+pKZNI18bj7stpReow==
- dependencies:
- loader-utils "^1.4.0"
- yaml "^1.8.3"
-
-yaml@^1.10.0, yaml@^1.8.3:
- version "1.10.0"
- resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.0.tgz#3b593add944876077d4d683fee01081bd9fff31e"
- integrity sha512-yr2icI4glYaNG+KWONODapy2/jDdMSDnrONSjblABjD9B4Z5LgiircSt8m8sRZFNi08kG9Sm0uSHtEmP3zaEGg==
-
-yargs-parser@5.0.0-security.0:
- version "5.0.0-security.0"
- resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0-security.0.tgz"
- integrity sha512-T69y4Ps64LNesYxeYGYPvfoMTt/7y1XtfpIslUeK4um+9Hu7hlGoRtaDLvdXb7+/tfq4opVa2HRY5xGip022rQ==
- dependencies:
- camelcase "^3.0.0"
- object.assign "^4.1.0"
-
-yargs-parser@^13.1.0, yargs-parser@^13.1.1:
- version "13.1.1"
- resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz"
- integrity sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==
- dependencies:
- camelcase "^5.0.0"
- decamelize "^1.2.0"
-
-yargs-parser@^18.1.2:
- version "18.1.3"
- resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz"
- integrity sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==
- dependencies:
- camelcase "^5.0.0"
- decamelize "^1.2.0"
-
-yargs-parser@^20.0.0:
- version "20.2.9"
- resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee"
- integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==
-
-yargs@13.2.4:
- version "13.2.4"
- resolved "https://registry.npmjs.org/yargs/-/yargs-13.2.4.tgz"
- integrity sha512-HG/DWAJa1PAnHT9JAhNa8AbAv3FPaiLzioSjCcmuXXhP8MlpHO5vwls4g4j6n30Z74GVQj8Xa62dWVx1QCGklg==
- dependencies:
- cliui "^5.0.0"
- find-up "^3.0.0"
- get-caller-file "^2.0.1"
- os-locale "^3.1.0"
- require-directory "^2.1.1"
- require-main-filename "^2.0.0"
- set-blocking "^2.0.0"
- string-width "^3.0.0"
- which-module "^2.0.0"
- y18n "^4.0.0"
- yargs-parser "^13.1.0"
-
-yargs@13.3.0:
- version "13.3.0"
- resolved "https://registry.npmjs.org/yargs/-/yargs-13.3.0.tgz"
- integrity sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA==
- dependencies:
- cliui "^5.0.0"
- find-up "^3.0.0"
- get-caller-file "^2.0.1"
- require-directory "^2.1.1"
- require-main-filename "^2.0.0"
- set-blocking "^2.0.0"
- string-width "^3.0.0"
- which-module "^2.0.0"
- y18n "^4.0.0"
- yargs-parser "^13.1.1"
-
-yargs@^15.4.1:
- version "15.4.1"
- resolved "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz"
- integrity sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==
- dependencies:
- cliui "^6.0.0"
- decamelize "^1.2.0"
- find-up "^4.1.0"
- get-caller-file "^2.0.1"
- require-directory "^2.1.1"
- require-main-filename "^2.0.0"
- set-blocking "^2.0.0"
- string-width "^4.2.0"
- which-module "^2.0.0"
- y18n "^4.0.0"
- yargs-parser "^18.1.2"
-
-yargs@^7.1.0:
- version "7.1.1"
- resolved "https://registry.npmjs.org/yargs/-/yargs-7.1.1.tgz"
- integrity sha512-huO4Fr1f9PmiJJdll5kwoS2e4GqzGSsMT3PPMpOwoVkOK8ckqAewMTZyA6LXVQWflleb/Z8oPBEvNsMft0XE+g==
- dependencies:
- camelcase "^3.0.0"
- cliui "^3.2.0"
- decamelize "^1.1.1"
- get-caller-file "^1.0.1"
- os-locale "^1.4.0"
- read-pkg-up "^1.0.1"
- require-directory "^2.1.1"
- require-main-filename "^1.0.1"
- set-blocking "^2.0.0"
- string-width "^1.0.2"
- which-module "^1.0.0"
- y18n "^3.2.1"
- yargs-parser "5.0.0-security.0"
-
-yargs@~1.2.6:
- version "1.2.6"
- resolved "https://registry.npmjs.org/yargs/-/yargs-1.2.6.tgz"
- integrity sha1-nHtKgv1dWVsr8Xq23MQxNUMv40s=
- dependencies:
- minimist "^0.1.0"
-
-yauzl@^2.10.0, yauzl@^2.4.2:
- version "2.10.0"
- resolved "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz"
- integrity sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=
- dependencies:
- buffer-crc32 "~0.2.3"
- fd-slicer "~1.1.0"
-
-yeast@0.1.2:
- version "0.1.2"
- resolved "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz"
- integrity sha1-AI4G2AlDIMNy28L47XagymyKxBk=
-
-zip-stream@~0.4.0:
- version "0.4.1"
- resolved "https://registry.npmjs.org/zip-stream/-/zip-stream-0.4.1.tgz"
- integrity sha1-TqeVqM4Z6fq0mjHR0IdyFBWfA6M=
- dependencies:
- compress-commons "~0.1.0"
- lodash "~2.4.1"
- readable-stream "~1.0.26"
diff --git a/mod_examples/README.md b/mod_examples/README.md
deleted file mode 100644
index 5086bbdb..00000000
--- a/mod_examples/README.md
+++ /dev/null
@@ -1,58 +0,0 @@
-# shapez.io Modding
-
-## General Instructions
-
-Currently there are two options to develop mods for shapez.io:
-
-1. Writing single file mods, which doesn't require any additional tools and can be loaded directly in the game
-2. Using the [create-shapezio-mod](https://www.npmjs.com/package/create-shapezio-mod) package. This package is still in development but allows you to pack multiple files and images into a single mod file, so you don't have to base64 encode your images etc.
-
-## Mod Developer Discord
-
-A great place to get help with mod development is the official [shapez.io modloader discord](https://discord.gg/xq5v8uyMue).
-
-## Setting up your development environment
-
-The simplest way of developing mods is by just creating a `mymod.js` file and putting it in the `mods/` folder of the standalone (You can find the `mods/` folder by clicking "Open Mods Folder" in the shapez Standalone, be sure to select the 1.5.0-modloader branch on Steam).
-
-You can then add `--dev` to the launch options on Steam. This adds an application menu where you can click "Restart" to reload your mod, and will also show the developer console where you can see any potential errors.
-
-## Getting started
-
-To get into shapez.io modding, I highly recommend checking out all of the examples in this folder. Here's a list of examples and what features of the modloader they show:
-
-| Example | Description | Demonstrates |
-| ---------------------------------------------------------- | ------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- |
-| [base.js](base.js) | The most basic mod | Base structure of a mod |
-| [class_extensions.js](class_extensions.js) | Shows how to extend multiple methods of one class at once, useful for overriding a lot of methods | Overriding and extending builtin methods |
-| [custom_css.js](custom_css.js) | Modifies the Main Menu State look | Modifying the UI styles with CSS |
-| [replace_builtin_sprites.js](replace_builtin_sprites.js) | Replaces all color sprites with icons | Replacing builtin sprites |
-| [translations.js](translations.js) | Shows how to replace and add new translations in multiple languages | Adding and replacing translations |
-| [add_building_basic.js](add_building_basic.js) | Shows how to add a new building | Registering a new building |
-| [add_building_flipper.js](add_building_flipper.js) | Adds a "flipper" building which mirrors shapes from top to bottom | Registering a new building, Adding a custom shape and item processing operation (flip) |
-| [custom_drawing.js](custom_drawing.js) | Displays a a small indicator on every item processing building whether it is currently working | Adding a new GameSystem and drawing overlays |
-| [custom_keybinding.js](custom_keybinding.js) | Adds a new customizable ingame keybinding (Shift+F) | Adding a new keybinding |
-| [custom_sub_shapes.js](custom_sub_shapes.js) | Adds a new type of sub-shape (Line) | Adding a new sub shape and drawing it, making it spawn on the map, modifying the builtin levels |
-| [modify_theme.js](modify_theme.js) | Modifies the default game themes | Modifying the builtin themes |
-| [custom_theme.js](custom_theme.js) | Adds a new UI and map theme | Adding a new game theme |
-| [mod_settings.js](mod_settings.js) | Shows a dialog counting how often the mod has been launched | Reading and storing mod settings |
-| [storing_data_in_savegame.js](storing_data_in_savegame.js) | Shows how to store custom (structured) data in the savegame | Storing custom data in savegame |
-| [modify_existing_building.js](modify_existing_building.js) | Makes the rotator building always unlocked and adds a new statistic to the building panel | Modifying a builtin building, replacing builtin methods |
-| [modify_ui.js](modify_ui.js) | Shows how to add custom UI elements to builtin game states (the Main Menu in this case) | Extending builtin UI states, Adding CSS |
-| [pasting.js](pasting.js) | Shows a dialog when pasting text in the game | Listening to paste events |
-| [smooth_zooming.js](smooth_zooming.js) | Allows to smoothly zoom in and out | Keybindings, overriding methods |
-| [sandbox.js](sandbox.js) | Makes blueprints free and always unlocked | Overriding builtin methods |
-
-### Advanced Examples
-
-| Example | Description | Demonstrates |
-| ------------------------------------------------ | ---------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| [notification_blocks.js](notification_blocks.js) | Adds a notification block building, which shows a user defined notification when receiving a truthy signal | Adding a new Component, Adding a new GameSystem, Working with wire networks, Adding a new building, Adding a new HUD part, Using Input Dialogs, Adding Translations |
-| [usage_statistics.js](usage_statistics.js) | Displays a percentage on every building showing its utilization | Adding a new component, Adding a new GameSystem, Drawing within a GameSystem, Modifying builtin buildings, Adding custom game logic |
-| [new_item_type.js](new_item_type.js) | Adds a new type of items to the map (fluids) | Adding a new item type, modifying map generation |
-| [buildings_have_cost.js](buildings_have_cost.js) | Adds a new currency, and belts cost 1 of that currency | Extending and replacing builtin methods, Adding CSS and custom sprites |
-| [mirrored_cutter.js](mirrored_cutter.js) | Adds a mirrored variant of the cutter | Adding a new variant to existing buildings |
-
-### Creating new sprites
-
-If you want to add new buildings and create sprites for them, you can download the original Photoshop PSD files here: https://static.shapez.io/building-psds.zip
diff --git a/mod_examples/add_building_basic.js b/mod_examples/add_building_basic.js
deleted file mode 100644
index 6b92e769..00000000
--- a/mod_examples/add_building_basic.js
+++ /dev/null
@@ -1,67 +0,0 @@
-// @ts-nocheck
-const METADATA = {
- website: "https://tobspr.io",
- author: "tobspr",
- name: "Mod Example: Add new basic building",
- version: "1",
- id: "add-building-basic",
- description: "Shows how to add a new basic building",
- minimumGameVersion: ">=1.5.0",
-};
-
-class MetaDemoModBuilding extends shapez.ModMetaBuilding {
- constructor() {
- super("demoModBuilding");
- }
-
- static getAllVariantCombinations() {
- return [
- {
- variant: shapez.defaultBuildingVariant,
- name: "A test name",
- description: "A test building",
-
- regularImageBase64: RESOURCES["demoBuilding.png"],
- blueprintImageBase64: RESOURCES["demoBuildingBlueprint.png"],
- tutorialImageBase64: RESOURCES["demoBuildingBlueprint.png"],
- },
- ];
- }
-
- getSilhouetteColor() {
- return "red";
- }
-
- setupEntityComponents(entity) {
- // Here you can add components, for example an ItemProcessorComponent.
- // To get an idea what you can do with the builtin components, have a look
- // at the builtin buildings in
- }
-}
-
-class Mod extends shapez.Mod {
- init() {
- // Register the new building
- this.modInterface.registerNewBuilding({
- metaClass: MetaDemoModBuilding,
- buildingIconBase64: RESOURCES["demoBuilding.png"],
- });
-
- // Add it to the regular toolbar
- this.modInterface.addNewBuildingToToolbar({
- toolbar: "regular",
- location: "primary",
- metaClass: MetaDemoModBuilding,
- });
- }
-}
-
-////////////////////////////////////////////////////////////////////////
-
-const RESOURCES = {
- "demoBuilding.png":
- "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAYAAABccqhmAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAHYgAAB2IBOHqZ2wAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAABLLSURBVHic7d17sFbVecfx75FjRBAOYKKCJiKCcklEovF+CxoxJkZDp7E2jZpGHWMd0/SinXQ6NcYxSTOd2oqmGptEp60dI1FDlAgOtfGSKArxQkRBoXgFRAG5Ch76x/Oeejy823PO3mutZ+/9/j4zz6B7Zq/9vOvd+zn73Ze1QEREREREREREREREREREREREREREREREREQqoc07AQliBDAG2A/YF/gIsA+wFzAUGAZ0NP5718Y6HcAujf/eAGwDOoF1jWVrgdXAGuCNxr9rgBXAMmB5Yz2pMBWA6mgHDgQ+DkxqxDjswO9wymk1VgheBJ4Gnmr8u9wpH+knFYDyGgccAXyqEVOA3V0z6rt1WCF4Ani4Ea+6ZiRNqQCUxwTgJOAE4ERgpGs24S0HHsKKwVzgBddsBFAB8DQIOAY4AzgT2N83neReBO5vxGx0PUFawAjgfGAWsAXYoWAHsBG4C/hjYI+8nStSRnsA5wL3YVfavQ+2sscm4A7gD7GzJJHKaQNOBm7BTm29D6qqxnrgRuDw/nW/iI9hwEXAIvwPnrrFIuAK7GeUSKlMxv7ab8b/QKl7bACuw56JEHF1HHZBrxP/A6PV4t1G3x/b67ckElAbcBawAP+DQGHxEHDqB31pIkW1Yffs5+O/wyuaxyPYxVeRoKYCj+O/gyv6FvcDRzf9JkX6YSJwO/47tCJfzAIO2OlbFenFcOCfge3478SKYrG18V0OQaQXA4CLsfffvXdcRdh4GXvUWKSpyegCXyvEr4DRiDTsij1hthX/nVORJjY2vvMBSEs7EngW/x1S4ROPYiMrSYtpx/4CvIP/Tqjwjc3YvtA1PqLU3Hh0T1+xc9yLDaQqNfYV9HquIjtWAp9Hamcgdi/YewdTlD86sX2lHamFA7Hhqr13LEW1Yi7wYaTSTgRW4b8zKaoZL2F3iqSC/go9yqsoHpup8ROEdXwQYgBwA/AtdGtHimsHpmOvgz/gm4r0Zg/gl/j/1VDUM37Ce3MrSsmMBBbiv5Mo6h1z8ZuLMbi6zAw0GvtixjrnIa1hITANmxy10upQACYAc7CpsUVSWQycArzinUgRVb9Idjg2IKQOfkltPHZRcH/nPAqp8hnAYdhp/3DvRKSlrcAGIl3qnUgeVS0Ah2IDP+7pnYgINtrQ8dgU6JVSxQJwCDAPHfxSLkuBE4DXvBPpj6oVgDHYb/6R3omINPEc9vj5Su9E+qpKFwFHYr/5dfBLWR2MjStQmecEqlIAOoD7sDMAkTL7JPAzKvLEYBXeBWgH7kYzvUh1HIjdmr7bO5HeVKEAzADO9k5CpJ+mYDMY/9o7kSr7S/yf/VYo8kYnJX+VuMx3AU7BJnGowlmKSJYt2O3B+d6JNFPWAjAa6zANySR1sAJ7bL10Lw+V8S7A7sBMdPBLfXwMuI0Sns2W8QzgVmz47ljeAh4D1kfchlTPUGz8v2ERt/FdbKQqyXAecS/K/Bz7okWaGQrcRdyLgp9L9mkq5mDgbeJ1/pvo4JfedWBnibH2w5XA3sk+TUV8iPjDec1J9mmk6uYQd1+8h5L8/C7LRcArsVd8Y3o7cvtSH7H3ldOBSyNvozKOIs34/TNTfSCpvJnE3x83U4Kpyb3nPxsE3ILv7ZF9gWMCtPM68GCT5ftgg0VI/z2I9WtPxxNmJt9H8BvTbyDwY2zfe9cpB3c/IH6l7e0MYHqg9mdntH9aws9Ytzgto09nB2p/ekb7Kc4AuuIbGTkk4XkN4BM4f3iRErgGx9fcvQrALsCNVOSdaZGIBgHXe23cqwB8Hb3fL9LlNOAcjw17FIARwLcdthtb1oXMstxqraKsvivdM/UB/AAYnHqjHjvn1dRzRN+DMpaPT5pFvRzcz+VVti/w16k3mroATAIuTLzNVPZn59O4IdjPHcnnEqwPuzsHe7uuji4n8UxDqZ8DuNZhmyndCkzF7l/vA1wMHOCaUbWNBZ4E/hV7HuB44HzPhCLbHfgeTtcDYjsZ33vKsZ8DUFQvyvAcQM/oBI7IyCu4lD8Brk64LZGqagOuSrWxVAVgOvbMv4j0bho2w1B0KQpAG/a2n4j03ZUpNpKiAHwBe+xXRPruJOyCclQpCoDGQBPJ5+9jbyB2AfgMCa9oitTMCUS+dha7AFweuX2RuvtmzMZjFoCJ2L1/EcnvD7DJRqOIWQC+QUkGPhSpsAHAZbEaj1UARgB/EqntMusE/hN7hv1K4FXXbOrhVawvL8H6ttM1Gx9/SsWGtP8L/B/z7BkpHgX+ao+2hwPLSvDZqxrLGn3Y3fkB2y/jo8BZcVFGroXEOgP4WqR2y+xl4Cc9lr0FzHDIpS5mYH3Y3U+xvm41Ud6ijVEAjsMuALaaZzOWL06aRb1k9V1WX9fZ4cCU0I3GKAB1fd+/N1lDO7fskM8BqE/f74LQDYYuAIOx2xYiEt6XsTEDggldAM7CYVwzkRbRQfZcCbmELgC1HMlEpETODtlYyAIwAnv2X0TiOYOAZ9khC8BZ2DTfIhLPIOBzoRoLWQDODNiWiGQL9jMgVAEYBJwSqC0R+WDTgN1CNBSqAEzDioCIxDcYe+CusFAFINhvEhHpk8+GaCRUAdB7/yJplaYAjANGB2hHRPpuIgGmEQtRAHTxT8RH4eduQhSA6EMXi0hThS8EhigAxwZoQ0T6r/CxV7QAjAFGFk1CRHIZS8Hjr2gB0F//9+zdz+XSu6ydW3903nNMkZWLFoCjC65fJx+n+fDNX0idSI18scmy8cCk1ImUmGsB+GTB9etkV+AX2KyuuwKjgGvJHnhSencGcBN2qjsEu/c9C2j3TKpkDiuycpGOHIAm/expIvAANoqr5kQI40Jad5i5vpiM7Ws78qxc5AzgIPT8fxYd/JLKMGC/vCsXKQCTC6wrIuHkPhMvUgBacehvkTLK/ce46E8AEfGX+65IkQJwcIF1RSScMXlXzFsA2rC3AEXE3wF5V8xbAPZG4/+LlMXe5Lwjl7cA5L7tICLBtZFzbIC8BeCjOdcTkThy/QzQGUB4bwBzgae8E6mRp7A+fcM7kRLL9Uc5bwHQ21jN3YYNj3Yqdm/2dGCrZ0IVtxXrw8lYn47G+lh29uE8K+UtAB/JuV6drcemb97YbdlsYIZPOrUwA+vDLhuxPl7vk06pJS0AuTZWc08Bm5os/03qRGqkWd9tQj+vmtkzz0oqAOFsyFi+MWO59C6r77L6upUlPQMYlnM9EYkjaQHQQ0Ai5TI0z0p5C4DGARApl1yTheoMQKQekhaAgTnXE5E4khaAATnXE5E4khYAjXknUi7JCoAOfpHyyXVchpgbUET8bcuzUp4CsCPvxkQkmmQFAGBLzvVEJI6kBaDZSy8i4ifXa+d5C8DmnOuJSBy5XpHOWwD0PrZIuazLs1LeAvBmzvVEJI6kZwAqADvLej9CL07ll9WneyTNohp0BuDsEJq/I3FE6kRq5OgmywZhfS3vtzLPSnkLwKqc69VZB3AD7y8CJwKX+aRTC5cCn+32/4OBm8n57nvN5SoA7Tk39krO9eruq8A0YD42W8uR6NHpInYD7sXGAFwJTEHD0WV5Pc9KKgDhjQLO9E6iZnTK37tcBSDvTwAVAJFyWZFnpbwFINfGRCSaZXlWKnIRMNdtBxEJbg2JbwMCvFBgXREJJ9dffyhWAJ4vsK6IhLMk74pFCsBzBdYVkXAW5V2xSAF4usC6IhLOM3lXLFIANEGjSDm4FIAX0CSNIt424HQRsBP9DOhpKXA69qz6OOBHvunUwo+wvhyK9e1S33RKZwF2LOZSdFTgRwuuXyfbgTOA2cDb2I56ETDLM6mKm4X14VKsT2djfbzdM6mSKXQMqgCE8wywuMnyO1MnUiM/b7JsMQWuetfQ/CIrFy0Avy24fp1kvYzxWtIs6kV92jvXArAcfRkiXl7CjsHcQswM9D8B2hCR/nugaAMhCsB/B2hDRPqv8B/fEAVgXoA2RKT/SlEAlqLxAURSe4EAz0SEmh343kDtiEjfzA7RSKgCcE+gdkSkb0pVAOah+QJFUtlMgDsAEK4AbEIXA0VSuY9AM3SHKgAAMwO2JSLZ7gjVUMgCcCfwTsD2RGRnW4FfhmosZAFYC8wN2J6I7GwuAUfkDlkAAG4P3J6IvN9/hGwsdAGYib23LSLhrQd+EbLB0AVgIwEvUIjI+9xOoKv/XUIXAICfRmizCgZkLI/Rx60iq0+zltfdraEbjLFzPkhrjtt2UMbyg5NmUS/jM5ZPSJpFOTwLPBS60RgFYAfwwwjtlt3+wDk9lg0BLnHIpS4uBYb3WHY+sF/6VNzdgB1bQbWHbrDhx8BVwOBI7ZfVrcBU7CxoH+Bi4ADXjKptNDbW4k3YhLTHAX/kmZCTTQS++t8lVgFYC/wX8LVI7ZdVO3BBIySMUcCV3kk4+3fgrRgNx7xAdR0RTllEWswO4NpYjccsAE8CcyK2L9IKZmEXAKOIfYvqHyK3L1J3/xiz8dgFYB7weORtiNTVo8CvY24gxUMq1yTYhkgdfTv2BlIUgLsoOHuJSAt6AvhV7I2kKAA7gKsTbEekTv6OBHfRUj2nPgudBYj01cMEGvSzN6kKwA7g8kTbEqm6K1JtKOWbag9Q//kDtgM3A+dhX+Iy33RqYRnWl+dhfbvdN53o7sTOAGppEvYF7nCIrEFLpwfcRrOXgZY4fd46xJJGH3Z3TsD2p9PcTKfPu43sNyCjSP2u+iKsitfRcuC2Hsvext7iknyuZ+cRpm4D/tchlxSuBxan3KDHYBXfAt5w2G5sSzKWP5c0i3p5vp/Lq2wVDi89eRSAN4G/ddhubO9mLO9MmkW9ZPVdVl9X2d9gb9Em5TVc1c3YY44iAo8At3hs2KsAdAJfp/5XdEV68w5wIU5nip4DVi4Evu+4fZEy+C7we6+NxxoRqK++A3wRmOiYw6PAlwK083rG8t8Far8V/S5j+TXYsHNFef8M/T1WAFraUaR5NkCTl0pfpXgO4B3g8FQfKEsZxqz/LfA97yREErsKjZXx/3bFTsdiVlwNTyZ9NYe4++Ij+P/8Lp2x2FNfsTr9TWBosk8jVTUMux8faz9cBxyY7NNUzLnErbx3AR3JPo1UTQc2+WbMfbBUF4TbvBNo4ibsvmgs67CfG8HmWJda6ACOJO4fiB9SspmiylgABmK/kaZ4JyIS0ALgWGCLdyLdlbEAgP1Gms/O88KJVNFq4FOU8C3GMtwGbOYF7LeSHhWWqtuG7culO/ih3POsv4jNh3a6dyIiBVwG/Mw7iSxlLgAAjwEjKcETUyI5XIc98FNaZb0G0N0A7NHMM70TEemHe7B9ttRjF1ShAAAMAu4HjvZORKQPngBOBDZ6J9KbqhQAgL2w0VLHeici8gGeB47HhvgqvbLeBWhmFTANeMU7EZEMK4DPUJGDH6pVAMDuDHwaeM07EZEeVmN/oFZ4J9IfVSsAYKPvTgPWeCci0rAaOJnEQ3qHUMUCAPA0cCoqAuJvFTAV2ycrp0oXAZuZgN0dGOWdiLSkVcApVPTgh+qeAXR5Fqu+ujAoqb2E3eqr7MEP1S8AYDPvnAAs9U5EWsZi4Dgq+Ju/pzoUALC7A8dibxCKxPQ49genUlf7s9SlAID9Hvs09gimSAz3YVf7V3snItnasZFXYg7rpGi9+BfK//KcdPNn2LvY3juOotqxDXulVyroFGw0YO+dSFHN6LrHLxX2MeLPOaCoXywARiO1MBAbbdh7p1JUI27C9hmpmXOJO/mIotqxFjgbqbWx2HyE3jubolzxGDAGaQntwBXYDK3eO57CN7Zhk9N+CGk5h2IXe7x3QoVPPAMchrS03YDvoLOBVoqt2Gi9uyHScCi6NtAK8RAwEZEmdgEuwJ719t5RFWFjNXAR1R8DQxIYgb1PoEeJqx/vAP+E5pmUHCYAs/DfiRX5YhYwfqdvVaSfpqLHiasUD2IDdogE9XlsQAjvHVzRPBY0viORaNqwOd90RlCeeBibRVoX+CSpk4B7gU78D4JWi85G35/Uy3ckEt0ngBuBDfgfGHWPjdgdGl3ck9IZBvw5Nlqs94FSt1gEfBO7RStSam3YKMU3A+vwP3iqGuuBf0PTwkuFDQK+DNwNbMH/oCp7bAHuBL4E7J6jv0VKqwP4CnAXul7QPTYAd2ADtgzL3bsiFTIQOA2YgU1s4n0Qpo4lwA3Y7TsNv+VE903L4wBsYpOu2Nc3neBewu7XzwPmAstdsxFABaDMPgoc1YgjgUOAIa4Z9d064ElgIfAb7MB/2TUjaUoFoDrasLOEQ4BJ2H3wcdgYh3s65bQWeB6boPU57PbnQmAZdpovJacCUA8jsDOG/YBR2M+HvRrLu2I4Nt5BR2Od7q/HdmJ/tWn8uw27BbcOe49+TSNexybFXIGd0r8V6wOJiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiEg3/weXg5P4WBwXrQAAAABJRU5ErkJggg==",
-
- "demoBuildingBlueprint.png":
- "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAgAAAAIACAYAAAD0eNT6AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAOxAAADsQBlSsOGwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAACAASURBVHic7d13gFxlvcbx5z0zW5NND4RAOgEBaYIFQQVEeoeNBb0qKqiIFMVCc1AR8V5BQVRQREFaIh3BClwURCkiXDokAUJI22Sz2c22mfO7f4QkW2Z3Z7ac95yZ7+cP2J3Tnt3MznnmPWfOkQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8Mn5DgCgMDtdsWJ0ZVV2YtYqJgUWTnJmE82CieZsopMmmdxE52yimZyZquRUK0mysE5yaZOc5MZJkkKrlNMokyRTi5zr2DCvNZqTOblOmZolKVS4XrJ2mUzONTjTqlBqkHMNkhqUCxuc08qgQqtSTUHDU2dNafHx+wFQHAoAEAN7XLl6bJjunGmhzZQFMwNplslmmTRD0iSTJjqp2jYuYJuXtTzrs24PWu/5rJ9le83Tey7Ls3CXb9sk1yDTylD2mpwtCkItkrPFCsJFuWzt4pe/PLEpz6YBRIgCAETkndesmGJZ21nObW+yWWZupqSZJpvp5Cbk30F338smpABsesDyTH3rq9UyLZa0yJwWW2iLU9LznWH66UWnb7k8TywAw4wCAAyzPa60isCt3s5StoezcMfQaSeZ9pC01cZ5LM+et8wKQH8/wxpJz5rpcZmeMenZtmo9sfTkqevzxAUwSBQAYAje9Zumicq17yXZrqZgVzPbWdJcmVIb5si3+6QA9FyggJ8ha9LLTnoqNHvKOT3ZkbV/LDlz2uo8iwIoAAUAKMLeV6+c2hnY3i4M9gmd7S3T7pKCjdN779woAD2nDvZnyL9+WyjpISn4eyrnHnr5jCnPyrl8qwPQAwUA6MO+GUu3zly1q8z2cRbsHco+IGkLST12bptRALo/MPIFoNdjK0Knfznp8SDU38NxHX9f/OlZbXlWD5Q9CgCwkZl7929WvcPJHWyhO8gUvstJVZsmd5uXAhDLAtB7/W2S/mVyf1Rg97566tQnGSEANqAAoKzt9cu1E5TKflCmA8zZYZK2ljbufPrY+b71DQWgj+W6PBCDAtDjcVvppAdC6e4wtLs5hwDljAKA8pKx4N0zV+2eMneAOR0g0wdMqug5GwWg7wybJiWzAHR9KGfSkzL3FwXu7tfWbPWwMi7Ms0qgJFEAUPJ2mm+VY1pXHRiYqw+lQyRNLmznQwHIl2HTpOQXgJ4/xwpJ9zppwei1a//8TGanjjyrB0oGBQAlqX6+pd5sW7NXGIb1kj4qabJU7M6HApAvw6ZJpVcAuj7eaNJdgbkFk0e9+YfHT96zM8+mgESjAKB0ZCzYZ/aa90pWb6E+bLIte85CAei5/n5ylHcB6GqNme4O5RZsRRlACaEAINkyFuwzY9X7lXLzzNxx6vYxvT52XN2+oAD0mYMC0GtbJi2XdEsQhDe/3jjt75wzgCSjACCR9r565VSXTn1CspMlzcr/gk0B6DoHBaD3g8UWgB5zvCGn3+ZyqZ+9+dWpr+aJAsQaBQDJkbFgn1kN+wfOnRSajpGU3jiJAtDf+ikAm78d1gKw8atQsvtkwVVTRi+7nUMESAoKAGJv3982bJM1d4Iz+6Kk6VLvHSgFoL/1UwA2fzsiBaDrw2+adG0uCK9afsaMhXniAbFBAUAs7TTfKie1rT5Ksv8K5Q6RNt5cZwMKQB/L5V0/BWDztyNeADb+L5TZfc4F1zlnC5acOa01T1TAKwoAYmXfG5om5XK5LzgLT5G0pVTIzoEC0P/6KQCbv42sAHThljsX/kSVwc/e+NI2DXkiA15QABAL+1zfODtludPM3Gcl1XZ99acA9Ld+CkDebH3m81EANj3WLqf5Lkx9b+lXpz6fZxYgUhQAeLXf9Y17hBaeJtPHJKU2v3hTAPItTQHoa/151hW/ArDxi9BJ98jCHy89a8Zf8swKRIICgMhlMhbcP3vNYXL6hqT3dp1GAej+DQVg8xwlVAC6fvG4Obts2brpNyjjsnkWA0YMBQCR2Wv+6zWVHaM/K9npzjS7/xdJCkC+pSkAfa0/z7qSUQA2fvuKnC6tXpe7enFmVluexYFhRwHAiNvjSqsYM3rNp810vt663e7AL94UgHxLUwD6Wn+edSWrAGy0xGT/U9McXkkRwEijAGDE7HGlVYypbfyoZOeb05xuEykAfS/b5RsKwOY5yqQAbHjM6TWZXbi8efqvODSAkUIBwLDLZCx4cO7q42S60OTmSoW8oG56+K0vKAD5lqYA9LX+POtKcgHY+B+nxZJdtHz69Ks1z+XyzAoMGgUAw8fM7X/D2uNN+rYsfFu3Sb3mpQD0uWyXbygAm+coywKw2XNm9v0VM6dfTxHAcKEAYFh88IY1R5vp25J23vDi1c/O860HKAB9LNvlGwrA5jnKvABsfPwpF+i85V+ZfmeexYCiUAAwJAfctGoHywWXmtxBGx+jAHT/ggLQfSoFoL9EheUy6QEXBKev+Mo2/8mzOFAQCgAG5YO/aZqodO58SadYz+v0SxQACgAFYMBcgy8Abwkld706Os9acc7s5XlWA/SLAoCi7HGlVYwb3fhFSRdIGiv1fp2iAHT/ggLQfSoFoL9Eg8lljTJ9f2xNx49e/vLc9jyrA/KiAKBgB1zfeIA5+7GkHft78aYAdP+CAtB9KgWgv0SDybXp0ZcknbPyazMW5Fkl0AsFAAPa77qm7VOp8BLJDi3kxZsC0P0LCkD3qRSA/hINJlevZH9NhcEZy78x7ek8qwY2oQCgT/vOXzE6la34rpNOkZSWCnvxpgB0/4IC0H0qBaC/RIPJlW8N6jSzy1NB9fnLz5rSkm8GIPAdAPH0wRsaDk5nK/7PSafprZ0/gMSokHNn5qz96S2+/9pBA8+OcsQIALo57PrG8e1B+H1n7qRC310xAtDf+hkB6DmVEYD+Eg0mV94RgJ6bWVCZqvji0q9OXZV3ZpQlRgCwyYduaqzvCPSCkzvJdxYAw6q+I9f5wqQfvMrfNjZhBAD60I0rp5qruMKZjt7wiBX17ooRgP7WzwhAz6mMAPSXaDC5ChoB2PSlk7s3m8p+ofGrs1/NuyDKBiMA5czMHXhT40nOKp7fvPMHUMpMdkgql3p24sWvfl3zLTXwEihVjACUqUNuapyTM10naS8pz7sbRgB6TWEEoMc8jAD0njcBIwA9PJwN9Ym135yxMO9KUNIYAShDH7qpsT4nPaa3dv4AytZ7U4GenMC5AWWJEYAycsD81WPTobsilDuh/3dvjAAwAtB3hk2TGAHoPW/yRgC6/s39LluZOrnpzGmr864QJYcRgDJx0M1r9ktZ8H8md4LvLABi6fh0Z/jkuB8s+oDvIIgGIwAlbt/7LV29rPFcc+5cvXXXvoHfvTECwAhA3xk2TWIEoPe8yR4B2PyQ2eWr29efpcxOHXlXjpJAAShhB89v2t7C8HpJe3R9nAKggV8UKQAUgH63VdIFYKPHgjB3wqqz57yYdwNIPA4BlKhDbm78nMLwCfXY+QNAIUzaMxeknphw0eITfWfByGAEoMTse41VV9es/Ymkz0iFv7tgBCDf+hkByJdh0yRGAHrPW0IjAD1+rutq2is/vzQzdX3ejSGRGAEoIQfe2DCturbpQbkNO38AGBZOn2it7vj72O8snuU7CoYPBaBEHHbzmv1SQfoxSe/0nQVASdrdpfXo2IsWHug7CIYHBSDpzNwhNzd+PVTwZ0lb+I4DoKRNdAruGXfRoowyxv4j4TgHIMGOvGNlXWdb1TWSHbfxsU1HFQc6Fsk5AAWsn3MA8mXYNIlzAHrPW6rnAOSdxe5Su/6rMTOrMW8AxB4NLqEOnt+0fWdb5SNdd/4AEB13hKrcP8df+NrbfSfB4FAAEuiwBWuOTZk9JmlH31kAlLXtLAgfHve9RdxNNIEoAAlz6Py1p5kFC0wa7TsLAEiqM+duHXfRoozvICgO5wAkRP18S7W4ph/LdIqkAY5/cg4A5wD0XopzAHo/yDkAQzkHIM+8Tr9Y27boi8rsl80/J+KEEYAEOPDaZaNa1HT7pp0/AMSR6XNjK2fePSHz0hjfUTAwCkDMHXRLy1YV1TX/K+lw31kAYEBOB+Uq03+bcPFL2/iOgv5RAGLssJvWvT2dyz4irucPIFl2yeXSj4y7cNFuvoOgbxSAmDrs5sYDFIR/lzTddxYAKJZJW4dOD465cPEhvrMgPwpADB02v+kzcu5eSWN9ZwGAIaiTszvqLlz0Kd9B0BsFIGYOn7/2S3L2C0lp31kAYBhUOKdf1X1v8Zm+g6A7CkCMHLag6etyulx8PBNAaXFO9sO6Cxd933cQbEYBiIkjFqz9tpP44wBQspzT1+u+t+hi3zmwAe80fTNzh9/SfKnMTnvrgUFcZKXnfFwIiAsB9V6KCwH1fpALAQ3zhYA2h+oj1YbHnennTZ0zT1HGhX3MhghQADyqn2+pVrfuKkknbn6UAqAey1MA+ls/BSBvtj7zUQD6ni+6ArDh/3Z9c8ern+Kqgf5wCMCTk660ija37kZ12/kDQHlw5k4YUzHzel35WIXvLOWKAuDBIfdY1Zvj182XVO87CwD4YtK8ulUTbtMlr9f4zlKOKAAR2/caq063NN8lJ26fCQByh41en71dmUXVvpOUGwpAhE660irq6tbNl7MP+c4CALHhdODoCt2uy16q8h2lnFAAIlI/31JLJzVdK+kI31kAIIYOGr0ufYMy93MRtIhQAKJg5tpS637uzH3EdxQAiLFj69Izf6mMsW+KAL/kkWbmjrq16SfO9FnfUQAg7szpk6MrFl3mO0c5oACMsKNuXXeRmfui7xwAkBzulFEXLrrEd4pSRwEYQUcuWJsx09d95wCA5LEzai9ceI7vFKWMAjBCjvzd2tPk3Ld85wCApHLSd0dduPAs3zlKFQVgBBx1S9NnJXep7xwAkHimi0dduOhTvmOUIgrAMDvylnX7SbpC3GcBAIaDk9lVoy5cyPVThhkFYBgd8bt1OznZrZIqfWcBgBJSIdPvRl24cBffQUoJBWCYHHtLy1aB0z2SxvnOAgAlaIzM7qnJvLSN7yClggIwDOrnrxidU/h7SdN9ZwGA0uW2dungDv33slG+k5QCCsAQ1c+3VGdQ81tJu/vOAgClz72jtn39zZpvKd9Jko4CMESdqeYfyeko3zkAoIwcVvvSwit8h0g6CsAQHHVr81clfcl3DgAoO+ZOrvnOotN8x0gyCsAgHXPrumOd2cW+cwBAuXLOLqn97iJGYAeJAjAIR97RtL1J14jfHwD4FEj228rvvbqj7yBJxA6sSEfesbIuyLnbZBrjOwsAQKNTudyt47//yljfQZKGAlAMM5fOVl8jaQffUQAAm2zf1uF+IzOuwFoECkARjrmt+WxzOs53DgBAD05H1Vy4mBsHFYECUKDjbmk+QNIFvnMAAPpgdtGoCxYd5DtGUlAACnDsLa0zQmc3SuLCEwAQX0EY2A3V31k8y3eQJKAADOBT11i1uewtkib5zgIAGNAEp/AWXfJ6je8gcZf2HSDu1o5tuULSHr5zDFbKSe+cWqGdJ6c0oTpQOpCskAX7mKmgZfPM2Wu5wldUzKzdFhrUct222c8ahvz7GWDZYf395JnDit5Mkdvse6bBbdOG9Bwa/HY3Lzyk5fNuf4A19v3PNowZuk/sDE3LmnP6x+tt+vPCVmXDIW7Qn91rWjqvbJX+y3eQOOOMyX4cc2vT5yR3Vc/HbdN/ejzW5Ssb6I+3zxdgG2D9mx/I98dsXSZuNyGls95Tq23qGOgBUJyXGjp18t2r9OSyjk2P5Xtdk/LU/X4Kk/X6oq/Xsvwvknnn7SuXuU+3nT/r131EKXsUgD7U37F221wu+LdJo3tOS0IBmDs+pf/ef5SqUvwTAxic9Z2mw29YtqkEJK4ASC2Wsne0nz3nxT7ilDXeGuZx0pVWkculrleenX8SpJx01rtr2fkDGJLaCqerjpikdHL3FKNcTjfoyscqfAeJo+T+s46ghskt35HsXb5zDNY7t6rQtDH80wIYum0nVGj/WYk+n26P6uUTzvcdIo7YS/Rw/O1N7zNnX/WdYyjePplPKwIYPu+dVu07wtA4O7v6Oy/t6ztG3FAAujj6tjXjQnO/VcI/7z+umn9WAMNni1GJfkmUpEAKrht70avjfQeJE/YUXQQu/TNJ033nGCqO/AMYTkFpvKhs09aZ7fWprnJGAXjL8bc3f1qmj/jOAQAYGU46vvrbCz/uO0dcUAAkHXdL22wz/ch3DgDAyDLZz6oyL2/rO0cclH0ByGQssKDzt5LG+M4CABhxo+XcNcpY2e//yv4X8PSuLac6ub185wAARMRpn6pg4ed9x/CtrO8FUH9X6/QwG3536FfYTrY7XuzQ0yuzXR4Z8Er4/V7FK9+VDAdYRbfHDp5dqb22Lvy6Hfe+0q6Hl3QWtIVCr0JWyHXYC/v95LmGvfq+clnv1fRxT4WBLiM/hOvI99xG/p+g9wr7vjJlH1MHuhLcEJ5DfU7M9/scxO9q/1nVqt+xdoC5NvvrwjbNf7Yl78r7/70NwPr+9+nv9/CeaVX63DvqCt1Kqbqo5rsv39V67rav+w7iS1kXgDCb+4kSerW/4fTC6qwefL3rDrTvS3kWsgPd8KLax46r+ybyrn+nSamiCsDLa3K6/9WO7g/28cJY8GVI8+wZel7KubDfT+EFIP+logcuAAOvP0+h6/NS1IUVgOIvV53nqyJ/huIuh91XvkEWgB7b2mp0IKnwArBwTVZ3vdiaN2CfP0PBuQovABu/rEyXxmn9QzQmDN3PJR3mO4gvZXsI4Ljbmj8u6QjfOQAA3hxaecHLH/YdwpeyLADH3No0UdIPfecAAPjlnPtJXeaFSb5z+FCWBSAVBD+WtIXvHAAA7ya1p9I/8B3Ch7IrAPV3NB8s6QTfOQAA8eBMn666YOGHfOeIWlkVgCPuslqTXeE7BwAgXszZVfrvZaN854hSWRWAymzL92Rutu8cAIDYmVnZ2pzxHSJKZVMA6m9ft6NzOsV3DgBAXLnTK7/90k6+U0SlbAqA5C5RmV/3AADQr7RZcKnvEFEpiwJw/J0tR5l0kO8cKEwuLG7+bG5kcgB96SzyOdoZlvfVRpPESR+quuDlQ3zniELJF4D6+VZpoZXlRzySasX64l5di50fGKql64prnW8UOT/8MrlLdOVjhV+ONKFKvgCoquU0J23nOwYK9+ib2YKvhd6eM/17Wb77AAAj5x9L2tWWLexZGpr0wOK2EU6EYfa2qmXjv+g7xEgr6QJwzK3rtpDpHN85UJzXm3L6y6KOgWeUdPOzbWrpZHgV0VrXHuqXTzQXNO+tz63X4sbswDMiVkz6lkr8CoElXQAqAl0oaazvHCjepf9s0Yur+3/RfOSNTl3zn9aIEgHd/fAfTQO+s39qeYfOuW9NRIkwzMZXKH2B7xAjqWQLQP1tzbuZ3Kd958DgtHSaTv3jOi14rk3tOes17ZdPtuob961TlsP/8CQbmj59xyr9z8NNWtfe/YnYljVd9fg6HXvzSjV3MEKVWE4nV2YW7uI7xkgp3Y/FBfqRTCnfMTB4bVnTTx5br1882aodJ6U1tsqpoTXUcw1ZdTCiihjIhtKP/tmknz62TrtNqdQWtYHWtIV6fGmHWgs8RwCxlrLALpX0Qd9BRkJJFoB5d7UcbTn7gO8cGB5tWdMTnOiHGOvImf71Rrs2nr3Krr+EmPZPZV45PJeZc7fvKMOt5A4BZDIWWGgZ3zkAAKUhcPqeMlZy+8uS+4Ge2715nqRdfecAAJSMnSvdwmN8hxhuJVUA6udbypw733cOAEBpMdkFpTYKUFo/TGXLCTLt4DsHAKDk7FTpFn7Yd4jhVDIFYMO7fy76AwAYGRtGAe4vmZPnS6YAuKr1J4pL/gIARs7cCjftBN8hhktJFID6+VYp6Zu+cwAASl5GmWcqfYcYDiVRAFzl+s9JmuU7BwCg5M2scFWf9B1iOCS+AHzqfquW0zd85wAAlAnTubrspSrfMYYq8QWgdV3r5yRt4zsHAKA8mDS9YnWQ+HvNJLoA1M+3lJmd5jsHAKC8mOzMpF8XINHhXXXrcZLm+M4BACg7c1PulaN8hxiKZBcAszN8ZwAAlCdn+orvDEOR2ALwkdtb3yfpPb5zAADK1t7pb7+0l+8Qg5XYAmAuTHTzAgCUgDA403eEwUpkAfjYXW1zJR3hOwcAoNzZMVWZl7f1nWIwElkAwjB3phKaHQBQUlJZKZGfRkvcTrT+D2snmNMnfOcAAECSnHSiMi9M8p2jWIkrAK4zfaqkUb5zAADwltpAqc/7DlGsRBWA+vlW6Uxf8J0D0QqctO34lPbcqkKzxqUUON+JgO4CJ71tUoXeN71KO06uUIrnaNlx0ilJu0lQou5r7Kpbj5a0pe8ciEZFIH10pxodv0O1xlZtfkVd3Rrq+mfa9Lvn2hSax4AoeyknnfiOOn1hz9GaXJva9Pjq1lC/eKJZP310nbI8ScvFlJSrPiIn3eI7SKESNQLgnH3OdwZEoyrl9D8H1Okzu9V02/lL0oSaQKfuWasL9x3NOy14kw6kq46YqPPfP7bbzl/a8Bz9+t5jdONxk1SV5klaNixZ+6jEFID6O1tnybS/7xyIxqnvrNVuW1b0O88+0yr1yV1qIkoEdHf6e8bowDn9P//eO61KmQ+MjSgRYuBDyiya6TtEoRJTAFIKP6sE5cXgTRkd6LBtC7vT5kd3qlZtBe+wEK26qkAn7VFX0Lwn7DJaW9elBp4RpSBIK3ei7xCFSsQOdd/7LS3pU75zIBrvnlpR8Il+1Wmn3bdM1KksKAF7bVOlmgKH9lNO2n9W9QgnQlyYdKLmWyIaXyIKwFbN6w+XNNV3DkRjyqjinpZbjkrE3xpKyFaji3vOTRtLSS0jW6eeXXiI7xCFSEQBCE2JOrECQ5Mu8lmZZv+PiFUW+Zyr5LOrZcY+6ztBIWJfAE64Z/02TjrIdw4AAAp0mDLPx37UOvYFIJezz0jiPR4AICnSgVKf8pxhQLEuAJmMBTIl5oxKAAAkycl9RhmL9T421uGe3b35A5Km+84BAECRZksL3+s7RH9iXQACBfN8ZwAAYDACWaz3YbEtAPXzLSWnY33nAABgUEz1qo/vNQFiWwDSVS37S9rCdw4AAAZpSnqnl9/nO0RfYlsAQudiPXQCAMBAQim2+7JYFoCTHrMKJx3jOwcAAEPjjlfm/lheCjKWBWDt0vUHSJroOwcAAENimpzW9H19x8gnlgXABfEdMgEAoBhhTD8NELsCUD/fKp3pSN85AAAYJscr80yl7xA9xa4ApGvWHyRpgu8cAAAMC9P4tKr29x2jp9gVAEnH+w4AAMBwCs3qfWfoKVYFILPhuskH+84BAMDwcodKFqv7QseqALy4R+ue4uI/AIDSM0Xnvbyb7xBdxaoAhLJDfGcAAGAkBCnFah8XqwIghv8BACXKycVqHxebAlD/h7UTnPRO3zkAABgJZtpLmUXjfOfYKDYFIN1RcZCk2N41CQCAIUqnlD3Ad4iNYlMA5CxWQyMAAAw3i9Gh7ngUADMn6SDfMQAAGFnx+ThgLArAx36//h2StvSdAwCAEWW2lTKLdvYdQ4pJAQgtiNVHIwAAGDFhLhb7vFgUACc70HcGAACi4IJ4HPL2XgAOuceqxMf/AADl4z1xuDug9wIwobN1T0nVvnMAABAJU42U9n5ZYO8FQIH29h0BAIBIhYH3fZ/3AhCKAgAAKC8uBm9+/RYAM+ekvbxmAAAgevv4DuC1AHz8zvbtJE32mQEAgMiZttS5L83xGcFrAbCUeR8CAQDAi7Tzug/0WwAUvtfn9hFPrdni5m/psJEJAvShucjn3LqOcISSIMkCC8u3AMj8th/E06trcyM6PzBUL63uLGr+FxuKmx/lwVyZjgD8161NEyVt72v7iK9H3ujUugLfYS1pyunZVUUOGQBD9MSbHVrcWNjzrrEt1P2L20Y4ERJqR2WemeBr494KQC6d2ktSLO6IhHhp6TRd9e/1A84XmvSjR9cr5AgAIhaa9K0HGgt67l34t7VFHzJAmTA5qfo9vjbvrQBYEOzua9uIvztfbNfVT7aqr5fNzlC6+B8t+ucbDK3Cj/sWtelrf16jzlz+Z6lJuvihJt3wdEu0wZAsudDbFQHTvjYss1jcDhHxde3Trfrn0k7N27Fau22Z1tiqQA2toR5d2qkbn2nT600c+4dfNz/TokeXtuvkPer0/hnV2nLUhufoP5a066rHm/XU8g7fERFzQWA7+zpF1F8BkHbxuG0kxAsNWX37b829HjdGVBETr6zJ6mt/WbPhG+v2P2BAZs7bvtDLIYD6+VYjaVsf2wYAIEa2U2aRlxvieSkAqVHrd5KU8rFtAABiJK1cdgcfG/ZTACxg+B8AAEmS83JOnJcCEIoTAAEAkKQgCMunADjjBEAAACTJQj8nAvq6DsDbPW0XAIB4cX7eFEdeAD7+h5at5LRF1NsFACCmpijzcuT7xcgLgHWmOP4PAEBXYfQnAkZeAEIXcgMgAAC6CbeLeouRFwDnNDPqbQIAEGvOzYx6k9GfBGgUAAAAurOZUW/RRwGYFfk2AQCIM7PI943RFwAOAQAA0IMr7QJQ/+fVYyWNj3KbAAAkwCR97fm6KDcYaQGo6Khk+B8AgHxq0zOi3FykBSAI3cwotwcAQGKE0Z4HEGkBCIPoj3EAAJAMbmaUW4u0ALiQEwABAMjLRftRwGg/BcAnAAAAyC/ijwJG/THA6RFvDwCAhHCRngSYjnJjEncBRHECJ71raoV2n1Khukqnte2mx97s1GNLO2W+wwGSnKT3z6jWPtOrNK460Nq2UA8vadcDi9qU40mK4kyOcmORFgAnTeTvAYXadnxK571vtGaOTXV7/GM7VeuFhqwyf2vRkqacp3SANGtcWlccniHuIgAAIABJREFUNlE7b1HR7fHP71mnFxo6dco9q/Xcyk5P6ZBAk6LcWGSHAE68w+pMqopqe0i22eNSuuygMb12/httPzGtnx5cpymjor+YJSBJ24xJ69YPb9Fr57/R9hMrdNuHJ2v7ifmnA3nUKLO0NqqNRfbqub6ybWJU20KyOUnf3HuURlW4fucbXx3ozPeMiiYU0MP3DxinSbX9v4TWVQa6/NAJCvp/KgObda6PbF8ZWQGoCMNIhzaQXDtvkdZ2Ewo7OrXX1hWaWscoAKI1c1xaH5hRXdC8O02u0J5TGfxEgQKLbF8Z2StnzowRABRkly2KOzXl7ZOjPpcV5W7PqZVFzf/OIudHGUtFt6+M7q2TpRgBQEHGVhU3Xjq2ihEARKvY59xAhwqATXJB6Y0AKGAEACPDcXwVESv2mL4TT1IUyJXgCIDjEAAAAAMpwREAOQ4BAADQrxIcAZATIwAAAPTHuRIsAKEbE9m2AABIItP4qDYVWQEwGR+EBQCgP6aaqDYV3UmAjssAAwDQL1eCBUBOXAkDAID+ld69AGQUAAAABlCCBYA7AQIAMJDSOwTgJO6JCQBA/wq7y9QwiPBTAIwAAAAwgFRUG4pyBIACAABA/0qvAJgcJwECANC/0isAklEAAADoXzqqDUX5KQAKAAAA/SvFEQAAABAXURaAjgi3BQBAEuWi2lCEBcBRAAAA6F82qg1FeClga49sWwAAJFMJjgA4DgEAADCA0isATmIEAACA/pVeATAZIwAAAPSvLaoNcRIgAADx0RrVhjgHAACA+Fgf1YaiOwfAOAcAAIABlF4BCI0RAAAA+mUleAjAyTECAABAv6z0RgCcs7VRbQsAgERybk1Um4ruY4Cmhqi2BQBAIjkX2b4ywkMAtiqqbQEAkEihlV4BsAhbDQAACRXZm+UIrwNAAcDIMPOdAOUmLPI5Z+JJigKV4iEAhY5DACjI2vbiXizXtIUjlATIb3Vrcc+5Vet5jqJQ0e0rIzwEkGMEAAV5akXht8O2IucHhsOjS9uLek//zzf4FDQKFES3r4zwEEDACAAK8vSKrF5oKGyn/uBrHVrRwrsrRGtJU05/eqWw67U8uaxDjy/lOmgoVAmOAHS2VDMCgIKYpIseblFLZ//vsVauD/Wjf0V2zQygm3Pua9Sy5v7v3LquI9SZf1zDGQAo3Nro9pWRFYAF81yzIrzNIZJtUWNOp/6xSYsa87/APrUiqy/c28SxVXizvDmnY25eoUf7eHf//KpOHX3TSr3Q0BlxMiTYel06LbJLAaej2tBbGiRtHfE2kVCvrMnpxLvX6p1TK7T7lhWqq3Ja3RrqsTc79e9lHPeHf0uaNpSA92xTpfdPr9Lk2pQa20M9/Hq7/ndxm3K89UdxIj1UHnUBWCkKAIoQmvTIG5165A3eRSG+HlnSrkeWtGvjWD/7fQxSpAUgupMAN3gt4u0BAJAQ9mqUW4u0AJjToii3BwBAYjgX6T4y0gLgTIuj3B4AAIlhbnGUm4u4ANjiKLcHAEBiBGHpjgBIxiEAAADyChZHurUoN2apURQAAADyal8c5dYiLQDXH+qaJK2JcpsAACTASmV2ao5yg1F/DFASnwQAAKCHyPeNPgrAYg/bBAAgvlz0+8bIC4AxAgAAQHdWBiMAXAsAAIAePHxMPvoRgCB4IeptAgAQay76fWPkBSDrOp+MepsAAMRap/1f1JuMvAAsOLRupUwrot4uAAAxtVQXzV0Z9UZ9fApAcvaUl+0CABA3Ji/7RE8FwFEAAACQ5Jx72sd2/RQA+flhAQCIm1BWPgUgCENGAAAAkCTzs0/0UgAaUrXPSMr62DYAADGSVWPwvI8NeykA9x7q2p3sJR/bBgAgRp7X5XPbfWw47WOjkiTnnpZpB2/bRyLsMCmt+h2qtduWaY2rDrSmLdTjb3bqxmfa9MqanO94gHacXKHP71GnfaZXaUJNSqtbc3r49Xb94olmPbmsw3c8xJxzeso8bdtbATBzT0s2z9f2EX+f3KVGn961Rq7LY5NqAh00u0oHzKrS5Y+u1y3Pt3nLB3xqt9HK7DtOqS5P0i1GpXT022p11Ntq9YOHmnTZP5v8BUTshaG8nRTv6VMAUujCf/vaNuLvqO2qdGKPnX9XKSed9q5avX96ZaS5gI0O2bZG396v+86/Kyfp63uP0Qk7j4o0FxLGuf/42rS3AhCo82FJoa/tI75GVTidtHvtgPM5SafuWdvnCzAwUtKB9K19x/VZULs6+31jNbqSJynyCtVR8YivjXsrADccPm6Nk3FjIPTynq0rCn7BnDI60E6T/Z3KgvK059QqbV2XKmjecdWB9p9VM8KJkEhOz+j7M9b42ry3AiBJpuAhn9tHPM0cW9gL60YzipwfGKptJxRXOrebSElFb86c132g1wIgEwUAvVQX+VpZU8HwKqJVky7uOTe6wu9LLeIpdFbGBcD5bT8AAHiTzZVvAbjhiOqXnLTMZwYAADxYpu++bZHPAN7HpUzydgYkAAA+OKe/+c7gvQBwHgAAoNyEod/j/1IMCoA5CgAAoMwEKe/7Pu8FINta87ikVt85AACIhFOLlq7xdgXAjbwXgAXzXIdMj/rOAQBAJEz/1FV7dvqO4b0ASJIL3B99ZwAAIApm9gffGaSYFICchbH4ZQAAMOIsFYt9XiwKwM2H1/5b0pu+cwAAMMKW6Duz/893CCkmBUDOmaQ/+Y4BAMAI+4PkzHcIKS4FQJJzLhZDIgAAjBQXk+P/UowKgNTxR0k53ykAABgh2VxQ8VffITaKTQG44fBxayT9y3cOAABGgpN7WJlZjb5zbBSbAiBJzule3xkAABgJFrN9XKwKQC5UbI6NAAAwnELlYrWPi1UB2OGJ2sclrfCdAwCAYbZMmbneL//bVawKQCbjQileQyQAAAyZc7+Py8f/NopVAZAkc1rgOwMAAMMpUDjfd4aeYlcAxkyp/ZOk1b5zAAAwTFZlteQ+3yF6il0BuGpP1ynpdt85AAAYFk63KLNf1neMnmJXACQplN3sOwMAAMMhCBXLfVosC8Dy0aPuE58GAAAkndPy7HNzHvQdI59YFoAH9nNZcRgAAJB47nda4GJ5mftYFgBJcgpjOWQCAEChwpyL7b4stgVg+ydGPyCnN33nAABgUJzeVGrWQ75j9CW2BSCTcaGZbvOdAwCAQZqvDRe4i6XYFgBJMgtiO3QCAEB/wly8P9EW6wKw47+r/y5pse8cAAAU6RV9Z9tHfIfoT6wLQCbjQpl+5TsHAADFMLlfxu3a/z3FugBIUi5wv5IUy49QAACQRzZU57W+Qwwk9gVgwRG1b4g7BAIAkuNuZd621HeIgcS+AEiSTL/wHQHRyRZ5zmxnLtajbChB7UWOSXaEPEfLi0vEPisRBWDZmNp7JL3hOweisayluAawrDm2n7JBiXqjqbj7ury2Nnb3gcHIWZLbcfYffYcoRCIKwAP7uayTfu07B6Lxz6WdKvQNU0un6d/LeXFFtP6xpF3NHYU9SbOhdP+ithFOhLhwsqs1L56X/u0pEQVAkrIKrpbEW70ysKw51N0vtRc073VPt6oty/AqorW+03TFo00FzXv90816Y10i9gcYujCbTl3jO0ShElMAFhxZs8ikv/rOgWj85LH1+veyzn7n+cuiDt34DO+s4MdPH12nO15Y3+88D73Wrgv+d21EiRADf9K5s1/1HaJQiSkAkuQsGSdWYOjac6az/rpOv3yyVY1t3d/hL28J9cNHWvTtvzUXfKgAGG6hSafes1pn39eopT3e4Te0hvr+39fqY7euUjsjVGUkWfuotO8AxQjba+4Iqtcvl7Sl7ywYeZ3hhiH+3/5fq2aOTWlcdaBVraFeX5tjx49YMEnX/qdZ1/2nWdtOSGuLUSk1rA/1YkOn+HBK2Xkzt9Wau3yHKEaiRgAWzHMdznSF7xyIVmjSwsacnljWqdfW5sTrKuLGJL20OquHXmvX86vY+Zcjk/1EJ+/Z/3HLmElUAZCkXFX2CkktvnMAAPCW9WFl9krfIYqVuAKw4OCxqyX9xncOAADe8kudvUOD7xDFSlwBkKRUkPqhuD8AAMC/XCpll/kOMRiJLAA3HF69UNIdvnMAAMqbk25pP2/uK75zDEYiC4AkOXM/9J0BAFDu7FLfCQYrsQXgpqNrH3amf/jOAQAoV+7BzszcR3ynGKzEFgBJCgNGAQAAfpjCRO+DEl0Adnyi5jZJL/vOAQAoOy/mtO3dvkMMRaILQCbjQpl+5DsHAKC8OOmHyrhE36Au0QVAkmrH1l4taYnvHACA8uCk1zonWOKvR5P4AvDr/VybSd/znQMAUCacfVtfnlvYPctjLPEFQJLGL6v9paRFvnMAAEreK51T1l7rO8RwKIkCcNXJrtOcLvSdAwBQ6uyCpN30py8lUQAkSW21v5b0gu8YAICS9WKnLbnRd4jhUjIFYME8l5P0Xd85AAClyUnnK7Nf1neO4VIyBUCSrH3UjXJ6zncOAEDJeabD5izwHWI4lVQB2DAKYBnfOQAApcVJ5yX9c/89lVQBkKT5R4xeIOlJ3zkAACXjiY7z59zuO8RwK7kCIOdMct/yHQMAUBpC03kb9i2lpfQKgKQFR426U6Y/+86B4VGTdtpzqwrtN6NSu26ZVkXKdyKgu8qU07u3rtLh29Von+lVqq1wviNh+Pw1l5lzj+8QIyHtO8BICVN2RhC6J1XCP2Opq047fW73Gh05t0qVqc0vqC2dppueadN1T7cqV3KdHEmSDqQvvWuMTtpjtOoqN7+fas+arn2qRT94aK3Wd/IkTbCsczrDd4iRUpIjAJJ0y5F1z5jsl75zYHBGVThdflCdjn9bdbed/8Zpn9mtRhfvX6d0yT6DEXfpwOmaoybpK3uN6bbzl6SqtNPn3jFat8yb3GsaksT9rOP8OU/7TjFSSvqZ6TrCcySt9p0DxTvz3aO03YT+B2/evXWFTty1JqJEQHdffe8Y7Tuzut95dtmyUhd+cFxEiTDM1nRWtF/gO8RIKukCsGDe2NWOiwMlzrQxKX1wVmVB887bsVqjON6KiNVVBfrM7qMLmvfYHWo1cxxHIpPGOXe+zt6hwXeOkVTSBUCSxi0f9RNxieBEeedWaRW6S69KOe0+pWJE8wA97bVNlarThT1LnaT9BhgpQNzYc+1brr7Sd4qRVvIF4KqTXadz7iu+c6BwW9QW97Qsdn5gqKbWFfdRlGLnh19OqTNK5YY//SmLV84FR436vaQ/+M6BwqSKfFameW1FxCqKfI5WBBymSpC72r8164++Q0ShLAqAJKVCO1NSyTc6AMCgdTjTV32HiErZFICbj617zkyX+84BAIgp06XtmTkv+o4RlbIpAJLUkR51nsm94jsHACB2Xuqoqyzpj/31VFYF4K4j3PogCE+SxKW5AAAbWeD0RZ05rdV3kCiVVQGQpAVH1t0n6TrfOQAAcWFXt5035y++U0St7AqAJOXC8ExJK3znAAB4t6y9ouJrvkP4UJYF4LZjxzRYCd/gAQBQGHPuVH1zxhrfOXwoywIgSbcePfoGZ3an7xwAAG9+33He7N/5DuFLWV+g2lWkT7Vsbj9Jdb6z+LT9hLQ6cl0fsS7/7YPl/XLz9wWcZplvFtOGewEUY9vxKe03I9+9A3pvwfJMyhs1z4N5f86+dNlQ3p+zwNNQey6dL3/e5QrI3/c2u3+R/yfovcK+/j37nDrAv0Ehv6N+t1nAP2xfz9WBNr3D5MLuVbHR7PFpHbFdTd6V9/97G4D1/e/T3+/hHVsVl79ENQVh+HnfIXwq+8tTHXvbulOd3GVSjz8k6/a/bvK9aPR8oRvwBbjP9dsA69/8QF/Zznp3jfafwfXxAQyP+c+06PN3r+qzlPWqVX28PnWbd6AC2MeLZDFlsddbme65vtB+/pyf9xGzLJTtIYCNdvnP6Cvk3EO+cwAAImJ6sD2cfZXvGL6VfQHIZFwYBMEnJDX5zgIAGHFrnQWfVMaFvoP4VvYFQJIWHFmzSKYv+84BABhZJn2xLTNrse8ccUABeMstx47+jUk3+s4BABgxv+04f84NvkPEBQWgC1P2i5K96jvHUHGdYwDDKSyNF5XXqyrSjPR2QQHo4vZjxjcGTp+QlBtw5hhrbCv7Q1sAhtGKlkS/JEpSKAs+sbZML/jTFwpAD787eszfJPcD3zmG4umVif9jBRAjD73e5jvCUH2n7fxZ/+s7RNxQAPJYPW7U+TL3T985BuvRNzv1WhOjAACG7sWGTt2/KNE3yXu0bYs1F/oOEUcUgDwe2M9lwyB7gqR1vrMMRmjS/zyyXm3Z0jhwB8CP9Z2mk+5apWxy3080m3SCTt6z03eQOKIA9OH2Y8a94mSn+84xWC+tyelr97UwEgBgUJ5f1alDr1+mp5Z3+I4yeE5fbD9vzku+Y8RV2V8KeCDH3LruF5I+2/WxuF8KuOvEwEl7bJXWLpPTmlgTKB0U+CmBwi7/XvAK8uUf3JoKX2go4x8D3g1hyL+fAZYd1t9P30/GweaN5jnUfamhPIcGv93NCw91PK2fO1MUusAIZOg+sTM0vbkup4deb9NfF7Yq1/N1KEGXAjZnP287d84X+ogBlfnNgArRVj36S9Vt63aV3Dt9ZxmMnEn/WprVv5ZmNz02cMHo+w+4kD/eDesfuAD0v/6elarHfAUVpH5ecgd68cnzS+q5gy7s91P4zYDyF8Q+MhSUv/schRXQ3tvo8/dYVEnN81WRP0Pxz6F8j+f5fRayo+21rT6en0X8XvurmcXlyr+rLXxHu/GLAf5mk+WfbWPCxI7gRoVDAAO491DXHgbp4ySt9J0FADCgFcrljteX57b7DhJ3FIAC3HF07euSPqKEXx8AAEpc1uQ+3JqZu8R3kCSgABTotmPr7pPsXN85AAB9cPb1tvNmPeA7RlJQAIpw2zF1F0ta4DsHAKAHs9taz5l9qe8YSUIBKIZzls62nijpWd9RAACbvNAahp+Scwk/dzFaFIAiLZi3RXOYsmPl1OQ7CwCUO5PW5RQco8xcXpOLRAEYhDuPGvOCQvukJK6yAwD+5Jx0Qsd5M5/zHSSJKACDdPvxY2535s7ynQMAypXJnbn+3Nl3+c6RVBSAIbjt+NGXSLrcdw4AKDfOuUtbz511me8cSUYBGKLdnh59uqTbfecAgDJyd8vcmYzADhEFYIgyGRdW5EZ/TEru7YMBIDGce3x9Ve1HNM9xYbYhogAMgwXzXGtK7hjJXvWdBQBK2GInO0xnTWnxHaQUUACGya3HjXpTOXeopEbfWQCgBDUptCNbzpm93HeQUkEBGEZ3zKt71oXuGEkJvoE2AMROp5wd23L+nKd9ByklFIBhdnt93QNOOlmJv5smAMSCSfpMyzlz/uo7SKmhAIyA248b82tzdprvHACQeE5ntZw7+zrfMUoRBWCE3HXc2Mtl7nzfOQAguezslnNm/9B3ilJFARhBd9bXfUemi3znAICkcdKFLefM4fVzBFEARtid9WPOlokGCwCFcu4nzefMPtd3jFJHAYjAncfXnSXpF75zAEDcOdNvmjtmcA5VBCgAUXDOqsK6L0juRt9RACC+7JZ12838jDKOO61GgAIQkQXzXG6rhtGflMSdqwCgtzubJ63+KJf4jQ4FIEJXnew6162rmye5P/nOAgCxYfpTc112nk7es9N3lHJCAYjYA592bdXh6COcdJvvLADgnbm7m7M6Sl+e2+47SrmhAHiwYJ7rqLK6eidd6zsLAPjinG5eN3nVscrMavOdpRxRADxZMM/lqqzuRHO62ncWAIie+21Tx+KPM+zvj/MdoOyZuSN+13yJyU5/64ENNxHocSeBXjcWsPw3G7AeE/ucp9/12wDr775Az/k2rL/XGnvN1P/6rfdjXecr6PfTe8lC8m9efz8/Q8G/n3wpeufPt/58SxeXv/sc+dffT44+MmyaVNRzNM9XRf4MxT+H8j2e5/c50L9F3m318fws4veaP9FgcuW/7UjBv+dNXwzwN9t7lj7m7fv1Y+O8zuynTZ2zTuVsf7/SvgOUPefsLumMwxesXSu5b/mOAwAjynRx0zmzv+E7BjgEEBt314/NmMQfBYDS5ZRZd84sXudiggIQI7+vH3Oxk06RxLAYgFJiks5o+uasC3wHwWYUgJi5q37sT83cZyRxYgyAUtAh2Sebzp71I99B0B0FIIbumTfm16HsYEmNvrMAwBCsCcwd3HT27Ot8B0FvFICYunfeuPuCINhH0mLfWQBgEBaFKbd34zkz7/cdBPlRAGLsruPrnjGl9pL0mO8sAFCEf+XM9mr++sznfAdB3ygAMXfPvNHLOtta95V0h+8sADAgp9tHdVTt13LO7OW+o6B/FIAE+NN/TWkZpTHHyeky31kAoC9OdtnatpnHLc1MXe87CwbGlQAT5tD5a0+T9EOZUlwJcKD1cyXArnNwJcDeD3IlwGG7EmDOnDuj6RszLs8/B+KIEYCEuWfe2B/LueMkrfOdBQAkNQXOHcPOP3koAAl0T/2YO2RuT8n+z3cWAOXLSS8E5vZa840Zd/nOguJRABLqno+MebHVdezlnFvgOwuAcuTukMu9e/XZM571nQSDwzkASWfmDl3Q9GUz/bekCs4B6Lp+zgHoOgfnAPR+kHMABnUOQM7kzln7jek/kHN9nBWAJGAEIOmcs3vmjf2xU3CAJD52A2AkrTK5g9d+c8bF7PyTjwJQIu75cN2DSmf3lPSI7ywASo+THlcu3HPtN2f8xXcWDA8KQAm597iJS1zdmH0l43oBAIaPs6tWt7W8t/Hc2a/6joLhwzkAJergG9d8Ss5dbtLontM4B0ADHxflHADOAeh3W2VzDsA6c+6Uxq/P4GY+JYgRgBL1h4+O/7XMdnayh3xnAZA8JvevnKXewc6/dFEAStgfPjp+cduW4/Z1ZhdIyvnOAyARcs7ZxY3jV+7T9M1pL/sOg5HDIYAycchNa98Tyn4raQ6HADTwsCiHADgE0O+2SvQQgOlVSwWfWPO16X/Lu1KUFEYAysS9Hxn7SJDNvUMyhvMA9Oa0ICe3Ozv/8sEIQBn60E2N9c50paTxGx9jBCDf+hkByJdh0yRGAHrPm8QRAFOTc/pSA8f6yw4jAGXozx8Zt0Ap7eHk/u47CwB/THowTOd2YedfnhgBKGdm7sCb135Opv82aUyXCYwAMALACEC/20r4CICpyQKdv3r99MuVcWHeFaDkUQCgg65r2SpMd/5E0rEbHqEAUAD6zrBpEgWg97wJKAAm/V7p9BdWf2Xr1/MuiLJBAcAmB96w+ghzwc8k25oC0HsKBaDHPBSA3vPGuwAsN6evNXxtxrV5F0DZ4RwAbPKnj024q7PN3m6yq5T/dQlA8pik69pzqZ3Y+aMrRgCQ14HXr3l/6PQLSdt1fZwRgK7rz7Ncni8YAeg+lRGA/hINJle/IwALzenkhrO4gQ96YwQAef3phPEP1tS17i6z/5HU6TsPgMI5qcNJ369OB29n54++MAKAAX3wpqbtnOW+K1M9IwBd159nuTxfMALQfSojAP0lGkyuXsn+kg51+rJvzHgmz6qBTSgAKNgB1zceEDq71ElvpwBQACgAeeb1WwBeMGdfWXXWzN/nWSXQC4cAULC/nDDuL+FW43Z35k6WtMp3HgCSpDUyfWPl+uZd2PmjGIwAYFAOmr92QrYz/JakL5qU7jqNEYDuXzAC0H0qIwD9JSoqV1bmfhVk0+cuO3urlXlWA/SLAoAhOfCGVW/LWvoSyQ7Z+BgFoPsXFIDuUykA/SUqNJe7z6V0+vIzpz2dZ3GgIBQADIsP/nb14XLuOybtRgHo/gUFoPtUCkB/iQbM9YSZO2/l16bdk2cxoCgUAAwfM7f/jWsOl7kLzGz3bpN6zUsB6HPZLt9QADbPUdYFwOkZF9oFy86a/js5l28RoGicBIjh45zd97EJd73/pXF7OmfzJL3gOxKQbO55M/vk8unTdl32tRkL2PljODECgBGTyVjw4NzVx8l0YSg3t9tERgD6XrbLN4wAbJ6jzEYAFkt20fLm6b9SxmXzzAIMGQUAI26PK61iTG3jR0Nn33LSbEkUAAoABSBfIqfXzOySusqOn7/85bnteVYDDBsKACJzyD1W1bp6zaclO1Pm5lIA+li2yzcUgM1zlHYBsBecdMmE5uZfP5PZqSPP4sCwowAgcpmMBffPXnOYAvdlmR3QdRoFoPs3FIDNc5RoAXjcnF22bNr06zXP5fIsBowYCgC8et91je8IXHi6TB+VlKYAdP+GArB5jhIqAKGT7pHLXbT0KzMfzjMrEAkKAGLh/dc2znJB7nQz9xlJoygA+ZemAPS1/jzril8BaJHT9a4zuGTp17fmEzLwjgKAWPngb5omdqayn1doX5I0RaIA9L9+CkDebH3m81IAlpm5y1OB/XzJmdNW54kMeEEBQCzVz7fUytaG/ULnTjLpWEmprtMpAH0sl3f9FIDN30ZWAEKZ3edccNWU0ctuf/zkPTvzRAW8ogAg9vb6zaqtU0HwcWf2eUkzJQoABaDn+vOsy08BWGrSdbkwd+Xys2YuyhMPiA0KAJIjY8E+sxr2D5w7KTQdLali4yQKQH/rpwBs/nZECkBOsvtlwVVvrNv6Ni7cg6SgACCR9r1mxZRskP6kFH5OcnMoAP2tnwKw+dthLQCvy+mGMEj9dOlpU1/LEwWINQoAki1jwT6z17zXTPMkO17SVpIoABSAkSkATktl7neh0/ylp099mGvzI8koACgdb5UByeot1DyTTek5CwWg5/r7yUEB2KjBTPeEcguWNk29lyF+lAoKAErTW2UgDMN6SR+WtKVEAei9/n5ylHcBWGPS3YG5BZNHvfkHzuJHKaIAoOTtcaVVVFau/qALrN5Mh0qaQgHoZ9kBMmyaVHoF4E0zu0eBLXi9cdpfeaePUkcBQNnZ+9cNO5nZ4eZ0gEzvN6lMn4/dAAACqUlEQVSy5zwUgL4zbJqU/AKQM+lJmd2tIHXXa1/e6gmO6aOcUABQ1na5dtmo2lxqf2fB4ebsEEnTJApAfxk2TUpmAVjhpP8NpbsD67xz8RmzGvOsAigLFACgi3ddvXzXIEgdbKaDJHu3pNqN0ygAPeZJRgFYL+kROf3RWfiHRadPeyrPIkBZogAAfdg3Y+mWmau3D8Jwb5n2Maf3S5ohiQKQZ+GYFIBlofSYc/p7YO6hwLU8+vKX57bnWT1Q9igAQBH2vnrl1M7A9nZhsE/obG+ZdpcUbJxOAej+wMgXAFso6SEp+Hsq5x56+Ywpz3IcHygMBQAYgn1+2ji+raZjL5cLdpVs19BpZydtJ1N6wxwUgJ5TB/kzZE16QU5PK3RPucA9mcu2/YNj+MDgUQCAYbbHlVYRuNXbhUFuR2e2kwVuD5l2lDR74zwUAPX3M6yR9KyZHpfpGZOe7cjlHl9y5rTWPHEBDBIFAIjI7r96c7JCt0tgbjtTMEuymdpwd8NZkiaVWQFYqVCLnWyRuWCxOS02cy+kKsOnXjx56qo8sQAMMwoAEAM7XbFidKoqnJlWapaZzTKzmYGCWaZwuklbSJooqSYhBWC9pAaZVpjcazItNuUWWaDFFUFqURAGi585ZYvmPJsGECEKAJAQe1y5tLa9wiamsxUTFdrkMLCJzoJJJptoziY6cxNlmiintEnjJFXINFqyGslVd3kPXiNTtdRtp90mudbNj1mbTK0mNUvWKadGZ8pK1hDKNcipwZlWKXQNCtyqwDpXtck1jEu7hsdPnro+wl8LAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEun/Af3OJlev0ZvTAAAAAElFTkSuQmCC",
-};
diff --git a/mod_examples/add_building_flipper.js b/mod_examples/add_building_flipper.js
deleted file mode 100644
index 03442499..00000000
--- a/mod_examples/add_building_flipper.js
+++ /dev/null
@@ -1,130 +0,0 @@
-// @ts-nocheck
-const METADATA = {
- website: "https://tobspr.io",
- author: "tobspr",
- name: "Mod Example: Add a flipper building",
- version: "1",
- id: "add-building-extended",
- description:
- "Shows how to add a new building with logic, in this case it flips/mirrors shapez from top to down",
- minimumGameVersion: ">=1.5.0",
-};
-
-// Declare a new type of item processor
-shapez.enumItemProcessorTypes.flipper = "flipper";
-
-// For now, flipper always has the same speed
-shapez.MOD_ITEM_PROCESSOR_SPEEDS.flipper = () => 10;
-
-// Declare a handler for the processor so we define the "flip" operation
-shapez.MOD_ITEM_PROCESSOR_HANDLERS.flipper = function (payload) {
- const shapeDefinition = payload.items.get(0).definition;
-
- // Flip bottom with top on a new, cloned item (NEVER modify the incoming item!)
- const newLayers = shapeDefinition.getClonedLayers();
- newLayers.forEach(layer => {
- const tr = layer[shapez.TOP_RIGHT];
- const br = layer[shapez.BOTTOM_RIGHT];
- const bl = layer[shapez.BOTTOM_LEFT];
- const tl = layer[shapez.TOP_LEFT];
-
- layer[shapez.BOTTOM_LEFT] = tl;
- layer[shapez.BOTTOM_RIGHT] = tr;
-
- layer[shapez.TOP_LEFT] = bl;
- layer[shapez.TOP_RIGHT] = br;
- });
-
- const newDefinition = new shapez.ShapeDefinition({ layers: newLayers });
- payload.outItems.push({
- item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(newDefinition),
- });
-};
-
-// Create the building
-class MetaModFlipperBuilding extends shapez.ModMetaBuilding {
- constructor() {
- super("modFlipperBuilding");
- }
-
- static getAllVariantCombinations() {
- return [
- {
- name: "Flipper",
- description: "Flipps/Mirrors shapez from top to bottom",
- variant: shapez.defaultBuildingVariant,
-
- regularImageBase64: RESOURCES["flipper.png"],
- blueprintImageBase64: RESOURCES["flipper.png"],
- tutorialImageBase64: RESOURCES["flipper.png"],
- },
- ];
- }
-
- getSilhouetteColor() {
- return "red";
- }
-
- getAdditionalStatistics(root) {
- const speed = root.hubGoals.getProcessorBaseSpeed(shapez.enumItemProcessorTypes.flipper);
- return [[shapez.T.ingame.buildingPlacement.infoTexts.speed, shapez.formatItemsPerSecond(speed)]];
- }
-
- getIsUnlocked(root) {
- return true;
- }
-
- setupEntityComponents(entity) {
- // Accept shapes from the bottom
- entity.addComponent(
- new shapez.ItemAcceptorComponent({
- slots: [
- {
- pos: new shapez.Vector(0, 0),
- direction: shapez.enumDirection.bottom,
- filter: "shape",
- },
- ],
- })
- );
-
- // Process those shapes with tye processor type "flipper" (which we added above)
- entity.addComponent(
- new shapez.ItemProcessorComponent({
- inputsPerCharge: 1,
- processorType: shapez.enumItemProcessorTypes.flipper,
- })
- );
-
- // Eject the result to the top
- entity.addComponent(
- new shapez.ItemEjectorComponent({
- slots: [{ pos: new shapez.Vector(0, 0), direction: shapez.enumDirection.top }],
- })
- );
- }
-}
-
-class Mod extends shapez.Mod {
- init() {
- // Register the new building
- this.modInterface.registerNewBuilding({
- metaClass: MetaModFlipperBuilding,
- buildingIconBase64: RESOURCES["flipper.png"],
- });
-
- // Add it to the regular toolbar
- this.modInterface.addNewBuildingToToolbar({
- toolbar: "regular",
- location: "primary",
- metaClass: MetaModFlipperBuilding,
- });
- }
-}
-
-////////////////////////////////////////////////////////////////////////
-
-const RESOURCES = {
- "flipper.png":
- "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAYAAABccqhmAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyZpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDcuMS1jMDAwIDc5LmRhYmFjYmIsIDIwMjEvMDQvMTQtMDA6Mzk6NDQgICAgICAgICI+IDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+IDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bXA6Q3JlYXRvclRvb2w9IkFkb2JlIFBob3Rvc2hvcCAyMy4wIChNYWNpbnRvc2gpIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOkZDMkFGQkY5NkUyQTExRUM5QUY0OTQyNUQyODU2NURGIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOkZDMkFGQkZBNkUyQTExRUM5QUY0OTQyNUQyODU2NURGIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6RkMyQUZCRjc2RTJBMTFFQzlBRjQ5NDI1RDI4NTY1REYiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6RkMyQUZCRjg2RTJBMTFFQzlBRjQ5NDI1RDI4NTY1REYiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz43izVKAAATMklEQVR42uzd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",
-};
diff --git a/mod_examples/base.js b/mod_examples/base.js
deleted file mode 100644
index f76ded9b..00000000
--- a/mod_examples/base.js
+++ /dev/null
@@ -1,20 +0,0 @@
-// @ts-nocheck
-const METADATA = {
- website: "https://tobspr.io",
- author: "tobspr",
- name: "Mod Example: Base",
- version: "1",
- id: "base",
- description: "The most basic mod",
- minimumGameVersion: ">=1.5.0",
-
- // You can specify this parameter if savegames will still work
- // after your mod has been uninstalled
- doesNotAffectSavegame: true,
-};
-
-class Mod extends shapez.Mod {
- init() {
- // Start the modding here
- }
-}
diff --git a/mod_examples/buildings_have_cost.js b/mod_examples/buildings_have_cost.js
deleted file mode 100644
index 3dae84ae..00000000
--- a/mod_examples/buildings_have_cost.js
+++ /dev/null
@@ -1,89 +0,0 @@
-// @ts-nocheck
-const METADATA = {
- website: "https://tobspr.io",
- author: "tobspr",
- name: "Mod Example: Patch Methods",
- version: "1",
- id: "patch-methods",
- description: "Shows how to patch existing methods to change the game by making the belts cost shapes",
- minimumGameVersion: ">=1.5.0",
-};
-
-class Mod extends shapez.Mod {
- init() {
- // Define our currency
- const CURRENCY = "CyCyCyCy:--------:CuCuCuCu";
-
- // Make sure the currency is always pinned
- this.modInterface.runAfterMethod(shapez.HUDPinnedShapes, "rerenderFull", function () {
- this.internalPinShape({
- key: CURRENCY,
- canUnpin: false,
- className: "currency",
- });
- });
-
- // Style it
- this.modInterface.registerCss(`
- #ingame_HUD_PinnedShapes .shape.currency::after {
- content: " ";
- position: absolute;
- display: inline-block;
- width: $scaled(8px);
- height: $scaled(8px);
- top: $scaled(4px);
- left: $scaled(-7px);
- background: url('${RESOURCES["currency.png"]}') center center / contain no-repeat;
- }
-
- .currencyIcon {
- display: inline-block;
- vertical-align: middle;
- background: url('${RESOURCES["currency.png"]}') center center / contain no-repeat;
- }
-
- .currencyIcon.small {
- width: $scaled(11px);
- height: $scaled(11px);
- }
- `);
-
- // Make the player start with some currency
- this.modInterface.runAfterMethod(shapez.GameCore, "initNewGame", function () {
- this.root.hubGoals.storedShapes[CURRENCY] = 100;
- });
-
- // Make belts have a cost
- this.modInterface.replaceMethod(shapez.MetaBeltBuilding, "getAdditionalStatistics", function (
- $original,
- [root, variant]
- ) {
- const oldStats = $original(root, variant);
- oldStats.push(["Cost", "1 x "]);
- return oldStats;
- });
-
- // Only allow placing an entity when there is enough currency
- this.modInterface.replaceMethod(shapez.GameLogic, "checkCanPlaceEntity", function (
- $original,
- [entity, options]
- ) {
- const storedCurrency = this.root.hubGoals.storedShapes[CURRENCY] || 0;
- return storedCurrency > 0 && $original(entity, options);
- });
-
- // Take shapes when placing a building
- this.modInterface.replaceMethod(shapez.GameLogic, "tryPlaceBuilding", function ($original, args) {
- const result = $original(...args);
- if (result && result.components.Belt) {
- this.root.hubGoals.storedShapes[CURRENCY]--;
- }
- return result;
- });
- }
-}
-
-const RESOURCES = {
- "currency.png":
- "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAACXBIWXMAAAIAAAACAAF+ftPjAAAFwWlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNy4xLWMwMDAgNzkuZGFiYWNiYiwgMjAyMS8wNC8xNC0wMDozOTo0NCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iIHhtbG5zOnBob3Rvc2hvcD0iaHR0cDovL25zLmFkb2JlLmNvbS9waG90b3Nob3AvMS4wLyIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0RXZ0PSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VFdmVudCMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIDIzLjAgKE1hY2ludG9zaCkiIHhtcDpDcmVhdGVEYXRlPSIyMDIyLTAxLTE2VDE2OjAzOjE1KzAxOjAwIiB4bXA6TW9kaWZ5RGF0ZT0iMjAyMi0wMS0xNlQxNjowNDowMyswMTowMCIgeG1wOk1ldGFkYXRhRGF0ZT0iMjAyMi0wMS0xNlQxNjowNDowMyswMTowMCIgZGM6Zm9ybWF0PSJpbWFnZS9wbmciIHBob3Rvc2hvcDpDb2xvck1vZGU9IjMiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6M2IxMTM4ZjEtNzdmMi00MzcyLTg4ZDktZTgzN2I4NzlkNGUwIiB4bXBNTTpEb2N1bWVudElE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",
-};
diff --git a/mod_examples/class_extensions.js b/mod_examples/class_extensions.js
deleted file mode 100644
index ace5aae9..00000000
--- a/mod_examples/class_extensions.js
+++ /dev/null
@@ -1,32 +0,0 @@
-// @ts-nocheck
-const METADATA = {
- website: "https://tobspr.io",
- author: "tobspr",
- name: "Mod Example: Class Extensions",
- version: "1",
- id: "class-extensions",
- description: "Shows how to extend builtin classes",
- minimumGameVersion: ">=1.5.0",
-};
-
-const BeltExtension = ({ $super, $old }) => ({
- getShowWiresLayerPreview() {
- // Access the old method
- return !$old.getShowWiresLayerPreview();
- },
-
- getIsReplaceable(variant, rotationVariant) {
- // Instead of super, use $super
- return $super.getIsReplaceable.call(this, variant, rotationVariant);
- },
-
- getIsRemoveable() {
- return false;
- },
-});
-
-class Mod extends shapez.Mod {
- init() {
- this.modInterface.extendClass(shapez.MetaBeltBuilding, BeltExtension);
- }
-}
diff --git a/mod_examples/custom_css.js b/mod_examples/custom_css.js
deleted file mode 100644
index 0d28fda7..00000000
--- a/mod_examples/custom_css.js
+++ /dev/null
@@ -1,44 +0,0 @@
-// @ts-nocheck
-const METADATA = {
- website: "https://tobspr.io",
- author: "tobspr",
- name: "Mod Example: Add custom CSS",
- version: "1",
- id: "custom-css",
- description: "Shows how to add custom css",
- minimumGameVersion: ">=1.5.0",
-
- // You can specify this parameter if savegames will still work
- // after your mod has been uninstalled
- doesNotAffectSavegame: true,
-};
-
-class Mod extends shapez.Mod {
- init() {
- // Notice that, since the UI is scaled dynamically, every pixel value
- // should be wrapped in '$scaled()' (see below)
-
- this.modInterface.registerCss(`
- * {
- font-family: "Comic Sans", "Comic Sans MS", "ComicSans", Tahoma !important;
- }
-
- #state_MainMenuState {
- background: #9dc499 url('${RESOURCES["cat.png"]}') top left repeat !important;
- }
-
- #state_MainMenuState .fullscreenBackgroundVideo {
- display: none !important;
- }
-
- #state_MainMenuState .mainContainer, #state_MainMenuState .modsOverview {
- border: $scaled(5px) solid #000 !important;
- }
- `);
- }
-}
-
-const RESOURCES = {
- "cat.png":
- "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAYAAADDPmHLAAAACXBIWXMAAAGxAAABsQFhmCgOAAAE8mlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNy4xLWMwMDAgNzkuZGFiYWNiYiwgMjAyMS8wNC8xNC0wMDozOTo0NCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iIHhtbG5zOnBob3Rvc2hvcD0iaHR0cDovL25zLmFkb2JlLmNvbS9waG90b3Nob3AvMS4wLyIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0RXZ0PSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VFdmVudCMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIDIzLjAgKE1hY2ludG9zaCkiIHhtcDpDcmVhdGVEYXRlPSIyMDIyLTAxLTE1VDEzOjI3OjU1KzAxOjAwIiB4bXA6TW9kaWZ5RGF0ZT0iMjAyMi0wMS0xNVQxMzozMDowMyswMTowMCIgeG1wOk1ldGFkYXRhRGF0ZT0iMjAyMi0wMS0xNVQxMzozMDowMyswMTowMCIgZGM6Zm9ybWF0PSJpbWFnZS9wbmciIHBob3Rvc2hvcDpDb2xvck1vZGU9IjMiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NTI2OGI2OWUtYTQ2Ni00YmNkLWJjNGYtM2VlNmUwOGI2NzA2IiB4bXBNTTpEb2N1bWVudElE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",
-};
diff --git a/mod_examples/custom_drawing.js b/mod_examples/custom_drawing.js
deleted file mode 100644
index 2dccab2d..00000000
--- a/mod_examples/custom_drawing.js
+++ /dev/null
@@ -1,63 +0,0 @@
-// @ts-nocheck
-const METADATA = {
- website: "https://tobspr.io",
- author: "tobspr",
- name: "Mod Example: custom drawing",
- version: "1",
- id: "base",
- description: "Displays an indicator on every item processing building when its working",
- minimumGameVersion: ">=1.5.0",
-
- // You can specify this parameter if savegames will still work
- // after your mod has been uninstalled
- doesNotAffectSavegame: true,
-};
-
-class ItemProcessorStatusGameSystem extends shapez.GameSystem {
- drawChunk(parameters, chunk) {
- const contents = chunk.containedEntitiesByLayer.regular;
- for (let i = 0; i < contents.length; ++i) {
- const entity = contents[i];
- const processorComp = entity.components.ItemProcessor;
- if (!processorComp) {
- continue;
- }
-
- const staticComp = entity.components.StaticMapEntity;
-
- const context = parameters.context;
- const center = staticComp.getTileSpaceBounds().getCenter().toWorldSpace();
-
- // Culling for better performance
- if (parameters.visibleRect.containsCircle(center.x, center.y, 40)) {
- // Circle
- context.fillStyle = processorComp.ongoingCharges.length === 0 ? "#aaa" : "#53cf47";
- context.strokeStyle = "#000";
- context.lineWidth = 1;
-
- context.beginCircle(center.x + 5, center.y + 5, 4);
- context.fill();
- context.stroke();
- }
- }
- }
-}
-
-class Mod extends shapez.Mod {
- init() {
- // Register our game system
- this.modInterface.registerGameSystem({
- id: "item_processor_status",
- systemClass: ItemProcessorStatusGameSystem,
-
- // Specify at which point the update method will be called,
- // in this case directly before the belt system. You can use
- // before: "end" to make it the last system
- before: "belt",
-
- // Specify where our drawChunk method should be called, check out
- // map_chunk_view
- drawHooks: ["staticAfter"],
- });
- }
-}
diff --git a/mod_examples/custom_keybinding.js b/mod_examples/custom_keybinding.js
deleted file mode 100644
index 0109833c..00000000
--- a/mod_examples/custom_keybinding.js
+++ /dev/null
@@ -1,32 +0,0 @@
-// @ts-nocheck
-const METADATA = {
- website: "https://tobspr.io",
- author: "tobspr",
- name: "Mod Example: Custom Keybindings",
- version: "1",
- id: "base",
- description: "Shows how to add a new keybinding",
- minimumGameVersion: ">=1.5.0",
-
- // You can specify this parameter if savegames will still work
- // after your mod has been uninstalled
- doesNotAffectSavegame: true,
-};
-
-class Mod extends shapez.Mod {
- init() {
- // Register keybinding
- this.modInterface.registerIngameKeybinding({
- id: "demo_mod_binding",
- keyCode: shapez.keyToKeyCode("F"),
- translation: "Do something (always with SHIFT)",
- modifiers: {
- shift: true,
- },
- handler: root => {
- this.dialogs.showInfo("Mod Message", "It worked!");
- return shapez.STOP_PROPAGATION;
- },
- });
- }
-}
diff --git a/mod_examples/custom_sub_shapes.js b/mod_examples/custom_sub_shapes.js
deleted file mode 100644
index 3aea03cf..00000000
--- a/mod_examples/custom_sub_shapes.js
+++ /dev/null
@@ -1,46 +0,0 @@
-// @ts-nocheck
-const METADATA = {
- website: "https://tobspr.io",
- author: "tobspr",
- name: "Mod Example: Custom Sub Shapes",
- version: "1",
- id: "custom-sub-shapes",
- description: "Shows how to add custom sub shapes",
- minimumGameVersion: ">=1.5.0",
-};
-
-class Mod extends shapez.Mod {
- init() {
- // Add a new type of sub shape ("Line", short code "L")
- this.modInterface.registerSubShapeType({
- id: "line",
- shortCode: "L",
-
- // Make it spawn on the map
- weightComputation: distanceToOriginInChunks =>
- Math.round(20 + Math.max(Math.min(distanceToOriginInChunks, 30), 0)),
-
- // This defines how to draw it
- draw: ({ context, quadrantSize, layerScale }) => {
- const quadrantHalfSize = quadrantSize / 2;
- context.beginPath();
- context.moveTo(-quadrantHalfSize, quadrantHalfSize);
- context.arc(
- -quadrantHalfSize,
- quadrantHalfSize,
- quadrantSize * layerScale,
- -Math.PI * 0.25,
- 0
- );
- context.closePath();
- context.fill();
- context.stroke();
- },
- });
-
- // Modify the goal of the first level to add our goal
- this.signals.modifyLevelDefinitions.add(definitions => {
- definitions[0].shape = "LuLuLuLu";
- });
- }
-}
diff --git a/mod_examples/custom_theme.js b/mod_examples/custom_theme.js
deleted file mode 100644
index a70d949f..00000000
--- a/mod_examples/custom_theme.js
+++ /dev/null
@@ -1,99 +0,0 @@
-// @ts-nocheck
-const METADATA = {
- website: "https://tobspr.io",
- author: "tobspr",
- name: "Mod Example: Custom Game Theme",
- version: "1",
- id: "custom-theme",
- description: "Shows how to add a custom game theme",
- minimumGameVersion: ">=1.5.0",
-
- // You can specify this parameter if savegames will still work
- // after your mod has been uninstalled
- doesNotAffectSavegame: true,
-};
-
-class Mod extends shapez.Mod {
- init() {
- this.modInterface.registerGameTheme({
- id: "my-theme",
- name: "My fancy theme",
- theme: RESOURCES["my-theme.json"],
- });
- }
-}
-
-const RESOURCES = {
- "my-theme.json": {
- map: {
- background: "#abc",
- grid: "#ccc",
- gridLineWidth: 1,
-
- selectionOverlay: "rgba(74, 163, 223, 0.7)",
- selectionOutline: "rgba(74, 163, 223, 0.5)",
- selectionBackground: "rgba(74, 163, 223, 0.2)",
-
- chunkBorders: "rgba(0, 30, 50, 0.03)",
-
- directionLock: {
- regular: {
- color: "rgb(74, 237, 134)",
- background: "rgba(74, 237, 134, 0.2)",
- },
- wires: {
- color: "rgb(74, 237, 134)",
- background: "rgba(74, 237, 134, 0.2)",
- },
- error: {
- color: "rgb(255, 137, 137)",
- background: "rgba(255, 137, 137, 0.2)",
- },
- },
-
- colorBlindPickerTile: "rgba(50, 50, 50, 0.4)",
-
- resources: {
- shape: "#eaebec",
- red: "#ffbfc1",
- green: "#cbffc4",
- blue: "#bfdaff",
- },
-
- chunkOverview: {
- empty: "#a6afbb",
- filled: "#c5ccd6",
- beltColor: "#777",
- },
-
- wires: {
- overlayColor: "rgba(97, 161, 152, 0.75)",
- previewColor: "rgb(97, 161, 152, 0.4)",
- highlightColor: "rgba(72, 137, 255, 1)",
- },
-
- connectedMiners: {
- overlay: "rgba(40, 50, 60, 0.5)",
- textColor: "#fff",
- textColorCapped: "#ef5072",
- background: "rgba(40, 50, 60, 0.8)",
- },
-
- zone: {
- borderSolid: "rgba(23, 192, 255, 1)",
- outerColor: "rgba(240, 240, 255, 0.5)",
- },
- },
-
- items: {
- outline: "#55575a",
- outlineWidth: 0.75,
- circleBackground: "rgba(40, 50, 65, 0.1)",
- },
-
- shapeTooltip: {
- background: "#dee1ea",
- outline: "#54565e",
- },
- },
-};
diff --git a/mod_examples/mirrored_cutter.js b/mod_examples/mirrored_cutter.js
deleted file mode 100644
index ae457a8c..00000000
--- a/mod_examples/mirrored_cutter.js
+++ /dev/null
@@ -1,81 +0,0 @@
-// @ts-nocheck
-const METADATA = {
- website: "https://tobspr.io",
- author: "tobspr",
- name: "Mod Example: Mirrored Cutter Variant",
- version: "1",
- id: "mirrored-cutter",
- description: "Shows how to add new variants to existing buildings",
- minimumGameVersion: ">=1.5.0",
-};
-
-class Mod extends shapez.Mod {
- init() {
- shapez.enumCutterVariants.mirrored = "mirrored";
-
- this.modInterface.addVariantToExistingBuilding(
- shapez.MetaCutterBuilding,
- shapez.enumCutterVariants.mirrored,
- {
- name: "Cutter (Mirrored)",
- description: "A mirrored cutter",
-
- tutorialImageBase64: RESOURCES["cutter-mirrored.png"],
- regularSpriteBase64: RESOURCES["cutter-mirrored.png"],
- blueprintSpriteBase64: RESOURCES["cutter-mirrored.png"],
-
- dimensions: new shapez.Vector(2, 1),
-
- additionalStatistics(root) {
- const speed = root.hubGoals.getProcessorBaseSpeed(shapez.enumItemProcessorTypes.cutter);
- return [
- [
- shapez.T.ingame.buildingPlacement.infoTexts.speed,
- shapez.formatItemsPerSecond(speed),
- ],
- ];
- },
-
- isUnlocked(root) {
- return true;
- },
- }
- );
-
- // Extend instance methods
- this.modInterface.extendClass(shapez.MetaCutterBuilding, ({ $old }) => ({
- updateVariants(entity, rotationVariant, variant) {
- if (variant === shapez.enumCutterVariants.mirrored) {
- entity.components.ItemEjector.setSlots([
- { pos: new shapez.Vector(0, 0), direction: shapez.enumDirection.top },
- { pos: new shapez.Vector(1, 0), direction: shapez.enumDirection.top },
- ]);
- entity.components.ItemProcessor.type = shapez.enumItemProcessorTypes.cutter;
- entity.components.ItemAcceptor.setSlots([
- {
- pos: new shapez.Vector(1, 0),
- direction: shapez.enumDirection.bottom,
- filter: "shape",
- },
- ]);
- } else {
- // Since we are changing the ItemAcceptor slots, we should reset
- // it to the regular slots when we are not using our mirrored variant
- entity.components.ItemAcceptor.setSlots([
- {
- pos: new shapez.Vector(0, 0),
- direction: shapez.enumDirection.bottom,
- filter: "shape",
- },
- ]);
- $old.updateVariants.bind(this)(entity, rotationVariant, variant);
- }
- },
- }));
- }
-}
-
-const RESOURCES = {
- "cutter-mirrored.png":
- "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAYAAAADACAYAAAAN6LRnAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA4VpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDcuMS1jMDAwIDc5LmRhYmFjYmIsIDIwMjEvMDQvMTQtMDA6Mzk6NDQgICAgICAgICI+IDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+IDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIiB4bWxuczpzdFJlZj0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlUmVmIyIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ9InhtcC5kaWQ6NGQwZTY5MmYtOTRlNy00MDQyLWFjY2ItNmU3OGEzMGU1N2ZjIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOkIwOTY4MzA0N0I4QTExRUNCQzRERjNBOEI5ODYyRkJBIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOkIwOTY4MzAzN0I4QTExRUNCQzRERjNBOEI5ODYyRkJBIiB4bXA6Q3JlYXRvclRvb2w9IkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE5IChXaW5kb3dzKSI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOmRmNmU1ODFjLTQ3ZDItYzE0OS05MmQzLWRhZDMyMTg5YTA3MiIgc3RSZWY6ZG9jdW1lbnRJRD0iYWRvYmU6ZG9jaWQ6cGhvdG9zaG9wOjk3MDYxZWYyLTY2ZGMtZjI0Zi1iZTMy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",
-};
diff --git a/mod_examples/mod_settings.js b/mod_examples/mod_settings.js
deleted file mode 100644
index b87c138b..00000000
--- a/mod_examples/mod_settings.js
+++ /dev/null
@@ -1,32 +0,0 @@
-// @ts-nocheck
-const METADATA = {
- website: "https://tobspr.io",
- author: "tobspr",
- name: "Mod Example: Mod Settings",
- version: "1",
- id: "mod-settings",
- description: "Shows how to add settings to your mod",
- minimumGameVersion: ">=1.5.0",
-
- settings: {
- timesLaunched: 0,
- },
-};
-
-class Mod extends shapez.Mod {
- init() {
- // Increment the setting every time we launch the mod
- this.settings.timesLaunched++;
- this.saveSettings();
-
- // Show a dialog in the main menu with the settings
- this.signals.stateEntered.add(state => {
- if (state instanceof shapez.MainMenuState) {
- this.dialogs.showInfo(
- "Welcome back",
- `You have launched this mod ${this.settings.timesLaunched} times`
- );
- }
- });
- }
-}
diff --git a/mod_examples/modify_existing_building.js b/mod_examples/modify_existing_building.js
deleted file mode 100644
index b09f5a20..00000000
--- a/mod_examples/modify_existing_building.js
+++ /dev/null
@@ -1,27 +0,0 @@
-// @ts-nocheck
-const METADATA = {
- website: "https://tobspr.io",
- author: "tobspr",
- name: "Mod Example: Modify existing building",
- version: "1",
- id: "modify-existing-building",
- description: "Shows how to modify an existing building",
- minimumGameVersion: ">=1.5.0",
-};
-
-class Mod extends shapez.Mod {
- init() {
- // Make Rotator always unlocked
- this.modInterface.replaceMethod(shapez.MetaRotaterBuilding, "getIsUnlocked", function () {
- return true;
- });
-
- // Add some custom stats to the info panel when selecting the building
- this.modInterface.replaceMethod(shapez.MetaRotaterBuilding, "getAdditionalStatistics", function (
- root,
- variant
- ) {
- return [["Awesomeness", 5]];
- });
- }
-}
diff --git a/mod_examples/modify_theme.js b/mod_examples/modify_theme.js
deleted file mode 100644
index de7f0ad2..00000000
--- a/mod_examples/modify_theme.js
+++ /dev/null
@@ -1,24 +0,0 @@
-// @ts-nocheck
-const METADATA = {
- website: "https://tobspr.io",
- author: "tobspr",
- name: "Mod Example: Modify Builtin Themes",
- version: "1",
- id: "modify-theme",
- description: "Shows how to modify builtin themes",
- minimumGameVersion: ">=1.5.0",
-
- // You can specify this parameter if savegames will still work
- // after your mod has been uninstalled
- doesNotAffectSavegame: true,
-};
-
-class Mod extends shapez.Mod {
- init() {
- shapez.THEMES.light.map.background = "#eee";
- shapez.THEMES.light.items.outline = "#000";
-
- shapez.THEMES.dark.map.background = "#245";
- shapez.THEMES.dark.items.outline = "#fff";
- }
-}
diff --git a/mod_examples/modify_ui.js b/mod_examples/modify_ui.js
deleted file mode 100644
index 4beb403d..00000000
--- a/mod_examples/modify_ui.js
+++ /dev/null
@@ -1,46 +0,0 @@
-// @ts-nocheck
-const METADATA = {
- website: "https://tobspr.io",
- author: "tobspr",
- name: "Mod Example: Modify UI",
- version: "1",
- id: "modify-ui",
- description: "Shows how to modify a builtin game state, in this case the main menu",
- minimumGameVersion: ">=1.5.0",
-
- // You can specify this parameter if savegames will still work
- // after your mod has been uninstalled
- doesNotAffectSavegame: true,
-};
-
-class Mod extends shapez.Mod {
- init() {
- // Add fancy sign to main menu
- this.signals.stateEntered.add(state => {
- if (state.key === "MainMenuState") {
- const element = document.createElement("div");
- element.id = "demo_mod_hello_world_element";
- document.body.appendChild(element);
-
- const button = document.createElement("button");
- button.classList.add("styledButton");
- button.innerText = "Hello!";
- button.addEventListener("click", () => {
- this.dialogs.showInfo("Mod Message", "Button clicked!");
- });
- element.appendChild(button);
- }
- });
-
- this.modInterface.registerCss(`
- #demo_mod_hello_world_element {
- position: absolute;
- top: calc(10px * var(--ui-scale));
- left: calc(10px * var(--ui-scale));
- color: red;
- z-index: 0;
- }
-
- `);
- }
-}
diff --git a/mod_examples/new_item_type.js b/mod_examples/new_item_type.js
deleted file mode 100644
index 104ef0a0..00000000
--- a/mod_examples/new_item_type.js
+++ /dev/null
@@ -1,149 +0,0 @@
-// @ts-nocheck
-const METADATA = {
- website: "https://tobspr.io",
- author: "tobspr",
- name: "Mod Example: New Item Type (Fluids)",
- version: "1",
- id: "new-item-type",
- description: "Shows how to add a new item type (fluid)",
- minimumGameVersion: ">=1.5.0",
-};
-
-// Define which fluid types there are
-const enumFluidType = {
- water: "water",
- oil: "oil",
-};
-
-// Define which color they should have on the map
-const fluidColors = {
- [enumFluidType.water]: "#477be7",
- [enumFluidType.oil]: "#bc483a",
-};
-
-// The fluid item class (also see ColorItem and ShapeItem)
-class FluidItem extends shapez.BaseItem {
- static getId() {
- return "fluid";
- }
-
- static getSchema() {
- return shapez.types.enum(enumFluidType);
- }
-
- serialize() {
- return this.fluidType;
- }
-
- deserialize(data) {
- this.fluidType = data;
- }
-
- getItemType() {
- return "fluid";
- }
-
- /**
- * @returns {string}
- */
- getAsCopyableKey() {
- return this.fluidType;
- }
-
- /**
- * @param {BaseItem} other
- */
- equalsImpl(other) {
- return this.fluidType === /** @type {FluidItem} */ (other).fluidType;
- }
-
- /**
- * @param {enumFluidType} fluidType
- */
- constructor(fluidType) {
- super();
- this.fluidType = fluidType;
- }
-
- getBackgroundColorAsResource() {
- return fluidColors[this.fluidType];
- }
-
- /**
- * Draws the item to a canvas
- * @param {CanvasRenderingContext2D} context
- * @param {number} size
- */
- drawFullSizeOnCanvas(context, size) {
- if (!this.cachedSprite) {
- this.cachedSprite = shapez.Loader.getSprite(`sprites/fluids/${this.fluidType}.png`);
- }
- this.cachedSprite.drawCentered(context, size / 2, size / 2, size);
- }
-
- /**
- * @param {number} x
- * @param {number} y
- * @param {number} diameter
- * @param {DrawParameters} parameters
- */
- drawItemCenteredClipped(x, y, parameters, diameter = shapez.globalConfig.defaultItemDiameter) {
- const realDiameter = diameter * 0.6;
- if (!this.cachedSprite) {
- this.cachedSprite = shapez.Loader.getSprite(`sprites/fluids/${this.fluidType}.png`);
- }
- this.cachedSprite.drawCachedCentered(parameters, x, y, realDiameter);
- }
-}
-
-/**
- * Singleton instances.
- *
- * NOTICE: The game tries to instantiate as few instances as possible.
- * Which means that if you have two types of fluids in this case, there should
- * ONLY be 2 instances of FluidItem at *any* time.
- *
- * This works by having a map from fluid type to the FluidItem singleton.
- * Additionally, all items are and should be immutable.
- * @type {Object}
- */
-const FLUID_ITEM_SINGLETONS = {};
-
-for (const fluidType in enumFluidType) {
- FLUID_ITEM_SINGLETONS[fluidType] = new FluidItem(fluidType);
-}
-
-class Mod extends shapez.Mod {
- init() {
- // Register the sprites
- this.modInterface.registerSprite("sprites/fluids/oil.png", RESOURCES["oil.png"]);
- this.modInterface.registerSprite("sprites/fluids/water.png", RESOURCES["water.png"]);
-
- // Make the item spawn on the map
- this.modInterface.runAfterMethod(shapez.MapChunk, "generatePatches", function ({
- rng,
- chunkCenter,
- distanceToOriginInChunks,
- }) {
- // Generate a simple patch
- // ALWAYS use rng and NEVER use Math.random() otherwise the map will look different
- // every time you resume the game
- if (rng.next() > 0.8) {
- const fluidType = rng.choice(Array.from(Object.keys(enumFluidType)));
- this.internalGeneratePatch(rng, 4, FLUID_ITEM_SINGLETONS[fluidType]);
- }
- });
-
- this.modInterface.registerItem(FluidItem, itemData => FLUID_ITEM_SINGLETONS[itemData]);
- }
-}
-
-///////////////////////////////////////
-
-const RESOURCES = {
- "oil.png":
- "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAYAAADDPmHLAAAACXBIWXMAAAOxAAADsQH1g+1JAAAE8mlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNy4xLWMwMDAgNzkuZGFiYWNiYiwgMjAyMS8wNC8xNC0wMDozOTo0NCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iIHhtbG5zOnBob3Rvc2hvcD0iaHR0cDovL25zLmFkb2JlLmNvbS9waG90b3Nob3AvMS4wLyIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0RXZ0PSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VFdmVudCMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIDIzLjAgKE1hY2ludG9zaCkiIHhtcDpDcmVhdGVEYXRlPSIyMDIyLTAxLTE3VDEyOjIyOjUxKzAxOjAwIiB4bXA6TW9kaWZ5RGF0ZT0iMjAyMi0wMS0xN1QxMjoyMzozMCswMTowMCIgeG1wOk1ldGFkYXRhRGF0ZT0iMjAyMi0wMS0xN1QxMjoyMzozMCswMTowMCIgZGM6Zm9ybWF0PSJpbWFnZS9wbmciIHBob3Rvc2hvcDpDb2xvck1vZGU9IjMiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6Y2EzMGQxMDEtZWU5Yy00Mzc2LTgyOGEtZDM5ZmFkN2ViZTYyIiB4bXBNTTpEb2N1bWVudElE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",
-
- "water.png":
- "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAYAAADDPmHLAAAACXBIWXMAAATEAAAExAE8zNSDAAAE8mlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNy4xLWMwMDAgNzkuZGFiYWNiYiwgMjAyMS8wNC8xNC0wMDozOTo0NCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iIHhtbG5zOnBob3Rvc2hvcD0iaHR0cDovL25zLmFkb2JlLmNvbS9waG90b3Nob3AvMS4wLyIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0RXZ0PSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VFdmVudCMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIDIzLjAgKE1hY2ludG9zaCkiIHhtcDpDcmVhdGVEYXRlPSIyMDIyLTAxLTE3VDEyOjI0OjA3KzAxOjAwIiB4bXA6TW9kaWZ5RGF0ZT0iMjAyMi0wMS0xN1QxMjoyNTowNiswMTowMCIgeG1wOk1ldGFkYXRhRGF0ZT0iMjAyMi0wMS0xN1QxMjoyNTowNiswMTowMCIgZGM6Zm9ybWF0PSJpbWFnZS9wbmciIHBob3Rvc2hvcDpDb2xvck1vZGU9IjMiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NmU3YjM1ZDctOTAyNi00ZjNlLTkxNGItZTc0NjJhMzM3MGE4IiB4bXBNTTpEb2N1bWVudElE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",
-};
diff --git a/mod_examples/notification_blocks.js b/mod_examples/notification_blocks.js
deleted file mode 100644
index 23f95943..00000000
--- a/mod_examples/notification_blocks.js
+++ /dev/null
@@ -1,314 +0,0 @@
-// @ts-nocheck
-const METADATA = {
- website: "https://tobspr.io",
- author: "tobspr",
- name: "Mod Example: Notification Blocks",
- version: "1",
- id: "notification-blocks",
- description:
- "Adds a new building to the wires layer, 'Notification Blocks' which show a custom notification when they get a truthy signal.",
-
- minimumGameVersion: ">=1.5.0",
-};
-
-////////////////////////////////////////////////////////////////////////
-// This is the component storing which text the block should show as
-// a notification.
-class NotificationBlockComponent extends shapez.Component {
- static getId() {
- return "NotificationBlock";
- }
-
- static getSchema() {
- // Here you define which properties should be saved to the savegame
- // and get automatically restored
- return {
- notificationText: shapez.types.string,
- lastStoredInput: shapez.types.bool,
- };
- }
-
- constructor() {
- super();
- this.notificationText = "Test";
- this.lastStoredInput = false;
- }
-}
-
-////////////////////////////////////////////////////////////////////////
-// The game system to trigger notifications when the signal changes
-class NotificationBlocksSystem extends shapez.GameSystemWithFilter {
- constructor(root) {
- // By specifying the list of components, `this.allEntities` will only
- // contain entities which have *all* of the specified components
- super(root, [NotificationBlockComponent]);
-
- // Ask for a notification text once an entity is placed
- this.root.signals.entityManuallyPlaced.add(entity => {
- const editorHud = this.root.hud.parts.notificationBlockEdit;
- if (editorHud) {
- editorHud.editNotificationText(entity, { deleteOnCancel: true });
- }
- });
- }
-
- update() {
- if (!this.root.gameInitialized) {
- // Do not start updating before the wires network was
- // computed to avoid dispatching all notifications
- return;
- }
-
- // Go over all notification blocks and check if the signal changed
- for (let i = 0; i < this.allEntities.length; ++i) {
- const entity = this.allEntities[i];
-
- // Compute if the bottom pin currently has a truthy input
- const pinsComp = entity.components.WiredPins;
- const network = pinsComp.slots[0].linkedNetwork;
-
- let currentInput = false;
-
- if (network && network.hasValue()) {
- const value = network.currentValue;
- if (value && shapez.isTruthyItem(value)) {
- currentInput = true;
- }
- }
-
- // If the value changed, show the notification if its truthy
- const notificationComp = entity.components.NotificationBlock;
- if (currentInput !== notificationComp.lastStoredInput) {
- notificationComp.lastStoredInput = currentInput;
- if (currentInput) {
- this.root.hud.signals.notification.dispatch(
- notificationComp.notificationText,
- shapez.enumNotificationType.info
- );
- }
- }
- }
- }
-}
-
-////////////////////////////////////////////////////////////////////////
-// The actual notification block building
-class MetaNotificationBlockBuilding extends shapez.ModMetaBuilding {
- constructor() {
- super("notification_block");
- }
-
- static getAllVariantCombinations() {
- return [
- {
- variant: shapez.defaultBuildingVariant,
- name: "Notification Block",
- description: "Shows a predefined notification on screen when receiving a truthy signal",
-
- regularImageBase64: RESOURCES["notification_block.png"],
- blueprintImageBase64: RESOURCES["notification_block.png"],
- tutorialImageBase64: RESOURCES["notification_block.png"],
- },
- ];
- }
-
- getSilhouetteColor() {
- return "#daff89";
- }
-
- getIsUnlocked(root) {
- return root.hubGoals.isRewardUnlocked(shapez.enumHubGoalRewards.reward_wires_painter_and_levers);
- }
-
- getLayer() {
- return "wires";
- }
-
- getDimensions() {
- return new shapez.Vector(1, 1);
- }
-
- getRenderPins() {
- // Do not show pin overlays since it would hide our building icon
- return false;
- }
-
- setupEntityComponents(entity) {
- // Accept logical input from the bottom
- entity.addComponent(
- new shapez.WiredPinsComponent({
- slots: [
- {
- pos: new shapez.Vector(0, 0),
- direction: shapez.enumDirection.bottom,
- type: shapez.enumPinSlotType.logicalAcceptor,
- },
- ],
- })
- );
-
- // Add your notification component to identify the building as a notification block
- entity.addComponent(new NotificationBlockComponent());
- }
-}
-
-////////////////////////////////////////////////////////////////////////
-// HUD Component to be able to edit notification blocks by clicking them
-class HUDNotificationBlockEdit extends shapez.BaseHUDPart {
- initialize() {
- this.root.camera.downPreHandler.add(this.downPreHandler, this);
- }
-
- /**
- * @param {Vector} pos
- * @param {enumMouseButton} button
- */
- downPreHandler(pos, button) {
- if (this.root.currentLayer !== "wires") {
- return;
- }
-
- const tile = this.root.camera.screenToWorld(pos).toTileSpace();
- const contents = this.root.map.getLayerContentXY(tile.x, tile.y, "wires");
- if (contents) {
- const notificationComp = contents.components.NotificationBlock;
- if (notificationComp) {
- if (button === shapez.enumMouseButton.left) {
- this.editNotificationText(contents, {
- deleteOnCancel: false,
- });
- return shapez.STOP_PROPAGATION;
- }
- }
- }
- }
-
- /**
- * Asks the player to enter a notification text
- * @param {Entity} entity
- * @param {object} param0
- * @param {boolean=} param0.deleteOnCancel
- */
- editNotificationText(entity, { deleteOnCancel = true }) {
- const notificationComp = entity.components.NotificationBlock;
- if (!notificationComp) {
- return;
- }
-
- // save the uid because it could get stale
- const uid = entity.uid;
-
- // create an input field to query the text
- const textInput = new shapez.FormElementInput({
- id: "notificationText",
- placeholder: "",
- defaultValue: notificationComp.notificationText,
- validator: val => val.length > 0,
- });
-
- // create the dialog & show it
- const dialog = new shapez.DialogWithForm({
- app: this.root.app,
- title: shapez.T.mods.notificationBlocks.dialogTitle,
- desc: shapez.T.mods.notificationBlocks.enterNotificationText,
- formElements: [textInput],
- buttons: ["cancel:bad:escape", "ok:good:enter"],
- closeButton: false,
- });
- this.root.hud.parts.dialogs.internalShowDialog(dialog);
-
- // When confirmed, set the text
- dialog.buttonSignals.ok.add(() => {
- if (!this.root || !this.root.entityMgr) {
- // Game got stopped
- return;
- }
-
- const entityRef = this.root.entityMgr.findByUid(uid, false);
- if (!entityRef) {
- // outdated
- return;
- }
-
- const notificationComp = entityRef.components.NotificationBlock;
- if (!notificationComp) {
- // no longer interesting
- return;
- }
-
- // set the text
- notificationComp.notificationText = textInput.getValue();
- });
-
- // When cancelled, destroy the entity again
- if (deleteOnCancel) {
- dialog.buttonSignals.cancel.add(() => {
- if (!this.root || !this.root.entityMgr) {
- // Game got stopped
- return;
- }
-
- const entityRef = this.root.entityMgr.findByUid(uid, false);
- if (!entityRef) {
- // outdated
- return;
- }
-
- const notificationComp = entityRef.components.NotificationBlock;
- if (!notificationComp) {
- // no longer interesting
- return;
- }
-
- this.root.logic.tryDeleteBuilding(entityRef);
- });
- }
- }
-}
-
-////////////////////////////////////////////////////////////////////////
-// The actual mod logic
-class Mod extends shapez.Mod {
- init() {
- // Register the component
- this.modInterface.registerComponent(NotificationBlockComponent);
-
- // Register the new building
- this.modInterface.registerNewBuilding({
- metaClass: MetaNotificationBlockBuilding,
- buildingIconBase64: RESOURCES["notification_block.png"],
- });
-
- // Add it to the regular toolbar
- this.modInterface.addNewBuildingToToolbar({
- toolbar: "wires",
- location: "secondary",
- metaClass: MetaNotificationBlockBuilding,
- });
-
- // Register our game system so we can dispatch the notifications
- this.modInterface.registerGameSystem({
- id: "notificationBlocks",
- systemClass: NotificationBlocksSystem,
- before: "constantSignal",
- });
-
- // Register our hud element to be able to edit the notification texts
- this.modInterface.registerHudElement("notificationBlockEdit", HUDNotificationBlockEdit);
-
- // This mod also supports translations
- this.modInterface.registerTranslations("en", {
- mods: {
- notificationBlocks: {
- enterNotificationText:
- "Enter the notification text to show once the signal switches from 0 to 1:",
- },
- },
- });
- }
-}
-
-const RESOURCES = {
- "notification_block.png":
- "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMAAAADACAYAAABS3GwHAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA4VpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDcuMS1jMDAwIDc5LmRhYmFjYmIsIDIwMjEvMDQvMTQtMDA6Mzk6NDQgICAgICAgICI+IDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+IDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIiB4bWxuczpzdFJlZj0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlUmVmIyIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ9InhtcC5kaWQ6NGQwZTY5MmYtOTRlNy00MDQyLWFjY2ItNmU3OGEzMGU1N2ZjIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjAyQTMyQTVGNzA1RTExRUNBQ0EzQTZCNEYxQjM5MkFBIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjAyQTMyQTVFNzA1RTExRUNBQ0EzQTZCNEYxQjM5MkFBIiB4bXA6Q3JlYXRvclRvb2w9IkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE5IChXaW5kb3dzKSI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjY3NDVhMzZlLTkyMWUtNDViYS04NDFjLWVjOWZjZTc0Y2MyNSIgc3RSZWY6ZG9jdW1lbnRJRD0iYWRvYmU6ZG9jaWQ6cGhvdG9zaG9wOjk3MDYxZWYyLTY2ZGMtZjI0Zi1iZTMy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",
-};
diff --git a/mod_examples/pasting.js b/mod_examples/pasting.js
deleted file mode 100644
index 698edeff..00000000
--- a/mod_examples/pasting.js
+++ /dev/null
@@ -1,23 +0,0 @@
-// @ts-nocheck
-const METADATA = {
- website: "https://tobspr.io",
- author: "tobspr",
- name: "Mod Example: Pasting",
- version: "1",
- id: "pasting",
- description: "Shows how to properly receive paste events ingame",
- minimumGameVersion: ">=1.5.0",
-};
-
-class Mod extends shapez.Mod {
- init() {
- this.signals.gameInitialized.add(root => {
- root.gameState.inputReciever.paste.add(event => {
- event.preventDefault();
-
- const data = event.clipboardData.getData("text");
- this.dialogs.showInfo("Pasted", `You pasted: '${data}'`);
- });
- });
- }
-}
diff --git a/mod_examples/replace_builtin_sprites.js b/mod_examples/replace_builtin_sprites.js
deleted file mode 100644
index 6e88b7fb..00000000
--- a/mod_examples/replace_builtin_sprites.js
+++ /dev/null
@@ -1,48 +0,0 @@
-// @ts-nocheck
-const METADATA = {
- website: "https://tobspr.io",
- author: "tobspr",
- name: "Mod Example: Replace builtin sprites",
- version: "1",
- id: "replace-builtin-sprites",
- description: "Shows how to replace builtin sprites",
- minimumGameVersion: ">=1.5.0",
-
- // You can specify this parameter if savegames will still work
- // after your mod has been uninstalled
- doesNotAffectSavegame: true,
-};
-
-class Mod extends shapez.Mod {
- init() {
- // Replace a builtin sprite
- ["red", "green", "blue", "yellow", "purple", "cyan", "white"].forEach(color => {
- this.modInterface.registerSprite(`sprites/colors/${color}.png`, RESOURCES[color + ".png"]);
- });
- }
-}
-
-////////////////////////////////////////////////////////////////////////
-
-const RESOURCES = {
- "red.png":
- "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAYAAADDPmHLAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAADsQAAA7EB9YPtSQAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAABJ2SURBVHic7Z17dF1Vncc/+9z3zeOmeVOThj5oi20DpU3btAU7KCrDS1GcJSiKLhRRVxXmweDgAkUcl+LgyKAzLsdxGB4jICgFnAJSp3k0tKVNH5Q2PNLmNmmbtM19v8+eP1JGrOfcnPtK0rA/a+Wfu/f57Z17vnc/f/u3QaFQKBQKhUKhUCgUCoVCoVAoFAqFQqFQKBQKhUKhUCgU0wQxmYW3lZU12qW2SpOs1AXzBWI20ACUAT5gFEiDGAJ5EMEBqbPNJkVPRzzw5mTW/XTWVFQs0HWxUkiWCzhHh1kCGgE34JUQERARyCMS7U2kvl9Cj11ktmyORocmq94TLoC1ror5uk1cC1wBLM27DoI+Ac8gxUOd0cC2YtbRKqs9Fe1SiGuBywTMLsDUTgFPY5MPdYZC+4tVPytMlABEu6fiI0LT1iPlRcUvV/YKuL8yGnrwOUgU1/afsg7cKa/vsxL5FWBRkc1LhNgsdf2+7ljoKUAW2f6fUXIBrPVWXCHhboloLXVZwCDwHWc0+G+bIF1Mw8vA4fJU3iQEt8uxpr2kCOQuHb7RHQ1tKG05JWKVu+psTdN/DFxeqjKysE/TtJs7wqObimFsdbnvYjLyAQQLimEvFyQ8LXTtq13x0YOlsF8SAbSXVV4rJA8wNpCbLKSEf01Gy2/dzmA0HwOtNJSVe6M/BHEjkztgDiC5qSsWfLTYhov6T60De8Jb+WMBN+XyXIPXy4KqKub5qpjhclHhcFLucBBNJQmlUwQSKd4IjtI3GsAfCaPLXLpGsUfY9I/nOrhqr6hYKDLicXLo5zUhmFNZyTm+Kloqyql2e6h0OIilMwCEUimOx2O8HgzQNzrKsVgslyoh4f6maPBrj0EmpwezUDQBrKOuPOlNPA58yEr+lopKPtjczAeamqn3eCyXE0wl6Rga5CX/YXaMDJOxJoZRTcorOmKhDiuZ17grLpSa+C1QNV5eu6bRVl/P+9/TTFtDPZUOp5UiABiOxXjB72fjwCH6Q0FLz0h4LhL1XLOLoxHLBWWhKAJYxkyv0xN6RgixLls+TQgumjmTT86bz/yqcb/bcRmJx3i4r49nDvaTzIz7o4gKuKYzGnw2W6bV3srLgF8B3mz5vHY7V549h6vnzKXO486t4gYcCIzyaN8B/jA4aKWF63BGXZduYjhcaLkFC2AROH2eit8hxF9ky7ewagZfP/985vsKf/Gnczwe45f7X2NDf/9486aUlHymOxZ8xChxTVnldVLyC8BhZkATgstaWrhh4bnMcBX+4k+nLxDgn3p3sO/kyewZJS8mYsFLt0OqkPJshTwMcI7X91MEHzNLF8D1CxZy+7Ll1LqtN/W54LU7aG88i8U1tewYGSaaNp0B2oTgo012525/OvnaOxPWeMqvlohHALvZwzPLyrh7xSo+MnsOHrtptoKocbu5dFYLLpuN3pERc0EL5tgdzsaBVPLpQsorSABrvL6bQH7TLL3MbueO5W1cNXsOQpR+ED2zrIxLW1oYikboD4XMsgmEuLzJ4f6dP5UYAljr9S2TQjwNmHbgF86cyffb1/Ke8rIS1Py0CgrBkpoazq+tpfvIERKm3ZtYNsvhPjqQSuS9Epr3Wzk1St6OSV9Z6/bwgzVraCmvyLeIvNGl5IG9u3nijTeyZRvKSPsKp4hnMth7gGazjJ+ev4Abzn3vpMwD/eEwt3RtZjgWN8sSFTZ5Qb5LyPm2ANosu3sDcLZRYrXLzX1rL2TWJLx8GPsFrahvwG238crwsFm2Ck3o75No1wILDe0ANy9awqcWLJi0RYBKp5P2hrP4w9AgMeOuzSGlaPOnEv9OHkvHeQlgjbficyC+ZJTmtNn43qrVzPVN5hrQGIura3DZbWw3F8HMU3+GfHnxEq6ZN68kdcuFSqeT1ppaXvAPGE57BTQ1O539A6nkzlxt5yyAddSV647MU0C5UfpXl5zHhTNNv9MJZ3F1DcfjcQ4ERnN67uNz5/HZheeWqFa5U+fxUOVy0X3kiEkOsXJGquqnR4nkNCvQcq1I0hP/gtlmyIr6Bq6cXciuaGlY33oey+rqLedfUd/AlxYtLmGN8uPylrNZ1WC6D3VWuSf2+Vxt5iSAZeBAiPVGaQ7Nxtdaz5tcDxMT7JrGnW0rLC3Y1Hnc3L5sOdoEzFryYX3reThtJg234K8XZZnJGJGTAFwe31XALKO0q2fP4ayy0k+R8qXc4eDW85ZmzaMJwe0XtOFz5vQdTiiNXi8fmzPHLLnZ5624NBd7OQlACnm90ecOzcYnpsBgaTxWNjRy6awW0/TLW87m/NraCaxRfnxi7jm4TFoBgfaZXGxZFsBan2+GgA8bpV3S1Ey1u/jLoqXg5sVLDFcka9weblxUbAef0lDlcnFJk/GyhURetq7K+kaLZQHIJJdgskb+oVmmayhTjnKHg28ub6Pc/sd/pcxu545ly//ks6nOB5sNe2IAZyqRvtiqHcsL2lIYb/PWedwsqZn6zeY7WVJTw4MfuITuo0eQSNobGkuysVNKFtfU0OD1cjT6574uUogPAb+2Ysf6joaUa4yG+CvqG6fkyH88qlyurOOBqY4A2urq2XCw3yBVW23VjqUuYB115QjOMUpbWltntSxFkbnAdG1DnttKg6UpmSUBpDyJxWZ5FxTBsUORH1l8K2xlnpilEa0lAUiTTR+XzcbMKTz3n+7MLC/DbTdbzReW+jdLAhCaNBzm13u8U3bF7N2AABrcxp5rAt3S1MxaC6BrhsP8ujNk7j+dqTV3qLW0+WFNAEIayszrOHPmzdMVr8NkIqcJS/53FheCjI25bDlvJiqKjFszGQNIkdWr+W0svUENaeiPlMzoVh5XlJCEbuwvKE3e2elYEoAOx40+DySTVh5XlBCzdyBM3tnpWGvDJScMC0+U9CS2wgKjCZMfoSyiAIRmbGwkHsvxnJ6imOhSctzkfKHQjH+0p2NNAFK8ZvR5JJ22fKZNUXz6Q0HCaWMXQF1qr1qxYUkA8WigF4Sh1PacGOcIk6JkmH/3IpaMju6xYsOSAMbOn0lDl+O9xy11NYoS8OoJs+9ebrd6ZtDyRF4Ieow+7z46RMpkKqIoHSldZ8tRExdxKQzflRHWV3IkG40+DqVSdB85atmMojh0HTliOgWUmnzeqh3LAnBEg88Dhm/6fwYOWTWjKBJZvvNjrkjwRat2LAtgE6QFPG6U9vKxo4zEcwt3osifkXiMrcdMWl3Bo5tyiJCW02J+RkrDwAppXefhvr5cTCkK4KG+A6R142V4oWP4jszISQBbYqEuYJ9R2ob+/mxHmBVF4kQ8znMHjSPGSXi1Mxa0PACE3M8GSin4R6OElJ7hkdcP5GhOkSsP9R0wDRihCe4hxyPiOe/nNkWCDwGvG6Vt6O/HHy44bpHCBH84bOIFDMCbjkjwv3O1mbMAHoOMQNxrlJbSM9zbu6P0AW7fpdy3a2eWaGjie5vyCI+bl0dHZTTwC8BwHrJzZIQX/AP5mFVkYaP/ULZAF4d80cAv87GblwCegwRS3GqW/sCe3QRTylegWASSSX6y23xpX0r5tXyjpOft09UVCzwOGAZdHE0kuHfnjnxNK07jn3f3Mpo0fb8bu2OhJ/O1XZBTn8ywHjCc+/3v4CC/eeutQswrgKfeeovf+/1myQktI79aiP2C4gT6M4kTzQ6XG7jIKH378DCrGhupUe7jefFmMMBd2142jYcs4Z6ueOiJQsoo2K3XFw3eDRi29yk9w7e3bf3/aNkK68TSGe7cujVLkEheqYoG7ym0nIIF8BwkZIZPIDEMzTkQDnHXtpeV61gO6FJyzyvbGAgbRzuVEJE2eV0xrscpOFYwjHUFs5zOYyCuNEo/HAkTT2doq7ceqevdzE9e3cPvDplfECKEvKk7HHqhGGUVRQAAA6nkjll213wES4zS9548QZXLzcIZM4pV5LTk2YP9/OxVc3c+IXisKxL6RrHKK+rRnrjbdjMC0w2B+3f3sm34WDGLnFZsGz7GD3uzBPuU7I87bTcWs8yitQAAQ/F4osXmflYKrsMgiLQENg8O0noqvInij+w7eZLbt3STNNnmBU5ouvxATzgwWMxyiyoAgEPpxMlmm6MHIa4zsp+Wko7BIZbX16vp4SneCAb5m65OUxdvIIUmruqMBYt+QWbRBQAwkE4ebHY6D4O4yig9qetsHhpkVWMjVS5XKapwxuAPh7mls4OA+UofEvHl7kjA0BurUEoiAICBVHJns9NVCbQbpScyGf4wOMjqxkZ8znenCAYjEdZ3dnAiYe5II6T4QVcs8N1S1aFkAgAYSCWeb3K4mwRcYJQez2ToPDLIqoZ3nwj84TBf7+rI7kspebArFvwKJbxCtqQCAGhPJZ4JOV0LAMPw29F0mpcGD7O8rv6MiTZaKAdDQW7p6sz68gXiSWcs+Kn+It4RaETJBfAqyPpU4jd2h+sCYL5Rnngmw0uH/bTW1FDvmd6zg/2jo9za1cHJ7CerN/qiwY+/UOCNYFYouQAAhkBvSiWeFHbnaoQwvFAgqetsGvRzbnU1Z3mnZ+SxV0aGua27i3DK/L0K6AxHPVd0EpkQP/sJEQCAH9Jz074ndEfmfZiEnE/rkpcO+2ko8zK3cvKvnCkmmw4f5s5tLxPPcsGlgE5H1PXhHo4V5VZQK0yYAAD6iSbrUzWP2h3JNmCuUR5dSjqHhkCIMyJ0uxV+/eYb/KB3h6kvP4CUcpMoc12+OToyoV61EyoAgCFCqcpU4lcuh3ORQJheyrNzZITj8TgrGxrP2FiEGSm5b9dOHjywf7xh/AZXLHTV5qhB5OcSM+ECABiGTHsq+UTQ4WoRcL5ZvgOBUXqPj7CyoaFkN3WWikAyyR0v97Bp8HD2jIJHEtHgJ7thUpwoJ0UAMDY78KcSv21yuGoErDDLdzQa5feH/Syprs0WFHFK8UYwwC1dHfSNjnNTmeBHXZHgF4dKPNXLxqQJ4BTSn0o812R3jQrBBzG5yTSaTvO8f4Bat5tzSnD5dDH5vd/PP/RsMQ/eNIYEvtUVDd5GCRd5rDDZAgDAn070zLI79iC0KzG5lSQjJZ1HhjiRiNNW3zDlxgW6lPxs317+Zc9u0tm9nxJIPt0VC94/UXXLxpQQAMBAOrmv2ebYjBBXYnIfMcCB0VF6jx9n1RQaF4z191vYODDugZgRTcrLOmMhQ3f6yWDKCADGdhFn28se0YV+IVmudD0aGxsXLK6upW6SxwWvBwLc2t1B32hgnJxit10X798cD+6akIpZZEoJAOBgOhacm0o8mHG4msgyQ4im02wcGMCuaSyqrp6Q6+lPZ6P/EN98uWe8/h7g2YTLdvmW8KjZva+TxpQTAEA/pAdSid80O51hEBdj4rqmS8n24WPsPXGC5XX1E9YlBJJJvrVtK4/0HRivv5fAd7qiwS8MxeNTMnjC1BpJGbDaXX4RmvYY48S/r3K5uG3pBaw0v1u3KOwYGeae7dvHD4kjCYH43KkjdFOWKS8AgIs81c1pkX4CaMuWTwBXz53LF9+7CIdZGPU8yUjJfx3Yz3/uf238Mw6S12w2/WObw2FL0TonkynZBZzOwXQsWJ+qechhT842czt/m30nT9Jz7ChLa+uoLNIdwP5wmNu2dPGi3z/upF1IHg7HPFdsTZ4sqvNmqTgjWoB30l5WeT2SBwRk3TN22Wx8ZsG5/NW8eXmvGUjGop78ZO8uC8fbRExK+ffdseCP8ipskjjjBADQXlGxUGTEw0D268CBxdU1/O3SpTSXV+RUxpFIlO/t3M7OkREr2fdKkflkdySyO6dCpgBnRBdwOv5kcmRxKvEfCbvTgRCrySLkY7EYzx46iE1Ymy6+/au/Y2s3/vC42/ISwY990eA1L6VSZ0STfzpnZAvwTtaU+S6RUv4SOGu8vK01taxvbWWOibPJW6EgP9rVS6+1X/0wcENXNPhMThWeYpzxAgBYXV5ej679AvjL8fJqQrCsro7zaup4z6lLLw9HIvQeH2b78LC1U8ySF4VIX98ZjZ6Rv/p3Mi0EcAqx2lP5FSn47ngDxHyREAH+rjsafIBJ3sUrFtNJAACscledrYnMzxHi4mLaFdCZznBDTyI4rWLiTjsBnEKs9vpuBHkvUF6gqRiCu7oige8D0+6evOkqAADWun1zMkL/uRBiXT7PSyk32aT2+Y544M0iV23KMK0F8Dbt3oqPaHCXRLRae0L2SrizOxp6qrQ1m3zeFQJ4m7Ve3zId+VEkqxByAYjqsRR5QiBek7BFRzy5JRp4ZXJrqlAoFAqFQqFQKBQKhUKhUCgUCoVCoVAoFAqFQqFQKBQKRc78H7cNicQwxMlzAAAAAElFTkSuQmCC",
-
- "green.png":
- "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAYAAADDPmHLAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAIwwAACMMBoDLh7AAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAABP2SURBVHic7Z15eFTV3cc/ZybJJJmQsEOQoqAVBaFVX7Uu5VXBpdW3uHZ56dviW1uL7VOXautSKy61Vay7Vn1tVV6tWkQUFI0RVFQsIPuO1hBMwhLJMskkmSQzv/5xb5K7zWSSzJKB+3me+yRz7nbO/f7uWX7n3HOUiOASP0opP3AhcC7wTaAeeEJEHk1rxHqJcg2ge5RSCk3smcClQIHlkDbgayKyNcVR6zNZ6Y5Af0cp9QPgTmBcjMOyAV9qYpRYXAOIglLqq8BjwLQ4Dl8EbExujJKDawAWlFI+4LfATcR+q3egCV8iIqWpiFsycA3AgFLqG8CzwJFRDgkA/wCeFpHlKYtYEnENQEcpNRVYCOQ77G4B/gTMEZGmlEYsybgGACilvg3MB3Iddi8ErhaRstTGKjUc9M1ApdQxwCrs4pcBvxSRxamPVeo4qHMAvcL3PHbx1wLniEh16mOVWjzpjkCauQuYbAn7J3DGwSA+HMRFgFJqNFCO+SXYD0wWkar0xCr19MscQCmVinhdhj39P02W+ClKU49JSw6glBoBnAAcAozS/xr/HwzUAVWWrVL/u1xE9vbh/gr4HDjMELxEROLx+kW75gjgFLrSMMqyDQRq6EpDpeX/VX1JU68RkZRswFjgWuADIAxIH7Yw8CHwa2BcL+IyzeGaP+jFdcbpafowQWn6QL/e2JTpkmTRJwO3Auv6+HC629bp95kUZ7xus5xfC+TGee6kFKdpcsYZAPA1oDTJDyja9lZ3Dw3N3Ws8Z0GcxvxWmtJUitbdnHCtEuoHUEoVo3WdzqSbCqZS4B/soXCEhwHDvRSO6Pjfg3+wh2BNhPo9EQJ7ItTvDhPYq/0NBaW7aJwDnKWUmgvcIiIVDsccavm9K0aaRgN3AD/qLk0APr+iqFhLT1Gxl8KRHopGdqWpYV+EwF5ta9inpStYE0FiJ2sasEYp9QzwOxHZ3V084iUhlUClVD5wvb75ox3n8cKhx+cw8RwfR0/zUTii5xXjYE2Ere+E2Lg4RNnKViQS8/Bm4AHgTyISMMR3J2Yj+I2IzLGkqRC4AbgayIt2A+WBsSfmMOnbWpr8g3uepsBeLU2bS0KUr24lEo55eBCYQ4L6JfpsAEqp6Wj95qOc9nuzYNzJOUw828dRU3v3gKLR+GWETW+F2PhGC1+sa4v1Fn2J5s9/Xo9zLVqtvIOZIvJsxw+l1Aw0wxnqdDGlYPTXspl8fi7HnOujYGji0hSsibBtSYjNb4f4/ONWwu1RD60CrhSR1/pyvz4ZgFLqRuAPgLLvg0nfzuWsX/sZOMrbhyjGR11VmI/nNvPP/2+K9QbdBfwO2ARMMITfICJ3683DO9HGAtjweOEb/5PPyT/KS1maSv8cZOPilmjGLcDNIvLH3t6jVwaglMoB/g+tXLRx6PHZnPvbAkZPzo7reu2tQmN1hIbqCIF9EYaO9TLiq72rnuzd0c7C2Q3sWtMW7ZB/AEOAqYawx4Fr0CqH33U6acxx2Xxn9gBGHJn67pOKDW28dXcj5aujpmkumhOrtafX7rEBKKWGAguA06z7Bo/xcvZ1BUw8O/pAmkgYdq1pY9vSEP/6uJX63RGa6+0F+Td+mMd5vxvQo7h1IAJrF7RQMqeRplrHSkI1MMzweyla3eUk64H5gzycc30Bx16Yi7Llc6ll89sh3r63kZpdjlnch8CFIvJlT67ZIwNQSk0AXkdz6pg49sJcpt8+AG+2/SmF22H7uyG2Lgmx471Wmupi19wAsnyKG5YPxefv/VNvro/w9p+DrJ7X3F0tOwyY8nSl4PhL8zj7137yivqPFzfcJrz2+wbWLmhx2l0GnC8iW+K9XtwGoJQ6EliBufKEUjDtmgKm/Mw+kEYENr3ZwjsPBKNZbVQGj/FydcmQhLx1m94M8fL19bEqVCa8WXDJnCKO+Vb/Hei77Mkm3rm/0cmw64CTRGRHPNeJywD0JtEK4ChjeHau4pI5hUw4y/6gyla0UjKnkcpNcT51HW8WHHZiDqfP8nPYCfHVIeJhx/utvPCretpDsdOb5VP84KEijvzPnITdO1lsKQ3x8vUB2lpsadqGZgQBh9NMdGsAes34NeC/jOEDhnv44V8GMmqiuVLUVBvhlRsb2P5eKOZ18woV48/0MfaEHApHeCgY5mHAMA/5gzxJK2vLVrby/Kz6qM4kn18x4y9FjD2x/4vfQdXmdp6bVUfDPluxugiYLt0IHI8B3A7cYgzzD/Hw83mDbE2hvZ+28/ysemornLN7/xAPx5zrY8I0H4edmIMn+S0pGxUb2ph7eR3NAXu6f/zXgRxxauaI30FdVZjHL60luN9mBHeIyO9jnRvTAJRSFwEvY2jne7Ng5tODbNnztndDvHxdwPHt8vkVp/0kn1MuyycnL81VabSm4jOX1dFoeWA3rRxGXmH649cbdq5q45nLaq31HAEuEZFXop0X1QD0Gv8KLN/BnX/LAE6aYfaMfvBUE6X3Ndrcst4s+I/v5XHGL/wJ9QAmgtZmYf5vA2wtDSECU6/yc/qsqF7sjGDF8828fkeDNbgRrT7g2DKIZQBLgDONYcddlMuFdxWajlv592YW3W67KQOGefjvR4vidgali6ZarTNm2OEHxvjYBTcFWPOKrYm4VESmOh3vaABKqWloXZCdHDIpm8ufH0hWTlcW+fnHrTx7eZ3N9XrIpGxmPFrEgOH9660/GGhvFZ6aUUflRpvX8CwReccaGE2hu4w/snIU33+w0CR+za4wL14dsIk/+bxcLn9uoCt+mnDSSucup+NtKimlLkYbr9fJSTPMnR8tDcJzP6+zuXCPnubjknsLyfJlZkXqQGHgKK+tngacoGtrwmQASikvWm9YJ74CxZQrzF6+0vsbqf7c/OqPHJ/FJfcUpt1f7qIx5Yp8fAU2Me7UNe7EmgP8GIu377Sf5JM/sOuw/eVhPnmp2XSSf4iHGX8pIiffVb+/kD/Qw2k/sbnnj0LTuBOrAdxo/FEwxMMpMy1v/32NtnL/e/cVpqR/3KVnnDIzn4IhtlLepHHnXv0jySOMO0+/0m9y3FRsaGNzidnFe9SZPsaelHnes4OBnDzF6VfafBtH6FoD5hxguvGoLJ/iuIvN30y+fW/Q9NvjhbOuzWznyYHOcRfnOlXKO7U2GsB3jEccfnI22bldJ9ZVhilbaR5w8vULchl+xIHhQDlQyc5VHH6yzRnXqbUHOodzm5p+488wd/FuXWLO+pUHzvyl+/ZnAlYt0ZqExdCVA5yPZWDn+NOtBmB++7/y9WyKit2KXyZg1RJN6/OhywBM5f+oCVmmMfvNAaH8E7MBOA0CcemfFI7wMGqCraieDuDRHQOmjoLxZ5rF3fF+yNb0mzDNNYBMwqopMFUp5fUAw7FMkTLO0qz7Yp25Y2Hk+CwGfcXN/jMJq6Zomg/3AMXWPUUjzc6Dxmqzz3/k0W7NP9OwaqpT7GgA1p68gGW8WaHb05dxROmdtRtAXqGyOQ6sAw4LhrnZf6aR5VNOw93sBjBguF3cxi/NBjBgmJsDZCIO2joZgFncUFBobzWPGioqdg0gE3EoBuwGYC3ffX7Focd3uRIHjvIyelL/Hufn4oxD3a04CzC1D7z2oURMv6OQZU8ECQWFKT/Np39OeObSHQ7a5mShTVHWSWCv/aOOYeO8XHx3oS3cJbNw0LbSg9UA9nT/5a5LZuKgbaUHME2iVO8awAGLg7YVthyguT7i9LWpS4bT1iJOE3HYcwDQZq1yObCIoqk9BwAI7OnZZA4u/Z8omlZ6RKQWMM0359YDDjwcNG0SkdqOFr2pGHCLgAMPB00roGtEUJlxz57tPZvWxaX/46BpGXQZwEfGPTtX9ni6OZd+joOmH0GXAbxv3NNQHWF/uVsRPFDYXx6modpWBLwPXQawAm1xxE7cXODAwUHLFjTNNQMQkVBHQAdlq6JOS+qSYThouULX3PRlkKkY2OkawAGDg5adWkc1gPrdYWq/cOsBmU7tF2Hqd9t0dDSAjwFTYeEWA5mPg4ataFoDBgMQkWa0NXQ7cSuCmY+Dhqt0rQH7BBGmYsDNATIfBw1NGsc0gLpKx/LDJUOo3x2mrjJ6+Q92A1gOmHyG25a6xUCm4qBdO5rGnZgMQEQa0VbP6GTDG44LE7hkAA7aLdU17sRpfO+Lxh9frG1zi4EMpH53mC/W2sr/F60BTgawAENzUAQ2Lo49979L/2Pj4pB1NZFWNG1N2AxAROqAEtPF3GIg43DQrETX1kS0TzxeMv6o2tLu9g5mEPvLw1RtsfX/v+R0bDQDWIi27Gonbi6QOTho1YymqQ1HAxCRBmCx6aJuPSBjcNBqsa6pjVhf+ZmyjH2ftbtDxTKAPdvb2fdZfNk/xDaA19GWG+nELQb6Pw4aNaJp6UhUA9A7DBaZLu4WA/0eB40WGTt/rHT3obfJcVBbEaZivdtB1F+pWN/mtGSfzfljpDsDKAHqjQGr/hHVmFzSjIM29Vh8OlZiGoA+bmyeMWzD66FoK3K7pJGm2ggbXrdl//M6xv5FI565Ph4x/mgPCatecnOB/saql5qd1kV+xOlYI90agIisx9KHvOLvzXGvxO2SfMLtmiYW3te1i0m8s/08aPzRsC/C5hK3Sdhf2FzS4rR49INOx1qJ1wAWAjuNAR/PdYuB/oKDFjuJ4vq1EpcBiEgYeNQYVrG+zW0S9gOi6PCorlm39GTCt6cA06JBbi6Qfhw0CKJpFRdxG4DelzzXGBal7HFJEVHqYnOd+v2j0dMpHx9CW5MeiFr7dEkRDq0xQdMobnpkACKyDcuq4lHany5JJoo/plTXKG56M+mrqXnRVBth/SK3SZhq1i9qcfLIxtX0M9IbA3gT+NQYsOzJJtcxlELC7dozt/ApmjY9oscGICK2cqZmV5hVL7p1gVSx6sVmanbZWnkP6dr0iN7O+/1XoMoY8N5jQUKNbl0g2YQahfceC1qDq9A06TG9MgB9gMFsY1iwJsIHT9myJZcE88FTTQRrbGX/7FiDPmLRl5n//wZsNwYsf6bJaTIilwTRUB1h+TO2l2w7mha9otcGoLsabzaGtbUISx+2ZU8uCWLpw0Gnibxvjtft60Sf1v4QkfnASmPYmvnNVP/LbRIkmup/tbNmvi2XX6lr0GsSsfjLDcYfkTCU3ufmAomm9L6gbfleLM++N/TZAETkXSzjzrYuCVG+2u0pTBTlq9vYusQ2sqtEf/Z9IlHLP92IoY8AoGROY5RDXXqKw7MUtGfeZxJiACKyFuu8Auva2FLqfkfQV7aUhmyLdwMv6s+8z6heOI+cL6TUOGAL0LlOeVGxl1++Nphc+5KlLnHQEhAemV5jnaAjBEwQkc8TcY+ErQCoR8jULKzfHea1WwOJusVBx2u3BpxmZ7k5UeJDAg1A535gmTFg05sh1i5wewt7ytoFLWx601aEvo/2jBNGwoqAzgsqNRbYABR0hOXkK37x6mAGj3FXHY+Hml1hHr2ghtYmkzYNwGQR2ZnIeyV8EVgRKQOuMYa1Ngnzrgs4tWNdLETCMO+6gFV8gKsSLT4kwQAAROQp4A1jWMWGNtdNHAdLHw5SscFW618oIk8n437JXAb6cmC/MWDZk0HKP3EdRNEo/6SNZU/aXpJq4KfJumfSDEBE9gCzTGERmHd9gJaAO27ASktAmHd9ALF3pv5MRPYl675JXQheROYBLxjD6neHWTjbcbqag5qFsxucmnzPisirybxvUg1A5xdYRg9tXNzCh39zB4908OHfmti42NZULgd+lex7J90A9JVJ/xdrX8E9jax8Ib3jCEONkvZhbCtfaKbkHpuvPwLMFJGke9ES7geIeiOlrgIeMIfBhX8s5NgLclMShw7qqsKU3hdkc4nmaJl4jo+zrvUzcFRq/RRrX21hwY0B65SuALNE5PFUxCFlBgCglLoTi7vY44WL7ylk8nnJN4JQUFj2RJDlz9o/ZsnyKU75cR5TrvDj8ye/72LDGy3M/42jb2S2iNyW9AjopNQAAJRST2Jp1igFU67wM/VXflQSCqVIGNa+0sw7DwZp/DL2mMWCoR6mXeXn2Ivy8CQhQ5AILHkoyLIngk5v/uMiMsvhtKSRDgPwoM07dJF135FTcrj03qKE9R5+WRZmzfxm1r7a0q3wVgqGejj2glyOuziPoWMTYwktAWHedfXsWOa4CMd84LsiDg3BJJJyAwBQSvmAZ4DvW/cNHuPlWzcWcNQZPtt58RAKCpvfCrH65WZ22efLt7JB/zs51kFjjs3m+EvymHiur9fFw7Z3Q7z5x0anDzpAG0sxs7sJnZJBWgyg8+ZK3QzcAdie6ujJ2Uy9ys8Rp+bEvEZrs7BrTRtlK1opW9lG1aa2eD5T+xS4la5BLN8HbgO+GuskbxaMOiabsSdmM/akHMYcl01OXmyD+OyjVpY86OjeBa1ldIuI/KHbGCeJtBoAgFLqAuA5wO+0f/AYL8VHZTFifBZDDvPSVCvUV4Wp2x2mtiLCnq1xCd5BBXA78LSImM5SSmUBlwG/B0bHczFvFow8OptBoz0MLPZSNMpL/iDF/rIwe7a3s3tbe6zFN4PAD5Pt6OkWEUn7hpYFf4b2RiR6i6CNUfgZ4IsjLj792GX6ucmI02doXbvpf/bpjoDhwWej9R1UJughrwN+A4zpQ5zG6NdYl6A4VeppzE738+7Y0l4EWFFK5QJXoo15H9aDU2uAj4APgTdEZHOC4zUROA84DTgVGNyD06uBPwGPiUi/Gh7V7wygA6VUPnAi8HXDdiTa/Le79a0SWA18AGyVFCVGKaWAo4FvAscDhwDF+laE9r3eOmC9/neliPTLzo9/Ayif0cMIPHkWAAAAAElFTkSuQmCC",
-
- "purple.png":
- "data:image/png;base64,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",
-
- "blue.png":
- "data:image/png;base64,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",
-
- "yellow.png":
- "data:image/png;base64,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",
-
- "cyan.png":
- "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAYAAADDPmHLAAAACXBIWXMAAAOxAAADsQH1g+1JAAAE8mlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNy4xLWMwMDAgNzkuZGFiYWNiYiwgMjAyMS8wNC8xNC0wMDozOTo0NCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iIHhtbG5zOnBob3Rvc2hvcD0iaHR0cDovL25zLmFkb2JlLmNvbS9waG90b3Nob3AvMS4wLyIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0RXZ0PSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VFdmVudCMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIDIzLjAgKE1hY2ludG9zaCkiIHhtcDpDcmVhdGVEYXRlPSIyMDIyLTAxLTE0VDEwOjMwOjMyKzAxOjAwIiB4bXA6TW9kaWZ5RGF0ZT0iMjAyMi0wMS0xNFQxMDozMDo1MCswMTowMCIgeG1wOk1ldGFkYXRhRGF0ZT0iMjAyMi0wMS0xNFQxMDozMDo1MCswMTowMCIgZGM6Zm9ybWF0PSJpbWFnZS9wbmciIHBob3Rvc2hvcDpDb2xvck1vZGU9IjMiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6ZTFiZTU2MjEtMTU1ZC00YmFmLWFiNzgtYjM2Y2QzMmIzNTNkIiB4bXBNTTpEb2N1bWVudElE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",
-
- "white.png":
- "data:image/png;base64,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",
-};
diff --git a/mod_examples/sandbox.js b/mod_examples/sandbox.js
deleted file mode 100644
index f405ab59..00000000
--- a/mod_examples/sandbox.js
+++ /dev/null
@@ -1,21 +0,0 @@
-// @ts-nocheck
-const METADATA = {
- website: "https://tobspr.io",
- author: "tobspr",
- name: "Sandbox",
- version: "1",
- id: "sandbox",
- description: "Blueprints are always unlocked and cost no money, also all buildings are unlocked",
- minimumGameVersion: ">=1.5.0",
-};
-
-class Mod extends shapez.Mod {
- init() {
- this.modInterface.replaceMethod(shapez.Blueprint, "getCost", function () {
- return 0;
- });
- this.modInterface.replaceMethod(shapez.HubGoals, "isRewardUnlocked", function () {
- return true;
- });
- }
-}
diff --git a/mod_examples/smooth_zooming.js b/mod_examples/smooth_zooming.js
deleted file mode 100644
index 94254f2d..00000000
--- a/mod_examples/smooth_zooming.js
+++ /dev/null
@@ -1,58 +0,0 @@
-// @ts-nocheck
-const METADATA = {
- website: "https://tobspr.io",
- author: "tobspr",
- name: "Smooth Zoom",
- version: "1",
- id: "smooth_zoom",
- description: "Allows to zoom in and out smoothly, also disables map overview",
- minimumGameVersion: ">=1.5.0",
-};
-
-class Mod extends shapez.Mod {
- init() {
- this.modInterface.registerIngameKeybinding({
- id: "smooth_zoom_zoom_in",
- keyCode: shapez.keyToKeyCode("1"),
- translation: "Zoom In (use with SHIFT)",
- modifiers: {
- shift: true,
- },
- handler: root => {
- root.camera.setDesiredZoom(5);
- return shapez.STOP_PROPAGATION;
- },
- });
- this.modInterface.registerIngameKeybinding({
- id: "smooth_zoom_zoom_out",
- keyCode: shapez.keyToKeyCode("0"),
- translation: "Zoom Out (use with SHIFT)",
- modifiers: {
- shift: true,
- },
- handler: root => {
- root.camera.setDesiredZoom(0.1);
- return shapez.STOP_PROPAGATION;
- },
- });
-
- this.modInterface.extendClass(shapez.Camera, ({ $old }) => ({
- internalUpdateZooming(now, dt) {
- if (!this.currentlyPinching && this.desiredZoom !== null) {
- const diff = this.zoomLevel - this.desiredZoom;
- if (Math.abs(diff) > 0.0001) {
- const speed = 0.0005;
- let step = Math.sign(diff) * Math.min(speed, Math.abs(diff));
- const pow = 1 / 2;
- this.zoomLevel = Math.pow(Math.pow(this.zoomLevel, pow) - step, 1 / pow);
- } else {
- this.zoomLevel = this.desiredZoom;
- this.desiredZoom = null;
- }
- }
- },
- }));
-
- shapez.globalConfig.mapChunkOverviewMinZoom = -1;
- }
-}
diff --git a/mod_examples/storing_data_in_savegame.js b/mod_examples/storing_data_in_savegame.js
deleted file mode 100644
index 92f7733b..00000000
--- a/mod_examples/storing_data_in_savegame.js
+++ /dev/null
@@ -1,78 +0,0 @@
-// @ts-nocheck
-const METADATA = {
- website: "https://tobspr.io",
- author: "tobspr",
- name: "Mod Example: Storing Data in Savegame",
- version: "1",
- id: "storing-savegame-data",
- description: "Shows how to add custom data to a savegame",
- minimumGameVersion: ">=1.5.0",
-};
-
-class Mod extends shapez.Mod {
- init() {
- ////////////////////////////////////////////////////////////////////
- // Option 1: For simple data
- this.signals.gameSerialized.add((root, data) => {
- data.modExtraData["storing-savegame-data"] = Math.random();
- });
-
- this.signals.gameDeserialized.add((root, data) => {
- alert("The value stored in the savegame was: " + data.modExtraData["storing-savegame-data"]);
- });
-
- ////////////////////////////////////////////////////////////////////
- // Option 2: If you need a structured way of storing data
-
- class SomeSerializableObject extends shapez.BasicSerializableObject {
- static getId() {
- return "SomeSerializableObject";
- }
-
- static getSchema() {
- return {
- someInt: shapez.types.int,
- someString: shapez.types.string,
- someVector: shapez.types.vector,
-
- // this value is allowed to be null
- nullableInt: shapez.types.nullable(shapez.types.int),
-
- // There is a lot more .. be sure to checkout src/js/savegame/serialization.js
- // You can have maps, classes, arrays etc..
- // And if you need something specific you can always ask in the modding discord.
- };
- }
-
- constructor() {
- super();
- this.someInt = 42;
- this.someString = "Hello World";
- this.someVector = new shapez.Vector(1, 2);
-
- this.nullableInt = null;
- }
- }
-
- // Store our object in the global game root
- this.signals.gameInitialized.add(root => {
- root.myObject = new SomeSerializableObject();
- });
-
- // Save it within the savegame
- this.signals.gameSerialized.add((root, data) => {
- data.modExtraData["storing-savegame-data-2"] = root.myObject.serialize();
- });
-
- // Restore it when the savegame is loaded
- this.signals.gameDeserialized.add((root, data) => {
- const errorText = root.myObject.deserialize(data.modExtraData["storing-savegame-data-2"]);
- if (errorText) {
- alert("Mod failed to deserialize from savegame: " + errorText);
- }
- alert("The other value stored in the savegame (option 2) was " + root.myObject.someInt);
- });
-
- ////////////////////////////////////////////////////////////////////
- }
-}
diff --git a/mod_examples/translations.js b/mod_examples/translations.js
deleted file mode 100644
index 6b9c708e..00000000
--- a/mod_examples/translations.js
+++ /dev/null
@@ -1,66 +0,0 @@
-// @ts-nocheck
-const METADATA = {
- website: "https://tobspr.io",
- author: "tobspr",
- name: "Mod Example: Translations",
- version: "1",
- id: "translations",
- description: "Shows how to add and modify translations",
- minimumGameVersion: ">=1.5.0",
-
- // You can specify this parameter if savegames will still work
- // after your mod has been uninstalled
- doesNotAffectSavegame: true,
-};
-
-class Mod extends shapez.Mod {
- init() {
- // Replace an existing translation in the english language
- this.modInterface.registerTranslations("en", {
- ingame: {
- interactiveTutorial: {
- title: "Hello",
- hints: {
- "1_1_extractor": "World!",
- },
- },
- },
- });
-
- // Replace an existing translation in german
- this.modInterface.registerTranslations("de", {
- ingame: {
- interactiveTutorial: {
- title: "Hallo",
- hints: {
- "1_1_extractor": "Welt!",
- },
- },
- },
- });
-
- // Add an entirely new translation which is localized in german and english
- this.modInterface.registerTranslations("en", {
- mods: {
- mymod: {
- test: "Test Translation",
- },
- },
- });
- this.modInterface.registerTranslations("de", {
- mods: {
- mymod: {
- test: "Test Übersetzung",
- },
- },
- });
-
- // Show a dialog in the main menu
- this.signals.stateEntered.add(state => {
- if (state instanceof shapez.MainMenuState) {
- // Will show differently based on the selected language
- this.dialogs.showInfo("My translation", shapez.T.mods.mymod.test);
- }
- });
- }
-}
diff --git a/mod_examples/usage_statistics.js b/mod_examples/usage_statistics.js
deleted file mode 100644
index 80828d95..00000000
--- a/mod_examples/usage_statistics.js
+++ /dev/null
@@ -1,148 +0,0 @@
-// @ts-nocheck
-const METADATA = {
- website: "https://tobspr.io",
- author: "tobspr",
- name: "Mod Example: Usage Statistics",
- version: "1",
- id: "usage-statistics",
- description:
- "Shows how to add a new component to the game, how to save additional data and how to add custom logic and drawings",
-
- minimumGameVersion: ">=1.5.0",
-};
-
-/**
- * Quick info on how this mod works:
- *
- * It tracks how many ticks a building was idle within X seconds to compute
- * the usage percentage.
- *
- * Every tick the logic checks if the building is idle, if so, it increases aggregatedIdleTime.
- * Once X seconds are over, the aggregatedIdleTime is copied to computedUsage which
- * is displayed on screen via the UsageStatisticsSystem
- */
-
-const MEASURE_INTERVAL_SECONDS = 5;
-
-class UsageStatisticsComponent extends shapez.Component {
- static getId() {
- return "UsageStatistics";
- }
-
- static getSchema() {
- // Here you define which properties should be saved to the savegame
- // and get automatically restored
- return {
- lastTimestamp: shapez.types.float,
- computedUsage: shapez.types.float,
- aggregatedIdleTime: shapez.types.float,
- };
- }
-
- constructor() {
- super();
- this.lastTimestamp = 0;
- this.computedUsage = 0;
- this.aggregatedIdleTime = 0;
- }
-}
-
-class UsageStatisticsSystem extends shapez.GameSystemWithFilter {
- constructor(root) {
- // By specifying the list of components, `this.allEntities` will only
- // contain entities which have *all* of the specified components
- super(root, [UsageStatisticsComponent, shapez.ItemProcessorComponent]);
- }
-
- update() {
- const now = this.root.time.now();
- for (let i = 0; i < this.allEntities.length; ++i) {
- const entity = this.allEntities[i];
-
- const processorComp = entity.components.ItemProcessor;
- const usageComp = entity.components.UsageStatistics;
-
- if (now - usageComp.lastTimestamp > MEASURE_INTERVAL_SECONDS) {
- usageComp.computedUsage = shapez.clamp(
- 1 - usageComp.aggregatedIdleTime / MEASURE_INTERVAL_SECONDS
- );
- usageComp.aggregatedIdleTime = 0;
- usageComp.lastTimestamp = now;
- }
-
- if (processorComp.ongoingCharges.length === 0) {
- usageComp.aggregatedIdleTime += this.root.dynamicTickrate.deltaSeconds;
- }
- }
- }
-
- drawChunk(parameters, chunk) {
- const contents = chunk.containedEntitiesByLayer.regular;
- for (let i = 0; i < contents.length; ++i) {
- const entity = contents[i];
- const usageComp = entity.components.UsageStatistics;
- if (!usageComp) {
- continue;
- }
-
- const staticComp = entity.components.StaticMapEntity;
- const context = parameters.context;
- const center = staticComp.getTileSpaceBounds().getCenter().toWorldSpace();
-
- // Culling for better performance
- if (parameters.visibleRect.containsCircle(center.x, center.y, 40)) {
- // Background badge
- context.fillStyle = "rgba(250, 250, 250, 0.8)";
- context.beginRoundedRect(center.x - 10, center.y + 3, 20, 8, 2);
-
- context.fill();
-
- // Text
- const usage = usageComp.computedUsage * 100.0;
- if (usage > 99.99) {
- context.fillStyle = "green";
- } else if (usage > 70) {
- context.fillStyle = "orange";
- } else {
- context.fillStyle = "red";
- }
-
- context.textAlign = "center";
- context.font = "7px GameFont";
- context.fillText(Math.round(usage) + "%", center.x, center.y + 10);
- }
- }
- }
-}
-
-class Mod extends shapez.Mod {
- init() {
- // Register the component
- this.modInterface.registerComponent(UsageStatisticsComponent);
-
- // Add our new component to all item processor buildings so we can see how many items it processed.
- // You can also inspect the entity with F8
- const buildings = [
- shapez.MetaBalancerBuilding,
- shapez.MetaCutterBuilding,
- shapez.MetaRotaterBuilding,
- shapez.MetaStackerBuilding,
- shapez.MetaMixerBuilding,
- shapez.MetaPainterBuilding,
- ];
-
- buildings.forEach(metaClass => {
- this.modInterface.runAfterMethod(metaClass, "setupEntityComponents", function (entity) {
- entity.addComponent(new UsageStatisticsComponent());
- });
- });
-
- // Register our game system so we can update and draw stuff
- this.modInterface.registerGameSystem({
- id: "demo_mod",
- systemClass: UsageStatisticsSystem,
- before: "belt",
- drawHooks: ["staticAfter"],
- });
- }
-}
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 00000000..c495152e
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,18492 @@
+{
+ "name": "shapez",
+ "version": "1.6.0",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "shapez",
+ "version": "1.6.0",
+ "hasInstallScript": true,
+ "license": "GPL-3.0-or-later",
+ "dependencies": {
+ "@msgpack/msgpack": "^3.1.2",
+ "ajv": "^6.10.2",
+ "clipboard-copy": "^3.1.0",
+ "debounce-promise": "^3.1.2",
+ "howler": "^2.1.2"
+ },
+ "devDependencies": {
+ "@electron/packager": "^18.3.6",
+ "@eslint/js": "^9.24.0",
+ "@tsconfig/node-lts": "^22.0.1",
+ "@tsconfig/strictest": "^2.0.5",
+ "@types/circular-dependency-plugin": "^5.0.5",
+ "@types/gulp": "^4.0.9",
+ "@types/gulp-htmlmin": "^1.3.32",
+ "@types/node": "^22.14.0",
+ "browser-sync": "^2.27.10",
+ "circular-dependency-plugin": "^5.2.2",
+ "css-mqpacker": "^7.0.0",
+ "cssnano": "^4.1.10",
+ "cssnano-preset-advanced": "^4.0.7",
+ "delete-empty": "^3.0.0",
+ "eslint": "^9.24.0",
+ "globals": "^15.0.0",
+ "gulp": "^4.0.2",
+ "gulp-audiosprite": "^1.1.0",
+ "gulp-cache": "^1.1.3",
+ "gulp-cached": "^1.1.1",
+ "gulp-clean": "^0.4.0",
+ "gulp-dart-sass": "^1.0.2",
+ "gulp-dom": "^1.0.0",
+ "gulp-fluent-ffmpeg": "^2.0.0",
+ "gulp-htmlmin": "^5.0.1",
+ "gulp-if": "^3.0.0",
+ "gulp-imagemin": "^7.1.0",
+ "gulp-plumber": "^1.2.1",
+ "gulp-postcss": "^8.0.0",
+ "gulp-rename": "^2.0.0",
+ "gulp-webserver": "^0.9.1",
+ "gulp-yaml": "^2.0.4",
+ "imagemin-gifsicle": "^7.0.0",
+ "imagemin-jpegtran": "^7.0.0",
+ "imagemin-mozjpeg": "^8.0.0",
+ "imagemin-pngquant": "^8.0.0",
+ "postcss-assets": "^5.0.0",
+ "postcss-critical-split": "^2.5.3",
+ "prettier": "^3.3.2",
+ "terser-webpack-plugin": "^5.3.14",
+ "ts-loader": "^9.5.2",
+ "typescript": "^5.8.2",
+ "typescript-eslint": "^8.29.1",
+ "webpack": "^5.99.9",
+ "webpack-deadcode-plugin": "^0.1.17",
+ "webpack-stream": "^7.0.0",
+ "webpack-strip-block": "^0.2.0",
+ "yaml": "^1.10.0"
+ }
+ },
+ "node_modules/@aashutoshrathi/word-wrap": {
+ "version": "1.2.6",
+ "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz",
+ "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/@babel/runtime": {
+ "version": "7.20.6",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.6.tgz",
+ "integrity": "sha512-Q+8MqP7TiHMWzSfwiJwXCjyf4GYA4Dgw3emg/7xmwsdLJOZUp+nMqcOwOzzYheuM1rhDu8FSj2l0aoMygEuXuA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "regenerator-runtime": "^0.13.11"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@electron/asar": {
+ "version": "3.4.1",
+ "resolved": "https://registry.npmjs.org/@electron/asar/-/asar-3.4.1.tgz",
+ "integrity": "sha512-i4/rNPRS84t0vSRa2HorerGRXWyF4vThfHesw0dmcWHp+cspK743UanA0suA5Q5y8kzY2y6YKrvbIUn69BCAiA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "commander": "^5.0.0",
+ "glob": "^7.1.6",
+ "minimatch": "^3.0.4"
+ },
+ "bin": {
+ "asar": "bin/asar.js"
+ },
+ "engines": {
+ "node": ">=10.12.0"
+ }
+ },
+ "node_modules/@electron/asar/node_modules/commander": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz",
+ "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/@electron/notarize": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/@electron/notarize/-/notarize-2.5.0.tgz",
+ "integrity": "sha512-jNT8nwH1f9X5GEITXaQ8IF/KdskvIkOFfB2CvwumsveVidzpSc+mvhhTMdAGSYF3O+Nq49lJ7y+ssODRXu06+A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^4.1.1",
+ "fs-extra": "^9.0.1",
+ "promise-retry": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 10.0.0"
+ }
+ },
+ "node_modules/@electron/osx-sign": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/@electron/osx-sign/-/osx-sign-1.3.3.tgz",
+ "integrity": "sha512-KZ8mhXvWv2rIEgMbWZ4y33bDHyUKMXnx4M0sTyPNK/vcB81ImdeY9Ggdqy0SWbMDgmbqyQ+phgejh6V3R2QuSg==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "compare-version": "^0.1.2",
+ "debug": "^4.3.4",
+ "fs-extra": "^10.0.0",
+ "isbinaryfile": "^4.0.8",
+ "minimist": "^1.2.6",
+ "plist": "^3.0.5"
+ },
+ "bin": {
+ "electron-osx-flat": "bin/electron-osx-flat.js",
+ "electron-osx-sign": "bin/electron-osx-sign.js"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ }
+ },
+ "node_modules/@electron/osx-sign/node_modules/fs-extra": {
+ "version": "10.1.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
+ "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^6.0.1",
+ "universalify": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@electron/osx-sign/node_modules/isbinaryfile": {
+ "version": "4.0.10",
+ "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.10.tgz",
+ "integrity": "sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/gjtorikian/"
+ }
+ },
+ "node_modules/@electron/osx-sign/node_modules/jsonfile": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
+ "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "universalify": "^2.0.0"
+ },
+ "optionalDependencies": {
+ "graceful-fs": "^4.1.6"
+ }
+ },
+ "node_modules/@electron/osx-sign/node_modules/universalify": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz",
+ "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 10.0.0"
+ }
+ },
+ "node_modules/@electron/packager": {
+ "version": "18.3.6",
+ "resolved": "https://registry.npmjs.org/@electron/packager/-/packager-18.3.6.tgz",
+ "integrity": "sha512-1eXHB5t+SQKvUiDpWGpvr90ZSSbXj+isrh3YbjCTjKT4bE4SQrKSBfukEAaBvp67+GXHFtCHjQgN9qSTFIge+Q==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "@electron/asar": "^3.2.13",
+ "@electron/get": "^3.0.0",
+ "@electron/notarize": "^2.1.0",
+ "@electron/osx-sign": "^1.0.5",
+ "@electron/universal": "^2.0.1",
+ "@electron/windows-sign": "^1.0.0",
+ "debug": "^4.0.1",
+ "extract-zip": "^2.0.0",
+ "filenamify": "^4.1.0",
+ "fs-extra": "^11.1.0",
+ "galactus": "^1.0.0",
+ "get-package-info": "^1.0.0",
+ "junk": "^3.1.0",
+ "parse-author": "^2.0.0",
+ "plist": "^3.0.0",
+ "resedit": "^2.0.0",
+ "resolve": "^1.1.6",
+ "semver": "^7.1.3",
+ "yargs-parser": "^21.1.1"
+ },
+ "bin": {
+ "electron-packager": "bin/electron-packager.js"
+ },
+ "engines": {
+ "node": ">= 16.13.0"
+ },
+ "funding": {
+ "url": "https://github.com/electron/packager?sponsor=1"
+ }
+ },
+ "node_modules/@electron/packager/node_modules/@electron/get": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/@electron/get/-/get-3.1.0.tgz",
+ "integrity": "sha512-F+nKc0xW+kVbBRhFzaMgPy3KwmuNTYX1fx6+FxxoSnNgwYX6LD7AKBTWkU0MQ6IBoe7dz069CNkR673sPAgkCQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^4.1.1",
+ "env-paths": "^2.2.0",
+ "fs-extra": "^8.1.0",
+ "got": "^11.8.5",
+ "progress": "^2.0.3",
+ "semver": "^6.2.0",
+ "sumchecker": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "optionalDependencies": {
+ "global-agent": "^3.0.0"
+ }
+ },
+ "node_modules/@electron/packager/node_modules/@electron/get/node_modules/fs-extra": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
+ "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^4.0.0",
+ "universalify": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=6 <7 || >=8"
+ }
+ },
+ "node_modules/@electron/packager/node_modules/@electron/get/node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/@electron/packager/node_modules/@electron/universal": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/@electron/universal/-/universal-2.0.3.tgz",
+ "integrity": "sha512-Wn9sPYIVFRFl5HmwMJkARCCf7rqK/EurkfQ/rJZ14mHP3iYTjZSIOSVonEAnhWeAXwtw7zOekGRlc6yTtZ0t+g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@electron/asar": "^3.3.1",
+ "@malept/cross-spawn-promise": "^2.0.0",
+ "debug": "^4.3.1",
+ "dir-compare": "^4.2.0",
+ "fs-extra": "^11.1.1",
+ "minimatch": "^9.0.3",
+ "plist": "^3.1.0"
+ },
+ "engines": {
+ "node": ">=16.4"
+ }
+ },
+ "node_modules/@electron/packager/node_modules/@electron/universal/node_modules/minimatch": {
+ "version": "9.0.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
+ "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/@electron/packager/node_modules/@malept/cross-spawn-promise": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@malept/cross-spawn-promise/-/cross-spawn-promise-2.0.0.tgz",
+ "integrity": "sha512-1DpKU0Z5ThltBwjNySMC14g0CkbyhCaz9FkhxqNsZI6uAPJXFS8cMXlBKo26FJ8ZuW6S9GCMcR9IO5k2X5/9Fg==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/malept"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/subscription/pkg/npm-.malept-cross-spawn-promise?utm_medium=referral&utm_source=npm_fund"
+ }
+ ],
+ "license": "Apache-2.0",
+ "dependencies": {
+ "cross-spawn": "^7.0.1"
+ },
+ "engines": {
+ "node": ">= 12.13.0"
+ }
+ },
+ "node_modules/@electron/packager/node_modules/@sindresorhus/is": {
+ "version": "4.6.0",
+ "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz",
+ "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sindresorhus/is?sponsor=1"
+ }
+ },
+ "node_modules/@electron/packager/node_modules/@szmarczak/http-timer": {
+ "version": "4.0.6",
+ "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz",
+ "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "defer-to-connect": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@electron/packager/node_modules/brace-expansion": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
+ "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/@electron/packager/node_modules/cacheable-request": {
+ "version": "7.0.4",
+ "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.4.tgz",
+ "integrity": "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "clone-response": "^1.0.2",
+ "get-stream": "^5.1.0",
+ "http-cache-semantics": "^4.0.0",
+ "keyv": "^4.0.0",
+ "lowercase-keys": "^2.0.0",
+ "normalize-url": "^6.0.1",
+ "responselike": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@electron/packager/node_modules/cross-spawn": {
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
+ "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@electron/packager/node_modules/decompress-response": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz",
+ "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "mimic-response": "^3.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@electron/packager/node_modules/defer-to-connect": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz",
+ "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@electron/packager/node_modules/dir-compare": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/dir-compare/-/dir-compare-4.2.0.tgz",
+ "integrity": "sha512-2xMCmOoMrdQIPHdsTawECdNPwlVFB9zGcz3kuhmBO6U3oU+UQjsue0i8ayLKpgBcm+hcXPMVSGUN9d+pvJ6+VQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "minimatch": "^3.0.5",
+ "p-limit": "^3.1.0 "
+ }
+ },
+ "node_modules/@electron/packager/node_modules/filenamify": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-4.3.0.tgz",
+ "integrity": "sha512-hcFKyUG57yWGAzu1CMt/dPzYZuv+jAJUT85bL8mrXvNe6hWj6yEHEc4EdcgiA6Z3oi1/9wXJdZPXF2dZNgwgOg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "filename-reserved-regex": "^2.0.0",
+ "strip-outer": "^1.0.1",
+ "trim-repeated": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@electron/packager/node_modules/flora-colossus": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/flora-colossus/-/flora-colossus-2.0.0.tgz",
+ "integrity": "sha512-dz4HxH6pOvbUzZpZ/yXhafjbR2I8cenK5xL0KtBFb7U2ADsR+OwXifnxZjij/pZWF775uSCMzWVd+jDik2H2IA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^4.3.4",
+ "fs-extra": "^10.1.0"
+ },
+ "engines": {
+ "node": ">= 12"
+ }
+ },
+ "node_modules/@electron/packager/node_modules/flora-colossus/node_modules/fs-extra": {
+ "version": "10.1.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
+ "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^6.0.1",
+ "universalify": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@electron/packager/node_modules/flora-colossus/node_modules/jsonfile": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
+ "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "universalify": "^2.0.0"
+ },
+ "optionalDependencies": {
+ "graceful-fs": "^4.1.6"
+ }
+ },
+ "node_modules/@electron/packager/node_modules/flora-colossus/node_modules/universalify": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz",
+ "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 10.0.0"
+ }
+ },
+ "node_modules/@electron/packager/node_modules/fs-extra": {
+ "version": "11.3.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.0.tgz",
+ "integrity": "sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^6.0.1",
+ "universalify": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=14.14"
+ }
+ },
+ "node_modules/@electron/packager/node_modules/fs-extra/node_modules/jsonfile": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
+ "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "universalify": "^2.0.0"
+ },
+ "optionalDependencies": {
+ "graceful-fs": "^4.1.6"
+ }
+ },
+ "node_modules/@electron/packager/node_modules/fs-extra/node_modules/universalify": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz",
+ "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 10.0.0"
+ }
+ },
+ "node_modules/@electron/packager/node_modules/galactus": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/galactus/-/galactus-1.0.0.tgz",
+ "integrity": "sha512-R1fam6D4CyKQGNlvJne4dkNF+PvUUl7TAJInvTGa9fti9qAv95quQz29GXapA4d8Ec266mJJxFVh82M4GIIGDQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^4.3.4",
+ "flora-colossus": "^2.0.0",
+ "fs-extra": "^10.1.0"
+ },
+ "engines": {
+ "node": ">= 12"
+ }
+ },
+ "node_modules/@electron/packager/node_modules/galactus/node_modules/fs-extra": {
+ "version": "10.1.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
+ "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^6.0.1",
+ "universalify": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@electron/packager/node_modules/galactus/node_modules/jsonfile": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
+ "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "universalify": "^2.0.0"
+ },
+ "optionalDependencies": {
+ "graceful-fs": "^4.1.6"
+ }
+ },
+ "node_modules/@electron/packager/node_modules/galactus/node_modules/universalify": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz",
+ "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 10.0.0"
+ }
+ },
+ "node_modules/@electron/packager/node_modules/get-stream": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
+ "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "pump": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@electron/packager/node_modules/got": {
+ "version": "11.8.6",
+ "resolved": "https://registry.npmjs.org/got/-/got-11.8.6.tgz",
+ "integrity": "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@sindresorhus/is": "^4.0.0",
+ "@szmarczak/http-timer": "^4.0.5",
+ "@types/cacheable-request": "^6.0.1",
+ "@types/responselike": "^1.0.0",
+ "cacheable-lookup": "^5.0.3",
+ "cacheable-request": "^7.0.2",
+ "decompress-response": "^6.0.0",
+ "http2-wrapper": "^1.0.0-beta.5.2",
+ "lowercase-keys": "^2.0.0",
+ "p-cancelable": "^2.0.0",
+ "responselike": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10.19.0"
+ },
+ "funding": {
+ "url": "https://github.com/sindresorhus/got?sponsor=1"
+ }
+ },
+ "node_modules/@electron/packager/node_modules/lowercase-keys": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz",
+ "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@electron/packager/node_modules/mimic-response": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz",
+ "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@electron/packager/node_modules/normalize-url": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz",
+ "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@electron/packager/node_modules/p-cancelable": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz",
+ "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@electron/packager/node_modules/responselike": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz",
+ "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "lowercase-keys": "^2.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@electron/packager/node_modules/shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "shebang-regex": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@electron/packager/node_modules/shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@electron/packager/node_modules/which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "node-which": "bin/node-which"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@electron/packager/node_modules/yargs-parser": {
+ "version": "21.1.1",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
+ "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@electron/windows-sign": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/@electron/windows-sign/-/windows-sign-1.2.2.tgz",
+ "integrity": "sha512-dfZeox66AvdPtb2lD8OsIIQh12Tp0GNCRUDfBHIKGpbmopZto2/A8nSpYYLoedPIHpqkeblZ/k8OV0Gy7PYuyQ==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "cross-dirname": "^0.1.0",
+ "debug": "^4.3.4",
+ "fs-extra": "^11.1.1",
+ "minimist": "^1.2.8",
+ "postject": "^1.0.0-alpha.6"
+ },
+ "bin": {
+ "electron-windows-sign": "bin/electron-windows-sign.js"
+ },
+ "engines": {
+ "node": ">=14.14"
+ }
+ },
+ "node_modules/@electron/windows-sign/node_modules/fs-extra": {
+ "version": "11.3.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.0.tgz",
+ "integrity": "sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^6.0.1",
+ "universalify": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=14.14"
+ }
+ },
+ "node_modules/@electron/windows-sign/node_modules/jsonfile": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
+ "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "universalify": "^2.0.0"
+ },
+ "optionalDependencies": {
+ "graceful-fs": "^4.1.6"
+ }
+ },
+ "node_modules/@electron/windows-sign/node_modules/universalify": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz",
+ "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 10.0.0"
+ }
+ },
+ "node_modules/@eslint-community/eslint-utils": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
+ "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "eslint-visitor-keys": "^3.3.0"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "peerDependencies": {
+ "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
+ }
+ },
+ "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz",
+ "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ }
+ },
+ "node_modules/@eslint-community/regexpp": {
+ "version": "4.12.1",
+ "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz",
+ "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
+ }
+ },
+ "node_modules/@eslint/config-array": {
+ "version": "0.20.0",
+ "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.20.0.tgz",
+ "integrity": "sha512-fxlS1kkIjx8+vy2SjuCB94q3htSNrufYTXubwiBFeaQHbH6Ipi43gFJq2zCMt6PHhImH3Xmr0NksKDvchWlpQQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@eslint/object-schema": "^2.1.6",
+ "debug": "^4.3.1",
+ "minimatch": "^3.1.2"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/config-helpers": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.2.1.tgz",
+ "integrity": "sha512-RI17tsD2frtDu/3dmI7QRrD4bedNKPM08ziRYaC5AhkGrzIAJelm9kJU1TznK+apx6V+cqRz8tfpEeG3oIyjxw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/core": {
+ "version": "0.12.0",
+ "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.12.0.tgz",
+ "integrity": "sha512-cmrR6pytBuSMTaBweKoGMwu3EiHiEC+DoyupPmlZ0HxBJBtIxwe+j/E4XPIKNx+Q74c8lXKPwYawBf5glsTkHg==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@types/json-schema": "^7.0.15"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/eslintrc": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz",
+ "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ajv": "^6.12.4",
+ "debug": "^4.3.2",
+ "espree": "^10.0.1",
+ "globals": "^14.0.0",
+ "ignore": "^5.2.0",
+ "import-fresh": "^3.2.1",
+ "js-yaml": "^4.1.0",
+ "minimatch": "^3.1.2",
+ "strip-json-comments": "^3.1.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/@eslint/eslintrc/node_modules/acorn-jsx": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
+ "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
+ }
+ },
+ "node_modules/@eslint/eslintrc/node_modules/argparse": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+ "dev": true,
+ "license": "Python-2.0"
+ },
+ "node_modules/@eslint/eslintrc/node_modules/eslint-visitor-keys": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz",
+ "integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/@eslint/eslintrc/node_modules/espree": {
+ "version": "10.0.1",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-10.0.1.tgz",
+ "integrity": "sha512-MWkrWZbJsL2UwnjxTX3gG8FneachS/Mwg7tdGXce011sJd5b0JG54vat5KHnfSBODZ3Wvzd2WnjxyzsRoVv+ww==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "acorn": "^8.11.3",
+ "acorn-jsx": "^5.3.2",
+ "eslint-visitor-keys": "^4.0.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/@eslint/eslintrc/node_modules/globals": {
+ "version": "14.0.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz",
+ "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@eslint/eslintrc/node_modules/import-fresh": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
+ "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "parent-module": "^1.0.0",
+ "resolve-from": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@eslint/eslintrc/node_modules/js-yaml": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
+ "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "argparse": "^2.0.1"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/@eslint/eslintrc/node_modules/resolve-from": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
+ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@eslint/js": {
+ "version": "9.24.0",
+ "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.24.0.tgz",
+ "integrity": "sha512-uIY/y3z0uvOGX8cp1C2fiC4+ZmBhp6yZWkojtHL1YEMnRt1Y63HB9TM17proGEmeG7HeUY+UP36F0aknKYTpYA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/object-schema": {
+ "version": "2.1.6",
+ "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz",
+ "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/plugin-kit": {
+ "version": "0.2.8",
+ "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.8.tgz",
+ "integrity": "sha512-ZAoA40rNMPwSm+AeHpCq8STiNAwzWLJuP8Xv4CHIc9wv/PSuExjMrmjfYNj682vW0OOiZ1HKxzvjQr9XZIisQA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@eslint/core": "^0.13.0",
+ "levn": "^0.4.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/plugin-kit/node_modules/@eslint/core": {
+ "version": "0.13.0",
+ "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.13.0.tgz",
+ "integrity": "sha512-yfkgDw1KR66rkT5A8ci4irzDysN7FRpq3ttJolR88OqQikAWqwA8j5VZyas+vjyBNFIJ7MfybJ9plMILI2UrCw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@types/json-schema": "^7.0.15"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@humanfs/core": {
+ "version": "0.19.1",
+ "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz",
+ "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=18.18.0"
+ }
+ },
+ "node_modules/@humanfs/node": {
+ "version": "0.16.6",
+ "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz",
+ "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@humanfs/core": "^0.19.1",
+ "@humanwhocodes/retry": "^0.3.0"
+ },
+ "engines": {
+ "node": ">=18.18.0"
+ }
+ },
+ "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz",
+ "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=18.18"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/nzakas"
+ }
+ },
+ "node_modules/@humanwhocodes/module-importer": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
+ "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=12.22"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/nzakas"
+ }
+ },
+ "node_modules/@humanwhocodes/retry": {
+ "version": "0.4.2",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.2.tgz",
+ "integrity": "sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=18.18"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/nzakas"
+ }
+ },
+ "node_modules/@jridgewell/gen-mapping": {
+ "version": "0.3.11",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.11.tgz",
+ "integrity": "sha512-C512c1ytBTio4MrpWKlJpyFHT6+qfFL8SZ58zBzJ1OOzUEjHeF1BtjY2fH7n4x/g2OV/KiiMLAivOp1DXmiMMw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.5.0",
+ "@jridgewell/trace-mapping": "^0.3.24"
+ }
+ },
+ "node_modules/@jridgewell/resolve-uri": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
+ "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/source-map": {
+ "version": "0.3.9",
+ "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.9.tgz",
+ "integrity": "sha512-amBU75CKOOkcQLfyM6J+DnWwz41yTsWI7o8MQ003LwUIWb4NYX/evAblTx1oBBYJySqL/zHPxHXDw5ewpQaUFw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.25"
+ }
+ },
+ "node_modules/@jridgewell/sourcemap-codec": {
+ "version": "1.5.3",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.3.tgz",
+ "integrity": "sha512-AiR5uKpFxP3PjO4R19kQGIMwxyRyPuXmKEEy301V1C0+1rVjS94EZQXf1QKZYN8Q0YM+estSPhmx5JwNftv6nw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@jridgewell/trace-mapping": {
+ "version": "0.3.28",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.28.tgz",
+ "integrity": "sha512-KNNHHwW3EIp4EDYOvYFGyIFfx36R2dNJYH4knnZlF8T5jdbD5Wx8xmSaQ2gP9URkJ04LGEtlcCtwArKcmFcwKw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/resolve-uri": "^3.1.0",
+ "@jridgewell/sourcemap-codec": "^1.4.14"
+ }
+ },
+ "node_modules/@msgpack/msgpack": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/@msgpack/msgpack/-/msgpack-3.1.2.tgz",
+ "integrity": "sha512-JEW4DEtBzfe8HvUYecLU9e6+XJnKDlUAIve8FvPzF3Kzs6Xo/KuZkZJsDH0wJXl/qEZbeeE7edxDNY3kMs39hQ==",
+ "license": "ISC",
+ "engines": {
+ "node": ">= 18"
+ }
+ },
+ "node_modules/@nodelib/fs.scandir": {
+ "version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
+ "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.stat": "2.0.5",
+ "run-parallel": "^1.1.9"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.stat": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
+ "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.walk": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
+ "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.scandir": "2.1.5",
+ "fastq": "^1.6.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@socket.io/component-emitter": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz",
+ "integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@tsconfig/node-lts": {
+ "version": "22.0.1",
+ "resolved": "https://registry.npmjs.org/@tsconfig/node-lts/-/node-lts-22.0.1.tgz",
+ "integrity": "sha512-BwlbLiYurZKrj+Pa6etSE1jXmr3VEDdgJto1jEYKcpBVwZZSWVkCPyFEFYbHdIOaFMlSTtV206DYPlT109aqug==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@tsconfig/strictest": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@tsconfig/strictest/-/strictest-2.0.5.tgz",
+ "integrity": "sha512-ec4tjL2Rr0pkZ5hww65c+EEPYwxOi4Ryv+0MtjeaSQRJyq322Q27eOQiFbuNgw2hpL4hB1/W/HBGk3VKS43osg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/cacheable-request": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz",
+ "integrity": "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/http-cache-semantics": "*",
+ "@types/keyv": "^3.1.4",
+ "@types/node": "*",
+ "@types/responselike": "^1.0.0"
+ }
+ },
+ "node_modules/@types/circular-dependency-plugin": {
+ "version": "5.0.5",
+ "resolved": "https://registry.npmjs.org/@types/circular-dependency-plugin/-/circular-dependency-plugin-5.0.5.tgz",
+ "integrity": "sha512-JU1sYQWNbUluWHseLUfokakx18+BXRA9Bxji56hdY5NW0nvrJSJd4SNAl0Btpm5ima9BnUkoGEcW/2PH1QuWQA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*",
+ "webpack": "^5.1.0"
+ }
+ },
+ "node_modules/@types/circular-dependency-plugin/node_modules/@types/node": {
+ "version": "18.11.10",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.10.tgz",
+ "integrity": "sha512-juG3RWMBOqcOuXC643OAdSA525V44cVgGV6dUDuiFtss+8Fk5x1hI93Rsld43VeJVIeqlP9I7Fn9/qaVqoEAuQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/clean-css": {
+ "version": "4.2.6",
+ "resolved": "https://registry.npmjs.org/@types/clean-css/-/clean-css-4.2.6.tgz",
+ "integrity": "sha512-Ze1tf+LnGPmG6hBFMi0B4TEB0mhF7EiMM5oyjLDNPE9hxrPU0W+5+bHvO+eFPA+bt0iC1zkQMoU/iGdRVjcRbw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*",
+ "source-map": "^0.6.0"
+ }
+ },
+ "node_modules/@types/clean-css/node_modules/@types/node": {
+ "version": "18.11.10",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.10.tgz",
+ "integrity": "sha512-juG3RWMBOqcOuXC643OAdSA525V44cVgGV6dUDuiFtss+8Fk5x1hI93Rsld43VeJVIeqlP9I7Fn9/qaVqoEAuQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/cookie": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz",
+ "integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/cors": {
+ "version": "2.8.12",
+ "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.12.tgz",
+ "integrity": "sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/eslint": {
+ "version": "9.6.1",
+ "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz",
+ "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree": "*",
+ "@types/json-schema": "*"
+ }
+ },
+ "node_modules/@types/eslint-scope": {
+ "version": "3.7.7",
+ "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz",
+ "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/eslint": "*",
+ "@types/estree": "*"
+ }
+ },
+ "node_modules/@types/estree": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
+ "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/expect": {
+ "version": "1.20.4",
+ "resolved": "https://registry.npmjs.org/@types/expect/-/expect-1.20.4.tgz",
+ "integrity": "sha512-Q5Vn3yjTDyCMV50TB6VRIbQNxSE4OmZR86VSbGaNpfUolm0iePBB4KdEEHmxoY5sT2+2DIvXW0rvMDP2nHZ4Mg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/glob": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz",
+ "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/minimatch": "*",
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/glob-stream": {
+ "version": "6.1.1",
+ "resolved": "https://registry.npmjs.org/@types/glob-stream/-/glob-stream-6.1.1.tgz",
+ "integrity": "sha512-AGOUTsTdbPkRS0qDeyeS+6KypmfVpbT5j23SN8UPG63qjKXNKjXn6V9wZUr8Fin0m9l8oGYaPK8b2WUMF8xI1A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/glob": "*",
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/glob-stream/node_modules/@types/glob": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/@types/glob/-/glob-8.0.0.tgz",
+ "integrity": "sha512-l6NQsDDyQUVeoTynNpC9uRvCUint/gSUXQA2euwmTuWGvPY5LSDUu6tkCtJB2SvGQlJQzLaKqcGZP4//7EDveA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/minimatch": "*",
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/glob-stream/node_modules/@types/node": {
+ "version": "18.11.10",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.10.tgz",
+ "integrity": "sha512-juG3RWMBOqcOuXC643OAdSA525V44cVgGV6dUDuiFtss+8Fk5x1hI93Rsld43VeJVIeqlP9I7Fn9/qaVqoEAuQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/glob/node_modules/@types/node": {
+ "version": "18.11.10",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.10.tgz",
+ "integrity": "sha512-juG3RWMBOqcOuXC643OAdSA525V44cVgGV6dUDuiFtss+8Fk5x1hI93Rsld43VeJVIeqlP9I7Fn9/qaVqoEAuQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/gulp": {
+ "version": "4.0.10",
+ "resolved": "https://registry.npmjs.org/@types/gulp/-/gulp-4.0.10.tgz",
+ "integrity": "sha512-spgZHJFqiEJGwqGlf7T/k4nkBpBcLgP7T0EfN6G2vvnhUfvd4uO1h8RwpXOE8x/54DVYUs1XCAtBHkX/R3axAQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/undertaker": ">=1.2.6",
+ "@types/vinyl-fs": "*",
+ "chokidar": "^3.3.1"
+ }
+ },
+ "node_modules/@types/gulp-htmlmin": {
+ "version": "1.3.32",
+ "resolved": "https://registry.npmjs.org/@types/gulp-htmlmin/-/gulp-htmlmin-1.3.32.tgz",
+ "integrity": "sha512-G/xcBVxm0haTePU+Z8nGs+pL7tl489v2gKzm4ARrv7o9taoaXRgRbp58yDz/XkuqFUHeU5Z0/YiR9RsN+M6LSQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/html-minifier": "*",
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/gulp-htmlmin/node_modules/@types/node": {
+ "version": "18.11.10",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.10.tgz",
+ "integrity": "sha512-juG3RWMBOqcOuXC643OAdSA525V44cVgGV6dUDuiFtss+8Fk5x1hI93Rsld43VeJVIeqlP9I7Fn9/qaVqoEAuQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/html-minifier": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/@types/html-minifier/-/html-minifier-4.0.2.tgz",
+ "integrity": "sha512-4IkmkXJP/25R2fZsCHDX2abztXuQRzUAZq39PfCMz2loLFj8vS9y7aF6vDl58koXSTpsF+eL4Lc5Y4Aww/GCTQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/clean-css": "*",
+ "@types/relateurl": "*",
+ "@types/uglify-js": "*"
+ }
+ },
+ "node_modules/@types/http-cache-semantics": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz",
+ "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/json-schema": {
+ "version": "7.0.15",
+ "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
+ "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/keyv": {
+ "version": "3.1.4",
+ "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz",
+ "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/minimatch": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz",
+ "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/node": {
+ "version": "22.14.0",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-22.14.0.tgz",
+ "integrity": "sha512-Kmpl+z84ILoG+3T/zQFyAJsU6EPTmOCj8/2+83fSN6djd6I4o7uOuGIH6vq3PrjY5BGitSbFuMN18j3iknubbA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "undici-types": "~6.21.0"
+ }
+ },
+ "node_modules/@types/q": {
+ "version": "1.5.5",
+ "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.5.tgz",
+ "integrity": "sha512-L28j2FcJfSZOnL1WBjDYp2vUHCeIFlyYI/53EwD/rKUBQ7MtUUfbQWiyKJGpcnv4/WgrhWsFKrcPstcAt/J0tQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/relateurl": {
+ "version": "0.2.29",
+ "resolved": "https://registry.npmjs.org/@types/relateurl/-/relateurl-0.2.29.tgz",
+ "integrity": "sha512-QSvevZ+IRww2ldtfv1QskYsqVVVwCKQf1XbwtcyyoRvLIQzfyPhj/C+3+PKzSDRdiyejaiLgnq//XTkleorpLg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/responselike": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.3.tgz",
+ "integrity": "sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/uglify-js": {
+ "version": "3.17.1",
+ "resolved": "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.17.1.tgz",
+ "integrity": "sha512-GkewRA4i5oXacU/n4MA9+bLgt5/L3F1mKrYvFGm7r2ouLXhRKjuWwo9XHNnbx6WF3vlGW21S3fCvgqxvxXXc5g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "source-map": "^0.6.1"
+ }
+ },
+ "node_modules/@types/undertaker": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/@types/undertaker/-/undertaker-1.2.8.tgz",
+ "integrity": "sha512-gW3PRqCHYpo45XFQHJBhch7L6hytPsIe0QeLujlnFsjHPnXLhJcPdN6a9368d7aIQgH2I/dUTPFBlGeSNA3qOg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*",
+ "@types/undertaker-registry": "*",
+ "async-done": "~1.3.2"
+ }
+ },
+ "node_modules/@types/undertaker-registry": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@types/undertaker-registry/-/undertaker-registry-1.0.1.tgz",
+ "integrity": "sha512-Z4TYuEKn9+RbNVk1Ll2SS4x1JeLHecolIbM/a8gveaHsW0Hr+RQMraZACwTO2VD7JvepgA6UO1A1VrbktQrIbQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/undertaker/node_modules/@types/node": {
+ "version": "18.11.10",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.10.tgz",
+ "integrity": "sha512-juG3RWMBOqcOuXC643OAdSA525V44cVgGV6dUDuiFtss+8Fk5x1hI93Rsld43VeJVIeqlP9I7Fn9/qaVqoEAuQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/vinyl": {
+ "version": "2.0.7",
+ "resolved": "https://registry.npmjs.org/@types/vinyl/-/vinyl-2.0.7.tgz",
+ "integrity": "sha512-4UqPv+2567NhMQuMLdKAyK4yzrfCqwaTt6bLhHEs8PFcxbHILsrxaY63n4wgE/BRLDWDQeI+WcTmkXKExh9hQg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/expect": "^1.20.4",
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/vinyl-fs": {
+ "version": "2.4.12",
+ "resolved": "https://registry.npmjs.org/@types/vinyl-fs/-/vinyl-fs-2.4.12.tgz",
+ "integrity": "sha512-LgBpYIWuuGsihnlF+OOWWz4ovwCYlT03gd3DuLwex50cYZLmX3yrW+sFF9ndtmh7zcZpS6Ri47PrIu+fV+sbXw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/glob-stream": "*",
+ "@types/node": "*",
+ "@types/vinyl": "*"
+ }
+ },
+ "node_modules/@types/vinyl-fs/node_modules/@types/node": {
+ "version": "18.11.10",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.10.tgz",
+ "integrity": "sha512-juG3RWMBOqcOuXC643OAdSA525V44cVgGV6dUDuiFtss+8Fk5x1hI93Rsld43VeJVIeqlP9I7Fn9/qaVqoEAuQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/vinyl/node_modules/@types/node": {
+ "version": "18.11.10",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.10.tgz",
+ "integrity": "sha512-juG3RWMBOqcOuXC643OAdSA525V44cVgGV6dUDuiFtss+8Fk5x1hI93Rsld43VeJVIeqlP9I7Fn9/qaVqoEAuQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/yauzl": {
+ "version": "2.10.0",
+ "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.0.tgz",
+ "integrity": "sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/yauzl/node_modules/@types/node": {
+ "version": "18.11.10",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.10.tgz",
+ "integrity": "sha512-juG3RWMBOqcOuXC643OAdSA525V44cVgGV6dUDuiFtss+8Fk5x1hI93Rsld43VeJVIeqlP9I7Fn9/qaVqoEAuQ==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/@typescript-eslint/eslint-plugin": {
+ "version": "8.29.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.29.1.tgz",
+ "integrity": "sha512-ba0rr4Wfvg23vERs3eB+P3lfj2E+2g3lhWcCVukUuhtcdUx5lSIFZlGFEBHKr+3zizDa/TvZTptdNHVZWAkSBg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/regexpp": "^4.10.0",
+ "@typescript-eslint/scope-manager": "8.29.1",
+ "@typescript-eslint/type-utils": "8.29.1",
+ "@typescript-eslint/utils": "8.29.1",
+ "@typescript-eslint/visitor-keys": "8.29.1",
+ "graphemer": "^1.4.0",
+ "ignore": "^5.3.1",
+ "natural-compare": "^1.4.0",
+ "ts-api-utils": "^2.0.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0",
+ "eslint": "^8.57.0 || ^9.0.0",
+ "typescript": ">=4.8.4 <5.9.0"
+ }
+ },
+ "node_modules/@typescript-eslint/eslint-plugin/node_modules/@eslint-community/regexpp": {
+ "version": "4.10.0",
+ "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz",
+ "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": {
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz",
+ "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/@typescript-eslint/parser": {
+ "version": "8.29.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.29.1.tgz",
+ "integrity": "sha512-zczrHVEqEaTwh12gWBIJWj8nx+ayDcCJs06yoNMY0kwjMWDM6+kppljY+BxWI06d2Ja+h4+WdufDcwMnnMEWmg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/scope-manager": "8.29.1",
+ "@typescript-eslint/types": "8.29.1",
+ "@typescript-eslint/typescript-estree": "8.29.1",
+ "@typescript-eslint/visitor-keys": "8.29.1",
+ "debug": "^4.3.4"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^8.57.0 || ^9.0.0",
+ "typescript": ">=4.8.4 <5.9.0"
+ }
+ },
+ "node_modules/@typescript-eslint/scope-manager": {
+ "version": "8.29.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.29.1.tgz",
+ "integrity": "sha512-2nggXGX5F3YrsGN08pw4XpMLO1Rgtnn4AzTegC2MDesv6q3QaTU5yU7IbS1tf1IwCR0Hv/1EFygLn9ms6LIpDA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/types": "8.29.1",
+ "@typescript-eslint/visitor-keys": "8.29.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/type-utils": {
+ "version": "8.29.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.29.1.tgz",
+ "integrity": "sha512-DkDUSDwZVCYN71xA4wzySqqcZsHKic53A4BLqmrWFFpOpNSoxX233lwGu/2135ymTCR04PoKiEEEvN1gFYg4Tw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/typescript-estree": "8.29.1",
+ "@typescript-eslint/utils": "8.29.1",
+ "debug": "^4.3.4",
+ "ts-api-utils": "^2.0.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^8.57.0 || ^9.0.0",
+ "typescript": ">=4.8.4 <5.9.0"
+ }
+ },
+ "node_modules/@typescript-eslint/types": {
+ "version": "8.29.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.29.1.tgz",
+ "integrity": "sha512-VT7T1PuJF1hpYC3AGm2rCgJBjHL3nc+A/bhOp9sGMKfi5v0WufsX/sHCFBfNTx2F+zA6qBc/PD0/kLRLjdt8mQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/typescript-estree": {
+ "version": "8.29.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.29.1.tgz",
+ "integrity": "sha512-l1enRoSaUkQxOQnbi0KPUtqeZkSiFlqrx9/3ns2rEDhGKfTa+88RmXqedC1zmVTOWrLc2e6DEJrTA51C9iLH5g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/types": "8.29.1",
+ "@typescript-eslint/visitor-keys": "8.29.1",
+ "debug": "^4.3.4",
+ "fast-glob": "^3.3.2",
+ "is-glob": "^4.0.3",
+ "minimatch": "^9.0.4",
+ "semver": "^7.6.0",
+ "ts-api-utils": "^2.0.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.8.4 <5.9.0"
+ }
+ },
+ "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+ "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/typescript-estree/node_modules/braces": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
+ "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fill-range": "^7.1.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@typescript-eslint/typescript-estree/node_modules/fast-glob": {
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
+ "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.stat": "^2.0.2",
+ "@nodelib/fs.walk": "^1.2.3",
+ "glob-parent": "^5.1.2",
+ "merge2": "^1.3.0",
+ "micromatch": "^4.0.8"
+ },
+ "engines": {
+ "node": ">=8.6.0"
+ }
+ },
+ "node_modules/@typescript-eslint/typescript-estree/node_modules/fill-range": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
+ "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "to-regex-range": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@typescript-eslint/typescript-estree/node_modules/micromatch": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
+ "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "braces": "^3.0.3",
+ "picomatch": "^2.3.1"
+ },
+ "engines": {
+ "node": ">=8.6"
+ }
+ },
+ "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": {
+ "version": "9.0.4",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz",
+ "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": {
+ "version": "7.6.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz",
+ "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "lru-cache": "^6.0.0"
+ },
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@typescript-eslint/utils": {
+ "version": "8.29.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.29.1.tgz",
+ "integrity": "sha512-QAkFEbytSaB8wnmB+DflhUPz6CLbFWE2SnSCrRMEa+KnXIzDYbpsn++1HGvnfAsUY44doDXmvRkO5shlM/3UfA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.4.0",
+ "@typescript-eslint/scope-manager": "8.29.1",
+ "@typescript-eslint/types": "8.29.1",
+ "@typescript-eslint/typescript-estree": "8.29.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^8.57.0 || ^9.0.0",
+ "typescript": ">=4.8.4 <5.9.0"
+ }
+ },
+ "node_modules/@typescript-eslint/visitor-keys": {
+ "version": "8.29.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.29.1.tgz",
+ "integrity": "sha512-RGLh5CRaUEf02viP5c1Vh1cMGffQscyHe7HPAzGpfmfflFg1wUz2rYxd+OZqwpeypYvZ8UxSxuIpF++fmOzEcg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/types": "8.29.1",
+ "eslint-visitor-keys": "^4.2.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@webassemblyjs/ast": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz",
+ "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@webassemblyjs/helper-numbers": "1.13.2",
+ "@webassemblyjs/helper-wasm-bytecode": "1.13.2"
+ }
+ },
+ "node_modules/@webassemblyjs/floating-point-hex-parser": {
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz",
+ "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@webassemblyjs/helper-api-error": {
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz",
+ "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@webassemblyjs/helper-buffer": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz",
+ "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@webassemblyjs/helper-numbers": {
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz",
+ "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@webassemblyjs/floating-point-hex-parser": "1.13.2",
+ "@webassemblyjs/helper-api-error": "1.13.2",
+ "@xtuc/long": "4.2.2"
+ }
+ },
+ "node_modules/@webassemblyjs/helper-wasm-bytecode": {
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz",
+ "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@webassemblyjs/helper-wasm-section": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz",
+ "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@webassemblyjs/ast": "1.14.1",
+ "@webassemblyjs/helper-buffer": "1.14.1",
+ "@webassemblyjs/helper-wasm-bytecode": "1.13.2",
+ "@webassemblyjs/wasm-gen": "1.14.1"
+ }
+ },
+ "node_modules/@webassemblyjs/ieee754": {
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz",
+ "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@xtuc/ieee754": "^1.2.0"
+ }
+ },
+ "node_modules/@webassemblyjs/leb128": {
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz",
+ "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@xtuc/long": "4.2.2"
+ }
+ },
+ "node_modules/@webassemblyjs/utf8": {
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz",
+ "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@webassemblyjs/wasm-edit": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz",
+ "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@webassemblyjs/ast": "1.14.1",
+ "@webassemblyjs/helper-buffer": "1.14.1",
+ "@webassemblyjs/helper-wasm-bytecode": "1.13.2",
+ "@webassemblyjs/helper-wasm-section": "1.14.1",
+ "@webassemblyjs/wasm-gen": "1.14.1",
+ "@webassemblyjs/wasm-opt": "1.14.1",
+ "@webassemblyjs/wasm-parser": "1.14.1",
+ "@webassemblyjs/wast-printer": "1.14.1"
+ }
+ },
+ "node_modules/@webassemblyjs/wasm-gen": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz",
+ "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@webassemblyjs/ast": "1.14.1",
+ "@webassemblyjs/helper-wasm-bytecode": "1.13.2",
+ "@webassemblyjs/ieee754": "1.13.2",
+ "@webassemblyjs/leb128": "1.13.2",
+ "@webassemblyjs/utf8": "1.13.2"
+ }
+ },
+ "node_modules/@webassemblyjs/wasm-opt": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz",
+ "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@webassemblyjs/ast": "1.14.1",
+ "@webassemblyjs/helper-buffer": "1.14.1",
+ "@webassemblyjs/wasm-gen": "1.14.1",
+ "@webassemblyjs/wasm-parser": "1.14.1"
+ }
+ },
+ "node_modules/@webassemblyjs/wasm-parser": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz",
+ "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@webassemblyjs/ast": "1.14.1",
+ "@webassemblyjs/helper-api-error": "1.13.2",
+ "@webassemblyjs/helper-wasm-bytecode": "1.13.2",
+ "@webassemblyjs/ieee754": "1.13.2",
+ "@webassemblyjs/leb128": "1.13.2",
+ "@webassemblyjs/utf8": "1.13.2"
+ }
+ },
+ "node_modules/@webassemblyjs/wast-printer": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz",
+ "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@webassemblyjs/ast": "1.14.1",
+ "@xtuc/long": "4.2.2"
+ }
+ },
+ "node_modules/@xmldom/xmldom": {
+ "version": "0.8.10",
+ "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.10.tgz",
+ "integrity": "sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
+ "node_modules/@xtuc/ieee754": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz",
+ "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==",
+ "dev": true,
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/@xtuc/long": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz",
+ "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==",
+ "dev": true,
+ "license": "Apache-2.0"
+ },
+ "node_modules/abab": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz",
+ "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==",
+ "dev": true,
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/accepts": {
+ "version": "1.3.8",
+ "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
+ "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "mime-types": "~2.1.34",
+ "negotiator": "0.6.3"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/acorn": {
+ "version": "8.14.1",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz",
+ "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "acorn": "bin/acorn"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/acorn-globals": {
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.4.tgz",
+ "integrity": "sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "acorn": "^6.0.1",
+ "acorn-walk": "^6.0.1"
+ }
+ },
+ "node_modules/acorn-globals/node_modules/acorn": {
+ "version": "6.4.2",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz",
+ "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "acorn": "bin/acorn"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/acorn-walk": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.2.0.tgz",
+ "integrity": "sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/ajv": {
+ "version": "6.12.6",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/ajv-formats": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz",
+ "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ajv": "^8.0.0"
+ },
+ "peerDependencies": {
+ "ajv": "^8.0.0"
+ },
+ "peerDependenciesMeta": {
+ "ajv": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/ajv-formats/node_modules/ajv": {
+ "version": "8.17.1",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
+ "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.3",
+ "fast-uri": "^3.0.1",
+ "json-schema-traverse": "^1.0.0",
+ "require-from-string": "^2.0.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/ajv-formats/node_modules/json-schema-traverse": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/alphanum-sort": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz",
+ "integrity": "sha512-0FcBfdcmaumGPQ0qPn7Q5qTgz/ooXgIyp1rf8ik5bGX8mpE2YHjC0P/eyQvxu1GURYQgq9ozf2mteQ5ZD9YiyQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/ansi-colors": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz",
+ "integrity": "sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-wrap": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ansi-cyan": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-cyan/-/ansi-cyan-0.1.1.tgz",
+ "integrity": "sha512-eCjan3AVo/SxZ0/MyIYRtkpxIu/H3xZN7URr1vXVrISxeyz8fUFz0FJziamK4sS8I+t35y4rHg1b2PklyBe/7A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-wrap": "0.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ansi-gray": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-gray/-/ansi-gray-0.1.1.tgz",
+ "integrity": "sha512-HrgGIZUl8h2EHuZaU9hTR/cU5nhKxpVE1V6kdGsQ8e4zirElJ5fvtfc8N7Q1oq1aatO275i8pUFUCpNWCAnVWw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-wrap": "0.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ansi-red": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-red/-/ansi-red-0.1.1.tgz",
+ "integrity": "sha512-ewaIr5y+9CUTGFwZfpECUbFlGcC0GCw1oqR9RI6h1gQCd9Aj2GxSckCnPsVJnmfMZbwFYE+leZGASgkWl06Jow==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-wrap": "0.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ansi-regex": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz",
+ "integrity": "sha512-sGwIGMjhYdW26/IhwK2gkWWI8DRCVO6uj3hYgHT+zD+QL1pa37tM3ujhyfcJIYSbsxp7Gxhy7zrRW/1AHm4BmA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/ansi-styles/node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/ansi-wrap": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz",
+ "integrity": "sha512-ZyznvL8k/FZeQHr2T6LzcJ/+vBApDnMNZvfVFy3At0knswWd6rJ3/0Hhmpu8oqa6C92npmozs890sX9Dl6q+Qw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/anymatch": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz",
+ "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "micromatch": "^3.1.4",
+ "normalize-path": "^2.1.1"
+ }
+ },
+ "node_modules/anymatch/node_modules/normalize-path": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz",
+ "integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "remove-trailing-separator": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/append-buffer": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/append-buffer/-/append-buffer-1.0.2.tgz",
+ "integrity": "sha512-WLbYiXzD3y/ATLZFufV/rZvWdZOs+Z/+5v1rBZ463Jn398pa6kcde27cvozYnBoxXblGZTFfoPpsaEw0orU5BA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "buffer-equal": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/arch": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/arch/-/arch-2.2.0.tgz",
+ "integrity": "sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/archive-type": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/archive-type/-/archive-type-4.0.0.tgz",
+ "integrity": "sha512-zV4Ky0v1F8dBrdYElwTvQhweQ0P7Kwc1aluqJsYtOBP01jXcWCyW2IEfI1YiqsG+Iy7ZR+o5LF1N+PGECBxHWA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "file-type": "^4.2.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/archive-type/node_modules/file-type": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/file-type/-/file-type-4.4.0.tgz",
+ "integrity": "sha512-f2UbFQEk7LXgWpi5ntcO86OeA/cC80fuDDDaX/fZ2ZGel+AF7leRQqBBW1eJNiiQkrZlAoM6P+VYP5P6bOlDEQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/archy": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz",
+ "integrity": "sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/argparse": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+ "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "sprintf-js": "~1.0.2"
+ }
+ },
+ "node_modules/arr-diff": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
+ "integrity": "sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/arr-filter": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/arr-filter/-/arr-filter-1.1.2.tgz",
+ "integrity": "sha512-A2BETWCqhsecSvCkWAeVBFLH6sXEUGASuzkpjL3GR1SlL/PWL6M3J8EAAld2Uubmh39tvkJTqC9LeLHCUKmFXA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "make-iterator": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/arr-flatten": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz",
+ "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/arr-map": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/arr-map/-/arr-map-2.0.2.tgz",
+ "integrity": "sha512-tVqVTHt+Q5Xb09qRkbu+DidW1yYzz5izWS2Xm2yFm7qJnmUfz4HPzNxbHkdRJbz2lrqI7S+z17xNYdFcBBO8Hw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "make-iterator": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/arr-union": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
+ "integrity": "sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/array-each": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz",
+ "integrity": "sha512-zHjL5SZa68hkKHBFBK6DJCTtr9sfTCPCaph/L7tMSLcTFgy+zX7E+6q5UArbtOtMBCtxdICpfTCspRse+ywyXA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/array-equal": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz",
+ "integrity": "sha512-H3LU5RLiSsGXPhN+Nipar0iR0IofH+8r89G2y1tBKxQ/agagKyAjhkAFDRBfodP2caPrNKHpAWNIM/c9yeL7uA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/array-find-index": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz",
+ "integrity": "sha512-M1HQyIXcBGtVywBt8WVdim+lrNaK7VHp99Qt5pSNziXznKHViIBbXWtfRTpEFpF/c4FdfxNAsCCwPp5phBYJtw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/array-initial": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/array-initial/-/array-initial-1.1.0.tgz",
+ "integrity": "sha512-BC4Yl89vneCYfpLrs5JU2aAu9/a+xWbeKhvISg9PT7eWFB9UlRvI+rKEtk6mgxWr3dSkk9gQ8hCrdqt06NXPdw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "array-slice": "^1.0.0",
+ "is-number": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/array-initial/node_modules/is-number": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz",
+ "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/array-last": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/array-last/-/array-last-1.3.0.tgz",
+ "integrity": "sha512-eOCut5rXlI6aCOS7Z7kCplKRKyiFQ6dHFBem4PwlwKeNFk2/XxTrhRh5T9PyaEWGy/NHTZWbY+nsZlNFJu9rYg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-number": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/array-last/node_modules/is-number": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz",
+ "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/array-slice": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz",
+ "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/array-sort": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/array-sort/-/array-sort-1.0.0.tgz",
+ "integrity": "sha512-ihLeJkonmdiAsD7vpgN3CRcx2J2S0TiYW+IS/5zHBI7mKUq3ySvBdzzBfD236ubDBQFiiyG3SWCPc+msQ9KoYg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "default-compare": "^1.0.0",
+ "get-value": "^2.0.6",
+ "kind-of": "^5.0.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/array-sort/node_modules/kind-of": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+ "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/array-union": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
+ "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/array-unique": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
+ "integrity": "sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/array.prototype.reduce": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/array.prototype.reduce/-/array.prototype.reduce-1.0.5.tgz",
+ "integrity": "sha512-kDdugMl7id9COE8R7MHF5jWk7Dqt/fs4Pv+JXoICnYwqpjjjbUurz6w5fT5IG6brLdJhv6/VoHB0H7oyIBXd+Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.4",
+ "es-abstract": "^1.20.4",
+ "es-array-method-boxes-properly": "^1.0.0",
+ "is-string": "^1.0.7"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/asn1": {
+ "version": "0.2.6",
+ "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz",
+ "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "safer-buffer": "~2.1.0"
+ }
+ },
+ "node_modules/assert-plus": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+ "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8"
+ }
+ },
+ "node_modules/assets": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/assets/-/assets-3.0.1.tgz",
+ "integrity": "sha512-fTyLNf/9V24y5zO83f4DAEuvaKj7MWBixbnqdZneAhsv1r21yQ/6ogZfvXHmphJAHsz4DhuOwHeJKVbGqqvk0Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "async": "^2.5.0",
+ "bluebird": "^3.4.6",
+ "calipers": "^2.0.0",
+ "calipers-gif": "^2.0.0",
+ "calipers-jpeg": "^2.0.0",
+ "calipers-png": "^2.0.0",
+ "calipers-svg": "^2.0.0",
+ "calipers-webp": "^2.0.0",
+ "glob": "^7.0.6",
+ "lodash": "^4.15.0",
+ "mime": "^2.4.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/assets/node_modules/mime": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz",
+ "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "mime": "cli.js"
+ },
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
+ "node_modules/assign-symbols": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz",
+ "integrity": "sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/async": {
+ "version": "2.6.4",
+ "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz",
+ "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "lodash": "^4.17.14"
+ }
+ },
+ "node_modules/async-done": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/async-done/-/async-done-1.3.2.tgz",
+ "integrity": "sha512-uYkTP8dw2og1tu1nmza1n1CMW0qb8gWWlwqMmLb7MhBVs4BXrFziT6HXUd+/RlRA/i4H9AkofYloUbs1fwMqlw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "end-of-stream": "^1.1.0",
+ "once": "^1.3.2",
+ "process-nextick-args": "^2.0.0",
+ "stream-exhaust": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/async-each": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz",
+ "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/async-each-series": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/async-each-series/-/async-each-series-0.1.1.tgz",
+ "integrity": "sha512-p4jj6Fws4Iy2m0iCmI2am2ZNZCgbdgE+P8F/8csmn2vx7ixXrO2zGcuNsD46X5uZSVecmkEy/M06X2vG8KD6dQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/async-limiter": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz",
+ "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/async-settle": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/async-settle/-/async-settle-1.0.0.tgz",
+ "integrity": "sha512-VPXfB4Vk49z1LHHodrEQ6Xf7W4gg1w0dAPROHngx7qgDjqmIQ+fXmwgGXTW/ITLai0YLSvWepJOP9EVpMnEAcw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "async-done": "^1.2.2"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/asynckit": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/at-least-node": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz",
+ "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">= 4.0.0"
+ }
+ },
+ "node_modules/atob": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
+ "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==",
+ "dev": true,
+ "license": "(MIT OR Apache-2.0)",
+ "bin": {
+ "atob": "bin/atob.js"
+ },
+ "engines": {
+ "node": ">= 4.5.0"
+ }
+ },
+ "node_modules/audiosprite": {
+ "version": "0.7.2",
+ "resolved": "https://registry.npmjs.org/audiosprite/-/audiosprite-0.7.2.tgz",
+ "integrity": "sha512-9Z6UwUuv4To5nUQNRIw5/Q3qA7HYm0ANzoW5EDGPEsU2oIRVgmIlLlm9YZfpPKoeUxt54vMStl2/762189VmJw==",
+ "dev": true,
+ "dependencies": {
+ "async": "~0.9.0",
+ "glob": "^6.0.4",
+ "mkdirp": "^0.5.0",
+ "optimist": "~0.6.1",
+ "underscore": "~1.8.3",
+ "winston": "~1.0.0"
+ },
+ "bin": {
+ "audiosprite": "cli.js"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/audiosprite/node_modules/async": {
+ "version": "0.9.2",
+ "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz",
+ "integrity": "sha512-l6ToIJIotphWahxxHyzK9bnLR6kM4jJIIgLShZeqLY7iboHoGkdgFl7W2/Ivi4SkMJYGKqW8vSuk0uKUj6qsSw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/audiosprite/node_modules/glob": {
+ "version": "6.0.4",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz",
+ "integrity": "sha512-MKZeRNyYZAVVVG1oZeLaWie1uweH40m9AZwIwxyPbTSX4hHrVYSzLg0Ro5Z5R7XKkIX+Cc6oD1rqeDJnwsB8/A==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "2 || 3",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/author-regex": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/author-regex/-/author-regex-1.0.0.tgz",
+ "integrity": "sha512-KbWgR8wOYRAPekEmMXrYYdc7BRyhn2Ftk7KWfMUnQ43hFdojWEFRxhhRUm3/OFEdPa1r0KAvTTg9YQK57xTe0g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8"
+ }
+ },
+ "node_modules/autoprefixer": {
+ "version": "9.8.8",
+ "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.8.8.tgz",
+ "integrity": "sha512-eM9d/swFopRt5gdJ7jrpCwgvEMIayITpojhkkSMRsFHYuH5bkSQ4p/9qTEHtmNudUZh22Tehu7I6CxAW0IXTKA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "browserslist": "^4.12.0",
+ "caniuse-lite": "^1.0.30001109",
+ "normalize-range": "^0.1.2",
+ "num2fraction": "^1.2.2",
+ "picocolors": "^0.2.1",
+ "postcss": "^7.0.32",
+ "postcss-value-parser": "^4.1.0"
+ },
+ "bin": {
+ "autoprefixer": "bin/autoprefixer"
+ },
+ "funding": {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/autoprefixer"
+ }
+ },
+ "node_modules/autoprefixer/node_modules/postcss-value-parser": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
+ "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/aws-sign2": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
+ "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/aws4": {
+ "version": "1.11.0",
+ "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz",
+ "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/axios": {
+ "version": "0.21.4",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz",
+ "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "follow-redirects": "^1.14.0"
+ }
+ },
+ "node_modules/bach": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/bach/-/bach-1.2.0.tgz",
+ "integrity": "sha512-bZOOfCb3gXBXbTFXq3OZtGR88LwGeJvzu6szttaIzymOTS4ZttBNOWSv7aLZja2EMycKtRYV0Oa8SNKH/zkxvg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "arr-filter": "^1.1.1",
+ "arr-flatten": "^1.0.1",
+ "arr-map": "^2.0.0",
+ "array-each": "^1.0.0",
+ "array-initial": "^1.0.0",
+ "array-last": "^1.1.1",
+ "async-done": "^1.2.2",
+ "async-settle": "^1.0.0",
+ "now-and-later": "^2.0.0"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/base": {
+ "version": "0.11.2",
+ "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz",
+ "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cache-base": "^1.0.1",
+ "class-utils": "^0.3.5",
+ "component-emitter": "^1.2.1",
+ "define-property": "^1.0.0",
+ "isobject": "^3.0.1",
+ "mixin-deep": "^1.2.0",
+ "pascalcase": "^0.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/base/node_modules/define-property": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+ "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-descriptor": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/base64-js": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
+ "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/base64id": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz",
+ "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^4.5.0 || >= 5.9"
+ }
+ },
+ "node_modules/batch": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz",
+ "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/bcrypt-pbkdf": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
+ "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "tweetnacl": "^0.14.3"
+ }
+ },
+ "node_modules/big.js": {
+ "version": "5.2.2",
+ "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
+ "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/bin-build": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/bin-build/-/bin-build-3.0.0.tgz",
+ "integrity": "sha512-jcUOof71/TNAI2uM5uoUaDq2ePcVBQ3R/qhxAz1rX7UfvduAL/RXD3jXzvn8cVcDJdGVkiR1shal3OH0ImpuhA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "decompress": "^4.0.0",
+ "download": "^6.2.2",
+ "execa": "^0.7.0",
+ "p-map-series": "^1.0.0",
+ "tempfile": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/bin-build/node_modules/cross-spawn": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz",
+ "integrity": "sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "lru-cache": "^4.0.1",
+ "shebang-command": "^1.2.0",
+ "which": "^1.2.9"
+ }
+ },
+ "node_modules/bin-build/node_modules/execa": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz",
+ "integrity": "sha512-RztN09XglpYI7aBBrJCPW95jEH7YF1UEPOoX9yDhUTPdp7mK+CQvnLTuD10BNXZ3byLTu2uehZ8EcKT/4CGiFw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cross-spawn": "^5.0.1",
+ "get-stream": "^3.0.0",
+ "is-stream": "^1.1.0",
+ "npm-run-path": "^2.0.0",
+ "p-finally": "^1.0.0",
+ "signal-exit": "^3.0.0",
+ "strip-eof": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/bin-build/node_modules/lru-cache": {
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
+ "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "pseudomap": "^1.0.2",
+ "yallist": "^2.1.2"
+ }
+ },
+ "node_modules/bin-build/node_modules/yallist": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
+ "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/bin-check": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/bin-check/-/bin-check-4.1.0.tgz",
+ "integrity": "sha512-b6weQyEUKsDGFlACWSIOfveEnImkJyK/FGW6FAG42loyoquvjdtOIqO6yBFzHyqyVVhNgNkQxxx09SFLK28YnA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "execa": "^0.7.0",
+ "executable": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/bin-check/node_modules/cross-spawn": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz",
+ "integrity": "sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "lru-cache": "^4.0.1",
+ "shebang-command": "^1.2.0",
+ "which": "^1.2.9"
+ }
+ },
+ "node_modules/bin-check/node_modules/execa": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz",
+ "integrity": "sha512-RztN09XglpYI7aBBrJCPW95jEH7YF1UEPOoX9yDhUTPdp7mK+CQvnLTuD10BNXZ3byLTu2uehZ8EcKT/4CGiFw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cross-spawn": "^5.0.1",
+ "get-stream": "^3.0.0",
+ "is-stream": "^1.1.0",
+ "npm-run-path": "^2.0.0",
+ "p-finally": "^1.0.0",
+ "signal-exit": "^3.0.0",
+ "strip-eof": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/bin-check/node_modules/lru-cache": {
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
+ "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "pseudomap": "^1.0.2",
+ "yallist": "^2.1.2"
+ }
+ },
+ "node_modules/bin-check/node_modules/yallist": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
+ "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/bin-version": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/bin-version/-/bin-version-3.1.0.tgz",
+ "integrity": "sha512-Mkfm4iE1VFt4xd4vH+gx+0/71esbfus2LsnCGe8Pi4mndSPyT+NGES/Eg99jx8/lUGWfu3z2yuB/bt5UB+iVbQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "execa": "^1.0.0",
+ "find-versions": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/bin-version-check": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/bin-version-check/-/bin-version-check-4.0.0.tgz",
+ "integrity": "sha512-sR631OrhC+1f8Cvs8WyVWOA33Y8tgwjETNPyyD/myRBXLkfS/vl74FmH/lFcRl9KY3zwGh7jFhvyk9vV3/3ilQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "bin-version": "^3.0.0",
+ "semver": "^5.6.0",
+ "semver-truncate": "^1.1.2"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/bin-version-check/node_modules/semver": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+ "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver"
+ }
+ },
+ "node_modules/bin-wrapper": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/bin-wrapper/-/bin-wrapper-4.1.0.tgz",
+ "integrity": "sha512-hfRmo7hWIXPkbpi0ZltboCMVrU+0ClXR/JgbCKKjlDjQf6igXa7OwdqNcFWQZPZTgiY7ZpzE3+LjjkLiTN2T7Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "bin-check": "^4.1.0",
+ "bin-version-check": "^4.0.0",
+ "download": "^7.1.0",
+ "import-lazy": "^3.1.0",
+ "os-filter-obj": "^2.0.0",
+ "pify": "^4.0.1"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/bin-wrapper/node_modules/@sindresorhus/is": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.7.0.tgz",
+ "integrity": "sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/bin-wrapper/node_modules/cacheable-request": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-2.1.4.tgz",
+ "integrity": "sha512-vag0O2LKZ/najSoUwDbVlnlCFvhBE/7mGTY2B5FgCBDcRD+oVV1HYTOwM6JZfMg/hIcM6IwnTZ1uQQL5/X3xIQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "clone-response": "1.0.2",
+ "get-stream": "3.0.0",
+ "http-cache-semantics": "3.8.1",
+ "keyv": "3.0.0",
+ "lowercase-keys": "1.0.0",
+ "normalize-url": "2.0.1",
+ "responselike": "1.0.2"
+ }
+ },
+ "node_modules/bin-wrapper/node_modules/cacheable-request/node_modules/lowercase-keys": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.0.tgz",
+ "integrity": "sha512-RPlX0+PHuvxVDZ7xX+EBVAp4RsVxP/TdDSN2mJYdiq1Lc4Hz7EUSjUI7RZrKKlmrIzVhf6Jo2stj7++gVarS0A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/bin-wrapper/node_modules/clone-response": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz",
+ "integrity": "sha512-yjLXh88P599UOyPTFX0POsd7WxnbsVsGohcwzHOLspIhhpalPw1BcqED8NblyZLKcGrL8dTgMlcaZxV2jAD41Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "mimic-response": "^1.0.0"
+ }
+ },
+ "node_modules/bin-wrapper/node_modules/download": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/download/-/download-7.1.0.tgz",
+ "integrity": "sha512-xqnBTVd/E+GxJVrX5/eUJiLYjCGPwMpdL+jGhGU57BvtcA7wwhtHVbXBeUk51kOpW3S7Jn3BQbN9Q1R1Km2qDQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "archive-type": "^4.0.0",
+ "caw": "^2.0.1",
+ "content-disposition": "^0.5.2",
+ "decompress": "^4.2.0",
+ "ext-name": "^5.0.0",
+ "file-type": "^8.1.0",
+ "filenamify": "^2.0.0",
+ "get-stream": "^3.0.0",
+ "got": "^8.3.1",
+ "make-dir": "^1.2.0",
+ "p-event": "^2.1.0",
+ "pify": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/bin-wrapper/node_modules/download/node_modules/pify": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+ "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/bin-wrapper/node_modules/file-type": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/file-type/-/file-type-8.1.0.tgz",
+ "integrity": "sha512-qyQ0pzAy78gVoJsmYeNgl8uH8yKhr1lVhW7JbzJmnlRi0I4R2eEDEJZVKG8agpDnLpacwNbDhLNG/LMdxHD2YQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/bin-wrapper/node_modules/got": {
+ "version": "8.3.2",
+ "resolved": "https://registry.npmjs.org/got/-/got-8.3.2.tgz",
+ "integrity": "sha512-qjUJ5U/hawxosMryILofZCkm3C84PLJS/0grRIpjAwu+Lkxxj5cxeCU25BG0/3mDSpXKTyZr8oh8wIgLaH0QCw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@sindresorhus/is": "^0.7.0",
+ "cacheable-request": "^2.1.1",
+ "decompress-response": "^3.3.0",
+ "duplexer3": "^0.1.4",
+ "get-stream": "^3.0.0",
+ "into-stream": "^3.1.0",
+ "is-retry-allowed": "^1.1.0",
+ "isurl": "^1.0.0-alpha5",
+ "lowercase-keys": "^1.0.0",
+ "mimic-response": "^1.0.0",
+ "p-cancelable": "^0.4.0",
+ "p-timeout": "^2.0.1",
+ "pify": "^3.0.0",
+ "safe-buffer": "^5.1.1",
+ "timed-out": "^4.0.1",
+ "url-parse-lax": "^3.0.0",
+ "url-to-options": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/bin-wrapper/node_modules/got/node_modules/pify": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+ "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/bin-wrapper/node_modules/http-cache-semantics": {
+ "version": "3.8.1",
+ "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz",
+ "integrity": "sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w==",
+ "dev": true,
+ "license": "BSD-2-Clause"
+ },
+ "node_modules/bin-wrapper/node_modules/keyv": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.0.0.tgz",
+ "integrity": "sha512-eguHnq22OE3uVoSYG0LVWNP+4ppamWr9+zWBe1bsNcovIMy6huUJFPgy4mGwCd/rnl3vOLGW1MTlu4c57CT1xA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "json-buffer": "3.0.0"
+ }
+ },
+ "node_modules/bin-wrapper/node_modules/normalize-url": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-2.0.1.tgz",
+ "integrity": "sha512-D6MUW4K/VzoJ4rJ01JFKxDrtY1v9wrgzCX5f2qj/lzH1m/lW6MhUZFKerVsnyjOhOsYzI9Kqqak+10l4LvLpMw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prepend-http": "^2.0.0",
+ "query-string": "^5.0.1",
+ "sort-keys": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/bin-wrapper/node_modules/p-cancelable": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.4.1.tgz",
+ "integrity": "sha512-HNa1A8LvB1kie7cERyy21VNeHb2CWJJYqyyC2o3klWFfMGlFmWv2Z7sFgZH8ZiaYL95ydToKTFVXgMV/Os0bBQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/bin-wrapper/node_modules/p-event": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/p-event/-/p-event-2.3.1.tgz",
+ "integrity": "sha512-NQCqOFhbpVTMX4qMe8PF8lbGtzZ+LCiN7pcNrb/413Na7+TRoe1xkKUzuWa/YEJdGQ0FvKtj35EEbDoVPO2kbA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-timeout": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/bin-wrapper/node_modules/p-timeout": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-2.0.1.tgz",
+ "integrity": "sha512-88em58dDVB/KzPEx1X0N3LwFfYZPyDc4B6eF38M1rk9VTZMbxXXgjugz8mmwpS9Ox4BDZ+t6t3QP5+/gazweIA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-finally": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/bin-wrapper/node_modules/pify": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
+ "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/bin-wrapper/node_modules/sort-keys": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-2.0.0.tgz",
+ "integrity": "sha512-/dPCrG1s3ePpWm6yBbxZq5Be1dXGLyLn9Z791chDC3NFrpkVbWGzkBwPN1knaciexFXgRJ7hzdnwZ4stHSDmjg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-plain-obj": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/binary-extensions": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
+ "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/bl": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.3.tgz",
+ "integrity": "sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "readable-stream": "^2.3.5",
+ "safe-buffer": "^5.1.1"
+ }
+ },
+ "node_modules/bluebird": {
+ "version": "3.7.2",
+ "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
+ "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/body-parser": {
+ "version": "1.8.4",
+ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.8.4.tgz",
+ "integrity": "sha512-jTeWaZdC6r5o7FUSWNTPtxeudzg3cybUEgT56clWiW3FOpZ0fbQAUoD2k/BqmQlyEI2sK3TBqs9Zp6p6Fsv/sQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "bytes": "1.0.0",
+ "depd": "0.4.5",
+ "iconv-lite": "0.4.4",
+ "media-typer": "0.3.0",
+ "on-finished": "2.1.0",
+ "qs": "2.2.4",
+ "raw-body": "1.3.0",
+ "type-is": "~1.5.1"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/body-parser/node_modules/depd": {
+ "version": "0.4.5",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-0.4.5.tgz",
+ "integrity": "sha512-MyQx8POntp7sey9ghPezYB5gIKSbcce5pkoHdFmDYkiOcsE5f5yLLBzv8Qcs9Ll1hPgmEOfIae51n4Fa7l3zxw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/body-parser/node_modules/ee-first": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.0.5.tgz",
+ "integrity": "sha512-+FCut34oNiJD2jD+YL/onRxOHF5ut3xOGgTIyEIOdYfun8AexYhEyurzv9izwhTft1Z7pdy4VlTq51K/sIsQRA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/body-parser/node_modules/iconv-lite": {
+ "version": "0.4.4",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.4.tgz",
+ "integrity": "sha512-BnjNp13aZpK4WBGbmjaNHN2MCp3P850n8zd/JLinQJ8Lsnq2Br4o2467C2waMsY5kr7Z41SL1gEqh8Vbfzg15A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/body-parser/node_modules/on-finished": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.1.0.tgz",
+ "integrity": "sha512-33+g6TZkplndl+2k2VNO1YphX5hm79DGhBP6TJcDI9o1sCFbUvO2bgxPdGanIFqZK4su6OVLwPHY9GkLQrojgA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ee-first": "1.0.5"
+ }
+ },
+ "node_modules/body-parser/node_modules/qs": {
+ "version": "2.2.4",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-2.2.4.tgz",
+ "integrity": "sha512-ptau9CngYR/IimcThDkAs7LzlZhxo92RiMHtLbOq3R6u9iDkixdSysaAVaZpYByrXWWantEJ4fVPl0xR2McSCQ==",
+ "dev": true
+ },
+ "node_modules/body-parser/node_modules/raw-body": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-1.3.0.tgz",
+ "integrity": "sha512-iuI1bOSi9tEmVCrXq02ZysXatTrhAu+fSo7XOQHhMo4g87dSy9YB2W/9Udwhz0bPpFk4UcoLhjrHgpPbRD3ktA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "bytes": "1",
+ "iconv-lite": "0.4.4"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/boolbase": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
+ "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/boolean": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz",
+ "integrity": "sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/braces": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
+ "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "arr-flatten": "^1.1.0",
+ "array-unique": "^0.3.2",
+ "extend-shallow": "^2.0.1",
+ "fill-range": "^4.0.0",
+ "isobject": "^3.0.1",
+ "repeat-element": "^1.1.2",
+ "snapdragon": "^0.8.1",
+ "snapdragon-node": "^2.0.1",
+ "split-string": "^3.0.2",
+ "to-regex": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/browser-process-hrtime": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz",
+ "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==",
+ "dev": true,
+ "license": "BSD-2-Clause"
+ },
+ "node_modules/browser-sync": {
+ "version": "2.27.10",
+ "resolved": "https://registry.npmjs.org/browser-sync/-/browser-sync-2.27.10.tgz",
+ "integrity": "sha512-xKm+6KJmJu6RuMWWbFkKwOCSqQOxYe3nOrFkKI5Tr/ZzjPxyU3pFShKK3tWnazBo/3lYQzN7fzjixG8fwJh1Xw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "browser-sync-client": "^2.27.10",
+ "browser-sync-ui": "^2.27.10",
+ "bs-recipes": "1.3.4",
+ "bs-snippet-injector": "^2.0.1",
+ "chokidar": "^3.5.1",
+ "connect": "3.6.6",
+ "connect-history-api-fallback": "^1",
+ "dev-ip": "^1.0.1",
+ "easy-extender": "^2.3.4",
+ "eazy-logger": "3.1.0",
+ "etag": "^1.8.1",
+ "fresh": "^0.5.2",
+ "fs-extra": "3.0.1",
+ "http-proxy": "^1.18.1",
+ "immutable": "^3",
+ "localtunnel": "^2.0.1",
+ "micromatch": "^4.0.2",
+ "opn": "5.3.0",
+ "portscanner": "2.2.0",
+ "qs": "6.2.3",
+ "raw-body": "^2.3.2",
+ "resp-modifier": "6.0.2",
+ "rx": "4.1.0",
+ "send": "0.16.2",
+ "serve-index": "1.9.1",
+ "serve-static": "1.13.2",
+ "server-destroy": "1.0.1",
+ "socket.io": "^4.4.1",
+ "ua-parser-js": "1.0.2",
+ "yargs": "^17.3.1"
+ },
+ "bin": {
+ "browser-sync": "dist/bin.js"
+ },
+ "engines": {
+ "node": ">= 8.0.0"
+ }
+ },
+ "node_modules/browser-sync-client": {
+ "version": "2.27.10",
+ "resolved": "https://registry.npmjs.org/browser-sync-client/-/browser-sync-client-2.27.10.tgz",
+ "integrity": "sha512-KCFKA1YDj6cNul0VsA28apohtBsdk5Wv8T82ClOZPZMZWxPj4Ny5AUbrj9UlAb/k6pdxE5HABrWDhP9+cjt4HQ==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "etag": "1.8.1",
+ "fresh": "0.5.2",
+ "mitt": "^1.1.3",
+ "rxjs": "^5.5.6",
+ "typescript": "^4.6.2"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/browser-sync-client/node_modules/typescript": {
+ "version": "4.9.3",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.3.tgz",
+ "integrity": "sha512-CIfGzTelbKNEnLpLdGFgdyKhG23CKdKgQPOBc+OUNrkJ2vr+KSzsSV5kq5iWhEQbok+quxgGzrAtGWCyU7tHnA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "bin": {
+ "tsc": "bin/tsc",
+ "tsserver": "bin/tsserver"
+ },
+ "engines": {
+ "node": ">=4.2.0"
+ }
+ },
+ "node_modules/browser-sync-ui": {
+ "version": "2.27.10",
+ "resolved": "https://registry.npmjs.org/browser-sync-ui/-/browser-sync-ui-2.27.10.tgz",
+ "integrity": "sha512-elbJILq4Uo6OQv6gsvS3Y9vRAJlWu+h8j0JDkF0X/ua+3S6SVbbiWnZc8sNOFlG7yvVGIwBED3eaYQ0iBo1Dtw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "async-each-series": "0.1.1",
+ "connect-history-api-fallback": "^1",
+ "immutable": "^3",
+ "server-destroy": "1.0.1",
+ "socket.io-client": "^4.4.1",
+ "stream-throttle": "^0.1.3"
+ }
+ },
+ "node_modules/browser-sync/node_modules/braces": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+ "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fill-range": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/browser-sync/node_modules/fill-range": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+ "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "to-regex-range": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/browser-sync/node_modules/fs-extra": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-3.0.1.tgz",
+ "integrity": "sha512-V3Z3WZWVUYd8hoCL5xfXJCaHWYzmtwW5XWYSlLgERi8PWd8bx1kUHUk8L1BT57e49oKnDDD180mjfrHc1yA9rg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "graceful-fs": "^4.1.2",
+ "jsonfile": "^3.0.0",
+ "universalify": "^0.1.0"
+ }
+ },
+ "node_modules/browser-sync/node_modules/jsonfile": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-3.0.1.tgz",
+ "integrity": "sha512-oBko6ZHlubVB5mRFkur5vgYR1UyqX+S6Y/oCfLhqNdcc2fYFlDpIoNc7AfKS1KOGcnNAkvsr0grLck9ANM815w==",
+ "dev": true,
+ "license": "MIT",
+ "optionalDependencies": {
+ "graceful-fs": "^4.1.6"
+ }
+ },
+ "node_modules/browser-sync/node_modules/micromatch": {
+ "version": "4.0.5",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
+ "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "braces": "^3.0.2",
+ "picomatch": "^2.3.1"
+ },
+ "engines": {
+ "node": ">=8.6"
+ }
+ },
+ "node_modules/browserslist": {
+ "version": "4.25.1",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.25.1.tgz",
+ "integrity": "sha512-KGj0KoOMXLpSNkkEI6Z6mShmQy0bc1I+T7K9N81k4WWMrfz+6fQ6es80B/YLAeRoKvjYE1YSHHOW1qe9xIVzHw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "caniuse-lite": "^1.0.30001726",
+ "electron-to-chromium": "^1.5.173",
+ "node-releases": "^2.0.19",
+ "update-browserslist-db": "^1.1.3"
+ },
+ "bin": {
+ "browserslist": "cli.js"
+ },
+ "engines": {
+ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
+ }
+ },
+ "node_modules/bs-recipes": {
+ "version": "1.3.4",
+ "resolved": "https://registry.npmjs.org/bs-recipes/-/bs-recipes-1.3.4.tgz",
+ "integrity": "sha512-BXvDkqhDNxXEjeGM8LFkSbR+jzmP/CYpCiVKYn+soB1dDldeU15EBNDkwVXndKuX35wnNUaPd0qSoQEAkmQtMw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/bs-snippet-injector": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/bs-snippet-injector/-/bs-snippet-injector-2.0.1.tgz",
+ "integrity": "sha512-4u8IgB+L9L+S5hknOj3ddNSb42436gsnGm1AuM15B7CdbkpQTyVWgIM5/JUBiKiRwGOR86uo0Lu/OsX+SAlJmw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/buffer": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
+ "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "base64-js": "^1.3.1",
+ "ieee754": "^1.1.13"
+ }
+ },
+ "node_modules/buffer-alloc": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz",
+ "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "buffer-alloc-unsafe": "^1.1.0",
+ "buffer-fill": "^1.0.0"
+ }
+ },
+ "node_modules/buffer-alloc-unsafe": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz",
+ "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/buffer-crc32": {
+ "version": "0.2.13",
+ "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
+ "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/buffer-equal": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.1.tgz",
+ "integrity": "sha512-QoV3ptgEaQpvVwbXdSO39iqPQTCxSF7A5U99AxbHYqUdCizL/lH2Z0A2y6nbZucxMEOtNyZfG2s6gsVugGpKkg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/buffer-fill": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz",
+ "integrity": "sha512-T7zexNBwiiaCOGDg9xNX9PBmjrubblRkENuptryuI64URkXDFum9il/JGL8Lm8wYfAXpredVXXZz7eMHilimiQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/buffer-from": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
+ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/bufferstreams": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/bufferstreams/-/bufferstreams-2.0.1.tgz",
+ "integrity": "sha512-ZswyIoBfFb3cVDsnZLLj2IDJ/0ppYdil/v2EGlZXvoefO689FokEmFEldhN5dV7R2QBxFneqTJOMIpfqhj+n0g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "readable-stream": "^2.3.6"
+ },
+ "engines": {
+ "node": ">=6.9.5"
+ }
+ },
+ "node_modules/bytes": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-1.0.0.tgz",
+ "integrity": "sha512-/x68VkHLeTl3/Ll8IvxdwzhrT+IyKc52e/oyHhA2RwqPqswSnjVbSddfPRwAsJtbilMAPSRWwAlpxdYsSWOTKQ==",
+ "dev": true
+ },
+ "node_modules/cache-base": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz",
+ "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "collection-visit": "^1.0.0",
+ "component-emitter": "^1.2.1",
+ "get-value": "^2.0.6",
+ "has-value": "^1.0.0",
+ "isobject": "^3.0.1",
+ "set-value": "^2.0.0",
+ "to-object-path": "^0.3.0",
+ "union-value": "^1.0.0",
+ "unset-value": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/cache-swap": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/cache-swap/-/cache-swap-0.3.0.tgz",
+ "integrity": "sha512-rwePCa4iVqXHrEEmQEoLR3Kea4aCTCf7JfX+mJA4Fd61Vb738TItRRv1v++emp9wfnRUKbXpIYfRJY4ThWK09g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "graceful-fs": "^4.1.2",
+ "mkdirp": "^0.5.1",
+ "object-assign": "^4.0.1",
+ "rimraf": "^2.4.0"
+ }
+ },
+ "node_modules/cacheable-lookup": {
+ "version": "5.0.4",
+ "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz",
+ "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10.6.0"
+ }
+ },
+ "node_modules/calipers": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/calipers/-/calipers-2.1.0.tgz",
+ "integrity": "sha512-D54tptnPCX7SJ5JJIpY6896GNxka+oEO3pefTIUh4tMVeeFuVPiao8Ty3ud+jBLvlzXiBmjPAdjPkMWxFrCpaQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/calipers-gif": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/calipers-gif/-/calipers-gif-2.0.0.tgz",
+ "integrity": "sha512-ZePtjAmTmugWWHDjZhrh7SZ8/8hG2sS5Dz6xyZ3bWkofLqq31c01GR0AvBg5Cn5/x4BjT9PhIi0VMjHBEO+kog==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "bluebird": "3.x.x"
+ },
+ "peerDependencies": {
+ "calipers": "2.x.x"
+ }
+ },
+ "node_modules/calipers-jpeg": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/calipers-jpeg/-/calipers-jpeg-2.1.0.tgz",
+ "integrity": "sha512-zNTtd+dWEAGcWw7qFtShcQRXotk+iI4n9chPmYAHNLzlkIA2A0/zUA5IPMBRxH6uArOv/E3D4m54Z/mkK7ulXA==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "calipers": "2.x.x"
+ }
+ },
+ "node_modules/calipers-png": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/calipers-png/-/calipers-png-2.1.0.tgz",
+ "integrity": "sha512-Iu4kwHtEXoNowsoR9CUUDc+KyFJSFhgVI0AsfYXYmo9kfEoTaQM/tLgWGzO3oisxkdeb5II3TMPDvpI+HDykjw==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "calipers": "2.x.x"
+ }
+ },
+ "node_modules/calipers-svg": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/calipers-svg/-/calipers-svg-2.0.1.tgz",
+ "integrity": "sha512-3PROqHARmj8wWudUC7DzXm1+mSocqgY7jNuehFNHgrUVrKf8o7MqDjS92vJz5LvZsAofJsoAFMajkqwbxBROSQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "bluebird": "3.x.x"
+ }
+ },
+ "node_modules/calipers-webp": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/calipers-webp/-/calipers-webp-2.0.0.tgz",
+ "integrity": "sha512-np7ZtCwUjpxz+DF/RYNYFxxaltJxlF7rIVKWnU/cKcgQ7r06/Fquw1Q/oMZiJe6hfjI911lhDY6ZC+X0MtA5rg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "bluebird": "3.x.x"
+ }
+ },
+ "node_modules/call-bind": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
+ "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "function-bind": "^1.1.1",
+ "get-intrinsic": "^1.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/caller-callsite": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz",
+ "integrity": "sha512-JuG3qI4QOftFsZyOn1qq87fq5grLIyk1JYd5lJmdA+fG7aQ9pA/i3JIJGcO3q0MrRcHlOt1U+ZeHW8Dq9axALQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "callsites": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/caller-callsite/node_modules/callsites": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz",
+ "integrity": "sha512-ksWePWBloaWPxJYQ8TL0JHvtci6G5QTKwQ95RcWAa/lzoAKuAOflGdAK92hpHXjkwb8zLxoLNUoNYZgVsaJzvQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/caller-path": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz",
+ "integrity": "sha512-MCL3sf6nCSXOwCTzvPKhN18TU7AHTvdtam8DAogxcrJ8Rjfbbg7Lgng64H9Iy+vUV6VGFClN/TyxBkAebLRR4A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "caller-callsite": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/callsites": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/camel-case": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz",
+ "integrity": "sha512-+MbKztAYHXPr1jNTSKQF52VpcFjwY5RkR7fxksV8Doo4KAYc5Fl4UJRgthBbTmEx8C54DqahhbLJkDwjI3PI/w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "no-case": "^2.2.0",
+ "upper-case": "^1.1.1"
+ }
+ },
+ "node_modules/camelcase": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz",
+ "integrity": "sha512-4nhGqUkc4BqbBBB4Q6zLuD7lzzrHYrjKGeYaEji/3tFR5VdJu9v+LilhGIVe8wxEJPPOeWo7eg8dwY13TZ1BNg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/camelcase-keys": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz",
+ "integrity": "sha512-bA/Z/DERHKqoEOrp+qeGKw1QlvEQkGZSc0XaY6VnTxZr+Kv1G5zFwttpjv8qxZ/sBPT4nthwZaAcsAZTJlSKXQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "camelcase": "^2.0.0",
+ "map-obj": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/camelcase-keys/node_modules/camelcase": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz",
+ "integrity": "sha512-DLIsRzJVBQu72meAKPkWQOLcujdXT32hwdfnkI1frSiSRMK1MofjKHf+MEx0SB6fjEFXL8fBDv1dKymBlOp4Qw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/caniuse-api": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz",
+ "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "browserslist": "^4.0.0",
+ "caniuse-lite": "^1.0.0",
+ "lodash.memoize": "^4.1.2",
+ "lodash.uniq": "^4.5.0"
+ }
+ },
+ "node_modules/caniuse-lite": {
+ "version": "1.0.30001727",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001727.tgz",
+ "integrity": "sha512-pB68nIHmbN6L/4C6MH1DokyR3bYqFwjaSs/sWDHGj4CTcFtQUQMuJftVwWkXq7mNWOybD3KhUv3oWHoGxgP14Q==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "CC-BY-4.0"
+ },
+ "node_modules/caseless": {
+ "version": "0.12.0",
+ "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
+ "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==",
+ "dev": true,
+ "license": "Apache-2.0"
+ },
+ "node_modules/caw": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/caw/-/caw-2.0.1.tgz",
+ "integrity": "sha512-Cg8/ZSBEa8ZVY9HspcGUYaK63d/bN7rqS3CYCzEGUxuYv6UlmcjzDUz2fCFFHyTvUW5Pk0I+3hkA3iXlIj6guA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "get-proxy": "^2.0.0",
+ "isurl": "^1.0.0-alpha5",
+ "tunnel-agent": "^0.6.0",
+ "url-to-options": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/chalk": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^2.2.1",
+ "escape-string-regexp": "^1.0.2",
+ "has-ansi": "^2.0.0",
+ "strip-ansi": "^3.0.0",
+ "supports-color": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/chalk/node_modules/ansi-styles": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
+ "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/chalk/node_modules/supports-color": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+ "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/chokidar": {
+ "version": "3.5.3",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
+ "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://paulmillr.com/funding/"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "anymatch": "~3.1.2",
+ "braces": "~3.0.2",
+ "glob-parent": "~5.1.2",
+ "is-binary-path": "~2.1.0",
+ "is-glob": "~4.0.1",
+ "normalize-path": "~3.0.0",
+ "readdirp": "~3.6.0"
+ },
+ "engines": {
+ "node": ">= 8.10.0"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/chokidar/node_modules/anymatch": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
+ "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "normalize-path": "^3.0.0",
+ "picomatch": "^2.0.4"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/chokidar/node_modules/braces": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+ "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fill-range": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/chokidar/node_modules/fill-range": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+ "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "to-regex-range": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/chrome-trace-event": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz",
+ "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.0"
+ }
+ },
+ "node_modules/circular-dependency-plugin": {
+ "version": "5.2.2",
+ "resolved": "https://registry.npmjs.org/circular-dependency-plugin/-/circular-dependency-plugin-5.2.2.tgz",
+ "integrity": "sha512-g38K9Cm5WRwlaH6g03B9OEz/0qRizI+2I7n+Gz+L5DxXJAPAiWQvwlYNm1V1jkdpUv95bOe/ASm2vfi/G560jQ==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=6.0.0"
+ },
+ "peerDependencies": {
+ "webpack": ">=4.0.1"
+ }
+ },
+ "node_modules/class-utils": {
+ "version": "0.3.6",
+ "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz",
+ "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "arr-union": "^3.1.0",
+ "define-property": "^0.2.5",
+ "isobject": "^3.0.0",
+ "static-extend": "^0.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/clean-css": {
+ "version": "4.2.4",
+ "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.4.tgz",
+ "integrity": "sha512-EJUDT7nDVFDvaQgAo2G/PJvxmp1o/c6iXLbswsBbUFXi1Nr+AjA2cKmfbKDMjMvzEe75g3P6JkaDDAKk96A85A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "source-map": "~0.6.0"
+ },
+ "engines": {
+ "node": ">= 4.0"
+ }
+ },
+ "node_modules/clipboard-copy": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/clipboard-copy/-/clipboard-copy-3.2.0.tgz",
+ "integrity": "sha512-vooFaGFL6ulEP1liiaWFBmmfuPm3cY3y7T9eB83ZTnYc/oFeAKsq3NcDrOkBC8XaauEE8zHQwI7k0+JSYiVQSQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/cliui": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
+ "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "string-width": "^4.2.0",
+ "strip-ansi": "^6.0.1",
+ "wrap-ansi": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/cliui/node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/cliui/node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/clone": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
+ "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8"
+ }
+ },
+ "node_modules/clone-buffer": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz",
+ "integrity": "sha512-KLLTJWrvwIP+OPfMn0x2PheDEP20RPUcGXj/ERegTgdmPEZylALQldygiqrPPu8P45uNuPs7ckmReLY6v/iA5g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/clone-response": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz",
+ "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "mimic-response": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/clone-stats": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz",
+ "integrity": "sha512-au6ydSpg6nsrigcZ4m8Bc9hxjeW+GJ8xh5G3BJCMt4WXe1H10UNaVOamqQTmrx1kjVuxAHIQSNU6hY4Nsn9/ag==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/cloneable-readable": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/cloneable-readable/-/cloneable-readable-1.1.3.tgz",
+ "integrity": "sha512-2EF8zTQOxYq70Y4XKtorQupqF0m49MBz2/yf5Bj+MHjvpG3Hy7sImifnqD6UA+TKYxeSV+u6qqQPawN5UvnpKQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "inherits": "^2.0.1",
+ "process-nextick-args": "^2.0.0",
+ "readable-stream": "^2.3.5"
+ }
+ },
+ "node_modules/coa": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/coa/-/coa-2.0.2.tgz",
+ "integrity": "sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/q": "^1.5.1",
+ "chalk": "^2.4.1",
+ "q": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 4.0"
+ }
+ },
+ "node_modules/coa/node_modules/ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^1.9.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/coa/node_modules/chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/code-point-at": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
+ "integrity": "sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/collection-map": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/collection-map/-/collection-map-1.0.0.tgz",
+ "integrity": "sha512-5D2XXSpkOnleOI21TG7p3T0bGAsZ/XknZpKBmGYyluO8pw4zA3K8ZlrBIbC4FXg3m6z/RNFiUFfT2sQK01+UHA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "arr-map": "^2.0.2",
+ "for-own": "^1.0.0",
+ "make-iterator": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/collection-visit": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz",
+ "integrity": "sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "map-visit": "^1.0.0",
+ "object-visit": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/color": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz",
+ "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^1.9.3",
+ "color-string": "^1.6.0"
+ }
+ },
+ "node_modules/color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "1.1.3"
+ }
+ },
+ "node_modules/color-convert/node_modules/color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/color-string": {
+ "version": "1.9.1",
+ "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz",
+ "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "^1.0.0",
+ "simple-swizzle": "^0.2.2"
+ }
+ },
+ "node_modules/color-support": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz",
+ "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "color-support": "bin.js"
+ }
+ },
+ "node_modules/colors": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz",
+ "integrity": "sha512-pFGrxThWcWQ2MsAz6RtgeWe4NK2kUE1WfsrvvlctdII745EW9I0yflqhe7++M5LEc7bV2c/9/5zc8sFcpL0Drw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.1.90"
+ }
+ },
+ "node_modules/combined-stream": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+ "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "delayed-stream": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/commander": {
+ "version": "2.20.3",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
+ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/compare-version": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/compare-version/-/compare-version-0.1.2.tgz",
+ "integrity": "sha512-pJDh5/4wrEnXX/VWRZvruAGHkzKdr46z11OlTPN+VrATlWWhSKewNCJ1futCO5C7eJB3nPMFZA1LeYtcFboZ2A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/component-emitter": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz",
+ "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/concat-stream": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz",
+ "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==",
+ "dev": true,
+ "engines": [
+ "node >= 6.0"
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "buffer-from": "^1.0.0",
+ "inherits": "^2.0.3",
+ "readable-stream": "^3.0.2",
+ "typedarray": "^0.0.6"
+ }
+ },
+ "node_modules/concat-stream/node_modules/readable-stream": {
+ "version": "3.6.2",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
+ "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/concat-stream/node_modules/string_decoder": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
+ "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "safe-buffer": "~5.2.0"
+ }
+ },
+ "node_modules/config-chain": {
+ "version": "1.1.13",
+ "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz",
+ "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ini": "^1.3.4",
+ "proto-list": "~1.2.1"
+ }
+ },
+ "node_modules/connect": {
+ "version": "3.6.6",
+ "resolved": "https://registry.npmjs.org/connect/-/connect-3.6.6.tgz",
+ "integrity": "sha512-OO7axMmPpu/2XuX1+2Yrg0ddju31B6xLZMWkJ5rYBu4YRmRVlOjvlY6kw2FJKiAzyxGwnrDUAG4s1Pf0sbBMCQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "debug": "2.6.9",
+ "finalhandler": "1.1.0",
+ "parseurl": "~1.3.2",
+ "utils-merge": "1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.10.0"
+ }
+ },
+ "node_modules/connect-history-api-fallback": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz",
+ "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8"
+ }
+ },
+ "node_modules/connect-livereload": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/connect-livereload/-/connect-livereload-0.4.1.tgz",
+ "integrity": "sha512-y/4fDdcveHQsVXTJeAr8HHLwul5M3VI071pEaov/jiCz2HIrmZynFHuOn1CfQ8euUsdjR1Ppwsb9mgBOSij3vw==",
+ "dev": true,
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/connect/node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/console-stream": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/console-stream/-/console-stream-0.1.1.tgz",
+ "integrity": "sha512-QC/8l9e6ofi6nqZ5PawlDgzmMw3OxIXtvolBzap/F4UDBJlDaZRSNbL/lb41C29FcbSJncBFlJFj2WJoNyZRfQ==",
+ "dev": true
+ },
+ "node_modules/content-disposition": {
+ "version": "0.5.4",
+ "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
+ "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "safe-buffer": "5.2.1"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/convert-source-map": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz",
+ "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/cookie": {
+ "version": "0.4.2",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz",
+ "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/copy-descriptor": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
+ "integrity": "sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/copy-props": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/copy-props/-/copy-props-2.0.5.tgz",
+ "integrity": "sha512-XBlx8HSqrT0ObQwmSzM7WE5k8FxTV75h1DX1Z3n6NhQ/UYYAvInWYmG06vFt7hQZArE2fuO62aihiWIVQwh1sw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "each-props": "^1.3.2",
+ "is-plain-object": "^5.0.0"
+ }
+ },
+ "node_modules/copy-props/node_modules/is-plain-object": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
+ "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/core-js": {
+ "version": "3.26.1",
+ "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.26.1.tgz",
+ "integrity": "sha512-21491RRQVzUn0GGM9Z1Jrpr6PNPxPi+Za8OM9q4tksTSnlbXXGKK1nXNg/QvwFYettXvSX6zWKCtHHfjN4puyA==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/core-js"
+ }
+ },
+ "node_modules/core-util-is": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
+ "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/cors": {
+ "version": "2.8.5",
+ "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
+ "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "object-assign": "^4",
+ "vary": "^1"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/cosmiconfig": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz",
+ "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "import-fresh": "^2.0.0",
+ "is-directory": "^0.3.1",
+ "js-yaml": "^3.13.1",
+ "parse-json": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/cosmiconfig/node_modules/parse-json": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
+ "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "error-ex": "^1.3.1",
+ "json-parse-better-errors": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/cross-dirname": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/cross-dirname/-/cross-dirname-0.1.0.tgz",
+ "integrity": "sha512-+R08/oI0nl3vfPcqftZRpytksBXDzOUveBq/NBVx0sUp1axwzPQrKinNx5yd5sxPu8j1wIy8AfnVQ+5eFdha6Q==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/cross-spawn": {
+ "version": "6.0.5",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
+ "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "nice-try": "^1.0.4",
+ "path-key": "^2.0.1",
+ "semver": "^5.5.0",
+ "shebang-command": "^1.2.0",
+ "which": "^1.2.9"
+ },
+ "engines": {
+ "node": ">=4.8"
+ }
+ },
+ "node_modules/cross-spawn/node_modules/path-key": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
+ "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/cross-spawn/node_modules/semver": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+ "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver"
+ }
+ },
+ "node_modules/css-color-names": {
+ "version": "0.0.4",
+ "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz",
+ "integrity": "sha512-zj5D7X1U2h2zsXOAM8EyUREBnnts6H+Jm+d1M2DbiQQcUtnqgQsMrdo8JW9R80YFUmIdBZeMu5wvYM7hcgWP/Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/css-declaration-sorter": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-4.0.1.tgz",
+ "integrity": "sha512-BcxQSKTSEEQUftYpBVnsH4SF05NTuBokb19/sBt6asXGKZ/6VP7PLG1CBCkFDYOnhXhPh0jMhO6xZ71oYHXHBA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "postcss": "^7.0.1",
+ "timsort": "^0.3.0"
+ },
+ "engines": {
+ "node": ">4"
+ }
+ },
+ "node_modules/css-mqpacker": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/css-mqpacker/-/css-mqpacker-7.0.0.tgz",
+ "integrity": "sha512-temVrWS+sB4uocE2quhW8ru/KguDmGhCU7zN213KxtDvWOH3WS/ZUStfpF4fdCT7W8fPpFrQdWRFqtFtPPfBLA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "minimist": "^1.2.0",
+ "postcss": "^7.0.0"
+ },
+ "bin": {
+ "mqpacker": "bin/mqpacker.js"
+ }
+ },
+ "node_modules/css-select": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.1.0.tgz",
+ "integrity": "sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "boolbase": "^1.0.0",
+ "css-what": "^3.2.1",
+ "domutils": "^1.7.0",
+ "nth-check": "^1.0.2"
+ }
+ },
+ "node_modules/css-select-base-adapter": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz",
+ "integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/css-tree": {
+ "version": "1.0.0-alpha.37",
+ "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz",
+ "integrity": "sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "mdn-data": "2.0.4",
+ "source-map": "^0.6.1"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/css-what": {
+ "version": "3.4.2",
+ "resolved": "https://registry.npmjs.org/css-what/-/css-what-3.4.2.tgz",
+ "integrity": "sha512-ACUm3L0/jiZTqfzRM3Hi9Q8eZqd6IK37mMWPLz9PJxkLWllYeRf+EHUSHYEtFop2Eqytaq1FizFVh7XfBnXCDQ==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">= 6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/fb55"
+ }
+ },
+ "node_modules/cssnano": {
+ "version": "4.1.11",
+ "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-4.1.11.tgz",
+ "integrity": "sha512-6gZm2htn7xIPJOHY824ERgj8cNPgPxyCSnkXc4v7YvNW+TdVfzgngHcEhy/8D11kUWRUMbke+tC+AUcUsnMz2g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cosmiconfig": "^5.0.0",
+ "cssnano-preset-default": "^4.0.8",
+ "is-resolvable": "^1.0.0",
+ "postcss": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/cssnano-preset-advanced": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/cssnano-preset-advanced/-/cssnano-preset-advanced-4.0.8.tgz",
+ "integrity": "sha512-DlZ5+XNKwB3ZnrtJ7jdj8WxT5Zgt1WIr4gdP9v1Sdn3SObqcLwbBobQaM7BqLIVHS74TE5iWn2TSYmOVSsmozQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "autoprefixer": "^9.4.7",
+ "cssnano-preset-default": "^4.0.8",
+ "postcss-discard-unused": "^4.0.1",
+ "postcss-merge-idents": "^4.0.1",
+ "postcss-reduce-idents": "^4.0.2",
+ "postcss-zindex": "^4.0.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/cssnano-preset-default": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-4.0.8.tgz",
+ "integrity": "sha512-LdAyHuq+VRyeVREFmuxUZR1TXjQm8QQU/ktoo/x7bz+SdOge1YKc5eMN6pRW7YWBmyq59CqYba1dJ5cUukEjLQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "css-declaration-sorter": "^4.0.1",
+ "cssnano-util-raw-cache": "^4.0.1",
+ "postcss": "^7.0.0",
+ "postcss-calc": "^7.0.1",
+ "postcss-colormin": "^4.0.3",
+ "postcss-convert-values": "^4.0.1",
+ "postcss-discard-comments": "^4.0.2",
+ "postcss-discard-duplicates": "^4.0.2",
+ "postcss-discard-empty": "^4.0.1",
+ "postcss-discard-overridden": "^4.0.1",
+ "postcss-merge-longhand": "^4.0.11",
+ "postcss-merge-rules": "^4.0.3",
+ "postcss-minify-font-values": "^4.0.2",
+ "postcss-minify-gradients": "^4.0.2",
+ "postcss-minify-params": "^4.0.2",
+ "postcss-minify-selectors": "^4.0.2",
+ "postcss-normalize-charset": "^4.0.1",
+ "postcss-normalize-display-values": "^4.0.2",
+ "postcss-normalize-positions": "^4.0.2",
+ "postcss-normalize-repeat-style": "^4.0.2",
+ "postcss-normalize-string": "^4.0.2",
+ "postcss-normalize-timing-functions": "^4.0.2",
+ "postcss-normalize-unicode": "^4.0.1",
+ "postcss-normalize-url": "^4.0.1",
+ "postcss-normalize-whitespace": "^4.0.2",
+ "postcss-ordered-values": "^4.1.2",
+ "postcss-reduce-initial": "^4.0.3",
+ "postcss-reduce-transforms": "^4.0.2",
+ "postcss-svgo": "^4.0.3",
+ "postcss-unique-selectors": "^4.0.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/cssnano-util-get-arguments": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/cssnano-util-get-arguments/-/cssnano-util-get-arguments-4.0.0.tgz",
+ "integrity": "sha512-6RIcwmV3/cBMG8Aj5gucQRsJb4vv4I4rn6YjPbVWd5+Pn/fuG+YseGvXGk00XLkoZkaj31QOD7vMUpNPC4FIuw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/cssnano-util-get-match": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/cssnano-util-get-match/-/cssnano-util-get-match-4.0.0.tgz",
+ "integrity": "sha512-JPMZ1TSMRUPVIqEalIBNoBtAYbi8okvcFns4O0YIhcdGebeYZK7dMyHJiQ6GqNBA9kE0Hym4Aqym5rPdsV/4Cw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/cssnano-util-raw-cache": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/cssnano-util-raw-cache/-/cssnano-util-raw-cache-4.0.1.tgz",
+ "integrity": "sha512-qLuYtWK2b2Dy55I8ZX3ky1Z16WYsx544Q0UWViebptpwn/xDBmog2TLg4f+DBMg1rJ6JDWtn96WHbOKDWt1WQA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "postcss": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/cssnano-util-same-parent": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/cssnano-util-same-parent/-/cssnano-util-same-parent-4.0.1.tgz",
+ "integrity": "sha512-WcKx5OY+KoSIAxBW6UBBRay1U6vkYheCdjyVNDm85zt5K9mHoGOfsOsqIszfAqrQQFIIKgjh2+FDgIj/zsl21Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/csso": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz",
+ "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "css-tree": "^1.1.2"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/csso/node_modules/css-tree": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz",
+ "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "mdn-data": "2.0.14",
+ "source-map": "^0.6.1"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/csso/node_modules/mdn-data": {
+ "version": "2.0.14",
+ "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz",
+ "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==",
+ "dev": true,
+ "license": "CC0-1.0"
+ },
+ "node_modules/cssom": {
+ "version": "0.3.8",
+ "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz",
+ "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/cssstyle": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-1.4.0.tgz",
+ "integrity": "sha512-GBrLZYZ4X4x6/QEoBnIrqb8B/f5l4+8me2dkom/j1Gtbxy0kBv6OGzKuAsGM75bkGwGAFkt56Iwg28S3XTZgSA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cssom": "0.3.x"
+ }
+ },
+ "node_modules/currently-unhandled": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz",
+ "integrity": "sha512-/fITjgjGU50vjQ4FH6eUoYu+iUoUKIXws2hL15JJpIR+BbTxaXQsMuuyjtNh2WqsSBS5nsaZHFsFecyw5CCAng==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "array-find-index": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/cycle": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/cycle/-/cycle-1.0.3.tgz",
+ "integrity": "sha512-TVF6svNzeQCOpjCqsy0/CSy8VgObG3wXusJ73xW2GbG5rGx7lC8zxDSURicsXI2UsGdi2L0QNRCi745/wUDvsA==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/d": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz",
+ "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "es5-ext": "^0.10.50",
+ "type": "^1.0.1"
+ }
+ },
+ "node_modules/dashdash": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
+ "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "assert-plus": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/data-urls": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-1.1.0.tgz",
+ "integrity": "sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "abab": "^2.0.0",
+ "whatwg-mimetype": "^2.2.0",
+ "whatwg-url": "^7.0.0"
+ }
+ },
+ "node_modules/dateformat": {
+ "version": "1.0.12",
+ "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.12.tgz",
+ "integrity": "sha512-5sFRfAAmbHdIts+eKjR9kYJoF0ViCMVX9yqLu5A7S/v+nd077KgCITOMiirmyCBiZpKLDXbBOkYm6tu7rX/TKg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "get-stdin": "^4.0.1",
+ "meow": "^3.3.0"
+ },
+ "bin": {
+ "dateformat": "bin/cli.js"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/debounce-promise": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/debounce-promise/-/debounce-promise-3.1.2.tgz",
+ "integrity": "sha512-rZHcgBkbYavBeD9ej6sP56XfG53d51CD4dnaw989YX/nZ/ZJfgRx/9ePKmTNiUiyQvh4mtrMoS3OAWW+yoYtpg==",
+ "license": "MIT"
+ },
+ "node_modules/debug": {
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+ "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "2.1.2"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/debug/node_modules/ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/decamelize": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
+ "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/decode-uri-component": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz",
+ "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/decompress": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/decompress/-/decompress-4.2.1.tgz",
+ "integrity": "sha512-e48kc2IjU+2Zw8cTb6VZcJQ3lgVbS4uuB1TfCHbiZIP/haNXm+SVyhu+87jts5/3ROpd82GSVCoNs/z8l4ZOaQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "decompress-tar": "^4.0.0",
+ "decompress-tarbz2": "^4.0.0",
+ "decompress-targz": "^4.0.0",
+ "decompress-unzip": "^4.0.1",
+ "graceful-fs": "^4.1.10",
+ "make-dir": "^1.0.0",
+ "pify": "^2.3.0",
+ "strip-dirs": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/decompress-response": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz",
+ "integrity": "sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "mimic-response": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/decompress-tar": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/decompress-tar/-/decompress-tar-4.1.1.tgz",
+ "integrity": "sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "file-type": "^5.2.0",
+ "is-stream": "^1.1.0",
+ "tar-stream": "^1.5.2"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/decompress-tarbz2": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/decompress-tarbz2/-/decompress-tarbz2-4.1.1.tgz",
+ "integrity": "sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "decompress-tar": "^4.1.0",
+ "file-type": "^6.1.0",
+ "is-stream": "^1.1.0",
+ "seek-bzip": "^1.0.5",
+ "unbzip2-stream": "^1.0.9"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/decompress-tarbz2/node_modules/file-type": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/file-type/-/file-type-6.2.0.tgz",
+ "integrity": "sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/decompress-targz": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/decompress-targz/-/decompress-targz-4.1.1.tgz",
+ "integrity": "sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "decompress-tar": "^4.1.1",
+ "file-type": "^5.2.0",
+ "is-stream": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/decompress-unzip": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/decompress-unzip/-/decompress-unzip-4.0.1.tgz",
+ "integrity": "sha512-1fqeluvxgnn86MOh66u8FjbtJpAFv5wgCT9Iw8rcBqQcCo5tO8eiJw7NNTrvt9n4CRBVq7CstiS922oPgyGLrw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "file-type": "^3.8.0",
+ "get-stream": "^2.2.0",
+ "pify": "^2.3.0",
+ "yauzl": "^2.4.2"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/decompress-unzip/node_modules/file-type": {
+ "version": "3.9.0",
+ "resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz",
+ "integrity": "sha512-RLoqTXE8/vPmMuTI88DAzhMYC99I8BWv7zYP4A1puo5HIjEJ5EX48ighy4ZyKMG9EDXxBgW6e++cn7d1xuFghA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/decompress-unzip/node_modules/get-stream": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz",
+ "integrity": "sha512-AUGhbbemXxrZJRD5cDvKtQxLuYaIbNtDTK8YqupCI393Q2KSTreEsLUN3ZxAWFGiKTzL6nKuzfcIvieflUX9qA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "object-assign": "^4.0.1",
+ "pinkie-promise": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/deep-is": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
+ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/default-compare": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/default-compare/-/default-compare-1.0.0.tgz",
+ "integrity": "sha512-QWfXlM0EkAbqOCbD/6HjdwT19j7WCkMyiRhWilc4H9/5h/RzTF9gv5LYh1+CmDV5d1rki6KAWLtQale0xt20eQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "kind-of": "^5.0.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/default-compare/node_modules/kind-of": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+ "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/default-resolution": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/default-resolution/-/default-resolution-2.0.0.tgz",
+ "integrity": "sha512-2xaP6GiwVwOEbXCGoJ4ufgC76m8cj805jrghScewJC2ZDsb9U0b4BIrba+xt/Uytyd0HvQ6+WymSRTfnYj59GQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/define-properties": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz",
+ "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-property-descriptors": "^1.0.0",
+ "object-keys": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-descriptor": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/define-property/node_modules/is-accessor-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+ "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "kind-of": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/define-property/node_modules/is-accessor-descriptor/node_modules/kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-buffer": "^1.1.5"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/define-property/node_modules/is-data-descriptor": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+ "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "kind-of": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/define-property/node_modules/is-data-descriptor/node_modules/kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-buffer": "^1.1.5"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/define-property/node_modules/is-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+ "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-accessor-descriptor": "^0.1.6",
+ "is-data-descriptor": "^0.1.4",
+ "kind-of": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/define-property/node_modules/kind-of": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+ "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/delayed-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+ "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/delete-empty": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/delete-empty/-/delete-empty-3.0.0.tgz",
+ "integrity": "sha512-ZUyiwo76W+DYnKsL3Kim6M/UOavPdBJgDYWOmuQhYaZvJH0AXAHbUNyEDtRbBra8wqqr686+63/0azfEk1ebUQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-colors": "^4.1.0",
+ "minimist": "^1.2.0",
+ "path-starts-with": "^2.0.0",
+ "rimraf": "^2.6.2"
+ },
+ "bin": {
+ "delete-empty": "bin/cli.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/delete-empty/node_modules/ansi-colors": {
+ "version": "4.1.3",
+ "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz",
+ "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/depd": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
+ "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/destroy": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
+ "integrity": "sha512-3NdhDuEXnfun/z7x9GOElY49LoqVHoGScmOKwmxhsS8N5Y+Z8KyPPDnaSzqWgYt/ji4mqwfTS34Htrk0zPIXVg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/detect-file": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz",
+ "integrity": "sha512-DtCOLG98P007x7wiiOmfI0fi3eIKyWiLTGJ2MDnVi/E04lWGbf+JzrRHMm0rgIIZJGtHpKpbVgLWHrv8xXpc3Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/detect-node": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz",
+ "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/dev-ip": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/dev-ip/-/dev-ip-1.0.1.tgz",
+ "integrity": "sha512-LmVkry/oDShEgSZPNgqCIp2/TlqtExeGmymru3uCELnfyjY11IzpAproLYs+1X88fXO6DBoYP3ul2Xo2yz2j6A==",
+ "dev": true,
+ "bin": {
+ "dev-ip": "lib/dev-ip.js"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/dir-glob": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
+ "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "path-type": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/dir-glob/node_modules/path-type": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
+ "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/dlv": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz",
+ "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/dom-serializer": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz",
+ "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "domelementtype": "^2.0.1",
+ "entities": "^2.0.0"
+ }
+ },
+ "node_modules/dom-serializer/node_modules/domelementtype": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
+ "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fb55"
+ }
+ ],
+ "license": "BSD-2-Clause"
+ },
+ "node_modules/domelementtype": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz",
+ "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==",
+ "dev": true,
+ "license": "BSD-2-Clause"
+ },
+ "node_modules/domexception": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz",
+ "integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "webidl-conversions": "^4.0.2"
+ }
+ },
+ "node_modules/domutils": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz",
+ "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "dom-serializer": "0",
+ "domelementtype": "1"
+ }
+ },
+ "node_modules/dot-prop": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz",
+ "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-obj": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/download": {
+ "version": "6.2.5",
+ "resolved": "https://registry.npmjs.org/download/-/download-6.2.5.tgz",
+ "integrity": "sha512-DpO9K1sXAST8Cpzb7kmEhogJxymyVUd5qz/vCOSyvwtp2Klj2XcDt5YUuasgxka44SxF0q5RriKIwJmQHG2AuA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "caw": "^2.0.0",
+ "content-disposition": "^0.5.2",
+ "decompress": "^4.0.0",
+ "ext-name": "^5.0.0",
+ "file-type": "5.2.0",
+ "filenamify": "^2.0.0",
+ "get-stream": "^3.0.0",
+ "got": "^7.0.0",
+ "make-dir": "^1.0.0",
+ "p-event": "^1.0.0",
+ "pify": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/download/node_modules/got": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/got/-/got-7.1.0.tgz",
+ "integrity": "sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "decompress-response": "^3.2.0",
+ "duplexer3": "^0.1.4",
+ "get-stream": "^3.0.0",
+ "is-plain-obj": "^1.1.0",
+ "is-retry-allowed": "^1.0.0",
+ "is-stream": "^1.0.0",
+ "isurl": "^1.0.0-alpha5",
+ "lowercase-keys": "^1.0.0",
+ "p-cancelable": "^0.3.0",
+ "p-timeout": "^1.1.1",
+ "safe-buffer": "^5.0.1",
+ "timed-out": "^4.0.0",
+ "url-parse-lax": "^1.0.0",
+ "url-to-options": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/download/node_modules/p-cancelable": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.3.0.tgz",
+ "integrity": "sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/download/node_modules/pify": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+ "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/download/node_modules/prepend-http": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz",
+ "integrity": "sha512-PhmXi5XmoyKw1Un4E+opM2KcsJInDvKyuOumcjjw3waw86ZNjHwVUOOWLc4bCzLdcKNaWBH9e99sbWzDQsVaYg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/download/node_modules/url-parse-lax": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz",
+ "integrity": "sha512-BVA4lR5PIviy2PMseNd2jbFQ+jwSwQGdJejf5ctd1rEXt0Ypd7yanUK9+lYechVlN5VaTJGsu2U/3MDDu6KgBA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prepend-http": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/duplexer2": {
+ "version": "0.0.2",
+ "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.0.2.tgz",
+ "integrity": "sha512-+AWBwjGadtksxjOQSFDhPNQbed7icNXApT4+2BNpsXzcCBiInq2H9XW0O8sfHFaPmnQRs7cg/P0fAr2IWQSW0g==",
+ "dev": true,
+ "license": "BSD",
+ "dependencies": {
+ "readable-stream": "~1.1.9"
+ }
+ },
+ "node_modules/duplexer2/node_modules/readable-stream": {
+ "version": "1.1.14",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
+ "integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.1",
+ "isarray": "0.0.1",
+ "string_decoder": "~0.10.x"
+ }
+ },
+ "node_modules/duplexer3": {
+ "version": "0.1.5",
+ "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.5.tgz",
+ "integrity": "sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA==",
+ "dev": true,
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/duplexify": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.2.tgz",
+ "integrity": "sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "end-of-stream": "^1.4.1",
+ "inherits": "^2.0.3",
+ "readable-stream": "^3.1.1",
+ "stream-shift": "^1.0.0"
+ }
+ },
+ "node_modules/duplexify/node_modules/readable-stream": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
+ "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/duplexify/node_modules/string_decoder": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
+ "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "safe-buffer": "~5.2.0"
+ }
+ },
+ "node_modules/each-props": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/each-props/-/each-props-1.3.2.tgz",
+ "integrity": "sha512-vV0Hem3zAGkJAyU7JSjixeU66rwdynTAa1vofCrSA5fEln+m67Az9CcnkVD776/fsN/UjIWmBDoNRS6t6G9RfA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-plain-object": "^2.0.1",
+ "object.defaults": "^1.1.0"
+ }
+ },
+ "node_modules/easy-extender": {
+ "version": "2.3.4",
+ "resolved": "https://registry.npmjs.org/easy-extender/-/easy-extender-2.3.4.tgz",
+ "integrity": "sha512-8cAwm6md1YTiPpOvDULYJL4ZS6WfM5/cTeVVh4JsvyYZAoqlRVUpHL9Gr5Fy7HA6xcSZicUia3DeAgO3Us8E+Q==",
+ "dev": true,
+ "dependencies": {
+ "lodash": "^4.17.10"
+ },
+ "engines": {
+ "node": ">= 4.0.0"
+ }
+ },
+ "node_modules/eazy-logger": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/eazy-logger/-/eazy-logger-3.1.0.tgz",
+ "integrity": "sha512-/snsn2JqBtUSSstEl4R0RKjkisGHAhvYj89i7r3ytNUKW12y178KDZwXLXIgwDqLW6E/VRMT9qfld7wvFae8bQ==",
+ "dev": true,
+ "dependencies": {
+ "tfunk": "^4.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/ecc-jsbn": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
+ "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "jsbn": "~0.1.0",
+ "safer-buffer": "^2.1.0"
+ }
+ },
+ "node_modules/ee-first": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
+ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/electron-to-chromium": {
+ "version": "1.5.178",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.178.tgz",
+ "integrity": "sha512-wObbz/ar3Bc6e4X5vf0iO8xTN8YAjN/tgiAOJLr7yjYFtP9wAjq8Mb5h0yn6kResir+VYx2DXBj9NNobs0ETSA==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/emojis-list": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz",
+ "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/encodeurl": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
+ "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/end-of-stream": {
+ "version": "1.4.4",
+ "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
+ "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "once": "^1.4.0"
+ }
+ },
+ "node_modules/engine.io": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.2.1.tgz",
+ "integrity": "sha512-ECceEFcAaNRybd3lsGQKas3ZlMVjN3cyWwMP25D2i0zWfyiytVbTpRPa34qrr+FHddtpBVOmq4H/DCv1O0lZRA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/cookie": "^0.4.1",
+ "@types/cors": "^2.8.12",
+ "@types/node": ">=10.0.0",
+ "accepts": "~1.3.4",
+ "base64id": "2.0.0",
+ "cookie": "~0.4.1",
+ "cors": "~2.8.5",
+ "debug": "~4.3.1",
+ "engine.io-parser": "~5.0.3",
+ "ws": "~8.2.3"
+ },
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
+ "node_modules/engine.io-client": {
+ "version": "6.2.3",
+ "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.2.3.tgz",
+ "integrity": "sha512-aXPtgF1JS3RuuKcpSrBtimSjYvrbhKW9froICH4s0F3XQWLxsKNxqzG39nnvQZQnva4CMvUK63T7shevxRyYHw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@socket.io/component-emitter": "~3.1.0",
+ "debug": "~4.3.1",
+ "engine.io-parser": "~5.0.3",
+ "ws": "~8.2.3",
+ "xmlhttprequest-ssl": "~2.0.0"
+ }
+ },
+ "node_modules/engine.io-parser": {
+ "version": "5.0.4",
+ "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.4.tgz",
+ "integrity": "sha512-+nVFp+5z1E3HcToEnO7ZIj3g+3k9389DvWtvJZz0T6/eOCPIyyxehFcedoYrZQrp0LgQbD9pPXhpMBKMd5QURg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
+ "node_modules/engine.io/node_modules/@types/node": {
+ "version": "18.11.10",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.10.tgz",
+ "integrity": "sha512-juG3RWMBOqcOuXC643OAdSA525V44cVgGV6dUDuiFtss+8Fk5x1hI93Rsld43VeJVIeqlP9I7Fn9/qaVqoEAuQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/enhanced-resolve": {
+ "version": "5.18.2",
+ "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.2.tgz",
+ "integrity": "sha512-6Jw4sE1maoRJo3q8MsSIn2onJFbLTOjY9hlx4DZXmOKvLRd1Ok2kXmAGXaafL2+ijsJZ1ClYbl/pmqr9+k4iUQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "graceful-fs": "^4.2.4",
+ "tapable": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/entities": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz",
+ "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/env-paths": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz",
+ "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/err-code": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz",
+ "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/errno": {
+ "version": "0.1.8",
+ "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz",
+ "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prr": "~1.0.1"
+ },
+ "bin": {
+ "errno": "cli.js"
+ }
+ },
+ "node_modules/error-ex": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
+ "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-arrayish": "^0.2.1"
+ }
+ },
+ "node_modules/es-abstract": {
+ "version": "1.20.4",
+ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.4.tgz",
+ "integrity": "sha512-0UtvRN79eMe2L+UNEF1BwRe364sj/DXhQ/k5FmivgoSdpM90b8Jc0mDzKMGo7QS0BVbOP/bTwBKNnDc9rNzaPA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "es-to-primitive": "^1.2.1",
+ "function-bind": "^1.1.1",
+ "function.prototype.name": "^1.1.5",
+ "get-intrinsic": "^1.1.3",
+ "get-symbol-description": "^1.0.0",
+ "has": "^1.0.3",
+ "has-property-descriptors": "^1.0.0",
+ "has-symbols": "^1.0.3",
+ "internal-slot": "^1.0.3",
+ "is-callable": "^1.2.7",
+ "is-negative-zero": "^2.0.2",
+ "is-regex": "^1.1.4",
+ "is-shared-array-buffer": "^1.0.2",
+ "is-string": "^1.0.7",
+ "is-weakref": "^1.0.2",
+ "object-inspect": "^1.12.2",
+ "object-keys": "^1.1.1",
+ "object.assign": "^4.1.4",
+ "regexp.prototype.flags": "^1.4.3",
+ "safe-regex-test": "^1.0.0",
+ "string.prototype.trimend": "^1.0.5",
+ "string.prototype.trimstart": "^1.0.5",
+ "unbox-primitive": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/es-array-method-boxes-properly": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz",
+ "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/es-module-lexer": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz",
+ "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/es-to-primitive": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz",
+ "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-callable": "^1.1.4",
+ "is-date-object": "^1.0.1",
+ "is-symbol": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/es5-ext": {
+ "version": "0.10.62",
+ "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.62.tgz",
+ "integrity": "sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "ISC",
+ "dependencies": {
+ "es6-iterator": "^2.0.3",
+ "es6-symbol": "^3.1.3",
+ "next-tick": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/es6-error": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz",
+ "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/es6-iterator": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz",
+ "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "d": "1",
+ "es5-ext": "^0.10.35",
+ "es6-symbol": "^3.1.1"
+ }
+ },
+ "node_modules/es6-symbol": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz",
+ "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "d": "^1.0.1",
+ "ext": "^1.1.2"
+ }
+ },
+ "node_modules/es6-weak-map": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz",
+ "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "d": "1",
+ "es5-ext": "^0.10.46",
+ "es6-iterator": "^2.0.3",
+ "es6-symbol": "^3.1.1"
+ }
+ },
+ "node_modules/escalade": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
+ "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/escape-html": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+ "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/escodegen": {
+ "version": "1.14.3",
+ "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz",
+ "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "esprima": "^4.0.1",
+ "estraverse": "^4.2.0",
+ "esutils": "^2.0.2",
+ "optionator": "^0.8.1"
+ },
+ "bin": {
+ "escodegen": "bin/escodegen.js",
+ "esgenerate": "bin/esgenerate.js"
+ },
+ "engines": {
+ "node": ">=4.0"
+ },
+ "optionalDependencies": {
+ "source-map": "~0.6.1"
+ }
+ },
+ "node_modules/escodegen/node_modules/estraverse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
+ "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/escodegen/node_modules/levn": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
+ "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prelude-ls": "~1.1.2",
+ "type-check": "~0.3.2"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/escodegen/node_modules/optionator": {
+ "version": "0.8.3",
+ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz",
+ "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "deep-is": "~0.1.3",
+ "fast-levenshtein": "~2.0.6",
+ "levn": "~0.3.0",
+ "prelude-ls": "~1.1.2",
+ "type-check": "~0.3.2",
+ "word-wrap": "~1.2.3"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/eslint": {
+ "version": "9.24.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.24.0.tgz",
+ "integrity": "sha512-eh/jxIEJyZrvbWRe4XuVclLPDYSYYYgLy5zXGGxD6j8zjSAxFEzI2fL/8xNq6O2yKqVt+eF2YhV+hxjV6UKXwQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.2.0",
+ "@eslint-community/regexpp": "^4.12.1",
+ "@eslint/config-array": "^0.20.0",
+ "@eslint/config-helpers": "^0.2.0",
+ "@eslint/core": "^0.12.0",
+ "@eslint/eslintrc": "^3.3.1",
+ "@eslint/js": "9.24.0",
+ "@eslint/plugin-kit": "^0.2.7",
+ "@humanfs/node": "^0.16.6",
+ "@humanwhocodes/module-importer": "^1.0.1",
+ "@humanwhocodes/retry": "^0.4.2",
+ "@types/estree": "^1.0.6",
+ "@types/json-schema": "^7.0.15",
+ "ajv": "^6.12.4",
+ "chalk": "^4.0.0",
+ "cross-spawn": "^7.0.6",
+ "debug": "^4.3.2",
+ "escape-string-regexp": "^4.0.0",
+ "eslint-scope": "^8.3.0",
+ "eslint-visitor-keys": "^4.2.0",
+ "espree": "^10.3.0",
+ "esquery": "^1.5.0",
+ "esutils": "^2.0.2",
+ "fast-deep-equal": "^3.1.3",
+ "file-entry-cache": "^8.0.0",
+ "find-up": "^5.0.0",
+ "glob-parent": "^6.0.2",
+ "ignore": "^5.2.0",
+ "imurmurhash": "^0.1.4",
+ "is-glob": "^4.0.0",
+ "json-stable-stringify-without-jsonify": "^1.0.1",
+ "lodash.merge": "^4.6.2",
+ "minimatch": "^3.1.2",
+ "natural-compare": "^1.4.0",
+ "optionator": "^0.9.3"
+ },
+ "bin": {
+ "eslint": "bin/eslint.js"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://eslint.org/donate"
+ },
+ "peerDependencies": {
+ "jiti": "*"
+ },
+ "peerDependenciesMeta": {
+ "jiti": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/eslint-scope": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
+ "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "esrecurse": "^4.3.0",
+ "estraverse": "^4.1.1"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/eslint-scope/node_modules/estraverse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
+ "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/eslint-visitor-keys": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz",
+ "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/eslint/node_modules/cross-spawn": {
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
+ "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/eslint/node_modules/escape-string-regexp": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/eslint/node_modules/eslint-scope": {
+ "version": "8.3.0",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.3.0.tgz",
+ "integrity": "sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "esrecurse": "^4.3.0",
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint/node_modules/find-up": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
+ "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "locate-path": "^6.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/eslint/node_modules/glob-parent": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
+ "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.3"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/eslint/node_modules/path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/eslint/node_modules/shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "shebang-regex": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/eslint/node_modules/shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/eslint/node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/eslint/node_modules/which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "node-which": "bin/node-which"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/espree": {
+ "version": "10.3.0",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz",
+ "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "acorn": "^8.14.0",
+ "acorn-jsx": "^5.3.2",
+ "eslint-visitor-keys": "^4.2.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/espree/node_modules/acorn-jsx": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
+ "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
+ }
+ },
+ "node_modules/esprima": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
+ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "bin": {
+ "esparse": "bin/esparse.js",
+ "esvalidate": "bin/esvalidate.js"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/esquery": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz",
+ "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "estraverse": "^5.1.0"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/esrecurse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
+ "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/estraverse": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/esutils": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
+ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/etag": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
+ "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/eventemitter3": {
+ "version": "4.0.7",
+ "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz",
+ "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/events": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
+ "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8.x"
+ }
+ },
+ "node_modules/exec-buffer": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/exec-buffer/-/exec-buffer-3.2.0.tgz",
+ "integrity": "sha512-wsiD+2Tp6BWHoVv3B+5Dcx6E7u5zky+hUwOHjuH2hKSLR3dvRmX8fk8UD8uqQixHs4Wk6eDmiegVrMPjKj7wpA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "execa": "^0.7.0",
+ "p-finally": "^1.0.0",
+ "pify": "^3.0.0",
+ "rimraf": "^2.5.4",
+ "tempfile": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/exec-buffer/node_modules/cross-spawn": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz",
+ "integrity": "sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "lru-cache": "^4.0.1",
+ "shebang-command": "^1.2.0",
+ "which": "^1.2.9"
+ }
+ },
+ "node_modules/exec-buffer/node_modules/execa": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz",
+ "integrity": "sha512-RztN09XglpYI7aBBrJCPW95jEH7YF1UEPOoX9yDhUTPdp7mK+CQvnLTuD10BNXZ3byLTu2uehZ8EcKT/4CGiFw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cross-spawn": "^5.0.1",
+ "get-stream": "^3.0.0",
+ "is-stream": "^1.1.0",
+ "npm-run-path": "^2.0.0",
+ "p-finally": "^1.0.0",
+ "signal-exit": "^3.0.0",
+ "strip-eof": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/exec-buffer/node_modules/lru-cache": {
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
+ "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "pseudomap": "^1.0.2",
+ "yallist": "^2.1.2"
+ }
+ },
+ "node_modules/exec-buffer/node_modules/pify": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+ "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/exec-buffer/node_modules/yallist": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
+ "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/execa": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz",
+ "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cross-spawn": "^6.0.0",
+ "get-stream": "^4.0.0",
+ "is-stream": "^1.1.0",
+ "npm-run-path": "^2.0.0",
+ "p-finally": "^1.0.0",
+ "signal-exit": "^3.0.0",
+ "strip-eof": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/execa/node_modules/get-stream": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
+ "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "pump": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/executable": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/executable/-/executable-4.1.1.tgz",
+ "integrity": "sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "pify": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/expand-brackets": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
+ "integrity": "sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^2.3.3",
+ "define-property": "^0.2.5",
+ "extend-shallow": "^2.0.1",
+ "posix-character-classes": "^0.1.0",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/expand-brackets/node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/expand-tilde": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz",
+ "integrity": "sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "homedir-polyfill": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ext": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz",
+ "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "type": "^2.7.2"
+ }
+ },
+ "node_modules/ext-list": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/ext-list/-/ext-list-2.2.2.tgz",
+ "integrity": "sha512-u+SQgsubraE6zItfVA0tBuCBhfU9ogSRnsvygI7wht9TS510oLkBRXBsqopeUG/GBOIQyKZO9wjTqIu/sf5zFA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "mime-db": "^1.28.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ext-name": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/ext-name/-/ext-name-5.0.0.tgz",
+ "integrity": "sha512-yblEwXAbGv1VQDmow7s38W77hzAgJAO50ztBLMcUyUBfxv1HC+LGwtiEN+Co6LtlqT/5uwVOxsD4TNIilWhwdQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ext-list": "^2.0.0",
+ "sort-keys-length": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/ext/node_modules/type": {
+ "version": "2.7.2",
+ "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz",
+ "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/extend": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
+ "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-extendable": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/extglob": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz",
+ "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "array-unique": "^0.3.2",
+ "define-property": "^1.0.0",
+ "expand-brackets": "^2.1.4",
+ "extend-shallow": "^2.0.1",
+ "fragment-cache": "^0.2.1",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/extglob/node_modules/define-property": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+ "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-descriptor": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/extract-zip": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz",
+ "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "debug": "^4.1.1",
+ "get-stream": "^5.1.0",
+ "yauzl": "^2.10.0"
+ },
+ "bin": {
+ "extract-zip": "cli.js"
+ },
+ "engines": {
+ "node": ">= 10.17.0"
+ },
+ "optionalDependencies": {
+ "@types/yauzl": "^2.9.1"
+ }
+ },
+ "node_modules/extract-zip/node_modules/get-stream": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
+ "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "pump": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/extsprintf": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
+ "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==",
+ "dev": true,
+ "engines": [
+ "node >=0.6.0"
+ ],
+ "license": "MIT"
+ },
+ "node_modules/eyes": {
+ "version": "0.1.8",
+ "resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz",
+ "integrity": "sha512-GipyPsXO1anza0AOZdy69Im7hGFCNB7Y/NGjDlZGJ3GJJLtwNSb2vrzYrTYJRrRloVx7pl+bhUaTB8yiccPvFQ==",
+ "dev": true,
+ "engines": {
+ "node": "> 0.1.90"
+ }
+ },
+ "node_modules/fancy-log": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.3.tgz",
+ "integrity": "sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-gray": "^0.1.1",
+ "color-support": "^1.1.3",
+ "parse-node-version": "^1.0.0",
+ "time-stamp": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/fast-deep-equal": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
+ "license": "MIT"
+ },
+ "node_modules/fast-fifo": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.1.0.tgz",
+ "integrity": "sha512-Kl29QoNbNvn4nhDsLYjyIAaIqaJB6rBx5p3sL9VjaefJ+eMFBWVZiaoguaoZfzEKr5RhAti0UgM8703akGPJ6g==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fast-glob": {
+ "version": "3.2.12",
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz",
+ "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.stat": "^2.0.2",
+ "@nodelib/fs.walk": "^1.2.3",
+ "glob-parent": "^5.1.2",
+ "merge2": "^1.3.0",
+ "micromatch": "^4.0.4"
+ },
+ "engines": {
+ "node": ">=8.6.0"
+ }
+ },
+ "node_modules/fast-glob/node_modules/braces": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+ "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fill-range": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/fast-glob/node_modules/fill-range": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+ "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "to-regex-range": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/fast-glob/node_modules/micromatch": {
+ "version": "4.0.5",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
+ "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "braces": "^3.0.2",
+ "picomatch": "^2.3.1"
+ },
+ "engines": {
+ "node": ">=8.6"
+ }
+ },
+ "node_modules/fast-json-stable-stringify": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
+ "license": "MIT"
+ },
+ "node_modules/fast-levenshtein": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fast-uri": {
+ "version": "3.0.6",
+ "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz",
+ "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fastify"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/fastify"
+ }
+ ],
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/fast-xml-parser": {
+ "version": "3.21.1",
+ "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-3.21.1.tgz",
+ "integrity": "sha512-FTFVjYoBOZTJekiUsawGsSYV9QL0A+zDYCRj7y34IO6Jg+2IMYEtQa+bbictpdpV8dHxXywqU7C0gRDEOFtBFg==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "strnum": "^1.0.4"
+ },
+ "bin": {
+ "xml2js": "cli.js"
+ },
+ "funding": {
+ "type": "paypal",
+ "url": "https://paypal.me/naturalintelligence"
+ }
+ },
+ "node_modules/fastq": {
+ "version": "1.14.0",
+ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.14.0.tgz",
+ "integrity": "sha512-eR2D+V9/ExcbF9ls441yIuN6TI2ED1Y2ZcA5BmMtJsOkWOFRJQ0Jt0g1UwqXJJVAb+V+umH5Dfr8oh4EVP7VVg==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "reusify": "^1.0.4"
+ }
+ },
+ "node_modules/faye-websocket": {
+ "version": "0.7.3",
+ "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.7.3.tgz",
+ "integrity": "sha512-Y00rKGptNaZuPbJuWmFApQf1GIxfrUCi39oQiNyGAQpRDx1L7BQcgq5XPf8JCmXgct3Z1b/6epxqA9z9VMI42Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "websocket-driver": ">=0.3.6"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/fd-slicer": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
+ "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "pend": "~1.2.0"
+ }
+ },
+ "node_modules/figures": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz",
+ "integrity": "sha512-UxKlfCRuCBxSXU4C6t9scbDyWZ4VlaFFdojKtzJuSkuOBQ5CNFum+zZXFwHjo+CxBC1t6zlYPgHIgFjL8ggoEQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "escape-string-regexp": "^1.0.5",
+ "object-assign": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/file-entry-cache": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz",
+ "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "flat-cache": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "node_modules/file-type": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz",
+ "integrity": "sha512-Iq1nJ6D2+yIO4c8HHg4fyVb8mAJieo1Oloy1mLLaB2PvezNedhBVm+QU7g0qM42aiMbRXTxKKwGD17rjKNJYVQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/filename-reserved-regex": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz",
+ "integrity": "sha512-lc1bnsSr4L4Bdif8Xb/qrtokGbq5zlsms/CYH8PP+WtCkGNF65DPiQY8vG3SakEdRn8Dlnm+gW/qWKKjS5sZzQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/filenamify": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-2.1.0.tgz",
+ "integrity": "sha512-ICw7NTT6RsDp2rnYKVd8Fu4cr6ITzGy3+u4vUujPkabyaz+03F24NWEX7fs5fp+kBonlaqPH8fAO2NM+SXt/JA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "filename-reserved-regex": "^2.0.0",
+ "strip-outer": "^1.0.0",
+ "trim-repeated": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/fill-range": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
+ "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "extend-shallow": "^2.0.1",
+ "is-number": "^3.0.0",
+ "repeat-string": "^1.6.1",
+ "to-regex-range": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/fill-range/node_modules/to-regex-range": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz",
+ "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-number": "^3.0.0",
+ "repeat-string": "^1.6.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/finalhandler": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.0.tgz",
+ "integrity": "sha512-ejnvM9ZXYzp6PUPUyQBMBf0Co5VX2gr5H2VQe2Ui2jWXNlxv+PYZo8wpAymJNJdLsG1R4p+M4aynF8KuoUEwRw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "debug": "2.6.9",
+ "encodeurl": "~1.0.1",
+ "escape-html": "~1.0.3",
+ "on-finished": "~2.3.0",
+ "parseurl": "~1.3.2",
+ "statuses": "~1.3.1",
+ "unpipe": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/finalhandler/node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/finalhandler/node_modules/statuses": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz",
+ "integrity": "sha512-wuTCPGlJONk/a1kqZ4fQM2+908lC7fa7nPYpTC1EhnvqLX/IICbeP1OZGDtA374trpSq68YubKUMo8oRhN46yg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/find-up": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz",
+ "integrity": "sha512-jvElSjyuo4EMQGoTwo1uJU5pQMwTW5lS1x05zzfJuTIyLR3zwO27LYrxNg+dlvKpGOuGy/MzBdXh80g0ve5+HA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "path-exists": "^2.0.0",
+ "pinkie-promise": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/find-versions": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/find-versions/-/find-versions-3.2.0.tgz",
+ "integrity": "sha512-P8WRou2S+oe222TOCHitLy8zj+SIsVJh52VP4lvXkaFVnOFFdoWv1H1Jjvel1aI6NCFOAaeAVm8qrI0odiLcww==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "semver-regex": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/findup-sync": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-2.0.0.tgz",
+ "integrity": "sha512-vs+3unmJT45eczmcAZ6zMJtxN3l/QXeccaXQx5cu/MeJMhewVfoWZqibRkOxPnmoR59+Zy5hjabfQc6JLSah4g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "detect-file": "^1.0.0",
+ "is-glob": "^3.1.0",
+ "micromatch": "^3.0.4",
+ "resolve-dir": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/findup-sync/node_modules/is-glob": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz",
+ "integrity": "sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-extglob": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/fined": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/fined/-/fined-1.2.0.tgz",
+ "integrity": "sha512-ZYDqPLGxDkDhDZBjZBb+oD1+j0rA4E0pXY50eplAAOPg2N/gUBSSk5IM1/QhPfyVo19lJ+CvXpqfvk+b2p/8Ng==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "expand-tilde": "^2.0.2",
+ "is-plain-object": "^2.0.3",
+ "object.defaults": "^1.1.0",
+ "object.pick": "^1.2.0",
+ "parse-filepath": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/flagged-respawn": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.1.tgz",
+ "integrity": "sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/flat-cache": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz",
+ "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "flatted": "^3.2.9",
+ "keyv": "^4.5.4"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/flatted": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz",
+ "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/fluent-ffmpeg": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/fluent-ffmpeg/-/fluent-ffmpeg-2.1.3.tgz",
+ "integrity": "sha512-Be3narBNt2s6bsaqP6Jzq91heDgOEaDCJAXcE3qcma/EJBSy5FB4cvO31XBInuAuKBx8Kptf8dkhjK0IOru39Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "async": "^0.2.9",
+ "which": "^1.1.1"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/fluent-ffmpeg/node_modules/async": {
+ "version": "0.2.10",
+ "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz",
+ "integrity": "sha512-eAkdoKxU6/LkKDBzLpT+t6Ff5EtfSF4wx1WfJiPEEV7WNLnDaRXk0oVysiEPm262roaachGexwUv94WhSgN5TQ==",
+ "dev": true
+ },
+ "node_modules/flush-write-stream": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz",
+ "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "inherits": "^2.0.3",
+ "readable-stream": "^2.3.6"
+ }
+ },
+ "node_modules/follow-redirects": {
+ "version": "1.15.2",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz",
+ "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/RubenVerborgh"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=4.0"
+ },
+ "peerDependenciesMeta": {
+ "debug": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/for-in": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
+ "integrity": "sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/for-own": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz",
+ "integrity": "sha512-0OABksIGrxKK8K4kynWkQ7y1zounQxP+CWnyclVwj81KW3vlLlGUx57DKGcP/LH216GzqnstnPocF16Nxs0Ycg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "for-in": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/forever-agent": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
+ "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/fork-stream": {
+ "version": "0.0.4",
+ "resolved": "https://registry.npmjs.org/fork-stream/-/fork-stream-0.0.4.tgz",
+ "integrity": "sha512-Pqq5NnT78ehvUnAk/We/Jr22vSvanRlFTpAmQ88xBY/M1TlHe+P0ILuEyXS595ysdGfaj22634LBkGMA2GTcpA==",
+ "dev": true,
+ "license": "BSD"
+ },
+ "node_modules/form-data": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
+ "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.6",
+ "mime-types": "^2.1.12"
+ },
+ "engines": {
+ "node": ">= 0.12"
+ }
+ },
+ "node_modules/fragment-cache": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
+ "integrity": "sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "map-cache": "^0.2.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/fresh": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
+ "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/from2": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz",
+ "integrity": "sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "inherits": "^2.0.1",
+ "readable-stream": "^2.0.0"
+ }
+ },
+ "node_modules/fs-constants": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
+ "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fs-extra": {
+ "version": "9.1.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz",
+ "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "at-least-node": "^1.0.0",
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^6.0.1",
+ "universalify": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/fs-extra/node_modules/jsonfile": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
+ "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "universalify": "^2.0.0"
+ },
+ "optionalDependencies": {
+ "graceful-fs": "^4.1.6"
+ }
+ },
+ "node_modules/fs-extra/node_modules/universalify": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
+ "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 10.0.0"
+ }
+ },
+ "node_modules/fs-mkdirp-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz",
+ "integrity": "sha512-+vSd9frUnapVC2RZYfL3FCB2p3g4TBhaUmrsWlSudsGdnxIuUvBB2QM1VZeBtc49QFwrp+wQLrDs3+xxDgI5gQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "graceful-fs": "^4.1.11",
+ "through2": "^2.0.3"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/function-bind": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/function.prototype.name": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz",
+ "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.19.0",
+ "functions-have-names": "^1.2.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/functions-have-names": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz",
+ "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/get-caller-file": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
+ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": "6.* || 8.* || >= 10.*"
+ }
+ },
+ "node_modules/get-intrinsic": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz",
+ "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "function-bind": "^1.1.1",
+ "has": "^1.0.3",
+ "has-symbols": "^1.0.3"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/get-package-info": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/get-package-info/-/get-package-info-1.0.0.tgz",
+ "integrity": "sha512-SCbprXGAPdIhKAXiG+Mk6yeoFH61JlYunqdFQFHDtLjJlDjFf6x07dsS8acO+xWt52jpdVo49AlVDnUVK1sDNw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "bluebird": "^3.1.1",
+ "debug": "^2.2.0",
+ "lodash.get": "^4.0.0",
+ "read-pkg-up": "^2.0.0"
+ },
+ "engines": {
+ "node": ">= 4.0"
+ }
+ },
+ "node_modules/get-package-info/node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/get-package-info/node_modules/find-up": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
+ "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "locate-path": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/get-package-info/node_modules/load-json-file": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz",
+ "integrity": "sha512-3p6ZOGNbiX4CdvEd1VcE6yi78UrGNpjHO33noGwHCnT/o2fyllJDepsm8+mFFv/DvtwFHht5HIHSyOy5a+ChVQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "graceful-fs": "^4.1.2",
+ "parse-json": "^2.2.0",
+ "pify": "^2.0.0",
+ "strip-bom": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/get-package-info/node_modules/locate-path": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz",
+ "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-locate": "^2.0.0",
+ "path-exists": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/get-package-info/node_modules/p-limit": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz",
+ "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-try": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/get-package-info/node_modules/p-locate": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz",
+ "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-limit": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/get-package-info/node_modules/path-exists": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
+ "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/get-package-info/node_modules/path-type": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz",
+ "integrity": "sha512-dUnb5dXUf+kzhC/W/F4e5/SkluXIFf5VUHolW1Eg1irn1hGWjPGdsRcvYJ1nD6lhk8Ir7VM0bHJKsYTx8Jx9OQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "pify": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/get-package-info/node_modules/read-pkg": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz",
+ "integrity": "sha512-eFIBOPW7FGjzBuk3hdXEuNSiTZS/xEMlH49HxMyzb0hyPfu4EhVjT2DH32K1hSSmVq4sebAWnZuuY5auISUTGA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "load-json-file": "^2.0.0",
+ "normalize-package-data": "^2.3.2",
+ "path-type": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/get-package-info/node_modules/read-pkg-up": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz",
+ "integrity": "sha512-1orxQfbWGUiTn9XsPlChs6rLie/AV9jwZTGmu2NZw/CUDJQchXJFYE0Fq5j7+n558T1JhDWLdhyd1Zj+wLY//w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "find-up": "^2.0.0",
+ "read-pkg": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/get-package-info/node_modules/strip-bom": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
+ "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/get-proxy": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/get-proxy/-/get-proxy-2.1.0.tgz",
+ "integrity": "sha512-zmZIaQTWnNQb4R4fJUEp/FC51eZsc6EkErspy3xtIYStaq8EB/hDIWipxsal+E8rz0qD7f2sL/NA9Xee4RInJw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "npm-conf": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/get-stdin": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz",
+ "integrity": "sha512-F5aQMywwJ2n85s4hJPTT9RPxGmubonuB10MNYo17/xph174n2MIR33HRguhzVag10O/npM7SPk73LMZNP+FaWw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/get-stream": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
+ "integrity": "sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/get-symbol-description": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz",
+ "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "get-intrinsic": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/get-value": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
+ "integrity": "sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/getpass": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
+ "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "assert-plus": "^1.0.0"
+ }
+ },
+ "node_modules/gifsicle": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/gifsicle/-/gifsicle-5.3.0.tgz",
+ "integrity": "sha512-FJTpgdj1Ow/FITB7SVza5HlzXa+/lqEY0tHQazAJbuAdvyJtkH4wIdsR2K414oaTwRXHFLLF+tYbipj+OpYg+Q==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "dependencies": {
+ "bin-build": "^3.0.0",
+ "bin-wrapper": "^4.0.0",
+ "execa": "^5.0.0"
+ },
+ "bin": {
+ "gifsicle": "cli.js"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/imagemin/gisicle-bin?sponsor=1"
+ }
+ },
+ "node_modules/gifsicle/node_modules/cross-spawn": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
+ "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/gifsicle/node_modules/execa": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
+ "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cross-spawn": "^7.0.3",
+ "get-stream": "^6.0.0",
+ "human-signals": "^2.1.0",
+ "is-stream": "^2.0.0",
+ "merge-stream": "^2.0.0",
+ "npm-run-path": "^4.0.1",
+ "onetime": "^5.1.2",
+ "signal-exit": "^3.0.3",
+ "strip-final-newline": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sindresorhus/execa?sponsor=1"
+ }
+ },
+ "node_modules/gifsicle/node_modules/get-stream": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz",
+ "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/gifsicle/node_modules/is-stream": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
+ "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/gifsicle/node_modules/npm-run-path": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
+ "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "path-key": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/gifsicle/node_modules/shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "shebang-regex": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/gifsicle/node_modules/shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/gifsicle/node_modules/which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "node-which": "bin/node-which"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/glob": {
+ "version": "7.2.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.1.1",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/glob-stream": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-6.1.0.tgz",
+ "integrity": "sha512-uMbLGAP3S2aDOHUDfdoYcdIePUCfysbAd0IAoWVZbeGU/oNQ8asHVSshLDJUPWxfzj8zsCG7/XeHPHTtow0nsw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "extend": "^3.0.0",
+ "glob": "^7.1.1",
+ "glob-parent": "^3.1.0",
+ "is-negated-glob": "^1.0.0",
+ "ordered-read-streams": "^1.0.0",
+ "pumpify": "^1.3.5",
+ "readable-stream": "^2.1.5",
+ "remove-trailing-separator": "^1.0.1",
+ "to-absolute-glob": "^2.0.0",
+ "unique-stream": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/glob-stream/node_modules/glob-parent": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz",
+ "integrity": "sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^3.1.0",
+ "path-dirname": "^1.0.0"
+ }
+ },
+ "node_modules/glob-stream/node_modules/is-glob": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz",
+ "integrity": "sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-extglob": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/glob-to-regexp": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz",
+ "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==",
+ "dev": true,
+ "license": "BSD-2-Clause"
+ },
+ "node_modules/glob-watcher": {
+ "version": "5.0.5",
+ "resolved": "https://registry.npmjs.org/glob-watcher/-/glob-watcher-5.0.5.tgz",
+ "integrity": "sha512-zOZgGGEHPklZNjZQaZ9f41i7F2YwE+tS5ZHrDhbBCk3stwahn5vQxnFmBJZHoYdusR6R1bLSXeGUy/BhctwKzw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "anymatch": "^2.0.0",
+ "async-done": "^1.2.0",
+ "chokidar": "^2.0.0",
+ "is-negated-glob": "^1.0.0",
+ "just-debounce": "^1.0.0",
+ "normalize-path": "^3.0.0",
+ "object.defaults": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/glob-watcher/node_modules/binary-extensions": {
+ "version": "1.13.1",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz",
+ "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/glob-watcher/node_modules/chokidar": {
+ "version": "2.1.8",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz",
+ "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "anymatch": "^2.0.0",
+ "async-each": "^1.0.1",
+ "braces": "^2.3.2",
+ "glob-parent": "^3.1.0",
+ "inherits": "^2.0.3",
+ "is-binary-path": "^1.0.0",
+ "is-glob": "^4.0.0",
+ "normalize-path": "^3.0.0",
+ "path-is-absolute": "^1.0.0",
+ "readdirp": "^2.2.1",
+ "upath": "^1.1.1"
+ },
+ "optionalDependencies": {
+ "fsevents": "^1.2.7"
+ }
+ },
+ "node_modules/glob-watcher/node_modules/glob-parent": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz",
+ "integrity": "sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^3.1.0",
+ "path-dirname": "^1.0.0"
+ }
+ },
+ "node_modules/glob-watcher/node_modules/glob-parent/node_modules/is-glob": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz",
+ "integrity": "sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-extglob": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/glob-watcher/node_modules/is-binary-path": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz",
+ "integrity": "sha512-9fRVlXc0uCxEDj1nQzaWONSpbTfx0FmJfzHF7pwlI8DkWGoHBBea4Pg5Ky0ojwwxQmnSifgbKkI06Qv0Ljgj+Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "binary-extensions": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/glob-watcher/node_modules/readdirp": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz",
+ "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "graceful-fs": "^4.1.11",
+ "micromatch": "^3.1.10",
+ "readable-stream": "^2.0.2"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/global-agent": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/global-agent/-/global-agent-3.0.0.tgz",
+ "integrity": "sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "optional": true,
+ "dependencies": {
+ "boolean": "^3.0.1",
+ "es6-error": "^4.1.1",
+ "matcher": "^3.0.0",
+ "roarr": "^2.15.3",
+ "semver": "^7.3.2",
+ "serialize-error": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=10.0"
+ }
+ },
+ "node_modules/global-modules": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz",
+ "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "global-prefix": "^1.0.1",
+ "is-windows": "^1.0.1",
+ "resolve-dir": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/global-prefix": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz",
+ "integrity": "sha512-5lsx1NUDHtSjfg0eHlmYvZKv8/nVqX4ckFbM+FrGcQ+04KWcWFo9P5MxPZYSzUvyzmdTbI7Eix8Q4IbELDqzKg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "expand-tilde": "^2.0.2",
+ "homedir-polyfill": "^1.0.1",
+ "ini": "^1.3.4",
+ "is-windows": "^1.0.1",
+ "which": "^1.2.14"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/globals": {
+ "version": "15.0.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-15.0.0.tgz",
+ "integrity": "sha512-m/C/yR4mjO6pXDTm9/R/SpYTAIyaUB4EOzcaaMEl7mds7Mshct9GfejiJNQGjHHbdMPey13Kpu4TMbYi9ex1pw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/globalthis": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz",
+ "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "define-properties": "^1.1.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/globby": {
+ "version": "10.0.2",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.2.tgz",
+ "integrity": "sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/glob": "^7.1.1",
+ "array-union": "^2.1.0",
+ "dir-glob": "^3.0.1",
+ "fast-glob": "^3.0.3",
+ "glob": "^7.1.3",
+ "ignore": "^5.1.1",
+ "merge2": "^1.2.3",
+ "slash": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/glogg": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/glogg/-/glogg-1.0.2.tgz",
+ "integrity": "sha512-5mwUoSuBk44Y4EshyiqcH95ZntbDdTQqA3QYSrxmzj28Ai0vXBGMH1ApSANH14j2sIRtqCEyg6PfsuP7ElOEDA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "sparkles": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/graceful-fs": {
+ "version": "4.2.11",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
+ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/graphemer": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz",
+ "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/gulp": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/gulp/-/gulp-4.0.2.tgz",
+ "integrity": "sha512-dvEs27SCZt2ibF29xYgmnwwCYZxdxhQ/+LFWlbAW8y7jt68L/65402Lz3+CKy0Ov4rOs+NERmDq7YlZaDqUIfA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "glob-watcher": "^5.0.3",
+ "gulp-cli": "^2.2.0",
+ "undertaker": "^1.2.1",
+ "vinyl-fs": "^3.0.0"
+ },
+ "bin": {
+ "gulp": "bin/gulp.js"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/gulp-audiosprite": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/gulp-audiosprite/-/gulp-audiosprite-1.1.0.tgz",
+ "integrity": "sha512-CwSfZjmNPlTyzcAFaE8RiKzh1dQFDLPPZMHshKwvGqNeTB86s30K8hMXGrrjFqHNF9xb0SUnXfbYT32MO4aNog==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "audiosprite": "*",
+ "through2": "*",
+ "vinyl": "*"
+ }
+ },
+ "node_modules/gulp-audiosprite/node_modules/readable-stream": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
+ "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/gulp-audiosprite/node_modules/replace-ext": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-2.0.0.tgz",
+ "integrity": "sha512-UszKE5KVK6JvyD92nzMn9cDapSk6w/CaFZ96CnmDMUqH9oowfxF/ZjRITD25H4DnOQClLA4/j7jLGXXLVKxAug==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/gulp-audiosprite/node_modules/string_decoder": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
+ "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "safe-buffer": "~5.2.0"
+ }
+ },
+ "node_modules/gulp-audiosprite/node_modules/through2": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz",
+ "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "readable-stream": "3"
+ }
+ },
+ "node_modules/gulp-audiosprite/node_modules/vinyl": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-3.0.0.tgz",
+ "integrity": "sha512-rC2VRfAVVCGEgjnxHUnpIVh3AGuk62rP3tqVrn+yab0YH7UULisC085+NYH+mnqf3Wx4SpSi1RQMwudL89N03g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "clone": "^2.1.2",
+ "clone-stats": "^1.0.0",
+ "remove-trailing-separator": "^1.1.0",
+ "replace-ext": "^2.0.0",
+ "teex": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/gulp-cache": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/gulp-cache/-/gulp-cache-1.1.3.tgz",
+ "integrity": "sha512-NE814LdX1NWQn2sMzn+Rf673o4mqlgg7OyLf92oQ4KEl6DdPfduEGLNH+HexLVcFZXH93DBuxFOvpv4/Js5VaA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.5.5",
+ "cache-swap": "^0.3.0",
+ "core-js": "3",
+ "object.pick": "^1.3.0",
+ "plugin-error": "^1.0.1",
+ "through2": "3.0.1",
+ "vinyl": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/gulp-cache/node_modules/readable-stream": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
+ "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/gulp-cache/node_modules/string_decoder": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
+ "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "safe-buffer": "~5.2.0"
+ }
+ },
+ "node_modules/gulp-cache/node_modules/through2": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.1.tgz",
+ "integrity": "sha512-M96dvTalPT3YbYLaKaCuwu+j06D/8Jfib0o/PxbVt6Amhv3dUAtW6rTV1jPgJSBG83I/e04Y6xkVdVhSRhi0ww==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "readable-stream": "2 || 3"
+ }
+ },
+ "node_modules/gulp-cached": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/gulp-cached/-/gulp-cached-1.1.1.tgz",
+ "integrity": "sha512-OEGsICR6Vmx0VK3nhpy5MGPzAjeDYC3+NKxNtJAu4DW8L15oy8tCe2WuD6HDEj9BsbSopnOBiXPK95YHvO0DpA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "lodash.defaults": "^4.2.0",
+ "through2": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 0.9.0"
+ }
+ },
+ "node_modules/gulp-clean": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/gulp-clean/-/gulp-clean-0.4.0.tgz",
+ "integrity": "sha512-DARK8rNMo4lHOFLGTiHEJdf19GuoBDHqGUaypz+fOhrvOs3iFO7ntdYtdpNxv+AzSJBx/JfypF0yEj9ks1IStQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fancy-log": "^1.3.2",
+ "plugin-error": "^0.1.2",
+ "rimraf": "^2.6.2",
+ "through2": "^2.0.3",
+ "vinyl": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=0.9"
+ }
+ },
+ "node_modules/gulp-clean/node_modules/arr-diff": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-1.1.0.tgz",
+ "integrity": "sha512-OQwDZUqYaQwyyhDJHThmzId8daf4/RFNLaeh3AevmSeZ5Y7ug4Ga/yKc6l6kTZOBW781rCj103ZuTh8GAsB3+Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "arr-flatten": "^1.0.1",
+ "array-slice": "^0.2.3"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/gulp-clean/node_modules/arr-union": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-2.1.0.tgz",
+ "integrity": "sha512-t5db90jq+qdgk8aFnxEkjqta0B/GHrM1pxzuuZz2zWsOXc5nKu3t+76s/PQBA8FTcM/ipspIH9jWG4OxCBc2eA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/gulp-clean/node_modules/array-slice": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-0.2.3.tgz",
+ "integrity": "sha512-rlVfZW/1Ph2SNySXwR9QYkChp8EkOEiTMO5Vwx60usw04i4nWemkm9RXmQqgkQFaLHsqLuADvjp6IfgL9l2M8Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/gulp-clean/node_modules/extend-shallow": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-1.1.4.tgz",
+ "integrity": "sha512-L7AGmkO6jhDkEBBGWlLtftA80Xq8DipnrRPr0pyi7GQLXkaq9JYA4xF4z6qnadIC6euiTDKco0cGSU9muw+WTw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "kind-of": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/gulp-clean/node_modules/kind-of": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-1.1.0.tgz",
+ "integrity": "sha512-aUH6ElPnMGon2/YkxRIigV32MOpTVcoXQ1Oo8aYn40s+sJ3j+0gFZsT8HKDcxNy7Fi9zuquWtGaGAahOdv5p/g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/gulp-clean/node_modules/plugin-error": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-0.1.2.tgz",
+ "integrity": "sha512-WzZHcm4+GO34sjFMxQMqZbsz3xiNEgonCskQ9v+IroMmYgk/tas8dG+Hr2D6IbRPybZ12oWpzE/w3cGJ6FJzOw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-cyan": "^0.1.1",
+ "ansi-red": "^0.1.1",
+ "arr-diff": "^1.0.1",
+ "arr-union": "^2.0.1",
+ "extend-shallow": "^1.1.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/gulp-cli": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/gulp-cli/-/gulp-cli-2.3.0.tgz",
+ "integrity": "sha512-zzGBl5fHo0EKSXsHzjspp3y5CONegCm8ErO5Qh0UzFzk2y4tMvzLWhoDokADbarfZRL2pGpRp7yt6gfJX4ph7A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-colors": "^1.0.1",
+ "archy": "^1.0.0",
+ "array-sort": "^1.0.0",
+ "color-support": "^1.1.3",
+ "concat-stream": "^1.6.0",
+ "copy-props": "^2.0.1",
+ "fancy-log": "^1.3.2",
+ "gulplog": "^1.0.0",
+ "interpret": "^1.4.0",
+ "isobject": "^3.0.1",
+ "liftoff": "^3.1.0",
+ "matchdep": "^2.0.0",
+ "mute-stdout": "^1.0.0",
+ "pretty-hrtime": "^1.0.0",
+ "replace-homedir": "^1.0.0",
+ "semver-greatest-satisfied-range": "^1.1.0",
+ "v8flags": "^3.2.0",
+ "yargs": "^7.1.0"
+ },
+ "bin": {
+ "gulp": "bin/gulp.js"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/gulp-cli/node_modules/cliui": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz",
+ "integrity": "sha512-0yayqDxWQbqk3ojkYqUKqaAQ6AfNKeKWRNA8kR0WXzAsdHpP4BIaOmMAG87JGuO6qcobyW4GjxHd9PmhEd+T9w==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "string-width": "^1.0.1",
+ "strip-ansi": "^3.0.1",
+ "wrap-ansi": "^2.0.0"
+ }
+ },
+ "node_modules/gulp-cli/node_modules/concat-stream": {
+ "version": "1.6.2",
+ "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
+ "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
+ "dev": true,
+ "engines": [
+ "node >= 0.8"
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "buffer-from": "^1.0.0",
+ "inherits": "^2.0.3",
+ "readable-stream": "^2.2.2",
+ "typedarray": "^0.0.6"
+ }
+ },
+ "node_modules/gulp-cli/node_modules/get-caller-file": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz",
+ "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/gulp-cli/node_modules/is-fullwidth-code-point": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
+ "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "number-is-nan": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/gulp-cli/node_modules/string-width": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+ "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "code-point-at": "^1.0.0",
+ "is-fullwidth-code-point": "^1.0.0",
+ "strip-ansi": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/gulp-cli/node_modules/wrap-ansi": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
+ "integrity": "sha512-vAaEaDM946gbNpH5pLVNR+vX2ht6n0Bt3GXwVB1AuAqZosOvHNF3P7wDnh8KLkSqgUh0uh77le7Owgoz+Z9XBw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "string-width": "^1.0.1",
+ "strip-ansi": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/gulp-cli/node_modules/y18n": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz",
+ "integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/gulp-cli/node_modules/yargs": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.2.tgz",
+ "integrity": "sha512-ZEjj/dQYQy0Zx0lgLMLR8QuaqTihnxirir7EwUHp1Axq4e3+k8jXU5K0VLbNvedv1f4EWtBonDIZm0NUr+jCcA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "camelcase": "^3.0.0",
+ "cliui": "^3.2.0",
+ "decamelize": "^1.1.1",
+ "get-caller-file": "^1.0.1",
+ "os-locale": "^1.4.0",
+ "read-pkg-up": "^1.0.1",
+ "require-directory": "^2.1.1",
+ "require-main-filename": "^1.0.1",
+ "set-blocking": "^2.0.0",
+ "string-width": "^1.0.2",
+ "which-module": "^1.0.0",
+ "y18n": "^3.2.1",
+ "yargs-parser": "^5.0.1"
+ }
+ },
+ "node_modules/gulp-cli/node_modules/yargs-parser": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.1.tgz",
+ "integrity": "sha512-wpav5XYiddjXxirPoCTUPbqM0PXvJ9hiBMvuJgInvo4/lAOTZzUprArw17q2O1P2+GHhbBr18/iQwjL5Z9BqfA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "camelcase": "^3.0.0",
+ "object.assign": "^4.1.0"
+ }
+ },
+ "node_modules/gulp-dart-sass": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/gulp-dart-sass/-/gulp-dart-sass-1.0.2.tgz",
+ "integrity": "sha512-8fLttA824mbuc0jRVlGs00zWYZXBckat6INawx5kp66Eqsz5srNWTA51t0mbfB4C8a/a/GZ9muYLwXGklgAHlw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "chalk": "^2.3.0",
+ "lodash.clonedeep": "^4.3.2",
+ "plugin-error": "^1.0.1",
+ "replace-ext": "^1.0.0",
+ "sass": "^1.26.3",
+ "strip-ansi": "^4.0.0",
+ "through2": "^2.0.0",
+ "vinyl-sourcemaps-apply": "^0.2.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/gulp-dart-sass/node_modules/ansi-regex": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz",
+ "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/gulp-dart-sass/node_modules/ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^1.9.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/gulp-dart-sass/node_modules/chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/gulp-dart-sass/node_modules/strip-ansi": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+ "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/gulp-dom": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/gulp-dom/-/gulp-dom-1.0.0.tgz",
+ "integrity": "sha512-hD2w2t3fsjPicX2mT6MFFb+eP3FyCVtEHdejGMMH4+w9EBFxA2xIZadqlzYdAEdE+39dP1aGatuhdHJteUvn1A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "jsdom": "12.2.0",
+ "plugin-error": "1.0.1",
+ "through2": "2.0.3"
+ }
+ },
+ "node_modules/gulp-dom/node_modules/through2": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz",
+ "integrity": "sha512-tmNYYHFqXmaKSSlOU4ZbQ82cxmFQa5LRWKFtWCNkGIiZ3/VHmOffCeWfBRZZRyXAhNP9itVMR+cuvomBOPlm8g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "readable-stream": "^2.1.5",
+ "xtend": "~4.0.1"
+ }
+ },
+ "node_modules/gulp-fluent-ffmpeg": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/gulp-fluent-ffmpeg/-/gulp-fluent-ffmpeg-2.0.0.tgz",
+ "integrity": "sha512-pwG6N+NKwLzO/0ybzgcwiADKZ4OzpFjNR4drqCvbvluYcSh/yvsAW7wm63jFzpJIjfFnanYGPNWiUn8+TuTR/g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "concat-stream": "^2.0.0",
+ "fluent-ffmpeg": "^2.1.2",
+ "plugin-error": "^1.0.1",
+ "through2": "^3.0.1"
+ }
+ },
+ "node_modules/gulp-fluent-ffmpeg/node_modules/readable-stream": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
+ "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/gulp-fluent-ffmpeg/node_modules/string_decoder": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
+ "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "safe-buffer": "~5.2.0"
+ }
+ },
+ "node_modules/gulp-fluent-ffmpeg/node_modules/through2": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz",
+ "integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "inherits": "^2.0.4",
+ "readable-stream": "2 || 3"
+ }
+ },
+ "node_modules/gulp-htmlmin": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/gulp-htmlmin/-/gulp-htmlmin-5.0.1.tgz",
+ "integrity": "sha512-ASlyDPZOSKjHYUifYV0rf9JPDflN9IRIb8lw2vRqtYMC4ljU3zAmnnaVXwFQ3H+CfXxZSUesZ2x7jrnPJu93jA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "html-minifier": "^3.5.20",
+ "plugin-error": "^1.0.1",
+ "through2": "^2.0.3"
+ },
+ "engines": {
+ "node": ">= 6.0"
+ }
+ },
+ "node_modules/gulp-if": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/gulp-if/-/gulp-if-3.0.0.tgz",
+ "integrity": "sha512-fCUEngzNiEZEK2YuPm+sdMpO6ukb8+/qzbGfJBXyNOXz85bCG7yBI+pPSl+N90d7gnLvMsarthsAImx0qy7BAw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "gulp-match": "^1.1.0",
+ "ternary-stream": "^3.0.0",
+ "through2": "^3.0.1"
+ }
+ },
+ "node_modules/gulp-if/node_modules/readable-stream": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
+ "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/gulp-if/node_modules/string_decoder": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
+ "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "safe-buffer": "~5.2.0"
+ }
+ },
+ "node_modules/gulp-if/node_modules/through2": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz",
+ "integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "inherits": "^2.0.4",
+ "readable-stream": "2 || 3"
+ }
+ },
+ "node_modules/gulp-imagemin": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/gulp-imagemin/-/gulp-imagemin-7.1.0.tgz",
+ "integrity": "sha512-6xBTNybmPY2YrvrhhlS8Mxi0zn0ypusLon63p9XXxDtIf7U7c6KcViz94K7Skosucr3378A6IY2kJSjJyuwylQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "chalk": "^3.0.0",
+ "fancy-log": "^1.3.2",
+ "imagemin": "^7.0.0",
+ "plugin-error": "^1.0.1",
+ "plur": "^3.0.1",
+ "pretty-bytes": "^5.3.0",
+ "through2-concurrent": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ },
+ "optionalDependencies": {
+ "imagemin-gifsicle": "^7.0.0",
+ "imagemin-mozjpeg": "^8.0.0",
+ "imagemin-optipng": "^7.0.0",
+ "imagemin-svgo": "^7.0.0"
+ },
+ "peerDependencies": {
+ "gulp": ">=4"
+ },
+ "peerDependenciesMeta": {
+ "gulp": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/gulp-imagemin/node_modules/chalk": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
+ "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/gulp-imagemin/node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/gulp-match": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/gulp-match/-/gulp-match-1.1.0.tgz",
+ "integrity": "sha512-DlyVxa1Gj24DitY2OjEsS+X6tDpretuxD6wTfhXE/Rw2hweqc1f6D/XtsJmoiCwLWfXgR87W9ozEityPCVzGtQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "minimatch": "^3.0.3"
+ }
+ },
+ "node_modules/gulp-plumber": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/gulp-plumber/-/gulp-plumber-1.2.1.tgz",
+ "integrity": "sha512-mctAi9msEAG7XzW5ytDVZ9PxWMzzi1pS2rBH7lA095DhMa6KEXjm+St0GOCc567pJKJ/oCvosVAZEpAey0q2eQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "chalk": "^1.1.3",
+ "fancy-log": "^1.3.2",
+ "plugin-error": "^0.1.2",
+ "through2": "^2.0.3"
+ },
+ "engines": {
+ "node": ">=0.10",
+ "npm": ">=1.2.10"
+ }
+ },
+ "node_modules/gulp-plumber/node_modules/arr-diff": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-1.1.0.tgz",
+ "integrity": "sha512-OQwDZUqYaQwyyhDJHThmzId8daf4/RFNLaeh3AevmSeZ5Y7ug4Ga/yKc6l6kTZOBW781rCj103ZuTh8GAsB3+Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "arr-flatten": "^1.0.1",
+ "array-slice": "^0.2.3"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/gulp-plumber/node_modules/arr-union": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-2.1.0.tgz",
+ "integrity": "sha512-t5db90jq+qdgk8aFnxEkjqta0B/GHrM1pxzuuZz2zWsOXc5nKu3t+76s/PQBA8FTcM/ipspIH9jWG4OxCBc2eA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/gulp-plumber/node_modules/array-slice": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-0.2.3.tgz",
+ "integrity": "sha512-rlVfZW/1Ph2SNySXwR9QYkChp8EkOEiTMO5Vwx60usw04i4nWemkm9RXmQqgkQFaLHsqLuADvjp6IfgL9l2M8Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/gulp-plumber/node_modules/extend-shallow": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-1.1.4.tgz",
+ "integrity": "sha512-L7AGmkO6jhDkEBBGWlLtftA80Xq8DipnrRPr0pyi7GQLXkaq9JYA4xF4z6qnadIC6euiTDKco0cGSU9muw+WTw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "kind-of": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/gulp-plumber/node_modules/kind-of": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-1.1.0.tgz",
+ "integrity": "sha512-aUH6ElPnMGon2/YkxRIigV32MOpTVcoXQ1Oo8aYn40s+sJ3j+0gFZsT8HKDcxNy7Fi9zuquWtGaGAahOdv5p/g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/gulp-plumber/node_modules/plugin-error": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-0.1.2.tgz",
+ "integrity": "sha512-WzZHcm4+GO34sjFMxQMqZbsz3xiNEgonCskQ9v+IroMmYgk/tas8dG+Hr2D6IbRPybZ12oWpzE/w3cGJ6FJzOw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-cyan": "^0.1.1",
+ "ansi-red": "^0.1.1",
+ "arr-diff": "^1.0.1",
+ "arr-union": "^2.0.1",
+ "extend-shallow": "^1.1.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/gulp-postcss": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/gulp-postcss/-/gulp-postcss-8.0.0.tgz",
+ "integrity": "sha512-Wtl6vH7a+8IS/fU5W9IbOpcaLqKxd5L1DUOzaPmlnCbX1CrG0aWdwVnC3Spn8th0m8D59YbysV5zPUe1n/GJYg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fancy-log": "^1.3.2",
+ "plugin-error": "^1.0.1",
+ "postcss": "^7.0.2",
+ "postcss-load-config": "^2.0.0",
+ "vinyl-sourcemaps-apply": "^0.2.1"
+ }
+ },
+ "node_modules/gulp-rename": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/gulp-rename/-/gulp-rename-2.0.0.tgz",
+ "integrity": "sha512-97Vba4KBzbYmR5VBs9mWmK+HwIf5mj+/zioxfZhOKeXtx5ZjBk57KFlePf5nxq9QsTtFl0ejnHE3zTC9MHXqyQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/gulp-util": {
+ "version": "2.2.20",
+ "resolved": "https://registry.npmjs.org/gulp-util/-/gulp-util-2.2.20.tgz",
+ "integrity": "sha512-9rtv4sj9EtCWYGD15HQQvWtRBtU9g1t0+w29tphetHxjxEAuBKQJkhGqvlLkHEtUjEgoqIpsVwPKU1yMZAa+wA==",
+ "dev": true,
+ "dependencies": {
+ "chalk": "^0.5.0",
+ "dateformat": "^1.0.7-1.2.3",
+ "lodash._reinterpolate": "^2.4.1",
+ "lodash.template": "^2.4.1",
+ "minimist": "^0.2.0",
+ "multipipe": "^0.1.0",
+ "through2": "^0.5.0",
+ "vinyl": "^0.2.1"
+ },
+ "engines": {
+ "node": ">= 0.9"
+ }
+ },
+ "node_modules/gulp-util/node_modules/ansi-styles": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.1.0.tgz",
+ "integrity": "sha512-f2PKUkN5QngiSemowa6Mrk9MPCdtFiOSmibjZ+j1qhLGHHYsqZwmBMRF3IRMVXo8sybDqx2fJl2d/8OphBoWkA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/gulp-util/node_modules/chalk": {
+ "version": "0.5.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.5.1.tgz",
+ "integrity": "sha512-bIKA54hP8iZhyDT81TOsJiQvR1gW+ZYSXFaZUAvoD4wCHdbHY2actmpTE4x344ZlFqHbvoxKOaESULTZN2gstg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^1.1.0",
+ "escape-string-regexp": "^1.0.0",
+ "has-ansi": "^0.1.0",
+ "strip-ansi": "^0.3.0",
+ "supports-color": "^0.2.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/gulp-util/node_modules/clone-stats": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz",
+ "integrity": "sha512-dhUqc57gSMCo6TX85FLfe51eC/s+Im2MLkAgJwfaRRexR2tA4dd3eLEW4L6efzHc2iNorrRRXITifnDLlRrhaA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/gulp-util/node_modules/has-ansi": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-0.1.0.tgz",
+ "integrity": "sha512-1YsTg1fk2/6JToQhtZkArMkurq8UoWU1Qe0aR3VUHjgij4nOylSWLWAtBXoZ4/dXOmugfLGm1c+QhuD0JyedFA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^0.2.0"
+ },
+ "bin": {
+ "has-ansi": "cli.js"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/gulp-util/node_modules/minimist": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.2.2.tgz",
+ "integrity": "sha512-g92kDfAOAszDRtHNagjZPPI/9lfOFaRBL/Ud6Z0RKZua/x+49awTydZLh5Gkhb80Xy5hmcvZNLGzscW5n5yd0g==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/gulp-util/node_modules/readable-stream": {
+ "version": "1.0.34",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
+ "integrity": "sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.1",
+ "isarray": "0.0.1",
+ "string_decoder": "~0.10.x"
+ }
+ },
+ "node_modules/gulp-util/node_modules/strip-ansi": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.3.0.tgz",
+ "integrity": "sha512-DerhZL7j6i6/nEnVG0qViKXI0OKouvvpsAiaj7c+LfqZZZxdwZtv8+UiA/w4VUJpT8UzX0pR1dcHOii1GbmruQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^0.2.1"
+ },
+ "bin": {
+ "strip-ansi": "cli.js"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/gulp-util/node_modules/supports-color": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-0.2.0.tgz",
+ "integrity": "sha512-tdCZ28MnM7k7cJDJc7Eq80A9CsRFAAOZUy41npOZCs++qSjfIy7o5Rh46CBk+Dk5FbKJ33X3Tqg4YrV07N5RaA==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "supports-color": "cli.js"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/gulp-util/node_modules/through2": {
+ "version": "0.5.1",
+ "resolved": "https://registry.npmjs.org/through2/-/through2-0.5.1.tgz",
+ "integrity": "sha512-zexCrAOTbjkBCXGyozn7hhS3aEaqdrc59mAD2E3dKYzV1vFuEGQ1hEDJN2oQMQFwy4he2zyLqPZV+AlfS8ZWJA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "readable-stream": "~1.0.17",
+ "xtend": "~3.0.0"
+ }
+ },
+ "node_modules/gulp-util/node_modules/vinyl": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.2.3.tgz",
+ "integrity": "sha512-4gFk9xrecazOTuFKcUYrE1TjHSYL63dio72D+q0d1mHF51FEcxTT2RHFpHbN5TNJgmPYHuVsBdhvXEOCDcytSA==",
+ "dev": true,
+ "dependencies": {
+ "clone-stats": "~0.0.1"
+ },
+ "engines": {
+ "node": ">= 0.9"
+ }
+ },
+ "node_modules/gulp-util/node_modules/xtend": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/xtend/-/xtend-3.0.0.tgz",
+ "integrity": "sha512-sp/sT9OALMjRW1fKDlPeuSZlDQpkqReA0pyJukniWbTGoEKefHxhGJynE3PNhUMlcM8qWIjPwecwCw4LArS5Eg==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.4"
+ }
+ },
+ "node_modules/gulp-webserver": {
+ "version": "0.9.1",
+ "resolved": "https://registry.npmjs.org/gulp-webserver/-/gulp-webserver-0.9.1.tgz",
+ "integrity": "sha512-Z9UVbOglUaLy4xsUN+3TvVZ3a1O/8r9xd7F552Zx2ARieR+Ko41jbOJjEmdOj1KteCuuPs0jRHlNvZgA+yW1zw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "connect": "^3.0.1",
+ "connect-livereload": "^0.4.0",
+ "gulp-util": "^2.2.19",
+ "isarray": "0.0.1",
+ "node.extend": "^1.0.10",
+ "open": "^0.0.5",
+ "proxy-middleware": "^0.5.0",
+ "serve-index": "^1.1.4",
+ "serve-static": "^1.3.0",
+ "through2": "^0.5.1",
+ "tiny-lr": "0.1.4",
+ "watch": "^0.11.0"
+ }
+ },
+ "node_modules/gulp-webserver/node_modules/connect": {
+ "version": "3.7.0",
+ "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz",
+ "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "debug": "2.6.9",
+ "finalhandler": "1.1.2",
+ "parseurl": "~1.3.3",
+ "utils-merge": "1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.10.0"
+ }
+ },
+ "node_modules/gulp-webserver/node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/gulp-webserver/node_modules/depd": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
+ "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/gulp-webserver/node_modules/destroy": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
+ "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8",
+ "npm": "1.2.8000 || >= 1.4.16"
+ }
+ },
+ "node_modules/gulp-webserver/node_modules/finalhandler": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
+ "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "debug": "2.6.9",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "on-finished": "~2.3.0",
+ "parseurl": "~1.3.3",
+ "statuses": "~1.5.0",
+ "unpipe": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/gulp-webserver/node_modules/finalhandler/node_modules/on-finished": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
+ "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ee-first": "1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/gulp-webserver/node_modules/finalhandler/node_modules/statuses": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
+ "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/gulp-webserver/node_modules/http-errors": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
+ "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "depd": "2.0.0",
+ "inherits": "2.0.4",
+ "setprototypeof": "1.2.0",
+ "statuses": "2.0.1",
+ "toidentifier": "1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/gulp-webserver/node_modules/mime": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
+ "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "mime": "cli.js"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/gulp-webserver/node_modules/on-finished": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
+ "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ee-first": "1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/gulp-webserver/node_modules/readable-stream": {
+ "version": "1.0.34",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
+ "integrity": "sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.1",
+ "isarray": "0.0.1",
+ "string_decoder": "~0.10.x"
+ }
+ },
+ "node_modules/gulp-webserver/node_modules/send": {
+ "version": "0.18.0",
+ "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz",
+ "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "debug": "2.6.9",
+ "depd": "2.0.0",
+ "destroy": "1.2.0",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "etag": "~1.8.1",
+ "fresh": "0.5.2",
+ "http-errors": "2.0.0",
+ "mime": "1.6.0",
+ "ms": "2.1.3",
+ "on-finished": "2.4.1",
+ "range-parser": "~1.2.1",
+ "statuses": "2.0.1"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/gulp-webserver/node_modules/send/node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/gulp-webserver/node_modules/serve-static": {
+ "version": "1.15.0",
+ "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz",
+ "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "parseurl": "~1.3.3",
+ "send": "0.18.0"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/gulp-webserver/node_modules/setprototypeof": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
+ "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/gulp-webserver/node_modules/statuses": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
+ "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/gulp-webserver/node_modules/through2": {
+ "version": "0.5.1",
+ "resolved": "https://registry.npmjs.org/through2/-/through2-0.5.1.tgz",
+ "integrity": "sha512-zexCrAOTbjkBCXGyozn7hhS3aEaqdrc59mAD2E3dKYzV1vFuEGQ1hEDJN2oQMQFwy4he2zyLqPZV+AlfS8ZWJA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "readable-stream": "~1.0.17",
+ "xtend": "~3.0.0"
+ }
+ },
+ "node_modules/gulp-webserver/node_modules/xtend": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/xtend/-/xtend-3.0.0.tgz",
+ "integrity": "sha512-sp/sT9OALMjRW1fKDlPeuSZlDQpkqReA0pyJukniWbTGoEKefHxhGJynE3PNhUMlcM8qWIjPwecwCw4LArS5Eg==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.4"
+ }
+ },
+ "node_modules/gulp-yaml": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/gulp-yaml/-/gulp-yaml-2.0.4.tgz",
+ "integrity": "sha512-S/9Ib8PO+jGkCvWDwBUkmFkeW7QM0pp4PO8NNrMEfWo5Sk30P+KqpyXc4055L/vOX326T/b9MhM4nw5EenyX9g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "bufferstreams": "^2.0.1",
+ "js-yaml": "^3.13.1",
+ "object-assign": "^4.1.1",
+ "plugin-error": "^1.0.1",
+ "replace-ext": "^1.0.0",
+ "through2": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.5"
+ }
+ },
+ "node_modules/gulp-yaml/node_modules/readable-stream": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
+ "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/gulp-yaml/node_modules/string_decoder": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
+ "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "safe-buffer": "~5.2.0"
+ }
+ },
+ "node_modules/gulp-yaml/node_modules/through2": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz",
+ "integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "inherits": "^2.0.4",
+ "readable-stream": "2 || 3"
+ }
+ },
+ "node_modules/gulplog": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/gulplog/-/gulplog-1.0.0.tgz",
+ "integrity": "sha512-hm6N8nrm3Y08jXie48jsC55eCZz9mnb4OirAStEk2deqeyhXU3C1otDVh+ccttMuc1sBi6RX6ZJ720hs9RCvgw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "glogg": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/har-schema": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
+ "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/har-validator": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz",
+ "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ajv": "^6.12.3",
+ "har-schema": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/has": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
+ "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "function-bind": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4.0"
+ }
+ },
+ "node_modules/has-ansi": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
+ "integrity": "sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/has-ansi/node_modules/ansi-regex": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+ "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/has-bigints": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz",
+ "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/has-property-descriptors": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz",
+ "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "get-intrinsic": "^1.1.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-symbol-support-x": {
+ "version": "1.4.2",
+ "resolved": "https://registry.npmjs.org/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz",
+ "integrity": "sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/has-symbols": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
+ "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-to-string-tag-x": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz",
+ "integrity": "sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-symbol-support-x": "^1.4.1"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/has-tostringtag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz",
+ "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-symbols": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-value": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz",
+ "integrity": "sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "get-value": "^2.0.6",
+ "has-values": "^1.0.0",
+ "isobject": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/has-values": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz",
+ "integrity": "sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-number": "^3.0.0",
+ "kind-of": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/has-values/node_modules/kind-of": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz",
+ "integrity": "sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-buffer": "^1.1.5"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/he": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
+ "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "he": "bin/he"
+ }
+ },
+ "node_modules/hex-color-regex": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz",
+ "integrity": "sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/homedir-polyfill": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz",
+ "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "parse-passwd": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/hosted-git-info": {
+ "version": "2.8.9",
+ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
+ "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/howler": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/howler/-/howler-2.2.3.tgz",
+ "integrity": "sha512-QM0FFkw0LRX1PR8pNzJVAY25JhIWvbKMBFM4gqk+QdV+kPXOhleWGCB6AiAF/goGjIHK2e/nIElplvjQwhr0jg==",
+ "license": "MIT"
+ },
+ "node_modules/hsl-regex": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/hsl-regex/-/hsl-regex-1.0.0.tgz",
+ "integrity": "sha512-M5ezZw4LzXbBKMruP+BNANf0k+19hDQMgpzBIYnya//Al+fjNct9Wf3b1WedLqdEs2hKBvxq/jh+DsHJLj0F9A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/hsla-regex": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/hsla-regex/-/hsla-regex-1.0.0.tgz",
+ "integrity": "sha512-7Wn5GMLuHBjZCb2bTmnDOycho0p/7UVaAeqXZGbHrBCl6Yd/xDhQJAXe6Ga9AXJH2I5zY1dEdYw2u1UptnSBJA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/html-encoding-sniffer": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz",
+ "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "whatwg-encoding": "^1.0.1"
+ }
+ },
+ "node_modules/html-minifier": {
+ "version": "3.5.21",
+ "resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-3.5.21.tgz",
+ "integrity": "sha512-LKUKwuJDhxNa3uf/LPR/KVjm/l3rBqtYeCOAekvG8F1vItxMUpueGd94i/asDDr8/1u7InxzFA5EeGjhhG5mMA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "camel-case": "3.0.x",
+ "clean-css": "4.2.x",
+ "commander": "2.17.x",
+ "he": "1.2.x",
+ "param-case": "2.1.x",
+ "relateurl": "0.2.x",
+ "uglify-js": "3.4.x"
+ },
+ "bin": {
+ "html-minifier": "cli.js"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/html-minifier/node_modules/commander": {
+ "version": "2.17.1",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz",
+ "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/http-cache-semantics": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz",
+ "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==",
+ "dev": true,
+ "license": "BSD-2-Clause"
+ },
+ "node_modules/http-errors": {
+ "version": "1.6.3",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz",
+ "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "depd": "~1.1.2",
+ "inherits": "2.0.3",
+ "setprototypeof": "1.1.0",
+ "statuses": ">= 1.4.0 < 2"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/http-errors/node_modules/inherits": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+ "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/http-parser-js": {
+ "version": "0.5.8",
+ "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz",
+ "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/http-proxy": {
+ "version": "1.18.1",
+ "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz",
+ "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "eventemitter3": "^4.0.0",
+ "follow-redirects": "^1.0.0",
+ "requires-port": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/http-signature": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
+ "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "assert-plus": "^1.0.0",
+ "jsprim": "^1.2.2",
+ "sshpk": "^1.7.0"
+ },
+ "engines": {
+ "node": ">=0.8",
+ "npm": ">=1.3.7"
+ }
+ },
+ "node_modules/http2-wrapper": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz",
+ "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "quick-lru": "^5.1.1",
+ "resolve-alpn": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=10.19.0"
+ }
+ },
+ "node_modules/human-signals": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
+ "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=10.17.0"
+ }
+ },
+ "node_modules/iconv-lite": {
+ "version": "0.4.24",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
+ "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "safer-buffer": ">= 2.1.2 < 3"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ieee754": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
+ "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/ignore": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.1.tgz",
+ "integrity": "sha512-d2qQLzTJ9WxQftPAuEQpSPmKqzxePjzVbpAVv62AQ64NTL+wR4JkrVqR/LqFsFEUsHDAiId52mJteHDFuDkElA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/imagemin": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/imagemin/-/imagemin-7.0.1.tgz",
+ "integrity": "sha512-33AmZ+xjZhg2JMCe+vDf6a9mzWukE7l+wAtesjE7KyteqqKjzxv7aVQeWnul1Ve26mWvEQqyPwl0OctNBfSR9w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "file-type": "^12.0.0",
+ "globby": "^10.0.0",
+ "graceful-fs": "^4.2.2",
+ "junk": "^3.1.0",
+ "make-dir": "^3.0.0",
+ "p-pipe": "^3.0.0",
+ "replace-ext": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/imagemin-gifsicle": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/imagemin-gifsicle/-/imagemin-gifsicle-7.0.0.tgz",
+ "integrity": "sha512-LaP38xhxAwS3W8PFh4y5iQ6feoTSF+dTAXFRUEYQWYst6Xd+9L/iPk34QGgK/VO/objmIlmq9TStGfVY2IcHIA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "execa": "^1.0.0",
+ "gifsicle": "^5.0.0",
+ "is-gif": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/imagemin/imagemin-gifsicle?sponsor=1"
+ }
+ },
+ "node_modules/imagemin-jpegtran": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/imagemin-jpegtran/-/imagemin-jpegtran-7.0.0.tgz",
+ "integrity": "sha512-MJoyTCW8YjMJf56NorFE41SR/WkaGA3IYk4JgvMlRwguJEEd3PnP9UxA8Y2UWjquz8d+On3Ds/03ZfiiLS8xTQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "exec-buffer": "^3.0.0",
+ "is-jpg": "^2.0.0",
+ "jpegtran-bin": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/imagemin-mozjpeg": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/imagemin-mozjpeg/-/imagemin-mozjpeg-8.0.0.tgz",
+ "integrity": "sha512-+EciPiIjCb8JWjQNr1q8sYWYf7GDCNDxPYnkD11TNIjjWNzaV+oTg4DpOPQjl5ZX/KRCPMEgS79zLYAQzLitIA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "execa": "^1.0.0",
+ "is-jpg": "^2.0.0",
+ "mozjpeg": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/imagemin-optipng": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/imagemin-optipng/-/imagemin-optipng-7.1.0.tgz",
+ "integrity": "sha512-JNORTZ6j6untH7e5gF4aWdhDCxe3ODsSLKs/f7Grewy3ebZpl1ZsU+VUTPY4rzeHgaFA8GSWOoA8V2M3OixWZQ==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "exec-buffer": "^3.0.0",
+ "is-png": "^2.0.0",
+ "optipng-bin": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/imagemin-pngquant": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/imagemin-pngquant/-/imagemin-pngquant-8.0.0.tgz",
+ "integrity": "sha512-PVq0diOxO+Zyq/zlMCz2Pfu6mVLHgiT1GpW702OwVlnej+NhS6ZQegYi3OFEDW8d7GxouyR5e8R+t53SMciOeg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "execa": "^1.0.0",
+ "is-png": "^2.0.0",
+ "is-stream": "^2.0.0",
+ "ow": "^0.13.2",
+ "pngquant-bin": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/imagemin-pngquant/node_modules/is-stream": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
+ "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/imagemin-svgo": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/imagemin-svgo/-/imagemin-svgo-7.1.0.tgz",
+ "integrity": "sha512-0JlIZNWP0Luasn1HT82uB9nU9aa+vUj6kpT+MjPW11LbprXC+iC4HDwn1r4Q2/91qj4iy9tRZNsFySMlEpLdpg==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "is-svg": "^4.2.1",
+ "svgo": "^1.3.2"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sindresorhus/imagemin-svgo?sponsor=1"
+ }
+ },
+ "node_modules/imagemin/node_modules/file-type": {
+ "version": "12.4.2",
+ "resolved": "https://registry.npmjs.org/file-type/-/file-type-12.4.2.tgz",
+ "integrity": "sha512-UssQP5ZgIOKelfsaB5CuGAL+Y+q7EmONuiwF3N5HAH0t27rvrttgi6Ra9k/+DVaY9UF6+ybxu5pOXLUdA8N7Vg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/imagemin/node_modules/make-dir": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
+ "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "semver": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/imagemin/node_modules/semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/immutable": {
+ "version": "3.8.2",
+ "resolved": "https://registry.npmjs.org/immutable/-/immutable-3.8.2.tgz",
+ "integrity": "sha512-15gZoQ38eYjEjxkorfbcgBKBL6R7T459OuK+CpcWt7O3KF4uPCx2tD0uFETlUDIyo+1789crbMhTvQBSR5yBMg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/import-cwd": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/import-cwd/-/import-cwd-2.1.0.tgz",
+ "integrity": "sha512-Ew5AZzJQFqrOV5BTW3EIoHAnoie1LojZLXKcCQ/yTRyVZosBhK1x1ViYjHGf5pAFOq8ZyChZp6m/fSN7pJyZtg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "import-from": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/import-fresh": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz",
+ "integrity": "sha512-eZ5H8rcgYazHbKC3PG4ClHNykCSxtAhxSSEM+2mb+7evD2CKF5V7c0dNum7AdpDh0ZdICwZY9sRSn8f+KH96sg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "caller-path": "^2.0.0",
+ "resolve-from": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/import-from": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/import-from/-/import-from-2.1.0.tgz",
+ "integrity": "sha512-0vdnLL2wSGnhlRmzHJAg5JHjt1l2vYhzJ7tNLGbeVg0fse56tpGaH0uzH+r9Slej+BSXXEHvBKDEnVSLLE9/+w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "resolve-from": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/import-lazy": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-3.1.0.tgz",
+ "integrity": "sha512-8/gvXvX2JMn0F+CDlSC4l6kOmVaLOO3XLkksI7CI3Ud95KDYJuYur2b9P/PUt/i/pDAMd/DulQsNbbbmRRsDIQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/imurmurhash": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+ "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8.19"
+ }
+ },
+ "node_modules/indent-string": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz",
+ "integrity": "sha512-aqwDFWSgSgfRaEwao5lg5KEcVd/2a+D1rvoG7NdilmYz0NwRk6StWpWdz/Hpk34MKPpx7s8XxUqimfcQK6gGlg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "repeating": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/indexes-of": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz",
+ "integrity": "sha512-bup+4tap3Hympa+JBJUG7XuOsdNQ6fxt0MHyXMKuLBKn0OqsTfvUxkUrroEX1+B2VsSHvCjiIcZVxRtYa4nllA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "node_modules/inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/ini": {
+ "version": "1.3.8",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
+ "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/internal-slot": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz",
+ "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "get-intrinsic": "^1.1.0",
+ "has": "^1.0.3",
+ "side-channel": "^1.0.4"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/interpret": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz",
+ "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/into-stream": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/into-stream/-/into-stream-3.1.0.tgz",
+ "integrity": "sha512-TcdjPibTksa1NQximqep2r17ISRiNE9fwlfbg3F8ANdvP5/yrFTew86VcO//jk4QTaMlbjypPBq76HN2zaKfZQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "from2": "^2.1.1",
+ "p-is-promise": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/invert-kv": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz",
+ "integrity": "sha512-xgs2NH9AE66ucSq4cNG1nhSFghr5l6tdL15Pk+jl46bmmBapgoaY/AacXyaDznAqmGL99TiLSQgO/XazFSKYeQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/irregular-plurals": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-2.0.0.tgz",
+ "integrity": "sha512-Y75zBYLkh0lJ9qxeHlMjQ7bSbyiSqNW/UOPWDmzC7cXskL1hekSITh1Oc6JV0XCWWZ9DE8VYSB71xocLk3gmGw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/is": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/is/-/is-3.3.0.tgz",
+ "integrity": "sha512-nW24QBoPcFGGHJGUwnfpI7Yc5CdqWNdsyHQszVE/z2pKHXzh7FZ5GWhJqSyaQ9wMkQnsTx+kAI8bHlCX4tKdbg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/is-absolute": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz",
+ "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-relative": "^1.0.0",
+ "is-windows": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-absolute-url": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-2.1.0.tgz",
+ "integrity": "sha512-vOx7VprsKyllwjSkLV79NIhpyLfr3jAp7VaTCMXOJHu4m0Ew1CZ2fcjASwmV1jI3BWuWHB013M48eyeldk9gYg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-accessor-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "kind-of": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-accessor-descriptor/node_modules/kind-of": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
+ "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-arrayish": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
+ "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/is-bigint": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz",
+ "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-bigints": "^1.0.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-binary-path": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
+ "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "binary-extensions": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-boolean-object": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz",
+ "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "has-tostringtag": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-buffer": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
+ "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/is-callable": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz",
+ "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-color-stop": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-color-stop/-/is-color-stop-1.1.0.tgz",
+ "integrity": "sha512-H1U8Vz0cfXNujrJzEcvvwMDW9Ra+biSYA3ThdQvAnMLJkEHQXn6bWzLkxHtVYJ+Sdbx0b6finn3jZiaVe7MAHA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "css-color-names": "^0.0.4",
+ "hex-color-regex": "^1.1.0",
+ "hsl-regex": "^1.0.0",
+ "hsla-regex": "^1.0.0",
+ "rgb-regex": "^1.0.1",
+ "rgba-regex": "^1.0.0"
+ }
+ },
+ "node_modules/is-core-module": {
+ "version": "2.11.0",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz",
+ "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has": "^1.0.3"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-data-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "kind-of": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-data-descriptor/node_modules/kind-of": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
+ "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-date-object": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz",
+ "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-tostringtag": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-descriptor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-accessor-descriptor": "^1.0.0",
+ "is-data-descriptor": "^1.0.0",
+ "kind-of": "^6.0.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-descriptor/node_modules/kind-of": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
+ "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-directory": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz",
+ "integrity": "sha512-yVChGzahRFvbkscn2MlwGismPO12i9+znNruC5gVEntG3qu0xQMzsGg/JFbrsqDOHtHFPci+V5aP5T9I+yeKqw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-extendable": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
+ "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-finite": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.1.0.tgz",
+ "integrity": "sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-gif": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-gif/-/is-gif-3.0.0.tgz",
+ "integrity": "sha512-IqJ/jlbw5WJSNfwQ/lHEDXF8rxhRgF6ythk2oiEvhpG29F704eX9NO6TvPfMiq9DrbwgcEDnETYNcZDPewQoVw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "file-type": "^10.4.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/is-gif/node_modules/file-type": {
+ "version": "10.11.0",
+ "resolved": "https://registry.npmjs.org/file-type/-/file-type-10.11.0.tgz",
+ "integrity": "sha512-uzk64HRpUZyTGZtVuvrjP0FYxzQrBf4rojot6J65YMEbwBLB0CWm0CLojVpwpmFmxcE/lkvYICgfcGozbBq6rw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/is-glob": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-extglob": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-jpg": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-jpg/-/is-jpg-2.0.0.tgz",
+ "integrity": "sha512-ODlO0ruzhkzD3sdynIainVP5eoOFNN85rxA1+cwwnPe4dKyX0r5+hxNO5XpCrxlHcmb9vkOit9mhRD2JVuimHg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/is-natural-number": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/is-natural-number/-/is-natural-number-4.0.1.tgz",
+ "integrity": "sha512-Y4LTamMe0DDQIIAlaer9eKebAlDSV6huy+TWhJVPlzZh2o4tRP5SQWFlLn5N0To4mDD22/qdOq+veo1cSISLgQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/is-negated-glob": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz",
+ "integrity": "sha512-czXVVn/QEmgvej1f50BZ648vUI+em0xqMq2Sn+QncCLN4zj1UAxlT+kw/6ggQTOaZPd1HqKQGEqbpQVtJucWug==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-negative-zero": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz",
+ "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-number": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+ "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "kind-of": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-number-like": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/is-number-like/-/is-number-like-1.0.8.tgz",
+ "integrity": "sha512-6rZi3ezCyFcn5L71ywzz2bS5b2Igl1En3eTlZlvKjpz1n3IZLAYMbKYAIQgFmEu0GENg92ziU/faEOA/aixjbA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "lodash.isfinite": "^3.3.2"
+ }
+ },
+ "node_modules/is-number-object": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz",
+ "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-tostringtag": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-obj": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz",
+ "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-object": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.2.tgz",
+ "integrity": "sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-plain-obj": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz",
+ "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-plain-object": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
+ "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "isobject": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-png": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-png/-/is-png-2.0.0.tgz",
+ "integrity": "sha512-4KPGizaVGj2LK7xwJIz8o5B2ubu1D/vcQsgOGFEDlpcvgZHto4gBnyd0ig7Ws+67ixmwKoNmu0hYnpo6AaKb5g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-regex": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz",
+ "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "has-tostringtag": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-relative": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz",
+ "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-unc-path": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-resolvable": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz",
+ "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/is-retry-allowed": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz",
+ "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-shared-array-buffer": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz",
+ "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-stream": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
+ "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-string": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz",
+ "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-tostringtag": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-svg": {
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/is-svg/-/is-svg-4.3.2.tgz",
+ "integrity": "sha512-mM90duy00JGMyjqIVHu9gNTjywdZV+8qNasX8cm/EEYZ53PHDgajvbBwNVvty5dwSAxLUD3p3bdo+7sR/UMrpw==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "fast-xml-parser": "^3.19.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-symbol": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz",
+ "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-symbols": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-typedarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
+ "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/is-unc-path": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz",
+ "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "unc-path-regex": "^0.1.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-utf8": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz",
+ "integrity": "sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/is-valid-glob": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-1.0.0.tgz",
+ "integrity": "sha512-AhiROmoEFDSsjx8hW+5sGwgKVIORcXnrlAx/R0ZSeaPw70Vw0CqkGBBhHGL58Uox2eXnU1AnvXJl1XlyedO5bA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-weakref": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz",
+ "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-windows": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
+ "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-wsl": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz",
+ "integrity": "sha512-gfygJYZ2gLTDlmbWMI0CE2MwnFzSN/2SZfkMlItC4K/JBlsWVDB0bO6XhqcY13YXE7iMcAJnzTCJjPiTeJJ0Mw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/isarray": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+ "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/isstream": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
+ "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/isurl": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isurl/-/isurl-1.0.0.tgz",
+ "integrity": "sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-to-string-tag-x": "^1.2.0",
+ "is-object": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/jest-worker": {
+ "version": "27.5.1",
+ "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz",
+ "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*",
+ "merge-stream": "^2.0.0",
+ "supports-color": "^8.0.0"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ }
+ },
+ "node_modules/jest-worker/node_modules/@types/node": {
+ "version": "18.11.10",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.10.tgz",
+ "integrity": "sha512-juG3RWMBOqcOuXC643OAdSA525V44cVgGV6dUDuiFtss+8Fk5x1hI93Rsld43VeJVIeqlP9I7Fn9/qaVqoEAuQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/jest-worker/node_modules/supports-color": {
+ "version": "8.1.1",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
+ "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/supports-color?sponsor=1"
+ }
+ },
+ "node_modules/jpegtran-bin": {
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/jpegtran-bin/-/jpegtran-bin-5.0.2.tgz",
+ "integrity": "sha512-4FSmgIcr8d5+V6T1+dHbPZjaFH0ogVyP4UVsE+zri7S9YLO4qAT2our4IN3sW3STVgNTbqPermdIgt2XuAJ4EA==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "dependencies": {
+ "bin-build": "^3.0.0",
+ "bin-wrapper": "^4.0.0",
+ "logalot": "^2.0.0"
+ },
+ "bin": {
+ "jpegtran": "cli.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/js-yaml": {
+ "version": "3.14.1",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
+ "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "argparse": "^1.0.7",
+ "esprima": "^4.0.0"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/jsbn": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
+ "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/jsdom": {
+ "version": "12.2.0",
+ "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-12.2.0.tgz",
+ "integrity": "sha512-QPOggIJ8fquWPLaYYMoh+zqUmdphDtu1ju0QGTitZT1Yd8I5qenPpXM1etzUegu3MjVp8XPzgZxdn8Yj7e40ig==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "abab": "^2.0.0",
+ "acorn": "^6.0.2",
+ "acorn-globals": "^4.3.0",
+ "array-equal": "^1.0.0",
+ "cssom": "^0.3.4",
+ "cssstyle": "^1.1.1",
+ "data-urls": "^1.0.1",
+ "domexception": "^1.0.1",
+ "escodegen": "^1.11.0",
+ "html-encoding-sniffer": "^1.0.2",
+ "nwsapi": "^2.0.9",
+ "parse5": "5.1.0",
+ "pn": "^1.1.0",
+ "request": "^2.88.0",
+ "request-promise-native": "^1.0.5",
+ "saxes": "^3.1.3",
+ "symbol-tree": "^3.2.2",
+ "tough-cookie": "^2.4.3",
+ "w3c-hr-time": "^1.0.1",
+ "webidl-conversions": "^4.0.2",
+ "whatwg-encoding": "^1.0.5",
+ "whatwg-mimetype": "^2.2.0",
+ "whatwg-url": "^7.0.0",
+ "ws": "^6.1.0",
+ "xml-name-validator": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/jsdom/node_modules/acorn": {
+ "version": "6.4.2",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz",
+ "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "acorn": "bin/acorn"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/jsdom/node_modules/ws": {
+ "version": "6.2.2",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz",
+ "integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "async-limiter": "~1.0.0"
+ }
+ },
+ "node_modules/json-buffer": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz",
+ "integrity": "sha512-CuUqjv0FUZIdXkHPI8MezCnFCdaTAacej1TZYulLoAg1h/PhwkdXFN4V/gzY4g+fMBCOV2xF+rp7t2XD2ns/NQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/json-parse-better-errors": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
+ "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/json-parse-even-better-errors": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
+ "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/json-schema": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz",
+ "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==",
+ "dev": true,
+ "license": "(AFL-2.1 OR BSD-3-Clause)"
+ },
+ "node_modules/json-schema-traverse": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+ "license": "MIT"
+ },
+ "node_modules/json-stable-stringify-without-jsonify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
+ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/json-stringify-safe": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
+ "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/json5": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
+ "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "minimist": "^1.2.0"
+ },
+ "bin": {
+ "json5": "lib/cli.js"
+ }
+ },
+ "node_modules/jsonfile": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
+ "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==",
+ "dev": true,
+ "license": "MIT",
+ "optionalDependencies": {
+ "graceful-fs": "^4.1.6"
+ }
+ },
+ "node_modules/jsprim": {
+ "version": "1.4.2",
+ "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz",
+ "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "assert-plus": "1.0.0",
+ "extsprintf": "1.3.0",
+ "json-schema": "0.4.0",
+ "verror": "1.10.0"
+ },
+ "engines": {
+ "node": ">=0.6.0"
+ }
+ },
+ "node_modules/junk": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/junk/-/junk-3.1.0.tgz",
+ "integrity": "sha512-pBxcB3LFc8QVgdggvZWyeys+hnrNWg4OcZIU/1X59k5jQdLBlCsYGRQaz234SqoRLTCgMH00fY0xRJH+F9METQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/just-debounce": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/just-debounce/-/just-debounce-1.1.0.tgz",
+ "integrity": "sha512-qpcRocdkUmf+UTNBYx5w6dexX5J31AKK1OmPwH630a83DdVVUIngk55RSAiIGpQyoH0dlr872VHfPjnQnK1qDQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/keyv": {
+ "version": "4.5.4",
+ "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
+ "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "json-buffer": "3.0.1"
+ }
+ },
+ "node_modules/keyv/node_modules/json-buffer": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
+ "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-buffer": "^1.1.5"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/last-run": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/last-run/-/last-run-1.1.1.tgz",
+ "integrity": "sha512-U/VxvpX4N/rFvPzr3qG5EtLKEnNI0emvIQB3/ecEwv+8GHaUKbIB8vxv1Oai5FAF0d0r7LXHhLLe5K/yChm5GQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "default-resolution": "^2.0.0",
+ "es6-weak-map": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/lazystream": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz",
+ "integrity": "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "readable-stream": "^2.0.5"
+ },
+ "engines": {
+ "node": ">= 0.6.3"
+ }
+ },
+ "node_modules/lcid": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz",
+ "integrity": "sha512-YiGkH6EnGrDGqLMITnGjXtGmNtjoXw9SVUzcaos8RBi7Ps0VBylkq+vOcY9QE5poLasPCR849ucFUkl0UzUyOw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "invert-kv": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/lead": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/lead/-/lead-1.0.0.tgz",
+ "integrity": "sha512-IpSVCk9AYvLHo5ctcIXxOBpMWUe+4TKN3VPWAKUbJikkmsGp0VrSM8IttVc32D6J4WUsiPE6aEFRNmIoF/gdow==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "flush-write-stream": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/levn": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
+ "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prelude-ls": "^1.2.1",
+ "type-check": "~0.4.0"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/levn/node_modules/prelude-ls": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
+ "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/levn/node_modules/type-check": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
+ "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prelude-ls": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/liftoff": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-3.1.0.tgz",
+ "integrity": "sha512-DlIPlJUkCV0Ips2zf2pJP0unEoT1kwYhiiPUGF3s/jtxTCjziNLoiVVh+jqWOWeFi6mmwQ5fNxvAUyPad4Dfog==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "extend": "^3.0.0",
+ "findup-sync": "^3.0.0",
+ "fined": "^1.0.1",
+ "flagged-respawn": "^1.0.0",
+ "is-plain-object": "^2.0.4",
+ "object.map": "^1.0.0",
+ "rechoir": "^0.6.2",
+ "resolve": "^1.1.7"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/liftoff/node_modules/findup-sync": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-3.0.0.tgz",
+ "integrity": "sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "detect-file": "^1.0.0",
+ "is-glob": "^4.0.0",
+ "micromatch": "^3.0.4",
+ "resolve-dir": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/limiter": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/limiter/-/limiter-1.1.5.tgz",
+ "integrity": "sha512-FWWMIEOxz3GwUI4Ts/IvgVy6LPvoMPgjMdQ185nN6psJyBJ4yOpzqm695/h5umdLJg2vW3GR5iG11MAkR2AzJA==",
+ "dev": true
+ },
+ "node_modules/load-json-file": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
+ "integrity": "sha512-cy7ZdNRXdablkXYNI049pthVeXFurRyb9+hA/dZzerZ0pGTx42z+y+ssxBaVV2l70t1muq5IdKhn4UtcoGUY9A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "graceful-fs": "^4.1.2",
+ "parse-json": "^2.2.0",
+ "pify": "^2.0.0",
+ "pinkie-promise": "^2.0.0",
+ "strip-bom": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/loader-runner": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz",
+ "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.11.5"
+ }
+ },
+ "node_modules/loader-utils": {
+ "version": "1.4.2",
+ "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.2.tgz",
+ "integrity": "sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "big.js": "^5.2.2",
+ "emojis-list": "^3.0.0",
+ "json5": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
+ "node_modules/localtunnel": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/localtunnel/-/localtunnel-2.0.2.tgz",
+ "integrity": "sha512-n418Cn5ynvJd7m/N1d9WVJISLJF/ellZnfsLnx8WBWGzxv/ntNcFkJ1o6se5quUhCplfLGBNL5tYHiq5WF3Nug==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "axios": "0.21.4",
+ "debug": "4.3.2",
+ "openurl": "1.1.1",
+ "yargs": "17.1.1"
+ },
+ "bin": {
+ "lt": "bin/lt.js"
+ },
+ "engines": {
+ "node": ">=8.3.0"
+ }
+ },
+ "node_modules/localtunnel/node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/localtunnel/node_modules/cliui": {
+ "version": "7.0.4",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
+ "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "string-width": "^4.2.0",
+ "strip-ansi": "^6.0.0",
+ "wrap-ansi": "^7.0.0"
+ }
+ },
+ "node_modules/localtunnel/node_modules/debug": {
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
+ "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "2.1.2"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/localtunnel/node_modules/ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/localtunnel/node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/localtunnel/node_modules/yargs": {
+ "version": "17.1.1",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.1.1.tgz",
+ "integrity": "sha512-c2k48R0PwKIqKhPMWjeiF6y2xY/gPMUlro0sgxqXpbOIohWiLNXWslsootttv7E1e73QPAMQSg5FeySbVcpsPQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cliui": "^7.0.2",
+ "escalade": "^3.1.1",
+ "get-caller-file": "^2.0.5",
+ "require-directory": "^2.1.1",
+ "string-width": "^4.2.0",
+ "y18n": "^5.0.5",
+ "yargs-parser": "^20.2.2"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/locate-path": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
+ "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-locate": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/lodash": {
+ "version": "4.17.21",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
+ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lodash._escapehtmlchar": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/lodash._escapehtmlchar/-/lodash._escapehtmlchar-2.4.1.tgz",
+ "integrity": "sha512-eHm2t2Lg476lq5v4FVmm3B5mCaRlDyTE8fnMfPCEq2o46G4au0qNXIKh7YWhjprm1zgSMLcMSs1XHMgkw02PbQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "lodash._htmlescapes": "~2.4.1"
+ }
+ },
+ "node_modules/lodash._escapestringchar": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/lodash._escapestringchar/-/lodash._escapestringchar-2.4.1.tgz",
+ "integrity": "sha512-iZ6Os4iipaE43pr9SBks+UpZgAjJgRC+lGf7onEoByMr1+Nagr1fmR7zCM6Q4RGMB/V3a57raEN0XZl7Uub3/g==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lodash._htmlescapes": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/lodash._htmlescapes/-/lodash._htmlescapes-2.4.1.tgz",
+ "integrity": "sha512-g79hNmMOBVyV+4oKIHM7MWy9Awtk3yqf0Twlawr6f+CmG44nTwBh9I5XiLUnk39KTfYoDBpS66glQGgQCnFIuA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lodash._isnative": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/lodash._isnative/-/lodash._isnative-2.4.1.tgz",
+ "integrity": "sha512-BOlKGKNHhCHswGOWtmVb5zBygyxN7EmTuzVOSQI6QSoGhG+kvv71gICFS1TBpnqvT1n53txK8CDK3u5D2/GZxQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lodash._objecttypes": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/lodash._objecttypes/-/lodash._objecttypes-2.4.1.tgz",
+ "integrity": "sha512-XpqGh1e7hhkOzftBfWE7zt+Yn9mVHFkDhicVttvKLsoCMLVVL+xTQjfjB4X4vtznauxv0QZ5ZAeqjvat0dh62Q==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lodash._reinterpolate": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-2.4.1.tgz",
+ "integrity": "sha512-QGEOOjJi7W9LIgDAMVgtGBb8Qgo8ieDlSOCoZjtG45ZNRvDJZjwVMTYlfTIWdNRUiR1I9BjIqQ3Zaf1+DYM94g==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lodash._reunescapedhtml": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/lodash._reunescapedhtml/-/lodash._reunescapedhtml-2.4.1.tgz",
+ "integrity": "sha512-CfmZRU1Mk4E/5jh+Wu8lc7tuc3VkuwWZYVIgdPDH9NRSHgiL4Or3AA4JCIpgrkVzHOM+jKu2OMkAVquruhRHDQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "lodash._htmlescapes": "~2.4.1",
+ "lodash.keys": "~2.4.1"
+ }
+ },
+ "node_modules/lodash._shimkeys": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/lodash._shimkeys/-/lodash._shimkeys-2.4.1.tgz",
+ "integrity": "sha512-lBrglYxLD/6KAJ8IEa5Lg+YHgNAL7FyKqXg4XOUI+Du/vtniLs1ZqS+yHNKPkK54waAgkdUnDOYaWf+rv4B+AA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "lodash._objecttypes": "~2.4.1"
+ }
+ },
+ "node_modules/lodash.clone": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/lodash.clone/-/lodash.clone-4.5.0.tgz",
+ "integrity": "sha512-GhrVeweiTD6uTmmn5hV/lzgCQhccwReIVRLHp7LT4SopOjqEZ5BbX8b5WWEtAKasjmy8hR7ZPwsYlxRCku5odg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lodash.clonedeep": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
+ "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lodash.defaults": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz",
+ "integrity": "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lodash.escape": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-2.4.1.tgz",
+ "integrity": "sha512-PiEStyvZ8gz37qBE+HqME1Yc/ewb/59AMOu8pG7Ztani86foPTxgzckQvMdphmXPY6V5f20Ex/CaNBqHG4/ycQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "lodash._escapehtmlchar": "~2.4.1",
+ "lodash._reunescapedhtml": "~2.4.1",
+ "lodash.keys": "~2.4.1"
+ }
+ },
+ "node_modules/lodash.get": {
+ "version": "4.4.2",
+ "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
+ "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lodash.isfinite": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/lodash.isfinite/-/lodash.isfinite-3.3.2.tgz",
+ "integrity": "sha512-7FGG40uhC8Mm633uKW1r58aElFlBlxCrg9JfSi3P6aYiWmfiWF0PgMd86ZUsxE5GwWPdHoS2+48bwTh2VPkIQA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lodash.isobject": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/lodash.isobject/-/lodash.isobject-2.4.1.tgz",
+ "integrity": "sha512-sTebg2a1PoicYEZXD5PBdQcTlIJ6hUslrlWr7iV0O7n+i4596s2NQ9I5CaZ5FbXSfya/9WQsrYLANUJv9paYVA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "lodash._objecttypes": "~2.4.1"
+ }
+ },
+ "node_modules/lodash.keys": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-2.4.1.tgz",
+ "integrity": "sha512-ZpJhwvUXHSNL5wYd1RM6CUa2ZuqorG9ngoJ9Ix5Cce+uX7I5O/E06FCJdhSZ33b5dVyeQDnIlWH7B2s5uByZ7g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "lodash._isnative": "~2.4.1",
+ "lodash._shimkeys": "~2.4.1",
+ "lodash.isobject": "~2.4.1"
+ }
+ },
+ "node_modules/lodash.memoize": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
+ "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lodash.merge": {
+ "version": "4.6.2",
+ "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
+ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lodash.some": {
+ "version": "4.6.0",
+ "resolved": "https://registry.npmjs.org/lodash.some/-/lodash.some-4.6.0.tgz",
+ "integrity": "sha512-j7MJE+TuT51q9ggt4fSgVqro163BEFjAt3u97IqU+JA2DkWl80nFTrowzLpZ/BnpN7rrl0JA/593NAdd8p/scQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lodash.sortby": {
+ "version": "4.7.0",
+ "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",
+ "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lodash.template": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-2.4.1.tgz",
+ "integrity": "sha512-5yLOQwlS69xbaez3g9dA1i0GMAj8pLDHp8lhA4V7M1vRam1lqD76f0jg5EV+65frbqrXo1WH9ZfKalfYBzJ5yQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "lodash._escapestringchar": "~2.4.1",
+ "lodash._reinterpolate": "~2.4.1",
+ "lodash.defaults": "~2.4.1",
+ "lodash.escape": "~2.4.1",
+ "lodash.keys": "~2.4.1",
+ "lodash.templatesettings": "~2.4.1",
+ "lodash.values": "~2.4.1"
+ }
+ },
+ "node_modules/lodash.template/node_modules/lodash.defaults": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-2.4.1.tgz",
+ "integrity": "sha512-5wTIPWwGGr07JFysAZB8+7JB2NjJKXDIwogSaRX5zED85zyUAQwtOqUk8AsJkkigUcL3akbHYXd5+BPtTGQPZw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "lodash._objecttypes": "~2.4.1",
+ "lodash.keys": "~2.4.1"
+ }
+ },
+ "node_modules/lodash.templatesettings": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-2.4.1.tgz",
+ "integrity": "sha512-vY3QQ7GxbeLe8XfTvoYDbaMHO5iyTDJS1KIZrxp00PRMmyBKr8yEcObHSl2ppYTwd8MgqPXAarTvLA14hx8ffw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "lodash._reinterpolate": "~2.4.1",
+ "lodash.escape": "~2.4.1"
+ }
+ },
+ "node_modules/lodash.uniq": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz",
+ "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lodash.values": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/lodash.values/-/lodash.values-2.4.1.tgz",
+ "integrity": "sha512-fQwubKvj2Nox2gy6YnjFm8C1I6MIlzKUtBB+Pj7JGtloGqDDL5CPRr4DUUFWPwXWwAl2k3f4C3Aw8H1qAPB9ww==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "lodash.keys": "~2.4.1"
+ }
+ },
+ "node_modules/logalot": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/logalot/-/logalot-2.1.0.tgz",
+ "integrity": "sha512-Ah4CgdSRfeCJagxQhcVNMi9BfGYyEKLa6d7OA6xSbld/Hg3Cf2QiOa1mDpmG7Ve8LOH6DN3mdttzjQAvWTyVkw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "figures": "^1.3.5",
+ "squeak": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/longest": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz",
+ "integrity": "sha512-k+yt5n3l48JU4k8ftnKG6V7u32wyH2NfKzeMto9F/QRE0amxy/LayxwlvjjkZEIzqR+19IrtFO8p5kB9QaYUFg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/loud-rejection": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz",
+ "integrity": "sha512-RPNliZOFkqFumDhvYqOaNY4Uz9oJM2K9tC6JWsJJsNdhuONW4LQHRBpb0qf4pJApVffI5N39SwzWZJuEhfd7eQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "currently-unhandled": "^0.4.1",
+ "signal-exit": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/lower-case": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz",
+ "integrity": "sha512-2Fgx1Ycm599x+WGpIYwJOvsjmXFzTSc34IwDWALRA/8AopUKAVPwfJ+h5+f85BCp0PWmmJcWzEpxOpoXycMpdA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lowercase-keys": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz",
+ "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/lpad-align": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/lpad-align/-/lpad-align-1.1.2.tgz",
+ "integrity": "sha512-MMIcFmmR9zlGZtBcFOows6c2COMekHCIFJz3ew/rRpKZ1wR4mXDPzvcVqLarux8M33X4TPSq2Jdw8WJj0q0KbQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "get-stdin": "^4.0.1",
+ "indent-string": "^2.1.0",
+ "longest": "^1.0.0",
+ "meow": "^3.3.0"
+ },
+ "bin": {
+ "lpad-align": "cli.js"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/lru-cache": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+ "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/make-dir": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz",
+ "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "pify": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/make-dir/node_modules/pify": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+ "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/make-iterator": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz",
+ "integrity": "sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "kind-of": "^6.0.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/make-iterator/node_modules/kind-of": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
+ "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/map-cache": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz",
+ "integrity": "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/map-obj": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz",
+ "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/map-visit": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz",
+ "integrity": "sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "object-visit": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/matchdep": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/matchdep/-/matchdep-2.0.0.tgz",
+ "integrity": "sha512-LFgVbaHIHMqCRuCZyfCtUOq9/Lnzhi7Z0KFUE2fhD54+JN2jLh3hC02RLkqauJ3U4soU6H1J3tfj/Byk7GoEjA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "findup-sync": "^2.0.0",
+ "micromatch": "^3.0.4",
+ "resolve": "^1.4.0",
+ "stack-trace": "0.0.10"
+ },
+ "engines": {
+ "node": ">= 0.10.0"
+ }
+ },
+ "node_modules/matcher": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz",
+ "integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "escape-string-regexp": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/matcher/node_modules/escape-string-regexp": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/mdn-data": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz",
+ "integrity": "sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==",
+ "dev": true,
+ "license": "CC0-1.0"
+ },
+ "node_modules/media-typer": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
+ "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/memory-fs": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz",
+ "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "errno": "^0.1.3",
+ "readable-stream": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=4.3.0 <5.0.0 || >=5.10"
+ }
+ },
+ "node_modules/meow": {
+ "version": "3.7.0",
+ "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz",
+ "integrity": "sha512-TNdwZs0skRlpPpCUK25StC4VH+tP5GgeY1HQOOGP+lQ2xtdkN2VtT/5tiX9k3IWpkBPV9b3LsAWXn4GGi/PrSA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "camelcase-keys": "^2.0.0",
+ "decamelize": "^1.1.2",
+ "loud-rejection": "^1.0.0",
+ "map-obj": "^1.0.1",
+ "minimist": "^1.1.3",
+ "normalize-package-data": "^2.3.4",
+ "object-assign": "^4.0.1",
+ "read-pkg-up": "^1.0.1",
+ "redent": "^1.0.0",
+ "trim-newlines": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/merge": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/merge/-/merge-1.2.1.tgz",
+ "integrity": "sha512-VjFo4P5Whtj4vsLzsYBu5ayHhoHJ0UqNm7ibvShmbmoz7tGi0vXaoJbGdB+GmDMLUdg8DpQXEIeVDAe8MaABvQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/merge-stream": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
+ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/merge2": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
+ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/micromatch": {
+ "version": "3.1.10",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
+ "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "arr-diff": "^4.0.0",
+ "array-unique": "^0.3.2",
+ "braces": "^2.3.1",
+ "define-property": "^2.0.2",
+ "extend-shallow": "^3.0.2",
+ "extglob": "^2.0.4",
+ "fragment-cache": "^0.2.1",
+ "kind-of": "^6.0.2",
+ "nanomatch": "^1.2.9",
+ "object.pick": "^1.3.0",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/micromatch/node_modules/define-property": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz",
+ "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-descriptor": "^1.0.2",
+ "isobject": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/micromatch/node_modules/extend-shallow": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
+ "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "assign-symbols": "^1.0.0",
+ "is-extendable": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/micromatch/node_modules/is-extendable": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-plain-object": "^2.0.4"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/micromatch/node_modules/kind-of": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
+ "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/mime": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz",
+ "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "mime": "cli.js"
+ }
+ },
+ "node_modules/mime-db": {
+ "version": "1.52.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+ "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/mime-types": {
+ "version": "2.1.35",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+ "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "mime-db": "1.52.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/mimic-fn": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
+ "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/mimic-response": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz",
+ "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/minimist": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
+ "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/mitt": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/mitt/-/mitt-1.2.0.tgz",
+ "integrity": "sha512-r6lj77KlwqLhIUku9UWYes7KJtsczvolZkzp8hbaDPPaE24OmWl5s539Mytlj22siEQKosZ26qCBgda2PKwoJw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/mixin-deep": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz",
+ "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "for-in": "^1.0.2",
+ "is-extendable": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/mixin-deep/node_modules/is-extendable": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-plain-object": "^2.0.4"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/mkdirp": {
+ "version": "0.5.6",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz",
+ "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "minimist": "^1.2.6"
+ },
+ "bin": {
+ "mkdirp": "bin/cmd.js"
+ }
+ },
+ "node_modules/mozjpeg": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/mozjpeg/-/mozjpeg-6.0.1.tgz",
+ "integrity": "sha512-9Z59pJMi8ni+IUvSH5xQwK5tNLw7p3dwDNCZ3o1xE+of3G5Hc/yOz6Ue/YuLiBXU3ZB5oaHPURyPdqfBX/QYJA==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "dependencies": {
+ "bin-build": "^3.0.0",
+ "bin-wrapper": "^4.0.0",
+ "logalot": "^2.1.0"
+ },
+ "bin": {
+ "mozjpeg": "cli.js"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/multipipe": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/multipipe/-/multipipe-0.1.2.tgz",
+ "integrity": "sha512-7ZxrUybYv9NonoXgwoOqtStIu18D1c3eFZj27hqgf5kBrBF8Q+tE8V0MW8dKM5QLkQPh1JhhbKgHLY9kifov4Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "duplexer2": "0.0.2"
+ }
+ },
+ "node_modules/mute-stdout": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/mute-stdout/-/mute-stdout-1.0.1.tgz",
+ "integrity": "sha512-kDcwXR4PS7caBpuRYYBUz9iVixUk3anO3f5OYFiIPwK/20vCzKCHyKoulbiDY1S53zD2bxUpxN/IJ+TnXjfvxg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/nanomatch": {
+ "version": "1.2.13",
+ "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
+ "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "arr-diff": "^4.0.0",
+ "array-unique": "^0.3.2",
+ "define-property": "^2.0.2",
+ "extend-shallow": "^3.0.2",
+ "fragment-cache": "^0.2.1",
+ "is-windows": "^1.0.2",
+ "kind-of": "^6.0.2",
+ "object.pick": "^1.3.0",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/nanomatch/node_modules/define-property": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz",
+ "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-descriptor": "^1.0.2",
+ "isobject": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/nanomatch/node_modules/extend-shallow": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
+ "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "assign-symbols": "^1.0.0",
+ "is-extendable": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/nanomatch/node_modules/is-extendable": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-plain-object": "^2.0.4"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/nanomatch/node_modules/kind-of": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
+ "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/natural-compare": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
+ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/negotiator": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
+ "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/neo-async": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
+ "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/next-tick": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz",
+ "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/nice-try": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
+ "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/no-case": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz",
+ "integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "lower-case": "^1.1.1"
+ }
+ },
+ "node_modules/node-releases": {
+ "version": "2.0.19",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz",
+ "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/node.extend": {
+ "version": "1.1.8",
+ "resolved": "https://registry.npmjs.org/node.extend/-/node.extend-1.1.8.tgz",
+ "integrity": "sha512-L/dvEBwyg3UowwqOUTyDsGBU6kjBQOpOhshio9V3i3BMPv5YUb9+mWNN8MK0IbWqT0AqaTSONZf0aTuMMahWgA==",
+ "dev": true,
+ "license": "(MIT OR GPL-2.0)",
+ "dependencies": {
+ "has": "^1.0.3",
+ "is": "^3.2.1"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/normalize-package-data": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
+ "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "hosted-git-info": "^2.1.4",
+ "resolve": "^1.10.0",
+ "semver": "2 || 3 || 4 || 5",
+ "validate-npm-package-license": "^3.0.1"
+ }
+ },
+ "node_modules/normalize-package-data/node_modules/semver": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+ "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver"
+ }
+ },
+ "node_modules/normalize-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/normalize-range": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz",
+ "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/normalize-url": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-3.3.0.tgz",
+ "integrity": "sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/now-and-later": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-2.0.1.tgz",
+ "integrity": "sha512-KGvQ0cB70AQfg107Xvs/Fbu+dGmZoTRJp2TaPwcwQm3/7PteUyN2BCgk8KBMPGBUXZdVwyWS8fDCGFygBm19UQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "once": "^1.3.2"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/npm-conf": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/npm-conf/-/npm-conf-1.1.3.tgz",
+ "integrity": "sha512-Yic4bZHJOt9RCFbRP3GgpqhScOY4HH3V2P8yBj6CeYq118Qr+BLXqT2JvpJ00mryLESpgOxf5XlFv4ZjXxLScw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "config-chain": "^1.1.11",
+ "pify": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/npm-conf/node_modules/pify": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+ "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/npm-run-path": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz",
+ "integrity": "sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "path-key": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/npm-run-path/node_modules/path-key": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
+ "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/nth-check": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz",
+ "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "boolbase": "~1.0.0"
+ }
+ },
+ "node_modules/num2fraction": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz",
+ "integrity": "sha512-Y1wZESM7VUThYY+4W+X4ySH2maqcA+p7UR+w8VWNWVAd6lwuXXWz/w/Cz43J/dI2I+PS6wD5N+bJUF+gjWvIqg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/number-is-nan": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
+ "integrity": "sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/nwsapi": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.2.tgz",
+ "integrity": "sha512-90yv+6538zuvUMnN+zCr8LuV6bPFdq50304114vJYJ8RDyK8D5O9Phpbd6SZWgI7PwzmmfN1upeOJlvybDSgCw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/oauth-sign": {
+ "version": "0.9.0",
+ "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
+ "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/object-copy": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz",
+ "integrity": "sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "copy-descriptor": "^0.1.0",
+ "define-property": "^0.2.5",
+ "kind-of": "^3.0.3"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/object-inspect": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz",
+ "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object-keys": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
+ "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/object-visit": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz",
+ "integrity": "sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "isobject": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/object.assign": {
+ "version": "4.1.4",
+ "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz",
+ "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.4",
+ "has-symbols": "^1.0.3",
+ "object-keys": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object.defaults": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz",
+ "integrity": "sha512-c/K0mw/F11k4dEUBMW8naXUuBuhxRCfG7W+yFy8EcijU/rSmazOUd1XAEEe6bC0OuXY4HUKjTJv7xbxIMqdxrA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "array-each": "^1.0.1",
+ "array-slice": "^1.0.0",
+ "for-own": "^1.0.0",
+ "isobject": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/object.getownpropertydescriptors": {
+ "version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.5.tgz",
+ "integrity": "sha512-yDNzckpM6ntyQiGTik1fKV1DcVDRS+w8bvpWNCBanvH5LfRX9O8WTHqQzG4RZwRAM4I0oU7TV11Lj5v0g20ibw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "array.prototype.reduce": "^1.0.5",
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.4",
+ "es-abstract": "^1.20.4"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object.map": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz",
+ "integrity": "sha512-3+mAJu2PLfnSVGHwIWubpOFLscJANBKuB/6A4CxBstc4aqwQY0FWcsppuy4jU5GSB95yES5JHSI+33AWuS4k6w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "for-own": "^1.0.0",
+ "make-iterator": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/object.pick": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz",
+ "integrity": "sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "isobject": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/object.reduce": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/object.reduce/-/object.reduce-1.0.1.tgz",
+ "integrity": "sha512-naLhxxpUESbNkRqc35oQ2scZSJueHGQNUfMW/0U37IgN6tE2dgDWg3whf+NEliy3F/QysrO48XKUz/nGPe+AQw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "for-own": "^1.0.0",
+ "make-iterator": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/object.values": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.6.tgz",
+ "integrity": "sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.4",
+ "es-abstract": "^1.20.4"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/on-finished": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
+ "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ee-first": "1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "wrappy": "1"
+ }
+ },
+ "node_modules/onetime": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
+ "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "mimic-fn": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/open": {
+ "version": "0.0.5",
+ "resolved": "https://registry.npmjs.org/open/-/open-0.0.5.tgz",
+ "integrity": "sha512-+X/dJYLapVO1VbC620DhtNZK9U4/kQVaTQp/Gh7cb6UTLYfGZzzU2ZXkWrOA/wBrf4UqAFwtLqXYTxe4tSnWQQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6.0"
+ }
+ },
+ "node_modules/openurl": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/openurl/-/openurl-1.1.1.tgz",
+ "integrity": "sha512-d/gTkTb1i1GKz5k3XE3XFV/PxQ1k45zDqGP2OA7YhgsaLoqm6qRvARAZOFer1fcXritWlGBRCu/UgeS4HAnXAA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/opn": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/opn/-/opn-5.3.0.tgz",
+ "integrity": "sha512-bYJHo/LOmoTd+pfiYhfZDnf9zekVJrY+cnS2a5F2x+w5ppvTqObojTP7WiFG+kVZs9Inw+qQ/lw7TroWwhdd2g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-wsl": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/optimist": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz",
+ "integrity": "sha512-snN4O4TkigujZphWLN0E//nQmm7790RYaE53DdL7ZYwee2D8DDo9/EyYiKUfN3rneWUjhJnueija3G9I2i0h3g==",
+ "dev": true,
+ "license": "MIT/X11",
+ "dependencies": {
+ "minimist": "~0.0.1",
+ "wordwrap": "~0.0.2"
+ }
+ },
+ "node_modules/optimist/node_modules/minimist": {
+ "version": "0.0.10",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz",
+ "integrity": "sha512-iotkTvxc+TwOm5Ieim8VnSNvCDjCK9S8G3scJ50ZthspSxa7jx50jkhYduuAtAjvfDUwSgOwf8+If99AlOEhyw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/optionator": {
+ "version": "0.9.3",
+ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz",
+ "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@aashutoshrathi/word-wrap": "^1.2.3",
+ "deep-is": "^0.1.3",
+ "fast-levenshtein": "^2.0.6",
+ "levn": "^0.4.1",
+ "prelude-ls": "^1.2.1",
+ "type-check": "^0.4.0"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/optionator/node_modules/prelude-ls": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
+ "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/optionator/node_modules/type-check": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
+ "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prelude-ls": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/optipng-bin": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/optipng-bin/-/optipng-bin-6.0.0.tgz",
+ "integrity": "sha512-95bB4y8IaTsa/8x6QH4bLUuyvyOoGBCLDA7wOgDL8UFqJpSUh1Hob8JRJhit+wC1ZLN3tQ7mFt7KuBj0x8F2Wg==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "bin-build": "^3.0.0",
+ "bin-wrapper": "^4.0.0",
+ "logalot": "^2.0.0"
+ },
+ "bin": {
+ "optipng": "cli.js"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ordered-read-streams": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz",
+ "integrity": "sha512-Z87aSjx3r5c0ZB7bcJqIgIRX5bxR7A4aSzvIbaxd0oTkWBCOoKfuGHiKj60CHVUgg1Phm5yMZzBdt8XqRs73Mw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "readable-stream": "^2.0.1"
+ }
+ },
+ "node_modules/os-filter-obj": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/os-filter-obj/-/os-filter-obj-2.0.0.tgz",
+ "integrity": "sha512-uksVLsqG3pVdzzPvmAHpBK0wKxYItuzZr7SziusRPoz67tGV8rL1szZ6IdeUrbqLjGDwApBtN29eEE3IqGHOjg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "arch": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/os-locale": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz",
+ "integrity": "sha512-PRT7ZORmwu2MEFt4/fv3Q+mEfN4zetKxufQrkShY2oGvUms9r8otu5HfdyIFHkYXjO7laNsoVGmM2MANfuTA8g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "lcid": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ow": {
+ "version": "0.13.2",
+ "resolved": "https://registry.npmjs.org/ow/-/ow-0.13.2.tgz",
+ "integrity": "sha512-9wvr+q+ZTDRvXDjL6eDOdFe5WUl/wa5sntf9kAolxqSpkBqaIObwLgFCGXSJASFw+YciXnOVtDWpxXa9cqV94A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "type-fest": "^0.5.1"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/p-event": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/p-event/-/p-event-1.3.0.tgz",
+ "integrity": "sha512-hV1zbA7gwqPVFcapfeATaNjQ3J0NuzorHPyG8GPL9g/Y/TplWVBVoCKCXL6Ej2zscrCEv195QNWJXuBH6XZuzA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-timeout": "^1.1.1"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/p-finally": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
+ "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/p-is-promise": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-1.1.0.tgz",
+ "integrity": "sha512-zL7VE4JVS2IFSkR2GQKDSPEVxkoH43/p7oEnwpdCndKYJO0HVeRB7fA8TJwuLOTBREtK0ea8eHaxdwcpob5dmg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/p-limit": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
+ "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "yocto-queue": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-locate": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
+ "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-limit": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-map-series": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/p-map-series/-/p-map-series-1.0.0.tgz",
+ "integrity": "sha512-4k9LlvY6Bo/1FcIdV33wqZQES0Py+iKISU9Uc8p8AjWoZPnFKMpVIVD3s0EYn4jzLh1I+WeUZkJ0Yoa4Qfw3Kg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-reduce": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/p-pipe": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/p-pipe/-/p-pipe-3.1.0.tgz",
+ "integrity": "sha512-08pj8ATpzMR0Y80x50yJHn37NF6vjrqHutASaX5LiH5npS9XPvrUmscd9MF5R4fuYRHOxQR1FfMIlF7AzwoPqw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-reduce": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/p-reduce/-/p-reduce-1.0.0.tgz",
+ "integrity": "sha512-3Tx1T3oM1xO/Y8Gj0sWyE78EIJZ+t+aEmXUdvQgvGmSMri7aPTHoovbXEreWKkL5j21Er60XAWLTzKbAKYOujQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/p-timeout": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-1.2.1.tgz",
+ "integrity": "sha512-gb0ryzr+K2qFqFv6qi3khoeqMZF/+ajxQipEF6NteZVnvz9tzdsfAVj3lYtn1gAXvH5lfLwfxEII799gt/mRIA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-finally": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/p-try": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz",
+ "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/param-case": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/param-case/-/param-case-2.1.1.tgz",
+ "integrity": "sha512-eQE845L6ot89sk2N8liD8HAuH4ca6Vvr7VWAWwt7+kvvG5aBcPmmphQ68JsEG2qa9n1TykS2DLeMt363AAH8/w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "no-case": "^2.2.0"
+ }
+ },
+ "node_modules/parent-module": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
+ "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "callsites": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/parse-author": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/parse-author/-/parse-author-2.0.0.tgz",
+ "integrity": "sha512-yx5DfvkN8JsHL2xk2Os9oTia467qnvRgey4ahSm2X8epehBLx/gWLcy5KI+Y36ful5DzGbCS6RazqZGgy1gHNw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "author-regex": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/parse-filepath": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz",
+ "integrity": "sha512-FwdRXKCohSVeXqwtYonZTXtbGJKrn+HNyWDYVcp5yuJlesTwNH4rsmRZ+GrKAPJ5bLpRxESMeS+Rl0VCHRvB2Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-absolute": "^1.0.0",
+ "map-cache": "^0.2.0",
+ "path-root": "^0.1.1"
+ },
+ "engines": {
+ "node": ">=0.8"
+ }
+ },
+ "node_modules/parse-json": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
+ "integrity": "sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "error-ex": "^1.2.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/parse-node-version": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz",
+ "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/parse-passwd": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz",
+ "integrity": "sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/parse5": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.0.tgz",
+ "integrity": "sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/parseurl": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
+ "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/pascalcase": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz",
+ "integrity": "sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/path-dirname": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz",
+ "integrity": "sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/path-exists": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz",
+ "integrity": "sha512-yTltuKuhtNeFJKa1PiRzfLAU5182q1y4Eb4XCJ3PBqyzEDkAZRzBrKKBct682ls9reBVHf9udYLN5Nd+K1B9BQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "pinkie-promise": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-parse": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/path-root": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz",
+ "integrity": "sha512-QLcPegTHF11axjfojBIoDygmS2E3Lf+8+jI6wOVmNVenrKSo3mFdSGiIgdSHenczw3wPtlVMQaFVwGmM7BJdtg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "path-root-regex": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/path-root-regex": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz",
+ "integrity": "sha512-4GlJ6rZDhQZFE0DPVKh0e9jmZ5egZfxTkp7bcRDuPlJXbAwhxcl2dINPUAsjLdejqaLsCeg8axcLjIbvBjN4pQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/path-starts-with": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/path-starts-with/-/path-starts-with-2.0.0.tgz",
+ "integrity": "sha512-3UHTHbJz5+NLkPafFR+2ycJOjoc4WV2e9qCZCnm71zHiWaFrm1XniLVTkZXvaRgxr1xFh9JsTdicpH2yM03nLA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-type": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz",
+ "integrity": "sha512-S4eENJz1pkiQn9Znv33Q+deTOKmbl+jj1Fl+qiP/vYezj+S8x+J3Uo0ISrx/QoEvIlOaDWJhPaRd1flJ9HXZqg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "graceful-fs": "^4.1.2",
+ "pify": "^2.0.0",
+ "pinkie-promise": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/pe-library": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/pe-library/-/pe-library-1.0.1.tgz",
+ "integrity": "sha512-nh39Mo1eGWmZS7y+mK/dQIqg7S1lp38DpRxkyoHf0ZcUs/HDc+yyTjuOtTvSMZHmfSLuSQaX945u05Y2Q6UWZg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14",
+ "npm": ">=7"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/jet2jet"
+ }
+ },
+ "node_modules/pend": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
+ "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/performance-now": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
+ "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/picocolors": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
+ "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/pify": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+ "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/pinkie": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
+ "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/pinkie-promise": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
+ "integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "pinkie": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/pkginfo": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/pkginfo/-/pkginfo-0.3.1.tgz",
+ "integrity": "sha512-yO5feByMzAp96LtP58wvPKSbaKAi/1C4kV9XpTctr6EepnP6F33RBNOiVrdz9BrPA98U2BMFsTNHo44TWcbQ2A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4.0"
+ }
+ },
+ "node_modules/plist": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/plist/-/plist-3.1.0.tgz",
+ "integrity": "sha512-uysumyrvkUX0rX/dEVqt8gC3sTBzd4zoWfLeS29nb53imdaXVvLINYXTI2GNqzaMuvacNx4uJQ8+b3zXR0pkgQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@xmldom/xmldom": "^0.8.8",
+ "base64-js": "^1.5.1",
+ "xmlbuilder": "^15.1.1"
+ },
+ "engines": {
+ "node": ">=10.4.0"
+ }
+ },
+ "node_modules/plugin-error": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-1.0.1.tgz",
+ "integrity": "sha512-L1zP0dk7vGweZME2i+EeakvUNqSrdiI3F91TwEoYiGrAfUXmVv6fJIq4g82PAXxNsWOp0J7ZqQy/3Szz0ajTxA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-colors": "^1.0.1",
+ "arr-diff": "^4.0.0",
+ "arr-union": "^3.1.0",
+ "extend-shallow": "^3.0.2"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/plugin-error/node_modules/extend-shallow": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
+ "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "assign-symbols": "^1.0.0",
+ "is-extendable": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/plugin-error/node_modules/is-extendable": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-plain-object": "^2.0.4"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/plur": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/plur/-/plur-3.1.1.tgz",
+ "integrity": "sha512-t1Ax8KUvV3FFII8ltczPn2tJdjqbd1sIzu6t4JL7nQ3EyeL/lTrj5PWKb06ic5/6XYDr65rQ4uzQEGN70/6X5w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "irregular-plurals": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/pn": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz",
+ "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/pngquant-bin": {
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/pngquant-bin/-/pngquant-bin-5.0.2.tgz",
+ "integrity": "sha512-OLdT+4JZx5BqE1CFJkrvomYV0aSsv6x2Bba+aWaVc0PMfWlE+ZByNKYAdKeIqsM4uvW1HOSEHnf8KcOnykPNxA==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "dependencies": {
+ "bin-build": "^3.0.0",
+ "bin-wrapper": "^4.0.1",
+ "execa": "^0.10.0",
+ "logalot": "^2.0.0"
+ },
+ "bin": {
+ "pngquant": "cli.js"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/pngquant-bin/node_modules/execa": {
+ "version": "0.10.0",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-0.10.0.tgz",
+ "integrity": "sha512-7XOMnz8Ynx1gGo/3hyV9loYNPWM94jG3+3T3Y8tsfSstFmETmENCMU/A/zj8Lyaj1lkgEepKepvd6240tBRvlw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cross-spawn": "^6.0.0",
+ "get-stream": "^3.0.0",
+ "is-stream": "^1.1.0",
+ "npm-run-path": "^2.0.0",
+ "p-finally": "^1.0.0",
+ "signal-exit": "^3.0.0",
+ "strip-eof": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/portscanner": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/portscanner/-/portscanner-2.2.0.tgz",
+ "integrity": "sha512-IFroCz/59Lqa2uBvzK3bKDbDDIEaAY8XJ1jFxcLWTqosrsc32//P4VuSB2vZXoHiHqOmx8B5L5hnKOxL/7FlPw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "async": "^2.6.0",
+ "is-number-like": "^1.0.3"
+ },
+ "engines": {
+ "node": ">=0.4",
+ "npm": ">=1.0.0"
+ }
+ },
+ "node_modules/posix-character-classes": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz",
+ "integrity": "sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/postcss": {
+ "version": "7.0.39",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
+ "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "picocolors": "^0.2.1",
+ "source-map": "^0.6.1"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ }
+ },
+ "node_modules/postcss-assets": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-assets/-/postcss-assets-5.0.0.tgz",
+ "integrity": "sha512-tq6EhGqdXUCQxiDFA2p22NYD2ru+nvNL2aT4n76jaXTd8kAN4rslPBT6O7R9lyUJem8ncMy3Hrr1V1sHVoOsuQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "assets": "^3.0.0",
+ "bluebird": "^3.5.0",
+ "postcss": "^6.0.10",
+ "postcss-functions": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=0.12"
+ }
+ },
+ "node_modules/postcss-assets/node_modules/ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^1.9.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/postcss-assets/node_modules/chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/postcss-assets/node_modules/postcss": {
+ "version": "6.0.23",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz",
+ "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "chalk": "^2.4.1",
+ "source-map": "^0.6.1",
+ "supports-color": "^5.4.0"
+ },
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
+ "node_modules/postcss-calc": {
+ "version": "7.0.5",
+ "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-7.0.5.tgz",
+ "integrity": "sha512-1tKHutbGtLtEZF6PT4JSihCHfIVldU72mZ8SdZHIYriIZ9fh9k9aWSppaT8rHsyI3dX+KSR+W+Ix9BMY3AODrg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "postcss": "^7.0.27",
+ "postcss-selector-parser": "^6.0.2",
+ "postcss-value-parser": "^4.0.2"
+ }
+ },
+ "node_modules/postcss-calc/node_modules/cssesc": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
+ "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "cssesc": "bin/cssesc"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/postcss-calc/node_modules/postcss-selector-parser": {
+ "version": "6.0.11",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.11.tgz",
+ "integrity": "sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cssesc": "^3.0.0",
+ "util-deprecate": "^1.0.2"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/postcss-calc/node_modules/postcss-value-parser": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
+ "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/postcss-colormin": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-4.0.3.tgz",
+ "integrity": "sha512-WyQFAdDZpExQh32j0U0feWisZ0dmOtPl44qYmJKkq9xFWY3p+4qnRzCHeNrkeRhwPHz9bQ3mo0/yVkaply0MNw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "browserslist": "^4.0.0",
+ "color": "^3.0.0",
+ "has": "^1.0.0",
+ "postcss": "^7.0.0",
+ "postcss-value-parser": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/postcss-convert-values": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-4.0.1.tgz",
+ "integrity": "sha512-Kisdo1y77KUC0Jmn0OXU/COOJbzM8cImvw1ZFsBgBgMgb1iL23Zs/LXRe3r+EZqM3vGYKdQ2YJVQ5VkJI+zEJQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "postcss": "^7.0.0",
+ "postcss-value-parser": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/postcss-critical-split": {
+ "version": "2.5.3",
+ "resolved": "https://registry.npmjs.org/postcss-critical-split/-/postcss-critical-split-2.5.3.tgz",
+ "integrity": "sha512-FDG+evU4RBGM9/LQ5nCktzFKjYH2O/SLollJwtrdGagXXbMvk620Bc9o8WpqHJnu573uxVkx9lhob1HZvSWhZg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "merge": "^1.2.0",
+ "postcss": "^6.0.1"
+ }
+ },
+ "node_modules/postcss-critical-split/node_modules/ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^1.9.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/postcss-critical-split/node_modules/chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/postcss-critical-split/node_modules/postcss": {
+ "version": "6.0.23",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz",
+ "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "chalk": "^2.4.1",
+ "source-map": "^0.6.1",
+ "supports-color": "^5.4.0"
+ },
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
+ "node_modules/postcss-discard-comments": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-4.0.2.tgz",
+ "integrity": "sha512-RJutN259iuRf3IW7GZyLM5Sw4GLTOH8FmsXBnv8Ab/Tc2k4SR4qbV4DNbyyY4+Sjo362SyDmW2DQ7lBSChrpkg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "postcss": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/postcss-discard-duplicates": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-4.0.2.tgz",
+ "integrity": "sha512-ZNQfR1gPNAiXZhgENFfEglF93pciw0WxMkJeVmw8eF+JZBbMD7jp6C67GqJAXVZP2BWbOztKfbsdmMp/k8c6oQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "postcss": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/postcss-discard-empty": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-4.0.1.tgz",
+ "integrity": "sha512-B9miTzbznhDjTfjvipfHoqbWKwd0Mj+/fL5s1QOz06wufguil+Xheo4XpOnc4NqKYBCNqqEzgPv2aPBIJLox0w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "postcss": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/postcss-discard-overridden": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-4.0.1.tgz",
+ "integrity": "sha512-IYY2bEDD7g1XM1IDEsUT4//iEYCxAmP5oDSFMVU/JVvT7gh+l4fmjciLqGgwjdWpQIdb0Che2VX00QObS5+cTg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "postcss": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/postcss-discard-unused": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-discard-unused/-/postcss-discard-unused-4.0.1.tgz",
+ "integrity": "sha512-/3vq4LU0bLH2Lj4NYN7BTf2caly0flUB7Xtrk9a5K3yLuXMkHMqMO/x3sDq8W2b1eQFSCyY0IVz2L+0HP8kUUA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "postcss": "^7.0.0",
+ "postcss-selector-parser": "^3.0.0",
+ "uniqs": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/postcss-functions": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-functions/-/postcss-functions-3.0.0.tgz",
+ "integrity": "sha512-N5yWXWKA+uhpLQ9ZhBRl2bIAdM6oVJYpDojuI1nF2SzXBimJcdjFwiAouBVbO5VuOF3qA6BSFWFc3wXbbj72XQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "glob": "^7.1.2",
+ "object-assign": "^4.1.1",
+ "postcss": "^6.0.9",
+ "postcss-value-parser": "^3.3.0"
+ }
+ },
+ "node_modules/postcss-functions/node_modules/ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^1.9.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/postcss-functions/node_modules/chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/postcss-functions/node_modules/postcss": {
+ "version": "6.0.23",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz",
+ "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "chalk": "^2.4.1",
+ "source-map": "^0.6.1",
+ "supports-color": "^5.4.0"
+ },
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
+ "node_modules/postcss-load-config": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-2.1.2.tgz",
+ "integrity": "sha512-/rDeGV6vMUo3mwJZmeHfEDvwnTKKqQ0S7OHUi/kJvvtx3aWtyWG2/0ZWnzCt2keEclwN6Tf0DST2v9kITdOKYw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cosmiconfig": "^5.0.0",
+ "import-cwd": "^2.0.0"
+ },
+ "engines": {
+ "node": ">= 4"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ }
+ },
+ "node_modules/postcss-merge-idents": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-merge-idents/-/postcss-merge-idents-4.0.1.tgz",
+ "integrity": "sha512-43S/VNdF6II0NZ31YxcvNYq4gfURlPAAsJW/z84avBXQCaP4I4qRHUH18slW/SOlJbcxxCobflPNUApYDddS7A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cssnano-util-same-parent": "^4.0.0",
+ "has": "^1.0.0",
+ "postcss": "^7.0.0",
+ "postcss-value-parser": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/postcss-merge-longhand": {
+ "version": "4.0.11",
+ "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-4.0.11.tgz",
+ "integrity": "sha512-alx/zmoeXvJjp7L4mxEMjh8lxVlDFX1gqWHzaaQewwMZiVhLo42TEClKaeHbRf6J7j82ZOdTJ808RtN0ZOZwvw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "css-color-names": "0.0.4",
+ "postcss": "^7.0.0",
+ "postcss-value-parser": "^3.0.0",
+ "stylehacks": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/postcss-merge-rules": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-4.0.3.tgz",
+ "integrity": "sha512-U7e3r1SbvYzO0Jr3UT/zKBVgYYyhAz0aitvGIYOYK5CPmkNih+WDSsS5tvPrJ8YMQYlEMvsZIiqmn7HdFUaeEQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "browserslist": "^4.0.0",
+ "caniuse-api": "^3.0.0",
+ "cssnano-util-same-parent": "^4.0.0",
+ "postcss": "^7.0.0",
+ "postcss-selector-parser": "^3.0.0",
+ "vendors": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/postcss-minify-font-values": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-4.0.2.tgz",
+ "integrity": "sha512-j85oO6OnRU9zPf04+PZv1LYIYOprWm6IA6zkXkrJXyRveDEuQggG6tvoy8ir8ZwjLxLuGfNkCZEQG7zan+Hbtg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "postcss": "^7.0.0",
+ "postcss-value-parser": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/postcss-minify-gradients": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-4.0.2.tgz",
+ "integrity": "sha512-qKPfwlONdcf/AndP1U8SJ/uzIJtowHlMaSioKzebAXSG4iJthlWC9iSWznQcX4f66gIWX44RSA841HTHj3wK+Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cssnano-util-get-arguments": "^4.0.0",
+ "is-color-stop": "^1.0.0",
+ "postcss": "^7.0.0",
+ "postcss-value-parser": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/postcss-minify-params": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-4.0.2.tgz",
+ "integrity": "sha512-G7eWyzEx0xL4/wiBBJxJOz48zAKV2WG3iZOqVhPet/9geefm/Px5uo1fzlHu+DOjT+m0Mmiz3jkQzVHe6wxAWg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "alphanum-sort": "^1.0.0",
+ "browserslist": "^4.0.0",
+ "cssnano-util-get-arguments": "^4.0.0",
+ "postcss": "^7.0.0",
+ "postcss-value-parser": "^3.0.0",
+ "uniqs": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/postcss-minify-selectors": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-4.0.2.tgz",
+ "integrity": "sha512-D5S1iViljXBj9kflQo4YutWnJmwm8VvIsU1GeXJGiG9j8CIg9zs4voPMdQDUmIxetUOh60VilsNzCiAFTOqu3g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "alphanum-sort": "^1.0.0",
+ "has": "^1.0.0",
+ "postcss": "^7.0.0",
+ "postcss-selector-parser": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/postcss-normalize-charset": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-4.0.1.tgz",
+ "integrity": "sha512-gMXCrrlWh6G27U0hF3vNvR3w8I1s2wOBILvA87iNXaPvSNo5uZAMYsZG7XjCUf1eVxuPfyL4TJ7++SGZLc9A3g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "postcss": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/postcss-normalize-display-values": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-4.0.2.tgz",
+ "integrity": "sha512-3F2jcsaMW7+VtRMAqf/3m4cPFhPD3EFRgNs18u+k3lTJJlVe7d0YPO+bnwqo2xg8YiRpDXJI2u8A0wqJxMsQuQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cssnano-util-get-match": "^4.0.0",
+ "postcss": "^7.0.0",
+ "postcss-value-parser": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/postcss-normalize-positions": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-4.0.2.tgz",
+ "integrity": "sha512-Dlf3/9AxpxE+NF1fJxYDeggi5WwV35MXGFnnoccP/9qDtFrTArZ0D0R+iKcg5WsUd8nUYMIl8yXDCtcrT8JrdA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cssnano-util-get-arguments": "^4.0.0",
+ "has": "^1.0.0",
+ "postcss": "^7.0.0",
+ "postcss-value-parser": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/postcss-normalize-repeat-style": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-4.0.2.tgz",
+ "integrity": "sha512-qvigdYYMpSuoFs3Is/f5nHdRLJN/ITA7huIoCyqqENJe9PvPmLhNLMu7QTjPdtnVf6OcYYO5SHonx4+fbJE1+Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cssnano-util-get-arguments": "^4.0.0",
+ "cssnano-util-get-match": "^4.0.0",
+ "postcss": "^7.0.0",
+ "postcss-value-parser": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/postcss-normalize-string": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-4.0.2.tgz",
+ "integrity": "sha512-RrERod97Dnwqq49WNz8qo66ps0swYZDSb6rM57kN2J+aoyEAJfZ6bMx0sx/F9TIEX0xthPGCmeyiam/jXif0eA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has": "^1.0.0",
+ "postcss": "^7.0.0",
+ "postcss-value-parser": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/postcss-normalize-timing-functions": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-4.0.2.tgz",
+ "integrity": "sha512-acwJY95edP762e++00Ehq9L4sZCEcOPyaHwoaFOhIwWCDfik6YvqsYNxckee65JHLKzuNSSmAdxwD2Cud1Z54A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cssnano-util-get-match": "^4.0.0",
+ "postcss": "^7.0.0",
+ "postcss-value-parser": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/postcss-normalize-unicode": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-4.0.1.tgz",
+ "integrity": "sha512-od18Uq2wCYn+vZ/qCOeutvHjB5jm57ToxRaMeNuf0nWVHaP9Hua56QyMF6fs/4FSUnVIw0CBPsU0K4LnBPwYwg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "browserslist": "^4.0.0",
+ "postcss": "^7.0.0",
+ "postcss-value-parser": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/postcss-normalize-url": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-4.0.1.tgz",
+ "integrity": "sha512-p5oVaF4+IHwu7VpMan/SSpmpYxcJMtkGppYf0VbdH5B6hN8YNmVyJLuY9FmLQTzY3fag5ESUUHDqM+heid0UVA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-absolute-url": "^2.0.0",
+ "normalize-url": "^3.0.0",
+ "postcss": "^7.0.0",
+ "postcss-value-parser": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/postcss-normalize-whitespace": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-4.0.2.tgz",
+ "integrity": "sha512-tO8QIgrsI3p95r8fyqKV+ufKlSHh9hMJqACqbv2XknufqEDhDvbguXGBBqxw9nsQoXWf0qOqppziKJKHMD4GtA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "postcss": "^7.0.0",
+ "postcss-value-parser": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/postcss-ordered-values": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-4.1.2.tgz",
+ "integrity": "sha512-2fCObh5UanxvSxeXrtLtlwVThBvHn6MQcu4ksNT2tsaV2Fg76R2CV98W7wNSlX+5/pFwEyaDwKLLoEV7uRybAw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cssnano-util-get-arguments": "^4.0.0",
+ "postcss": "^7.0.0",
+ "postcss-value-parser": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/postcss-reduce-idents": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/postcss-reduce-idents/-/postcss-reduce-idents-4.0.2.tgz",
+ "integrity": "sha512-Tz70Ri10TclPoCtFfftjFVddx3fZGUkr0dEDbIEfbYhFUOFQZZ77TEqRrU0e6TvAvF+Wa5VVzYTpFpq0uwFFzw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "postcss": "^7.0.0",
+ "postcss-value-parser": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/postcss-reduce-initial": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-4.0.3.tgz",
+ "integrity": "sha512-gKWmR5aUulSjbzOfD9AlJiHCGH6AEVLaM0AV+aSioxUDd16qXP1PCh8d1/BGVvpdWn8k/HiK7n6TjeoXN1F7DA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "browserslist": "^4.0.0",
+ "caniuse-api": "^3.0.0",
+ "has": "^1.0.0",
+ "postcss": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/postcss-reduce-transforms": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-4.0.2.tgz",
+ "integrity": "sha512-EEVig1Q2QJ4ELpJXMZR8Vt5DQx8/mo+dGWSR7vWXqcob2gQLyQGsionYcGKATXvQzMPn6DSN1vTN7yFximdIAg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cssnano-util-get-match": "^4.0.0",
+ "has": "^1.0.0",
+ "postcss": "^7.0.0",
+ "postcss-value-parser": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/postcss-selector-parser": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz",
+ "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "dot-prop": "^5.2.0",
+ "indexes-of": "^1.0.1",
+ "uniq": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/postcss-svgo": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-4.0.3.tgz",
+ "integrity": "sha512-NoRbrcMWTtUghzuKSoIm6XV+sJdvZ7GZSc3wdBN0W19FTtp2ko8NqLsgoh/m9CzNhU3KLPvQmjIwtaNFkaFTvw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "postcss": "^7.0.0",
+ "postcss-value-parser": "^3.0.0",
+ "svgo": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/postcss-unique-selectors": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-4.0.1.tgz",
+ "integrity": "sha512-+JanVaryLo9QwZjKrmJgkI4Fn8SBgRO6WXQBJi7KiAVPlmxikB5Jzc4EvXMT2H0/m0RjrVVm9rGNhZddm/8Spg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "alphanum-sort": "^1.0.0",
+ "postcss": "^7.0.0",
+ "uniqs": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/postcss-value-parser": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz",
+ "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/postcss-zindex": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-zindex/-/postcss-zindex-4.0.1.tgz",
+ "integrity": "sha512-d/8BlQcUdEugZNRM9AdCA2V4fqREUtn/wcixLN3L6ITgc2P/FMcVVYz8QZkhItWT9NB5qr8wuN2dJCE4/+dlrA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has": "^1.0.0",
+ "postcss": "^7.0.0",
+ "uniqs": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/postject": {
+ "version": "1.0.0-alpha.6",
+ "resolved": "https://registry.npmjs.org/postject/-/postject-1.0.0-alpha.6.tgz",
+ "integrity": "sha512-b9Eb8h2eVqNE8edvKdwqkrY6O7kAwmI8kcnBv1NScolYJbo59XUF0noFq+lxbC1yN20bmC0WBEbDC5H/7ASb0A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "commander": "^9.4.0"
+ },
+ "bin": {
+ "postject": "dist/cli.js"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/postject/node_modules/commander": {
+ "version": "9.5.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz",
+ "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.20.0 || >=14"
+ }
+ },
+ "node_modules/prelude-ls": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
+ "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/prepend-http": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz",
+ "integrity": "sha512-ravE6m9Atw9Z/jjttRUZ+clIXogdghyZAuWJ3qEzjT+jI/dL1ifAqhZeC5VHzQp1MSt1+jxKkFNemj/iO7tVUA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/prettier": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.2.tgz",
+ "integrity": "sha512-rAVeHYMcv8ATV5d508CFdn+8/pHPpXeIid1DdrPwXnaAdH7cqjVbpJaT5eq4yRAFU/lsbwYwSF/n5iNrdJHPQA==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "prettier": "bin/prettier.cjs"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/prettier/prettier?sponsor=1"
+ }
+ },
+ "node_modules/pretty-bytes": {
+ "version": "5.6.0",
+ "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz",
+ "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/pretty-hrtime": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz",
+ "integrity": "sha512-66hKPCr+72mlfiSjlEB1+45IjXSqvVAIy6mocupoww4tBFE9R9IhwwUGoI4G++Tc9Aq+2rxOt0RFU6gPcrte0A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/process-nextick-args": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
+ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/progress": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
+ "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/promise-retry": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz",
+ "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "err-code": "^2.0.2",
+ "retry": "^0.12.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/proto-list": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz",
+ "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/proxy-middleware": {
+ "version": "0.5.1",
+ "resolved": "https://registry.npmjs.org/proxy-middleware/-/proxy-middleware-0.5.1.tgz",
+ "integrity": "sha512-bMULIe/lp43YW3ZcPX4s8ND3GJPCjMyMGL049A+ikSZa2F+iPV0KiQZJsd+rwQd/7td0o3cpL/TPTg5apjUAyQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/prr": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz",
+ "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/pseudomap": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
+ "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/psl": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz",
+ "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/pump": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
+ "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "end-of-stream": "^1.1.0",
+ "once": "^1.3.1"
+ }
+ },
+ "node_modules/pumpify": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz",
+ "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "duplexify": "^3.6.0",
+ "inherits": "^2.0.3",
+ "pump": "^2.0.0"
+ }
+ },
+ "node_modules/pumpify/node_modules/duplexify": {
+ "version": "3.7.1",
+ "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz",
+ "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "end-of-stream": "^1.0.0",
+ "inherits": "^2.0.1",
+ "readable-stream": "^2.0.0",
+ "stream-shift": "^1.0.0"
+ }
+ },
+ "node_modules/pumpify/node_modules/pump": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz",
+ "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "end-of-stream": "^1.1.0",
+ "once": "^1.3.1"
+ }
+ },
+ "node_modules/punycode": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
+ "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/q": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz",
+ "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.6.0",
+ "teleport": ">=0.2.0"
+ }
+ },
+ "node_modules/qs": {
+ "version": "6.2.3",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.2.3.tgz",
+ "integrity": "sha512-AY4g8t3LMboim0t6XWFdz6J5OuJ1ZNYu54SXihS/OMpgyCqYmcAJnWqkNSOjSjWmq3xxy+GF9uWQI2lI/7tKIA==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.6"
+ }
+ },
+ "node_modules/query-string": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz",
+ "integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "decode-uri-component": "^0.2.0",
+ "object-assign": "^4.1.0",
+ "strict-uri-encode": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/queue-microtask": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
+ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/queue-tick": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz",
+ "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/quick-lru": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz",
+ "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/randombytes": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
+ "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "safe-buffer": "^5.1.0"
+ }
+ },
+ "node_modules/range-parser": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
+ "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/raw-body": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz",
+ "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "bytes": "3.1.2",
+ "http-errors": "2.0.0",
+ "iconv-lite": "0.4.24",
+ "unpipe": "1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/raw-body/node_modules/bytes": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
+ "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/raw-body/node_modules/depd": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
+ "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/raw-body/node_modules/http-errors": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
+ "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "depd": "2.0.0",
+ "inherits": "2.0.4",
+ "setprototypeof": "1.2.0",
+ "statuses": "2.0.1",
+ "toidentifier": "1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/raw-body/node_modules/setprototypeof": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
+ "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/raw-body/node_modules/statuses": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
+ "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/read-pkg": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz",
+ "integrity": "sha512-7BGwRHqt4s/uVbuyoeejRn4YmFnYZiFl4AuaeXHlgZf3sONF0SOGlxs2Pw8g6hCKupo08RafIO5YXFNOKTfwsQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "load-json-file": "^1.0.0",
+ "normalize-package-data": "^2.3.2",
+ "path-type": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/read-pkg-up": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz",
+ "integrity": "sha512-WD9MTlNtI55IwYUS27iHh9tK3YoIVhxis8yKhLpTqWtml739uXc9NWTpxoHkfZf3+DkCCsXox94/VWZniuZm6A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "find-up": "^1.0.0",
+ "read-pkg": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/readable-stream": {
+ "version": "2.3.7",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+ "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "node_modules/readable-stream/node_modules/isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/readable-stream/node_modules/safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/readable-stream/node_modules/string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "safe-buffer": "~5.1.0"
+ }
+ },
+ "node_modules/readdirp": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
+ "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "picomatch": "^2.2.1"
+ },
+ "engines": {
+ "node": ">=8.10.0"
+ }
+ },
+ "node_modules/rechoir": {
+ "version": "0.6.2",
+ "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz",
+ "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==",
+ "dev": true,
+ "dependencies": {
+ "resolve": "^1.1.6"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/redent": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz",
+ "integrity": "sha512-qtW5hKzGQZqKoh6JNSD+4lfitfPKGz42e6QwiRmPM5mmKtR0N41AbJRYu0xJi7nhOJ4WDgRkKvAk6tw4WIwR4g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "indent-string": "^2.1.0",
+ "strip-indent": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/regenerator-runtime": {
+ "version": "0.13.11",
+ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz",
+ "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/regex-not": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
+ "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "extend-shallow": "^3.0.2",
+ "safe-regex": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/regex-not/node_modules/extend-shallow": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
+ "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "assign-symbols": "^1.0.0",
+ "is-extendable": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/regex-not/node_modules/is-extendable": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-plain-object": "^2.0.4"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/regexp.prototype.flags": {
+ "version": "1.4.3",
+ "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz",
+ "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.3",
+ "functions-have-names": "^1.2.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/relateurl": {
+ "version": "0.2.7",
+ "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz",
+ "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/remove-bom-buffer": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/remove-bom-buffer/-/remove-bom-buffer-3.0.0.tgz",
+ "integrity": "sha512-8v2rWhaakv18qcvNeli2mZ/TMTL2nEyAKRvzo1WtnZBl15SHyEhrCu2/xKlJyUFKHiHgfXIyuY6g2dObJJycXQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-buffer": "^1.1.5",
+ "is-utf8": "^0.2.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/remove-bom-stream": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/remove-bom-stream/-/remove-bom-stream-1.2.0.tgz",
+ "integrity": "sha512-wigO8/O08XHb8YPzpDDT+QmRANfW6vLqxfaXm1YXhnFf3AkSLyjfG3GEFg4McZkmgL7KvCj5u2KczkvSP6NfHA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "remove-bom-buffer": "^3.0.0",
+ "safe-buffer": "^5.1.0",
+ "through2": "^2.0.3"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/remove-trailing-separator": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
+ "integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/repeat-element": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz",
+ "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/repeat-string": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
+ "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/repeating": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz",
+ "integrity": "sha512-ZqtSMuVybkISo2OWvqvm7iHSWngvdaW3IpsT9/uP8v4gMi591LY6h35wdOfvQdWCKFWZWm2Y1Opp4kV7vQKT6A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-finite": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/replace-ext": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.1.tgz",
+ "integrity": "sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/replace-homedir": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/replace-homedir/-/replace-homedir-1.0.0.tgz",
+ "integrity": "sha512-CHPV/GAglbIB1tnQgaiysb8H2yCy8WQ7lcEwQ/eT+kLj0QHV8LnJW0zpqpE7RSkrMSRoa+EBoag86clf7WAgSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "homedir-polyfill": "^1.0.1",
+ "is-absolute": "^1.0.0",
+ "remove-trailing-separator": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/request": {
+ "version": "2.88.2",
+ "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz",
+ "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "aws-sign2": "~0.7.0",
+ "aws4": "^1.8.0",
+ "caseless": "~0.12.0",
+ "combined-stream": "~1.0.6",
+ "extend": "~3.0.2",
+ "forever-agent": "~0.6.1",
+ "form-data": "~2.3.2",
+ "har-validator": "~5.1.3",
+ "http-signature": "~1.2.0",
+ "is-typedarray": "~1.0.0",
+ "isstream": "~0.1.2",
+ "json-stringify-safe": "~5.0.1",
+ "mime-types": "~2.1.19",
+ "oauth-sign": "~0.9.0",
+ "performance-now": "^2.1.0",
+ "qs": "~6.5.2",
+ "safe-buffer": "^5.1.2",
+ "tough-cookie": "~2.5.0",
+ "tunnel-agent": "^0.6.0",
+ "uuid": "^3.3.2"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/request-promise-core": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz",
+ "integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "lodash": "^4.17.19"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ },
+ "peerDependencies": {
+ "request": "^2.34"
+ }
+ },
+ "node_modules/request-promise-native": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.9.tgz",
+ "integrity": "sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "request-promise-core": "1.1.4",
+ "stealthy-require": "^1.1.1",
+ "tough-cookie": "^2.3.3"
+ },
+ "engines": {
+ "node": ">=0.12.0"
+ },
+ "peerDependencies": {
+ "request": "^2.34"
+ }
+ },
+ "node_modules/request/node_modules/qs": {
+ "version": "6.5.3",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz",
+ "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.6"
+ }
+ },
+ "node_modules/require-directory": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+ "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/require-from-string": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
+ "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/require-main-filename": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz",
+ "integrity": "sha512-IqSUtOVP4ksd1C/ej5zeEh/BIP2ajqpn8c5x+q99gvcIG/Qf0cud5raVnE/Dwd0ua9TXYDoDc0RE5hBSdz22Ug==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/requires-port": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
+ "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/resedit": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/resedit/-/resedit-2.0.3.tgz",
+ "integrity": "sha512-oTeemxwoMuxxTYxXUwjkrOPfngTQehlv0/HoYFNkB4uzsP1Un1A9nI8JQKGOFkxpqkC7qkMs0lUsGrvUlbLNUA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "pe-library": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=14",
+ "npm": ">=7"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/jet2jet"
+ }
+ },
+ "node_modules/resolve": {
+ "version": "1.22.1",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz",
+ "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-core-module": "^2.9.0",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
+ },
+ "bin": {
+ "resolve": "bin/resolve"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/resolve-alpn": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz",
+ "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/resolve-dir": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz",
+ "integrity": "sha512-R7uiTjECzvOsWSfdM0QKFNBVFcK27aHOUwdvK53BcW8zqnGdYp0Fbj82cy54+2A4P2tFM22J5kRfe1R+lM/1yg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "expand-tilde": "^2.0.0",
+ "global-modules": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/resolve-from": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz",
+ "integrity": "sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/resolve-options": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/resolve-options/-/resolve-options-1.1.0.tgz",
+ "integrity": "sha512-NYDgziiroVeDC29xq7bp/CacZERYsA9bXYd1ZmcJlF3BcrZv5pTb4NG7SjdyKDnXZ84aC4vo2u6sNKIA1LCu/A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "value-or-function": "^3.0.0"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/resolve-url": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
+ "integrity": "sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/resp-modifier": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/resp-modifier/-/resp-modifier-6.0.2.tgz",
+ "integrity": "sha512-U1+0kWC/+4ncRFYqQWTx/3qkfE6a4B/h3XXgmXypfa0SPZ3t7cbbaFk297PjQS/yov24R18h6OZe6iZwj3NSLw==",
+ "dev": true,
+ "dependencies": {
+ "debug": "^2.2.0",
+ "minimatch": "^3.0.2"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/resp-modifier/node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/responselike": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz",
+ "integrity": "sha512-/Fpe5guzJk1gPqdJLJR5u7eG/gNY4nImjbRDaVWVMRhne55TCmj2i9Q+54PBRfatRC8v/rIiv9BN0pMd9OV5EQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "lowercase-keys": "^1.0.0"
+ }
+ },
+ "node_modules/ret": {
+ "version": "0.1.15",
+ "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz",
+ "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.12"
+ }
+ },
+ "node_modules/retry": {
+ "version": "0.12.0",
+ "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz",
+ "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/reusify": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
+ "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "iojs": ">=1.0.0",
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/rgb-regex": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/rgb-regex/-/rgb-regex-1.0.1.tgz",
+ "integrity": "sha512-gDK5mkALDFER2YLqH6imYvK6g02gpNGM4ILDZ472EwWfXZnC2ZEpoB2ECXTyOVUKuk/bPJZMzwQPBYICzP+D3w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/rgba-regex": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/rgba-regex/-/rgba-regex-1.0.0.tgz",
+ "integrity": "sha512-zgn5OjNQXLUTdq8m17KdaicF6w89TZs8ZU8y0AYENIU6wG8GG6LLm0yLSiPY8DmaYmHdgRW8rnApjoT0fQRfMg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/rimraf": {
+ "version": "2.7.1",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
+ "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "glob": "^7.1.3"
+ },
+ "bin": {
+ "rimraf": "bin.js"
+ }
+ },
+ "node_modules/roarr": {
+ "version": "2.15.4",
+ "resolved": "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz",
+ "integrity": "sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "optional": true,
+ "dependencies": {
+ "boolean": "^3.0.1",
+ "detect-node": "^2.0.4",
+ "globalthis": "^1.0.1",
+ "json-stringify-safe": "^5.0.1",
+ "semver-compare": "^1.0.0",
+ "sprintf-js": "^1.1.2"
+ },
+ "engines": {
+ "node": ">=8.0"
+ }
+ },
+ "node_modules/roarr/node_modules/sprintf-js": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz",
+ "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "optional": true
+ },
+ "node_modules/run-parallel": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
+ "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "queue-microtask": "^1.2.2"
+ }
+ },
+ "node_modules/rx": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/rx/-/rx-4.1.0.tgz",
+ "integrity": "sha512-CiaiuN6gapkdl+cZUr67W6I8jquN4lkak3vtIsIWCl4XIPP8ffsoyN6/+PuGXnQy8Cu8W2y9Xxh31Rq4M6wUug==",
+ "dev": true,
+ "license": "Apache-2.0"
+ },
+ "node_modules/rxjs": {
+ "version": "5.5.12",
+ "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.5.12.tgz",
+ "integrity": "sha512-xx2itnL5sBbqeeiVgNPVuQQ1nC8Jp2WfNJhXWHmElW9YmrpS9UVnNzhP3EH3HFqexO5Tlp8GhYY+WEcqcVMvGw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "symbol-observable": "1.0.1"
+ },
+ "engines": {
+ "npm": ">=2.0.0"
+ }
+ },
+ "node_modules/safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/safe-regex": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
+ "integrity": "sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ret": "~0.1.10"
+ }
+ },
+ "node_modules/safe-regex-test": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz",
+ "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "get-intrinsic": "^1.1.3",
+ "is-regex": "^1.1.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/sass": {
+ "version": "1.56.1",
+ "resolved": "https://registry.npmjs.org/sass/-/sass-1.56.1.tgz",
+ "integrity": "sha512-VpEyKpyBPCxE7qGDtOcdJ6fFbcpOM+Emu7uZLxVrkX8KVU/Dp5UF7WLvzqRuUhB6mqqQt1xffLoG+AndxTZrCQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "chokidar": ">=3.0.0 <4.0.0",
+ "immutable": "^4.0.0",
+ "source-map-js": ">=0.6.2 <2.0.0"
+ },
+ "bin": {
+ "sass": "sass.js"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ }
+ },
+ "node_modules/sass/node_modules/immutable": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.1.0.tgz",
+ "integrity": "sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/sax": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
+ "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/saxes": {
+ "version": "3.1.11",
+ "resolved": "https://registry.npmjs.org/saxes/-/saxes-3.1.11.tgz",
+ "integrity": "sha512-Ydydq3zC+WYDJK1+gRxRapLIED9PWeSuuS41wqyoRmzvhhh9nc+QQrVMKJYzJFULazeGhzSV0QleN2wD3boh2g==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "xmlchars": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/seek-bzip": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/seek-bzip/-/seek-bzip-1.0.6.tgz",
+ "integrity": "sha512-e1QtP3YL5tWww8uKaOCQ18UxIT2laNBXHjV/S2WYCiK4udiv8lkG89KRIoCjUagnAmCBurjF4zEVX2ByBbnCjQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "commander": "^2.8.1"
+ },
+ "bin": {
+ "seek-bunzip": "bin/seek-bunzip",
+ "seek-table": "bin/seek-bzip-table"
+ }
+ },
+ "node_modules/semver": {
+ "version": "7.3.8",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
+ "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "lru-cache": "^6.0.0"
+ },
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/semver-compare": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz",
+ "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/semver-greatest-satisfied-range": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/semver-greatest-satisfied-range/-/semver-greatest-satisfied-range-1.1.0.tgz",
+ "integrity": "sha512-Ny/iyOzSSa8M5ML46IAx3iXc6tfOsYU2R4AXi2UpHk60Zrgyq6eqPj/xiOfS0rRl/iiQ/rdJkVjw/5cdUyCntQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "sver-compat": "^1.5.0"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/semver-regex": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-2.0.0.tgz",
+ "integrity": "sha512-mUdIBBvdn0PLOeP3TEkMH7HHeUP3GjsXCwKarjv/kGmUFOYg1VqEemKhoQpWMu6X2I8kHeuVdGibLGkVK+/5Qw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/semver-truncate": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/semver-truncate/-/semver-truncate-1.1.2.tgz",
+ "integrity": "sha512-V1fGg9i4CL3qesB6U0L6XAm4xOJiHmt4QAacazumuasc03BvtFGIMCduv01JWQ69Nv+JST9TqhSCiJoxoY031w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "semver": "^5.3.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/semver-truncate/node_modules/semver": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+ "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver"
+ }
+ },
+ "node_modules/send": {
+ "version": "0.16.2",
+ "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz",
+ "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "debug": "2.6.9",
+ "depd": "~1.1.2",
+ "destroy": "~1.0.4",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "etag": "~1.8.1",
+ "fresh": "0.5.2",
+ "http-errors": "~1.6.2",
+ "mime": "1.4.1",
+ "ms": "2.0.0",
+ "on-finished": "~2.3.0",
+ "range-parser": "~1.2.0",
+ "statuses": "~1.4.0"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/send/node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/send/node_modules/statuses": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz",
+ "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/serialize-error": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz",
+ "integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "type-fest": "^0.13.1"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/serialize-error/node_modules/type-fest": {
+ "version": "0.13.1",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz",
+ "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==",
+ "dev": true,
+ "license": "(MIT OR CC0-1.0)",
+ "optional": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/serialize-javascript": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz",
+ "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "randombytes": "^2.1.0"
+ }
+ },
+ "node_modules/serve-index": {
+ "version": "1.9.1",
+ "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz",
+ "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "accepts": "~1.3.4",
+ "batch": "0.6.1",
+ "debug": "2.6.9",
+ "escape-html": "~1.0.3",
+ "http-errors": "~1.6.2",
+ "mime-types": "~2.1.17",
+ "parseurl": "~1.3.2"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/serve-index/node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/serve-static": {
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz",
+ "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "parseurl": "~1.3.2",
+ "send": "0.16.2"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/server-destroy": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/server-destroy/-/server-destroy-1.0.1.tgz",
+ "integrity": "sha512-rb+9B5YBIEzYcD6x2VKidaa+cqYBJQKnU4oe4E3ANwRRN56yk/ua1YCJT1n21NTS8w6CcOclAKNP3PhdCXKYtQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/set-blocking": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
+ "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/set-value": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz",
+ "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "extend-shallow": "^2.0.1",
+ "is-extendable": "^0.1.1",
+ "is-plain-object": "^2.0.3",
+ "split-string": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/setprototypeof": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz",
+ "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/shebang-command": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
+ "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "shebang-regex": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/shebang-regex": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
+ "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/side-channel": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
+ "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.0",
+ "get-intrinsic": "^1.0.2",
+ "object-inspect": "^1.9.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/signal-exit": {
+ "version": "3.0.7",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
+ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/simple-swizzle": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
+ "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-arrayish": "^0.3.1"
+ }
+ },
+ "node_modules/simple-swizzle/node_modules/is-arrayish": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz",
+ "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/slash": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
+ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/snapdragon": {
+ "version": "0.8.2",
+ "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
+ "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "base": "^0.11.1",
+ "debug": "^2.2.0",
+ "define-property": "^0.2.5",
+ "extend-shallow": "^2.0.1",
+ "map-cache": "^0.2.2",
+ "source-map": "^0.5.6",
+ "source-map-resolve": "^0.5.0",
+ "use": "^3.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/snapdragon-node": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz",
+ "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "define-property": "^1.0.0",
+ "isobject": "^3.0.0",
+ "snapdragon-util": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/snapdragon-node/node_modules/define-property": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+ "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-descriptor": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/snapdragon-util": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz",
+ "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "kind-of": "^3.2.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/snapdragon/node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/snapdragon/node_modules/source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/socket.io": {
+ "version": "4.5.4",
+ "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.5.4.tgz",
+ "integrity": "sha512-m3GC94iK9MfIEeIBfbhJs5BqFibMtkRk8ZpKwG2QwxV0m/eEhPIV4ara6XCF1LWNAus7z58RodiZlAH71U3EhQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "accepts": "~1.3.4",
+ "base64id": "~2.0.0",
+ "debug": "~4.3.2",
+ "engine.io": "~6.2.1",
+ "socket.io-adapter": "~2.4.0",
+ "socket.io-parser": "~4.2.1"
+ },
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
+ "node_modules/socket.io-adapter": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.4.0.tgz",
+ "integrity": "sha512-W4N+o69rkMEGVuk2D/cvca3uYsvGlMwsySWV447y99gUPghxq42BxqLNMndb+a1mm/5/7NeXVQS7RLa2XyXvYg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/socket.io-client": {
+ "version": "4.5.4",
+ "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.5.4.tgz",
+ "integrity": "sha512-ZpKteoA06RzkD32IbqILZ+Cnst4xewU7ZYK12aS1mzHftFFjpoMz69IuhP/nL25pJfao/amoPI527KnuhFm01g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@socket.io/component-emitter": "~3.1.0",
+ "debug": "~4.3.2",
+ "engine.io-client": "~6.2.3",
+ "socket.io-parser": "~4.2.1"
+ },
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
+ "node_modules/socket.io-parser": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.1.tgz",
+ "integrity": "sha512-V4GrkLy+HeF1F/en3SpUaM+7XxYXpuMUWLGde1kSSh5nQMN4hLrbPIkD+otwh6q9R6NOQBN4AMaOZ2zVjui82g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@socket.io/component-emitter": "~3.1.0",
+ "debug": "~4.3.1"
+ },
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
+ "node_modules/sort-keys": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz",
+ "integrity": "sha512-vzn8aSqKgytVik0iwdBEi+zevbTYZogewTUM6dtpmGwEcdzbub/TX4bCzRhebDCRC3QzXgJsLRKB2V/Oof7HXg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-plain-obj": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/sort-keys-length": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/sort-keys-length/-/sort-keys-length-1.0.1.tgz",
+ "integrity": "sha512-GRbEOUqCxemTAk/b32F2xa8wDTs+Z1QHOkbhJDQTvv/6G3ZkbJ+frYWsTcc7cBB3Fu4wy4XlLCuNtJuMn7Gsvw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "sort-keys": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/source-map-js": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
+ "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/source-map-resolve": {
+ "version": "0.5.3",
+ "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz",
+ "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "atob": "^2.1.2",
+ "decode-uri-component": "^0.2.0",
+ "resolve-url": "^0.2.1",
+ "source-map-url": "^0.4.0",
+ "urix": "^0.1.0"
+ }
+ },
+ "node_modules/source-map-support": {
+ "version": "0.5.21",
+ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
+ "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "buffer-from": "^1.0.0",
+ "source-map": "^0.6.0"
+ }
+ },
+ "node_modules/source-map-url": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz",
+ "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/sparkles": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-1.0.1.tgz",
+ "integrity": "sha512-dSO0DDYUahUt/0/pD/Is3VIm5TGJjludZ0HVymmhYF6eNA53PVLhnUk0znSYbH8IYBuJdCE+1luR22jNLMaQdw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/spdx-correct": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz",
+ "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "spdx-expression-parse": "^3.0.0",
+ "spdx-license-ids": "^3.0.0"
+ }
+ },
+ "node_modules/spdx-exceptions": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz",
+ "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==",
+ "dev": true,
+ "license": "CC-BY-3.0"
+ },
+ "node_modules/spdx-expression-parse": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
+ "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "spdx-exceptions": "^2.1.0",
+ "spdx-license-ids": "^3.0.0"
+ }
+ },
+ "node_modules/spdx-license-ids": {
+ "version": "3.0.12",
+ "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.12.tgz",
+ "integrity": "sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA==",
+ "dev": true,
+ "license": "CC0-1.0"
+ },
+ "node_modules/split-string": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
+ "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "extend-shallow": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/split-string/node_modules/extend-shallow": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
+ "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "assign-symbols": "^1.0.0",
+ "is-extendable": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/split-string/node_modules/is-extendable": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-plain-object": "^2.0.4"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/sprintf-js": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+ "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==",
+ "dev": true,
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/squeak": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/squeak/-/squeak-1.3.0.tgz",
+ "integrity": "sha512-YQL1ulInM+ev8nXX7vfXsCsDh6IqXlrremc1hzi77776BtpWgYJUMto3UM05GSAaGzJgWekszjoKDrVNB5XG+A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "chalk": "^1.0.0",
+ "console-stream": "^0.1.1",
+ "lpad-align": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/sshpk": {
+ "version": "1.17.0",
+ "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz",
+ "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "asn1": "~0.2.3",
+ "assert-plus": "^1.0.0",
+ "bcrypt-pbkdf": "^1.0.0",
+ "dashdash": "^1.12.0",
+ "ecc-jsbn": "~0.1.1",
+ "getpass": "^0.1.1",
+ "jsbn": "~0.1.0",
+ "safer-buffer": "^2.0.2",
+ "tweetnacl": "~0.14.0"
+ },
+ "bin": {
+ "sshpk-conv": "bin/sshpk-conv",
+ "sshpk-sign": "bin/sshpk-sign",
+ "sshpk-verify": "bin/sshpk-verify"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/stable": {
+ "version": "0.1.8",
+ "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz",
+ "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/stack-trace": {
+ "version": "0.0.10",
+ "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz",
+ "integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/static-extend": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz",
+ "integrity": "sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "define-property": "^0.2.5",
+ "object-copy": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/statuses": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
+ "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/stealthy-require": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz",
+ "integrity": "sha512-ZnWpYnYugiOVEY5GkcuJK1io5V8QmNYChG62gSit9pQVGErXtrKuPC55ITaVSukmMta5qpMU7vqLt2Lnni4f/g==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/stream-exhaust": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/stream-exhaust/-/stream-exhaust-1.0.2.tgz",
+ "integrity": "sha512-b/qaq/GlBK5xaq1yrK9/zFcyRSTNxmcZwFLGSTG0mXgZl/4Z6GgiyYOXOvY7N3eEvFRAG1bkDRz5EPGSvPYQlw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/stream-shift": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz",
+ "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/stream-throttle": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/stream-throttle/-/stream-throttle-0.1.3.tgz",
+ "integrity": "sha512-889+B9vN9dq7/vLbGyuHeZ6/ctf5sNuGWsDy89uNxkFTAgzy0eK7+w5fL3KLNRTkLle7EgZGvHUphZW0Q26MnQ==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "commander": "^2.2.0",
+ "limiter": "^1.0.5"
+ },
+ "bin": {
+ "throttleproxy": "bin/throttleproxy.js"
+ },
+ "engines": {
+ "node": ">= 0.10.0"
+ }
+ },
+ "node_modules/streamx": {
+ "version": "2.12.5",
+ "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.12.5.tgz",
+ "integrity": "sha512-Y+nkFw57Z5JHT3zLlqFm3GccOy2FeYdUrrqita6Dd8kr/8enPn9GKa8IYf3/DmEKfZl/E2sWoSKUnd4qhonrgg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-fifo": "^1.0.0",
+ "queue-tick": "^1.0.0"
+ }
+ },
+ "node_modules/strict-uri-encode": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz",
+ "integrity": "sha512-R3f198pcvnB+5IpnBlRkphuE9n46WyVl8I39W/ZUTZLz4nqSP/oLYUrcnJrw462Ds8he4YKMov2efsTIw1BDGQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/string_decoder": {
+ "version": "0.10.31",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
+ "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/string-width/node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/string-width/node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/string.prototype.trimend": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz",
+ "integrity": "sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.4",
+ "es-abstract": "^1.20.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/string.prototype.trimstart": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz",
+ "integrity": "sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.4",
+ "es-abstract": "^1.20.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/strip-ansi": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+ "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/strip-ansi/node_modules/ansi-regex": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+ "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/strip-bom": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz",
+ "integrity": "sha512-kwrX1y7czp1E69n2ajbG65mIo9dqvJ+8aBQXOGVxqwvNbsXdFM6Lq37dLAY3mknUwru8CfcCbfOLL/gMo+fi3g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-utf8": "^0.2.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/strip-dirs": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/strip-dirs/-/strip-dirs-2.1.0.tgz",
+ "integrity": "sha512-JOCxOeKLm2CAS73y/U4ZeZPTkE+gNVCzKt7Eox84Iej1LT/2pTWYpZKJuxwQpvX1LiZb1xokNR7RLfuBAa7T3g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-natural-number": "^4.0.1"
+ }
+ },
+ "node_modules/strip-eof": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
+ "integrity": "sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/strip-final-newline": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
+ "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/strip-indent": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz",
+ "integrity": "sha512-I5iQq6aFMM62fBEAIB/hXzwJD6EEZ0xEGCX2t7oXqaKPIRgt4WruAQ285BISgdkP+HLGWyeGmNJcpIwFeRYRUA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "get-stdin": "^4.0.1"
+ },
+ "bin": {
+ "strip-indent": "cli.js"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/strip-json-comments": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
+ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/strip-outer": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz",
+ "integrity": "sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "escape-string-regexp": "^1.0.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/strnum": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz",
+ "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/stylehacks": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-4.0.3.tgz",
+ "integrity": "sha512-7GlLk9JwlElY4Y6a/rmbH2MhVlTyVmiJd1PfTCqFaIBEGMYNsrO/v3SeGTdhBThLg4Z+NbOk/qFMwCa+J+3p/g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "browserslist": "^4.0.0",
+ "postcss": "^7.0.0",
+ "postcss-selector-parser": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/sumchecker": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-3.0.1.tgz",
+ "integrity": "sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "debug": "^4.1.0"
+ },
+ "engines": {
+ "node": ">= 8.0"
+ }
+ },
+ "node_modules/supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/supports-color/node_modules/has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/supports-preserve-symlinks-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/sver-compat": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/sver-compat/-/sver-compat-1.5.0.tgz",
+ "integrity": "sha512-aFTHfmjwizMNlNE6dsGmoAM4lHjL0CyiobWaFiXWSlD7cIxshW422Nb8KbXCmR6z+0ZEPY+daXJrDyh/vuwTyg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es6-iterator": "^2.0.1",
+ "es6-symbol": "^3.1.1"
+ }
+ },
+ "node_modules/svgo": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.3.2.tgz",
+ "integrity": "sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "chalk": "^2.4.1",
+ "coa": "^2.0.2",
+ "css-select": "^2.0.0",
+ "css-select-base-adapter": "^0.1.1",
+ "css-tree": "1.0.0-alpha.37",
+ "csso": "^4.0.2",
+ "js-yaml": "^3.13.1",
+ "mkdirp": "~0.5.1",
+ "object.values": "^1.1.0",
+ "sax": "~1.2.4",
+ "stable": "^0.1.8",
+ "unquote": "~1.1.1",
+ "util.promisify": "~1.0.0"
+ },
+ "bin": {
+ "svgo": "bin/svgo"
+ },
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
+ "node_modules/svgo/node_modules/ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^1.9.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/svgo/node_modules/chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/symbol-observable": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.0.1.tgz",
+ "integrity": "sha512-Kb3PrPYz4HanVF1LVGuAdW6LoVgIwjUYJGzFe7NDrBLCN4lsV/5J0MFurV+ygS4bRVwrCEt2c7MQ1R2a72oJDw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/symbol-tree": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz",
+ "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/tapable": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz",
+ "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/tar-stream": {
+ "version": "1.6.2",
+ "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz",
+ "integrity": "sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "bl": "^1.0.0",
+ "buffer-alloc": "^1.2.0",
+ "end-of-stream": "^1.0.0",
+ "fs-constants": "^1.0.0",
+ "readable-stream": "^2.3.0",
+ "to-buffer": "^1.1.1",
+ "xtend": "^4.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/teex": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/teex/-/teex-1.0.1.tgz",
+ "integrity": "sha512-eYE6iEI62Ni1H8oIa7KlDU6uQBtqr4Eajni3wX7rpfXD8ysFx8z0+dri+KWEPWpBsxXfxu58x/0jvTVT1ekOSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "streamx": "^2.12.5"
+ }
+ },
+ "node_modules/temp-dir": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-1.0.0.tgz",
+ "integrity": "sha512-xZFXEGbG7SNC3itwBzI3RYjq/cEhBkx2hJuKGIUOcEULmkQExXiHat2z/qkISYsuR+IKumhEfKKbV5qXmhICFQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/tempfile": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/tempfile/-/tempfile-2.0.0.tgz",
+ "integrity": "sha512-ZOn6nJUgvgC09+doCEF3oB+r3ag7kUvlsXEGX069QRD60p+P3uP7XG9N2/at+EyIRGSN//ZY3LyEotA1YpmjuA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "temp-dir": "^1.0.0",
+ "uuid": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/ternary-stream": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/ternary-stream/-/ternary-stream-3.0.0.tgz",
+ "integrity": "sha512-oIzdi+UL/JdktkT+7KU5tSIQjj8pbShj3OASuvDEhm0NT5lppsm7aXWAmAq4/QMaBIyfuEcNLbAQA+HpaISobQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "duplexify": "^4.1.1",
+ "fork-stream": "^0.0.4",
+ "merge-stream": "^2.0.0",
+ "through2": "^3.0.1"
+ }
+ },
+ "node_modules/ternary-stream/node_modules/readable-stream": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
+ "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/ternary-stream/node_modules/string_decoder": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
+ "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "safe-buffer": "~5.2.0"
+ }
+ },
+ "node_modules/ternary-stream/node_modules/through2": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz",
+ "integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "inherits": "^2.0.4",
+ "readable-stream": "2 || 3"
+ }
+ },
+ "node_modules/terser": {
+ "version": "5.43.1",
+ "resolved": "https://registry.npmjs.org/terser/-/terser-5.43.1.tgz",
+ "integrity": "sha512-+6erLbBm0+LROX2sPXlUYx/ux5PyE9K/a92Wrt6oA+WDAoFTdpHE5tCYCI5PNzq2y8df4rA+QgHLJuR4jNymsg==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "@jridgewell/source-map": "^0.3.3",
+ "acorn": "^8.14.0",
+ "commander": "^2.20.0",
+ "source-map-support": "~0.5.20"
+ },
+ "bin": {
+ "terser": "bin/terser"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/terser-webpack-plugin": {
+ "version": "5.3.14",
+ "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.14.tgz",
+ "integrity": "sha512-vkZjpUjb6OMS7dhV+tILUW6BhpDR7P2L/aQSAv+Uwk+m8KATX9EccViHTJR2qDtACKPIYndLGCyl3FMo+r2LMw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/trace-mapping": "^0.3.25",
+ "jest-worker": "^27.4.5",
+ "schema-utils": "^4.3.0",
+ "serialize-javascript": "^6.0.2",
+ "terser": "^5.31.1"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ },
+ "peerDependencies": {
+ "webpack": "^5.1.0"
+ },
+ "peerDependenciesMeta": {
+ "@swc/core": {
+ "optional": true
+ },
+ "esbuild": {
+ "optional": true
+ },
+ "uglify-js": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/terser-webpack-plugin/node_modules/ajv": {
+ "version": "8.17.1",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
+ "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.3",
+ "fast-uri": "^3.0.1",
+ "json-schema-traverse": "^1.0.0",
+ "require-from-string": "^2.0.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/terser-webpack-plugin/node_modules/ajv-keywords": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz",
+ "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.3"
+ },
+ "peerDependencies": {
+ "ajv": "^8.8.2"
+ }
+ },
+ "node_modules/terser-webpack-plugin/node_modules/json-schema-traverse": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/terser-webpack-plugin/node_modules/schema-utils": {
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.2.tgz",
+ "integrity": "sha512-Gn/JaSk/Mt9gYubxTtSn/QCV4em9mpAPiR1rqy/Ocu19u/G9J5WWdNoUT4SiV6mFC3y6cxyFcFwdzPM3FgxGAQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/json-schema": "^7.0.9",
+ "ajv": "^8.9.0",
+ "ajv-formats": "^2.1.1",
+ "ajv-keywords": "^5.1.0"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ }
+ },
+ "node_modules/tfunk": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/tfunk/-/tfunk-4.0.0.tgz",
+ "integrity": "sha512-eJQ0dGfDIzWNiFNYFVjJ+Ezl/GmwHaFTBTjrtqNPW0S7cuVDBrZrmzUz6VkMeCR4DZFqhd4YtLwsw3i2wYHswQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "chalk": "^1.1.3",
+ "dlv": "^1.1.3"
+ }
+ },
+ "node_modules/through": {
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
+ "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/through2": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz",
+ "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "readable-stream": "~2.3.6",
+ "xtend": "~4.0.1"
+ }
+ },
+ "node_modules/through2-concurrent": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/through2-concurrent/-/through2-concurrent-2.0.0.tgz",
+ "integrity": "sha512-R5/jLkfMvdmDD+seLwN7vB+mhbqzWop5fAjx5IX8/yQq7VhBhzDmhXgaHAOnhnWkCpRMM7gToYHycB0CS/pd+A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "through2": "^2.0.0"
+ }
+ },
+ "node_modules/through2-filter": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-3.0.0.tgz",
+ "integrity": "sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "through2": "~2.0.0",
+ "xtend": "~4.0.0"
+ }
+ },
+ "node_modules/time-stamp": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz",
+ "integrity": "sha512-gLCeArryy2yNTRzTGKbZbloctj64jkZ57hj5zdraXue6aFgd6PmvVtEyiUU+hvU0v7q08oVv8r8ev0tRo6bvgw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/timed-out": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz",
+ "integrity": "sha512-G7r3AhovYtr5YKOWQkta8RKAPb+J9IsO4uVmzjl8AZwfhs8UcUwTiD6gcJYSgOtzyjvQKrKYn41syHbUWMkafA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/timsort": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz",
+ "integrity": "sha512-qsdtZH+vMoCARQtyod4imc2nIJwg9Cc7lPRrw9CzF8ZKR0khdr8+2nX80PBhET3tcyTtJDxAffGh2rXH4tyU8A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/tiny-lr": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/tiny-lr/-/tiny-lr-0.1.4.tgz",
+ "integrity": "sha512-whc75HNnTqUGFBbpsbrpFgNaz5yI/D8QkhFdJlc/sAZsVsYX6o9Dj+z2NPoRqCNILX9yDJZJZyYoNAsyRobLbQ==",
+ "dev": true,
+ "dependencies": {
+ "body-parser": "~1.8.0",
+ "debug": "~0.8.1",
+ "faye-websocket": "~0.7.2",
+ "parseurl": "~1.3.0",
+ "qs": "~2.2.3"
+ }
+ },
+ "node_modules/tiny-lr/node_modules/debug": {
+ "version": "0.8.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-0.8.1.tgz",
+ "integrity": "sha512-HlXEJm99YsRjLJ8xmuz0Lq8YUwrv7hAJkTEr6/Em3sUlSUNl0UdFA+1SrY4fnykeq1FVkUEUtwRGHs9VvlYbGA==",
+ "dev": true,
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/tiny-lr/node_modules/qs": {
+ "version": "2.2.5",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-2.2.5.tgz",
+ "integrity": "sha512-z/IJSH2F7g7FbYokpSQqLcMAk0VXtR8boQS1EqLxeB7T5xcFK/RuGY0PZbPtF9r151X+a/ZaRauCOok4Xiyjmg==",
+ "dev": true
+ },
+ "node_modules/to-absolute-glob": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz",
+ "integrity": "sha512-rtwLUQEwT8ZeKQbyFJyomBRYXyE16U5VKuy0ftxLMK/PZb2fkOsg5r9kHdauuVDbsNdIBoC/HCthpidamQFXYA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-absolute": "^1.0.0",
+ "is-negated-glob": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/to-buffer": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz",
+ "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/to-object-path": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz",
+ "integrity": "sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "kind-of": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/to-regex": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz",
+ "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "define-property": "^2.0.2",
+ "extend-shallow": "^3.0.2",
+ "regex-not": "^1.0.2",
+ "safe-regex": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-number": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=8.0"
+ }
+ },
+ "node_modules/to-regex-range/node_modules/is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.12.0"
+ }
+ },
+ "node_modules/to-regex/node_modules/define-property": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz",
+ "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-descriptor": "^1.0.2",
+ "isobject": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/to-regex/node_modules/extend-shallow": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
+ "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "assign-symbols": "^1.0.0",
+ "is-extendable": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/to-regex/node_modules/is-extendable": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-plain-object": "^2.0.4"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/to-through": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/to-through/-/to-through-2.0.0.tgz",
+ "integrity": "sha512-+QIz37Ly7acM4EMdw2PRN389OneM5+d844tirkGp4dPKzI5OE72V9OsbFp+CIYJDahZ41ZV05hNtcPAQUAm9/Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "through2": "^2.0.3"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/toidentifier": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
+ "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.6"
+ }
+ },
+ "node_modules/tough-cookie": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
+ "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "psl": "^1.1.28",
+ "punycode": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.8"
+ }
+ },
+ "node_modules/tr46": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz",
+ "integrity": "sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "punycode": "^2.1.0"
+ }
+ },
+ "node_modules/trim-newlines": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz",
+ "integrity": "sha512-Nm4cF79FhSTzrLKGDMi3I4utBtFv8qKy4sq1enftf2gMdpqI8oVQTAfySkTz5r49giVzDj88SVZXP4CeYQwjaw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/trim-repeated": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz",
+ "integrity": "sha512-pkonvlKk8/ZuR0D5tLW8ljt5I8kmxp2XKymhepUeOdCEfKpZaktSArkLHZt76OB1ZvO9bssUsDty4SWhLvZpLg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "escape-string-regexp": "^1.0.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ts-api-utils": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz",
+ "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18.12"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.8.4"
+ }
+ },
+ "node_modules/ts-loader": {
+ "version": "9.5.2",
+ "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.5.2.tgz",
+ "integrity": "sha512-Qo4piXvOTWcMGIgRiuFa6nHNm+54HbYaZCKqc9eeZCLRy3XqafQgwX2F7mofrbJG3g7EEb+lkiR+z2Lic2s3Zw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "chalk": "^4.1.0",
+ "enhanced-resolve": "^5.0.0",
+ "micromatch": "^4.0.0",
+ "semver": "^7.3.4",
+ "source-map": "^0.7.4"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "peerDependencies": {
+ "typescript": "*",
+ "webpack": "^5.0.0"
+ }
+ },
+ "node_modules/ts-loader/node_modules/braces": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+ "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fill-range": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ts-loader/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/ts-loader/node_modules/fill-range": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+ "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "to-regex-range": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ts-loader/node_modules/micromatch": {
+ "version": "4.0.5",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
+ "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "braces": "^3.0.2",
+ "picomatch": "^2.3.1"
+ },
+ "engines": {
+ "node": ">=8.6"
+ }
+ },
+ "node_modules/ts-loader/node_modules/source-map": {
+ "version": "0.7.4",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz",
+ "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/ts-loader/node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/tunnel-agent": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
+ "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "safe-buffer": "^5.0.1"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/tweetnacl": {
+ "version": "0.14.5",
+ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
+ "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==",
+ "dev": true,
+ "license": "Unlicense"
+ },
+ "node_modules/type": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz",
+ "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/type-check": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
+ "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prelude-ls": "~1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/type-fest": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.5.2.tgz",
+ "integrity": "sha512-DWkS49EQKVX//Tbupb9TFa19c7+MK1XmzkrZUR8TAktmE/DizXoaoJV6TZ/tSIPXipqNiRI6CyAe7x69Jb6RSw==",
+ "dev": true,
+ "license": "(MIT OR CC0-1.0)",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/type-is": {
+ "version": "1.5.7",
+ "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.5.7.tgz",
+ "integrity": "sha512-of68V0oUmVH4thGc1cLR3sKdICPsaL7kzpYc7FX1pcagY4eIllhyMqQcoOq289f+xj2orm8oPWwsCwxiCgVJbQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "media-typer": "0.3.0",
+ "mime-types": "~2.0.9"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/type-is/node_modules/mime-db": {
+ "version": "1.12.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.12.0.tgz",
+ "integrity": "sha512-5aMAW7I4jZoZB27fXRuekqc4DVvJ7+hM8UcWrNj2mqibE54gXgPSonBYBdQW5hyaVNGmiYjY0ZMqn9fBefWYvA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/type-is/node_modules/mime-types": {
+ "version": "2.0.14",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.0.14.tgz",
+ "integrity": "sha512-2ZHUEstNkIf2oTWgtODr6X0Cc4Ns/RN/hktdozndiEhhAC2wxXejF1FH0XLHTEImE9h6gr/tcnr3YOnSGsxc7Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "mime-db": "~1.12.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/typedarray": {
+ "version": "0.0.6",
+ "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
+ "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/typescript": {
+ "version": "5.8.2",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.2.tgz",
+ "integrity": "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "bin": {
+ "tsc": "bin/tsc",
+ "tsserver": "bin/tsserver"
+ },
+ "engines": {
+ "node": ">=14.17"
+ }
+ },
+ "node_modules/typescript-eslint": {
+ "version": "8.29.1",
+ "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.29.1.tgz",
+ "integrity": "sha512-f8cDkvndhbQMPcysk6CUSGBWV+g1utqdn71P5YKwMumVMOG/5k7cHq0KyG4O52nB0oKS4aN2Tp5+wB4APJGC+w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/eslint-plugin": "8.29.1",
+ "@typescript-eslint/parser": "8.29.1",
+ "@typescript-eslint/utils": "8.29.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^8.57.0 || ^9.0.0",
+ "typescript": ">=4.8.4 <5.9.0"
+ }
+ },
+ "node_modules/ua-parser-js": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.2.tgz",
+ "integrity": "sha512-00y/AXhx0/SsnI51fTc0rLRmafiGOM4/O+ny10Ps7f+j/b8p/ZY11ytMgznXkOVo4GQ+KwQG5UQLkLGirsACRg==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/ua-parser-js"
+ },
+ {
+ "type": "paypal",
+ "url": "https://paypal.me/faisalman"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/uglify-js": {
+ "version": "3.4.10",
+ "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.10.tgz",
+ "integrity": "sha512-Y2VsbPVs0FIshJztycsO2SfPk7/KAF/T72qzv9u5EpQ4kB2hQoHlhNQTsNyy6ul7lQtqJN/AoWeS23OzEiEFxw==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "commander": "~2.19.0",
+ "source-map": "~0.6.1"
+ },
+ "bin": {
+ "uglifyjs": "bin/uglifyjs"
+ },
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/uglify-js/node_modules/commander": {
+ "version": "2.19.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz",
+ "integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/unbox-primitive": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz",
+ "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "has-bigints": "^1.0.2",
+ "has-symbols": "^1.0.3",
+ "which-boxed-primitive": "^1.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/unbzip2-stream": {
+ "version": "1.4.3",
+ "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz",
+ "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "buffer": "^5.2.1",
+ "through": "^2.3.8"
+ }
+ },
+ "node_modules/unc-path-regex": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz",
+ "integrity": "sha512-eXL4nmJT7oCpkZsHZUOJo8hcX3GbsiDOa0Qu9F646fi8dT3XuSVopVqAcEiVzSKKH7UoDti23wNX3qGFxcW5Qg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/underscore": {
+ "version": "1.8.3",
+ "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz",
+ "integrity": "sha512-5WsVTFcH1ut/kkhAaHf4PVgI8c7++GiVcpCGxPouI6ZVjsqPnSDf8h/8HtVqc0t4fzRXwnMK70EcZeAs3PIddg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/undertaker": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/undertaker/-/undertaker-1.3.0.tgz",
+ "integrity": "sha512-/RXwi5m/Mu3H6IHQGww3GNt1PNXlbeCuclF2QYR14L/2CHPz3DFZkvB5hZ0N/QUkiXWCACML2jXViIQEQc2MLg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "arr-flatten": "^1.0.1",
+ "arr-map": "^2.0.0",
+ "bach": "^1.0.0",
+ "collection-map": "^1.0.0",
+ "es6-weak-map": "^2.0.1",
+ "fast-levenshtein": "^1.0.0",
+ "last-run": "^1.1.0",
+ "object.defaults": "^1.0.0",
+ "object.reduce": "^1.0.0",
+ "undertaker-registry": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/undertaker-registry": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/undertaker-registry/-/undertaker-registry-1.0.1.tgz",
+ "integrity": "sha512-UR1khWeAjugW3548EfQmL9Z7pGMlBgXteQpr1IZeZBtnkCJQJIJ1Scj0mb9wQaPvUZ9Q17XqW6TIaPchJkyfqw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/undertaker/node_modules/fast-levenshtein": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-1.1.4.tgz",
+ "integrity": "sha512-Ia0sQNrMPXXkqVFt6w6M1n1oKo3NfKs+mvaV811Jwir7vAk9a6PVV9VPYf6X3BU97QiLEmuW3uXH9u87zDFfdw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/undici-types": {
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
+ "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/union-value": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz",
+ "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "arr-union": "^3.1.0",
+ "get-value": "^2.0.6",
+ "is-extendable": "^0.1.1",
+ "set-value": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/uniq": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz",
+ "integrity": "sha512-Gw+zz50YNKPDKXs+9d+aKAjVwpjNwqzvNpLigIruT4HA9lMZNdMqs9x07kKHB/L9WRzqp4+DlTU5s4wG2esdoA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/uniqs": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/uniqs/-/uniqs-2.0.0.tgz",
+ "integrity": "sha512-mZdDpf3vBV5Efh29kMw5tXoup/buMgxLzOt/XKFKcVmi+15ManNQWr6HfZ2aiZTYlYixbdNJ0KFmIZIv52tHSQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/unique-stream": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.3.1.tgz",
+ "integrity": "sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "json-stable-stringify-without-jsonify": "^1.0.1",
+ "through2-filter": "^3.0.0"
+ }
+ },
+ "node_modules/universalify": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
+ "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4.0.0"
+ }
+ },
+ "node_modules/unpipe": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
+ "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/unquote": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/unquote/-/unquote-1.1.1.tgz",
+ "integrity": "sha512-vRCqFv6UhXpWxZPyGDh/F3ZpNv8/qo7w6iufLpQg9aKnQ71qM4B5KiI7Mia9COcjEhrO9LueHpMYjYzsWH3OIg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/unset-value": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz",
+ "integrity": "sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-value": "^0.3.1",
+ "isobject": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/unset-value/node_modules/has-value": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz",
+ "integrity": "sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "get-value": "^2.0.3",
+ "has-values": "^0.1.4",
+ "isobject": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/unset-value/node_modules/has-value/node_modules/isobject": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
+ "integrity": "sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "isarray": "1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/unset-value/node_modules/has-values": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz",
+ "integrity": "sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/unset-value/node_modules/isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/upath": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz",
+ "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4",
+ "yarn": "*"
+ }
+ },
+ "node_modules/update-browserslist-db": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz",
+ "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "escalade": "^3.2.0",
+ "picocolors": "^1.1.1"
+ },
+ "bin": {
+ "update-browserslist-db": "cli.js"
+ },
+ "peerDependencies": {
+ "browserslist": ">= 4.21.0"
+ }
+ },
+ "node_modules/update-browserslist-db/node_modules/picocolors": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
+ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/upper-case": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz",
+ "integrity": "sha512-WRbjgmYzgXkCV7zNVpy5YgrHgbBv126rMALQQMrmzOVC4GM2waQ9x7xtm8VU+1yF2kWyPzI9zbZ48n4vSxwfSA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/uri-js": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
+ "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "punycode": "^2.1.0"
+ }
+ },
+ "node_modules/urix": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz",
+ "integrity": "sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/url-parse-lax": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz",
+ "integrity": "sha512-NjFKA0DidqPa5ciFcSrXnAltTtzz84ogy+NebPvfEgAck0+TNg4UJ4IN+fB7zRZfbgUf0syOo9MDxFkDSMuFaQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prepend-http": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/url-to-options": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/url-to-options/-/url-to-options-1.0.1.tgz",
+ "integrity": "sha512-0kQLIzG4fdk/G5NONku64rSH/x32NOA39LVQqlK8Le6lvTF6GGRJpqaQFGgU+CLwySIqBSMdwYM0sYcW9f6P4A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/use": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
+ "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/util.promisify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.1.tgz",
+ "integrity": "sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.17.2",
+ "has-symbols": "^1.0.1",
+ "object.getownpropertydescriptors": "^2.1.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/utils-merge": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
+ "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4.0"
+ }
+ },
+ "node_modules/uuid": {
+ "version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
+ "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "uuid": "bin/uuid"
+ }
+ },
+ "node_modules/v8flags": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.2.0.tgz",
+ "integrity": "sha512-mH8etigqMfiGWdeXpaaqGfs6BndypxusHHcv2qSHyZkGEznCd/qAXCWWRzeowtL54147cktFOC4P5y+kl8d8Jg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "homedir-polyfill": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/validate-npm-package-license": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
+ "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "spdx-correct": "^3.0.0",
+ "spdx-expression-parse": "^3.0.0"
+ }
+ },
+ "node_modules/value-or-function": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/value-or-function/-/value-or-function-3.0.0.tgz",
+ "integrity": "sha512-jdBB2FrWvQC/pnPtIqcLsMaQgjhdb6B7tk1MMyTKapox+tQZbdRP4uLxu/JY0t7fbfDCUMnuelzEYv5GsxHhdg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/vary": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
+ "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/vendors": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.4.tgz",
+ "integrity": "sha512-/juG65kTL4Cy2su4P8HjtkTxk6VmJDiOPBufWniqQ6wknac6jNiXS9vU+hO3wgusiyqWlzTbVHi0dyJqRONg3w==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/verror": {
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
+ "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==",
+ "dev": true,
+ "engines": [
+ "node >=0.6.0"
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "assert-plus": "^1.0.0",
+ "core-util-is": "1.0.2",
+ "extsprintf": "^1.2.0"
+ }
+ },
+ "node_modules/verror/node_modules/core-util-is": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
+ "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/verror/node_modules/extsprintf": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.4.1.tgz",
+ "integrity": "sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA==",
+ "dev": true,
+ "engines": [
+ "node >=0.6.0"
+ ],
+ "license": "MIT"
+ },
+ "node_modules/vinyl": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.1.tgz",
+ "integrity": "sha512-LII3bXRFBZLlezoG5FfZVcXflZgWP/4dCwKtxd5ky9+LOtM4CS3bIRQsmR1KMnMW07jpE8fqR2lcxPZ+8sJIcw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "clone": "^2.1.1",
+ "clone-buffer": "^1.0.0",
+ "clone-stats": "^1.0.0",
+ "cloneable-readable": "^1.0.0",
+ "remove-trailing-separator": "^1.0.1",
+ "replace-ext": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/vinyl-fs": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-3.0.3.tgz",
+ "integrity": "sha512-vIu34EkyNyJxmP0jscNzWBSygh7VWhqun6RmqVfXePrOwi9lhvRs//dOaGOTRUQr4tx7/zd26Tk5WeSVZitgng==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fs-mkdirp-stream": "^1.0.0",
+ "glob-stream": "^6.1.0",
+ "graceful-fs": "^4.0.0",
+ "is-valid-glob": "^1.0.0",
+ "lazystream": "^1.0.0",
+ "lead": "^1.0.0",
+ "object.assign": "^4.0.4",
+ "pumpify": "^1.3.5",
+ "readable-stream": "^2.3.3",
+ "remove-bom-buffer": "^3.0.0",
+ "remove-bom-stream": "^1.2.0",
+ "resolve-options": "^1.1.0",
+ "through2": "^2.0.0",
+ "to-through": "^2.0.0",
+ "value-or-function": "^3.0.0",
+ "vinyl": "^2.0.0",
+ "vinyl-sourcemap": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/vinyl-sourcemap": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/vinyl-sourcemap/-/vinyl-sourcemap-1.1.0.tgz",
+ "integrity": "sha512-NiibMgt6VJGJmyw7vtzhctDcfKch4e4n9TBeoWlirb7FMg9/1Ov9k+A5ZRAtywBpRPiyECvQRQllYM8dECegVA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "append-buffer": "^1.0.2",
+ "convert-source-map": "^1.5.0",
+ "graceful-fs": "^4.1.6",
+ "normalize-path": "^2.1.1",
+ "now-and-later": "^2.0.0",
+ "remove-bom-buffer": "^3.0.0",
+ "vinyl": "^2.0.0"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/vinyl-sourcemap/node_modules/normalize-path": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz",
+ "integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "remove-trailing-separator": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/vinyl-sourcemaps-apply": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/vinyl-sourcemaps-apply/-/vinyl-sourcemaps-apply-0.2.1.tgz",
+ "integrity": "sha512-+oDh3KYZBoZC8hfocrbrxbLUeaYtQK7J5WU5Br9VqWqmCll3tFJqKp97GC9GmMsVIL0qnx2DgEDVxdo5EZ5sSw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "source-map": "^0.5.1"
+ }
+ },
+ "node_modules/vinyl-sourcemaps-apply/node_modules/source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/w3c-hr-time": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz",
+ "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "browser-process-hrtime": "^1.0.0"
+ }
+ },
+ "node_modules/watch": {
+ "version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/watch/-/watch-0.11.0.tgz",
+ "integrity": "sha512-kfWV9VP0kzdOQzouKDEXdWFssokWv7Mat7cnB4ixI3SjJN2UW3RK4x6yrRF+Zq9kc3mfHvKjAvLnyENGTxE9BA==",
+ "dev": true,
+ "engines": [
+ "node >=0.1.95"
+ ]
+ },
+ "node_modules/watchpack": {
+ "version": "2.4.4",
+ "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.4.tgz",
+ "integrity": "sha512-c5EGNOiyxxV5qmTtAB7rbiXxi1ooX1pQKMLX/MIabJjRA0SJBQOjKF+KSVfHkr9U1cADPon0mRiVe/riyaiDUA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "glob-to-regexp": "^0.4.1",
+ "graceful-fs": "^4.1.2"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/webidl-conversions": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz",
+ "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==",
+ "dev": true,
+ "license": "BSD-2-Clause"
+ },
+ "node_modules/webpack": {
+ "version": "5.99.9",
+ "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.99.9.tgz",
+ "integrity": "sha512-brOPwM3JnmOa+7kd3NsmOUOwbDAj8FT9xDsG3IW0MgbN9yZV7Oi/s/+MNQ/EcSMqw7qfoRyXPoeEWT8zLVdVGg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/eslint-scope": "^3.7.7",
+ "@types/estree": "^1.0.6",
+ "@types/json-schema": "^7.0.15",
+ "@webassemblyjs/ast": "^1.14.1",
+ "@webassemblyjs/wasm-edit": "^1.14.1",
+ "@webassemblyjs/wasm-parser": "^1.14.1",
+ "acorn": "^8.14.0",
+ "browserslist": "^4.24.0",
+ "chrome-trace-event": "^1.0.2",
+ "enhanced-resolve": "^5.17.1",
+ "es-module-lexer": "^1.2.1",
+ "eslint-scope": "5.1.1",
+ "events": "^3.2.0",
+ "glob-to-regexp": "^0.4.1",
+ "graceful-fs": "^4.2.11",
+ "json-parse-even-better-errors": "^2.3.1",
+ "loader-runner": "^4.2.0",
+ "mime-types": "^2.1.27",
+ "neo-async": "^2.6.2",
+ "schema-utils": "^4.3.2",
+ "tapable": "^2.1.1",
+ "terser-webpack-plugin": "^5.3.11",
+ "watchpack": "^2.4.1",
+ "webpack-sources": "^3.2.3"
+ },
+ "bin": {
+ "webpack": "bin/webpack.js"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ },
+ "peerDependenciesMeta": {
+ "webpack-cli": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/webpack-deadcode-plugin": {
+ "version": "0.1.17",
+ "resolved": "https://registry.npmjs.org/webpack-deadcode-plugin/-/webpack-deadcode-plugin-0.1.17.tgz",
+ "integrity": "sha512-m57+nCO3wYa/QEJiJNUTE2OpRZj6DY6dbf4G4h9rFyNiq0g1XBH05O09UAJoXyqedv7Dfvqp+YeratTDRuqQuA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "chalk": "^3.0.0",
+ "fast-glob": "^3.1.1"
+ },
+ "engines": {
+ "node": ">=6.11.5"
+ },
+ "peerDependencies": {
+ "webpack": "> 3"
+ }
+ },
+ "node_modules/webpack-deadcode-plugin/node_modules/chalk": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
+ "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/webpack-deadcode-plugin/node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/webpack-sources": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz",
+ "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/webpack-stream": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/webpack-stream/-/webpack-stream-7.0.0.tgz",
+ "integrity": "sha512-XoAQTHyCaYMo6TS7Atv1HYhtmBgKiVLONJbzLBl2V3eibXQ2IT/MCRM841RW/r3vToKD5ivrTJFWgd/ghoxoRg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fancy-log": "^1.3.3",
+ "lodash.clone": "^4.3.2",
+ "lodash.some": "^4.2.2",
+ "memory-fs": "^0.5.0",
+ "plugin-error": "^1.0.1",
+ "supports-color": "^8.1.1",
+ "through": "^2.3.8",
+ "vinyl": "^2.2.1"
+ },
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "peerDependencies": {
+ "webpack": "^5.21.2"
+ }
+ },
+ "node_modules/webpack-stream/node_modules/supports-color": {
+ "version": "8.1.1",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
+ "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/supports-color?sponsor=1"
+ }
+ },
+ "node_modules/webpack-strip-block": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/webpack-strip-block/-/webpack-strip-block-0.2.0.tgz",
+ "integrity": "sha512-SX0Qir0bJ94gyqyqAjoH1h72sHngq2onR8pA1ldWNNisaU+QCMJBvK2K//zfStUHcqqkWYYoyMAqiPAj0CXm1g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "loader-utils": "^1.1.0"
+ },
+ "peerDependencies": {
+ "webpack": ">=2.2.0"
+ }
+ },
+ "node_modules/webpack/node_modules/ajv": {
+ "version": "8.17.1",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
+ "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.3",
+ "fast-uri": "^3.0.1",
+ "json-schema-traverse": "^1.0.0",
+ "require-from-string": "^2.0.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/webpack/node_modules/ajv-keywords": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz",
+ "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.3"
+ },
+ "peerDependencies": {
+ "ajv": "^8.8.2"
+ }
+ },
+ "node_modules/webpack/node_modules/json-schema-traverse": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/webpack/node_modules/schema-utils": {
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.2.tgz",
+ "integrity": "sha512-Gn/JaSk/Mt9gYubxTtSn/QCV4em9mpAPiR1rqy/Ocu19u/G9J5WWdNoUT4SiV6mFC3y6cxyFcFwdzPM3FgxGAQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/json-schema": "^7.0.9",
+ "ajv": "^8.9.0",
+ "ajv-formats": "^2.1.1",
+ "ajv-keywords": "^5.1.0"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ }
+ },
+ "node_modules/websocket-driver": {
+ "version": "0.7.4",
+ "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz",
+ "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "http-parser-js": ">=0.5.1",
+ "safe-buffer": ">=5.1.0",
+ "websocket-extensions": ">=0.1.1"
+ },
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/websocket-extensions": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz",
+ "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/whatwg-encoding": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz",
+ "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "iconv-lite": "0.4.24"
+ }
+ },
+ "node_modules/whatwg-mimetype": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz",
+ "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/whatwg-url": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz",
+ "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "lodash.sortby": "^4.7.0",
+ "tr46": "^1.0.1",
+ "webidl-conversions": "^4.0.2"
+ }
+ },
+ "node_modules/which": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
+ "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "which": "bin/which"
+ }
+ },
+ "node_modules/which-boxed-primitive": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz",
+ "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-bigint": "^1.0.1",
+ "is-boolean-object": "^1.1.0",
+ "is-number-object": "^1.0.4",
+ "is-string": "^1.0.5",
+ "is-symbol": "^1.0.3"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/which-module": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz",
+ "integrity": "sha512-F6+WgncZi/mJDrammbTuHe1q0R5hOXv/mBaiNA2TCNT/LTHusX0V+CJnj9XT8ki5ln2UZyyddDgHfCzyrOH7MQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/winston": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/winston/-/winston-1.0.2.tgz",
+ "integrity": "sha512-BLxJH3KCgJ2paj2xKYTQLpxdKr9URPDDDLJnRVcbud7izT+m8Xzt5Rod6mnNgEcfT0fRvhEy2Cj3cEnnQpa6qA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "async": "~1.0.0",
+ "colors": "1.0.x",
+ "cycle": "1.0.x",
+ "eyes": "0.1.x",
+ "isstream": "0.1.x",
+ "pkginfo": "0.3.x",
+ "stack-trace": "0.0.x"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/winston/node_modules/async": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/async/-/async-1.0.0.tgz",
+ "integrity": "sha512-5mO7DX4CbJzp9zjaFXusQQ4tzKJARjNB1Ih1pVBi8wkbmXy/xzIDgEMXxWePLzt2OdFwaxfneIlT1nCiXubrPQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/word-wrap": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
+ "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/wordwrap": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz",
+ "integrity": "sha512-1tMA907+V4QmxV7dbRvb4/8MaRALK6q9Abid3ndMYnbyo8piisCmeONVqVSXqQA3KaP4SLt5b7ud6E2sqP8TFw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/wrap-ansi": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/wrap-ansi/node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/wrap-ansi/node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/ws": {
+ "version": "8.2.3",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz",
+ "integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10.0.0"
+ },
+ "peerDependencies": {
+ "bufferutil": "^4.0.1",
+ "utf-8-validate": "^5.0.2"
+ },
+ "peerDependenciesMeta": {
+ "bufferutil": {
+ "optional": true
+ },
+ "utf-8-validate": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/xml-name-validator": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz",
+ "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==",
+ "dev": true,
+ "license": "Apache-2.0"
+ },
+ "node_modules/xmlbuilder": {
+ "version": "15.1.1",
+ "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz",
+ "integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8.0"
+ }
+ },
+ "node_modules/xmlchars": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz",
+ "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/xmlhttprequest-ssl": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz",
+ "integrity": "sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/xtend": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
+ "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.4"
+ }
+ },
+ "node_modules/y18n": {
+ "version": "5.0.8",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
+ "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/yaml": {
+ "version": "1.10.2",
+ "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz",
+ "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/yargs": {
+ "version": "17.6.2",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz",
+ "integrity": "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cliui": "^8.0.1",
+ "escalade": "^3.1.1",
+ "get-caller-file": "^2.0.5",
+ "require-directory": "^2.1.1",
+ "string-width": "^4.2.3",
+ "y18n": "^5.0.5",
+ "yargs-parser": "^21.1.1"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/yargs-parser": {
+ "version": "20.2.9",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
+ "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/yargs/node_modules/yargs-parser": {
+ "version": "21.1.1",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
+ "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/yauzl": {
+ "version": "2.10.0",
+ "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz",
+ "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "buffer-crc32": "~0.2.3",
+ "fd-slicer": "~1.1.0"
+ }
+ },
+ "node_modules/yocto-queue": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
+ "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ }
+ }
+}
diff --git a/package.json b/package.json
index e7e4c2e9..a54d3278 100644
--- a/package.json
+++ b/package.json
@@ -1,106 +1,80 @@
-{
- "name": "shapez.io",
- "version": "1.0.0",
- "main": "index.js",
- "repository": "https://github.com/tobspr-games/shapez.io",
- "author": "tobspr Games ",
- "license": "MIT",
- "private": true,
- "scripts": {
- "dev": "cd gulp && yarn gulp",
- "devStandalone": "cd gulp && yarn gulp serve.standalone-steam",
- "tslint": "cd src/js && tsc",
- "lint": "eslint src/js",
- "prettier-all": "prettier --write src/**/*.* && prettier --write gulp/**/*.*",
- "publishOnItchWindows": "butler push tmp_standalone_files/shapez.io-standalone-win32-x64 tobspr/shapezio:windows --userversion-file version",
- "publishOnItchLinux": "butler push tmp_standalone_files/shapez.io-standalone-linux-x64 tobspr/shapezio:linux --userversion-file version",
- "publishOnItch": "yarn publishOnItchWindows && yarn publishOnItchLinux",
- "publishOnSteam": "cd gulp/steampipe && ./upload.bat",
- "publishStandalone": "yarn publishOnItch && yarn publishOnSteam",
- "publishWeb": "cd gulp && yarn main.deploy.prod",
- "publish": "yarn publishStandalone && yarn publishWeb",
- "syncTranslations": "node sync-translations.js",
- "buildTypes": "tsc src/js/application.js --declaration --allowJs --emitDeclarationOnly --skipLibCheck --out types.js"
- },
- "dependencies": {
- "@babel/core": "^7.5.4",
- "@babel/plugin-transform-block-scoping": "^7.4.4",
- "@babel/plugin-transform-classes": "^7.5.5",
- "@babel/preset-env": "^7.5.4",
- "@nastyox/rando.js": "^2.0.5",
- "@types/cordova": "^0.0.34",
- "@types/filesystem": "^0.0.29",
- "ajv": "^6.10.2",
- "babel-core": "^6.26.3",
- "babel-loader": "^8.0.4",
- "circular-dependency-plugin": "^5.0.2",
- "circular-json": "^0.5.9",
- "clipboard-copy": "^3.1.0",
- "colors": "^1.3.3",
- "core-js": "3",
- "crc": "^3.8.0",
- "cssnano-preset-advanced": "^4.0.7",
- "debounce-promise": "^3.1.2",
- "email-validator": "^2.0.4",
- "eslint": "7.1.0",
- "fastdom": "^1.0.8",
- "flatted": "^2.0.1",
- "howler": "^2.1.2",
- "html-loader": "^0.5.5",
- "ignore-loader": "^0.1.2",
- "logrocket": "^1.0.7",
- "lz-string": "^1.4.4",
- "markdown-loader": "^4.0.0",
- "match-all": "^1.2.5",
- "phonegap-plugin-mobile-accessibility": "^1.0.5",
- "postcss": ">=5.0.0",
- "promise-polyfill": "^8.1.0",
- "query-string": "^6.8.1",
- "rusha": "^0.8.13",
- "semver": "^7.3.5",
- "strictdom": "^1.0.1",
- "string-replace-webpack-plugin": "^0.1.3",
- "terser-webpack-plugin": "^1.1.0",
- "typescript": "3.9.3",
- "uglify-template-string-loader": "^1.1.0",
- "unused-files-webpack-plugin": "^3.4.0",
- "webpack": "^4.43.0",
- "webpack-bundle-analyzer": "^3.0.3",
- "webpack-cli": "^3.1.0",
- "webpack-deep-scope-plugin": "^1.6.0",
- "webpack-plugin-replace": "^1.1.1",
- "webpack-strip-block": "^0.2.0",
- "whatwg-fetch": "^3.0.0",
- "worker-loader": "^2.0.0",
- "yaml": "^1.10.0",
- "yawn-yaml": "^1.5.0"
- },
- "devDependencies": {
- "@octokit/rest": "^18.0.6",
- "@typescript-eslint/eslint-plugin": "3.0.1",
- "@typescript-eslint/parser": "3.0.1",
- "autoprefixer": "^9.4.3",
- "babel-plugin-closure-elimination": "^1.3.0",
- "babel-plugin-console-source": "^2.0.2",
- "babel-plugin-danger-remove-unused-import": "^1.1.2",
- "css-mqpacker": "^7.0.0",
- "cssnano": "^4.1.10",
- "eslint-config-prettier": "6.11.0",
- "eslint-plugin-prettier": "3.1.3",
- "faster.js": "^1.1.0",
- "glob": "^7.1.3",
- "imagemin-mozjpeg": "^8.0.0",
- "imagemin-pngquant": "^8.0.0",
- "jimp": "^0.6.1",
- "js-yaml": "^3.13.1",
- "postcss-assets": "^5.0.0",
- "postcss-preset-env": "^6.5.0",
- "postcss-round-subpixels": "^1.2.0",
- "postcss-unprefix": "^2.1.3",
- "prettier": "^2.0.4",
- "sass-unused": "^0.3.0",
- "strip-json-comments": "^3.0.1",
- "trim": "^0.0.1",
- "yarn": "^1.22.4"
- }
-}
+{
+ "name": "shapez",
+ "version": "1.6.0",
+ "main": "index.js",
+ "repository": "https://github.com/tobspr-games/shapez.io",
+ "author": "tobspr Games ",
+ "license": "GPL-3.0-or-later",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "postinstall": "gulp -f gulp/environment.js prepare",
+ "gulp": "gulp --cwd gulp",
+ "lint": "eslint .",
+ "prettier-all": "prettier --write .",
+ "package-win32-x64": "gulp --cwd gulp package.standalone.win32-x64",
+ "package-win32-arm64": "gulp --cwd gulp package.standalone.win32-arm64",
+ "package-linux-x64": "gulp --cwd gulp package.standalone.linux-x64",
+ "package-linux-arm64": "gulp --cwd gulp package.standalone.linux-arm64",
+ "package-darwin-x64": "gulp --cwd gulp package.standalone.darwin-x64",
+ "package-darwin-arm64": "gulp --cwd gulp package.standalone.darwin-arm64",
+ "package-all": "gulp --cwd gulp package.standalone.all"
+ },
+ "dependencies": {
+ "@msgpack/msgpack": "^3.1.2",
+ "ajv": "^6.10.2",
+ "clipboard-copy": "^3.1.0",
+ "debounce-promise": "^3.1.2",
+ "howler": "^2.1.2"
+ },
+ "devDependencies": {
+ "@electron/packager": "^18.3.6",
+ "@eslint/js": "^9.24.0",
+ "@tsconfig/node-lts": "^22.0.1",
+ "@tsconfig/strictest": "^2.0.5",
+ "@types/circular-dependency-plugin": "^5.0.5",
+ "@types/gulp": "^4.0.9",
+ "@types/gulp-htmlmin": "^1.3.32",
+ "@types/node": "^22.14.0",
+ "browser-sync": "^2.27.10",
+ "circular-dependency-plugin": "^5.2.2",
+ "css-mqpacker": "^7.0.0",
+ "cssnano": "^4.1.10",
+ "cssnano-preset-advanced": "^4.0.7",
+ "delete-empty": "^3.0.0",
+ "eslint": "^9.24.0",
+ "globals": "^15.0.0",
+ "gulp": "^4.0.2",
+ "gulp-audiosprite": "^1.1.0",
+ "gulp-cache": "^1.1.3",
+ "gulp-cached": "^1.1.1",
+ "gulp-clean": "^0.4.0",
+ "gulp-dart-sass": "^1.0.2",
+ "gulp-dom": "^1.0.0",
+ "gulp-fluent-ffmpeg": "^2.0.0",
+ "gulp-htmlmin": "^5.0.1",
+ "gulp-if": "^3.0.0",
+ "gulp-imagemin": "^7.1.0",
+ "gulp-plumber": "^1.2.1",
+ "gulp-postcss": "^8.0.0",
+ "gulp-rename": "^2.0.0",
+ "gulp-webserver": "^0.9.1",
+ "gulp-yaml": "^2.0.4",
+ "imagemin-gifsicle": "^7.0.0",
+ "imagemin-jpegtran": "^7.0.0",
+ "imagemin-mozjpeg": "^8.0.0",
+ "imagemin-pngquant": "^8.0.0",
+ "postcss-assets": "^5.0.0",
+ "postcss-critical-split": "^2.5.3",
+ "prettier": "^3.3.2",
+ "terser-webpack-plugin": "^5.3.14",
+ "ts-loader": "^9.5.2",
+ "typescript": "^5.8.2",
+ "typescript-eslint": "^8.29.1",
+ "webpack": "^5.99.9",
+ "webpack-deadcode-plugin": "^0.1.17",
+ "webpack-stream": "^7.0.0",
+ "webpack-strip-block": "^0.2.0",
+ "yaml": "^1.10.0"
+ }
+}
diff --git a/res/logo_cn.png b/res/logo_cn.png
deleted file mode 100644
index bec48a66..00000000
Binary files a/res/logo_cn.png and /dev/null differ
diff --git a/res/logo_demo.png b/res/logo_demo.png
deleted file mode 100644
index 9ea6ee62..00000000
Binary files a/res/logo_demo.png and /dev/null differ
diff --git a/res/logo_wegame.png b/res/logo_wegame.png
deleted file mode 100644
index 06237666..00000000
Binary files a/res/logo_wegame.png and /dev/null differ
diff --git a/res/puzzle_dlc_logo_china.png b/res/puzzle_dlc_logo_china.png
deleted file mode 100644
index c45b6cdc..00000000
Binary files a/res/puzzle_dlc_logo_china.png and /dev/null differ
diff --git a/res/ui/building_icons/rotater.png b/res/ui/building_icons/rotator.png
similarity index 100%
rename from res/ui/building_icons/rotater.png
rename to res/ui/building_icons/rotator.png
diff --git a/res/ui/building_tutorials/rotater-ccw.png b/res/ui/building_tutorials/rotator-ccw.png
similarity index 100%
rename from res/ui/building_tutorials/rotater-ccw.png
rename to res/ui/building_tutorials/rotator-ccw.png
diff --git a/res/ui/building_tutorials/rotater-rotate180.png b/res/ui/building_tutorials/rotator-rotate180.png
similarity index 100%
rename from res/ui/building_tutorials/rotater-rotate180.png
rename to res/ui/building_tutorials/rotator-rotate180.png
diff --git a/res/ui/building_tutorials/rotater.png b/res/ui/building_tutorials/rotator.png
similarity index 100%
rename from res/ui/building_tutorials/rotater.png
rename to res/ui/building_tutorials/rotator.png
diff --git a/res/ui/building_tutorials/virtual_processor-rotater.png b/res/ui/building_tutorials/virtual_processor-rotator.png
similarity index 100%
rename from res/ui/building_tutorials/virtual_processor-rotater.png
rename to res/ui/building_tutorials/virtual_processor-rotator.png
diff --git a/res/ui/cursor.png b/res/ui/cursor.png
deleted file mode 100644
index 6d2514e4..00000000
Binary files a/res/ui/cursor.png and /dev/null differ
diff --git a/res/ui/demo_badge.png b/res/ui/demo_badge.png
deleted file mode 100644
index 6c80db7d..00000000
Binary files a/res/ui/demo_badge.png and /dev/null differ
diff --git a/res/ui/get_on_itch_io.svg b/res/ui/get_on_itch_io.svg
deleted file mode 100644
index f6dde21e..00000000
--- a/res/ui/get_on_itch_io.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/res/ui/icons/advantage_achievements.png b/res/ui/icons/advantage_achievements.png
deleted file mode 100644
index 55860f99..00000000
Binary files a/res/ui/icons/advantage_achievements.png and /dev/null differ
diff --git a/res/ui/icons/advantage_buildings.png b/res/ui/icons/advantage_buildings.png
deleted file mode 100644
index 91e7a565..00000000
Binary files a/res/ui/icons/advantage_buildings.png and /dev/null differ
diff --git a/res/ui/icons/advantage_dark_mode.png b/res/ui/icons/advantage_dark_mode.png
deleted file mode 100644
index c176b8ad..00000000
Binary files a/res/ui/icons/advantage_dark_mode.png and /dev/null differ
diff --git a/res/ui/icons/advantage_markers.png b/res/ui/icons/advantage_markers.png
deleted file mode 100644
index af3835c7..00000000
Binary files a/res/ui/icons/advantage_markers.png and /dev/null differ
diff --git a/res/ui/icons/advantage_mods.png b/res/ui/icons/advantage_mods.png
deleted file mode 100644
index bacdda89..00000000
Binary files a/res/ui/icons/advantage_mods.png and /dev/null differ
diff --git a/res/ui/icons/advantage_new_levels.png b/res/ui/icons/advantage_new_levels.png
deleted file mode 100644
index 730732fe..00000000
Binary files a/res/ui/icons/advantage_new_levels.png and /dev/null differ
diff --git a/res/ui/icons/advantage_savegames.png b/res/ui/icons/advantage_savegames.png
deleted file mode 100644
index 79e7c327..00000000
Binary files a/res/ui/icons/advantage_savegames.png and /dev/null differ
diff --git a/res/ui/icons/advantage_support.png b/res/ui/icons/advantage_support.png
deleted file mode 100644
index b86703a5..00000000
Binary files a/res/ui/icons/advantage_support.png and /dev/null differ
diff --git a/res/ui/icons/advantage_upgrades.png b/res/ui/icons/advantage_upgrades.png
deleted file mode 100644
index e06b6d82..00000000
Binary files a/res/ui/icons/advantage_upgrades.png and /dev/null differ
diff --git a/res/ui/icons/advantage_wires.png b/res/ui/icons/advantage_wires.png
deleted file mode 100644
index bb26fa87..00000000
Binary files a/res/ui/icons/advantage_wires.png and /dev/null differ
diff --git a/res/ui/icons/demo_steam_link_indicator.png b/res/ui/icons/demo_steam_link_indicator.png
deleted file mode 100644
index 98add9df..00000000
Binary files a/res/ui/icons/demo_steam_link_indicator.png and /dev/null differ
diff --git a/res/ui/icons/savegame_correct.png b/res/ui/icons/savegame_correct.png
deleted file mode 100644
index bcbce3dc..00000000
Binary files a/res/ui/icons/savegame_correct.png and /dev/null differ
diff --git a/res/ui/interactive_tutorial.cn.noinline/1_1_extractor.gif b/res/ui/interactive_tutorial.cn.noinline/1_1_extractor.gif
deleted file mode 100644
index c7208ac2..00000000
Binary files a/res/ui/interactive_tutorial.cn.noinline/1_1_extractor.gif and /dev/null differ
diff --git a/res/ui/interactive_tutorial.cn.noinline/1_2_conveyor.gif b/res/ui/interactive_tutorial.cn.noinline/1_2_conveyor.gif
deleted file mode 100644
index 8432b676..00000000
Binary files a/res/ui/interactive_tutorial.cn.noinline/1_2_conveyor.gif and /dev/null differ
diff --git a/res/ui/interactive_tutorial.cn.noinline/1_3_expand.gif b/res/ui/interactive_tutorial.cn.noinline/1_3_expand.gif
deleted file mode 100644
index 9c655ab1..00000000
Binary files a/res/ui/interactive_tutorial.cn.noinline/1_3_expand.gif and /dev/null differ
diff --git a/res/ui/interactive_tutorial.cn.noinline/21_1_place_quad_painter.gif b/res/ui/interactive_tutorial.cn.noinline/21_1_place_quad_painter.gif
deleted file mode 100644
index ea854cf2..00000000
Binary files a/res/ui/interactive_tutorial.cn.noinline/21_1_place_quad_painter.gif and /dev/null differ
diff --git a/res/ui/interactive_tutorial.cn.noinline/21_2_switch_to_wires.gif b/res/ui/interactive_tutorial.cn.noinline/21_2_switch_to_wires.gif
deleted file mode 100644
index 78ab6fd2..00000000
Binary files a/res/ui/interactive_tutorial.cn.noinline/21_2_switch_to_wires.gif and /dev/null differ
diff --git a/res/ui/interactive_tutorial.cn.noinline/21_3_place_button.gif b/res/ui/interactive_tutorial.cn.noinline/21_3_place_button.gif
deleted file mode 100644
index 52ffb076..00000000
Binary files a/res/ui/interactive_tutorial.cn.noinline/21_3_place_button.gif and /dev/null differ
diff --git a/res/ui/interactive_tutorial.cn.noinline/21_4_press_button.gif b/res/ui/interactive_tutorial.cn.noinline/21_4_press_button.gif
deleted file mode 100644
index 5d79f1e3..00000000
Binary files a/res/ui/interactive_tutorial.cn.noinline/21_4_press_button.gif and /dev/null differ
diff --git a/res/ui/interactive_tutorial.cn.noinline/2_1_place_cutter.gif b/res/ui/interactive_tutorial.cn.noinline/2_1_place_cutter.gif
deleted file mode 100644
index 1678c0b2..00000000
Binary files a/res/ui/interactive_tutorial.cn.noinline/2_1_place_cutter.gif and /dev/null differ
diff --git a/res/ui/interactive_tutorial.cn.noinline/2_2_place_trash.gif b/res/ui/interactive_tutorial.cn.noinline/2_2_place_trash.gif
deleted file mode 100644
index 0d60fa9f..00000000
Binary files a/res/ui/interactive_tutorial.cn.noinline/2_2_place_trash.gif and /dev/null differ
diff --git a/res/ui/interactive_tutorial.cn.noinline/2_3_more_cutters.gif b/res/ui/interactive_tutorial.cn.noinline/2_3_more_cutters.gif
deleted file mode 100644
index 50ce88f9..00000000
Binary files a/res/ui/interactive_tutorial.cn.noinline/2_3_more_cutters.gif and /dev/null differ
diff --git a/res/ui/interactive_tutorial.cn.noinline/3_1_rectangles.gif b/res/ui/interactive_tutorial.cn.noinline/3_1_rectangles.gif
deleted file mode 100644
index 81668af8..00000000
Binary files a/res/ui/interactive_tutorial.cn.noinline/3_1_rectangles.gif and /dev/null differ
diff --git a/res/ui/kiwi_clicker.png b/res/ui/kiwi_clicker.png
deleted file mode 100644
index bc411e93..00000000
Binary files a/res/ui/kiwi_clicker.png and /dev/null differ
diff --git a/res/ui/main_menu/bg_pattern.png b/res/ui/main_menu/bg_pattern.png
deleted file mode 100644
index 00291768..00000000
Binary files a/res/ui/main_menu/bg_pattern.png and /dev/null differ
diff --git a/res/ui/main_menu/changelog.svg b/res/ui/main_menu/changelog.svg
deleted file mode 100644
index f12bff7b..00000000
--- a/res/ui/main_menu/changelog.svg
+++ /dev/null
@@ -1,2 +0,0 @@
-
-
diff --git a/res/ui/main_menu/github.svg b/res/ui/main_menu/github.svg
deleted file mode 100644
index 79a2756d..00000000
--- a/res/ui/main_menu/github.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/res/ui/main_menu/opensea.png b/res/ui/main_menu/opensea.png
deleted file mode 100644
index 33e2db44..00000000
Binary files a/res/ui/main_menu/opensea.png and /dev/null differ
diff --git a/res/ui/main_menu/steam.svg b/res/ui/main_menu/steam.svg
deleted file mode 100644
index 9f6e00f2..00000000
--- a/res/ui/main_menu/steam.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/res/ui/main_menu/translate.svg b/res/ui/main_menu/translate.svg
deleted file mode 100644
index e38b3392..00000000
--- a/res/ui/main_menu/translate.svg
+++ /dev/null
@@ -1,2 +0,0 @@
-
-
diff --git a/res/ui/main_menu/twitter.svg b/res/ui/main_menu/twitter.svg
deleted file mode 100644
index 047a527c..00000000
--- a/res/ui/main_menu/twitter.svg
+++ /dev/null
@@ -1,46 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/res/ui/memes/cat1.png b/res/ui/memes/cat1.png
deleted file mode 100644
index 7ec97051..00000000
Binary files a/res/ui/memes/cat1.png and /dev/null differ
diff --git a/res/ui/puzzle_dlc_logo_china.png b/res/ui/puzzle_dlc_logo_china.png
deleted file mode 100644
index c45b6cdc..00000000
Binary files a/res/ui/puzzle_dlc_logo_china.png and /dev/null differ
diff --git a/res/ui/sad_ghost.png b/res/ui/sad_ghost.png
deleted file mode 100644
index 19cd0cac..00000000
Binary files a/res/ui/sad_ghost.png and /dev/null differ
diff --git a/res/ui/shapez2.png b/res/ui/shapez2.png
deleted file mode 100644
index 1db84543..00000000
Binary files a/res/ui/shapez2.png and /dev/null differ
diff --git a/res/ui/steam_link_btn/0.png b/res/ui/steam_link_btn/0.png
deleted file mode 100644
index ceb8631b..00000000
Binary files a/res/ui/steam_link_btn/0.png and /dev/null differ
diff --git a/res/ui/steam_signin.png b/res/ui/steam_signin.png
deleted file mode 100644
index cd3120f8..00000000
Binary files a/res/ui/steam_signin.png and /dev/null differ
diff --git a/res/ui/toolbar_bg.lossless.png b/res/ui/toolbar_bg.lossless.png
deleted file mode 100644
index 93967a91..00000000
Binary files a/res/ui/toolbar_bg.lossless.png and /dev/null differ
diff --git a/res/ui/wegame_isbn_rating.jpg b/res/ui/wegame_isbn_rating.jpg
deleted file mode 100644
index 581dd744..00000000
Binary files a/res/ui/wegame_isbn_rating.jpg and /dev/null differ
diff --git a/res_raw/sounds/music/theme-short.mp3 b/res_raw/sounds/music/theme-short.mp3
deleted file mode 100644
index 1cc3b7da..00000000
Binary files a/res_raw/sounds/music/theme-short.mp3 and /dev/null differ
diff --git a/res_raw/sprites/belt/generate_wire_sprites.js b/res_raw/sprites/belt/generate_wire_sprites.js
index 7db9782c..1a88c508 100644
--- a/res_raw/sprites/belt/generate_wire_sprites.js
+++ b/res_raw/sprites/belt/generate_wire_sprites.js
@@ -1,212 +1,212 @@
-/**
- *
- * Run `yarn global add canvas` first
- */
-
-const { createCanvas } = require("canvas");
-const fs = require("fs");
-const path = require("path");
-
-const outputFolder = path.join(__dirname, "..", "wires", "sets");
-
-const dimensions = 192;
-const lineSize = 14;
-const lowerLineSize = 32;
-
-const variants = {
- first: "#61ef6f",
- second: "#5fb2f1",
- conflict: "#f74c4c",
-};
-
-function hexToRGB(h) {
- let r = 0,
- g = 0,
- b = 0;
-
- // 3 digits
- if (h.length == 4) {
- r = "0x" + h[1] + h[1];
- g = "0x" + h[2] + h[2];
- b = "0x" + h[3] + h[3];
-
- // 6 digits
- } else if (h.length == 7) {
- r = "0x" + h[1] + h[2];
- g = "0x" + h[3] + h[4];
- b = "0x" + h[5] + h[6];
- }
-
- return [+r, +g, +b];
-}
-
-function RGBToHSL(r, g, b) {
- // Make r, g, and b fractions of 1
- r /= 255;
- g /= 255;
- b /= 255;
-
- // Find greatest and smallest channel values
- let cmin = Math.min(r, g, b),
- cmax = Math.max(r, g, b),
- delta = cmax - cmin,
- h = 0,
- s = 0,
- l = 0;
- // Calculate hue
- // No difference
- if (delta == 0) h = 0;
- // Red is max
- else if (cmax == r) h = ((g - b) / delta) % 6;
- // Green is max
- else if (cmax == g) h = (b - r) / delta + 2;
- // Blue is max
- else h = (r - g) / delta + 4;
-
- h = Math.round(h * 60);
-
- // Make negative hues positive behind 360°
- if (h < 0) h += 360;
-
- // Calculate lightness
- l = (cmax + cmin) / 2;
-
- // Calculate saturation
- s = delta == 0 ? 0 : delta / (1 - Math.abs(2 * l - 1));
-
- // Multiply l and s by 100
- s = +(s * 100).toFixed(1);
- l = +(l * 100).toFixed(1);
-
- return [h, s, l];
-}
-
-function HSLToRGB(h, s, l) {
- // Must be fractions of 1
- s /= 100;
- l /= 100;
-
- let c = (1 - Math.abs(2 * l - 1)) * s,
- x = c * (1 - Math.abs(((h / 60) % 2) - 1)),
- m = l - c / 2,
- r = 0,
- g = 0,
- b = 0;
-
- if (0 <= h && h < 60) {
- r = c;
- g = x;
- b = 0;
- } else if (60 <= h && h < 120) {
- r = x;
- g = c;
- b = 0;
- } else if (120 <= h && h < 180) {
- r = 0;
- g = c;
- b = x;
- } else if (180 <= h && h < 240) {
- r = 0;
- g = x;
- b = c;
- } else if (240 <= h && h < 300) {
- r = x;
- g = 0;
- b = c;
- } else if (300 <= h && h < 360) {
- r = c;
- g = 0;
- b = x;
- }
- r = Math.round((r + m) * 255);
- g = Math.round((g + m) * 255);
- b = Math.round((b + m) * 255);
-
- return [r, g, b];
-}
-
-async function run() {
- console.log("Running");
-
- const promises = [];
-
- for (const variantId in variants) {
- const variantColor = variants[variantId];
- const variantHSL = RGBToHSL(...hexToRGB(variantColor));
- const darkenedColor = HSLToRGB(variantHSL[0], variantHSL[1] - 15, variantHSL[2] - 20);
- const hexDarkenedColor = "rgb(" + darkenedColor.join(",") + ")";
-
- console.log(variantColor, "->", hexToRGB(variantColor), variantHSL, "->", darkenedColor);
-
- const parts = {
- forward: [[0.5, 0, 0.5, 1]],
- turn: [
- [0.5, 0.5, 0.5, 1],
- [0.5, 0.5, 1, 0.5],
- ],
- split: [
- [0.5, 0.5, 0.5, 1],
- [0, 0.5, 1, 0.5],
- ],
- cross: [
- [0, 0.5, 1, 0.5],
- [0.5, 0, 0.5, 1],
- ],
- };
-
- for (const partId in parts) {
- const partLines = parts[partId];
-
- const canvas = createCanvas(dimensions, dimensions);
- const context = canvas.getContext("2d");
- context.quality = "best";
- context.clearRect(0, 0, dimensions, dimensions);
-
- const lineCanvas = createCanvas(dimensions, dimensions);
- const lineContext = lineCanvas.getContext("2d");
- lineContext.quality = "best";
- lineContext.clearRect(0, 0, dimensions, dimensions);
- lineContext.strokeStyle = hexDarkenedColor;
- lineContext.lineWidth = lowerLineSize;
- lineContext.lineCap = "square";
- lineContext.imageSmoothingEnabled = false;
-
- // Draw lower lines
- partLines.forEach(([x1, y1, x2, y2]) => {
- lineContext.beginPath();
- lineContext.moveTo(x1 * dimensions, y1 * dimensions);
- lineContext.lineTo(x2 * dimensions, y2 * dimensions);
- lineContext.stroke();
- });
-
- context.globalAlpha = 0.4;
- context.drawImage(lineCanvas, 0, 0, dimensions, dimensions);
-
- context.globalAlpha = 1;
- context.imageSmoothingEnabled = false;
- context.lineCap = "square";
- context.strokeStyle = variantColor;
- context.lineWidth = lineSize;
-
- // Draw upper lines
- partLines.forEach(([x1, y1, x2, y2]) => {
- context.beginPath();
- context.moveTo(x1 * dimensions, y1 * dimensions);
- context.lineTo(x2 * dimensions, y2 * dimensions);
- context.stroke();
- });
-
- const out = fs.createWriteStream(path.join(outputFolder, variantId + "_" + partId + ".png"));
- const stream = canvas.createPNGStream();
- stream.pipe(out);
- promises.push(new Promise(resolve => stream.on("end", resolve)));
- }
- }
-
- console.log("Waiting for completion");
- await Promise.all(promises);
-
- console.log("Done!");
-}
-
-run();
+/**
+ *
+ * Run `yarn global add canvas` first
+ */
+
+const { createCanvas } = require("canvas");
+const fs = require("fs");
+const path = require("path");
+
+const outputFolder = path.join(__dirname, "..", "wires", "sets");
+
+const dimensions = 192;
+const lineSize = 14;
+const lowerLineSize = 32;
+
+const variants = {
+ first: "#61ef6f",
+ second: "#5fb2f1",
+ conflict: "#f74c4c",
+};
+
+function hexToRGB(h) {
+ let r = 0,
+ g = 0,
+ b = 0;
+
+ // 3 digits
+ if (h.length == 4) {
+ r = "0x" + h[1] + h[1];
+ g = "0x" + h[2] + h[2];
+ b = "0x" + h[3] + h[3];
+
+ // 6 digits
+ } else if (h.length == 7) {
+ r = "0x" + h[1] + h[2];
+ g = "0x" + h[3] + h[4];
+ b = "0x" + h[5] + h[6];
+ }
+
+ return [+r, +g, +b];
+}
+
+function RGBToHSL(r, g, b) {
+ // Make r, g, and b fractions of 1
+ r /= 255;
+ g /= 255;
+ b /= 255;
+
+ // Find greatest and smallest channel values
+ let cmin = Math.min(r, g, b),
+ cmax = Math.max(r, g, b),
+ delta = cmax - cmin,
+ h = 0,
+ s = 0,
+ l = 0;
+ // Calculate hue
+ // No difference
+ if (delta == 0) h = 0;
+ // Red is max
+ else if (cmax == r) h = ((g - b) / delta) % 6;
+ // Green is max
+ else if (cmax == g) h = (b - r) / delta + 2;
+ // Blue is max
+ else h = (r - g) / delta + 4;
+
+ h = Math.round(h * 60);
+
+ // Make negative hues positive behind 360°
+ if (h < 0) h += 360;
+
+ // Calculate lightness
+ l = (cmax + cmin) / 2;
+
+ // Calculate saturation
+ s = delta == 0 ? 0 : delta / (1 - Math.abs(2 * l - 1));
+
+ // Multiply l and s by 100
+ s = +(s * 100).toFixed(1);
+ l = +(l * 100).toFixed(1);
+
+ return [h, s, l];
+}
+
+function HSLToRGB(h, s, l) {
+ // Must be fractions of 1
+ s /= 100;
+ l /= 100;
+
+ let c = (1 - Math.abs(2 * l - 1)) * s,
+ x = c * (1 - Math.abs(((h / 60) % 2) - 1)),
+ m = l - c / 2,
+ r = 0,
+ g = 0,
+ b = 0;
+
+ if (0 <= h && h < 60) {
+ r = c;
+ g = x;
+ b = 0;
+ } else if (60 <= h && h < 120) {
+ r = x;
+ g = c;
+ b = 0;
+ } else if (120 <= h && h < 180) {
+ r = 0;
+ g = c;
+ b = x;
+ } else if (180 <= h && h < 240) {
+ r = 0;
+ g = x;
+ b = c;
+ } else if (240 <= h && h < 300) {
+ r = x;
+ g = 0;
+ b = c;
+ } else if (300 <= h && h < 360) {
+ r = c;
+ g = 0;
+ b = x;
+ }
+ r = Math.round((r + m) * 255);
+ g = Math.round((g + m) * 255);
+ b = Math.round((b + m) * 255);
+
+ return [r, g, b];
+}
+
+async function run() {
+ console.log("Running");
+
+ const promises = [];
+
+ for (const variantId in variants) {
+ const variantColor = variants[variantId];
+ const variantHSL = RGBToHSL(...hexToRGB(variantColor));
+ const darkenedColor = HSLToRGB(variantHSL[0], variantHSL[1] - 15, variantHSL[2] - 20);
+ const hexDarkenedColor = "rgb(" + darkenedColor.join(",") + ")";
+
+ console.log(variantColor, "->", hexToRGB(variantColor), variantHSL, "->", darkenedColor);
+
+ const parts = {
+ forward: [[0.5, 0, 0.5, 1]],
+ turn: [
+ [0.5, 0.5, 0.5, 1],
+ [0.5, 0.5, 1, 0.5],
+ ],
+ split: [
+ [0.5, 0.5, 0.5, 1],
+ [0, 0.5, 1, 0.5],
+ ],
+ cross: [
+ [0, 0.5, 1, 0.5],
+ [0.5, 0, 0.5, 1],
+ ],
+ };
+
+ for (const partId in parts) {
+ const partLines = parts[partId];
+
+ const canvas = createCanvas(dimensions, dimensions);
+ const context = canvas.getContext("2d");
+ context.quality = "best";
+ context.clearRect(0, 0, dimensions, dimensions);
+
+ const lineCanvas = createCanvas(dimensions, dimensions);
+ const lineContext = lineCanvas.getContext("2d");
+ lineContext.quality = "best";
+ lineContext.clearRect(0, 0, dimensions, dimensions);
+ lineContext.strokeStyle = hexDarkenedColor;
+ lineContext.lineWidth = lowerLineSize;
+ lineContext.lineCap = "square";
+ lineContext.imageSmoothingEnabled = false;
+
+ // Draw lower lines
+ partLines.forEach(([x1, y1, x2, y2]) => {
+ lineContext.beginPath();
+ lineContext.moveTo(x1 * dimensions, y1 * dimensions);
+ lineContext.lineTo(x2 * dimensions, y2 * dimensions);
+ lineContext.stroke();
+ });
+
+ context.globalAlpha = 0.4;
+ context.drawImage(lineCanvas, 0, 0, dimensions, dimensions);
+
+ context.globalAlpha = 1;
+ context.imageSmoothingEnabled = false;
+ context.lineCap = "square";
+ context.strokeStyle = variantColor;
+ context.lineWidth = lineSize;
+
+ // Draw upper lines
+ partLines.forEach(([x1, y1, x2, y2]) => {
+ context.beginPath();
+ context.moveTo(x1 * dimensions, y1 * dimensions);
+ context.lineTo(x2 * dimensions, y2 * dimensions);
+ context.stroke();
+ });
+
+ const out = fs.createWriteStream(path.join(outputFolder, variantId + "_" + partId + ".png"));
+ const stream = canvas.createPNGStream();
+ stream.pipe(out);
+ promises.push(new Promise(resolve => stream.on("end", resolve)));
+ }
+ }
+
+ console.log("Waiting for completion");
+ await Promise.all(promises);
+
+ console.log("Done!");
+}
+
+run();
diff --git a/res_raw/sprites/blueprints/rotater-ccw.png b/res_raw/sprites/blueprints/rotator-ccw.png
similarity index 100%
rename from res_raw/sprites/blueprints/rotater-ccw.png
rename to res_raw/sprites/blueprints/rotator-ccw.png
diff --git a/res_raw/sprites/blueprints/rotater-rotate180.png b/res_raw/sprites/blueprints/rotator-rotate180.png
similarity index 100%
rename from res_raw/sprites/blueprints/rotater-rotate180.png
rename to res_raw/sprites/blueprints/rotator-rotate180.png
diff --git a/res_raw/sprites/blueprints/rotater.png b/res_raw/sprites/blueprints/rotator.png
similarity index 100%
rename from res_raw/sprites/blueprints/rotater.png
rename to res_raw/sprites/blueprints/rotator.png
diff --git a/res_raw/sprites/blueprints/virtual_processor-rotater.png b/res_raw/sprites/blueprints/virtual_processor-rotator.png
similarity index 100%
rename from res_raw/sprites/blueprints/virtual_processor-rotater.png
rename to res_raw/sprites/blueprints/virtual_processor-rotator.png
diff --git a/res_raw/sprites/buildings/rotater-ccw.png b/res_raw/sprites/buildings/rotator-ccw.png
similarity index 100%
rename from res_raw/sprites/buildings/rotater-ccw.png
rename to res_raw/sprites/buildings/rotator-ccw.png
diff --git a/res_raw/sprites/buildings/rotater-rotate180.png b/res_raw/sprites/buildings/rotator-rotate180.png
similarity index 100%
rename from res_raw/sprites/buildings/rotater-rotate180.png
rename to res_raw/sprites/buildings/rotator-rotate180.png
diff --git a/res_raw/sprites/buildings/rotater.png b/res_raw/sprites/buildings/rotator.png
similarity index 100%
rename from res_raw/sprites/buildings/rotater.png
rename to res_raw/sprites/buildings/rotator.png
diff --git a/res_raw/sprites/buildings/virtual_processor-rotater.png b/res_raw/sprites/buildings/virtual_processor-rotator.png
similarity index 100%
rename from res_raw/sprites/buildings/virtual_processor-rotater.png
rename to res_raw/sprites/buildings/virtual_processor-rotator.png
diff --git a/shapez.code-workspace b/shapez.code-workspace
deleted file mode 100644
index 8cd13e00..00000000
--- a/shapez.code-workspace
+++ /dev/null
@@ -1,25 +0,0 @@
-{
- "folders": [
- {
- "path": "."
- }
- ],
- "settings": {
- "files.exclude": {
- "**/build": true,
- "**/node_modules": true,
- "**/tmp_standalone_files": true,
- "**/typedefs_gen": true
- },
- "vetur.format.defaultFormatter.js": "vscode-typescript",
- "vetur.format.defaultFormatter.ts": "vscode-typescript",
- "editor.defaultFormatter": "esbenp.prettier-vscode",
- "editor.formatOnSave": true,
- "files.trimTrailingWhitespace": true,
- "workbench.colorCustomizations": {
- "activityBar.background": "#163328",
- "titleBar.activeBackground": "#1F4738",
- "titleBar.activeForeground": "#F7FBFA"
- }
- }
-}
\ No newline at end of file
diff --git a/src/css/adinplay.scss b/src/css/adinplay.scss
deleted file mode 100644
index 9707a502..00000000
--- a/src/css/adinplay.scss
+++ /dev/null
@@ -1,110 +0,0 @@
-#aip_gdpr {
- &,
- * {
- text-shadow: none !important;
- pointer-events: all;
- color: #111 !important;
- }
-
- #aip_gdpr_banner {
- padding: 5px 0;
- }
-
- #aip_gdpr_message {
- padding: 0px 15px;
- }
-}
-
-#adinplayVideoContainer {
- position: fixed;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- z-index: 20000;
- background: rgba($mainBgColor, 0.9);
- pointer-events: all;
- cursor: default;
- display: flex;
- justify-content: center;
- align-items: center;
-
- *,
- & {
- pointer-events: all;
- }
-
- &:not(.visible) {
- display: none;
- }
-
- &.waitingForFinish {
- .videoInner {
- @include S(border-radius, $globalBorderRadius);
- overflow: hidden;
-
- &::after {
- content: " ";
- position: absolute;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- @include InlineAnimation(0.2s ease-in-out) {
- 0% {
- opacity: 0;
- }
- 100% {
- opacity: 1;
- }
- }
-
- & {
- background: rgba($mainBgColor, 0.9) uiResource("loading.svg") center center / #{D(60px)} no-repeat;
- }
- }
- }
- }
-
- @include InlineAnimation(1s ease-in-out) {
- 0% {
- background: rgba($mainBgColor, 0.1);
- }
- 100% {
- background: rgba($mainBgColor, 0.9);
- }
- }
-
- .adInner {
- @include BoxShadow3D(lighten($mainBgColor, 15));
- @include S(border-radius, $globalBorderRadius);
- @include S(padding, 15px);
- // max-width: 960px;
- display: block !important;
-
- .topbar {
- display: grid;
- grid-template-columns: 1fr auto;
- @include S(margin-bottom, 15px);
- @include S(grid-column-gap, 10px);
-
- .desc {
- @include TextShadow3D(#fff);
- @include PlainText;
- }
-
- button.getOnSteam {
- @include Text;
- }
- }
-
- .videoInner {
- // width: 960px;
- // height: 570px;
- // min-width: 960px;
- // min-height: 570px;
- background: darken($mainBgColor, 1);
- display: block !important;
- }
- }
-}
diff --git a/src/css/animations.scss b/src/css/animations.scss
deleted file mode 100644
index 16ba7fd1..00000000
--- a/src/css/animations.scss
+++ /dev/null
@@ -1,19 +0,0 @@
-@each $animName in ("changeAnimEven", "changeAnimOdd") {
- @keyframes #{$animName} {
- 0% {
- transform: scale(1, 1);
- }
-
- 50% {
- transform: scale(1.03, 1.03);
- }
-
- 100% {
- transform: scale(1, 1);
- }
- }
-
- .#{$animName} {
- animation: $animName 0.2s ease-in-out;
- }
-}
diff --git a/src/css/changelog_skins.scss b/src/css/changelog_skins.scss
deleted file mode 100644
index f63849ad..00000000
--- a/src/css/changelog_skins.scss
+++ /dev/null
@@ -1,18 +0,0 @@
-// [data-changelog-skin="achievements"] {
-// background: #f8f8f8;
-
-// @include DarkThemeOverride {
-// background: rgba(0, 10, 20, 0.2);
-// }
-
-// @include S(border-radius, 5px);
-// &::before {
-// content: " ";
-// width: 100%;
-// display: block;
-// background: uiResource("changelog_skins/achievements.noinline.png") center center / cover no-repeat !important;
-// @include S(height, 80px);
-// @include S(border-radius, 5px);
-// @include S(margin-bottom, 5px);
-// }
-// }
diff --git a/src/css/common.scss b/src/css/common.scss
index 448ebe4f..619706ff 100644
--- a/src/css/common.scss
+++ b/src/css/common.scss
@@ -2,7 +2,7 @@
* {
margin: 0;
padding: 0;
- touch-action: pan-x pan-y !important;
+ touch-action: pan-x pan-y;
pointer-events: none;
-webkit-tap-highlight-color: rgba(255, 255, 255, 0);
}
@@ -21,18 +21,7 @@ body {
}
html {
- position: fixed;
- // scroll-behavior: smooth;
background: $mainBgColor;
- // Disable zooming and thus
- -ms-touch-action: pan-x, pan-y;
- touch-action: pan-x, pan-y;
- -ms-content-zooming: none;
- top: 0;
- left: 0;
- bottom: 0;
- right: 0;
- background: #dee1ea;
@include DarkThemeOverride {
background: $darkModeGameBackground;
}
@@ -41,77 +30,11 @@ html {
body {
color: #555;
user-select: none;
- -moz-user-select: none;
- -ms-user-select: none;
- background: inherit !important;
- text-transform: none;
- white-space: normal;
- word-break: normal;
- word-spacing: normal;
- word-wrap: break-word;
- font-style: normal;
- line-break: auto;
- font-stretch: 100%;
+ background: inherit;
+ overflow-wrap: break-word;
text-rendering: optimizeLegibility;
- text-decoration: none;
- text-size-adjust: 100%;
- letter-spacing: normal;
- scrollbar-width: 6px;
-webkit-font-smoothing: antialiased;
- // -webkit-overflow-scrolling: touch; /* stop scrolling immediately */
- -webkit-touch-callout: none;
- /* prevent callout to copy image, etc when tap to hold */
- -webkit-text-size-adjust: none;
- /* prevent webkit from resizing text to fit */
- // Internet explorer
- scrollbar-face-color: #888;
- scrollbar-track-color: rgba(255, 255, 255, 0.1);
- // Firefox
- scrollbar-color: #cdd0d4 rgba(#000, 0.05);
- overflow: hidden;
@include Text;
- &.externalAdOpen {
- &::before {
- text-transform: uppercase;
- @include SuperSmallText;
- content: "Loading Advertisement...";
- color: #333;
- position: fixed;
- top: 0;
- pointer-events: all;
- left: 0;
- right: 0;
- bottom: 0;
- background: rgba(50, 60, 70, 0.8);
- z-index: 999999;
- display: flex;
- justify-content: center;
- align-items: center;
- color: #fff;
- @include InlineAnimation(1s ease-in-out infinite) {
- 50% {
- transform: scale(1.05);
- }
- }
- }
- }
- // For recording the bg video
- // filter: blur(5px);
- // &::after {
- // position: fixed;
- // top: 0;
- // left: 0;
- // right: 0;
- // bottom: 0;
- // z-index: 9999;
- // content: " ";
- // background: rgba($ingameHudBg, 0.5);
- // }
-}
-
-img {
- -webkit-touch-callout: none;
- /* prevent callout to copy image, etc when tap to hold */
}
i {
@@ -132,8 +55,6 @@ input,
textarea,
select {
font-size: inherit;
- font-weight: inherit;
- font-family: inherit;
line-height: inherit;
}
@@ -143,70 +64,25 @@ button {
pointer-events: all;
cursor: pointer;
position: relative;
- @include TextShadow3D;
- &.prefab_BuyButtonWithResources {
- display: flex;
- box-sizing: border-box;
- @include S(padding, 6px, 4px);
- // letter-spacing: 0;
- background-color: color($cyan, 400);
- flex-direction: row;
- justify-content: center;
- align-items: center;
- @include S(width, 85px);
- &.tooExpensive {
- color: $colorRedBright;
- background-color: #555;
- cursor: default;
- }
- .cost_entry {
- display: flex;
- flex-grow: 1;
- justify-content: center;
- align-items: center;
- }
- b {
- display: flex;
- flex-grow: 1;
- justify-content: center;
- align-items: center;
- }
- &.tooExpensive {
- cursor: default !important;
- background-color: #565859 !important;
- b {
- color: $colorRedBright !important;
- }
- .cost_entry {
- opacity: 0.6;
- }
- }
- }
+ color: $legacyTextShadow3DColor;
}
.styledButton {
- background: $themeColor;
text-transform: uppercase;
box-sizing: content-box;
- @include S(padding, 3px, 10px);
- @include IncreasedClickArea(10px);
- @include TextShadow3D(#fff, $borderColor: #28292a);
+ padding: 0.3rem 1rem;
@include ButtonText;
border: 0;
background: $colorBlueBright;
color: #fff;
-
- @include S(border-radius, 0.8 * $globalBorderRadius);
- // border: #{D(1px)} solid rgba(0, 10, 20, 0.2);
- @include S(border-bottom-width, 2px);
- // color: $accentColorDark;
- letter-spacing: 0em !important;
- // box-shadow: 0 #{D(1px)} #{D(2px)} 0 rgba(0, 10, 20, 0.2);
- .keybinding {
- @include S(bottom, -2.5px);
- @include S(right, -2px);
- }
+ border-radius: 0.8 * $globalBorderRadius;
transition: opacity 0.12s ease-in-out;
+
+ kbd {
+ bottom: -0.25rem;
+ right: -0.2rem;
+ }
+
&:hover {
opacity: 0.9;
}
@@ -217,17 +93,11 @@ button {
/* WebKit/Blink Browsers */
}
-::-moz-selection {
- background: $colorGreenBright;
- /* Gecko Browsers */
-}
-
input[type="text"],
input[type="email"] {
- @include S(padding, 11px, 12px);
- @include S(margin, 10px, 0);
+ padding: 1.1rem 1.2rem;
+ margin: 1rem 0;
border: 0;
- cursor: text;
display: block;
text-align: left;
box-sizing: border-box;
@@ -237,14 +107,13 @@ input[type="email"] {
user-select: text !important;
pointer-events: all !important;
@include Text;
- @include IncreasedClickArea(15px);
- @include S(border-radius, $globalBorderRadius);
+ border-radius: $globalBorderRadius;
&::placeholder {
color: #fff;
opacity: 0.4;
}
transition: background-color 0.1s ease-in-out !important;
- @include TextShadow3D(#fff);
+ color: #fff;
@include BoxShadow3D(lighten($mainBgColor, 30));
&:focus {
@include BoxShadow3D(lighten($mainBgColor, 35));
@@ -258,8 +127,8 @@ input[type="email"] {
&.input-token {
@include SuperHeading;
text-align: center;
- @include S(letter-spacing, 30px);
- @include S(padding-left, 30px);
+ letter-spacing: 3rem;
+ padding-left: 3rem;
}
}
@@ -282,8 +151,6 @@ a {
a {
text-decoration: none;
- cursor: pointer;
- pointer-events: all;
}
i {
@@ -292,35 +159,20 @@ i {
input {
user-select: text;
- -moz-user-select: text;
pointer-events: all;
- cursor: text;
border-radius: 0;
}
canvas {
pointer-events: all;
- // image-rendering: pixelated;
- // &.smoothed {
- // }1
- // &.unsmoothed {
- // }
- letter-spacing: 0 !important;
transform: translateZ(0);
backface-visibility: hidden;
- -webkit-backface-visibility: hidden;
-}
-
-.fontPreload {
- position: absolute;
- top: -100px;
- left: -100px;
}
// Scrollbar
::-webkit-scrollbar {
- @include S(width, 6px);
- @include S(height, 6px);
+ width: 0.6rem;
+ height: 0.6rem;
}
::-webkit-scrollbar-track {
@@ -329,7 +181,7 @@ canvas {
::-webkit-scrollbar-thumb {
// border-radius: 4px;
- @include S(border-radius, $globalBorderRadius);
+ border-radius: $globalBorderRadius;
background: #cdd0d4;
}
@@ -337,21 +189,6 @@ canvas {
background: #d8dce0;
}
-#uiTestPlaybackCursor {
- position: fixed;
- top: 100px;
- left: 100px;
- z-index: 9999;
- border-radius: 50%;
- background: rgba(255, 255, 0, 0.4);
- width: 24px;
- height: 24px;
- border: 3px solid rgba(0, 0, 0, 0.5);
- margin-top: -12px;
- margin-left: -12px;
- box-sizing: border-box;
-}
-
.pressed:not(.noPressEffect) {
transform: scale(0.98) !important;
animation: none !important;
@@ -375,25 +212,20 @@ canvas {
display: inline-block;
}
-.badged {
- color: color($purple, 300);
-}
-
-.prefab_LoadingTextWithAnim,
-.prefab_LoadingTextWithAnimDelayed {
+.prefab_LoadingTextWithAnim {
display: inline-flex;
align-items: center;
justify-content: center;
text-transform: uppercase;
@include Text;
- @include TextShadow3D;
+ color: $legacyTextShadow3DColor;
opacity: 1;
z-index: 20;
color: #393747;
&::after {
content: " ";
- @include S(width, 35px);
- @include S(height, 35px);
+ width: 3.5rem;
+ height: 3.5rem;
display: inline-block;
vertical-align: middle;
@@ -413,67 +245,16 @@ canvas {
}
}
-.prefab_LoadingTextWithAnimDelayed {
- @include InlineAnimation(0.6s ease-in-out) {
- 0% {
- opacity: 0;
- }
- 50% {
- opacity: 0;
- }
- 100% {
- opacity: 1;
- }
- }
-}
-
.prefab_LoadingProgressIndicator {
@include PlainText;
- @include S(margin-top, 20px);
+ margin-top: 2rem;
width: 100%;
color: #336c9f;
- @include S(height, 20px);
+ height: 2rem;
text-transform: uppercase;
text-align: center;
}
-.prefab_FeatureComingSoon {
- position: relative;
- &::after {
- @include S(top, -5px);
- @include S(left, -5px);
- @include S(right, -5px);
- @include S(bottom, -5px);
- content: "Coming soon!";
- z-index: 10000;
- background: rgba(lighten($mainBgColor, 0), 0.4);
- @include S(border-radius, $globalBorderRadius);
- position: absolute;
- display: flex;
- justify-content: center;
- align-items: center;
- pointer-events: all;
- @include PlainText;
- text-transform: uppercase;
- }
- opacity: 0.6;
- > * {
- opacity: 0.5 !important;
- }
-}
-
-.prefab_InfoIcon {
- @include S(width, 25px);
- @include S(height, 25px);
- z-index: 100;
- opacity: 0.8;
- cursor: pointer;
- pointer-events: all;
- display: inline-block;
- position: relative;
- @include IncreasedClickArea(10px);
-}
-
.gameState.prefab_LoadingState {
text-align: center;
display: flex;
@@ -492,15 +273,15 @@ canvas {
}
& {
- background: uiResource("loading.svg") center center / #{D(40px)} no-repeat;
+ background: uiResource("loading.svg") center center / 4rem no-repeat;
}
}
.prefab_GameHint {
position: absolute;
- @include S(left, 20px);
- @include S(right, 20px);
- @include S(bottom, 60px);
+ left: 2rem;
+ right: 2rem;
+ bottom: 6rem;
@include Text;
color: #666;
@@ -511,9 +292,9 @@ canvas {
.loadingStatus {
position: absolute;
- @include S(left, 20px);
- @include S(right, 20px);
- @include S(bottom, 30px);
+ left: 2rem;
+ right: 2rem;
+ bottom: 3rem;
@include Text;
@include PlainText;
color: #aaa;
@@ -528,11 +309,11 @@ canvas {
align-items: center;
> .bar {
display: none;
- @include S(margin-top, 15px);
+ margin-top: 1.5rem;
width: 80vw;
@include BoxShadow3D(lighten($mainBgColor, 10), $size: 1px);
position: relative;
- @include TextShadow3D(#fff);
+ color: #fff;
height: 2px;
.inner {
position: absolute !important;
@@ -541,7 +322,7 @@ canvas {
bottom: 0;
z-index: 1;
@include BoxShadow3D($themeColor, $size: 1px);
- @include S(border-radius, $globalBorderRadius);
+ border-radius: $globalBorderRadius;
transform-origin: 0% 50%;
@include InlineAnimation(1.3s ease-in-out infinite) {
0% {
@@ -563,7 +344,7 @@ canvas {
position: relative;
z-index: 2;
display: inline-flex;
- @include S(padding, 5px);
+ padding: 0.5rem;
@include PlainText;
}
}
@@ -577,17 +358,19 @@ canvas {
.checkbox {
$bgColor: darken($mainBgColor, 3);
background-color: $bgColor;
- @include S(width, 35px);
- @include S(height, 17px);
+ width: 3.5rem;
+ height: 1.7rem;
display: flex;
- @include S(padding, 3px);
+ padding: 0.3rem;
box-sizing: content-box;
cursor: pointer;
pointer-events: all;
- transition: opacity 0.2s ease-in-out, background-color 0.3s ease-in-out, box-shadow 0.4s ease-in-out !important;
+ transition:
+ opacity 0.2s ease-in-out,
+ background-color 0.3s ease-in-out,
+ box-shadow 0.4s ease-in-out !important;
position: relative;
- @include BorderRadius(20px);
- @include IncreasedClickArea(10px);
+ border-radius: 2rem;
@include BoxShadow3D($bgColor, $size: 2px);
&.loading {
opacity: 0.2;
@@ -596,20 +379,20 @@ canvas {
background-color: darken($bgColor, 5);
}
.knob {
- @include S(width, 20px);
- @include S(height, 17px);
+ width: 2rem;
+ height: 1.7rem;
display: inline-block;
transition: margin-left 0.4s ease-in-out !important;
background: #fff;
position: relative;
- @include BorderRadius(20px);
+ border-radius: 2rem;
@include BoxShadow3D(#fff, $size: 1px);
}
&.checked {
background-color: $themeColor;
@include BoxShadow3D($themeColor, $size: 2px);
.knob {
- @include S(margin-left, 15px);
+ margin-left: 1.5rem;
}
&:hover {
background-color: lighten($themeColor, 15);
@@ -630,7 +413,7 @@ canvas {
justify-content: center;
label {
- @include S(margin-right, 5px);
+ margin-right: 0.5rem;
&,
& * {
@include PlainText;
@@ -641,14 +424,14 @@ canvas {
input.rangeInput {
cursor: pointer;
background-color: transparent;
- @include S(width, 100px);
- @include S(height, 16px);
+ width: 10rem;
+ height: 1.6rem;
&::-webkit-slider-runnable-track {
background-color: darken($mainBgColor, 3);
color: darken($mainBgColor, 3);
- // @include S(height, 16px);
- @include S(border-radius, 8px);
+ // height: 1.6rem;
+ border-radius: 0.8rem;
}
@include DarkThemeOverride {
@@ -657,14 +440,13 @@ input.rangeInput {
}
&::-webkit-slider-thumb {
- box-shadow: inset 0 0 0 D(10px) #eee;
+ box-shadow: inset 0 0 0 1rem #eee;
}
}
&::-webkit-slider-thumb {
appearance: none;
- -webkit-appearance: none;
- box-shadow: inset 0 0 0 D(10px) $themeColor;
+ box-shadow: inset 0 0 0 1rem $themeColor;
border-radius: 50%;
transition: box-shadow 0.3s;
@@ -672,104 +454,43 @@ input.rangeInput {
&:hover {
&::-webkit-slider-thumb {
- box-shadow: inset 0 0 0 D(10px) lighten($themeColor, 15);
+ box-shadow: inset 0 0 0 1rem lighten($themeColor, 15);
}
}
}
+// FIXME: Translations are still using code.keybinding instead of kbd
+kbd,
.keybinding {
background: #fff;
text-transform: uppercase;
- @include S(padding, 1.5px, 3px, 2px);
+ font-family: inherit;
+ padding: 0.15rem 0.3rem 0.2rem;
@include PlainText;
- @include S(border-radius, 0.5 * $globalBorderRadius);
+ border-radius: 0.5 * $globalBorderRadius;
&,
> span {
- @include S(font-size, 9px);
- @include S(line-height, 11px);
- font-weight: bold !important;
- text-shadow: none !important;
- // font-family: Arial, sans-serif !important;
+ font-size: 0.9rem;
+ line-height: 1.1rem;
}
- font-weight: bold;
color: $accentColorDark;
text-align: center;
justify-content: center;
align-items: center;
- @include S(min-width, 12px);
+ min-width: 1.2rem;
display: inline-flex;
position: absolute;
- @include S(bottom, 0px);
- @include S(right, 0px);
+ bottom: 0rem;
+ right: 0rem;
z-index: 999;
box-sizing: border-box;
- @include S(height, 12px);
+ height: 1.2rem;
overflow: hidden;
- border: #{D(0px)} solid $accentColorDark;
- .keybinding_space {
- @include S(font-size, 17px);
- @include S(line-height, 11px);
- @include S(margin-top, -12px);
- }
-}
-
-.xpaystation-widget-lightbox {
- z-index: 19999;
- .xpaystation-widget-lightbox-overlay {
- background: rgba($mainBgColor, 0.94);
- }
- &,
- iframe {
- pointer-events: all;
- user-select: all;
- }
+ border: 0rem solid $accentColorDark;
}
iframe {
pointer-events: all;
user-select: all;
}
-
-// Steam overlay fix
-#steamOverlayCanvasFix {
- position: fixed;
- top: 0px;
- left: 0;
- right: 0;
- bottom: 0;
- width: 100%;
- height: 100%;
- opacity: 0.01;
- pointer-events: none;
- z-index: -1;
-}
-
-.sentry-error-embed-wrapper {
- z-index: 10000;
- background: rgba(0, 0, 0, 0.9);
- * {
- text-shadow: none !important;
- pointer-events: all;
- }
-}
-
-.cpmsrendertarget {
- &,
- * {
- pointer-events: all;
- }
- background: rgba($mainBgColor, 0.94) !important;
- .cpmsvideoclosebanner {
- font-family: GameFont !important;
- font-size: 16px !important;
- border-radius: 2px !important;
- background: $themeColor !important;
- @include BoxShadow3D(darken($mainBgColor, 12));
- color: #eee !important;
- &:active {
- @include BoxShadow3D(darken($mainBgColor, 12), $size: 1px);
- transform: translateY(2px);
- }
- }
-}
diff --git a/src/css/dynamic_ui.scss b/src/css/dynamic_ui.scss
deleted file mode 100644
index 8b005eff..00000000
--- a/src/css/dynamic_ui.scss
+++ /dev/null
@@ -1,43 +0,0 @@
-// Removes the unit (px, %, etc) from a value
-@function strip-unit($number) {
- @if type-of($number) == "number" and not unitless($number) {
- @return $number / ($number * 0 + 1);
- }
-
- @return $number;
-}
-
-// Helper method to scale a value, for use in calc() etc
-@function D($v) {
- $baseValue: strip-unit($v) * 1px;
- @return calc(#{$baseValue} * var(--ui-scale));
-}
-
-// Helper method to scale the font size
-@mixin ScaleFont($fontSize, $lineHeight) {
- font-size: D($fontSize * $mainFontScale);
- line-height: D($lineHeight * $mainFontScale);
-}
-
-// Helper method to scale a property value
-@mixin S($propName, $v1, $v2: "", $v3: "", $v4: "", $important: false) {
- $impSuffix: "";
- @if $important == true {
- $impSuffix: "!important";
- }
-
- $v1: D($v1);
-
- @if $v2 != "" {
- $v2: D($v2);
- }
-
- @if $v3 != "" {
- $v3: D($v3);
- }
- @if $v4 != "" {
- $v4: D($v4);
- }
-
- #{$propName}: #{$v1} #{$v2} #{$v3} #{$v4} #{$impSuffix};
-}
diff --git a/src/css/error_handler.scss b/src/css/error_handler.scss
new file mode 100644
index 00000000..f94ed651
--- /dev/null
+++ b/src/css/error_handler.scss
@@ -0,0 +1,89 @@
+:root {
+ // Provide a fallback font-size for UI scale calculations before the app loads
+ // TODO: perhaps use this as the primary source of UI scale?
+ font-size: #{"round(clamp(1px, calc(min(100vw, 100vh) * 0.019), 100px), 0.01px)"};
+}
+
+#errorHandler {
+ --background-primary: hsl(0deg 40% 18%);
+ --background-container: hsl(0deg 40% 10%);
+ --foreground: hsl(0deg 100% 95%);
+
+ --background-button: rgba(255 255 255 / 0.05);
+ --background-button-hover: rgba(255 255 255 / 0.03);
+ --background-button-active: hsl(from var(--background-container) h s l / 0.4);
+ --background-button-success: hsl(130deg 40% 25%);
+
+ background: var(--background-primary);
+ color: var(--foreground);
+
+ font-size: 1.2rem;
+ line-height: 1.3;
+
+ display: grid;
+ padding: 3rem;
+ gap: 0.8rem;
+
+ grid-template-rows: auto 1fr 1fr auto;
+ grid-template-columns: auto minmax(20rem, 20%);
+
+ pre {
+ background: var(--background-container);
+ border-radius: 0.3rem;
+
+ font-size: 85%;
+ padding: 0.2rem 0.4rem;
+ overflow-y: auto;
+ white-space: pre-wrap;
+ overflow-wrap: break-word;
+ pointer-events: all;
+ }
+
+ button {
+ background: var(--background-button);
+ border-radius: 0.3rem;
+ color: inherit;
+ transition: 0.15s ease-out background-color;
+
+ padding: 0.6rem 0.6rem 0.8rem;
+ min-width: 10rem;
+ width: 15%;
+ font-size: inherit;
+
+ &:hover {
+ background: var(--background-button-hover);
+ }
+
+ &:active {
+ background: var(--background-button-active);
+ }
+
+ &.success {
+ background: var(--background-button-success);
+ }
+ }
+
+ .header,
+ .actions {
+ grid-column: 1 / 3;
+ }
+
+ .stackTrace {
+ grid-row: 2 / 4;
+ }
+
+ .loadedMods,
+ .buildInformation {
+ display: grid;
+ grid-template-rows: auto 1fr;
+ gap: 0.2rem;
+ overflow: auto;
+ }
+
+ .actions {
+ display: flex;
+ padding-top: 1rem;
+ gap: 1rem;
+ justify-content: flex-end;
+ }
+}
diff --git a/src/css/game_state.scss b/src/css/game_state.scss
index 60fab61d..31d2944c 100644
--- a/src/css/game_state.scss
+++ b/src/css/game_state.scss
@@ -6,22 +6,10 @@ $gameStateTransition: 0.2s ease-out;
}
.gameState {
- display: block;
- // background: $mainBgColor;
- height: 100%;
- width: 100%;
- position: fixed;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- z-index: 0;
- overflow: hidden !important;
@include Text;
@include StateAnim(opacity, transform, filter);
opacity: 0;
- // transform: scaleX(0.99) skewX(1deg) translate(1%, 0.5%);
&.arrived {
opacity: 1;
diff --git a/src/css/ingame_hud/beta_overlay.scss b/src/css/ingame_hud/beta_overlay.scss
index 08eba960..18535ae0 100644
--- a/src/css/ingame_hud/beta_overlay.scss
+++ b/src/css/ingame_hud/beta_overlay.scss
@@ -1,6 +1,6 @@
#ingame_HUD_BetaOverlay {
position: fixed;
- @include S(top, 70px);
+ top: 7rem;
left: 50%;
transform: translateX(-50%);
color: $colorRedBright;
diff --git a/src/css/ingame_hud/blueprint_placer.scss b/src/css/ingame_hud/blueprint_placer.scss
index 36d1cdad..184fea76 100644
--- a/src/css/ingame_hud/blueprint_placer.scss
+++ b/src/css/ingame_hud/blueprint_placer.scss
@@ -1,40 +1,40 @@
-#ingame_HUD_BlueprintPlacer {
- position: absolute;
- @include S(top, 70px);
- left: 50%;
- transform: translateX(-50%);
- color: #333;
- z-index: 9999;
- background: $ingameHudBg;
- @include S(padding, 5px);
- display: flex;
- flex-direction: column;
- color: #fff;
- @include S(width, 120px);
- align-items: center;
- justify-content: center;
- @include S(border-radius, $globalBorderRadius);
-
- .label {
- @include PlainText;
- text-transform: uppercase;
- }
- .costContainer {
- display: flex;
- align-items: center;
- @include Heading;
-
- > canvas {
- @include S(margin-left, 5px);
- @include S(width, 30px);
- @include S(height, 30px);
- }
- }
-
- &:not(.canAfford) {
- background: rgba(98, 27, 41, 0.8);
- // .costContainer {
- color: rgb(255, 97, 128);
- // }
- }
-}
+#ingame_HUD_BlueprintPlacer {
+ position: absolute;
+ top: 7rem;
+ left: 50%;
+ transform: translateX(-50%);
+ color: #333;
+ z-index: 9999;
+ background: $ingameHudBg;
+ padding: 0.5rem;
+ display: flex;
+ flex-direction: column;
+ color: #fff;
+ width: 12rem;
+ align-items: center;
+ justify-content: center;
+ border-radius: $globalBorderRadius;
+
+ .label {
+ @include PlainText;
+ text-transform: uppercase;
+ }
+ .costContainer {
+ display: flex;
+ align-items: center;
+ @include Heading;
+
+ > canvas {
+ margin-left: 0.5rem;
+ width: 3rem;
+ height: 3rem;
+ }
+ }
+
+ &:not(.canAfford) {
+ background: rgba(98, 27, 41, 0.8);
+ // .costContainer {
+ color: rgb(255, 97, 128);
+ // }
+ }
+}
diff --git a/src/css/ingame_hud/building_placer.scss b/src/css/ingame_hud/building_placer.scss
index 12965f0f..6b350f6c 100644
--- a/src/css/ingame_hud/building_placer.scss
+++ b/src/css/ingame_hud/building_placer.scss
@@ -1,14 +1,14 @@
#ingame_HUD_PlacementHints {
position: fixed;
- @include S(top, 60px);
- @include S(right, 10px);
+ top: 6rem;
+ right: 1rem;
display: grid;
- @include S(padding, 6px);
- @include S(border-radius, $globalBorderRadius);
- @include S(width, 240px);
- @include S(grid-column-gap, 5px);
+ padding: 0.6rem;
+ border-radius: $globalBorderRadius;
+ width: 24rem;
+ grid-column-gap: 0.5rem;
background: $ingameHudBg;
grid-template-columns: 1fr auto;
@@ -28,7 +28,7 @@
.buildingLabel {
@include PlainText;
- @include S(margin-bottom, 2px);
+ margin-bottom: 0.2rem;
color: #fff;
text-transform: uppercase;
grid-column: 1 / 3;
@@ -55,7 +55,7 @@
label {
color: lighten($colorGreenBright, 10);
font-weight: bold;
- @include S(margin-right, 5px);
+ margin-right: 0.5rem;
}
}
@@ -65,19 +65,20 @@
display: flex;
flex-direction: row;
align-items: center;
- .keybinding {
+
+ kbd {
position: relative;
- @include S(margin-left, 5px);
+ margin-left: 0.5rem;
}
}
.buildingImage {
grid-column: 2 / 3;
grid-row: 1 / 3;
- @include S(width, 100px);
- @include S(height, 100px);
+ width: 10rem;
+ height: 10rem;
background: top left / 100% 100% no-repeat;
- @include S(border-radius, $globalBorderRadius);
+ border-radius: $globalBorderRadius;
transition: opacity 0.1s ease-in-out;
}
@@ -97,15 +98,15 @@
#ingame_HUD_PlacerVariants {
position: absolute;
- @include S(right, 10px);
- @include S(top, 200px);
+ right: 1rem;
+ top: 20rem;
display: flex;
- @include S(grid-gap, 5px);
+ grid-gap: 0.5rem;
flex-direction: column;
align-items: flex-end;
&.compact {
- @include S(top, 150px);
+ top: 15rem;
}
.explanation {
@@ -113,10 +114,11 @@
grid-row: 1 / 2;
@include SuperSmallText;
text-align: right;
- .keybinding {
+ font-weight: bold !important;
+
+ .kbd {
position: relative;
}
- font-weight: bold !important;
@include DarkThemeOverride {
color: rgba(#fff, 0.5);
@@ -125,22 +127,22 @@
.variants {
display: grid;
- @include S(grid-gap, 5px);
+ grid-gap: 0.5rem;
.variant {
pointer-events: all;
cursor: pointer;
grid-row: 2 / 3;
- @include S(border-radius, $globalBorderRadius);
+ border-radius: $globalBorderRadius;
background: rgba($ingameHudBg, 0.5);
opacity: 0.5;
display: inline-flex;
vertical-align: top;
position: relative;
align-items: center;
- @include S(padding, 3px);
- @include S(grid-gap, 10px);
+ padding: 0.3rem;
+ grid-gap: 1rem;
transition: background-color 0.12s ease-in-out;
@@ -154,30 +156,30 @@
background-color: rgba($colorBlueBright, 0.8);
}
- $iconSize: 25px;
+ $iconSize: 2.5rem;
.iconWrap {
grid-column: 1 / 2;
grid-row: 1 / 2;
position: relative;
- @include S(width, $iconSize);
- @include S(height, $iconSize);
+ width: $iconSize;
+ height: $iconSize;
background: center center / contain no-repeat;
&[data-tile-w="2"] {
- @include S(width, 2 * $iconSize);
+ width: 2 * $iconSize;
}
&[data-tile-h="2"] {
- @include S(height, 2 * $iconSize);
+ height: 2 * $iconSize;
}
&[data-tile-h="3"] {
- @include S(height, 3 * $iconSize);
+ height: 3 * $iconSize;
}
&[data-tile-w="3"] {
- @include S(width, 3 * $iconSize);
+ width: 3 * $iconSize;
}
&[data-tile-w="4"] {
- @include S(width, 4 * $iconSize);
+ width: 4 * $iconSize;
}
}
diff --git a/src/css/ingame_hud/buildings_toolbar.scss b/src/css/ingame_hud/buildings_toolbar.scss
index 4e9028b5..141c8a9a 100644
--- a/src/css/ingame_hud/buildings_toolbar.scss
+++ b/src/css/ingame_hud/buildings_toolbar.scss
@@ -1,185 +1,185 @@
-.ingame_buildingsToolbar {
- position: absolute;
- @include S(bottom, 10px);
- left: 50%;
- transform: translateX(-50%);
-
- display: grid;
- grid-template-rows: auto auto;
- justify-items: center;
- @include S(grid-gap, 4px);
-
- background: transparent;
- transition: transform 120ms ease-in-out;
- will-change: transform;
-
- &:not(.visible) {
- transform: translateX(-50%) translateY(#{D(100px)});
- }
-
- .buildings {
- display: grid;
- grid-auto-flow: column;
- justify-items: center;
- align-self: center;
- grid-gap: D(2px);
- grid-row: 2 / 3;
-
- @include S(border-radius, $globalBorderRadius);
- @include S(padding, 2px);
- background-color: rgba($ingameHudBg, 0.07);
-
- @include DarkThemeOverride {
- background-color: rgba(darken($darkModeGameBackground, 15), 0.95);
- }
-
- &.secondary {
- grid-row: 1 / 2;
-
- .building {
- @include S(width, 30px);
- @include S(height, 30px);
- background-size: 45%;
-
- &:not(.unlocked) {
- &::before {
- background-size: #{D(13px)};
- }
- }
- }
- }
-
- .building {
- display: flex;
- @include S(width, 40px);
- position: relative;
- @include S(height, 40px);
-
- @at-root html[data-tutorial-step="1_1_extractor"] &[data-id="miner"]:not(.selected),
- html[data-tutorial-step="1_2_conveyor"] &[data-id="belt"]:not(.selected),
- html[data-tutorial-step="2_1_place_cutter"] &[data-id="cutter"]:not(.selected),
- html[data-tutorial-step="2_2_place_trash"] &[data-id="trash"]:not(.selected) {
- &::before {
- content: "";
-
- & {
- /* load-async */
- background: uiResource("icons/tutorial_arrow.png") center center / contain no-repeat;
- }
-
- @include S(width, 25px);
- @include S(height, 25px);
- position: absolute;
- left: 50%;
- bottom: 100%;
- transform: translateX(-50%);
- @include InlineAnimation(1s ease-in-out infinite) {
- 50% {
- transform: translateX(-50%) translateY(20%);
- }
- }
- }
- @include S(border-radius, $globalBorderRadius);
- box-shadow: 0 0 D(10px) D(5px) rgba(74, 237, 134, 0.5) !important;
- background: rgba(74, 237, 134, 0.5) !important;
- }
-
- .icon {
- color: $accentColorDark;
- display: flex;
- flex-direction: column-reverse;
- position: relative;
- align-items: center;
- justify-content: center;
- width: 100%;
- height: 100%;
- padding: 0;
- margin: 0;
-
- background: center center / 70% no-repeat;
- }
-
- &:not(.unlocked) {
- @include S(width, 25px);
- .icon {
- opacity: 0.15;
- }
- &.editor {
- .icon {
- pointer-events: all;
- cursor: pointer;
- &:hover {
- background-color: rgba(22, 30, 68, 0.1);
- }
- }
- }
- &:not(.editor) {
- .icon {
- background-image: uiResource("locked_building.png") !important;
- }
- }
- }
-
- &.unlocked {
- .icon {
- @include S(border-radius, $globalBorderRadius * 0.9);
-
- pointer-events: all;
- transition: all 0.12s ease-in-out;
- transition-property: background-color, transform;
- cursor: pointer;
-
- &:hover {
- background-color: rgba(30, 40, 90, 0.1);
-
- @include DarkThemeOverride {
- background-color: rgba(255, 255, 255, 0.07);
- }
- }
-
- &.pressed {
- transform: scale(0.9) !important;
- }
- }
- &.selected {
- .icon {
- background-color: rgba(lighten($colorBlueBright, 9), 0.4);
- }
- // transform: scale(1.05);
- // @include S(border-radius, $globalBorderRadius);
-
- .keybinding {
- color: #111;
- }
- }
-
- .puzzle-lock {
- & {
- /* @load-async */
- background: uiResource("locked_building.png") center center / 90% no-repeat;
- }
-
- display: grid;
- grid-auto-flow: column;
-
- position: absolute;
- @include S(top, -15px);
- left: 50%;
- transform: translateX(-50%) !important;
- transition: all 0.12s ease-in-out;
- transition-property: opacity, transform;
-
- cursor: pointer;
- pointer-events: all;
-
- @include S(width, 12px);
- @include S(height, 12px);
-
- &:hover {
- opacity: 0.5;
- }
- }
- }
- }
- }
-}
+.ingame_buildingsToolbar {
+ position: absolute;
+ bottom: 1rem;
+ left: 50%;
+ transform: translateX(-50%);
+
+ display: grid;
+ grid-template-rows: auto auto;
+ justify-items: center;
+ grid-gap: 0.4rem;
+
+ background: transparent;
+ transition: transform 120ms ease-in-out;
+ will-change: transform;
+
+ &:not(.visible) {
+ transform: translateX(-50%) translateY(10rem);
+ }
+
+ .buildings {
+ display: grid;
+ grid-auto-flow: column;
+ justify-items: center;
+ align-self: center;
+ grid-gap: 0.2rem;
+ grid-row: 2 / 3;
+
+ border-radius: $globalBorderRadius;
+ padding: 0.2rem;
+ background-color: rgba($ingameHudBg, 0.07);
+
+ @include DarkThemeOverride {
+ background-color: rgba(darken($darkModeGameBackground, 15), 0.95);
+ }
+
+ &.secondary {
+ grid-row: 1 / 2;
+
+ .building {
+ width: 3rem;
+ height: 3rem;
+ background-size: 45%;
+
+ &:not(.unlocked) {
+ &::before {
+ background-size: 1.3rem;
+ }
+ }
+ }
+ }
+
+ .building {
+ display: flex;
+ width: 4rem;
+ position: relative;
+ height: 4rem;
+
+ @at-root html[data-tutorial-step="1_1_extractor"] &[data-id="miner"]:not(.selected),
+ html[data-tutorial-step="1_2_conveyor"] &[data-id="belt"]:not(.selected),
+ html[data-tutorial-step="2_1_place_cutter"] &[data-id="cutter"]:not(.selected),
+ html[data-tutorial-step="2_2_place_trash"] &[data-id="trash"]:not(.selected) {
+ &::before {
+ content: "";
+
+ & {
+ /* load-async */
+ background: uiResource("icons/tutorial_arrow.png") center center / contain no-repeat;
+ }
+
+ width: 2.5rem;
+ height: 2.5rem;
+ position: absolute;
+ left: 50%;
+ bottom: 100%;
+ transform: translateX(-50%);
+ @include InlineAnimation(1s ease-in-out infinite) {
+ 50% {
+ transform: translateX(-50%) translateY(20%);
+ }
+ }
+ }
+ border-radius: $globalBorderRadius;
+ box-shadow: 0 0 1rem 0.5rem rgba(74, 237, 134, 0.5) !important;
+ background: rgba(74, 237, 134, 0.5) !important;
+ }
+
+ .icon {
+ color: $accentColorDark;
+ display: flex;
+ flex-direction: column-reverse;
+ position: relative;
+ align-items: center;
+ justify-content: center;
+ width: 100%;
+ height: 100%;
+ padding: 0;
+ margin: 0;
+
+ background: center center / 70% no-repeat;
+ }
+
+ &:not(.unlocked) {
+ width: 2.5rem;
+ .icon {
+ opacity: 0.15;
+ }
+ &.editor {
+ .icon {
+ pointer-events: all;
+ cursor: pointer;
+ &:hover {
+ background-color: rgba(22, 30, 68, 0.1);
+ }
+ }
+ }
+ &:not(.editor) {
+ .icon {
+ background-image: uiResource("locked_building.png") !important;
+ }
+ }
+ }
+
+ &.unlocked {
+ .icon {
+ border-radius: $globalBorderRadius * 0.9;
+
+ pointer-events: all;
+ transition: all 0.12s ease-in-out;
+ transition-property: background-color, transform;
+ cursor: pointer;
+
+ &:hover {
+ background-color: rgba(30, 40, 90, 0.1);
+
+ @include DarkThemeOverride {
+ background-color: rgba(255, 255, 255, 0.07);
+ }
+ }
+
+ &.pressed {
+ transform: scale(0.9) !important;
+ }
+ }
+ &.selected {
+ .icon {
+ background-color: rgba(lighten($colorBlueBright, 9), 0.4);
+ }
+ // transform: scale(1.05);
+ // border-radius: $globalBorderRadius;
+
+ kbd {
+ color: #111;
+ }
+ }
+
+ .puzzle-lock {
+ & {
+ /* @load-async */
+ background: uiResource("locked_building.png") center center / 90% no-repeat;
+ }
+
+ display: grid;
+ grid-auto-flow: column;
+
+ position: absolute;
+ top: -1.5rem;
+ left: 50%;
+ transform: translateX(-50%) !important;
+ transition: all 0.12s ease-in-out;
+ transition-property: opacity, transform;
+
+ cursor: pointer;
+ pointer-events: all;
+
+ width: 1.2rem;
+ height: 1.2rem;
+
+ &:hover {
+ opacity: 0.5;
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/css/ingame_hud/color_blind_helper.scss b/src/css/ingame_hud/color_blind_helper.scss
index 027b781b..0c1fc780 100644
--- a/src/css/ingame_hud/color_blind_helper.scss
+++ b/src/css/ingame_hud/color_blind_helper.scss
@@ -4,8 +4,8 @@
@include SuperSmallText;
color: #fff;
background: $ingameHudBg;
- @include S(padding, 5px);
- @include S(top, 20px);
+ padding: 0.5rem;
+ top: 2rem;
left: 50%;
transform: translateX(-50%);
text-transform: uppercase;
diff --git a/src/css/ingame_hud/debug_info.scss b/src/css/ingame_hud/debug_info.scss
index 3a077d53..017e1f8f 100644
--- a/src/css/ingame_hud/debug_info.scss
+++ b/src/css/ingame_hud/debug_info.scss
@@ -1,7 +1,7 @@
#ingame_HUD_DebugInfo {
position: absolute;
- @include S(bottom, 5px);
- @include S(right, 5px);
+ bottom: 0.5rem;
+ right: 0.5rem;
text-align: right;
font-size: 15px;
@@ -28,7 +28,6 @@
font-size: 14px;
line-height: 15px;
padding: 1px;
- font-family: "GameFont";
border-radius: 3px;
}
}
diff --git a/src/css/ingame_hud/dialogs.scss b/src/css/ingame_hud/dialogs.scss
index 412a1911..433c5aa3 100644
--- a/src/css/ingame_hud/dialogs.scss
+++ b/src/css/ingame_hud/dialogs.scss
@@ -1,307 +1,296 @@
-.ingameDialog {
- position: absolute;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- pointer-events: all;
- background: $modalDialogBg;
-
- display: flex;
- align-items: center;
- justify-content: center;
-
- @include InlineAnimation(0.12s ease-in-out) {
- 0% {
- background-color: transparent;
- opacity: 0.5;
- }
- 100% {
- background-color: $modalDialogBg;
- }
- }
-
- $darkModeDialogBg: darken($darkModeGameBackground, 5);
-
- @include DarkThemeOverride {
- background: rgba($darkModeDialogBg, 0.9);
- @include InlineAnimation(0.12s ease-in-out) {
- 0% {
- background-color: transparent;
- opacity: 0.5;
- }
- 100% {
- background-color: rgba($darkModeDialogBg, 0.9);
- }
- }
-
- > .dialogInner.optionChooserDialog .optionParent {
- .option {
- background: $darkModeControlsBackground;
-
- &:hover {
- background-color: lighten($darkModeControlsBackground, 5);
- }
-
- &.active {
- background: $colorBlueBright;
- color: #fff;
- }
- }
- }
- }
-
- &.visible {
- .dialogInner {
- opacity: 1;
- }
- backdrop-filter: blur(D(3px));
- }
-
- .dialogInner {
- transition: opacity 0.2s ease-in-out;
- opacity: 0;
- }
-
- &.loadingDialog {
- * {
- color: #fff;
- }
-
- display: flex;
- flex-direction: column;
-
- .text {
- text-transform: uppercase;
- @include S(margin-bottom, 10px);
- }
- }
-
- > .dialogInner {
- background: #fff;
- max-height: calc(100vh - #{D(40px)});
- @include S(border-radius, $globalBorderRadius);
- display: flex;
- flex-direction: column;
- @include S(padding, 12px);
-
- box-shadow: 0 D(5px) D(15px) rgba(#000, 0.1);
- pointer-events: all;
-
- @include DarkThemeOverride {
- background: darken($darkModeControlsBackground, 5);
- }
-
- &.optionChooserDialog {
- .optionParent {
- display: grid;
- @include S(grid-gap, 5px);
- @include S(padding-right, 5px);
- grid-template-columns: 1fr 1fr;
- .option {
- @include S(border-radius, $globalBorderRadius);
-
- pointer-events: all;
- cursor: pointer;
- @include S(padding, 10px);
-
- background: #eee;
-
- transition: background-color 0.12s ease-in-out;
-
- &:hover {
- background-color: #e7e7e7;
- }
-
- &.active {
- background-color: $colorBlueBright;
- color: #fff;
- }
- }
- }
- }
-
- > .title {
- @include Heading;
- margin: 0;
- text-transform: uppercase;
- display: grid;
- align-items: center;
- grid-template-columns: 1fr auto;
- @include S(margin-bottom, 10px);
-
- @include DarkThemeInvert();
- > .closeButton {
- opacity: 0.7;
- @include S(width, 20px);
- @include S(height, 20px);
- cursor: pointer;
- pointer-events: all;
- transition: opacity 0.2s ease-in-out;
- &:hover {
- opacity: 0.4;
- }
- & {
- background: uiResource("icons/close.png") center center / 80% no-repeat;
- }
- }
- }
-
- > .content {
- @include PlainText;
- overflow-y: auto;
- pointer-events: all;
- @include S(width, 350px);
-
- @include DarkThemeOverride {
- color: #aaa;
- }
-
- a {
- color: $colorBlueBright;
- }
-
- strong {
- font-weight: bold;
- }
-
- .keybinding {
- position: relative;
- background: #eee;
- @include PlainText;
- height: unset;
- margin: 1px 0;
- }
-
- h3 {
- @include S(margin-top, 10px);
- }
-
- input {
- background: #eee;
- color: #333438;
- width: 100%;
-
- &.errored {
- background-color: rgb(250, 206, 206);
-
- &::placeholder {
- color: #fff;
- opacity: 0.8;
- }
- }
- }
-
- ul.bucketList {
- padding-left: 30px;
-
- li {
- display: list-item;
- }
- }
-
- .ingameItemChooser {
- @include S(margin, 10px, 0);
- display: grid;
- @include S(grid-column-gap, 3px);
- @include S(grid-row-gap, 5px);
- grid-template-columns: repeat(10, 1fr);
- align-items: center;
- justify-items: center;
-
- canvas {
- pointer-events: all;
- @include S(width, 25px);
- @include S(height, 25px);
- position: relative;
- cursor: pointer;
- @include IncreasedClickArea(3px);
-
- &:hover {
- opacity: 0.9;
- }
- }
- }
-
- .dialogModsMod {
- background: rgba(0, 0, 0, 0.05);
- @include S(padding, 5px);
- @include S(margin, 10px, 0);
- @include S(border-radius, $globalBorderRadius);
- display: grid;
- grid-template-columns: 1fr D(100px);
-
- @include DarkThemeOverride {
- background: rgba(0, 0, 0, 0.2);
- }
-
- button {
- grid-column: 2 / 3;
- grid-row: 1 / 3;
- align-self: start;
- }
-
- .version {
- @include SuperSmallText;
- opacity: 0.5;
- }
-
- .name {
- }
- }
- }
-
- > .buttons {
- @include S(margin-top, 15px);
- display: flex;
- justify-content: flex-end;
- > button {
- @include S(margin-left, 8px);
- @include Text;
- @include S(min-width, 60px);
- @include S(padding, 5px, 15px);
-
- transition: opacity 0.12s ease-in-out;
- &:hover {
- opacity: 0.9;
- }
-
- &.good {
- background-color: $colorGreenBright;
- color: #fff;
- }
-
- &.bad {
- background-color: $colorRedBright;
- color: #fff;
- }
-
- &.timedButton {
- pointer-events: none;
- cursor: default;
- position: relative;
- overflow: hidden;
- &::after {
- position: absolute;
- top: 0;
- right: 0;
- bottom: 0;
- left: unset;
- z-index: 5;
- content: " ";
- display: inline-block;
- background: rgba(#fff, 0.6);
- @include InlineAnimation(1s linear) {
- 0% {
- width: 100%;
- }
- 100% {
- width: 0%;
- }
- }
- }
- }
- }
- }
- }
-}
+.ingameDialog {
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ pointer-events: all;
+ background: $modalDialogBg;
+
+ display: flex;
+ align-items: center;
+ justify-content: center;
+
+ @include InlineAnimation(0.12s ease-in-out) {
+ 0% {
+ background-color: transparent;
+ opacity: 0.5;
+ }
+ 100% {
+ background-color: $modalDialogBg;
+ }
+ }
+
+ $darkModeDialogBg: darken($darkModeGameBackground, 5);
+
+ @include DarkThemeOverride {
+ background: rgba($darkModeDialogBg, 0.9);
+ @include InlineAnimation(0.12s ease-in-out) {
+ 0% {
+ background-color: transparent;
+ opacity: 0.5;
+ }
+ 100% {
+ background-color: rgba($darkModeDialogBg, 0.9);
+ }
+ }
+
+ > .dialogInner.optionChooserDialog .optionParent {
+ .option {
+ background: $darkModeControlsBackground;
+
+ &:hover {
+ background-color: lighten($darkModeControlsBackground, 5);
+ }
+
+ &.active {
+ background: $colorBlueBright;
+ color: #fff;
+ }
+ }
+ }
+ }
+
+ &.visible {
+ .dialogInner {
+ opacity: 1;
+ }
+ backdrop-filter: blur(0.3rem);
+ }
+
+ .dialogInner {
+ transition: opacity 0.2s ease-in-out;
+ opacity: 0;
+ }
+
+ &.loadingDialog {
+ * {
+ color: #fff;
+ }
+
+ display: flex;
+ flex-direction: column;
+
+ .text {
+ text-transform: uppercase;
+ margin-bottom: 1rem;
+ }
+ }
+
+ > .dialogInner {
+ background: #fff;
+ max-height: calc(100vh - 4rem);
+ border-radius: $globalBorderRadius;
+ display: flex;
+ flex-direction: column;
+ padding: 1.2rem;
+
+ box-shadow: 0 0.5rem 1.5rem rgba(#000, 0.1);
+ pointer-events: all;
+
+ @include DarkThemeOverride {
+ background: darken($darkModeControlsBackground, 5);
+ }
+
+ &.optionChooserDialog {
+ .optionParent {
+ display: grid;
+ grid-gap: 0.5rem;
+ padding-right: 0.5rem;
+ grid-template-columns: 1fr 1fr;
+ .option {
+ border-radius: $globalBorderRadius;
+
+ pointer-events: all;
+ cursor: pointer;
+ padding: 1rem;
+
+ background: #eee;
+
+ transition: background-color 0.12s ease-in-out;
+
+ &:hover {
+ background-color: #e7e7e7;
+ }
+
+ &.active {
+ background-color: $colorBlueBright;
+ color: #fff;
+ }
+ }
+ }
+ }
+
+ > .title {
+ @include Heading;
+ margin: 0;
+ text-transform: uppercase;
+ display: grid;
+ align-items: center;
+ grid-template-columns: 1fr auto;
+ margin-bottom: 1rem;
+
+ @include DarkThemeInvert();
+ > .closeButton {
+ opacity: 0.7;
+ width: 2rem;
+ height: 2rem;
+ cursor: pointer;
+ pointer-events: all;
+ transition: opacity 0.2s ease-in-out;
+ &:hover {
+ opacity: 0.4;
+ }
+ & {
+ background: uiResource("icons/close.png") center center / 80% no-repeat;
+ }
+ }
+ }
+
+ > .content {
+ @include PlainText;
+ overflow-y: auto;
+ pointer-events: all;
+ width: 35rem;
+
+ @include DarkThemeOverride {
+ color: #aaa;
+ }
+
+ a {
+ color: $colorBlueBright;
+ }
+
+ strong {
+ font-weight: bold;
+ }
+
+ // FIXME: Translations are still using code.keybinding instead of kbd
+ kbd,
+ .keybinding {
+ position: relative;
+ background: #eee;
+ @include PlainText;
+ height: unset;
+ margin: 1px 0;
+ }
+
+ h3 {
+ margin-top: 1rem;
+ }
+
+ input {
+ background: #eee;
+ color: #333438;
+ width: 100%;
+
+ &.errored {
+ background-color: rgb(250, 206, 206);
+
+ &::placeholder {
+ color: #fff;
+ opacity: 0.8;
+ }
+ }
+ }
+
+ .ingameItemChooser {
+ margin: 1rem 0;
+ display: grid;
+ grid-column-gap: 0.3rem;
+ grid-row-gap: 0.5rem;
+ grid-template-columns: repeat(10, 1fr);
+ place-items: center;
+
+ canvas {
+ pointer-events: all;
+ width: 2.5rem;
+ height: 2.5rem;
+ position: relative;
+ cursor: pointer;
+
+ &:hover {
+ opacity: 0.9;
+ }
+ }
+ }
+
+ .dialogModsMod {
+ background: rgba(0, 0, 0, 0.05);
+ padding: 0.5rem;
+ margin: 1rem 0;
+ border-radius: $globalBorderRadius;
+ display: grid;
+ grid-template-columns: 1fr 10rem;
+
+ @include DarkThemeOverride {
+ background: rgba(0, 0, 0, 0.2);
+ }
+
+ button {
+ grid-column: 2 / 3;
+ grid-row: 1 / 3;
+ align-self: start;
+ }
+
+ .version {
+ @include SuperSmallText;
+ opacity: 0.5;
+ }
+ }
+ }
+
+ > .buttons {
+ margin-top: 1.5rem;
+ display: flex;
+ justify-content: flex-end;
+ > button {
+ margin-left: 0.8rem;
+ @include Text;
+ min-width: 6rem;
+ padding: 0.5rem 1.5rem;
+
+ transition: opacity 0.12s ease-in-out;
+ &:hover {
+ opacity: 0.9;
+ }
+
+ &.good {
+ background-color: $colorGreenBright;
+ color: #fff;
+ }
+
+ &.bad {
+ background-color: $colorRedBright;
+ color: #fff;
+ }
+
+ &.timedButton {
+ pointer-events: none;
+ cursor: default;
+ position: relative;
+ overflow: hidden;
+ &::after {
+ position: absolute;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: unset;
+ z-index: 5;
+ content: " ";
+ display: inline-block;
+ background: rgba(#fff, 0.6);
+ @include InlineAnimation(1s linear) {
+ 0% {
+ width: 100%;
+ }
+ 100% {
+ width: 0%;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/css/ingame_hud/entity_debugger.scss b/src/css/ingame_hud/entity_debugger.scss
index 4cf7e5e9..3ce9c75c 100644
--- a/src/css/ingame_hud/entity_debugger.scss
+++ b/src/css/ingame_hud/entity_debugger.scss
@@ -1,8 +1,8 @@
#ingame_HUD_EntityDebugger {
position: absolute;
background: $ingameHudBg;
- @include S(padding, 5px);
- @include S(right, 30px);
+ padding: 0.5rem;
+ right: 3rem;
top: 50%;
transform: translateY(-50%);
@@ -26,7 +26,7 @@
}
.propertyTable {
- @include S(margin-top, 8px);
+ margin-top: 0.8rem;
}
.propertyTable,
@@ -34,16 +34,16 @@
.entityComponents .object > div {
display: grid;
grid-template-columns: 1fr auto;
- @include S(column-gap, 10px);
+ column-gap: 1rem;
}
.entityComponents {
grid-column: 1 / 3;
- @include S(margin-top, 5px);
+ margin-top: 0.5rem;
font-family: "Roboto Mono", "Fira Code", monospace;
font-size: 90%;
- @include S(letter-spacing, -0.5px);
+ letter-spacing: -0.05rem;
label,
span {
@@ -56,8 +56,8 @@
&,
* {
@include SuperSmallText;
- @include S(font-size, 7px, $important: true);
- @include S(line-height, 12px, $important: true);
+ font-size: 0.7rem !important;
+ line-height: 1.2rem !important;
}
.object {
@@ -72,7 +72,7 @@
}
}
> div {
- @include S(margin-left, 4px);
+ margin-left: 0.4rem;
cursor: pointer;
}
}
diff --git a/src/css/ingame_hud/game_menu.scss b/src/css/ingame_hud/game_menu.scss
index c95626f1..b8dedf2b 100644
--- a/src/css/ingame_hud/game_menu.scss
+++ b/src/css/ingame_hud/game_menu.scss
@@ -1,141 +1,139 @@
-#ingame_HUD_GameMenu {
- position: absolute;
- @include S(top, 10px);
- @include S(right, 10px);
- display: grid;
- grid-template-columns: 1fr 1fr 1fr 1fr;
- @include S(grid-gap, 6px);
-
- backdrop-filter: blur(D(1px));
-
- > button,
- > .button {
- @include PlainText;
- @include IncreasedClickArea(0px);
- background: green;
- @include S(width, 30px);
- @include S(height, 30px);
-
- pointer-events: all;
- cursor: pointer;
- position: relative;
- transition: all 0.12s ease-in-out;
- transition-property: opacity, transform;
-
- display: inline-flex;
- background: center center / 70% no-repeat;
- grid-row: 1;
-
- &.pressed {
- transform: scale(0.9) !important;
- }
-
- opacity: 0.7;
- &:hover {
- opacity: 0.9 !important;
- }
-
- @include DarkThemeInvert;
-
- &.shop {
- grid-column: 1;
- & {
- /* @load-async */
- background-image: uiResource("icons/shop.png");
- }
- }
-
- &.stats {
- grid-column: 2;
- & {
- /* @load-async */
- background-image: uiResource("icons/statistics.png");
- }
- }
-
- &.save {
- & {
- /* @load-async */
- background-image: uiResource("icons/save.png");
- }
- grid-column: 3;
- @include MakeAnimationWrappedEvenOdd(0.5s ease-in-out) {
- 0% {
- transform: scale(1, 1);
- }
-
- 70% {
- transform: scale(1.5, 1.5) rotate(20deg);
- opacity: 0.2;
- }
-
- 85% {
- transform: scale(0.9, 0.9);
- opacity: 1;
- }
-
- 90% {
- transform: scale(1.1, 1.1);
- }
- }
-
- &.saving {
- @include InlineAnimation(0.4s ease-in-out infinite) {
- 50% {
- opacity: 0.5;
- transform: scale(0.8);
- }
- }
- pointer-events: none;
- cursor: default;
- }
- }
-
- &.settings {
- grid-column: 4;
- & {
- /* @load-async */
- background-image: uiResource("icons/settings_menu_settings.png");
- }
- }
-
- &:hover {
- opacity: 0.9;
- transform: translateY(0);
- }
-
- &:not(.hasBadge) .badge {
- display: none;
- }
-
- &.hasBadge {
- &.shop {
- filter: none;
- opacity: 0.9;
-
- & {
- /* @load-async */
- background-image: uiResource("icons/shop_active.png");
- }
- }
-
- transform-origin: 50% 50%;
- @include InlineAnimation(0.8s ease-in-out infinite) {
- 50% {
- transform: scale(1.3) rotate(6deg);
- }
- }
-
- .badge {
- position: absolute;
- top: 50%;
- left: 50%;
- transform: translate(-50%, -50%);
- @include PlainText;
- display: flex;
- justify-content: center;
- align-items: center;
- }
- }
- }
-}
+#ingame_HUD_GameMenu {
+ position: absolute;
+ top: 1rem;
+ right: 1rem;
+ display: grid;
+ grid-template-columns: 1fr 1fr 1fr 1fr;
+ grid-gap: 0.6rem;
+
+ backdrop-filter: blur(0.1rem);
+
+ > button,
+ > .button {
+ @include PlainText;
+ width: 3rem;
+ height: 3rem;
+
+ pointer-events: all;
+ cursor: pointer;
+ position: relative;
+ transition: all 0.12s ease-in-out;
+ transition-property: opacity, transform;
+
+ display: inline-flex;
+ background: center center / 70% no-repeat;
+ grid-row: 1;
+
+ &.pressed {
+ transform: scale(0.9) !important;
+ }
+
+ opacity: 0.7;
+ &:hover {
+ opacity: 0.9 !important;
+ }
+
+ @include DarkThemeInvert;
+
+ &.shop {
+ grid-column: 1;
+ & {
+ /* @load-async */
+ background-image: uiResource("icons/shop.png");
+ }
+ }
+
+ &.stats {
+ grid-column: 2;
+ & {
+ /* @load-async */
+ background-image: uiResource("icons/statistics.png");
+ }
+ }
+
+ &.save {
+ & {
+ /* @load-async */
+ background-image: uiResource("icons/save.png");
+ }
+ grid-column: 3;
+ @include MakeAnimationWrappedEvenOdd(0.5s ease-in-out) {
+ 0% {
+ transform: scale(1, 1);
+ }
+
+ 70% {
+ transform: scale(1.5, 1.5) rotate(20deg);
+ opacity: 0.2;
+ }
+
+ 85% {
+ transform: scale(0.9, 0.9);
+ opacity: 1;
+ }
+
+ 90% {
+ transform: scale(1.1, 1.1);
+ }
+ }
+
+ &.saving {
+ @include InlineAnimation(0.4s ease-in-out infinite) {
+ 50% {
+ opacity: 0.5;
+ transform: scale(0.8);
+ }
+ }
+ pointer-events: none;
+ cursor: default;
+ }
+ }
+
+ &.settings {
+ grid-column: 4;
+ & {
+ /* @load-async */
+ background-image: uiResource("icons/settings_menu_settings.png");
+ }
+ }
+
+ &:hover {
+ opacity: 0.9;
+ transform: translateY(0);
+ }
+
+ &:not(.hasBadge) .badge {
+ display: none;
+ }
+
+ &.hasBadge {
+ &.shop {
+ filter: none;
+ opacity: 0.9;
+
+ & {
+ /* @load-async */
+ background-image: uiResource("icons/shop_active.png");
+ }
+ }
+
+ transform-origin: 50% 50%;
+ @include InlineAnimation(0.8s ease-in-out infinite) {
+ 50% {
+ transform: scale(1.3) rotate(6deg);
+ }
+ }
+
+ .badge {
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ @include PlainText;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ }
+ }
+ }
+}
diff --git a/src/css/ingame_hud/interactive_tutorial.scss b/src/css/ingame_hud/interactive_tutorial.scss
index dad52841..cb802935 100644
--- a/src/css/ingame_hud/interactive_tutorial.scss
+++ b/src/css/ingame_hud/interactive_tutorial.scss
@@ -1,21 +1,21 @@
#ingame_HUD_InteractiveTutorial {
position: absolute;
- @include S(left, 10px);
- @include S(bottom, 10px);
+ left: 1rem;
+ bottom: 1rem;
@include StyleBelowWidth(1430px) {
- @include S(bottom, 10px + 40px);
+ bottom: 5rem;
}
- @include S(width, 150px);
+ width: 15rem;
background: $ingameHudBg;
- @include S(padding, 7px);
+ padding: 0.7rem;
color: #eee;
display: flex;
flex-direction: column;
- @include S(border-radius, $globalBorderRadius);
+ border-radius: $globalBorderRadius;
@include MakeAnimationWrappedEvenOdd(0.5s ease-in-out) {
0% {
@@ -49,11 +49,11 @@
}
.helperGif {
- @include S(margin-top, 5px);
- @include S(width, 150px);
- @include S(height, 150px);
+ margin-top: 0.5rem;
+ width: 15rem;
+ height: 15rem;
background: center center / cover no-repeat;
transition: opacity 0.1s ease-out;
- @include S(border-radius, $globalBorderRadius);
+ border-radius: $globalBorderRadius;
}
}
diff --git a/src/css/ingame_hud/keybindings_overlay.scss b/src/css/ingame_hud/keybindings_overlay.scss
index b44dde4b..2f19bd9b 100644
--- a/src/css/ingame_hud/keybindings_overlay.scss
+++ b/src/css/ingame_hud/keybindings_overlay.scss
@@ -1,76 +1,77 @@
-#ingame_HUD_KeybindingOverlay {
- position: absolute;
- @include S(top, 10px);
- @include S(left, 10px);
-
- display: flex;
- flex-direction: column;
- align-items: flex-start;
- color: #333438;
- backdrop-filter: blur(D(1px));
- padding: D(3px);
-
- @include DarkThemeOverride {
- color: #fff;
- }
-
- transition: opacity 0.1s ease-out;
- &.hovered {
- opacity: 0.1;
- }
-
- > .binding {
- &:not(.visible) {
- display: none !important;
- }
-
- display: inline-grid;
- @include PlainText;
- align-items: center;
- @include S(margin-bottom, 3px);
- grid-auto-flow: column;
- @include S(grid-gap, 2px);
-
- i {
- display: inline-block;
- @include S(height, 10px);
- width: 1px;
- @include S(margin, 0, 3px);
- background-color: #fff;
- transform: rotate(10deg);
- // @include S(margin, 0, 3px);
- }
-
- code {
- position: relative;
- top: unset;
- left: unset;
- margin: 0;
- &.rightMouse {
- /* @load-async */
- background: #fff uiResource("icons/mouse_right.png") center center / 85% no-repeat;
- }
-
- &.leftMouse {
- /* @load-async */
- background: #fff uiResource("icons/mouse_left.png") center center / 85% no-repeat;
- }
- }
-
- label {
- color: #333438;
- @include SuperSmallText;
- text-transform: uppercase;
- // color: #fff;
- @include DarkThemeOverride {
- color: #fff;
- }
-
- @include S(margin-left, 5px);
- }
- }
-}
-
-body.uiHidden #ingame_HUD_KeybindingOverlay .binding:not(.hudToggle) {
- display: none;
-}
+#ingame_HUD_KeybindingOverlay {
+ position: absolute;
+ top: 1rem;
+ left: 1rem;
+
+ display: flex;
+ flex-direction: column;
+ align-items: flex-start;
+ color: #333438;
+ backdrop-filter: blur(0.1rem);
+ padding: 0.3rem;
+
+ @include DarkThemeOverride {
+ color: #fff;
+ }
+
+ transition: opacity 0.1s ease-out;
+ &.hovered {
+ opacity: 0.1;
+ }
+
+ > .binding {
+ &:not(.visible) {
+ display: none !important;
+ }
+
+ display: inline-grid;
+ @include PlainText;
+ align-items: center;
+ margin-bottom: 0.3rem;
+ grid-auto-flow: column;
+ grid-gap: 0.2rem;
+
+ i {
+ display: inline-block;
+ height: 1rem;
+ width: 1px;
+ margin: 0 0.3rem;
+ background-color: #fff;
+ transform: rotate(10deg);
+ // margin: 0 .3rem;
+ }
+
+ kbd {
+ position: relative;
+ top: unset;
+ left: unset;
+ margin: 0;
+
+ &.rightMouse {
+ /* @load-async */
+ background: #fff uiResource("icons/mouse_right.png") center center / 85% no-repeat;
+ }
+
+ &.leftMouse {
+ /* @load-async */
+ background: #fff uiResource("icons/mouse_left.png") center center / 85% no-repeat;
+ }
+ }
+
+ label {
+ color: #333438;
+ @include SuperSmallText;
+ text-transform: uppercase;
+ // color: #fff;
+ @include DarkThemeOverride {
+ color: #fff;
+ }
+
+ margin-left: 0.5rem;
+ }
+ }
+}
+
+body.uiHidden #ingame_HUD_KeybindingOverlay .binding:not(.hudToggle) {
+ display: none;
+}
diff --git a/src/css/ingame_hud/notifications.scss b/src/css/ingame_hud/notifications.scss
index 4b8ee767..f5db5fe9 100644
--- a/src/css/ingame_hud/notifications.scss
+++ b/src/css/ingame_hud/notifications.scss
@@ -1,27 +1,27 @@
#ingame_HUD_Notifications {
position: absolute;
- @include S(bottom, 60px);
- @include S(right, 10px);
+ bottom: 6rem;
+ right: 1rem;
.notification {
background: rgba(#333438, 0.8);
- @include S(border-radius, $globalBorderRadius);
- @include S(margin-top, 3px);
+ border-radius: $globalBorderRadius;
+ margin-top: 0.3rem;
color: #fff;
@include SuperSmallText;
- @include S(padding, 7px, 10px);
- @include S(width, 150px);
+ padding: 0.7rem 1rem;
+ width: 15rem;
@include DarkThemeOverride {
background-color: rgba(#55595d, 0.8);
}
&[data-icon] {
- @include S(background-position-x, 8px);
+ background-position-x: 0.8rem;
background-position-y: center;
- @include S(padding-left, 35px);
+ padding-left: 3.5rem;
background-repeat: no-repeat;
- @include S(background-size, 15px);
+ background-size: 1.5rem;
}
transform-origin: 100% 50%;
diff --git a/src/css/ingame_hud/pinned_shapes.scss b/src/css/ingame_hud/pinned_shapes.scss
index c9a39536..e7ef4691 100644
--- a/src/css/ingame_hud/pinned_shapes.scss
+++ b/src/css/ingame_hud/pinned_shapes.scss
@@ -1,156 +1,154 @@
-#ingame_HUD_PinnedShapes {
- position: absolute;
- @include S(left, 9px);
- @include S(top, 150px);
- @include PlainText;
- display: flex;
- flex-direction: column;
- align-items: flex-start;
- justify-content: flex-start;
-
- > .shape {
- position: relative;
- display: grid;
- align-items: center;
- justify-content: center;
- grid-template-columns: auto 1fr;
- grid-template-rows: 1fr 1fr;
- @include S(margin-bottom, 4px);
- color: #333438;
-
- &.removable {
- pointer-events: all;
- }
-
- > canvas {
- @include S(width, 25px);
- @include S(height, 25px);
- grid-column: 1 / 2;
- grid-row: 1 / 3;
- pointer-events: none;
- z-index: 20;
- position: relative;
- }
-
- > .amountLabel,
- > .goalLabel {
- @include S(margin-left, 5px);
- @include SuperSmallText;
- font-weight: bold;
- display: inline-flex;
- align-items: center;
- flex-direction: row;
- grid-column: 2 / 3;
- @include S(height, 9px);
-
- @include DarkThemeOverride {
- color: #eee;
- }
- }
-
- > .goalLabel {
- @include S(font-size, 7px);
- opacity: 0.9;
- align-self: start;
- justify-self: start;
- font-weight: normal;
- grid-row: 2 / 3;
- }
-
- > .amountLabel {
- align-self: end;
- justify-self: start;
- grid-row: 1 / 2;
- }
-
- > .infoButton {
- @include S(width, 8px);
- @include S(height, 8px);
- position: absolute;
- opacity: 0.7;
- @include S(top, 13px);
- @include S(left, -7px);
- @include DarkThemeInvert;
- @include IncreasedClickArea(2px);
- transition: opacity 0.12s ease-in-out;
- z-index: 100;
-
- &:hover {
- opacity: 0.8;
- }
-
- & {
- /* @load-async */
- background: uiResource("icons/info_button.png") center center / 95% no-repeat;
- }
- }
-
- > .unpinButton {
- @include S(width, 8px);
- @include S(height, 8px);
- position: absolute;
- opacity: 0.7;
- @include S(top, 3px);
- @include S(left, -7px);
- @include DarkThemeInvert;
- @include IncreasedClickArea(2px);
- transition: opacity 0.12s ease-in-out;
- z-index: 100;
-
- &:hover {
- opacity: 0.8;
- }
-
- & {
- /* @load-async */
- background: uiResource("icons/unpin_shape.png") center center / 80% no-repeat;
- }
- }
-
- &.goal,
- &.blueprint {
- .amountLabel::after {
- content: " ";
- position: absolute;
- display: inline-block;
- @include S(width, 8px);
- @include S(height, 8px);
- @include S(top, 4px);
- @include S(left, -7px);
- background: center center / contain no-repeat;
- }
-
- &.goal .amountLabel {
- &::after {
- /* @load-async */
- background-image: uiResource("icons/current_goal_marker.png");
- background-size: 90%;
- }
- @include DarkThemeOverride {
- &::after {
- /* @load-async */
- background-image: uiResource("icons/current_goal_marker_inverted.png") !important;
- }
- }
- }
-
- &.blueprint .amountLabel {
- &::after {
- /* @load-async */
- background-image: uiResource("icons/blueprint_marker.png");
- background-size: 90%;
- }
- @include DarkThemeOverride {
- &::after {
- /* @load-async */
- background-image: uiResource("icons/blueprint_marker_inverted.png") !important;
- }
- }
- }
- }
-
- &.completed {
- opacity: 0.5;
- }
- }
-}
+#ingame_HUD_PinnedShapes {
+ position: absolute;
+ left: 0.9rem;
+ top: 15rem;
+ @include PlainText;
+ display: flex;
+ flex-direction: column;
+ align-items: flex-start;
+ justify-content: flex-start;
+
+ > .shape {
+ position: relative;
+ display: grid;
+ align-items: center;
+ justify-content: center;
+ grid-template-columns: auto 1fr;
+ grid-template-rows: 1fr 1fr;
+ margin-bottom: 0.4rem;
+ color: #333438;
+
+ &.removable {
+ pointer-events: all;
+ }
+
+ > canvas {
+ width: 2.5rem;
+ height: 2.5rem;
+ grid-column: 1 / 2;
+ grid-row: 1 / 3;
+ pointer-events: none;
+ z-index: 20;
+ position: relative;
+ }
+
+ > .amountLabel,
+ > .goalLabel {
+ margin-left: 0.5rem;
+ @include SuperSmallText;
+ font-weight: bold;
+ display: inline-flex;
+ align-items: center;
+ flex-direction: row;
+ grid-column: 2 / 3;
+ height: 0.9rem;
+
+ @include DarkThemeOverride {
+ color: #eee;
+ }
+ }
+
+ > .goalLabel {
+ font-size: 0.7rem;
+ opacity: 0.9;
+ align-self: start;
+ justify-self: start;
+ font-weight: normal;
+ grid-row: 2 / 3;
+ }
+
+ > .amountLabel {
+ align-self: end;
+ justify-self: start;
+ grid-row: 1 / 2;
+ }
+
+ > .infoButton {
+ width: 0.8rem;
+ height: 0.8rem;
+ position: absolute;
+ opacity: 0.7;
+ top: 1.3rem;
+ left: -0.7rem;
+ @include DarkThemeInvert;
+ transition: opacity 0.12s ease-in-out;
+ z-index: 100;
+
+ &:hover {
+ opacity: 0.8;
+ }
+
+ & {
+ /* @load-async */
+ background: uiResource("icons/info_button.png") center center / 95% no-repeat;
+ }
+ }
+
+ > .unpinButton {
+ width: 0.8rem;
+ height: 0.8rem;
+ position: absolute;
+ opacity: 0.7;
+ top: 0.3rem;
+ left: -0.7rem;
+ @include DarkThemeInvert;
+ transition: opacity 0.12s ease-in-out;
+ z-index: 100;
+
+ &:hover {
+ opacity: 0.8;
+ }
+
+ & {
+ /* @load-async */
+ background: uiResource("icons/unpin_shape.png") center center / 80% no-repeat;
+ }
+ }
+
+ &.goal,
+ &.blueprint {
+ .amountLabel::after {
+ content: " ";
+ position: absolute;
+ display: inline-block;
+ width: 0.8rem;
+ height: 0.8rem;
+ top: 0.4rem;
+ left: -0.7rem;
+ background: center center / contain no-repeat;
+ }
+
+ &.goal .amountLabel {
+ &::after {
+ /* @load-async */
+ background-image: uiResource("icons/current_goal_marker.png");
+ background-size: 90%;
+ }
+ @include DarkThemeOverride {
+ &::after {
+ /* @load-async */
+ background-image: uiResource("icons/current_goal_marker_inverted.png") !important;
+ }
+ }
+ }
+
+ &.blueprint .amountLabel {
+ &::after {
+ /* @load-async */
+ background-image: uiResource("icons/blueprint_marker.png");
+ background-size: 90%;
+ }
+ @include DarkThemeOverride {
+ &::after {
+ /* @load-async */
+ background-image: uiResource("icons/blueprint_marker_inverted.png") !important;
+ }
+ }
+ }
+ }
+
+ &.completed {
+ opacity: 0.5;
+ }
+ }
+}
diff --git a/src/css/ingame_hud/puzzle_back_to_menu.scss b/src/css/ingame_hud/puzzle_back_to_menu.scss
index 564b592e..e103b183 100644
--- a/src/css/ingame_hud/puzzle_back_to_menu.scss
+++ b/src/css/ingame_hud/puzzle_back_to_menu.scss
@@ -1,13 +1,13 @@
#ingame_HUD_PuzzleBackToMenu {
position: absolute;
- @include S(top, 10px);
- @include S(left, 0px);
+ top: 1rem;
+ left: 0rem;
display: flex;
flex-direction: column;
align-items: flex-start;
- backdrop-filter: blur(D(1px));
- padding: D(3px);
+ backdrop-filter: blur(0.1rem);
+ padding: 0.3rem;
> .button {
@include PlainText;
@@ -19,8 +19,8 @@
transition-property: opacity, transform;
text-transform: uppercase;
@include PlainText;
- @include S(width, 30px);
- @include S(height, 30px);
+ width: 3rem;
+ height: 3rem;
@include DarkThemeInvert;
@@ -35,7 +35,7 @@
& {
/* @load-async */
- background: uiResource("icons/state_back_button.png") center center / D(15px) no-repeat;
+ background: uiResource("icons/state_back_button.png") center center / 1.5rem no-repeat;
}
}
}
diff --git a/src/css/ingame_hud/puzzle_complete_notification.scss b/src/css/ingame_hud/puzzle_complete_notification.scss
index a35da83d..e6e77844 100644
--- a/src/css/ingame_hud/puzzle_complete_notification.scss
+++ b/src/css/ingame_hud/puzzle_complete_notification.scss
@@ -13,7 +13,7 @@
& {
/* @load-async */
- background: rgba(#333538, 0.95) uiResource("dialog_bg_pattern.png") top left / #{D(10px)} repeat;
+ background: rgba(#333538, 0.95) uiResource("dialog_bg_pattern.png") top left / 1rem repeat;
}
@include InlineAnimation(0.1s ease-in-out) {
@@ -24,8 +24,8 @@
> .dialog {
// background: rgba(#222428, 0.5);
- @include S(border-radius, $globalBorderRadius);
- @include S(padding, 30px);
+ border-radius: $globalBorderRadius;
+ padding: 3rem;
@include InlineAnimation(0.5s ease-in-out) {
0% {
@@ -43,8 +43,8 @@
> .title {
@include SuperHeading;
text-transform: uppercase;
- @include S(font-size, 30px);
- @include S(margin-bottom, 40px);
+ font-size: 3rem;
+ margin-bottom: 4rem;
color: $colorGreenBright !important;
@include InlineAnimation(0.5s ease-in-out) {
@@ -82,23 +82,24 @@
> .stepLike {
display: flex;
flex-direction: column;
- @include S(margin-bottom, 10px);
+ margin-bottom: 1rem;
@include SuperSmallText;
> .buttons {
display: flex;
align-items: center;
justify-content: center;
- @include S(margin, 10px, 0);
+ margin: 1rem 0;
> button {
- @include S(width, 60px);
- @include S(height, 60px);
- @include S(margin, 0, 10px);
+ width: 6rem;
+ height: 6rem;
+ margin: 0 1rem;
box-sizing: border-box;
border-radius: 50%;
- transition: opacity 0.12s ease-in-out, background-color 0.12s ease-in-out;
- @include IncreasedClickArea(0px);
+ transition:
+ opacity 0.12s ease-in-out,
+ background-color 0.12s ease-in-out;
&.liked-yes {
/* @load-async */
@@ -133,7 +134,7 @@
> .buttonBar {
display: flex;
- @include S(margin-top, 20px);
+ margin-top: 2rem;
button.continue {
background: #555;
@@ -148,19 +149,18 @@
}
> button {
- @include S(min-width, 100px);
- @include S(padding, 8px, 16px);
- @include S(margin, 0, 6px);
- @include IncreasedClickArea(0px);
+ min-width: 10rem;
+ padding: 0.8rem 1.6rem;
+ margin: 0 0.6rem;
}
}
> .actions {
position: absolute;
- @include S(bottom, 40px);
+ bottom: 4rem;
display: grid;
- @include S(grid-gap, 15px);
+ grid-gap: 1.5rem;
grid-auto-flow: column;
button {
diff --git a/src/css/ingame_hud/puzzle_dlc_logo.scss b/src/css/ingame_hud/puzzle_dlc_logo.scss
index c2a64607..bab78f5d 100644
--- a/src/css/ingame_hud/puzzle_dlc_logo.scss
+++ b/src/css/ingame_hud/puzzle_dlc_logo.scss
@@ -1,9 +1,9 @@
#ingame_HUD_PuzzleDLCLogo {
position: absolute;
- @include S(width, 120px);
- @include S(height, 40px);
- @include S(left, 40px);
- @include S(top, 7px);
+ width: 12rem;
+ height: 4rem;
+ left: 4rem;
+ top: 0.7rem;
& {
/* @load-async */
@@ -16,9 +16,4 @@
background: uiResource("puzzle_dlc_logo_inverse.png") center center / contain no-repeat;
}
}
-
- &.china {
- /* @load-async */
- background: uiResource("puzzle_dlc_logo_china.png") center center / contain no-repeat !important;
- }
}
diff --git a/src/css/ingame_hud/puzzle_editor_controls.scss b/src/css/ingame_hud/puzzle_editor_controls.scss
index 7ce76b41..99f4cf5d 100644
--- a/src/css/ingame_hud/puzzle_editor_controls.scss
+++ b/src/css/ingame_hud/puzzle_editor_controls.scss
@@ -1,16 +1,16 @@
#ingame_HUD_PuzzleEditorControls {
position: absolute;
- @include S(top, 70px);
- @include S(left, 10px);
+ top: 7rem;
+ left: 1rem;
display: flex;
flex-direction: column;
@include SuperDuperSmallText;
- @include S(width, 200px);
+ width: 20rem;
> span {
- @include S(margin-bottom, 10px);
+ margin-bottom: 1rem;
strong {
font-weight: bold;
@@ -23,7 +23,7 @@
#ingame_HUD_PuzzleEditorTitle {
position: absolute;
- @include S(top, 18px);
+ top: 1.8rem;
left: 50%;
transform: translateX(-50%);
text-transform: uppercase;
diff --git a/src/css/ingame_hud/puzzle_editor_review.scss b/src/css/ingame_hud/puzzle_editor_review.scss
index 523d8025..82ccbb24 100644
--- a/src/css/ingame_hud/puzzle_editor_review.scss
+++ b/src/css/ingame_hud/puzzle_editor_review.scss
@@ -1,17 +1,16 @@
#ingame_HUD_PuzzleEditorReview {
position: absolute;
- @include S(top, 17px);
- @include S(right, 10px);
+ top: 1.7rem;
+ right: 1rem;
display: flex;
flex-direction: column;
align-items: flex-end;
- backdrop-filter: blur(D(1px));
- padding: D(3px);
+ backdrop-filter: blur(0.1rem);
+ padding: 0.3rem;
> .button {
@include ButtonText;
- @include IncreasedClickArea(0px);
pointer-events: all;
cursor: pointer;
position: relative;
@@ -20,7 +19,7 @@
text-transform: uppercase;
transition-property: opacity, transform;
@include PlainText;
- @include S(padding-right, 25px);
+ padding-right: 2.5rem;
opacity: 1;
@include DarkThemeInvert;
@@ -35,14 +34,14 @@
& {
/* @load-async */
- background: uiResource("icons/state_next_button.png") right center / D(15px) no-repeat;
+ background: uiResource("icons/state_next_button.png") right center / 1.5rem no-repeat;
}
}
> .content {
@include SuperDuperSmallText;
- @include S(width, 180px);
- @include S(padding-right, 25px);
+ width: 18rem;
+ padding-right: 2.5rem;
text-align: right;
text-transform: uppercase;
color: $accentColorDark;
diff --git a/src/css/ingame_hud/puzzle_editor_settings.scss b/src/css/ingame_hud/puzzle_editor_settings.scss
index 9d093c42..a3276524 100644
--- a/src/css/ingame_hud/puzzle_editor_settings.scss
+++ b/src/css/ingame_hud/puzzle_editor_settings.scss
@@ -1,71 +1,70 @@
-#ingame_HUD_PuzzleEditorSettings {
- position: absolute;
- background: $ingameHudBg;
- @include S(padding, 10px);
- @include S(bottom, 60px);
- @include S(left, 10px);
-
- @include SuperSmallText;
- color: #eee;
- display: flex;
- flex-direction: column;
- @include S(border-radius, $globalBorderRadius);
-
- > .section {
- > label {
- text-transform: uppercase;
- }
-
- .plusMinus {
- @include S(margin-top, 5px);
- display: grid;
- grid-template-columns: 1fr auto auto auto;
- align-items: center;
- @include S(grid-gap, 5px);
-
- label {
- @include S(margin-right, 10px);
- }
-
- button {
- @include PlainText;
- @include S(padding, 0);
- display: flex;
- align-items: center;
- justify-content: center;
- @include S(width, 15px);
- @include S(height, 15px);
- @include IncreasedClickArea(0px);
- }
-
- .value {
- text-align: center;
- @include S(min-width, 15px);
- }
- }
-
- > .buttons {
- > .buttonBar {
- display: flex;
- align-items: center;
- @include S(margin-top, 10px);
- > button {
- @include S(margin-right, 4px);
- @include SuperSmallText;
- &:last-child {
- margin-right: 0;
- }
- }
- }
-
- > .buildingsButton {
- display: grid;
- align-items: center;
- @include S(margin-top, 4px);
- > button {
- @include SuperSmallText;
- }
- }
- }
- }
-}
+#ingame_HUD_PuzzleEditorSettings {
+ position: absolute;
+ background: $ingameHudBg;
+ padding: 1rem;
+ bottom: 6rem;
+ left: 1rem;
+
+ @include SuperSmallText;
+ color: #eee;
+ display: flex;
+ flex-direction: column;
+ border-radius: $globalBorderRadius;
+
+ > .section {
+ > label {
+ text-transform: uppercase;
+ }
+
+ .plusMinus {
+ margin-top: 0.5rem;
+ display: grid;
+ grid-template-columns: 1fr auto auto auto;
+ align-items: center;
+ grid-gap: 0.5rem;
+
+ label {
+ margin-right: 1rem;
+ }
+
+ button {
+ @include PlainText;
+ padding: 0;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 1.5rem;
+ height: 1.5rem;
+ }
+
+ .value {
+ text-align: center;
+ min-width: 1.5rem;
+ }
+ }
+
+ > .buttons {
+ > .buttonBar {
+ display: flex;
+ align-items: center;
+ margin-top: 1rem;
+ > button {
+ margin-right: 0.4rem;
+ @include SuperSmallText;
+ &:last-child {
+ margin-right: 0;
+ }
+ }
+ }
+
+ > .buildingsButton {
+ display: grid;
+ align-items: center;
+ margin-top: 0.4rem;
+ > button {
+ @include SuperSmallText;
+ }
+ }
+ }
+ }
+}
diff --git a/src/css/ingame_hud/puzzle_next.scss b/src/css/ingame_hud/puzzle_next.scss
index ee0f664f..de415ed7 100644
--- a/src/css/ingame_hud/puzzle_next.scss
+++ b/src/css/ingame_hud/puzzle_next.scss
@@ -1,17 +1,16 @@
#ingame_HUD_PuzzleNextPuzzle {
position: absolute;
- @include S(top, 17px);
- @include S(right, 10px);
+ top: 1.7rem;
+ right: 1rem;
display: flex;
flex-direction: column;
align-items: flex-end;
- backdrop-filter: blur(D(1px));
- padding: D(3px);
+ backdrop-filter: blur(0.1rem);
+ padding: 0.3rem;
> .button {
@include ButtonText;
- @include IncreasedClickArea(0px);
pointer-events: all;
cursor: pointer;
position: relative;
@@ -20,7 +19,7 @@
text-transform: uppercase;
transition-property: opacity, transform;
@include PlainText;
- @include S(padding-right, 25px);
+ padding-right: 2.5rem;
opacity: 1;
@include DarkThemeInvert;
@@ -35,7 +34,7 @@
& {
/* @load-async */
- background: uiResource("icons/state_next_button.png") right center / D(15px) no-repeat;
+ background: uiResource("icons/state_next_button.png") right center / 1.5rem no-repeat;
}
}
}
diff --git a/src/css/ingame_hud/puzzle_play_metadata.scss b/src/css/ingame_hud/puzzle_play_metadata.scss
index d0675b13..66ffa7de 100644
--- a/src/css/ingame_hud/puzzle_play_metadata.scss
+++ b/src/css/ingame_hud/puzzle_play_metadata.scss
@@ -1,18 +1,18 @@
#ingame_HUD_PuzzlePlayMetadata {
position: absolute;
- @include S(top, 70px);
- @include S(left, 10px);
+ top: 7rem;
+ left: 1rem;
display: flex;
flex-direction: column;
- @include S(width, 200px);
+ width: 20rem;
> .info {
display: flex;
flex-direction: column;
@include SuperSmallText;
- @include S(margin-bottom, 5px);
+ margin-bottom: 0.5rem;
> label {
text-transform: uppercase;
@@ -35,7 +35,7 @@
justify-self: end;
align-self: end;
flex-direction: row;
- @include S(margin-bottom, 10px);
+ margin-bottom: 1rem;
opacity: 0.8;
@include DarkThemeInvert;
@include DarkThemeOverride {
@@ -48,8 +48,8 @@
align-self: start;
justify-self: start;
font-weight: bold;
- @include S(margin-right, 10px);
- @include S(padding-left, 14px);
+ margin-right: 1rem;
+ padding-left: 1.4rem;
opacity: 0.7;
display: inline-flex;
align-items: center;
@@ -57,7 +57,7 @@
& {
/* @load-async */
- background: uiResource("icons/puzzle_plays.png") #{D(2px)} center / #{D(8px)} #{D(8px)} no-repeat;
+ background: uiResource("icons/puzzle_plays.png") 0.2rem center / 0.8rem 0.8rem no-repeat;
}
}
@@ -69,25 +69,25 @@
align-self: start;
justify-self: start;
font-weight: bold;
- @include S(padding-left, 14px);
+ padding-left: 1.4rem;
opacity: 0.7;
& {
/* @load-async */
- background: uiResource("icons/puzzle_upvotes.png") #{D(2px)} center / #{D(8px)} #{D(8px)} no-repeat;
+ background: uiResource("icons/puzzle_upvotes.png") 0.2rem center / 0.8rem 0.8rem no-repeat;
}
}
}
> .key {
button {
- @include S(margin-top, 2px);
+ margin-top: 0.2rem;
}
}
button {
@include SuperSmallText;
align-self: start;
- @include S(min-width, 50px);
+ min-width: 5rem;
&.report {
background-color: $accentColorDark;
@@ -100,7 +100,7 @@
flex-direction: column;
> button {
- @include S(margin-bottom, 4px);
+ margin-bottom: 0.4rem;
}
}
}
@@ -108,7 +108,7 @@
#ingame_HUD_PuzzlePlayTitle {
position: absolute;
- @include S(top, 18px);
+ top: 1.8rem;
left: 50%;
transform: translateX(-50%);
text-transform: uppercase;
diff --git a/src/css/ingame_hud/puzzle_play_settings.scss b/src/css/ingame_hud/puzzle_play_settings.scss
index b53d0829..e815732d 100644
--- a/src/css/ingame_hud/puzzle_play_settings.scss
+++ b/src/css/ingame_hud/puzzle_play_settings.scss
@@ -1,19 +1,19 @@
#ingame_HUD_PuzzlePlaySettings {
position: absolute;
background: $ingameHudBg;
- @include S(padding, 10px);
- @include S(bottom, 60px);
- @include S(left, 10px);
+ padding: 1rem;
+ bottom: 6rem;
+ left: 1rem;
@include SuperSmallText;
color: #eee;
display: flex;
flex-direction: column;
- @include S(border-radius, $globalBorderRadius);
+ border-radius: $globalBorderRadius;
> .section {
display: grid;
- @include S(grid-gap, 5px);
+ grid-gap: 0.5rem;
grid-auto-flow: row;
> button {
diff --git a/src/css/ingame_hud/sandbox_controller.scss b/src/css/ingame_hud/sandbox_controller.scss
index e4680fe4..5a86de35 100644
--- a/src/css/ingame_hud/sandbox_controller.scss
+++ b/src/css/ingame_hud/sandbox_controller.scss
@@ -1,50 +1,48 @@
-#ingame_HUD_SandboxController {
- position: absolute;
- background: $ingameHudBg;
- @include S(padding, 5px);
- @include S(bottom, 10px);
- @include S(left, 10px);
-
- @include SuperSmallText;
- color: #eee;
- display: flex;
- flex-direction: column;
-
- > label {
- text-transform: uppercase;
- }
-
- .sandboxHint {
- color: #aaa;
- }
-
- .plusMinus {
- @include S(margin-top, 4px);
- display: grid;
- grid-template-columns: 1fr auto auto;
- align-items: center;
- @include S(grid-gap, 4px);
-
- button {
- @include PlainText;
- @include S(padding, 0);
- display: flex;
- align-items: center;
- justify-content: center;
- @include S(width, 15px);
- @include S(height, 15px);
- @include IncreasedClickArea(0px);
- }
- }
-
- .additionalOptions {
- display: flex;
- flex-direction: column;
- @include S(margin-top, 10px);
- button {
- @include S(margin-bottom, 2px);
- @include IncreasedClickArea(0px);
- @include SuperSmallText;
- }
- }
-}
+#ingame_HUD_SandboxController {
+ position: absolute;
+ background: $ingameHudBg;
+ padding: 0.5rem;
+ bottom: 1rem;
+ left: 1rem;
+
+ @include SuperSmallText;
+ color: #eee;
+ display: flex;
+ flex-direction: column;
+
+ > label {
+ text-transform: uppercase;
+ }
+
+ .sandboxHint {
+ color: #aaa;
+ }
+
+ .plusMinus {
+ margin-top: 0.4rem;
+ display: grid;
+ grid-template-columns: 1fr auto auto;
+ align-items: center;
+ grid-gap: 0.4rem;
+
+ button {
+ @include PlainText;
+ padding: 0;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 1.5rem;
+ height: 1.5rem;
+ }
+ }
+
+ .additionalOptions {
+ display: flex;
+ flex-direction: column;
+ margin-top: 1rem;
+ button {
+ margin-bottom: 0.2rem;
+ @include SuperSmallText;
+ }
+ }
+}
diff --git a/src/css/ingame_hud/settings_menu.scss b/src/css/ingame_hud/settings_menu.scss
index 55d5a9e4..e03e3fef 100644
--- a/src/css/ingame_hud/settings_menu.scss
+++ b/src/css/ingame_hud/settings_menu.scss
@@ -1,67 +1,66 @@
-#ingame_HUD_SettingsMenu {
- .statsElement {
- position: absolute;
- @include S(left, 30px);
- @include S(right, 30px);
- @include S(bottom, 30px);
- color: #fff;
- display: grid;
- grid-template-rows: auto auto;
- grid-auto-columns: 1fr;
- align-items: center;
- justify-items: center;
-
- strong {
- text-transform: uppercase;
- @include PlainText;
- opacity: 0.5;
- grid-row: 1;
- }
-
- span {
- @include Heading;
- grid-row: 2;
- }
- }
-
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
-
- .buttons {
- display: grid;
- grid-auto-flow: column;
- @include S(grid-gap, 50px);
- @include S(margin-top, -10px);
-
- button {
- background: transparent;
- filter: invert(1);
-
- content: "";
- opacity: 0.8;
- @include S(width, 35px);
- @include S(height, 35px);
-
- &.settings {
- /* @load-async */
- background-image: uiResource("icons/settings_menu_settings.png");
- }
-
- &.menu {
- /* @load-async */
- background-image: uiResource("icons/settings_menu_exit.png");
- }
-
- &:hover {
- opacity: 0.6;
- }
-
- & {
- /* @load-async */
- background: uiResource("icons/settings_menu_play.png") center top / contain no-repeat;
- }
- }
- }
-}
+#ingame_HUD_SettingsMenu {
+ .statsElement {
+ position: absolute;
+ left: 3rem;
+ right: 3rem;
+ bottom: 3rem;
+ color: #fff;
+ display: grid;
+ grid-template-rows: auto auto;
+ grid-auto-columns: 1fr;
+ place-items: center;
+
+ strong {
+ text-transform: uppercase;
+ @include PlainText;
+ opacity: 0.5;
+ grid-row: 1;
+ }
+
+ span {
+ @include Heading;
+ grid-row: 2;
+ }
+ }
+
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+
+ .buttons {
+ display: grid;
+ grid-auto-flow: column;
+ grid-gap: 5rem;
+ margin-top: -1rem;
+
+ button {
+ background: transparent;
+ filter: invert(1);
+
+ content: "";
+ opacity: 0.8;
+ width: 3.5rem;
+ height: 3.5rem;
+
+ &.settings {
+ /* @load-async */
+ background-image: uiResource("icons/settings_menu_settings.png");
+ }
+
+ &.menu {
+ /* @load-async */
+ background-image: uiResource("icons/settings_menu_exit.png");
+ }
+
+ &:hover {
+ opacity: 0.6;
+ }
+
+ & {
+ /* @load-async */
+ background: uiResource("icons/settings_menu_play.png") center top / contain no-repeat;
+ }
+ }
+ }
+}
diff --git a/src/css/ingame_hud/shape_viewer.scss b/src/css/ingame_hud/shape_viewer.scss
index 2e07f1da..7b5f4beb 100644
--- a/src/css/ingame_hud/shape_viewer.scss
+++ b/src/css/ingame_hud/shape_viewer.scss
@@ -1,155 +1,156 @@
-#ingame_HUD_ShapeViewer {
- $dims: 170px;
-
- .content {
- display: flex;
- @include S(width, $dims);
- width: 100%;
- flex-direction: column;
- overflow-x: hidden;
-
- &[data-layers="3"],
- &[data-layers="4"] {
- @include S(width, 2 * $dims);
- .renderArea {
- display: grid;
- grid-template-columns: 1fr 1fr;
- @include S(grid-row-gap, 15px);
- }
- }
-
- .renderArea {
- display: grid;
- width: 100%;
- @include S(grid-row-gap, 10px);
- align-items: center;
- justify-items: center;
- }
-
- .infoArea {
- align-self: flex-end;
- @include S(margin-top, 10px);
- display: flex;
- flex-direction: column;
- overflow: hidden;
-
- button {
- @include S(margin, 0);
- @include PlainText;
- }
- }
-
- .layer {
- position: relative;
- background: #eee;
-
- @include DarkThemeOverride {
- background: rgba(0, 10, 20, 0.2);
- }
- @include S(width, 150px);
- @include S(height, 100px);
- display: flex;
- align-items: center;
- justify-content: center;
- @include S(border-radius, $globalBorderRadius);
-
- > canvas {
- @include S(width, 50px);
- @include S(height, 50px);
- }
-
- .quad {
- position: absolute;
- width: 50%;
- height: 50%;
- display: flex;
- justify-content: center;
- align-items: center;
- box-sizing: border-box;
-
- $arrowDims: 23px;
- $spacing: 9px;
- @include S(padding, 6px);
-
- .colorLabel {
- text-transform: uppercase;
- @include SuperSmallText;
- @include S(font-size, 9px);
- }
-
- .emptyLabel {
- text-transform: uppercase;
- @include SuperSmallText;
- @include S(font-size, 9px);
- }
-
- &::after {
- content: " ";
- background: rgba(0, 10, 20, 0.5);
- @include S(width, $arrowDims);
- @include S(height, 1px);
- position: absolute;
- transform: rotate(45deg);
- transform-origin: 50% 50%;
- }
- @include DarkThemeOverride {
- &::after {
- background: rgba(255, 255, 255, 0.5);
- }
- }
-
- &.quad-0 {
- right: 0;
- top: 0;
- align-items: flex-start;
- justify-content: flex-end;
-
- &::after {
- @include S(left, $spacing);
- @include S(bottom, $arrowDims / 2 + $spacing);
- transform: rotate(-45deg);
- }
- }
- &.quad-1 {
- bottom: 0;
- right: 0;
-
- align-items: flex-end;
- justify-content: flex-end;
-
- &::after {
- @include S(left, $spacing);
- @include S(top, $arrowDims / 2 + $spacing);
- transform: rotate(45deg);
- }
- }
- &.quad-2 {
- bottom: 0;
- left: 0;
-
- align-items: flex-end;
- justify-content: flex-start;
-
- &::after {
- @include S(right, $spacing);
- @include S(top, $arrowDims / 2 + $spacing);
- transform: rotate(135deg);
- }
- }
- &.quad-3 {
- top: 0;
- left: 0;
-
- align-items: flex-start;
- justify-content: flex-start;
-
- &::after {
- @include S(right, $spacing);
- @include S(bottom, $arrowDims / 2 + $spacing);
- transform: rotate(225deg);
- }
- }
- }
- }
- }
-}
+@use "sass:math";
+
+#ingame_HUD_ShapeViewer {
+ $dims: 17rem;
+
+ .content {
+ display: flex;
+ width: $dims;
+ width: 100%;
+ flex-direction: column;
+ overflow-x: hidden;
+
+ &[data-layers="3"],
+ &[data-layers="4"] {
+ width: 2 * $dims;
+ .renderArea {
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ grid-row-gap: 1.5rem;
+ }
+ }
+
+ .renderArea {
+ display: grid;
+ width: 100%;
+ grid-row-gap: 1rem;
+ place-items: center;
+ }
+
+ .infoArea {
+ align-self: flex-end;
+ margin-top: 1rem;
+ display: flex;
+ flex-direction: column;
+ overflow: hidden;
+
+ button {
+ margin: 0;
+ @include PlainText;
+ }
+ }
+
+ .layer {
+ position: relative;
+ background: #eee;
+
+ @include DarkThemeOverride {
+ background: rgba(0, 10, 20, 0.2);
+ }
+ width: 15rem;
+ height: 10rem;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ border-radius: $globalBorderRadius;
+
+ > canvas {
+ width: 5rem;
+ height: 5rem;
+ }
+
+ .quad {
+ position: absolute;
+ width: 50%;
+ height: 50%;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ box-sizing: border-box;
+
+ $arrowDims: 2.3rem;
+ $spacing: 0.9rem;
+ padding: 0.6rem;
+
+ .colorLabel {
+ text-transform: uppercase;
+ @include SuperSmallText;
+ font-size: 0.9rem;
+ }
+
+ .emptyLabel {
+ text-transform: uppercase;
+ @include SuperSmallText;
+ font-size: 0.9rem;
+ }
+
+ &::after {
+ content: " ";
+ background: rgba(0, 10, 20, 0.5);
+ width: $arrowDims;
+ height: 0.1rem;
+ position: absolute;
+ transform: rotate(45deg);
+ transform-origin: 50% 50%;
+ }
+ @include DarkThemeOverride {
+ &::after {
+ background: rgba(255, 255, 255, 0.5);
+ }
+ }
+
+ &.quad-0 {
+ right: 0;
+ top: 0;
+ align-items: flex-start;
+ justify-content: flex-end;
+
+ &::after {
+ left: $spacing;
+ bottom: math.div($arrowDims, 2) + $spacing;
+ transform: rotate(-45deg);
+ }
+ }
+ &.quad-1 {
+ bottom: 0;
+ right: 0;
+
+ align-items: flex-end;
+ justify-content: flex-end;
+
+ &::after {
+ left: $spacing;
+ top: math.div($arrowDims, 2) + $spacing;
+ transform: rotate(45deg);
+ }
+ }
+ &.quad-2 {
+ bottom: 0;
+ left: 0;
+
+ align-items: flex-end;
+ justify-content: flex-start;
+
+ &::after {
+ right: $spacing;
+ top: math.div($arrowDims, 2) + $spacing;
+ transform: rotate(135deg);
+ }
+ }
+ &.quad-3 {
+ top: 0;
+ left: 0;
+
+ align-items: flex-start;
+ justify-content: flex-start;
+
+ &::after {
+ right: $spacing;
+ bottom: math.div($arrowDims, 2) + $spacing;
+ transform: rotate(225deg);
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/css/ingame_hud/shop.scss b/src/css/ingame_hud/shop.scss
index a9b27ebe..284a076c 100644
--- a/src/css/ingame_hud/shop.scss
+++ b/src/css/ingame_hud/shop.scss
@@ -1,335 +1,332 @@
-#ingame_HUD_Shop {
- .content {
- @include S(padding-right, 10px);
- display: flex;
- flex-direction: column;
- @include S(width, 500px);
-
- .upgrade {
- display: grid;
- grid-template-columns: auto 1fr auto;
- background: #eee;
- @include S(border-radius, $globalBorderRadius);
- @include S(margin-bottom, 4px);
- @include S(padding, 5px, 10px);
- @include S(grid-row-gap, 1px);
- @include S(height, 85px);
- grid-template-rows: #{D(20px)} auto;
-
- &:last-child {
- margin-bottom: 0;
- }
-
- @include DarkThemeOverride {
- background: $darkModeControlsBackground;
- }
-
- .title {
- grid-column: 1 / 3;
- grid-row: 1 / 2;
- @include PlainText;
- display: flex;
- align-items: center;
- flex-direction: row-reverse;
- justify-content: flex-end;
-
- @include DarkThemeOverride {
- color: #fff;
- }
-
- .tier {
- @include S(margin-right, 9px);
- background: $colorGreenBright;
- @include S(border-radius, $globalBorderRadius);
- text-transform: uppercase;
- @include PlainText;
- color: #fff;
- text-align: center;
- font-weight: bold;
- @include S(min-width, 50px);
- @include S(padding, 0px, 5px);
-
- &[data-tier="0"] {
- background-color: rgb(73, 186, 190);
- }
- &[data-tier="1"] {
- background-color: rgb(88, 110, 207);
- }
- &[data-tier="2"] {
- background-color: rgb(189, 100, 192);
- }
- &[data-tier="3"] {
- background-color: rgb(117, 192, 98);
- }
- &[data-tier="4"] {
- background-color: rgb(243, 77, 48);
- }
- &[data-tier="5"] {
- background-color: rgb(255, 209, 6);
- }
- &[data-tier="6"] {
- background-color: rgb(44, 41, 46);
- }
- }
- }
-
- .icon {
- @include S(width, 40px);
- @include S(height, 40px);
- background: center center / 80% no-repeat;
- align-self: center;
- justify-self: center;
- grid-column: 1 / 2;
- grid-row: 2 / 4;
- @include S(margin-right, 30px);
- @include S(margin-left, 10px);
- opacity: 0.32;
- display: none;
- }
-
- .description {
- grid-column: 2 / 4;
- grid-row: 1 / 2;
- @include PlainText;
- color: #aaa;
- align-self: start;
- justify-self: end;
- }
-
- .requirements {
- grid-column: 2 / 3;
- grid-row: 3 / 4;
- display: grid;
- grid-auto-flow: column;
- @include S(grid-gap, 9px);
- justify-content: start;
-
- .requirement {
- position: relative;
- display: flex;
- flex-direction: column;
- align-items: center;
- @include S(width, 70px);
- overflow: hidden;
-
- button.pin {
- & {
- /* @load-async */
- background: uiResource("icons/pin.png") center center / 95% no-repeat;
- }
-
- @include S(width, 12px);
- @include S(height, 12px);
- position: absolute;
- @include S(top, 2px);
- @include S(right, 2px);
- opacity: 0.6;
- cursor: pointer;
- pointer-events: all;
- @include IncreasedClickArea(5px);
- transition: opacity 0.12s ease-in-out;
-
- @include DarkThemeInvert;
-
- $disabledOpacity: 0.6;
- $enabledOpacity: 0.6;
-
- &:hover {
- opacity: $enabledOpacity + 0.1;
- }
-
- &.alreadyPinned {
- opacity: $disabledOpacity !important;
-
- &:hover {
- opacity: $disabledOpacity + 0.1 !important;
- }
- }
-
- &.isGoal {
- /* @load-async */
- background: uiResource("icons/current_goal_marker.png") center center / 95%
- no-repeat;
- opacity: $disabledOpacity !important;
- cursor: default;
- pointer-events: none;
- }
-
- &.pinned {
- opacity: $disabledOpacity;
-
- & {
- /* @load-async */
- background: uiResource("icons/unpin_shape.png") center center / 75% no-repeat !important;
- }
-
- @include InlineAnimation(0.3s ease-in-out) {
- 0% {
- opacity: 1;
- transform: scale(0.8);
- }
-
- 30% {
- opacity: 1;
- transform: scale(1.2);
- }
-
- 100% {
- transform: scale(1);
- }
- }
- &:hover {
- opacity: $disabledOpacity + 0.1;
- }
- }
-
- &.unpinned {
- opacity: $enabledOpacity;
- @include InlineAnimation(0.3s ease-in-out) {
- 0% {
- opacity: 1;
- transform: scale(0.8);
- }
-
- 30% {
- opacity: 1;
- transform: scale(1.2);
- }
-
- 100% {
- transform: scale(1);
- }
- }
- &:hover {
- opacity: $enabledOpacity + 0.1;
- }
- }
- }
-
- button.showInfo {
- @include S(width, 11px);
- @include S(height, 11px);
- position: absolute;
- @include S(top, 17px);
- @include S(right, 2.5px);
- opacity: 0.5;
- cursor: pointer;
- pointer-events: all;
- @include IncreasedClickArea(5px);
- transition: opacity 0.12s ease-in-out;
- @include DarkThemeInvert;
-
- &:hover {
- opacity: 0.6;
- }
- }
- button.showInfo {
- /* @load-async */
- background: uiResource("icons/info_button.png") center center / 95% no-repeat;
- }
-
- canvas {
- @include S(width, 40px);
- @include S(height, 40px);
- }
-
- .amount {
- @include S(margin-top, 4px);
- z-index: 10;
- @include SuperSmallText;
- letter-spacing: 0;
- background: #e2e4e6;
-
- @include S(line-height, 13px);
- @include S(border-radius, $globalBorderRadius);
- @include S(padding, 1px, 0px, 2px);
- position: relative;
- text-align: center;
- @include S(min-width, 50px);
- // @include S(max-width, 100px);
- overflow: hidden;
- width: 100%;
-
- @include DarkThemeOverride {
- background: #333438;
- color: #fff;
- }
-
- .progressBar {
- bottom: 0;
- left: 0;
- right: 0;
- top: 0;
- @include S(border-radius, $globalBorderRadius);
- position: absolute;
- display: inline-block;
- z-index: -1;
- transition: all 0.2s ease-in-out;
- transition-property: width, background-color;
- background: #bdbfca;
-
- @include DarkThemeOverride {
- background: #8c8d96;
- }
-
- &.complete {
- background-color: $colorGreenBright;
-
- @include DarkThemeOverride {
- background-color: $colorGreenBright;
- }
- }
- }
- }
- }
- }
-
- button.buy {
- grid-column: 3 / 4;
- grid-row: 3 / 4;
- align-self: center;
- justify-self: end;
- // @include S(padding, 4px, 5px);
- // @include PlainText;
- background-color: $colorGreenBright;
- color: #fff;
-
- transition: all 0.2s ease-in-out;
- transition-property: background-color, opacity;
-
- &:not(.buyable) {
- background-color: #aaa;
- cursor: default;
- pointer-events: none;
- opacity: 0.3;
- }
-
- &.buyable {
- @include InlineAnimation(1s ease-in-out infinite) {
- 0% {
- }
-
- 50% {
- background-color: lighten($colorGreenBright, 10);
- transform: scale(1.02);
- }
- 100% {
- }
- }
- }
- }
-
- &.maxLevel {
- button.buy {
- opacity: 0 !important;
- }
- .requirements {
- display: none;
- }
- .description {
- color: $colorGreenBright;
- }
- }
- }
- }
-}
+#ingame_HUD_Shop {
+ .content {
+ padding-right: 1rem;
+ display: flex;
+ flex-direction: column;
+ width: 50rem;
+
+ .upgrade {
+ display: grid;
+ grid-template-columns: auto 1fr auto;
+ background: #eee;
+ border-radius: $globalBorderRadius;
+ margin-bottom: 0.4rem;
+ padding: 0.5rem 1rem;
+ grid-row-gap: 0.1rem;
+ height: 8.5rem;
+ grid-template-rows: #{2rem} auto;
+
+ &:last-child {
+ margin-bottom: 0;
+ }
+
+ @include DarkThemeOverride {
+ background: $darkModeControlsBackground;
+ }
+
+ .title {
+ grid-column: 1 / 3;
+ grid-row: 1 / 2;
+ @include PlainText;
+ display: flex;
+ align-items: center;
+ flex-direction: row-reverse;
+ justify-content: flex-end;
+
+ @include DarkThemeOverride {
+ color: #fff;
+ }
+
+ .tier {
+ margin-right: 0.9rem;
+ background: $colorGreenBright;
+ border-radius: $globalBorderRadius;
+ text-transform: uppercase;
+ @include PlainText;
+ color: #fff;
+ text-align: center;
+ font-weight: bold;
+ min-width: 5rem;
+ padding: 0rem 0.5rem;
+
+ &[data-tier="0"] {
+ background-color: rgb(73, 186, 190);
+ }
+ &[data-tier="1"] {
+ background-color: rgb(88, 110, 207);
+ }
+ &[data-tier="2"] {
+ background-color: rgb(189, 100, 192);
+ }
+ &[data-tier="3"] {
+ background-color: rgb(117, 192, 98);
+ }
+ &[data-tier="4"] {
+ background-color: rgb(243, 77, 48);
+ }
+ &[data-tier="5"] {
+ background-color: rgb(255, 209, 6);
+ }
+ &[data-tier="6"] {
+ background-color: rgb(44, 41, 46);
+ }
+ }
+ }
+
+ .icon {
+ width: 4rem;
+ height: 4rem;
+ background: center center / 80% no-repeat;
+ align-self: center;
+ justify-self: center;
+ grid-column: 1 / 2;
+ grid-row: 2 / 4;
+ margin-right: 3rem;
+ margin-left: 1rem;
+ opacity: 0.32;
+ display: none;
+ }
+
+ .description {
+ grid-column: 2 / 4;
+ grid-row: 1 / 2;
+ @include PlainText;
+ color: #aaa;
+ align-self: start;
+ justify-self: end;
+ }
+
+ .requirements {
+ grid-column: 2 / 3;
+ grid-row: 3 / 4;
+ display: grid;
+ grid-auto-flow: column;
+ grid-gap: 0.9rem;
+ justify-content: start;
+
+ .requirement {
+ position: relative;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ width: 7rem;
+ overflow: hidden;
+
+ button.pin {
+ & {
+ /* @load-async */
+ background: uiResource("icons/pin.png") center center / 95% no-repeat;
+ }
+
+ width: 1.2rem;
+ height: 1.2rem;
+ position: absolute;
+ top: 0.2rem;
+ right: 0.2rem;
+ opacity: 0.6;
+ cursor: pointer;
+ pointer-events: all;
+ transition: opacity 0.12s ease-in-out;
+
+ @include DarkThemeInvert;
+
+ $disabledOpacity: 0.6;
+ $enabledOpacity: 0.6;
+
+ &:hover {
+ opacity: $enabledOpacity + 0.1;
+ }
+
+ &.alreadyPinned {
+ opacity: $disabledOpacity !important;
+
+ &:hover {
+ opacity: $disabledOpacity + 0.1 !important;
+ }
+ }
+
+ &.isGoal {
+ /* @load-async */
+ background: uiResource("icons/current_goal_marker.png") center center / 95%
+ no-repeat;
+ opacity: $disabledOpacity !important;
+ cursor: default;
+ pointer-events: none;
+ }
+
+ &.pinned {
+ opacity: $disabledOpacity;
+
+ & {
+ /* @load-async */
+ background: uiResource("icons/unpin_shape.png") center center / 75% no-repeat !important;
+ }
+
+ @include InlineAnimation(0.3s ease-in-out) {
+ 0% {
+ opacity: 1;
+ transform: scale(0.8);
+ }
+
+ 30% {
+ opacity: 1;
+ transform: scale(1.2);
+ }
+
+ 100% {
+ transform: scale(1);
+ }
+ }
+ &:hover {
+ opacity: $disabledOpacity + 0.1;
+ }
+ }
+
+ &.unpinned {
+ opacity: $enabledOpacity;
+ @include InlineAnimation(0.3s ease-in-out) {
+ 0% {
+ opacity: 1;
+ transform: scale(0.8);
+ }
+
+ 30% {
+ opacity: 1;
+ transform: scale(1.2);
+ }
+
+ 100% {
+ transform: scale(1);
+ }
+ }
+ &:hover {
+ opacity: $enabledOpacity + 0.1;
+ }
+ }
+ }
+
+ button.showInfo {
+ width: 1.1rem;
+ height: 1.1rem;
+ position: absolute;
+ top: 1.7rem;
+ right: 0.25rem;
+ opacity: 0.5;
+ cursor: pointer;
+ pointer-events: all;
+ transition: opacity 0.12s ease-in-out;
+ @include DarkThemeInvert;
+
+ &:hover {
+ opacity: 0.6;
+ }
+ }
+ button.showInfo {
+ /* @load-async */
+ background: uiResource("icons/info_button.png") center center / 95% no-repeat;
+ }
+
+ canvas {
+ width: 4rem;
+ height: 4rem;
+ }
+
+ .amount {
+ margin-top: 0.4rem;
+ z-index: 10;
+ @include SuperSmallText;
+ background: #e2e4e6;
+
+ line-height: 1.3rem;
+ border-radius: $globalBorderRadius;
+ padding: 0.1rem 0 0.2rem;
+ position: relative;
+ text-align: center;
+ min-width: 5rem;
+ // max-width: 10.0rem;
+ overflow: hidden;
+ width: 100%;
+
+ @include DarkThemeOverride {
+ background: #333438;
+ color: #fff;
+ }
+
+ .progressBar {
+ bottom: 0;
+ left: 0;
+ right: 0;
+ top: 0;
+ border-radius: $globalBorderRadius;
+ position: absolute;
+ display: inline-block;
+ z-index: -1;
+ transition: all 0.2s ease-in-out;
+ transition-property: width, background-color;
+ background: #bdbfca;
+
+ @include DarkThemeOverride {
+ background: #8c8d96;
+ }
+
+ &.complete {
+ background-color: $colorGreenBright;
+
+ @include DarkThemeOverride {
+ background-color: $colorGreenBright;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ button.buy {
+ grid-column: 3 / 4;
+ grid-row: 3 / 4;
+ align-self: center;
+ justify-self: end;
+ // padding: .4rem .5rem;
+ // @include PlainText;
+ background-color: $colorGreenBright;
+ color: #fff;
+
+ transition: all 0.2s ease-in-out;
+ transition-property: background-color, opacity;
+
+ &:not(.buyable) {
+ background-color: #aaa;
+ cursor: default;
+ pointer-events: none;
+ opacity: 0.3;
+ }
+
+ &.buyable {
+ @include InlineAnimation(1s ease-in-out infinite) {
+ 0% {
+ }
+
+ 50% {
+ background-color: lighten($colorGreenBright, 10);
+ transform: scale(1.02);
+ }
+ 100% {
+ }
+ }
+ }
+ }
+
+ &.maxLevel {
+ button.buy {
+ opacity: 0 !important;
+ }
+ .requirements {
+ display: none;
+ }
+ .description {
+ color: $colorGreenBright;
+ }
+ }
+ }
+ }
+}
diff --git a/src/css/ingame_hud/standalone_advantages.scss b/src/css/ingame_hud/standalone_advantages.scss
deleted file mode 100644
index a75ace4c..00000000
--- a/src/css/ingame_hud/standalone_advantages.scss
+++ /dev/null
@@ -1,293 +0,0 @@
-#ingame_HUD_StandaloneAdvantages {
- .content {
- @include S(width, 500px);
- @include S(min-height, 300px);
- }
- p {
- @include PlainText;
- }
-
- .points {
- display: grid;
- grid-template-columns: 1fr 1fr;
- @include S(grid-column-gap, 5px);
- @include S(grid-row-gap, 5px);
- @include S(margin, 10px, 0, 10px);
- align-items: center;
- }
-
- .title {
- @include Heading;
- text-transform: none;
- text-align: center;
- color: $colorRedBright;
- }
- .subTitle {
- @include PlainText;
- text-transform: none;
- text-align: center;
- }
-
- .lowerBar {
- width: 100%;
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
-
- > button {
- transition: opacity 0.12s ease-in-out;
- &:hover {
- opacity: 0.85;
- }
- }
-
- .otherCloseButton {
- @include SuperSmallText;
- @include S(margin-right, 30px);
- color: #aaa;
- @include S(margin, 0);
- @include IncreasedClickArea(0px);
- @include S(margin-top, 15px);
-
- &[data-btn-variant="prod"] {
- @include InlineAnimation(11s ease-in-out) {
- 0% {
- opacity: 0.05;
- }
- 80% {
- opacity: 0.05;
- }
- 100% {
- opacity: 1;
- }
- }
- }
-
- &[data-btn-variant="steam-demo"] {
- @include InlineAnimation(5s ease-in-out) {
- 0% {
- opacity: 0.05;
- }
- 50% {
- opacity: 0.05;
- }
- 100% {
- opacity: 1;
- }
- }
- }
- }
-
- .playtimeDisclaimer {
- @include S(margin-bottom, 15px);
- @include PlainText;
- }
-
- .playtimeDisclaimerDownload {
- @include SuperSmallText;
- box-sizing: border-box;
- text-align: center;
- @include S(border-radius, $globalBorderRadius);
- @include S(padding, 8px, 10px, 8px, 20px);
- @include S(margin-bottom, 15px);
- pointer-events: all;
- transition: background-color 0.12s ease-in-out;
- color: rgba(#000, 0.5);
-
- width: 100%;
- background: rgba($colorGreenBright, 0.2);
- cursor: pointer;
-
- display: grid;
- grid-template-columns: auto 1fr;
- @include S(grid-gap, 5px);
-
- &::before {
- content: "";
- display: inline-flex;
- @include S(width, 15px);
- @include S(height, 15px);
- & {
- /* load-async */
- background: uiResource("icons/savegame_correct.png") center center / contain no-repeat;
- }
- }
-
- strong {
- color: #000;
- }
- }
-
- .steamLinkButton {
- @include IncreasedClickArea(5px);
- @include S(margin, 0);
- @include S(width, 180px);
- @include S(height, 40px);
- background: #171a23 center center / contain no-repeat;
-
- box-shadow: 0 D(3px) D(10px) rgba(96, 163, 136, 0.5);
- overflow: visible;
- @include S(border-radius, $globalBorderRadius);
-
- @include InlineAnimation(1s ease-in-out infinite) {
- 50% {
- transform: scale(1.02, 1.03);
- }
- }
-
- &:hover {
- opacity: 0.94 !important;
- }
-
- > .discount {
- position: absolute;
- @include S(top, -12px);
- @include S(right, -15px);
- background: #4c6b22;
- color: #c5ea3f;
- @include S(border-radius, $globalBorderRadius);
- @include S(padding, 1px, 3px, 1px, 4px);
- @include PlainText;
- text-transform: uppercase;
- transform: rotate(3deg);
- }
- }
-
- .specialOffer {
- color: #000000;
- @include PlainText;
- align-self: center;
- text-align: center;
- @include S(margin-top, 5px);
- }
- }
-
- .point {
- display: grid;
- grid-template-columns: #{D(50px)} auto;
- grid-template-rows: D(20px) D(20px);
- background: #eff2f4 #{D(12px)} center / #{D(30px)} no-repeat;
-
- @include S(border-radius, $globalBorderRadius);
- align-items: center;
- @include S(padding, 10px, 4px, 4px);
- @include S(height, 40px);
-
- > strong {
- grid-column: 2 / 3;
- grid-row: 1 / 2;
- @include PlainText;
- text-transform: uppercase;
- font-weight: bold;
- }
-
- > p {
- grid-column: 2 / 3;
- grid-row: 2 / 3;
- @include SuperSmallText;
- line-height: 1em;
- opacity: 0.8;
- }
-
- &.levels {
- & {
- /* @load-async */
- background-image: uiResource("res/ui/icons/advantage_new_levels.png");
- }
- > strong {
- color: #f13555;
- }
- }
-
- &.upgrades {
- & {
- /* @load-async */
- background-image: uiResource("res/ui/icons/advantage_upgrades.png");
- }
- > strong {
- color: #8a00ff;
- }
- }
-
- &.buildings {
- & {
- /* @load-async */
- background-image: uiResource("res/ui/icons/advantage_buildings.png");
- }
- > strong {
- color: #3fce8b;
- }
- }
-
- &.wires {
- & {
- /* @load-async */
- background-image: uiResource("res/ui/icons/advantage_wires.png");
- }
- > strong {
- color: #ef2fdb;
- }
- }
-
- &.markers {
- & {
- /* @load-async */
- background-image: uiResource("res/ui/icons/advantage_markers.png");
- }
- > strong {
- color: #4294ff;
- }
- }
-
- &.mods {
- & {
- /* @load-async */
- background-image: uiResource("res/ui/icons/advantage_mods.png");
- }
- > strong {
- color: #8a00ff;
- }
- }
-
- &.savegames {
- & {
- /* @load-async */
- background-image: uiResource("res/ui/icons/advantage_savegames.png");
- }
- > strong {
- color: #ff9500;
- }
- }
-
- &.darkmode {
- & {
- /* @load-async */
- background-image: uiResource("res/ui/icons/advantage_dark_mode.png");
- }
- > strong {
- color: #292c32;
- }
- }
-
- &.support {
- & {
- /* @load-async */
- background-image: uiResource("res/ui/icons/advantage_support.png");
- }
- > strong {
- color: #e72d2d;
- }
- }
-
- &.achievements {
- & {
- /* @load-async */
- background-image: uiResource("res/ui/icons/advantage_achievements.png");
- }
- > strong {
- color: #ffac0f;
- }
- }
- }
-}
diff --git a/src/css/ingame_hud/statistics.scss b/src/css/ingame_hud/statistics.scss
index cdc428c1..ea307b89 100644
--- a/src/css/ingame_hud/statistics.scss
+++ b/src/css/ingame_hud/statistics.scss
@@ -1,6 +1,6 @@
#ingame_HUD_Statistics {
.content {
- @include S(width, 500px);
+ width: 50rem;
}
.filterHeader {
@@ -10,32 +10,31 @@
justify-items: end;
button {
- @include S(height, 20px);
- @include S(padding, 1px, 10px);
+ height: 2rem;
+ padding: 0.1rem 1rem;
border: 0;
box-shadow: none;
- @include IncreasedClickArea(1px);
- @include S(min-width, 30px);
+ min-width: 3rem;
color: #fff;
opacity: 0.25;
- @include S(border-radius, $globalBorderRadius);
+ border-radius: $globalBorderRadius;
border-radius: 0;
&:first-child {
- @include S(border-top-left-radius, $globalBorderRadius);
- @include S(border-bottom-left-radius, $globalBorderRadius);
+ border-top-left-radius: $globalBorderRadius;
+ border-bottom-left-radius: $globalBorderRadius;
}
&:last-child {
- @include S(border-top-right-radius, $globalBorderRadius);
- @include S(border-bottom-right-radius, $globalBorderRadius);
+ border-top-right-radius: $globalBorderRadius;
+ border-bottom-right-radius: $globalBorderRadius;
}
&.displayIcons,
&.displayDetailed,
&.displaySorted,
&.displayIterateUnit {
- background: transparent center center / #{D(15px)} no-repeat;
+ background: transparent center center / 1.5rem no-repeat;
}
&.displayDetailed {
@@ -46,12 +45,12 @@
&.displayIcons {
/* @load-async */
background-image: uiResource("icons/display_icons.png");
- background-size: #{D(11.5px)};
+ background-size: 1.15rem;
}
&.displayDetailed {
- @include S(border-top-left-radius, $globalBorderRadius);
- @include S(border-bottom-left-radius, $globalBorderRadius);
+ border-top-left-radius: $globalBorderRadius;
+ border-bottom-left-radius: $globalBorderRadius;
}
&.displaySorted {
@@ -59,12 +58,12 @@
/* @load-async */
background-image: uiResource("icons/display_sorted.png");
}
- background-size: #{D(11.5px)};
+ background-size: 1.15rem;
margin-right: 5px;
- @include S(border-top-right-radius, $globalBorderRadius);
- @include S(border-bottom-right-radius, $globalBorderRadius);
+ border-top-right-radius: $globalBorderRadius;
+ border-bottom-right-radius: $globalBorderRadius;
- @include S(padding, 1px, 0);
+ padding: 0.1rem 0;
}
&.displayIterateUnit {
@@ -73,7 +72,7 @@
background-image: uiResource("icons/toggle_unit.png");
}
opacity: 0.8;
- @include S(padding, 1px, 0);
+ padding: 0.1rem 0;
}
background-color: #44484a !important;
@@ -101,20 +100,20 @@
.sourceExplanation {
@include SuperSmallText();
- @include S(margin-top, 5px);
+ margin-top: 0.5rem;
color: #aaa;
}
.content {
- @include S(margin-top, 10px);
- @include S(height, 350px);
+ margin-top: 1rem;
+ height: 35rem;
overflow-y: scroll;
display: flex;
flex-direction: column;
justify-content: flex-start;
- @include S(padding-right, 4px);
+ padding-right: 0.4rem;
> .noEntries {
width: 100%;
@@ -128,12 +127,12 @@
> div {
background: #f4f4f4;
- @include S(margin-bottom, 4px);
+ margin-bottom: 0.4rem;
display: grid;
- @include S(border-radius, $globalBorderRadius);
+ border-radius: $globalBorderRadius;
grid-template-columns: 1fr auto;
- @include S(padding, 5px);
+ padding: 0.5rem;
&:last-child {
margin-bottom: 0;
}
@@ -153,13 +152,13 @@
canvas.icon {
grid-column: 1 / 2;
grid-row: 1 / 2;
- @include S(width, 40px);
- @include S(height, 40px);
+ width: 4rem;
+ height: 4rem;
}
.counter {
@include SuperSmallText;
- @include S(padding, 0, 3px);
+ padding: 0, 0.3rem;
}
}
}
@@ -177,16 +176,15 @@
&[data-displaymode="icons"] .content.hasEntries {
display: grid;
grid-template-columns: repeat(6, 1fr);
- grid-auto-rows: #{D(73px)};
+ grid-auto-rows: 7.3rem;
align-items: flex-start;
- @include S(grid-column-gap, 3px);
+ grid-column-gap: 0.3rem;
> div {
- @include S(grid-row-gap, 5px);
- @include S(height, 60px);
+ grid-row-gap: 0.5rem;
+ height: 6rem;
grid-template-columns: 1fr;
grid-template-rows: 1fr auto;
- justify-items: center;
- align-items: center;
+ place-items: center;
.counter {
grid-column: 1 / 2;
@@ -202,10 +200,10 @@
}
&[data-displaymode="detailed"] .content.hasEntries {
> div {
- @include S(padding, 10px);
- @include S(height, 40px);
+ padding: 1rem;
+ height: 4rem;
grid-template-columns: auto 1fr auto;
- @include S(grid-column-gap, 15px);
+ grid-column-gap: 1.5rem;
.counter {
grid-column: 3 / 4;
@@ -221,14 +219,13 @@
}
canvas.graph {
- @include S(width, 270px);
- @include S(height, 40px);
- @include S(border-radius, 0, 0, 2px, 2px);
+ width: 27rem;
+ height: 4rem;
+ border-radius: 0 0 0.2rem 0.2rem;
$color: rgba(0, 10, 20, 0.04);
// background: $color;
- border: #{D(4px)} solid transparent;
- // @include S(border-width, 1px, 0, 1px, 0);
- @include S(margin-top, -3px);
+ border: 0.4rem solid transparent;
+ margin-top: -0.3rem;
}
}
}
diff --git a/src/css/ingame_hud/tutorial_hints.scss b/src/css/ingame_hud/tutorial_hints.scss
index 27d85fe1..14d86377 100644
--- a/src/css/ingame_hud/tutorial_hints.scss
+++ b/src/css/ingame_hud/tutorial_hints.scss
@@ -1,120 +1,119 @@
-#ingame_HUD_TutorialHints {
- position: absolute;
- @include S(left, 10px);
- @include S(bottom, 10px);
-
- @include StyleBelowWidth(1430px) {
- @include S(bottom, 50px);
- }
-
- display: flex;
- flex-direction: column;
- background: rgba(50, 60, 70, 0);
-
- transition: all 0.2s ease-in-out;
- pointer-events: all;
-
- transition-property: background-color, transform, bottom, left;
-
- @include S(padding, 5px);
- video {
- transition: all 0.2s ease-in-out;
- transition-property: opacity, width;
- @include S(width, 0px);
- opacity: 0;
- z-index: 10;
- position: relative;
- }
-
- .header {
- color: #333438;
- display: grid;
- align-items: center;
- @include S(grid-gap, 2px);
- grid-template-columns: 1fr;
- @include S(margin-bottom, 3px);
- z-index: 11;
- position: relative;
-
- > span {
- @include DarkThemeInvert;
-
- display: flex;
- @include SuperSmallText;
- justify-content: flex-start;
- align-items: center;
- &::before {
- @include S(margin-right, 4px);
- content: " ";
- @include S(width, 12px);
- @include S(height, 12px);
- display: inline-block;
- & {
- /* @load-async */
- background: uiResource("icons/help.png") center center / 95% no-repeat;
- }
- }
- }
-
- button.toggleHint {
- @include PlainText;
- @include IncreasedClickArea(0px);
- }
- }
-
- button.toggleHint {
- .hide {
- display: none;
- }
- }
-
- &.enlarged {
- background: $ingameHudBg;
- left: 50%;
- bottom: 50%;
- transform: translate(-50%, 50%);
-
- &::before {
- pointer-events: all;
- content: " ";
- position: fixed;
- top: -1000px;
- left: -1000px;
- right: -1000px;
- bottom: -1000px;
- z-index: 0;
-
- background: rgba($ingameHudBg, 0.3);
- }
-
- .header {
- grid-template-columns: 1fr auto;
- > span {
- display: none;
- }
- button.toggleHint {
- grid-column: 2 / 3;
- }
- }
-
- video {
- @include InlineAnimation(0.2s ease-in-out) {
- 0% {
- opacity: 0;
- @include S(width, 0px);
- }
- }
-
- opacity: 1;
- @include S(width, 500px);
- }
- button.toggleHint {
- .hide {
- display: block;
- }
- .show {
- display: none;
- }
- }
- }
-}
+#ingame_HUD_TutorialHints {
+ position: absolute;
+ left: 1rem;
+ bottom: 1rem;
+
+ @include StyleBelowWidth(1430px) {
+ bottom: 5rem;
+ }
+
+ display: flex;
+ flex-direction: column;
+ background: rgba(50, 60, 70, 0);
+
+ transition: all 0.2s ease-in-out;
+ pointer-events: all;
+
+ transition-property: background-color, transform, bottom, left;
+
+ padding: 0.5rem;
+ video {
+ transition: all 0.2s ease-in-out;
+ transition-property: opacity, width;
+ width: 0rem;
+ opacity: 0;
+ z-index: 10;
+ position: relative;
+ }
+
+ .header {
+ color: #333438;
+ display: grid;
+ align-items: center;
+ grid-gap: 0.2rem;
+ grid-template-columns: 1fr;
+ margin-bottom: 0.3rem;
+ z-index: 11;
+ position: relative;
+
+ > span {
+ @include DarkThemeInvert;
+
+ display: flex;
+ @include SuperSmallText;
+ justify-content: flex-start;
+ align-items: center;
+ &::before {
+ margin-right: 0.4rem;
+ content: " ";
+ width: 1.2rem;
+ height: 1.2rem;
+ display: inline-block;
+ & {
+ /* @load-async */
+ background: uiResource("icons/help.png") center center / 95% no-repeat;
+ }
+ }
+ }
+
+ button.toggleHint {
+ @include PlainText;
+ }
+ }
+
+ button.toggleHint {
+ .hide {
+ display: none;
+ }
+ }
+
+ &.enlarged {
+ background: $ingameHudBg;
+ left: 50%;
+ bottom: 50%;
+ transform: translate(-50%, 50%);
+
+ &::before {
+ pointer-events: all;
+ content: " ";
+ position: fixed;
+ top: -1000px;
+ left: -1000px;
+ right: -1000px;
+ bottom: -1000px;
+ z-index: 0;
+
+ background: rgba($ingameHudBg, 0.3);
+ }
+
+ .header {
+ grid-template-columns: 1fr auto;
+ > span {
+ display: none;
+ }
+ button.toggleHint {
+ grid-column: 2 / 3;
+ }
+ }
+
+ video {
+ @include InlineAnimation(0.2s ease-in-out) {
+ 0% {
+ opacity: 0;
+ width: 0rem;
+ }
+ }
+
+ opacity: 1;
+ width: 50rem;
+ }
+ button.toggleHint {
+ .hide {
+ display: block;
+ }
+ .show {
+ display: none;
+ }
+ }
+ }
+}
diff --git a/src/css/ingame_hud/unlock_notification.scss b/src/css/ingame_hud/unlock_notification.scss
index eeac3588..1cf1e59d 100644
--- a/src/css/ingame_hud/unlock_notification.scss
+++ b/src/css/ingame_hud/unlock_notification.scss
@@ -1,184 +1,178 @@
-#ingame_HUD_UnlockNotification {
- position: absolute;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- overflow: auto;
- pointer-events: all;
-
- & {
- /* @load-async */
- background: rgba(#333538, 0.98) uiResource("dialog_bg_pattern.png") top left / #{D(10px)} repeat;
- }
-
- @include InlineAnimation(0.1s ease-in-out) {
- 0% {
- opacity: 0;
- }
- }
-
- &.withinDemo {
- > .dialog {
- @include S(padding-top, 60px);
- }
- }
-
- .dialog {
- // background: rgba(#222428, 0.5);
- @include S(border-radius, $globalBorderRadius);
- @include S(padding, 30px);
-
- @include InlineAnimation(0.5s ease-in-out) {
- 0% {
- opacity: 0;
- }
- }
- display: flex;
- align-items: center;
- flex-direction: column;
-
- color: #fff;
- text-align: center;
- .title,
- .subTitle {
- @include SuperHeading;
- text-transform: uppercase;
- @include S(font-size, 40px);
-
- @include InlineAnimation(0.5s ease-in-out) {
- 0% {
- transform: translateY(-50vh);
- }
- 50% {
- transform: translateY(5vh);
- }
- 75% {
- transform: translateY(-2vh);
- }
- }
- }
-
- .subTitle {
- @include PlainText;
- display: inline-block;
- @include S(margin, 5px, 0, 20px);
- color: $colorGreenBright;
-
- @include S(border-radius, $globalBorderRadius);
- @include InlineAnimation(0.5s ease-in-out) {
- 0% {
- transform: translateY(-60vh);
- }
- 50% {
- transform: translateY(6vh);
- }
- 75% {
- transform: translateY(-3vh);
- }
- }
- }
-
- .contents {
- @include S(width, 400px);
- @include InlineAnimation(0.5s ease-in-out) {
- 0% {
- transform: translateX(-100vw);
- }
- 50% {
- transform: translateX(5vw);
- }
-
- 75% {
- transform: translateX(-2vw);
- }
- }
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- @include S(grid-gap, 10px);
-
- .rewardName {
- grid-column: 1 / 3;
- display: none;
- @include InlineAnimation(0.5s ease-in-out) {
- 0% {
- transform: translateX(200vw);
- }
- 50% {
- transform: translateX(-10vw);
- }
-
- 75% {
- transform: translateX(4vw);
- }
- }
- }
-
- .rewardDesc {
- grid-column: 1 / 3;
- @include PlainText;
- @include S(margin-bottom, 15px);
- color: #aaacaf;
- @include S(width, 400px);
- text-align: left;
- strong {
- color: #fff;
- }
- }
-
- .images {
- display: flex;
- .buildingExplanation {
- @include S(width, 200px);
- @include S(height, 200px);
- display: inline-block;
- background-position: center center;
- background-size: cover;
- background-repeat: no-repeat;
- @include S(border-radius, $globalBorderRadius);
- box-shadow: #{D(2px)} #{D(3px)} 0 0 rgba(0, 0, 0, 0.15);
- }
- }
- }
-
- button.close {
- border: 0;
- position: relative;
- @include S(margin-top, 30px);
-
- &:not(.unlocked) {
- pointer-events: none;
- opacity: 0.8;
- cursor: default;
- }
-
- &.unlocked {
- &::after {
- animation: none !important;
- }
- }
-
- &::after {
- content: " ";
- display: inline-block;
- position: absolute;
- top: 0;
- left: 100%;
- right: 0;
- bottom: 0;
- background: rgba(0, 10, 20, 0.8);
-
- @include InlineAnimation(1.5s linear) {
- 0% {
- left: 0;
- }
- 100% {
- left: 100%;
- }
- }
- }
- }
- }
-}
+#ingame_HUD_UnlockNotification {
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ overflow: auto;
+ pointer-events: all;
+
+ & {
+ /* @load-async */
+ background: rgba(#333538, 0.98) uiResource("dialog_bg_pattern.png") top left / 1rem repeat;
+ }
+
+ @include InlineAnimation(0.1s ease-in-out) {
+ 0% {
+ opacity: 0;
+ }
+ }
+
+ .dialog {
+ // background: rgba(#222428, 0.5);
+ border-radius: $globalBorderRadius;
+ padding: 3rem;
+
+ @include InlineAnimation(0.5s ease-in-out) {
+ 0% {
+ opacity: 0;
+ }
+ }
+ display: flex;
+ align-items: center;
+ flex-direction: column;
+
+ color: #fff;
+ text-align: center;
+ .title,
+ .subTitle {
+ @include SuperHeading;
+ text-transform: uppercase;
+ font-size: 4rem;
+
+ @include InlineAnimation(0.5s ease-in-out) {
+ 0% {
+ transform: translateY(-50vh);
+ }
+ 50% {
+ transform: translateY(5vh);
+ }
+ 75% {
+ transform: translateY(-2vh);
+ }
+ }
+ }
+
+ .subTitle {
+ @include PlainText;
+ display: inline-block;
+ margin: 0.5rem 0 2rem;
+ color: $colorGreenBright;
+
+ border-radius: $globalBorderRadius;
+ @include InlineAnimation(0.5s ease-in-out) {
+ 0% {
+ transform: translateY(-60vh);
+ }
+ 50% {
+ transform: translateY(6vh);
+ }
+ 75% {
+ transform: translateY(-3vh);
+ }
+ }
+ }
+
+ .contents {
+ width: 40rem;
+ @include InlineAnimation(0.5s ease-in-out) {
+ 0% {
+ transform: translateX(-100vw);
+ }
+ 50% {
+ transform: translateX(5vw);
+ }
+
+ 75% {
+ transform: translateX(-2vw);
+ }
+ }
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ grid-gap: 1rem;
+
+ .rewardName {
+ grid-column: 1 / 3;
+ display: none;
+ @include InlineAnimation(0.5s ease-in-out) {
+ 0% {
+ transform: translateX(200vw);
+ }
+ 50% {
+ transform: translateX(-10vw);
+ }
+
+ 75% {
+ transform: translateX(4vw);
+ }
+ }
+ }
+
+ .rewardDesc {
+ grid-column: 1 / 3;
+ @include PlainText;
+ margin-bottom: 1.5rem;
+ color: #aaacaf;
+ width: 40rem;
+ text-align: left;
+ strong {
+ color: #fff;
+ }
+ }
+
+ .images {
+ display: flex;
+ .buildingExplanation {
+ width: 20rem;
+ height: 20rem;
+ display: inline-block;
+ background-position: center center;
+ background-size: cover;
+ background-repeat: no-repeat;
+ border-radius: $globalBorderRadius;
+ box-shadow: 0.2rem 0.3rem 0 0 rgba(0, 0, 0, 0.15);
+ }
+ }
+ }
+
+ button.close {
+ border: 0;
+ position: relative;
+ margin-top: 3rem;
+
+ &:not(.unlocked) {
+ pointer-events: none;
+ opacity: 0.8;
+ cursor: default;
+ }
+
+ &.unlocked {
+ &::after {
+ animation: none !important;
+ }
+ }
+
+ &::after {
+ content: " ";
+ display: inline-block;
+ position: absolute;
+ top: 0;
+ left: 100%;
+ right: 0;
+ bottom: 0;
+ background: rgba(0, 10, 20, 0.8);
+
+ @include InlineAnimation(1.5s linear) {
+ 0% {
+ left: 0;
+ }
+ 100% {
+ left: 100%;
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/css/ingame_hud/watermark.scss b/src/css/ingame_hud/watermark.scss
deleted file mode 100644
index f7a3d089..00000000
--- a/src/css/ingame_hud/watermark.scss
+++ /dev/null
@@ -1,107 +0,0 @@
-#ingame_HUD_Watermark {
- position: absolute;
-
- @include S(border-radius, $globalBorderRadius);
- @include S(top, 70px);
- pointer-events: all;
- cursor: pointer;
- left: 50%;
- text-align: center;
-
- background: rgba(207, 65, 65, 0.8);
- color: #fff;
- transform: translateX(-50%);
- @include PlainText;
- @include S(padding, 10px);
-
- &:hover {
- transform: translateX(-50%) scale(1.02) !important;
- }
-
- > strong {
- @include PlainText;
- text-transform: uppercase;
- }
- > p {
- @include SuperSmallText;
- opacity: 0.7;
- }
-
- opacity: 0;
-
- &.visible {
- @include InlineAnimation(0.5s ease-in-out) {
- 0% {
- opacity: 0;
- }
- 100% {
- opacity: 1;
- }
- }
- opacity: 1;
- }
-
- &:not(.visible) {
- @include InlineAnimation(0.5s ease-in-out) {
- 0% {
- opacity: 1;
- }
- 100% {
- opacity: 0;
- }
- }
- }
-}
-
-#ingame_HUD_WatermarkClicker {
- @include S(top, 55px);
- position: absolute;
- left: 50%;
- transform: translateX(-50%) !important;
- @include SuperSmallText;
- color: $colorBlueBright;
- text-transform: uppercase;
- pointer-events: all;
- cursor: pointer;
- display: flex;
- align-items: center;
-
- &:hover {
- opacity: 0.9;
- }
-
- &::after {
- @include S(margin-left, 4px);
- content: "";
- @include S(width, 10px);
- @include S(height, 10px);
- display: inline-flex;
- background: center center / contain no-repeat;
- & {
- /* @load-async */
- background-image: uiResource("res/ui/icons/demo_steam_link_indicator.png");
- }
- }
-
- &.withDiscount {
- color: #4c6b22;
- }
-
- > .discount {
- // position: absolute;
- @include S(margin, 0, 5px);
-
- background: rgba(#4c6b22, 1);
- color: #c5ea3f;
- @include S(border-radius, $globalBorderRadius);
- @include S(padding, 0px, 2px, 0px, 3px);
- @include SuperSmallText;
- text-transform: uppercase;
- transform: rotate(0deg);
- @include InlineAnimation(1.3s ease-in-out infinite) {
- 50% {
- transform: rotate(0.5deg) scale(1.05);
- }
- }
- }
-}
diff --git a/src/css/ingame_hud/waypoints.scss b/src/css/ingame_hud/waypoints.scss
index f7566ee5..9537eb01 100644
--- a/src/css/ingame_hud/waypoints.scss
+++ b/src/css/ingame_hud/waypoints.scss
@@ -1,122 +1,122 @@
-#ingame_HUD_Waypoints_Hint {
- position: absolute;
- @include S(right, 10px);
- @include S(bottom, 10px);
-
- display: flex;
- flex-direction: column;
-
- @include PlainText;
- @include S(width, 150px);
- background: $ingameHudBg;
- @include S(padding, 7px);
-
- color: #eee;
- @include S(border-radius, $globalBorderRadius);
-
- .desc {
- @include SuperSmallText;
- color: #babcbf;
- .keybinding {
- position: relative;
- }
-
- strong {
- color: #fff;
- }
- }
-}
-
-#ingame_HUD_Waypoints {
- position: absolute;
- @include S(right, 10px);
- @include S(top, 45px);
- display: flex;
- flex-direction: column;
- @include DarkThemeInvert();
-
- max-height: 50vh;
- overflow-x: hidden;
- overflow-y: auto;
- pointer-events: all;
- @include S(padding-right, 5px);
- @include S(padding-bottom, 5px);
- @include S(padding-top, 5px);
-
- // Scrollbar
- &::-webkit-scrollbar {
- @include S(width, 2px);
- @include S(height, 6px);
- }
-
- .waypoint {
- @include SuperSmallText;
- pointer-events: all;
- cursor: pointer;
- color: #333438;
- @include S(padding-left, 11px);
- display: grid;
- grid-template-columns: 1fr auto;
- align-items: center;
- & {
- /* @load-async */
- background: uiResource("icons/waypoint.png") left 50% / #{D(8px)} no-repeat;
- }
-
- &.layer--wires {
- /* @load-async */
- background-image: uiResource("icons/waypoint_wires.png");
- }
-
- opacity: 0.7;
- @include S(margin-bottom, 1px);
- font-weight: bold;
-
- &:hover {
- opacity: 0.8;
- }
-
- .editButton {
- @include S(width, 10px);
- @include S(height, 10px);
- @include S(margin-left, 4px);
- & {
- /* @load-async */
- background: uiResource("icons/edit_key.png") center center / 70% no-repeat;
- }
- pointer-events: all;
- cursor: pointer;
- position: relative;
- @include IncreasedClickArea(2px);
- transition: transform 0.04s ease-in-out;
-
- &:hover {
- transform: scale(1.5);
- }
- }
-
- &.hub {
- // Transform because there is a canvas before
- @include S(margin-left, -2px);
-
- grid-template-columns: auto 1fr;
- background: none !important;
- @include S(padding-left, 0);
- canvas {
- @include S(width, 12px);
- @include S(height, 12px);
- @include S(margin-right, 1px);
- }
- }
-
- &.shapeIcon {
- canvas {
- @include S(width, 15px);
- @include S(height, 15px);
- pointer-events: none;
- // Double invert, to make sure it has the right color
- @include DarkThemeInvert();
- }
- }
- }
-}
+#ingame_HUD_Waypoints_Hint {
+ position: absolute;
+ right: 1rem;
+ bottom: 1rem;
+
+ display: flex;
+ flex-direction: column;
+
+ @include PlainText;
+ width: 15rem;
+ background: $ingameHudBg;
+ padding: 0.7rem;
+
+ color: #eee;
+ border-radius: $globalBorderRadius;
+
+ .desc {
+ @include SuperSmallText;
+ color: #babcbf;
+
+ kbd {
+ position: relative;
+ }
+
+ strong {
+ color: #fff;
+ }
+ }
+}
+
+#ingame_HUD_Waypoints {
+ position: absolute;
+ right: 1rem;
+ top: 4.5rem;
+ display: flex;
+ flex-direction: column;
+ @include DarkThemeInvert();
+
+ max-height: 50vh;
+ overflow-x: hidden;
+ overflow-y: auto;
+ pointer-events: all;
+ padding-right: 0.5rem;
+ padding-bottom: 0.5rem;
+ padding-top: 0.5rem;
+
+ // Scrollbar
+ &::-webkit-scrollbar {
+ width: 0.2rem;
+ height: 0.6rem;
+ }
+
+ .waypoint {
+ @include SuperSmallText;
+ pointer-events: all;
+ cursor: pointer;
+ color: #333438;
+ padding-left: 1.1rem;
+ display: grid;
+ grid-template-columns: 1fr auto;
+ align-items: center;
+ & {
+ /* @load-async */
+ background: uiResource("icons/waypoint.png") left 50% / 0.8rem no-repeat;
+ }
+
+ &.layer--wires {
+ /* @load-async */
+ background-image: uiResource("icons/waypoint_wires.png");
+ }
+
+ opacity: 0.7;
+ margin-bottom: 0.1rem;
+ font-weight: bold;
+
+ &:hover {
+ opacity: 0.8;
+ }
+
+ .editButton {
+ width: 1rem;
+ height: 1rem;
+ margin-left: 0.4rem;
+ & {
+ /* @load-async */
+ background: uiResource("icons/edit_key.png") center center / 70% no-repeat;
+ }
+ pointer-events: all;
+ cursor: pointer;
+ position: relative;
+ transition: transform 0.04s ease-in-out;
+
+ &:hover {
+ transform: scale(1.5);
+ }
+ }
+
+ &.hub {
+ // Transform because there is a canvas before
+ margin-left: -0.2rem;
+
+ grid-template-columns: auto 1fr;
+ background: none !important;
+ padding-left: 0;
+ canvas {
+ width: 1.2rem;
+ height: 1.2rem;
+ margin-right: 0.1rem;
+ }
+ }
+
+ &.shapeIcon {
+ canvas {
+ width: 1.5rem;
+ height: 1.5rem;
+ pointer-events: none;
+ // Double invert, to make sure it has the right color
+ @include DarkThemeInvert();
+ }
+ }
+ }
+}
diff --git a/src/css/main.scss b/src/css/main.scss
index f1ec8570..74ad265c 100644
--- a/src/css/main.scss
+++ b/src/css/main.scss
@@ -1,135 +1,126 @@
-// Control here whether to inline all resources or instead load them
-@function uiResource($pth) {
- @if (str-index($string: $pth, $substring: ".noinline")) {
- @return resolve($pth);
- }
- @return inline($pth);
-}
-
-@import "resources";
-@import "trigonometry";
-@import "material_colors";
-@import "dynamic_ui";
-@import "variables";
-
-@import "mixins";
-@import "common";
-@import "animations";
-@import "game_state";
-@import "textual_game_state";
-@import "adinplay";
-@import "changelog_skins";
-
-@import "states/wegame_splash";
-@import "states/preload";
-@import "states/main_menu";
-@import "states/ingame";
-@import "states/keybindings";
-@import "states/settings";
-@import "states/about";
-@import "states/mobile_warning";
-@import "states/changelog";
-@import "states/puzzle_menu";
-@import "states/mods";
-
-@import "ingame_hud/buildings_toolbar";
-@import "ingame_hud/building_placer";
-@import "ingame_hud/beta_overlay";
-@import "ingame_hud/keybindings_overlay";
-@import "ingame_hud/unlock_notification";
-@import "ingame_hud/shop";
-@import "ingame_hud/game_menu";
-@import "ingame_hud/dialogs";
-@import "ingame_hud/vignette_overlay";
-@import "ingame_hud/statistics";
-@import "ingame_hud/pinned_shapes";
-@import "ingame_hud/notifications";
-@import "ingame_hud/settings_menu";
-@import "ingame_hud/debug_info";
-@import "ingame_hud/entity_debugger";
-@import "ingame_hud/tutorial_hints";
-@import "ingame_hud/watermark";
-@import "ingame_hud/blueprint_placer";
-@import "ingame_hud/waypoints";
-@import "ingame_hud/interactive_tutorial";
-@import "ingame_hud/color_blind_helper";
-@import "ingame_hud/shape_viewer";
-@import "ingame_hud/sandbox_controller";
-@import "ingame_hud/standalone_advantages";
-@import "ingame_hud/puzzle_back_to_menu";
-@import "ingame_hud/puzzle_editor_review";
-@import "ingame_hud/puzzle_dlc_logo";
-@import "ingame_hud/puzzle_editor_controls";
-@import "ingame_hud/puzzle_editor_settings";
-@import "ingame_hud/puzzle_play_settings";
-@import "ingame_hud/puzzle_play_metadata";
-@import "ingame_hud/puzzle_complete_notification";
-@import "ingame_hud/puzzle_next";
-
-// prettier-ignore
-$elements:
-// Base
-ingame_Canvas,
-ingame_VignetteOverlay,
-ingame_HUD_PuzzleDLCLogo,
-
-// Ingame overlays
-ingame_HUD_Waypoints,
-ingame_HUD_PlacementHints,
-ingame_HUD_PlacerVariants,
-
-// Regular hud
-ingame_HUD_PinnedShapes,
-ingame_HUD_GameMenu,
-ingame_HUD_KeybindingOverlay,
-ingame_HUD_PuzzleBackToMenu,
-ingame_HUD_PuzzleNextPuzzle,
-ingame_HUD_PuzzleEditorReview,
-ingame_HUD_PuzzleEditorControls,
-ingame_HUD_PuzzleEditorTitle,
-ingame_HUD_PuzzleEditorSettings,
-ingame_HUD_PuzzlePlaySettings,
-ingame_HUD_PuzzlePlayMetadata,
-ingame_HUD_PuzzlePlayTitle,
-ingame_HUD_Notifications,
-ingame_HUD_DebugInfo,
-ingame_HUD_EntityDebugger,
-ingame_HUD_TutorialHints,
-ingame_HUD_InteractiveTutorial,
-ingame_HUD_BuildingsToolbar,
-ingame_HUD_wires_toolbar,
-ingame_HUD_BlueprintPlacer,
-ingame_HUD_Waypoints_Hint,
-ingame_HUD_WatermarkClicker,
-ingame_HUD_Watermark,
-ingame_HUD_ColorBlindBelowTileHelper,
-ingame_HUD_SandboxController,
-
-// Overlays
-ingame_HUD_BetaOverlay,
-
-// Dialogs
-ingame_HUD_Shop,
-ingame_HUD_Statistics,
-ingame_HUD_ShapeViewer,
-ingame_HUD_StandaloneAdvantages,
-ingame_HUD_UnlockNotification,
-ingame_HUD_PuzzleCompleteNotification,
-ingame_HUD_SettingsMenu,
-ingame_HUD_ModalDialogs;
-
-$zindex: 100;
-
-@each $elem in $elements {
- ##{$elem} {
- z-index: $zindex;
- }
-
- $zindex: $zindex + 10;
-}
-
-body.uiHidden {
- > div:not(.ingameDialog):not(#ingame_HUD_SettingsMenu):not(#ingame_HUD_ModalDialogs):not(#ingame_HUD_UnlockNotification):not(#ingame_HUD_PuzzleCompleteNotification) {
- display: none !important;
- }
-}
+// Control here whether to inline all resources or instead load them
+@function uiResource($pth) {
+ @if (str-index($string: $pth, $substring: ".noinline")) {
+ @return resolve($pth);
+ }
+ @return inline($pth);
+}
+
+@import "resources";
+@import "variables";
+
+@import "mixins";
+@import "common";
+@import "game_state";
+@import "textual_game_state";
+@import "error_handler";
+
+@import "states/preload";
+@import "states/main_menu";
+@import "states/ingame";
+@import "states/keybindings";
+@import "states/settings";
+@import "states/about";
+@import "states/changelog";
+@import "states/puzzle_menu";
+@import "states/mods";
+
+@import "ingame_hud/buildings_toolbar";
+@import "ingame_hud/building_placer";
+@import "ingame_hud/beta_overlay";
+@import "ingame_hud/keybindings_overlay";
+@import "ingame_hud/unlock_notification";
+@import "ingame_hud/shop";
+@import "ingame_hud/game_menu";
+@import "ingame_hud/dialogs";
+@import "ingame_hud/vignette_overlay";
+@import "ingame_hud/statistics";
+@import "ingame_hud/pinned_shapes";
+@import "ingame_hud/notifications";
+@import "ingame_hud/settings_menu";
+@import "ingame_hud/debug_info";
+@import "ingame_hud/entity_debugger";
+@import "ingame_hud/tutorial_hints";
+@import "ingame_hud/blueprint_placer";
+@import "ingame_hud/waypoints";
+@import "ingame_hud/interactive_tutorial";
+@import "ingame_hud/color_blind_helper";
+@import "ingame_hud/shape_viewer";
+@import "ingame_hud/sandbox_controller";
+@import "ingame_hud/puzzle_back_to_menu";
+@import "ingame_hud/puzzle_editor_review";
+@import "ingame_hud/puzzle_dlc_logo";
+@import "ingame_hud/puzzle_editor_controls";
+@import "ingame_hud/puzzle_editor_settings";
+@import "ingame_hud/puzzle_play_settings";
+@import "ingame_hud/puzzle_play_metadata";
+@import "ingame_hud/puzzle_complete_notification";
+@import "ingame_hud/puzzle_next";
+
+// prettier-ignore
+$elements:
+// Base
+ingame_Canvas,
+ingame_VignetteOverlay,
+ingame_HUD_PuzzleDLCLogo,
+
+// Ingame overlays
+ingame_HUD_Waypoints,
+ingame_HUD_PlacementHints,
+ingame_HUD_PlacerVariants,
+
+// Regular hud
+ingame_HUD_PinnedShapes,
+ingame_HUD_GameMenu,
+ingame_HUD_KeybindingOverlay,
+ingame_HUD_PuzzleBackToMenu,
+ingame_HUD_PuzzleNextPuzzle,
+ingame_HUD_PuzzleEditorReview,
+ingame_HUD_PuzzleEditorControls,
+ingame_HUD_PuzzleEditorTitle,
+ingame_HUD_PuzzleEditorSettings,
+ingame_HUD_PuzzlePlaySettings,
+ingame_HUD_PuzzlePlayMetadata,
+ingame_HUD_PuzzlePlayTitle,
+ingame_HUD_Notifications,
+ingame_HUD_DebugInfo,
+ingame_HUD_EntityDebugger,
+ingame_HUD_TutorialHints,
+ingame_HUD_InteractiveTutorial,
+ingame_HUD_BuildingsToolbar,
+ingame_HUD_wires_toolbar,
+ingame_HUD_BlueprintPlacer,
+ingame_HUD_Waypoints_Hint,
+ingame_HUD_WatermarkClicker,
+ingame_HUD_ColorBlindBelowTileHelper,
+ingame_HUD_SandboxController,
+
+// Overlays
+ingame_HUD_BetaOverlay,
+
+// Dialogs
+ingame_HUD_Shop,
+ingame_HUD_Statistics,
+ingame_HUD_ShapeViewer,
+ingame_HUD_UnlockNotification,
+ingame_HUD_PuzzleCompleteNotification,
+ingame_HUD_SettingsMenu,
+ingame_HUD_ModalDialogs;
+
+$zindex: 100;
+
+@each $elem in $elements {
+ ##{$elem} {
+ z-index: $zindex;
+ }
+
+ $zindex: $zindex + 10;
+}
+
+body.uiHidden {
+ > div:not(.ingameDialog):not(#ingame_HUD_SettingsMenu):not(#ingame_HUD_ModalDialogs):not(
+ #ingame_HUD_UnlockNotification
+ ):not(#ingame_HUD_PuzzleCompleteNotification) {
+ display: none !important;
+ }
+}
diff --git a/src/css/material_colors.scss b/src/css/material_colors.scss
deleted file mode 100644
index dd4bdd1d..00000000
--- a/src/css/material_colors.scss
+++ /dev/null
@@ -1,319 +0,0 @@
-//
-// color palette
-
-// sass-lint:disable hex-length
-
-@function color($color, $value: 500) {
- @return map-get($color, $value);
-}
-
-$red: (
- 50: #ffebee,
- 100: #ffcdd2,
- 200: #ef9a9a,
- 300: #e57373,
- 400: #ef5350,
- 500: #f44336,
- 600: #e53935,
- 700: #d32f2f,
- 800: #c62828,
- 900: #b71c1c,
- a100: #ff8a80,
- a200: #ff5252,
- a400: #ff1744,
- a700: #d50000,
-);
-
-$pink: (
- 50: #fce4ec,
- 100: #f8bbd0,
- 200: #f48fb1,
- 300: #f06292,
- 400: #ec407a,
- 500: #e91e63,
- 600: #d81b60,
- 700: #c2185b,
- 800: #ad1457,
- 900: #880e4f,
- a100: #ff80ab,
- a200: #ff4081,
- a400: #f50057,
- a700: hsl(333, 84%, 42%),
-);
-
-$purple: (
- 50: #f3e5f5,
- 100: #e1bee7,
- 200: #ce93d8,
- 300: #ba68c8,
- 400: #ab47bc,
- 500: #9c27b0,
- 600: #8e24aa,
- 700: #7b1fa2,
- 800: #6a1b9a,
- 900: #4a148c,
- a100: #ea80fc,
- a200: #e040fb,
- a400: #d500f9,
- a700: #aa00ff,
-);
-
-$deep-purple: (
- 50: #ede7f6,
- 100: #d1c4e9,
- 200: #b39ddb,
- 300: #9575cd,
- 400: #7e57c2,
- 500: #673ab7,
- 600: #5e35b1,
- 700: #512da8,
- 800: #4527a0,
- 900: #311b92,
- a100: #b388ff,
- a200: #7c4dff,
- a400: #651fff,
- a700: #6200ea,
-);
-
-$indigo: (
- 50: #e8eaf6,
- 100: #c5cae9,
- 200: #9fa8da,
- 300: #7986cb,
- 400: #5c6bc0,
- 500: #3f51b5,
- 600: #3949ab,
- 700: #303f9f,
- 800: #283593,
- 900: #1a237e,
- a100: #8c9eff,
- a200: #536dfe,
- a400: #3d5afe,
- a700: #304ffe,
-);
-
-$blue: (
- 50: #e3f2fd,
- 100: #bbdefb,
- 200: #90caf9,
- 300: #64b5f6,
- 400: #42a5f5,
- 500: #2196f3,
- 600: #1e88e5,
- 700: #1976d2,
- 800: #1565c0,
- 900: #0d47a1,
- a100: #82b1ff,
- a200: #448aff,
- a400: #2979ff,
- a700: #2962ff,
-);
-
-$light-blue: (
- 50: #e1f5fe,
- 100: #b3e5fc,
- 200: #81d4fa,
- 300: #4fc3f7,
- 400: #29b6f6,
- 500: #03a9f4,
- 600: #039be5,
- 700: #0288d1,
- 800: #0277bd,
- 900: #01579b,
- a100: #80d8ff,
- a200: #40c4ff,
- a400: #00b0ff,
- a700: #0091ea,
-);
-
-$cyan: (
- 50: #e0f7fa,
- 100: #b2ebf2,
- 200: #80deea,
- 300: #4dd0e1,
- 400: #26c6da,
- 500: #00bcd4,
- 600: #00acc1,
- 700: #0097a7,
- 800: #00838f,
- 900: #006064,
- a100: #84ffff,
- a200: #18ffff,
- a400: #00e5ff,
- a700: #00b8d4,
-);
-
-$teal: (
- 50: #e0f2f1,
- 100: #b2dfdb,
- 200: #80cbc4,
- 300: #4db6ac,
- 400: #26a69a,
- 500: #009688,
- 600: #00897b,
- 700: #00796b,
- 800: #00695c,
- 900: #004d40,
- a100: #a7ffeb,
- a200: #64ffda,
- a400: #1de9b6,
- a700: #00bfa5,
-);
-
-$green: (
- 50: #e8f5e9,
- 100: #c8e6c9,
- 200: #a5d6a7,
- 300: #81c784,
- 400: #66bb6a,
- 500: #4caf50,
- 600: #43a047,
- 700: #388e3c,
- 800: #2e7d32,
- 900: #1b5e20,
- a100: #b9f6ca,
- a200: #69f0ae,
- a400: #00e676,
- a700: #00c853,
-);
-
-$light-green: (
- 50: #f1f8e9,
- 100: #dcedc8,
- 200: #c5e1a5,
- 300: #aed581,
- 400: #9ccc65,
- 500: #8bc34a,
- 600: #7cb342,
- 700: #689f38,
- 800: #558b2f,
- 900: #33691e,
- a100: #ccff90,
- a200: #b2ff59,
- a400: #76ff03,
- a700: #64dd17,
-);
-
-$lime: (
- 50: #f9fbe7,
- 100: #f0f4c3,
- 200: #e6ee9c,
- 300: #dce775,
- 400: #d4e157,
- 500: #cddc39,
- 600: #c0ca33,
- 700: #afb42b,
- 800: #9e9d24,
- 900: #827717,
- a100: #f4ff81,
- a200: #eeff41,
- a400: #c6ff00,
- a700: #aeea00,
-);
-
-$yellow: (
- 50: #fffde7,
- 100: #fff9c4,
- 200: #fff59d,
- 300: #fff176,
- 400: #ffee58,
- 500: #ffeb3b,
- 600: #fdd835,
- 700: #fbc02d,
- 800: #f9a825,
- 900: #f57f17,
- a100: #ffff8d,
- a200: #ffff00,
- a400: #ffea00,
- a700: #ffd600,
-);
-
-$amber: (
- 50: #fff8e1,
- 100: #ffecb3,
- 200: #ffe082,
- 300: #ffd54f,
- 400: #ffca28,
- 500: #ffc107,
- 600: #ffb300,
- 700: #ffa000,
- 800: #ff8f00,
- 900: #ff6f00,
- a100: #ffe57f,
- a200: #ffd740,
- a400: #ffc400,
- a700: #ffab00,
-);
-
-$orange: (
- 50: #fff3e0,
- 100: #ffe0b2,
- 200: #ffcc80,
- 300: #ffb74d,
- 400: #ffa726,
- 500: #ff9800,
- 600: #fb8c00,
- 700: #f57c00,
- 800: #ef6c00,
- 900: #e65100,
- a100: #ffd180,
- a200: #ffab40,
- a400: #ff9100,
- a700: #ff6d00,
-);
-
-$deep-orange: (
- 50: #fbe9e7,
- 100: #ffccbc,
- 200: #ffab91,
- 300: #ff8a65,
- 400: #ff7043,
- 500: #ff5722,
- 600: #f4511e,
- 700: #e64a19,
- 800: #d84315,
- 900: #bf360c,
- a100: #ff9e80,
- a200: #ff6e40,
- a400: #ff3d00,
- a700: #dd2c00,
-);
-
-$brown: (
- 50: #efebe9,
- 100: #d7ccc8,
- 200: #bcaaa4,
- 300: #a1887f,
- 400: #8d6e63,
- 500: #795548,
- 600: #6d4c41,
- 700: #5d4037,
- 800: #4e342e,
- 900: #3e2723,
-);
-
-$grey: (
- 50: #fafafa,
- 100: #f5f5f5,
- 200: #eeeeee,
- 300: #e0e0e0,
- 400: #bdbdbd,
- 500: #9e9e9e,
- 600: #757575,
- 700: #616161,
- 800: #424242,
- 900: #212121,
-);
-
-$blue-grey: (
- 50: #eceff1,
- 100: #cfd8dc,
- 200: #b0bec5,
- 300: #90a4ae,
- 400: #78909c,
- 500: #607d8b,
- 600: #546e7a,
- 700: #455a64,
- 800: #37474f,
- 900: #263238,
-);
diff --git a/src/css/mixins.scss b/src/css/mixins.scss
index d0a4f367..7a4c0e1a 100644
--- a/src/css/mixins.scss
+++ b/src/css/mixins.scss
@@ -1,292 +1,80 @@
-// ----------------------------------------
-/* Forces an element to get rendered on its own layer, increasing
-the performance when animated. Use only transform and opacity in animations! */
-@mixin FastAnimation {
- will-change: transform, opacity, filter;
- // transform: translateZ(0);
- backface-visibility: hidden;
- -webkit-backface-visibility: hidden;
-}
-
-// Helper which includes the translateZ webkit fix, use together with Fast animation
-// $hardwareAcc: translateZ(0);
-$hardwareAcc: null;
-
-// ----------------------------------------
-/** Increased click area for this element, helpful on mobile */
-@mixin IncreasedClickArea($size) {
- // &::after {
- // content: "";
- // position: absolute;
- // top: #{D(-$size)};
- // bottom: #{D(-$size)};
- // left: #{D(-$size)};
- // right: #{D(-$size)};
- // // background: rgba(255, 0, 0, 0.3);
- // }
-}
-button,
-.increasedClickArea {
- position: relative;
- @include IncreasedClickArea(15px);
-}
-
-// ----------------------------------------
-/* Duplicates an animation and adds two classes .Even and .Odd which uses the
- animation. This can be used to replay the animation by toggling between the classes, because
- it is not possible to restart a css animation */
-@mixin MakeAnimationWrappedEvenOdd($duration, $classPrefix: "anim", $childSelector: "") {
- $animName: autogen_anim_#{unique-id()};
-
- @at-root {
- @keyframes #{$animName}_even {
- @content;
- }
-
- @keyframes #{$animName}_odd {
- @content;
- }
- }
-
- &.#{$classPrefix}Even #{$childSelector} {
- animation: #{$animName}_even $duration;
- }
-
- &.#{$classPrefix}Odd #{$childSelector} {
- animation: #{$animName}_odd $duration;
- }
-}
-
-// ----------------------------------------
-/* Allows to use and define an animation without specifying its name */
-@mixin InlineAnimation($duration) {
- $animName: autogen_anim_#{unique-id()};
-
- @at-root {
- @keyframes #{$animName} {
- @content;
- }
- }
-
- animation: $animName $duration !important;
-}
-
-// ----------------------------------------
-/* Animation prefab for a double bounce pop-in animation, useful for dialogs */
-@mixin DoubleBounceAnim($duration: 0.5s ease-in-out, $amount: 0.2, $initialOpacity: 0) {
- @include InlineAnimation($duration) {
- 0% {
- opacity: $initialOpacity;
- transform: scale(0) $hardwareAcc;
- }
-
- 25% {
- opacity: 0.5;
- transform: scale(1 + $amount) $hardwareAcc;
- }
-
- 50% {
- opacity: 1;
- transform: scale(1 - $amount * 0.5) $hardwareAcc;
- }
-
- 75% {
- transform: scale(1 + $amount * 0.25) $hardwareAcc;
- }
-
- 100% {
- transform: scale(1) $hardwareAcc;
- }
- }
-
- opacity: 1;
-}
-
-// ----------------------------------------
-/* Automatically transforms the game state if a hardware keyboard is open */
-@mixin TransformToMatchKeyboard {
- transition: transform 0.2s ease-in-out;
- @include AndroidHwKeyboardOpen {
- @include VerticalStyle {
- transform: translateY(#{D(-125px)}) $hardwareAcc;
- }
- @include HorizontalStyle {
- transform: translateY(#{D(-100px)}) $hardwareAcc;
- }
- }
-}
-
-// ----------------------------------------
-/* Define a style which is only applied when the viewport is at least X pixels wide */
-@mixin StyleAtWidth($minW) {
- @media (min-width: #{$minW}) {
- @content;
- }
-}
-
-// ----------------------------------------
-/* Define a style which is only applied when the viewport is at least X pixels height */
-@mixin StyleAtHeight($minH) {
- @media (min-height: #{$minH}) {
- @content;
- }
-}
-
-// ----------------------------------------
-/* Define a style which is only applied when the viewport has at least the given dimensions */
-@mixin StyleAtDims($minW, $minH) {
- @media (min-height: #{$minH}) and (min-width: #{$minW}) {
- @content;
- }
-}
-
-// ----------------------------------------
-/* Define a style which is only applied when the viewport has at maximum the given dimensions */
-@mixin StyleBelowDims($maxW, $maxH) {
- @media (max-height: #{$maxH}) and (max-width: #{$maxW}) {
- @content;
- }
-}
-
-// ----------------------------------------
-/* Define a style which is only applied when the viewport has at maximum the given height */
-@mixin StyleBelowHeight($maxH) {
- @media (max-height: #{$maxH}) {
- @content;
- }
-}
-// ----------------------------------------
-/* Define a style which is only applied when the viewport has at maximum the given width */
-@mixin StyleBelowWidth($maxW) {
- @media (max-width: #{$maxW}) {
- @content;
- }
-}
-
-// ----------------------------------------
-// Dynamic graphics quality styles
-
-@mixin BoxShadow3D($bgColor, $size: 3px, $pressEffect: true) {
- background-color: $bgColor;
-
- $borderSize: 1.5px;
- $borderColor: rgb(18, 20, 24);
-
- // box-shadow: 0 0 0 D($borderSize) $borderColor, 0 D($size) 0 0px rgba(mix(darken($bgColor, 9), #b0e2ff, 95%), 1),
- // 0 D($size) 0 D($borderSize) $borderColor;
-
- // box-shadow: 0 0 0 D($borderSize) $borderColor, 0 D($size) 0 D($borderSize) $borderColor,
- // D(-$size * 1.5) D($size * 2) 0 D($borderSize) rgba(0, 0, 0, 0.1);
-
- // transition: box-shadow 0.1s ease-in-out;
-
- // @if $pressEffect {
- // &.pressed {
- // transform: none !important;
- // $pSize: max(0, $size - 1.5px);
- // transition: none !important;
- // box-shadow: 0 0 0 D($borderSize) $borderColor, 0 D($pSize) 0 0px rgba(mix(darken($bgColor, 9), #b0e2ff, 95%), 1),
- // 0 D($pSize) 0 D($borderSize) $borderColor;
- // top: D($size - $pSize);
- // }
- // }
-}
-
-@mixin BorderRadius($v1: 2px, $v2: "", $v3: "", $v4: "") {
- @include S(border-radius, $v1, $v2, $v3, $v4);
-}
-
-@mixin BoxShadow($x, $y, $blur, $offset, $color) {
- box-shadow: D($x) D($y) D($blur) D($offset) $color;
-}
-
-@mixin DropShadow($yOffset: 2px, $blur: 2px, $amount: 0.2) {
- @include BoxShadow(0, $yOffset, $blur, 0, rgba(#000, $amount));
-}
-
-@mixin TextShadow($yOffset: 2px, $blur: 1px, $amount: 0.6) {
- text-shadow: 0 D($yOffset) D($blur) rgba(#000, $amount);
-}
-
-@mixin Button3D($bgColor, $pressEffect: true) {
- @include BoxShadow3D($bgColor, 2px, $pressEffect);
-}
-
-@mixin ButtonDisabled3D($bgColor) {
- @include BoxShadow3D($bgColor, 0.5px, false);
-}
-
-@mixin BoxShadowInset($bgColor, $size: 3px) {
- background-color: $bgColor;
-
- $borderSize: 1px;
- $borderColor: rgb(15, 19, 24);
- box-shadow: 0 0 0 D($borderSize) $borderColor, 0 D($size) 0 rgba(#fff, 0.07);
- border-top: D($size) solid rgba(#000, 0.1);
-
- //, 0 D($size) 0 0px rgba(mix(darken($bgColor, 9), #b0e2ff, 95%), 1),
- // 0 D($size + $borderSize) 0 0 $borderColor;
-}
-
-@mixin TextShadow3D($color: rgb(222, 234, 238), $borderColor: #000) {
- color: $color;
-}
-
-// ----------------------------------------
-/* String replacement */
-@function str-replace($string, $search, $replace: "") {
- $index: str-index($string, $search);
-
- @if $index {
- @return str-slice($string, 1, $index - 1) + $replace +
- str-replace(str-slice($string, $index + str-length($search)), $search, $replace);
- }
-
- @return $string;
-}
-
-@mixin BounceInFromSide($mul, $duration: 0.18s ease-in-out) {
- @include InlineAnimation($duration) {
- 0% {
- transform: translateY(#{D(-100px * $mul)}) scale(0.9);
- opacity: 0;
- }
-
- 100% {
- opacity: 1;
- transform: none;
- }
- }
- opacity: 1;
- transform: none;
-}
-
-@mixin BreakText {
- word-wrap: break-word;
- word-break: break-all;
- overflow-wrap: break-all;
-}
-
-@mixin SupportsAndroidNotchQuery {
- @supports (color: constant(--notch-inset-left)) {
- @content;
- }
-}
-@mixin SupportsiOsNotchQuery {
- @supports (color: env(safe-area-inset-left, 0px)) {
- @content;
- }
-}
-
-@mixin DarkThemeOverride {
- @at-root html[data-theme="dark"] &,
- &[data-theme="dark"] {
- @content;
- }
-}
-
-@mixin DarkThemeInvert {
- @include DarkThemeOverride {
- filter: invert(1);
- }
-}
+// ----------------------------------------
+/* Duplicates an animation and adds two classes .Even and .Odd which uses the
+ animation. This can be used to replay the animation by toggling between the classes, because
+ it is not possible to restart a css animation */
+@mixin MakeAnimationWrappedEvenOdd($duration, $classPrefix: "anim", $childSelector: "") {
+ $animName: autogen_anim_#{unique-id()};
+
+ @at-root {
+ @keyframes #{$animName}_even {
+ @content;
+ }
+
+ @keyframes #{$animName}_odd {
+ @content;
+ }
+ }
+
+ &.#{$classPrefix}Even #{$childSelector} {
+ animation: #{$animName}_even $duration;
+ }
+
+ &.#{$classPrefix}Odd #{$childSelector} {
+ animation: #{$animName}_odd $duration;
+ }
+}
+
+// ----------------------------------------
+/* Allows to use and define an animation without specifying its name */
+@mixin InlineAnimation($duration) {
+ $animName: autogen_anim_#{unique-id()};
+
+ @at-root {
+ @keyframes #{$animName} {
+ @content;
+ }
+ }
+
+ animation: $animName $duration !important;
+}
+
+// ----------------------------------------
+/* Define a style which is only applied when the viewport has at maximum the given width */
+@mixin StyleBelowWidth($maxW) {
+ @media (max-width: #{$maxW}) {
+ @content;
+ }
+}
+
+// ----------------------------------------
+// Dynamic graphics quality styles
+
+@mixin BoxShadow3D($bgColor, $size: 3px, $pressEffect: true) {
+ background-color: $bgColor;
+
+ $borderSize: 1.5px;
+ $borderColor: rgb(18, 20, 24);
+}
+
+@mixin DropShadow($yOffset: 0.2rem, $blur: 0.2rem, $amount: 0.2) {
+ box-shadow: 0 $yOffset $blur 0 rgba(#000, $amount);
+}
+
+@mixin Button3D($bgColor, $pressEffect: true) {
+ @include BoxShadow3D($bgColor, 2px, $pressEffect);
+}
+
+$legacyTextShadow3DColor: rgb(222, 234, 238);
+
+@mixin DarkThemeOverride {
+ @at-root html[data-theme="dark"] &,
+ &[data-theme="dark"] {
+ @content;
+ }
+}
+
+@mixin DarkThemeInvert {
+ @include DarkThemeOverride {
+ filter: invert(1);
+ }
+}
diff --git a/src/css/resources.scss b/src/css/resources.scss
index 2d1e46ae..de6ce65e 100644
--- a/src/css/resources.scss
+++ b/src/css/resources.scss
@@ -1,84 +1,80 @@
-$buildings: belt, cutter, miner, mixer, painter, rotater, balancer, stacker, trash, underground_belt, wire,
- constant_signal, logic_gate, lever, filter, wire_tunnel, display, virtual_processor, reader, storage,
- transistor, analyzer, comparator, item_producer, constant_producer, goal_acceptor, block;
-
-@each $building in $buildings {
- [data-icon="building_icons/#{$building}.png"] {
- /* @load-async */
- .icon {
- background-image: uiResource("res/ui/building_icons/#{$building}.png") !important;
- }
- }
-}
-
-$buildingsAndVariants: belt, balancer, underground_belt, underground_belt-tier2, miner, miner-chainable,
- cutter, cutter-quad, rotater, rotater-ccw, stacker, mixer, painter-double, painter-quad, trash, storage,
- reader, rotater-rotate180, display, constant_signal, wire, wire_tunnel, logic_gate-or, logic_gate-not,
- logic_gate-xor, analyzer, virtual_processor-rotater, virtual_processor-unstacker, item_producer,
- constant_producer, virtual_processor-stacker, virtual_processor-painter, wire-second, painter,
- painter-mirrored, comparator, goal_acceptor, block;
-@each $building in $buildingsAndVariants {
- [data-icon="building_tutorials/#{$building}.png"] {
- /* @load-async */
- background-image: uiResource("res/ui/building_tutorials/#{$building}.png") !important;
- }
-}
-
-[data-icon="building_tutorials/balancer-merger.png"],
-[data-icon="building_tutorials/balancer-merger-inverse.png"] {
- /* @load-async */
- background-image: uiResource("res/ui/building_tutorials/balancer-merger.png") !important;
-}
-
-[data-icon="building_tutorials/balancer-splitter.png"],
-[data-icon="building_tutorials/balancer-splitter-inverse.png"] {
- /* @load-async */
- background-image: uiResource("res/ui/building_tutorials/balancer-splitter.png") !important;
-}
-
-[data-icon="building_tutorials/transistor.png"],
-[data-icon="building_tutorials/transistor-mirrored.png"] {
- /* @load-async */
- background-image: uiResource("res/ui/building_tutorials/transistor.png") !important;
-}
-
-// Filter and lever share tutorials
-[data-icon="building_tutorials/filter.png"],
-[data-icon="building_tutorials/lever.png"] {
- /* @load-async */
- background-image: uiResource("res/ui/building_tutorials/lever.png") !important;
-}
-
-// Logic gate
-[data-icon="building_tutorials/logic_gate.png"] {
- /* @load-async */
- background-image: uiResource("res/ui/building_tutorials/logic_gate-and.png") !important;
-}
-
-// Virtual processor
-[data-icon="building_tutorials/virtual_processor.png"] {
- /* @load-async */
- background-image: uiResource("res/ui/building_tutorials/virtual_processor-cutter.png") !important;
-}
-
-$icons: notification_saved, notification_success, notification_upgrade, notification_info,
- notification_warning, notification_error;
-@each $icon in $icons {
- [data-icon="icons/#{$icon}.png"] {
- /* @load-async */
- background-image: uiResource("res/ui/icons/#{$icon}.png") !important;
- }
-}
-
-$languages: en, de, cs, da, et, es-419, fr, it, pt-BR, sv, tr, el, ru, uk, zh-TW, zh-CN, nb, mt-MT, ar, nl, vi,
- th, hu, pl, ja, kor, no, pt-PT, fi, ro, he;
-
-@each $language in $languages {
- [data-languageicon="#{$language}"] {
- background-image: uiResource("languages/#{$language}.svg") !important;
- }
-}
-
-.steam_dlbtn_0 {
- background-image: uiResource("steam_link_btn/0.png") !important;
-}
+$buildings: belt, cutter, miner, mixer, painter, rotator, balancer, stacker, trash, underground_belt, wire,
+ constant_signal, logic_gate, lever, filter, wire_tunnel, display, virtual_processor, reader, storage,
+ transistor, analyzer, comparator, item_producer, constant_producer, goal_acceptor, block;
+
+@each $building in $buildings {
+ [data-icon="building_icons/#{$building}.png"] {
+ /* @load-async */
+ .icon {
+ background-image: uiResource("res/ui/building_icons/#{$building}.png") !important;
+ }
+ }
+}
+
+$buildingsAndVariants: belt, balancer, underground_belt, underground_belt-tier2, miner, miner-chainable,
+ cutter, cutter-quad, rotator, rotator-ccw, stacker, mixer, painter-double, painter-quad, trash, storage,
+ reader, rotator-rotate180, display, constant_signal, wire, wire_tunnel, logic_gate-or, logic_gate-not,
+ logic_gate-xor, analyzer, virtual_processor-rotator, virtual_processor-unstacker, item_producer,
+ constant_producer, virtual_processor-stacker, virtual_processor-painter, wire-second, painter,
+ painter-mirrored, comparator, goal_acceptor, block;
+@each $building in $buildingsAndVariants {
+ [data-icon="building_tutorials/#{$building}.png"] {
+ /* @load-async */
+ background-image: uiResource("res/ui/building_tutorials/#{$building}.png") !important;
+ }
+}
+
+[data-icon="building_tutorials/balancer-merger.png"],
+[data-icon="building_tutorials/balancer-merger-inverse.png"] {
+ /* @load-async */
+ background-image: uiResource("res/ui/building_tutorials/balancer-merger.png") !important;
+}
+
+[data-icon="building_tutorials/balancer-splitter.png"],
+[data-icon="building_tutorials/balancer-splitter-inverse.png"] {
+ /* @load-async */
+ background-image: uiResource("res/ui/building_tutorials/balancer-splitter.png") !important;
+}
+
+[data-icon="building_tutorials/transistor.png"],
+[data-icon="building_tutorials/transistor-mirrored.png"] {
+ /* @load-async */
+ background-image: uiResource("res/ui/building_tutorials/transistor.png") !important;
+}
+
+// Filter and lever share tutorials
+[data-icon="building_tutorials/filter.png"],
+[data-icon="building_tutorials/lever.png"] {
+ /* @load-async */
+ background-image: uiResource("res/ui/building_tutorials/lever.png") !important;
+}
+
+// Logic gate
+[data-icon="building_tutorials/logic_gate.png"] {
+ /* @load-async */
+ background-image: uiResource("res/ui/building_tutorials/logic_gate-and.png") !important;
+}
+
+// Virtual processor
+[data-icon="building_tutorials/virtual_processor.png"] {
+ /* @load-async */
+ background-image: uiResource("res/ui/building_tutorials/virtual_processor-cutter.png") !important;
+}
+
+$icons: notification_saved, notification_success, notification_upgrade, notification_info,
+ notification_warning, notification_error;
+@each $icon in $icons {
+ [data-icon="icons/#{$icon}.png"] {
+ /* @load-async */
+ background-image: uiResource("res/ui/icons/#{$icon}.png") !important;
+ }
+}
+
+$languages: en, de, cs, da, et, es-419, fr, it, pt-BR, sv, tr, el, ru, uk, zh-TW, zh-CN, nb, mt-MT, ar, nl, vi,
+ th, hu, pl, ja, kor, no, pt-PT, fi, ro, he;
+
+@each $language in $languages {
+ [data-languageicon="#{$language}"] {
+ background-image: uiResource("languages/#{$language}.svg") !important;
+ }
+}
diff --git a/src/css/states/about.scss b/src/css/states/about.scss
index 02025e03..5d1e2151 100644
--- a/src/css/states/about.scss
+++ b/src/css/states/about.scss
@@ -1,26 +1,26 @@
#state_AboutState {
> .container .content {
- @include S(max-width, 600px);
+ max-width: 60rem;
@include PlainText;
padding: 0;
background: transparent;
}
.head {
- @include S(padding, 20px);
+ padding: 2rem;
img {
display: block;
margin: 0 auto;
- @include S(max-width, 200px);
+ max-width: 20rem;
}
}
.text {
- @include S(margin, 10px);
+ margin: 1rem;
}
a {
- @include S(margin, 0, 3px);
+ margin: 0 0.3rem;
}
}
diff --git a/src/css/states/changelog.scss b/src/css/states/changelog.scss
index 1daa5f04..2ecceadf 100644
--- a/src/css/states/changelog.scss
+++ b/src/css/states/changelog.scss
@@ -1,6 +1,6 @@
#state_ChangelogState {
.content {
- @include S(max-width, 800px);
+ max-width: 80rem;
display: flex;
flex-direction: column;
}
@@ -19,12 +19,12 @@
.changes {
@include PlainText;
- @include S(padding-left, 20px);
+ padding-left: 2rem;
strong {
color: #aaa;
text-transform: uppercase;
- @include S(padding, 1px, 2px);
- @include S(margin-right, 3px);
+ padding: 0.1rem 0.2rem;
+ margin-right: 0.3rem;
}
}
}
diff --git a/src/css/states/ingame.scss b/src/css/states/ingame.scss
index d67ee00f..381603a8 100644
--- a/src/css/states/ingame.scss
+++ b/src/css/states/ingame.scss
@@ -1,52 +1,52 @@
-#state_InGameState {
- .gameLoadingOverlay {
- position: absolute;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- z-index: 9999;
- align-items: center;
- justify-content: center;
- pointer-events: all;
- display: flex;
- background: $mainBgColor;
- flex-direction: column;
- }
-
- .prefab_GameHint {
- position: absolute;
- @include S(bottom, 40px);
- @include S(left, 20px);
- @include S(right, 20px);
- @include PlainText;
- text-align: center;
-
- color: #666;
-
- @include DarkThemeOverride() {
- color: lighten($darkModeGameBackground, 50);
- }
- }
-
- #ingame_Canvas {
- position: absolute;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- }
- #ingame_HUD_ModalDialogs {
- position: absolute;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- }
-
- @include DarkThemeOverride {
- .gameLoadingOverlay {
- background: $darkModeGameBackground;
- }
- }
-}
+#state_InGameState {
+ .gameLoadingOverlay {
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ z-index: 9999;
+ align-items: center;
+ justify-content: center;
+ pointer-events: all;
+ display: flex;
+ background: $mainBgColor;
+ flex-direction: column;
+ }
+
+ .prefab_GameHint {
+ position: absolute;
+ bottom: 4rem;
+ left: 2rem;
+ right: 2rem;
+ @include PlainText;
+ text-align: center;
+
+ color: #666;
+
+ @include DarkThemeOverride() {
+ color: lighten($darkModeGameBackground, 50);
+ }
+ }
+
+ #ingame_Canvas {
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ }
+ #ingame_HUD_ModalDialogs {
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ }
+
+ @include DarkThemeOverride {
+ .gameLoadingOverlay {
+ background: $darkModeGameBackground;
+ }
+ }
+}
diff --git a/src/css/states/keybindings.scss b/src/css/states/keybindings.scss
index 991d2af4..4111bf80 100644
--- a/src/css/states/keybindings.scss
+++ b/src/css/states/keybindings.scss
@@ -1,72 +1,71 @@
-#state_KeybindingsState {
- .content {
- .topEntries {
- display: grid;
- grid-template-columns: 1fr auto;
- @include S(grid-gap, 5px);
- @include S(margin-bottom, 10px);
- }
-
- .hint {
- display: block;
- background: #eee;
- @include S(padding, 6px, 10px);
- @include PlainText;
- @include S(border-radius, $globalBorderRadius);
- }
-
- .category {
- .entry {
- display: grid;
- @include S(margin-top, 2px);
- @include S(padding-top, 2px);
- @include S(grid-gap, 4px);
- grid-template-columns: 1fr #{D(100px)} auto auto;
- border-bottom: #{D(1px)} dotted #eee;
- color: #888c8f;
- .mapping {
- color: $colorBlueBright;
- text-align: center;
- }
-
- button {
- @include S(height, 15px);
- @include S(width, 15px);
- @include IncreasedClickArea(0px);
- background: transparent center center / 40% no-repeat;
- opacity: 0.9;
- &.editKeybinding {
- background-image: uiResource("icons/edit_key.png");
- }
-
- &.resetKeybinding {
- background-image: uiResource("icons/reset_key.png");
- }
-
- &.disabled {
- pointer-events: none;
- cursor: default;
- opacity: 0.1 !important;
- }
- }
- }
- }
- }
-
- @include DarkThemeOverride {
- .content {
- .hint {
- background: darken($darkModeControlsBackground, 4);
- }
-
- .category .entry {
- color: #c0c4c8;
- border-bottom-color: #888;
-
- button {
- filter: invert(1);
- }
- }
- }
- }
-}
+#state_KeybindingsState {
+ .content {
+ .topEntries {
+ display: grid;
+ grid-template-columns: 1fr auto;
+ grid-gap: 0.5rem;
+ margin-bottom: 1rem;
+ }
+
+ .hint {
+ display: block;
+ background: #eee;
+ padding: 0.6rem 1rem;
+ @include PlainText;
+ border-radius: $globalBorderRadius;
+ }
+
+ .category {
+ .entry {
+ display: grid;
+ margin-top: 0.2rem;
+ padding-top: 0.2rem;
+ grid-gap: 0.4rem;
+ grid-template-columns: 1fr 10rem auto auto;
+ border-bottom: 0.1rem dotted #eee;
+ color: #888c8f;
+ .mapping {
+ color: $colorBlueBright;
+ text-align: center;
+ }
+
+ button {
+ height: 1.5rem;
+ width: 1.5rem;
+ background: transparent center center / 40% no-repeat;
+ opacity: 0.9;
+ &.editKeybinding {
+ background-image: uiResource("icons/edit_key.png");
+ }
+
+ &.resetKeybinding {
+ background-image: uiResource("icons/reset_key.png");
+ }
+
+ &.disabled {
+ pointer-events: none;
+ cursor: default;
+ opacity: 0.1 !important;
+ }
+ }
+ }
+ }
+ }
+
+ @include DarkThemeOverride {
+ .content {
+ .hint {
+ background: darken($darkModeControlsBackground, 4);
+ }
+
+ .category .entry {
+ color: #c0c4c8;
+ border-bottom-color: #888;
+
+ button {
+ filter: invert(1);
+ }
+ }
+ }
+ }
+}
diff --git a/src/css/states/main_menu.scss b/src/css/states/main_menu.scss
index 6d2f432e..e48549a4 100644
--- a/src/css/states/main_menu.scss
+++ b/src/css/states/main_menu.scss
@@ -1,1277 +1,717 @@
-#state_MainMenuState {
- display: grid;
- align-items: center;
- justify-content: center;
- grid-template-rows: D(95px) 1fr D(100px);
- grid-template-columns: 1fr;
-
- // background: #aaacb4 center center / cover !important;
- background: #bbc2cf center center / cover !important;
-
- .topButtons {
- position: absolute;
- @include S(top, 25px);
- @include S(right, 25px);
- display: flex;
- flex-direction: row;
- z-index: 20;
- @include S(gap, 9px);
-
- .settingsButton,
- .exitAppButton,
- .languageChoose {
- @include S(width, 35px);
- @include S(height, 35px);
- pointer-events: all;
- border-radius: 50%;
- box-shadow: 0 D(2px) D(3px) rgba(#000, 0.1);
- background: rgba(#fff, 1) uiResource("icons/main_menu_settings.png") center center / 70% no-repeat;
-
- cursor: pointer;
- transition: opacity 0.12s ease-in-out;
- @include IncreasedClickArea(2px);
- opacity: 0.85;
- &:hover {
- opacity: 1;
- }
- }
-
- .exitAppButton {
- background-image: uiResource("icons/main_menu_exit.png");
- background-size: 56%;
- }
-
- .languageChoose {
- background: rgba(#fff, 1) center center / contain no-repeat;
- border-radius: 50%;
- background-color: #222428 !important;
- background-size: contain !important;
- background-position: center center !important;
- opacity: 0.8;
- transform: scale(0.98);
- }
- }
-
- &::after {
- position: absolute;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- background: uiResource("vignette-strong.lossless.png") center center / cover no-repeat;
- pointer-events: none;
- z-index: 2;
- content: "";
- }
-
- .fullscreenBackgroundVideo {
- // display: none !important;
- z-index: 1;
- position: fixed;
- right: 50%;
- bottom: 50%;
- min-width: 100%;
- min-height: 100%;
-
- opacity: 0;
- display: none;
- transform: translate(50%, 50%);
- filter: blur(D(10px));
-
- $opacity: 0.4;
- &.loaded {
- display: block;
- opacity: $opacity;
-
- @include InlineAnimation(0.1s ease-in-out) {
- 0% {
- opacity: 0;
- }
- 100% {
- opacity: $opacity;
- }
- }
- }
- }
-
- .mainWrapper {
- @include S(margin-top, 15px);
- align-items: start;
- justify-items: center;
- align-self: center;
- justify-self: center;
- @include S(grid-column-gap, 20px);
- display: grid;
-
- position: relative;
- z-index: 10;
- grid-template-rows: 1fr;
-
- &[data-columns="1"] {
- grid-template-columns: 1fr;
- }
- &[data-columns="2"] {
- grid-template-columns: D(290px) 1fr;
- }
- }
-
- .logo {
- display: flex;
- flex-grow: 1;
- align-items: center;
- justify-content: center;
- z-index: 20;
-
- flex-direction: column;
- @include S(padding-top, 0px);
-
- img {
- @include S(width, 710px / 3);
- @include S(height, 180px / 3);
- }
- position: relative;
- @include S(left, -8px);
-
- .updateLabel {
- position: absolute;
- transform: translateX(50%) rotate(-5deg);
- color: #fff;
- @include PlainText;
- font-weight: bold;
- @include S(right, 40px);
- @include S(bottom, 20px);
- background: $modsColor;
- @include S(border-radius, $globalBorderRadius);
- @include S(padding, 0, 5px, 1px, 5px);
-
- @include InlineAnimation(1.3s ease-in-out infinite) {
- 50% {
- transform: translateX(50%) rotate(-7deg) scale(1.1);
- }
- }
- }
- }
-
- .betaWarning {
- @include S(width, 400px);
- @include PlainText;
- background: $colorRedBright;
- @include S(padding, 10px);
- @include S(border-radius, $globalBorderRadius);
- color: #fff;
- @include S(margin-top, 10px);
- border: #{D(2px)} solid rgba(0, 10, 20, 0.1);
- }
-
- .sideContainer {
- display: flex;
- width: 100%;
- grid-column: 2 / 3;
- flex-direction: column;
- @include S(grid-gap, 20px);
-
- .mainNews {
- background: linear-gradient(220deg, rgb(74, 93, 201), rgb(93, 255, 150));
- &::before {
- background: uiResource("shapez2.png") center center / 100% no-repeat;
- content: "";
- @include S(width, 100px);
- @include S(height, 100px);
- position: absolute;
- top: 55%;
- right: 8%;
- pointer-events: none;
- transform: translateY(-50%);
- transition: transform 0.5s ease-in-out;
- }
-
- // .close {
- // position: absolute;
- // pointer-events: all;
- // background: uiResource("icons/main_menu_exit.png") center center / 50% no-repeat;
- // display: inline-flex;
- // @include S(width, 15px);
- // @include S(height, 15px);
- // @include S(top, 2px);
- // opacity: 0.3;
- // @include S(right, 2px);
- // z-index: 200;
- // transition: opacity 0.12s ease-in-out;
- // &:hover {
- // opacity: 0.7;
- // }
- // }
-
- &:hover::before {
- transform: translate(0, -51%);
- }
-
- box-shadow: 0 D(9px) D(15px) rgba(#000, 0.2);
- width: 100%;
- display: flex;
- flex-direction: column;
- @include S(height, 60px);
-
- pointer-events: all;
- flex-grow: 1;
- z-index: 100;
- position: relative;
- grid-row: 2 / 3;
- @include S(border-radius, $globalBorderRadius);
- justify-content: center;
- @include S(padding, 10px);
- @include S(padding-right, 100px);
- box-sizing: border-box;
- transition: opacity 0.12s ease-in-out;
- cursor: pointer;
- &:hover {
- opacity: 0.85;
- }
-
- .text {
- @include SuperSmallText;
- @include S(width, 100px);
- color: rgba(#000, 1);
- }
- }
-
- .standaloneBanner {
- background: transparent;
- @include S(border-radius, $globalBorderRadius);
- @include S(min-width, 320px);
- @include S(max-width, 370px);
- width: 100%;
- box-sizing: border-box;
- grid-row: 1 / 3;
-
- display: flex;
- flex-direction: column;
- margin: 0;
-
- strong {
- font-weight: 700 !important;
- }
-
- .onlinePlayerCount {
- color: #333;
- display: none;
- @include S(margin-top, 15px);
- @include SuperSmallText;
- @include S(height, 15px);
- text-align: center;
- }
-
- h3 {
- @include Heading;
- font-weight: bold;
- @include S(margin-bottom, 20px);
- text-align: center;
- color: #222;
- text-shadow: 0 D(1px) D(5px) rgba(#fff, 0.7);
- }
-
- p {
- @include Text;
- color: #333;
- }
-
- ul {
- @include S(margin-top, 5px);
- @include S(padding-left, 20px);
- li {
- @include Text;
- color: #fff;
- }
- }
-
- .playtimeDisclaimer {
- color: #333;
- @include S(margin-top, 15px);
- @include SuperSmallText;
- text-align: center;
- }
-
- .steamLink {
- align-self: center;
- justify-self: center;
- width: 100%;
- @include S(height, 40px * 1.2);
- @include S(width, 180px * 1.2);
- background: #171a23 center center / contain no-repeat;
- // overflow: hidden;
- display: block;
- cursor: pointer;
- @include S(margin-top, 15px);
- pointer-events: all;
- transition: all 0.12s ease-in;
- transition-property: opacity, transform;
- position: relative;
- @include S(border-radius, $globalBorderRadius);
- color: transparent;
-
- box-shadow: 0 D(3px) D(7px) rgba(#000, 0.3);
- &:hover {
- opacity: 0.9;
- }
-
- @include InlineAnimation(1s ease-in-out infinite) {
- 50% {
- transform: scale(1.02, 1.03);
- }
- }
-
- > .discount {
- position: absolute;
- @include S(top, -7px);
- @include S(right, -5px);
- background: #4c6b22;
- color: #c5ea3f;
- @include S(border-radius, $globalBorderRadius);
- @include S(padding, 1px, 3px, 1px, 4px);
- @include PlainText;
- text-transform: uppercase;
- transform: rotate(5deg);
- }
- }
- .specialOffer {
- color: #000000;
- @include PlainText;
- align-self: center;
- text-align: center;
- @include S(margin-top, 5px);
- @include InlineAnimation(1s ease-in-out infinite) {
- 50% {
- transform: scale(1.02, 1.03) translateY(2%);
- }
- }
- }
-
- .points {
- display: grid;
- grid-template-columns: 1fr 1fr;
- width: 100%;
- @include S(grid-gap, 5px);
- }
-
- .point {
- display: grid;
- grid-template-columns: #{D(27px)} auto;
- grid-template-rows: 1fr 1fr;
- background: #fff #{D(10px)} center / #{D(17px)} no-repeat;
- @include S(grid-row-gap, 2px);
- align-items: center;
- @include S(padding, 6px);
- @include S(border-radius, $globalBorderRadius);
- @include S(height, 26px);
- box-shadow: 0 D(5px) D(10px) rgba(#000, 0.2);
-
- > strong {
- grid-column: 2 / 3;
- grid-row: 1 / 2;
- @include PlainText;
- @include S(font-size, 12px);
- line-height: 0.8em;
- white-space: nowrap;
- text-transform: uppercase;
- font-weight: bold;
- align-self: end;
- }
-
- > p {
- grid-column: 2 / 3;
- grid-row: 2 / 3;
- @include SuperSmallText;
- @include S(font-size, 8px);
- line-height: 1em;
- align-self: center;
-
- opacity: 0.8;
- }
-
- &.levels {
- background-image: uiResource("res/ui/icons/advantage_new_levels.png");
- > strong {
- color: #f13555;
- }
- }
-
- &.upgrades {
- background-image: uiResource("res/ui/icons/advantage_upgrades.png");
- > strong {
- color: #8a00ff;
- }
- }
-
- &.buildings {
- background-image: uiResource("res/ui/icons/advantage_buildings.png");
- > strong {
- color: #3fce8b;
- }
- }
-
- &.wires {
- background-image: uiResource("res/ui/icons/advantage_wires.png");
- > strong {
- color: #ef2fdb;
- }
- }
-
- &.markers {
- background-image: uiResource("res/ui/icons/advantage_markers.png");
- > strong {
- color: #4294ff;
- }
- }
-
- &.mods {
- background-image: uiResource("res/ui/icons/advantage_mods.png");
- > strong {
- color: #8a00ff;
- }
- }
-
- &.savegames {
- background-image: uiResource("res/ui/icons/advantage_savegames.png");
- > strong {
- color: #ff9500;
- }
- }
-
- &.darkmode {
- background-image: uiResource("res/ui/icons/advantage_dark_mode.png");
- > strong {
- color: #292c32;
- }
- }
-
- &.support {
- background-image: uiResource("res/ui/icons/advantage_support.png");
- > strong {
- color: #e72d2d;
- }
- }
-
- &.achievements {
- background-image: uiResource("res/ui/icons/advantage_achievements.png");
- > strong {
- color: #ffac0f;
- }
- }
- }
- }
-
- .puzzleContainer {
- display: flex;
- align-items: center;
- justify-content: center;
- flex-direction: column;
- background: $colorBlueBright;
- grid-row: 1 / 2;
- width: 100%;
- box-sizing: border-box;
- position: relative;
- @include S(border-radius, $globalBorderRadius);
- box-shadow: 0 D(5px) D(10px) rgba(#000, 0.4);
- border: D(1px) solid rgba(#000, 0.1);
- overflow: hidden;
-
- > .badge {
- color: #fff;
- text-transform: uppercase;
- font-weight: bold;
- position: absolute;
- @include S(top, 10px);
- @include S(right, 10px);
-
- transform: translateX(50%) rotate(10deg);
- @include Heading;
- font-weight: bold;
-
- @include InlineAnimation(1.3s ease-in-out infinite) {
- 50% {
- transform: translateX(50%) rotate(12deg) scale(1.1);
- }
- }
- }
-
- > .hint {
- @include SuperDuperSmallText;
- @include S(margin-top, 10px);
- @include S(width, 200px);
- }
-
- > .dlcLogo {
- @include S(width, 120px);
- }
-
- > button {
- @include S(margin-top, 20px);
- @include Heading;
- @include S(padding, 10px, 30px);
- background-color: #333;
- color: #fff;
- }
-
- &.owned {
- @include S(height, 118px);
- @include S(width, 250px);
- background: uiResource("puzzle_460x215_15.png") center D(-5px) / cover repeat;
- .dlcLogo {
- display: none;
- }
-
- > button {
- pointer-events: all;
- @include S(padding, 4px, 10px);
- margin: 0;
- background: #47c599;
- box-sizing: border-box;
- position: absolute;
- @include S(top, 10px);
- @include S(right, 10px);
- z-index: 100;
- @include PlainText;
- z-index: 200;
- color: #111215;
- box-shadow: 0 D(2px) D(9px) rgba(#000, 0.4);
- }
- }
-
- &.notOwned {
- @include S(height, 200px);
- @include S(width, 250px);
- border: 0;
- background: uiResource("puzzle_460x215_15.png") center D(-5px) / 100% repeat;
- .dlcLogo {
- display: none;
- }
- &::before {
- content: "";
- position: absolute;
- top: 0;
- right: 0;
- bottom: 0;
- left: 0;
- background: linear-gradient(180deg, rgba(#222529, 0.1) 40%, rgba(#222529, 1) 70%);
- }
-
- p {
- position: absolute;
- left: 0;
- right: 0;
- @include S(bottom, 35px);
- z-index: 50;
- box-sizing: border-box;
- display: block;
- @include PlainText;
- color: rgba(#fff, 0.9);
- @include S(padding, 10px);
- @include SuperSmallText;
- }
- > button {
- pointer-events: all;
- @include S(padding, 4px, 10px);
- margin: 0;
- background: #47c599;
- box-sizing: border-box;
- position: absolute;
- @include S(bottom, 10px);
- @include S(right, 10px);
- z-index: 100;
- @include PlainText;
- z-index: 200;
- color: #111215;
- box-shadow: 0 D(2px) D(4px) rgba(#000, 1);
- }
- }
- }
-
- .modsOverview {
- display: flex;
- align-items: center;
- justify-content: center;
- flex-direction: column;
- background: #fff;
- grid-row: 1 / 2;
- position: relative;
- text-align: left;
- align-items: flex-start;
- @include S(width, 250px);
- @include S(padding, 15px);
- @include S(padding-bottom, 10px);
- @include S(border-radius, $globalBorderRadius);
- box-shadow: 0 D(5px) D(15px) rgba(#000, 0.2);
-
- .header {
- display: flex;
- width: 100%;
- align-items: center;
- text-transform: uppercase;
-
- @include S(margin-bottom, 10px);
-
- .editMods {
- margin-left: auto;
- @include S(width, 20px);
- @include S(height, 20px);
- padding: 0;
- opacity: 0.5;
- background: transparent center center/ 80% no-repeat;
- & {
- background-image: uiResource("icons/edit_key.png") !important;
- }
- @include DarkThemeInvert;
- &:hover {
- opacity: 0.6;
- }
- }
- }
-
- h3 {
- @include Heading;
- color: $modsColor;
- margin: 0;
- }
-
- .dlcHint {
- @include SuperSmallText;
- @include S(margin-top, 10px);
- width: 100%;
-
- display: grid;
- grid-template-columns: 1fr auto;
- grid-gap: 20px;
- align-items: center;
- }
-
- .mod {
- background: #eee;
- width: 100%;
- @include S(border-radius, $globalBorderRadius);
- @include S(padding, 5px);
- box-sizing: border-box;
- @include PlainText;
- @include S(margin-bottom, 5px);
- display: flex;
- flex-direction: column;
-
- .author,
- .version {
- @include SuperSmallText;
- align-self: end;
- opacity: 0.4;
- }
- .name {
- overflow: hidden;
- }
- }
-
- .modsList {
- box-sizing: border-box;
- @include S(height, 100px);
- @include S(padding, 5px);
- border: D(1px) solid #eee;
- overflow-y: scroll;
- width: 100%;
- display: flex;
- flex-direction: column;
- @include S(border-radius, $globalBorderRadius);
- pointer-events: all;
-
- :last-child {
- margin-bottom: auto;
- }
- }
- }
- }
-
- .mainContainer {
- display: flex;
- align-items: center;
- justify-content: center;
- flex-direction: column;
- background: rgba(#fff, 0.9);
- @include S(border-radius, $globalBorderRadius);
- height: 100%;
- box-shadow: 0 D(9px) D(15px) rgba(#000, 0.2);
- width: 100%;
- position: relative;
- align-self: center;
- justify-self: center;
- grid-column: 1 / 2;
- @include S(max-width, 400px);
- overflow: hidden;
- box-sizing: border-box;
-
- &[data-savegames="0"] .buttons .outer {
- grid-template-rows: 1fr 1fr;
- }
-
- .buttons {
- display: grid;
- grid-template-columns: auto auto;
- grid-template-rows: 1fr;
- // flex-direction: column;
- // align-items: center;
- width: 100%;
- background: rgba(0, 20, 40, 0.05);
-
- @include S(padding, 10px);
- @include S(grid-gap, 10px);
- max-width: 100%;
- box-sizing: border-box;
-
- .playButton,
- .continueButton {
- @include SuperHeading;
- width: 100%;
- @include S(padding, 15px, 10px);
- letter-spacing: 0.1em !important;
- @include IncreasedClickArea(0px);
- box-sizing: border-box;
- font-weight: bold;
- color: #fff;
- background-color: $colorGreenBright;
- transition: transform 0.12s ease-in-out, background-color 0.12s ease-in-out;
-
- grid-column: 1 / 2;
- min-width: auto;
- grid-row: 1 / 1;
-
- &:hover {
- background-color: darken($colorGreenBright, 4);
- opacity: 1;
- }
-
- &.continueButton {
- @include Heading;
- }
- }
-
- .outer {
- display: grid;
- grid-template-columns: 1fr;
- grid-template-rows: 1fr 1fr 1fr;
- height: 100%;
-
- grid-column: 2 / 3;
- grid-row: 1 / 1;
- min-width: auto;
-
- @include S(grid-gap, 5px);
- width: 100%;
-
- > button {
- @include S(padding, 3px, 6px);
- width: 100%;
- white-space: nowrap;
- margin: 0 !important;
- box-sizing: border-box;
- }
-
- .importButton {
- @include IncreasedClickArea(0px);
- }
-
- .newGameButton {
- @include IncreasedClickArea(0px);
- }
-
- .modsButton {
- @include IncreasedClickArea(0px);
- background-color: $modsColor !important;
- }
- }
- }
-
- .modeButtons {
- display: grid;
- grid-template-columns: repeat(2, 1fr);
- @include S(grid-column-gap, 10px);
- align-items: start;
- height: 100%;
- width: 100%;
- }
-
- .steamSso {
- cursor: default;
- pointer-events: all;
- display: inline-flex;
- @include S(padding, 10px);
- color: #000;
- flex-direction: column;
- line-height: 1em;
- @include S(gap, 3px);
- position: relative;
- background: rgba(0, 20, 40, 0.05);
- width: 100%;
- box-sizing: border-box;
- margin-top: auto;
- display: grid;
- grid-template-columns: 1fr auto;
- align-items: center;
-
- .description {
- @include SuperSmallText;
- color: rgba(0, 10, 20, 0.5);
- @include DarkThemeOverride {
- color: rgba(#fff, 0.7);
- }
- }
- // &:hover {
- // .tooltip {
- // opacity: 1;
- // }
- // }
-
- a.ssoSignIn {
- background: #171a23 uiResource("steam_signin.png") center center / contain no-repeat;
- width: 100%;
- box-sizing: border-box;
-
- @include S(height, 19px);
- @include S(width, 110px);
-
- display: inline-flex;
- @include S(border-radius, $globalBorderRadius * 0.5);
- transition: opacity 0.12s ease-in-out;
- overflow: hidden;
- text-indent: -999em;
- &:hover {
- opacity: 0.9;
- }
-
- box-shadow: 0 D(1.5px) D(4px) rgba(#000, 0.21);
- }
-
- a.ssoSignOut {
- width: 100%;
- background: $colorRedBright;
- color: #fff !important;
- display: flex;
- align-items: center;
- box-sizing: border-box;
- justify-content: center;
- @include SuperSmallText;
- text-transform: uppercase;
-
- @include S(border-radius, $globalBorderRadius * 0.5);
-
- box-shadow: 0 D(1.5px) D(4px) rgba(#000, 0.21);
- @include S(padding, 2px, 9px);
- &:hover {
- opacity: 0.95;
- }
- }
- }
-
- .savegamesMount {
- width: 100%;
- display: flex;
- flex-grow: 1;
- flex-direction: column;
- @include S(padding, 10px);
- box-sizing: border-box;
- @include S(min-height, 150px);
-
- .savegamesNone {
- align-items: center;
- justify-content: center;
- display: flex;
- @include PlainText;
- flex-grow: 1;
- text-align: center;
- @include S(padding, 0, 20px);
- opacity: 0.5;
-
- @include DarkThemeOverride {
- color: #fff;
- }
- }
-
- .savegames {
- overflow-y: auto;
- width: 100%;
- pointer-events: all;
- @include S(padding-right, 5px);
- margin-right: D(-5px);
- @include S(max-height, 150px);
- display: grid;
- grid-auto-flow: row;
- @include S(grid-gap, 5px);
-
- .savegame {
- background: #eee;
- @include S(border-radius, $globalBorderRadius);
- @include S(padding, 5px);
- display: grid;
- grid-template-columns: 1fr 1fr auto auto;
- grid-template-rows: auto auto;
- @include S(grid-column-gap, 4px);
- @include S(grid-row-gap, 1px);
-
- .playtime {
- grid-column: 2 / 3;
- grid-row: 2 / 3;
- @include SuperSmallText;
- opacity: 0.5;
- }
-
- .level {
- grid-column: 1 / 2;
- grid-row: 2 / 3;
- @include SuperSmallText;
- opacity: 0.5;
- }
-
- .name {
- grid-column: 1 / 3;
- grid-row: 1 / 2;
- @include PlainText;
- display: inline-flex;
- align-items: center;
-
- > span {
- display: inline-flex;
- @include S(max-width, 140px);
- overflow: hidden;
- }
- }
-
- button.resumeGame,
- button.downloadGame,
- button.deleteGame,
- button.renameGame {
- padding: 0;
- align-self: center;
- justify-self: center;
- @include IncreasedClickArea(0px);
- background: #44484a center center / 40% no-repeat;
- }
-
- button.resumeGame {
- background-color: #44484a;
- & {
- background-image: uiResource("icons/play.png");
- }
- }
-
- button.downloadGame {
- grid-column: 3 / 4;
- grid-row: 1 / 2;
- background-color: transparent;
-
- & {
- background-image: uiResource("icons/download.png");
- }
- @include S(width, 15px);
- @include IncreasedClickArea(0px);
- @include S(height, 15px);
- background-size: 80%;
- align-self: start;
- border-radius: 0;
- opacity: 0.4;
-
- &:hover {
- opacity: 0.5;
- }
-
- @include DarkThemeInvert;
- }
-
- button.deleteGame {
- grid-column: 3 / 4;
- grid-row: 2 / 3;
- background-color: transparent;
- @include IncreasedClickArea(0px);
-
- & {
- background-image: uiResource("icons/delete.png");
- }
- @include S(width, 15px);
- @include S(height, 15px);
- align-self: end;
- background-size: 80%;
- border-radius: 0;
- opacity: 0.4;
-
- &:hover {
- opacity: 0.5;
- }
-
- @include DarkThemeInvert;
- }
-
- button.renameGame {
- background-color: transparent;
- @include IncreasedClickArea(2px);
-
- & {
- background-image: uiResource("icons/edit_key.png");
- }
- @include S(width, 10px);
- @include S(height, 10px);
- align-self: center;
- justify-self: center;
- border-radius: 0;
- background-size: 90%;
- opacity: 0.4;
- @include S(margin-left, 4px);
-
- &:hover {
- opacity: 0.5;
- }
-
- @include DarkThemeInvert;
- }
-
- button.resumeGame {
- grid-column: 4 / 5;
- grid-row: 1 / 3;
- margin: 0;
- @include S(width, 32px);
- height: 100%;
- @include S(margin-left, 4px);
-
- @include DarkThemeOverride {
- background-color: lighten($darkModeControlsBackground, 10);
- }
- }
- }
- }
- }
- }
-
- .bottomContainer {
- display: flex;
- align-items: center;
- justify-content: center;
- flex-direction: row;
- @include S(padding-top, 10px);
- height: 100%;
- width: 100%;
- box-sizing: border-box;
-
- .buttons {
- display: grid;
- grid-template-columns: repeat(2, 1fr);
- @include S(grid-column-gap, 10px);
- align-items: start;
- height: 100%;
- width: 100%;
- box-sizing: border-box;
- }
- }
-
- .socialLinks {
- position: fixed;
- z-index: 100;
- display: flex;
- flex-direction: row;
- @include S(gap, 9px);
- @include S(top, 25px);
- @include S(left, 25px);
-
- @media (max-aspect-ratio: 1460/1000) {
- position: unset;
- top: unset;
- left: unset;
- .label {
- display: none;
- }
- }
-
- > .boxLink {
- pointer-events: all;
- display: flex;
- flex-direction: column;
- align-items: center;
- position: relative;
- cursor: pointer;
- @include S(gap, 3px);
- @include S(width, 35px);
-
- .label {
- @include SuperSmallText;
- font-weight: bold;
- box-sizing: border-box;
- text-transform: uppercase;
- opacity: 0;
- transition: opacity 0.12s ease-in-out;
- }
-
- &:hover {
- .label {
- opacity: 1;
- .thirdpartyLogo {
- background-color: #fff;
- }
- }
- }
-
- .thirdpartyLogo {
- display: inline-flex;
- @include S(width, 35px);
- @include S(height, 35px);
- background: rgba(#fff, 0.9) center center / contain no-repeat;
- border-radius: 50%;
- box-shadow: 0 D(2px) D(3px) rgba(#000, 0.1);
-
- transition: background-color 0.12s ease-in-out;
-
- &.githubLogo {
- background-image: uiResource("main_menu/github.png");
- background-size: 66%;
- background-position: 54% 50%;
- }
-
- &.discordLogo {
- background-image: uiResource("main_menu/discord.svg");
- background-size: 66%;
- background-position: 50% 53%;
- }
-
- &.redditLogo {
- background-image: uiResource("main_menu/reddit.svg");
- background-size: 65%;
- }
- &.twitterLogo {
- background-image: uiResource("main_menu/twitter.svg");
- background-size: 60%;
- background-position: 60% 58%;
- }
-
- &.patreonLogo {
- background-image: uiResource("main_menu/patreon.svg");
- background-size: 60%;
- background-position: 60% 60%;
- }
-
- &.steamLogo {
- background-image: uiResource("main_menu/steam.svg");
- background-size: 105%;
- }
- }
- }
- }
-
- .footer {
- display: flex;
- justify-content: center;
- align-self: end;
- align-items: center;
- position: relative;
- z-index: 20;
- width: 100%;
- box-sizing: border-box;
- @include S(gap, 30px);
- @include S(padding, 15px, 25px, 15px, 20px);
-
- &.wegameDisclaimer {
- @include SuperSmallText;
- display: grid;
- justify-content: center;
- text-align: center;
-
- > .disclaimer {
- grid-column: 2 / 3;
-
- @include DarkThemeOverride {
- color: #fff;
- }
- }
-
- > .rating {
- grid-column: 3 / 4;
- justify-self: end;
- align-self: end;
-
- @include S(width, 32px);
- @include S(height, 40px);
- background: green;
- cursor: pointer !important;
- pointer-events: all;
- @include S(border-radius, 4px);
- overflow: hidden;
-
- & {
- background: #fff uiResource("wegame_isbn_rating.jpg") center center / contain no-repeat;
- }
- }
- }
-
- .author {
- margin-left: auto;
- display: flex;
- @include S(width, 110px);
- justify-content: flex-end;
-
- a {
- &:hover img {
- opacity: 0.85;
- }
- position: relative;
- display: flex;
- align-items: center;
- justify-content: center;
-
- img {
- transition: opacity 0.12s ease-in-out;
- @include S(width, 82px * 0.8);
- @include S(height, 25px * 0.8);
- filter: invert(100%);
- opacity: 0.75;
- }
- }
- }
-
- .footerGrow {
- flex-grow: 1;
- display: flex;
- align-items: center;
- justify-content: flex-start;
- @include S(gap, 15px);
- > a {
- @include SuperSmallText;
- @include S(padding, 2px);
- font-weight: bold;
- color: #000;
- opacity: 0.6;
- transition: opacity 0.12s ease-in-out;
- &:hover {
- opacity: 1;
- }
- }
- }
- }
-
- @include DarkThemeOverride {
- background: rgba($darkModeGameBackground, 0.5) center center / cover !important;
-
- .mainContainer {
- background: $darkModeControlsBackground;
-
- .savegames .savegame {
- background: darken($darkModeControlsBackground, 5);
- color: white;
- }
- }
-
- .modsOverview {
- background: $darkModeControlsBackground;
-
- .modsList {
- border-color: darken($darkModeControlsBackground, 5);
-
- .mod {
- background: darken($darkModeControlsBackground, 5);
- color: white;
- }
- }
-
- .dlcHint {
- color: $accentColorBright;
- }
- }
- }
-}
+#state_MainMenuState {
+ display: grid;
+ align-items: center;
+ justify-content: center;
+ grid-template-rows: 9.5rem 1fr 10rem;
+ grid-template-columns: 1fr;
+
+ // background: #aaacb4 center center / cover !important;
+ background: #bbc2cf center center / cover !important;
+
+ .topButtons {
+ position: absolute;
+ top: 2.5rem;
+ right: 2.5rem;
+ display: flex;
+ flex-direction: row;
+ z-index: 20;
+ gap: 0.9rem;
+
+ .settingsButton,
+ .exitAppButton,
+ .languageChoose {
+ width: 3.5rem;
+ height: 3.5rem;
+ pointer-events: all;
+ border-radius: 50%;
+ box-shadow: 0 0.2rem 0.3rem rgba(#000, 0.1);
+ background: rgba(#fff, 1) uiResource("icons/main_menu_settings.png") center center / 70% no-repeat;
+
+ cursor: pointer;
+ transition: opacity 0.12s ease-in-out;
+ opacity: 0.85;
+ &:hover {
+ opacity: 1;
+ }
+ }
+
+ .exitAppButton {
+ background-image: uiResource("icons/main_menu_exit.png");
+ background-size: 56%;
+ }
+
+ .languageChoose {
+ background: rgba(#fff, 1) center center / contain no-repeat;
+ border-radius: 50%;
+ background-color: #222428 !important;
+ background-size: contain !important;
+ background-position: center center !important;
+ opacity: 0.8;
+ transform: scale(0.98);
+ }
+ }
+
+ &::after {
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background: uiResource("vignette-strong.lossless.png") center center / cover no-repeat;
+ pointer-events: none;
+ z-index: 2;
+ content: "";
+ }
+
+ .fullscreenBackgroundVideo {
+ // display: none !important;
+ z-index: 1;
+ position: fixed;
+ right: 50%;
+ bottom: 50%;
+ min-width: 100%;
+ min-height: 100%;
+
+ opacity: 0;
+ display: none;
+ transform: translate(50%, 50%);
+ filter: blur(1rem);
+
+ $opacity: 0.4;
+ &.loaded {
+ display: block;
+ opacity: $opacity;
+
+ @include InlineAnimation(0.1s ease-in-out) {
+ 0% {
+ opacity: 0;
+ }
+ 100% {
+ opacity: $opacity;
+ }
+ }
+ }
+ }
+
+ .mainWrapper {
+ margin-top: 1.5rem;
+ align-items: start;
+ justify-items: center;
+ align-self: center;
+ justify-self: center;
+ grid-column-gap: 2rem;
+ display: grid;
+
+ position: relative;
+ z-index: 10;
+ grid-template-rows: 1fr;
+
+ &[data-columns="1"] {
+ grid-template-columns: 1fr;
+ }
+ &[data-columns="2"] {
+ grid-template-columns: 29rem 1fr;
+ }
+ }
+
+ .logo {
+ display: flex;
+ flex-grow: 1;
+ align-items: center;
+ justify-content: center;
+ z-index: 20;
+
+ flex-direction: column;
+ padding-top: 0rem;
+
+ img {
+ width: 710px / 3;
+ height: 180px / 3;
+ }
+ position: relative;
+ left: -0.8rem;
+ }
+
+ .sideContainer {
+ display: flex;
+ width: 100%;
+ grid-column: 2 / 3;
+ flex-direction: column;
+ grid-gap: 2rem;
+
+ .puzzleContainer {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ flex-direction: column;
+ background: $colorBlueBright;
+ grid-row: 1 / 2;
+ width: 100%;
+ box-sizing: border-box;
+ position: relative;
+ border-radius: $globalBorderRadius;
+ box-shadow: 0 0.5rem 1rem rgba(#000, 0.4);
+ border: 0.1rem solid rgba(#000, 0.1);
+ overflow: hidden;
+
+ > button {
+ margin-top: 2rem;
+ @include Heading;
+ padding: 1rem 3rem;
+ background-color: #333;
+ color: #fff;
+ }
+
+ &.owned {
+ height: 11.8rem;
+ width: 25rem;
+ background: uiResource("puzzle_460x215_15.png") center -0.5rem / cover repeat;
+
+ > button {
+ pointer-events: all;
+ padding: 0.4rem 1rem;
+ margin: 0;
+ background: #47c599;
+ box-sizing: border-box;
+ position: absolute;
+ top: 1rem;
+ right: 1rem;
+ z-index: 100;
+ @include PlainText;
+ z-index: 200;
+ color: #111215;
+ box-shadow: 0 0.2rem 0.9rem rgba(#000, 0.4);
+ }
+ }
+ }
+
+ .modsOverview {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ flex-direction: column;
+ background: #fff;
+ grid-row: 1 / 2;
+ position: relative;
+ text-align: left;
+ align-items: flex-start;
+ width: 25rem;
+ padding: 1.5rem;
+ padding-bottom: 1rem;
+ border-radius: $globalBorderRadius;
+ box-shadow: 0 0.5rem 1.5rem rgba(#000, 0.2);
+
+ .header {
+ display: flex;
+ width: 100%;
+ align-items: center;
+ text-transform: uppercase;
+
+ margin-bottom: 1rem;
+
+ .editMods {
+ margin-left: auto;
+ width: 2rem;
+ height: 2rem;
+ padding: 0;
+ opacity: 0.5;
+ background: transparent center center/ 80% no-repeat;
+ & {
+ background-image: uiResource("icons/edit_key.png") !important;
+ }
+ @include DarkThemeInvert;
+ &:hover {
+ opacity: 0.6;
+ }
+ }
+ }
+
+ h3 {
+ @include Heading;
+ color: $modsColor;
+ margin: 0;
+ }
+
+ .dlcHint {
+ @include SuperSmallText;
+ margin-top: 1rem;
+ width: 100%;
+
+ display: grid;
+ grid-template-columns: 1fr auto;
+ grid-gap: 20px;
+ align-items: center;
+ }
+
+ .mod {
+ background: #eee;
+ width: 100%;
+ border-radius: $globalBorderRadius;
+ padding: 0.5rem;
+ box-sizing: border-box;
+ @include PlainText;
+ margin-bottom: 0.5rem;
+ display: flex;
+ flex-direction: column;
+
+ .author,
+ .version {
+ @include SuperSmallText;
+ align-self: end;
+ opacity: 0.4;
+ }
+ .name {
+ overflow: hidden;
+ }
+ }
+
+ .modsList {
+ box-sizing: border-box;
+ height: 10rem;
+ padding: 0.5rem;
+ border: 0.1rem solid #eee;
+ overflow-y: scroll;
+ width: 100%;
+ display: flex;
+ flex-direction: column;
+ border-radius: $globalBorderRadius;
+ pointer-events: all;
+
+ :last-child {
+ margin-bottom: auto;
+ }
+ }
+ }
+ }
+
+ .mainContainer {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ flex-direction: column;
+ background: rgba(#fff, 0.9);
+ border-radius: $globalBorderRadius;
+ height: 100%;
+ box-shadow: 0 0.9rem 1.5rem rgba(#000, 0.2);
+ width: 100%;
+ position: relative;
+ align-self: center;
+ justify-self: center;
+ grid-column: 1 / 2;
+ max-width: 40rem;
+ overflow: hidden;
+ box-sizing: border-box;
+
+ &[data-savegames="0"] .buttons .outer {
+ grid-template-rows: 1fr 1fr;
+ }
+
+ .buttons {
+ display: grid;
+ grid-template-columns: auto auto;
+ grid-template-rows: 1fr;
+ // flex-direction: column;
+ // align-items: center;
+ width: 100%;
+ background: rgba(0, 20, 40, 0.05);
+
+ padding: 1rem;
+ grid-gap: 1rem;
+ max-width: 100%;
+ box-sizing: border-box;
+
+ .playButton,
+ .continueButton {
+ @include SuperHeading;
+ width: 100%;
+ padding: 1.5rem 1rem;
+ letter-spacing: 0.1em;
+ box-sizing: border-box;
+ font-weight: bold;
+ background-color: $colorGreenBright;
+ transition:
+ transform 0.12s ease-in-out,
+ background-color 0.12s ease-in-out;
+
+ grid-column: 1 / 2;
+ min-width: auto;
+ grid-row: 1 / 1;
+
+ &:hover {
+ background-color: darken($colorGreenBright, 4);
+ opacity: 1;
+ }
+
+ &.continueButton {
+ @include Heading;
+ }
+ }
+
+ .outer {
+ display: grid;
+ grid-template-columns: 1fr;
+ grid-template-rows: 1fr 1fr 1fr;
+ height: 100%;
+
+ grid-column: 2 / 3;
+ grid-row: 1 / 1;
+ min-width: auto;
+
+ grid-gap: 0.5rem;
+ width: 100%;
+
+ > button {
+ padding: 0.3rem 0.6rem;
+ width: 100%;
+ white-space: nowrap;
+ margin: 0 !important;
+ box-sizing: border-box;
+ }
+
+ .modsButton {
+ background-color: $modsColor !important;
+ }
+ }
+ }
+
+ .savegamesMount {
+ width: 100%;
+ display: flex;
+ flex-grow: 1;
+ flex-direction: column;
+ padding: 1rem;
+ box-sizing: border-box;
+ min-height: 15rem;
+
+ .savegamesNone {
+ align-items: center;
+ justify-content: center;
+ display: flex;
+ @include PlainText;
+ flex-grow: 1;
+ text-align: center;
+ padding: 0 2rem;
+ opacity: 0.5;
+
+ @include DarkThemeOverride {
+ color: #fff;
+ }
+ }
+
+ .savegames {
+ overflow-y: auto;
+ width: 100%;
+ pointer-events: all;
+ padding-right: 0.5rem;
+ margin-right: -0.5rem;
+ max-height: 15rem;
+ display: grid;
+ grid-auto-flow: row;
+ grid-gap: 0.5rem;
+
+ .savegame {
+ background: #eee;
+ border-radius: $globalBorderRadius;
+ padding: 0.5rem;
+ display: grid;
+ grid-template-columns: 1fr 1fr auto auto;
+ grid-template-rows: auto auto;
+ grid-column-gap: 0.4rem;
+ grid-row-gap: 0.1rem;
+
+ .playtime {
+ grid-column: 2 / 3;
+ grid-row: 2 / 3;
+ @include SuperSmallText;
+ opacity: 0.5;
+ }
+
+ .level {
+ grid-column: 1 / 2;
+ grid-row: 2 / 3;
+ @include SuperSmallText;
+ opacity: 0.5;
+ }
+
+ .name {
+ grid-column: 1 / 3;
+ grid-row: 1 / 2;
+ @include PlainText;
+ display: inline-flex;
+ align-items: center;
+
+ > span {
+ display: inline-flex;
+ max-width: 14rem;
+ overflow: hidden;
+ }
+ }
+
+ button.resumeGame,
+ button.downloadGame,
+ button.deleteGame,
+ button.renameGame {
+ padding: 0;
+ align-self: center;
+ justify-self: center;
+ background: #44484a center center / 40% no-repeat;
+ }
+
+ button.resumeGame {
+ background-color: #44484a;
+ & {
+ background-image: uiResource("icons/play.png");
+ }
+ }
+
+ button.downloadGame {
+ grid-column: 3 / 4;
+ grid-row: 1 / 2;
+ background-color: transparent;
+
+ & {
+ background-image: uiResource("icons/download.png");
+ }
+ width: 1.5rem;
+ height: 1.5rem;
+ background-size: 80%;
+ align-self: start;
+ border-radius: 0;
+ opacity: 0.4;
+
+ &:hover {
+ opacity: 0.5;
+ }
+
+ @include DarkThemeInvert;
+ }
+
+ button.deleteGame {
+ grid-column: 3 / 4;
+ grid-row: 2 / 3;
+ background-color: transparent;
+
+ & {
+ background-image: uiResource("icons/delete.png");
+ }
+ width: 1.5rem;
+ height: 1.5rem;
+ align-self: end;
+ background-size: 80%;
+ border-radius: 0;
+ opacity: 0.4;
+
+ &:hover {
+ opacity: 0.5;
+ }
+
+ @include DarkThemeInvert;
+ }
+
+ button.renameGame {
+ background-color: transparent;
+
+ & {
+ background-image: uiResource("icons/edit_key.png");
+ }
+ width: 1rem;
+ height: 1rem;
+ align-self: center;
+ justify-self: center;
+ border-radius: 0;
+ background-size: 90%;
+ opacity: 0.4;
+ margin-left: 0.4rem;
+
+ &:hover {
+ opacity: 0.5;
+ }
+
+ @include DarkThemeInvert;
+ }
+
+ button.resumeGame {
+ grid-column: 4 / 5;
+ grid-row: 1 / 3;
+ margin: 0;
+ width: 3.2rem;
+ height: 100%;
+ margin-left: 0.4rem;
+
+ @include DarkThemeOverride {
+ background-color: lighten($darkModeControlsBackground, 10);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ .socialLinks {
+ position: fixed;
+ z-index: 100;
+ display: flex;
+ flex-direction: row;
+ gap: 0.9rem;
+ top: 2.5rem;
+ left: 2.5rem;
+
+ @media (max-aspect-ratio: 1460/1000) {
+ position: unset;
+ top: unset;
+ left: unset;
+ .label {
+ display: none;
+ }
+ }
+
+ > .boxLink {
+ pointer-events: all;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ position: relative;
+ cursor: pointer;
+ gap: 0.3rem;
+ width: 3.5rem;
+
+ .label {
+ @include SuperSmallText;
+ font-weight: bold;
+ box-sizing: border-box;
+ text-transform: uppercase;
+ opacity: 0;
+ transition: opacity 0.12s ease-in-out;
+ }
+
+ &:hover {
+ .label {
+ opacity: 1;
+ .thirdpartyLogo {
+ background-color: #fff;
+ }
+ }
+ }
+
+ .thirdpartyLogo {
+ display: inline-flex;
+ width: 3.5rem;
+ height: 3.5rem;
+ background: rgba(#fff, 0.9) center center / contain no-repeat;
+ border-radius: 50%;
+ box-shadow: 0 0.2rem 0.3rem rgba(#000, 0.1);
+
+ transition: background-color 0.12s ease-in-out;
+
+ &.githubLogo {
+ background-image: uiResource("main_menu/github.png");
+ background-size: 66%;
+ background-position: 54% 50%;
+ }
+
+ &.discordLogo {
+ background-image: uiResource("main_menu/discord.svg");
+ background-size: 66%;
+ background-position: 50% 53%;
+ }
+
+ &.redditLogo {
+ background-image: uiResource("main_menu/reddit.svg");
+ background-size: 65%;
+ }
+
+ &.patreonLogo {
+ background-image: uiResource("main_menu/patreon.svg");
+ background-size: 60%;
+ background-position: 60% 60%;
+ }
+ }
+ }
+ }
+
+ .footer {
+ display: flex;
+ justify-content: center;
+ align-self: end;
+ align-items: center;
+ position: relative;
+ z-index: 20;
+ width: 100%;
+ box-sizing: border-box;
+ gap: 3rem;
+ padding: 1.5rem 2.5rem 1.5rem 2rem;
+
+ .author {
+ margin-left: auto;
+ display: flex;
+ width: 11rem;
+ justify-content: flex-end;
+
+ a {
+ &:hover img {
+ opacity: 0.85;
+ }
+ position: relative;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+
+ img {
+ transition: opacity 0.12s ease-in-out;
+ width: 6rem;
+ filter: invert(100%);
+ opacity: 0.75;
+ }
+ }
+ }
+
+ .footerGrow {
+ flex-grow: 1;
+ display: flex;
+ align-items: center;
+ justify-content: flex-start;
+ gap: 1.5rem;
+ > a {
+ @include SuperSmallText;
+ padding: 0.2rem;
+ font-weight: bold;
+ color: #000;
+ opacity: 0.6;
+ transition: opacity 0.12s ease-in-out;
+ &:hover {
+ opacity: 1;
+ }
+ }
+ }
+ }
+
+ @include DarkThemeOverride {
+ background: rgba($darkModeGameBackground, 0.5) center center / cover !important;
+
+ .mainContainer {
+ background: $darkModeControlsBackground;
+
+ .savegames .savegame {
+ background: darken($darkModeControlsBackground, 5);
+ color: white;
+ }
+ }
+
+ .modsOverview {
+ background: $darkModeControlsBackground;
+
+ .modsList {
+ border-color: darken($darkModeControlsBackground, 5);
+
+ .mod {
+ background: darken($darkModeControlsBackground, 5);
+ color: white;
+ }
+ }
+
+ .dlcHint {
+ color: $accentColorBright;
+ }
+ }
+ }
+}
diff --git a/src/css/states/mobile_warning.scss b/src/css/states/mobile_warning.scss
deleted file mode 100644
index 947d530c..00000000
--- a/src/css/states/mobile_warning.scss
+++ /dev/null
@@ -1,51 +0,0 @@
-#state_MobileWarningState {
- display: flex;
- align-items: center;
- background: #555b75 !important;
- @include S(padding, 20px);
- box-sizing: border-box;
- justify-content: center;
- flex-direction: column;
-
- .logo {
- width: 80%;
- max-width: 200px;
- margin-bottom: 10px;
- }
-
- p {
- color: rgba(#fff, 0.5);
- display: block;
- margin-bottom: 13px;
- font-size: 16px;
- line-height: 20px;
- max-width: 300px;
- text-align: left;
- a {
- color: $colorBlueBright;
- }
- }
-
- .standaloneLink {
- width: 200px;
- height: 48px;
- min-height: 40px;
- & {
- background: #000 uiResource("steam_link_btn/0.png") center center / contain no-repeat;
- }
- display: block;
- text-indent: -999em;
- cursor: pointer;
- margin-top: 10px;
- pointer-events: all;
- transition: all 0.12s ease-in;
- transition-property: opacity, transform;
- @include S(border-radius, $globalBorderRadius);
- overflow: hidden;
-
- &:hover {
- transform: skewX(-1deg) scale(1.02);
- opacity: 0.9;
- }
- }
-}
diff --git a/src/css/states/mods.scss b/src/css/states/mods.scss
index 60912510..3935e390 100644
--- a/src/css/states/mods.scss
+++ b/src/css/states/mods.scss
@@ -1,144 +1,41 @@
#state_ModsState {
- .mainContent {
- display: flex;
- flex-direction: column;
- }
-
- > .headerBar {
+ // TODO: Update dimensions to use less build-time logic
+ .modsGrid {
display: grid;
- grid-template-columns: 1fr auto;
- align-items: center;
+ grid-template-columns: repeat(2, 1fr);
+ gap: 1rem;
+ }
- > h1 {
- justify-self: start;
- }
+ .modsGrid.noMods {
+ grid-template-columns: unset;
+ place-items: center;
+ }
- .openModsFolder {
- background-color: $modsColor;
+ .mod {
+ width: 100%;
+ box-sizing: border-box;
+ padding: 1rem;
+
+ border-radius: 0.4rem;
+ background: #eee;
+
+ @include DarkThemeOverride {
+ background: lighten($darkModeControlsBackground, 5);
}
}
- .noModSupport {
- display: flex;
- align-items: center;
- justify-content: center;
- height: 100%;
- flex-direction: column;
- text-align: center;
- max-width: 80%;
- align-self: center;
-
- .steamLink {
- @include S(height, 50px);
- @include S(width, 220px);
- background: #171a23 center center / contain no-repeat;
- overflow: hidden;
- display: block;
- text-indent: -999em;
- cursor: pointer;
- @include S(margin-top, 30px);
- pointer-events: all;
- transition: all 0.12s ease-in;
- transition-property: opacity, transform;
-
- box-shadow: 0 D(3px) D(10px) rgba(96, 163, 136, 0.5);
- @include S(border-radius, $globalBorderRadius);
-
- &:hover {
- opacity: 0.9;
- }
- }
+ .mod > .title {
+ text-wrap: nowrap;
+ text-overflow: ellipsis;
+ overflow: hidden;
}
- .modsStats {
- @include PlainText;
+ .mod > .description {
+ @include PlainText();
+ }
+
+ .mod > .advanced {
+ @include PlainText();
color: $accentColorDark;
-
- &.noMods {
- @include S(width, 400px);
- align-self: center;
- justify-self: center;
- text-align: center;
- display: flex;
- flex-direction: column;
- align-items: center;
- @include Text;
- @include S(margin-top, 100px);
- color: lighten($accentColorDark, 15);
-
- button {
- @include S(margin-top, 10px);
- @include S(padding, 10px, 20px);
- }
-
- &::before {
- @include S(margin-bottom, 15px);
- content: "";
- @include S(width, 50px);
- @include S(height, 50px);
- background-position: center center;
- background-size: contain;
- opacity: 0.2;
- }
- &::before {
- background-image: uiResource("res/ui/icons/mods.png") !important;
- }
- }
- }
-
- .modsList {
- @include S(margin-top, 10px);
- overflow-y: scroll;
- pointer-events: all;
- @include S(padding-right, 5px);
- flex-grow: 1;
-
- .mod {
- @include S(border-radius, $globalBorderRadius);
- background: #eeeff4;
- @include S(margin-bottom, 4px);
- @include S(padding, 7px, 10px);
- @include S(grid-gap, 15px);
- display: grid;
- grid-template-columns: 1fr D(100px) D(80px) D(50px);
-
- @include DarkThemeOverride {
- background: darken($darkModeControlsBackground, 5);
- }
-
- .checkbox {
- align-self: center;
- justify-self: center;
- }
-
- .mainInfo {
- display: flex;
- flex-direction: column;
-
- .description {
- @include PlainText;
- @include S(margin-top, 5px);
- color: $accentColorDark;
- }
- .website {
- text-transform: uppercase;
- align-self: start;
- @include PlainText;
- @include S(margin-top, 5px);
- }
- }
-
- .version,
- .author {
- display: flex;
- flex-direction: column;
- align-self: center;
- strong {
- text-transform: uppercase;
- color: $accentColorDark;
- @include SuperSmallText;
- }
- }
- }
}
}
diff --git a/src/css/states/preload.scss b/src/css/states/preload.scss
index dee33c06..caae6be7 100644
--- a/src/css/states/preload.scss
+++ b/src/css/states/preload.scss
@@ -1,153 +1,152 @@
-#state_PreloadState {
- .changelogDialogEntry {
- @include S(margin-top, 10px);
-
- width: 100%;
- flex-direction: column;
- text-align: left;
- padding: 10px;
- box-sizing: border-box;
- background: #eef1f4;
- @include S(border-radius, $globalBorderRadius);
-
- @include DarkThemeOverride {
- background: #33343c;
- }
-
- .version {
- @include Heading;
- }
- .date {
- @include PlainText;
- &::before {
- content: " | ";
- }
- color: #aaabaf;
- }
-
- .changes {
- @include PlainText;
- @include S(padding-left, 15px);
- @include S(margin-top, 10px);
- strong {
- background: $colorBlueBright;
- color: #fff;
- text-transform: uppercase;
- @include S(padding, 1px, 2px);
- @include S(margin-right, 3px);
- }
- a {
- color: $colorBlueBright;
- }
- li {
- @include SuperSmallText;
- @include S(margin-bottom, 5px);
- }
- }
- }
-
- .failureBox {
- position: absolute;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- z-index: 999999;
- background: #d5d8de;
- display: flex;
- align-items: center;
- justify-content: center;
- flex-direction: column;
-
- .logo {
- img {
- @include S(width, 240px);
- }
-
- @include S(margin-bottom, 30px);
- }
-
- @include InlineAnimation(0.3s ease-in-out) {
- 0% {
- opacity: 0;
- }
- 100% {
- opacity: 1;
- }
- }
-
- .failureInner {
- // background: darken($mainBgColor, 6);
- @include S(max-width, 350px);
- margin: 0 20px;
- text-align: left;
-
- @include BoxShadow3D(#fff);
- @include S(padding, 15px);
- @include S(border-radius, $globalBorderRadius);
- @include DropShadow;
-
- .errorHeader {
- color: #ef5072;
- }
-
- .errorMessage {
- @include PlainText;
- display: block;
- color: #666;
- text-align: left;
- @include BreakText;
- hyphens: auto;
- // border: dotted #666;
- // @include S(border-width, 1px, 0);
- @include S(padding, 10px, 0);
- @include S(margin-top, 10px);
- }
-
- .supportHelp {
- @include S(margin-top, 10px);
- @include PlainText;
-
- .email {
- color: $themeColor;
- cursor: pointer;
- pointer-events: all;
- }
- }
-
- .lower {
- display: flex;
- align-items: center;
- @include S(margin-top, 16px);
-
- i {
- flex-grow: 1;
- text-align: right;
- color: #777;
- @include PlainText;
- }
-
- button.resetApp {
- @include Button3D($colorRedBright);
- @include PlainText;
- @include S(padding, 5px, 8px, 4px);
- color: #fff;
- }
- }
- }
- }
-
- /* Animations */
- .status {
- transform: scale(0.7) $hardwareAcc;
- opacity: 0;
- @include StateAnim(transform, opacity);
- }
-
- &.arrived {
- .status {
- opacity: 1;
- transform: none;
- }
- }
-}
+#state_PreloadState {
+ .changelogDialogEntry {
+ margin-top: 1rem;
+
+ width: 100%;
+ flex-direction: column;
+ text-align: left;
+ padding: 10px;
+ box-sizing: border-box;
+ background: #eef1f4;
+ border-radius: $globalBorderRadius;
+
+ @include DarkThemeOverride {
+ background: #33343c;
+ }
+
+ .version {
+ @include Heading;
+ }
+ .date {
+ @include PlainText;
+ &::before {
+ content: " | ";
+ }
+ color: #aaabaf;
+ }
+
+ .changes {
+ @include PlainText;
+ padding-left: 1.5rem;
+ margin-top: 1rem;
+ strong {
+ background: $colorBlueBright;
+ color: #fff;
+ text-transform: uppercase;
+ padding: 0.1rem 0.2rem;
+ margin-right: 0.3rem;
+ }
+ a {
+ color: $colorBlueBright;
+ }
+ li {
+ @include SuperSmallText;
+ margin-bottom: 0.5rem;
+ }
+ }
+ }
+
+ .failureBox {
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ z-index: 999999;
+ background: #d5d8de;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ flex-direction: column;
+
+ .logo {
+ img {
+ width: 24rem;
+ }
+
+ margin-bottom: 3rem;
+ }
+
+ @include InlineAnimation(0.3s ease-in-out) {
+ 0% {
+ opacity: 0;
+ }
+ 100% {
+ opacity: 1;
+ }
+ }
+
+ .failureInner {
+ // background: darken($mainBgColor, 6);
+ max-width: 35rem;
+ margin: 0 20px;
+ text-align: left;
+
+ @include BoxShadow3D(#fff);
+ padding: 1.5rem;
+ border-radius: $globalBorderRadius;
+ @include DropShadow;
+
+ .errorHeader {
+ color: #ef5072;
+ }
+
+ .errorMessage {
+ @include PlainText;
+ display: block;
+ color: #666;
+ text-align: left;
+ overflow-wrap: break-word;
+ hyphens: auto;
+ // border: dotted #666;
+ padding: 1rem 0;
+ margin-top: 1rem;
+ }
+
+ .supportHelp {
+ margin-top: 1rem;
+ @include PlainText;
+
+ .email {
+ color: $themeColor;
+ cursor: pointer;
+ pointer-events: all;
+ }
+ }
+
+ .lower {
+ display: flex;
+ align-items: center;
+ margin-top: 1.6rem;
+
+ i {
+ flex-grow: 1;
+ text-align: right;
+ color: #777;
+ @include PlainText;
+ }
+
+ button.resetApp {
+ @include Button3D($colorRedBright);
+ @include PlainText;
+ padding: 0.5rem 0.8rem 0.4rem;
+ color: #fff;
+ }
+ }
+ }
+ }
+
+ /* Animations */
+ .status {
+ transform: scale(0.7);
+ opacity: 0;
+ @include StateAnim(transform, opacity);
+ }
+
+ &.arrived {
+ .status {
+ opacity: 1;
+ transform: none;
+ }
+ }
+}
diff --git a/src/css/states/puzzle_menu.scss b/src/css/states/puzzle_menu.scss
index ad326c49..94bcfc72 100644
--- a/src/css/states/puzzle_menu.scss
+++ b/src/css/states/puzzle_menu.scss
@@ -10,7 +10,7 @@
.createPuzzle {
background-color: $colorGreenBright;
- @include S(margin-left, 5px);
+ margin-left: 0.5rem;
}
}
@@ -22,8 +22,8 @@
color: #333;
background: $accentColorBright;
- @include S(padding, 5px);
- @include S(border-radius, $globalBorderRadius);
+ padding: 0.5rem;
+ border-radius: $globalBorderRadius;
flex-wrap: wrap;
@include DarkThemeOverride {
@@ -35,8 +35,8 @@
margin: 0;
display: inline-block;
flex-grow: 1;
- @include S(padding, 5px, 10px);
- @include S(min-width, 50px);
+ padding: 0.5rem 1rem;
+ min-width: 5rem;
&::placeholder {
color: #aaa;
@@ -46,15 +46,15 @@
select {
color: #333;
border: 0;
- @include S(padding, 5px);
- @include S(border-radius, $globalBorderRadius);
- @include S(padding, 7px, 10px);
- @include S(margin-left, 5px);
+ padding: 0.5rem;
+ border-radius: $globalBorderRadius;
+ padding: 0.7rem 1rem;
+ margin-left: 0.5rem;
@include PlainText;
}
.filterCompleted {
- @include S(margin-left, 20px);
+ margin-left: 2rem;
pointer-events: all;
cursor: pointer;
display: flex;
@@ -62,26 +62,26 @@
justify-content: center;
text-transform: uppercase;
@include PlainText;
- @include S(margin-right, 10px);
+ margin-right: 1rem;
@include DarkThemeOverride {
color: #bbbbc4;
}
input {
- @include S(width, 15px);
- @include S(height, 15px);
- @include S(margin-right, 5px);
- @include S(border-radius, $globalBorderRadius);
+ width: 1.5rem;
+ height: 1.5rem;
+ margin-right: 0.5rem;
+ border-radius: $globalBorderRadius;
border: 0;
}
}
button[type="submit"] {
- @include S(padding, 7px, 10px, 5px);
- @include S(margin-left, 20px);
- @include S(margin-top, 4px);
- @include S(margin-bottom, 4px);
+ padding: 0.7rem 1rem 0.5rem;
+ margin-left: 2rem;
+ margin-top: 0.4rem;
+ margin-bottom: 0.4rem;
margin-left: auto;
}
}
@@ -96,9 +96,9 @@
display: grid;
grid-auto-columns: 1fr;
grid-auto-flow: column;
- @include S(grid-gap, 2px);
- @include S(padding-right, 10px);
- @include S(margin-bottom, 5px);
+ grid-gap: 0.2rem;
+ padding-right: 1rem;
+ margin-bottom: 0.5rem;
.category {
background: $accentColorBright;
@@ -108,8 +108,8 @@
transition-property: opacity, background-color, color;
&:first-child {
- @include S(border-top-left-radius, $globalBorderRadius);
- @include S(border-bottom-left-radius, $globalBorderRadius);
+ border-top-left-radius: $globalBorderRadius;
+ border-bottom-left-radius: $globalBorderRadius;
}
&:last-child {
border-top-right-radius: $globalBorderRadius;
@@ -134,8 +134,8 @@
}
&.root {
- @include S(padding-top, 10px);
- @include S(padding-bottom, 10px);
+ padding-top: 1rem;
+ padding-bottom: 1rem;
@include Text;
}
&.child {
@@ -147,11 +147,11 @@
> .puzzles {
display: grid;
- grid-template-columns: repeat(auto-fit, minmax(D(240px), 1fr));
- @include S(grid-auto-rows, 65px);
- @include S(grid-gap, 7px);
- @include S(margin-top, 10px);
- @include S(padding-right, 4px);
+ grid-template-columns: repeat(auto-fit, minmax(24rem, 1fr));
+ grid-auto-rows: 6.5rem;
+ grid-gap: 0.7rem;
+ margin-top: 1rem;
+ padding-right: 0.4rem;
overflow-y: scroll;
flex-grow: 1;
pointer-events: all;
@@ -159,20 +159,20 @@
> .puzzle {
width: 100%;
- @include S(height, 65px);
+ height: 6.5rem;
background: #f3f3f8;
- @include S(border-radius, $globalBorderRadius);
+ border-radius: $globalBorderRadius;
display: grid;
grid-template-columns: auto 1fr;
- grid-template-rows: D(15px) D(15px) 1fr;
- @include S(padding, 5px);
- @include S(grid-column-gap, 5px);
+ grid-template-rows: 1.5rem 1.5rem 1fr;
+ padding: 0.5rem;
+ grid-column-gap: 0.5rem;
box-sizing: border-box;
pointer-events: all;
cursor: pointer;
position: relative;
- @include S(padding-left, 10px);
+ padding-left: 1rem;
@include DarkThemeOverride {
background: rgba(0, 0, 10, 0.2);
@@ -202,8 +202,8 @@
justify-self: start;
width: 100%;
box-sizing: border-box;
- @include S(padding, 2px, 5px);
- @include S(height, 17px);
+ padding: 0.2rem 0.5rem;
+ height: 1.7rem;
}
> .author {
@@ -215,7 +215,7 @@
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
- @include S(padding, 2px, 5px);
+ padding: 0.2rem 0.5rem;
}
> .icon {
@@ -223,8 +223,8 @@
grid-row: 1 / 4;
align-self: center;
justify-self: center;
- @include S(width, 45px);
- @include S(height, 45px);
+ width: 4.5rem;
+ height: 4.5rem;
canvas {
width: 100%;
@@ -234,14 +234,14 @@
> button.delete {
position: absolute;
- @include S(top, 5px);
- @include S(right, 5px);
+ top: 0.5rem;
+ right: 0.5rem;
background-repeat: no-repeat;
background-position: center center;
background-size: 70%;
background-color: transparent !important;
- @include S(width, 20px);
- @include S(height, 20px);
+ width: 2rem;
+ height: 2rem;
padding: 0;
opacity: 0.7;
@include DarkThemeInvert;
@@ -259,14 +259,14 @@
justify-self: end;
justify-content: center;
align-self: end;
- @include S(height, 14px);
+ height: 1.4rem;
> .downloads {
@include SuperSmallText;
color: #000;
font-weight: bold;
- @include S(margin-right, 5px);
- @include S(padding-left, 12px);
+ margin-right: 0.5rem;
+ padding-left: 1.2rem;
opacity: 0.7;
display: inline-flex;
align-items: center;
@@ -274,9 +274,8 @@
@include DarkThemeInvert;
& {
- background: uiResource("icons/puzzle_plays.png") #{D(2px)} #{D(2.5px)} / #{D(
- 8px
- )} #{D(8px)} no-repeat;
+ background: uiResource("icons/puzzle_plays.png") 0.2rem 0.25rem / 0.8rem
+ 0.8rem no-repeat;
}
}
@@ -286,14 +285,13 @@
justify-content: center;
color: #000;
font-weight: bold;
- @include S(padding-left, 14px);
+ padding-left: 1.4rem;
opacity: 0.7;
@include DarkThemeInvert;
& {
- background: uiResource("icons/puzzle_upvotes.png") #{D(2px)} #{D(2.4px)} / #{D(
- 9px
- )} #{D(9px)} no-repeat;
+ background: uiResource("icons/puzzle_upvotes.png") 0.2rem 0.24rem / 0.9rem
+ 0.9rem no-repeat;
}
}
@@ -303,7 +301,7 @@
justify-content: center;
color: #000;
font-weight: bold;
- @include S(margin-right, 3px);
+ margin-right: 0.3rem;
opacity: 0.7;
text-transform: uppercase;
@@ -339,10 +337,10 @@
&::after {
content: "";
position: absolute;
- @include S(top, 10px);
- @include S(right, 10px);
- @include S(width, 30px);
- @include S(height, 30px);
+ top: 1rem;
+ right: 1rem;
+ width: 3rem;
+ height: 3rem;
opacity: 0.1;
& {
diff --git a/src/css/states/settings.scss b/src/css/states/settings.scss
index 98135909..619a1772 100644
--- a/src/css/states/settings.scss
+++ b/src/css/states/settings.scss
@@ -1,272 +1,248 @@
-#state_SettingsState {
- $colorCategoryButton: #eeeff5;
- $colorCategoryButtonSelected: $colorBlueBright;
-
- $layoutBreak: 1000px;
-
- .container .content {
- display: grid;
- grid-template-columns: auto 1fr;
- @include S(grid-gap, 10px);
-
- @include StyleBelowWidth($layoutBreak) {
- grid-template-columns: 1fr;
- grid-template-rows: auto 1fr;
- }
-
- .sidebar {
- display: flex;
- @include S(min-width, 210px);
- @include S(max-width, 320px);
- flex-direction: column;
-
- @include StyleBelowWidth($layoutBreak) {
- display: grid;
- grid-template-columns: 1fr 1fr 1fr;
- @include S(grid-gap, 5px);
- max-width: unset !important;
- }
-
- button {
- text-align: left;
- @include S(margin-bottom, 3px);
- &::after {
- content: unset;
- }
- width: 100%;
- box-sizing: border-box;
-
- @include StyleBelowWidth($layoutBreak) {
- text-align: center;
- height: D(30px) !important;
- padding: D(5px) !important;
- }
- }
-
- .other {
- align-self: end;
- margin-top: auto;
-
- &.noabout {
- align-self: start;
- }
-
- @include StyleBelowWidth($layoutBreak) {
- margin-top: 0;
- display: grid;
- grid-template-columns: 1fr 1fr;
- @include S(grid-gap, 5px);
- max-width: unset !important;
- grid-column: 1 / 3;
-
- button {
- margin: 0 !important;
- }
- }
- }
-
- button.categoryButton,
- button.about,
- button.privacy {
- background-color: $colorCategoryButton;
- color: #777a7f;
-
- &.active {
- background-color: $colorCategoryButtonSelected;
- color: #fff;
-
- &:hover {
- opacity: 1;
- }
- }
-
- &.pressed {
- transform: none !important;
- }
- }
-
- button.manageMods {
- background-color: lighten($modsColor, 38);
- color: $modsColor;
- display: flex;
- @include S(padding-right, 5px);
- .newBadge {
- color: #fff;
- @include S(border-radius, $globalBorderRadius);
- background: $modsColor;
- margin-left: auto;
- @include S(padding, 0, 3px, 0, 3px);
-
- @include InlineAnimation(1.3s ease-in-out infinite) {
- 50% {
- transform: rotate(0deg) scale(1.1);
- }
- }
- }
-
- &.active {
- background-color: $colorGreenBright;
- }
- }
-
- .versionbar {
- @include S(margin-top, 10px);
-
- @include StyleBelowWidth($layoutBreak) {
- display: none;
- }
-
- @include SuperSmallText;
- display: grid;
- align-items: center;
- grid-template-columns: 1fr auto;
- .buildVersion {
- display: flex;
- flex-direction: column;
- color: #aaadaf;
- }
- }
- }
-
- .categoryContainer {
- overflow-y: scroll;
- pointer-events: all;
- @include S(padding-right, 10px);
-
- .category {
- display: none;
-
- &.active {
- display: block;
- }
-
- .setting {
- @include S(padding, 10px);
- background: #eeeff5;
- @include S(border-radius, $globalBorderRadius);
- @include S(margin-bottom, 5px);
-
- .desc {
- @include S(margin-top, 5px);
- @include SuperSmallText;
- color: #aaadb2;
- }
-
- > .row {
- display: grid;
- align-items: center;
- grid-template-columns: 1fr auto;
-
- > label {
- text-transform: uppercase;
- @include Text;
- }
- }
-
- &.disabled {
- // opacity: 0.3;
- pointer-events: none;
- * {
- pointer-events: none !important;
- cursor: default !important;
- }
- position: relative;
- .standaloneOnlyHint {
- @include PlainText;
- position: absolute;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- pointer-events: all;
- display: flex;
- align-items: center;
- z-index: 100;
- justify-content: center;
- background: rgba(#fff, 0.5);
- text-transform: uppercase;
- color: $colorRedBright;
- @include S(border-radius, $globalBorderRadius);
-
- @include DarkThemeOverride {
- background: rgba(#55585f, 0.95);
- }
- }
- }
-
- .value.enum {
- background: #fff;
- @include PlainText;
- display: flex;
- align-items: flex-start;
- pointer-events: all;
- cursor: pointer;
- justify-content: center;
- @include S(min-width, 100px);
- @include S(border-radius, $globalBorderRadius);
- @include S(padding, 4px);
- @include S(padding-right, 15px);
-
- & {
- background: #fff uiResource("icons/enum_selector.png") calc(100% - #{D(5px)})
- calc(50% + #{D(1px)}) / #{D(15px)} no-repeat;
- }
-
- transition: background-color 0.12s ease-in-out;
- &:hover {
- background-color: #fafafa;
- }
- }
- }
- }
- }
- }
-
- @include DarkThemeOverride {
- .container .content {
- .sidebar {
- button.categoryButton,
- button.about,
- button.privacy {
- color: #ccc;
- background-color: darken($darkModeControlsBackground, 5);
-
- &.active {
- color: #fff;
- background-color: $colorCategoryButtonSelected;
- }
- }
- }
-
- .categoryContainer {
- .category {
- .setting {
- background: darken($darkModeGameBackground, 10);
-
- .value.enum {
- // dirty but works
- // color: #222;
- background-color: $darkModeControlsBackground;
-
- & {
- background-image: uiResource("icons/enum_selector_white.png");
- }
- color: #ddd;
- &:hover {
- background-color: darken($darkModeControlsBackground, 2);
- }
- }
-
- .value.checkbox {
- background-color: #74767b;
-
- &.checked {
- background-color: $colorBlueBright;
- }
- }
- }
- }
- }
- }
- }
-}
+#state_SettingsState {
+ $colorCategoryButton: #eeeff5;
+ $colorCategoryButtonSelected: $colorBlueBright;
+
+ $layoutBreak: 1000px;
+
+ .container .content {
+ display: grid;
+ grid-template-columns: auto 1fr;
+ grid-gap: 1rem;
+
+ @include StyleBelowWidth($layoutBreak) {
+ grid-template-columns: 1fr;
+ grid-template-rows: auto 1fr;
+ }
+
+ .sidebar {
+ display: flex;
+ min-width: 21rem;
+ max-width: 32rem;
+ flex-direction: column;
+
+ @include StyleBelowWidth($layoutBreak) {
+ display: grid;
+ grid-template-columns: 1fr 1fr 1fr;
+ grid-gap: 0.5rem;
+ max-width: unset !important;
+ }
+
+ button {
+ text-align: left;
+ margin-bottom: 0.3rem;
+ &::after {
+ content: unset;
+ }
+ width: 100%;
+ box-sizing: border-box;
+
+ @include StyleBelowWidth($layoutBreak) {
+ text-align: center;
+ height: 3rem !important;
+ padding: 0.5rem !important;
+ }
+ }
+
+ .other {
+ align-self: end;
+ margin-top: auto;
+
+ &.noabout {
+ align-self: start;
+ }
+
+ @include StyleBelowWidth($layoutBreak) {
+ margin-top: 0;
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ grid-gap: 0.5rem;
+ max-width: unset !important;
+ grid-column: 1 / 3;
+
+ button {
+ margin: 0 !important;
+ }
+ }
+ }
+
+ button.categoryButton,
+ button.about,
+ button.privacy {
+ background-color: $colorCategoryButton;
+ color: #777a7f;
+
+ &.active {
+ background-color: $colorCategoryButtonSelected;
+ color: #fff;
+
+ &:hover {
+ opacity: 1;
+ }
+ }
+
+ &.pressed {
+ transform: none !important;
+ }
+ }
+
+ .versionbar {
+ margin-top: 1rem;
+
+ @include StyleBelowWidth($layoutBreak) {
+ display: none;
+ }
+
+ @include SuperSmallText;
+ display: grid;
+ align-items: center;
+ grid-template-columns: 1fr auto;
+ .buildVersion {
+ display: flex;
+ flex-direction: column;
+ color: #aaadaf;
+ }
+ }
+ }
+
+ .categoryContainer {
+ overflow-y: scroll;
+ pointer-events: all;
+ padding-right: 1rem;
+
+ .category {
+ display: none;
+
+ &.active {
+ display: block;
+ }
+
+ .setting {
+ padding: 1rem;
+ background: #eeeff5;
+ border-radius: $globalBorderRadius;
+ margin-bottom: 0.5rem;
+
+ .desc {
+ margin-top: 0.5rem;
+ @include SuperSmallText;
+ color: #aaadb2;
+ }
+
+ > .row {
+ display: grid;
+ align-items: center;
+ grid-template-columns: 1fr auto;
+
+ > label {
+ text-transform: uppercase;
+ @include Text;
+ }
+ }
+
+ &.disabled {
+ // opacity: 0.3;
+ pointer-events: none;
+ * {
+ pointer-events: none !important;
+ cursor: default !important;
+ }
+ position: relative;
+ .standaloneOnlyHint {
+ @include PlainText;
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ pointer-events: all;
+ display: flex;
+ align-items: center;
+ z-index: 100;
+ justify-content: center;
+ background: rgba(#fff, 0.5);
+ text-transform: uppercase;
+ color: $colorRedBright;
+ border-radius: $globalBorderRadius;
+
+ @include DarkThemeOverride {
+ background: rgba(#55585f, 0.95);
+ }
+ }
+ }
+
+ .value.enum {
+ background: #fff;
+ @include PlainText;
+ display: flex;
+ align-items: flex-start;
+ pointer-events: all;
+ cursor: pointer;
+ justify-content: center;
+ min-width: 10rem;
+ border-radius: $globalBorderRadius;
+ padding: 0.4rem;
+ padding-right: 1.5rem;
+
+ & {
+ background: #fff uiResource("icons/enum_selector.png") calc(100% - 0.5rem)
+ calc(50% + 0.1rem) / 1.5rem no-repeat;
+ }
+
+ transition: background-color 0.12s ease-in-out;
+ &:hover {
+ background-color: #fafafa;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ @include DarkThemeOverride {
+ .container .content {
+ .sidebar {
+ button.categoryButton,
+ button.about,
+ button.privacy {
+ color: #ccc;
+ background-color: darken($darkModeControlsBackground, 5);
+
+ &.active {
+ color: #fff;
+ background-color: $colorCategoryButtonSelected;
+ }
+ }
+ }
+
+ .categoryContainer {
+ .category {
+ .setting {
+ background: darken($darkModeGameBackground, 10);
+
+ .value.enum {
+ // dirty but works
+ // color: #222;
+ background-color: $darkModeControlsBackground;
+
+ & {
+ background-image: uiResource("icons/enum_selector_white.png");
+ }
+ color: #ddd;
+ &:hover {
+ background-color: darken($darkModeControlsBackground, 2);
+ }
+ }
+
+ .value.checkbox {
+ background-color: #74767b;
+
+ &.checked {
+ background-color: $colorBlueBright;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/css/states/wegame_splash.scss b/src/css/states/wegame_splash.scss
deleted file mode 100644
index 961cfa67..00000000
--- a/src/css/states/wegame_splash.scss
+++ /dev/null
@@ -1,38 +0,0 @@
-#state_WegameSplashState {
- background: #000 !important;
- display: flex;
- align-items: center;
- justify-content: center;
-
- .wrapper {
- opacity: 0;
- @include InlineAnimation(5.9s ease-in-out) {
- 0% {
- opacity: 0;
- }
- 20% {
- opacity: 1;
- }
- 90% {
- opacity: 1;
- }
- 100% {
- opacity: 0;
- }
- }
-
- text-align: center;
- color: #fff;
- @include Heading;
-
- strong {
- display: block;
- @include SuperHeading;
- @include S(margin-bottom, 20px);
- }
-
- div {
- @include S(margin-bottom, 10px);
- }
- }
-}
diff --git a/src/css/textual_game_state.scss b/src/css/textual_game_state.scss
index 6e3fad30..bb637ddd 100644
--- a/src/css/textual_game_state.scss
+++ b/src/css/textual_game_state.scss
@@ -1,82 +1,81 @@
-.gameState.textualState {
- display: grid;
- grid-template-rows: auto 1fr;
- box-sizing: border-box;
- @include S(padding, 32px);
- height: 100vh;
-
- .headerBar {
- display: flex;
-
- h1 {
- display: grid;
- grid-template-columns: auto 1fr;
- align-items: center;
- pointer-events: all;
- cursor: pointer;
- @include SuperHeading;
- text-transform: uppercase;
- color: #333438;
- position: relative;
- @include IncreasedClickArea(10px);
- }
-
- .backButton {
- @include S(width, 30px);
- @include S(height, 30px);
- @include S(margin-right, 10px);
- @include S(margin-left, -5px);
- & {
- background: uiResource("icons/state_back_button.png") center center / 70% no-repeat;
- }
- }
- @include S(margin-bottom, 20px);
- }
-
- > .container {
- display: flex;
- justify-content: center;
- width: 100%;
- overflow-y: auto;
-
- > .content {
- width: 100%;
- background: #fff;
- @include S(border-radius, $globalBorderRadius);
- @include S(padding, 10px);
- height: 100%;
- overflow-y: auto;
- box-sizing: border-box;
- pointer-events: all;
-
- a {
- color: $colorBlueBright;
- }
-
- .categoryLabel {
- display: block;
- text-transform: uppercase;
- @include S(margin-top, 15px);
- @include S(margin-bottom, 15px);
- @include Heading;
- }
- }
- }
-
- @include DarkThemeOverride {
- .headerBar {
- h1 {
- color: #e2e0db;
- }
-
- .backButton {
- filter: invert(1);
- }
- }
-
- > .container > .content {
- background: $darkModeControlsBackground;
- color: #eee;
- }
- }
-}
+.gameState.textualState {
+ display: grid;
+ grid-template-rows: auto 1fr;
+ box-sizing: border-box;
+ padding: 3.2rem;
+ height: 100vh;
+
+ .headerBar {
+ display: flex;
+
+ h1 {
+ display: grid;
+ grid-template-columns: auto 1fr;
+ align-items: center;
+ pointer-events: all;
+ cursor: pointer;
+ @include SuperHeading;
+ text-transform: uppercase;
+ color: #333438;
+ position: relative;
+ }
+
+ .backButton {
+ width: 3rem;
+ height: 3rem;
+ margin-right: 1rem;
+ margin-left: -0.5rem;
+ & {
+ background: uiResource("icons/state_back_button.png") center center / 70% no-repeat;
+ }
+ }
+ margin-bottom: 2rem;
+ }
+
+ > .container {
+ display: flex;
+ justify-content: center;
+ width: 100%;
+ overflow-y: auto;
+
+ > .content {
+ width: 100%;
+ background: #fff;
+ border-radius: $globalBorderRadius;
+ padding: 1rem;
+ height: 100%;
+ overflow-y: auto;
+ box-sizing: border-box;
+ pointer-events: all;
+
+ a {
+ color: $colorBlueBright;
+ }
+
+ .categoryLabel {
+ display: block;
+ text-transform: uppercase;
+ margin-top: 1.5rem;
+ margin-bottom: 1.5rem;
+ @include Heading;
+ }
+ }
+ }
+
+ @include DarkThemeOverride {
+ .headerBar {
+ h1 {
+ color: #e2e0db;
+ }
+
+ .backButton {
+ filter: invert(1);
+ }
+ }
+
+ > .container > .content {
+ background: $darkModeControlsBackground;
+ color: #eee;
+ }
+ }
+}
diff --git a/src/css/trigonometry.scss b/src/css/trigonometry.scss
deleted file mode 100644
index 97d2e730..00000000
--- a/src/css/trigonometry.scss
+++ /dev/null
@@ -1,66 +0,0 @@
-///////////////////////////////////////////////////////////
-// Plain SASS Trigonometry Algorithm in Taylor Expansion //
-// //
-// Based on //
-// http://japborst.net/posts/sass-sines-and-cosines //
-///////////////////////////////////////////////////////////
-
-$pi: 3.14159265359;
-$_precision: 10;
-
-@function pow($base, $exp) {
- $value: $base;
- @if $exp > 1 {
- @for $i from 2 through $exp {
- $value: $value * $base;
- }
- }
- @if $exp < 1 {
- @for $i from 0 through -$exp {
- $value: $value / $base;
- }
- }
- @return $value;
-}
-
-@function fact($num) {
- $fact: 1;
- @if $num > 0 {
- @for $i from 1 through $num {
- $fact: $fact * $i;
- }
- }
- @return $fact;
-}
-
-@function _to_unitless_rad($angle) {
- @if unit($angle) == "deg" {
- $angle: $angle / 180deg * $pi;
- }
- @if unit($angle) == "rad" {
- $angle: $angle / 1rad;
- }
- @return $angle;
-}
-
-@function sin($angle) {
- $a: _to_unitless_rad($angle);
- $sin: $a;
- @for $n from 1 through $_precision {
- $sin: $sin + (pow(-1, $n) / fact(2 * $n + 1)) * pow($a, (2 * $n + 1));
- }
- @return $sin;
-}
-
-@function cos($angle) {
- $a: _to_unitless_rad($angle);
- $cos: 1;
- @for $n from 1 through $_precision {
- $cos: $cos + (pow(-1, $n) / fact(2 * $n)) * pow($a, 2 * $n);
- }
- @return $cos;
-}
-
-@function tan($angle) {
- @return sin($angle) / cos($angle);
-}
diff --git a/src/css/variables.scss b/src/css/variables.scss
index 3ae8878d..60e0a13c 100644
--- a/src/css/variables.scss
+++ b/src/css/variables.scss
@@ -1,180 +1,103 @@
-$globalBorderRadius: 6px;
-
-// When to reduce control elements size for small devices
-$layoutExpandMinWidth: 340px;
-
-// Font sizes and line heights
-$superHeadingFontSize: 25px;
-$superHeadingLineHeight: 24px;
-
-$breakTooltipShowStatsPx: 1023px;
-
-$headingFontSize: 19px;
-$headingLineHeight: 21px;
-
-$textFontSize: 16px;
-$textLineHeight: 21px;
-
-$plainTextFontSize: 13px;
-$plainTextLineHeight: 17px;
-
-$superDuperSmallTextFontSize: 8px;
-$superDuperSmallTextLineHeight: 9px;
-$superSmallTextFontSize: 10px;
-$superSmallTextLineHeight: 13px;
-$buttonFontSize: 14px;
-$buttonLineHeight: 18px;
-
-// Main background color
-$mainBgColor: #dee1ea;
-
-// Accent colors
-
-$accentColorBright: #e1e4ed;
-$accentColorDark: #7d808a;
-$colorGreenBright: #66bb6a;
-$colorBlueBright: rgb(74, 151, 223);
-$colorRedBright: #ef5072;
-$colorOrangeBright: #ef9d50;
-$themeColor: #393747;
-$ingameHudBg: rgba(#33343b, 0.9);
-$modsColor: rgb(214, 60, 228);
-
-$text3dColor: #f4ffff;
-
-$darkModeGameBackground: #535866;
-$darkModeControlsBackground: darken($darkModeGameBackground, 5);
-
-// Dialog properties
-$modalDialogBg: rgba(160, 165, 180, 0.8);
-$dialogBgColor: lighten($mainBgColor, 10);
-
-$lightFontWeight: normal;
-$boldFontWeight: 600;
-
-$iconSizeSmall: 30px;
-$iconSizeMedium: 40px;
-$iconSizeLarge: 60px;
-
-// Poppins 500
-// Rubik 400
-// Cairo 400
-// Viga 400
-// Sniglet 400
-
-$mainFont: "GameFont", sans-serif;
-// $mainFont: "DK Canoodle";
-// $mainFont: "MADE Florence Sans";
-$numberFont: $mainFont;
-$textFont: $mainFont;
-
-$mainFontWeight: 400;
-$mainFontSpacing: 0.01em;
-$mainFontScale: 1;
-
-@mixin DebugText($color) {
- // font-size: 3px;
- // &,
- // * {
- // color: $color !important;
- // }
-}
-
-@mixin SuperDuperSmallText {
- @include ScaleFont($superDuperSmallTextFontSize, $superDuperSmallTextLineHeight);
- font-weight: $mainFontWeight;
- font-family: $mainFont;
- letter-spacing: $mainFontSpacing;
- @include DebugText(green);
-}
-
-@mixin SuperSmallText {
- @include ScaleFont($superSmallTextFontSize, $superSmallTextLineHeight);
- font-weight: $mainFontWeight;
- font-family: $mainFont;
- letter-spacing: $mainFontSpacing;
- @include DebugText(green);
-}
-
-@mixin PlainText {
- @include ScaleFont($plainTextFontSize, $plainTextLineHeight);
- font-weight: $mainFontWeight;
- font-family: $mainFont;
- letter-spacing: $mainFontSpacing;
-
- @include DebugText(red);
-}
-
-@mixin Text {
- @include ScaleFont($textFontSize, $textLineHeight);
- font-weight: $mainFontWeight;
- font-family: $mainFont;
-
- letter-spacing: $mainFontSpacing;
-
- @include DebugText(blue);
-}
-
-@mixin Heading {
- @include ScaleFont($headingFontSize, $headingLineHeight);
- font-weight: $mainFontWeight;
- font-family: $mainFont;
- letter-spacing: $mainFontSpacing;
-
- @include DebugText(yellow);
-}
-
-@mixin SuperHeading {
- @include ScaleFont($superHeadingFontSize, $superHeadingLineHeight);
- font-weight: $mainFontWeight;
- font-family: $mainFont;
- letter-spacing: $mainFontSpacing;
-
- @include DebugText(orange);
-}
-
-@mixin ButtonText {
- @include ScaleFont($buttonFontSize, $buttonLineHeight);
- font-weight: $mainFontWeight;
- font-family: $mainFont;
- letter-spacing: $mainFontSpacing;
- @include DebugText(purple);
-}
-
-@function str-split($string, $separator) {
- // empty array/list
- $split-arr: ();
- // first index of separator in string
- $index: str-index($string, $separator);
- // loop through string
- @while $index != null {
- // get the substring from the first character to the separator
- $item: str-slice($string, 1, $index - 1);
- // push item to array
- $split-arr: append($split-arr, $item);
- // remove item and separator from string
- $string: str-slice($string, $index + 1);
- // find new index of separator
- $index: str-index($string, $separator);
- }
- // add the remaining string to list (the last item)
- $split-arr: append($split-arr, $string);
-
- @return $split-arr;
-}
-
-@function _first-index($string, $direction: "left") {
- @for $i from 1 through str-length($string) {
- $index: if($direction == "left", $i, -$i);
-
- @if str-slice($string, $index, $index) != " " {
- @return $index;
- }
- }
-
- @return 0;
-}
-
-@function trim($string) {
- @return str-slice($string, _first-index($string, "left"), _first-index($string, "right"));
-}
+$globalBorderRadius: 0.6rem;
+
+// Font sizes and line heights
+$superHeadingFontSize: 2.5rem;
+$superHeadingLineHeight: 2.4rem;
+
+$headingFontSize: 1.9rem;
+$headingLineHeight: 2.1rem;
+
+$textFontSize: 1.6rem;
+$textLineHeight: 2.1rem;
+
+$plainTextFontSize: 1.3rem;
+$plainTextLineHeight: 1.7rem;
+
+$superDuperSmallTextFontSize: 0.8rem;
+$superDuperSmallTextLineHeight: 0.9rem;
+$superSmallTextFontSize: 1rem;
+$superSmallTextLineHeight: 1.3rem;
+$buttonFontSize: 1.4rem;
+$buttonLineHeight: 1.8rem;
+
+// Main background color
+$mainBgColor: #dee1ea;
+
+// Accent colors
+
+$accentColorBright: #e1e4ed;
+$accentColorDark: #7d808a;
+$colorGreenBright: #66bb6a;
+$colorBlueBright: rgb(74, 151, 223);
+$colorRedBright: #ef5072;
+$colorOrangeBright: #ef9d50;
+$themeColor: #393747;
+$ingameHudBg: rgba(#33343b, 0.9);
+$modsColor: rgb(214, 60, 228);
+
+$darkModeGameBackground: #535866;
+$darkModeControlsBackground: darken($darkModeGameBackground, 5);
+
+// Dialog properties
+$modalDialogBg: rgba(160, 165, 180, 0.8);
+$dialogBgColor: lighten($mainBgColor, 10);
+
+// Poppins 500
+// Rubik 400
+// Cairo 400
+// Viga 400
+// Sniglet 400
+
+$mainFont: "GameFont", sans-serif;
+// $mainFont: "DK Canoodle";
+// $mainFont: "MADE Florence Sans";
+
+@mixin DebugText($color) {
+ // font-size: 3px;
+ // &,
+ // * {
+ // color: $color !important;
+ // }
+}
+
+@mixin SuperDuperSmallText {
+ font-size: $superDuperSmallTextFontSize;
+ line-height: $superDuperSmallTextLineHeight;
+ @include DebugText(green);
+}
+
+@mixin SuperSmallText {
+ font-size: $superSmallTextFontSize;
+ line-height: $superSmallTextLineHeight;
+ @include DebugText(green);
+}
+
+@mixin PlainText {
+ font-size: $plainTextFontSize;
+ line-height: $plainTextLineHeight;
+ @include DebugText(red);
+}
+
+@mixin Text {
+ font-size: $textFontSize;
+ line-height: $textLineHeight;
+ @include DebugText(blue);
+}
+
+@mixin Heading {
+ font-size: $headingFontSize;
+ line-height: $headingLineHeight;
+ @include DebugText(yellow);
+}
+
+@mixin SuperHeading {
+ font-size: $superHeadingFontSize;
+ line-height: $superHeadingLineHeight;
+ @include DebugText(orange);
+}
+
+@mixin ButtonText {
+ font-size: $buttonFontSize;
+ line-height: $buttonLineHeight;
+ @include DebugText(purple);
+}
diff --git a/src/html/index.html b/src/html/index.html
index ab32169c..88ec6b32 100644
--- a/src/html/index.html
+++ b/src/html/index.html
@@ -1,46 +1,25 @@
-
-
+
+
- shapez Demo - Factory Automation Game
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
-
-
+
+ _
+
+
+
+
+
+
+
diff --git a/src/html/index.standalone.html b/src/html/index.standalone.html
deleted file mode 100644
index 9209c2fc..00000000
--- a/src/html/index.standalone.html
+++ /dev/null
@@ -1,22 +0,0 @@
-
-
-
- shapez
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/js/.gitignore b/src/js/.gitignore
deleted file mode 100644
index d71c2f1e..00000000
--- a/src/js/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-built-temp
diff --git a/src/js/application.js b/src/js/application.js
index d31e6e3f..088020e9 100644
--- a/src/js/application.js
+++ b/src/js/application.js
@@ -1,440 +1,345 @@
-import { AnimationFrame } from "./core/animation_frame";
-import { BackgroundResourcesLoader } from "./core/background_resources_loader";
-import { IS_MOBILE } from "./core/config";
-import { GameState } from "./core/game_state";
-import { GLOBAL_APP, setGlobalApp } from "./core/globals";
-import { InputDistributor } from "./core/input_distributor";
-import { Loader } from "./core/loader";
-import { createLogger, logSection } from "./core/logging";
-import { StateManager } from "./core/state_manager";
-import { TrackedState } from "./core/tracked_state";
-import { getPlatformName, waitNextFrame } from "./core/utils";
-import { Vector } from "./core/vector";
-import { AdProviderInterface } from "./platform/ad_provider";
-import { NoAdProvider } from "./platform/ad_providers/no_ad_provider";
-import { NoAchievementProvider } from "./platform/browser/no_achievement_provider";
-import { AnalyticsInterface } from "./platform/analytics";
-import { GoogleAnalyticsImpl } from "./platform/browser/google_analytics";
-import { SoundImplBrowser } from "./platform/browser/sound";
-import { PlatformWrapperImplBrowser } from "./platform/browser/wrapper";
-import { PlatformWrapperImplElectron } from "./platform/electron/wrapper";
-import { PlatformWrapperInterface } from "./platform/wrapper";
-import { ApplicationSettings } from "./profile/application_settings";
-import { SavegameManager } from "./savegame/savegame_manager";
-import { AboutState } from "./states/about";
-import { ChangelogState } from "./states/changelog";
-import { InGameState } from "./states/ingame";
-import { KeybindingsState } from "./states/keybindings";
-import { MainMenuState } from "./states/main_menu";
-import { MobileWarningState } from "./states/mobile_warning";
-import { PreloadState } from "./states/preload";
-import { SettingsState } from "./states/settings";
-import { ShapezGameAnalytics } from "./platform/browser/game_analytics";
-import { RestrictionManager } from "./core/restriction_manager";
-import { PuzzleMenuState } from "./states/puzzle_menu";
-import { ClientAPI } from "./platform/api";
-import { LoginState } from "./states/login";
-import { WegameSplashState } from "./states/wegame_splash";
-import { MODS } from "./mods/modloader";
-import { MOD_SIGNALS } from "./mods/mod_signals";
-import { ModsState } from "./states/mods";
-
-/**
- * @typedef {import("./platform/achievement_provider").AchievementProviderInterface} AchievementProviderInterface
- * @typedef {import("./platform/sound").SoundInterface} SoundInterface
- * @typedef {import("./platform/storage").StorageInterface} StorageInterface
- */
-
-const logger = createLogger("application");
-
-// Set the name of the hidden property and the change event for visibility
-let pageHiddenPropName, pageVisibilityEventName;
-if (typeof document.hidden !== "undefined") {
- // Opera 12.10 and Firefox 18 and later support
- pageHiddenPropName = "hidden";
- pageVisibilityEventName = "visibilitychange";
- // @ts-ignore
-} else if (typeof document.msHidden !== "undefined") {
- pageHiddenPropName = "msHidden";
- pageVisibilityEventName = "msvisibilitychange";
- // @ts-ignore
-} else if (typeof document.webkitHidden !== "undefined") {
- pageHiddenPropName = "webkitHidden";
- pageVisibilityEventName = "webkitvisibilitychange";
-}
-
-export class Application {
- /**
- * Boots the application
- */
- async boot() {
- console.log("Booting ...");
-
- assert(!GLOBAL_APP, "Tried to construct application twice");
- logger.log("Creating application, platform =", getPlatformName());
- setGlobalApp(this);
- MODS.app = this;
-
- // MODS
-
- try {
- await MODS.initMods();
- } catch (ex) {
- alert("Failed to load mods (launch with --dev for more info): \n\n" + ex);
- }
-
- this.unloaded = false;
-
- // Global stuff
- this.settings = new ApplicationSettings(this);
- this.ticker = new AnimationFrame();
- this.stateMgr = new StateManager(this);
- this.savegameMgr = new SavegameManager(this);
- this.inputMgr = new InputDistributor(this);
- this.backgroundResourceLoader = new BackgroundResourcesLoader(this);
- this.clientApi = new ClientAPI(this);
-
- // Restrictions (Like demo etc)
- this.restrictionMgr = new RestrictionManager(this);
-
- // Platform dependent stuff
-
- /** @type {StorageInterface} */
- this.storage = null;
-
- /** @type {SoundInterface} */
- this.sound = null;
-
- /** @type {PlatformWrapperInterface} */
- this.platformWrapper = null;
-
- /** @type {AchievementProviderInterface} */
- this.achievementProvider = null;
-
- /** @type {AdProviderInterface} */
- this.adProvider = null;
-
- /** @type {AnalyticsInterface} */
- this.analytics = null;
-
- /** @type {ShapezGameAnalytics} */
- this.gameAnalytics = null;
-
- this.initPlatformDependentInstances();
-
- // Track if the window is focused (only relevant for browser)
- this.focused = true;
-
- // Track if the window is visible
- this.pageVisible = true;
-
- // Track if the app is paused (cordova)
- this.applicationPaused = false;
-
- /** @type {TypedTrackedState} */
- this.trackedIsRenderable = new TrackedState(this.onAppRenderableStateChanged, this);
-
- /** @type {TypedTrackedState} */
- this.trackedIsPlaying = new TrackedState(this.onAppPlayingStateChanged, this);
-
- // Dimensions
- this.screenWidth = 0;
- this.screenHeight = 0;
-
- // Store the timestamp where we last checked for a screen resize, since orientationchange is unreliable with cordova
- this.lastResizeCheck = null;
-
- // Store the mouse position, or null if not available
- /** @type {Vector|null} */
- this.mousePosition = null;
-
- this.registerStates();
- this.registerEventListeners();
-
- Loader.linkAppAfterBoot(this);
-
- if (G_WEGAME_VERSION) {
- this.stateMgr.moveToState("WegameSplashState");
- }
-
- // Check for mobile
- else if (IS_MOBILE) {
- this.stateMgr.moveToState("MobileWarningState");
- } else {
- this.stateMgr.moveToState("PreloadState");
- }
-
- // Starting rendering
- this.ticker.frameEmitted.add(this.onFrameEmitted, this);
- this.ticker.bgFrameEmitted.add(this.onBackgroundFrame, this);
- this.ticker.start();
-
- window.focus();
-
- MOD_SIGNALS.appBooted.dispatch();
- }
-
- /**
- * Initializes all platform instances
- */
- initPlatformDependentInstances() {
- logger.log("Creating platform dependent instances (standalone=", G_IS_STANDALONE, ")");
-
- if (G_IS_STANDALONE) {
- this.platformWrapper = new PlatformWrapperImplElectron(this);
- } else {
- this.platformWrapper = new PlatformWrapperImplBrowser(this);
- }
-
- // Start with empty ad provider
- this.adProvider = new NoAdProvider(this);
- this.sound = new SoundImplBrowser(this);
- this.analytics = new GoogleAnalyticsImpl(this);
- this.gameAnalytics = new ShapezGameAnalytics(this);
- this.achievementProvider = new NoAchievementProvider(this);
- }
-
- /**
- * Registers all game states
- */
- registerStates() {
- /** @type {Array} */
- const states = [
- WegameSplashState,
- PreloadState,
- MobileWarningState,
- MainMenuState,
- InGameState,
- SettingsState,
- KeybindingsState,
- AboutState,
- ChangelogState,
- PuzzleMenuState,
- LoginState,
- ModsState,
- ];
-
- for (let i = 0; i < states.length; ++i) {
- this.stateMgr.register(states[i]);
- }
- }
-
- /**
- * Registers all event listeners
- */
- registerEventListeners() {
- window.addEventListener("focus", this.onFocus.bind(this));
- window.addEventListener("blur", this.onBlur.bind(this));
-
- window.addEventListener("resize", () => this.checkResize(), true);
- window.addEventListener("orientationchange", () => this.checkResize(), true);
-
- window.addEventListener("mousemove", this.handleMousemove.bind(this));
- window.addEventListener("mouseout", this.handleMousemove.bind(this));
- window.addEventListener("mouseover", this.handleMousemove.bind(this));
- window.addEventListener("mouseleave", this.handleMousemove.bind(this));
-
- // Unload events
- window.addEventListener("beforeunload", this.onBeforeUnload.bind(this), true);
-
- document.addEventListener(pageVisibilityEventName, this.handleVisibilityChange.bind(this), false);
-
- // Track touches so we can update the focus appropriately
- document.addEventListener("touchstart", this.updateFocusAfterUserInteraction.bind(this), true);
- document.addEventListener("touchend", this.updateFocusAfterUserInteraction.bind(this), true);
- }
-
- /**
- * Checks the focus after a touch
- * @param {TouchEvent} event
- */
- updateFocusAfterUserInteraction(event) {
- const target = /** @type {HTMLElement} */ (event.target);
- if (!target || !target.tagName) {
- // Safety check
- logger.warn("Invalid touchstart/touchend event:", event);
- return;
- }
-
- // When clicking an element which is not the currently focused one, defocus it
- if (target !== document.activeElement) {
- // @ts-ignore
- if (document.activeElement.blur) {
- // @ts-ignore
- document.activeElement.blur();
- }
- }
-
- // If we click an input field, focus it now
- if (target.tagName.toLowerCase() === "input") {
- // We *really* need the focus
- waitNextFrame().then(() => target.focus());
- }
- }
-
- /**
- * Handles a page visibility change event
- * @param {Event} event
- */
- handleVisibilityChange(event) {
- window.focus();
- const pageVisible = !document[pageHiddenPropName];
- if (pageVisible !== this.pageVisible) {
- this.pageVisible = pageVisible;
- logger.log("Visibility changed:", this.pageVisible);
- this.trackedIsRenderable.set(this.isRenderable());
- }
- }
-
- /**
- * Handles a mouse move event
- * @param {MouseEvent} event
- */
- handleMousemove(event) {
- this.mousePosition = new Vector(event.clientX, event.clientY);
- }
-
- /**
- * Internal on focus handler
- */
- onFocus() {
- this.focused = true;
- }
-
- /**
- * Internal blur handler
- */
- onBlur() {
- this.focused = false;
- }
-
- /**
- * Returns if the app is currently visible
- */
- isRenderable() {
- return !this.applicationPaused && this.pageVisible;
- }
-
- onAppRenderableStateChanged(renderable) {
- logger.log("Application renderable:", renderable);
- window.focus();
- const currentState = this.stateMgr.getCurrentState();
- if (!renderable) {
- if (currentState) {
- currentState.onAppPause();
- }
- } else {
- if (currentState) {
- currentState.onAppResume();
- }
- this.checkResize();
- }
-
- this.sound.onPageRenderableStateChanged(renderable);
- }
-
- onAppPlayingStateChanged(playing) {
- try {
- this.adProvider.setPlayStatus(playing);
- } catch (ex) {
- console.warn("Play status changed");
- }
- }
-
- /**
- * Internal before-unload handler
- */
- onBeforeUnload(event) {
- logSection("BEFORE UNLOAD HANDLER", "#f77");
- const currentState = this.stateMgr.getCurrentState();
-
- if (!G_IS_DEV && currentState && currentState.getHasUnloadConfirmation()) {
- if (!G_IS_STANDALONE) {
- // Need to show a "Are you sure you want to exit"
- event.preventDefault();
- event.returnValue = "Are you sure you want to exit?";
- }
- }
- }
-
- /**
- * Deinitializes the application
- */
- deinitialize() {
- return this.sound.deinitialize();
- }
-
- /**
- * Background frame update callback
- * @param {number} dt
- */
- onBackgroundFrame(dt) {
- if (this.isRenderable()) {
- return;
- }
-
- const currentState = this.stateMgr.getCurrentState();
- if (currentState) {
- currentState.onBackgroundTick(dt);
- }
- }
-
- /**
- * Frame update callback
- * @param {number} dt
- */
- onFrameEmitted(dt) {
- if (!this.isRenderable()) {
- return;
- }
-
- const time = performance.now();
-
- // Periodically check for resizes, this is expensive (takes 2-3ms so only do it once in a while!)
- if (!this.lastResizeCheck || time - this.lastResizeCheck > 1000) {
- this.checkResize();
- this.lastResizeCheck = time;
- }
-
- const currentState = this.stateMgr.getCurrentState();
- this.trackedIsPlaying.set(currentState && currentState.getIsIngame());
- if (currentState) {
- currentState.onRender(dt);
- }
- }
-
- /**
- * Checks if the app resized. Only does this once in a while
- * @param {boolean} forceUpdate Forced update of the dimensions
- */
- checkResize(forceUpdate = false) {
- const w = window.innerWidth;
- const h = window.innerHeight;
- if (this.screenWidth !== w || this.screenHeight !== h || forceUpdate) {
- this.screenWidth = w;
- this.screenHeight = h;
- const currentState = this.stateMgr.getCurrentState();
- if (currentState) {
- currentState.onResized(this.screenWidth, this.screenHeight);
- }
-
- const scale = this.getEffectiveUiScale();
- waitNextFrame().then(() => document.documentElement.style.setProperty("--ui-scale", `${scale}`));
- window.focus();
- }
- }
-
- /**
- * Returns the effective ui sclae
- */
- getEffectiveUiScale() {
- return this.platformWrapper.getUiScale() * this.settings.getInterfaceScaleValue();
- }
-
- /**
- * Callback after ui scale has changed
- */
- updateAfterUiScaleChanged() {
- this.checkResize(true);
- }
-}
+import { AnimationFrame } from "./core/animation_frame";
+import { BackgroundResourcesLoader } from "./core/background_resources_loader";
+import { ErrorHandler } from "./core/error_handler";
+import { GameState } from "./core/game_state";
+import { setGlobalApp } from "./core/globals";
+import { InputDistributor } from "./core/input_distributor";
+import { Loader } from "./core/loader";
+import { createLogger } from "./core/logging";
+import { StateManager } from "./core/state_manager";
+import { TrackedState } from "./core/tracked_state";
+import { getPlatformName, round2Digits, waitNextFrame } from "./core/utils";
+import { Vector } from "./core/vector";
+import { MOD_SIGNALS } from "./mods/mod_signals";
+import { MODS } from "./mods/modloader";
+import { ClientAPI } from "./platform/api";
+import { Sound } from "./platform/sound";
+import { Storage, STORAGE_SAVES } from "./platform/storage";
+import { PlatformWrapperImplElectron } from "./platform/wrapper";
+import { ApplicationSettings } from "./profile/application_settings";
+import { SavegameManager } from "./savegame/savegame_manager";
+import { AboutState } from "./states/about";
+import { ChangelogState } from "./states/changelog";
+import { InGameState } from "./states/ingame";
+import { KeybindingsState } from "./states/keybindings";
+import { LoginState } from "./states/login";
+import { MainMenuState } from "./states/main_menu";
+import { ModsState } from "./states/mods";
+import { PreloadState } from "./states/preload";
+import { PuzzleMenuState } from "./states/puzzle_menu";
+import { SettingsState } from "./states/settings";
+
+/**
+ * @typedef {import("./platform/sound").SoundInterface} SoundInterface
+ */
+
+const logger = createLogger("application");
+
+export class Application {
+ /**
+ * Boots the application
+ */
+ async boot() {
+ console.log("Booting ...");
+
+ this.errorHandler = new ErrorHandler();
+
+ logger.log("Creating application, platform =", getPlatformName());
+ setGlobalApp(this);
+
+ // MODS
+
+ try {
+ await MODS.initMods();
+ } catch (ex) {
+ throw new Error("Failed to initialize mods", { cause: ex });
+ }
+
+ this.unloaded = false;
+
+ // Platform stuff
+ this.storage = new Storage(this, STORAGE_SAVES);
+ await this.storage.initialize();
+
+ this.platformWrapper = new PlatformWrapperImplElectron(this);
+
+ // Global stuff
+ this.settings = new ApplicationSettings(this, this.storage);
+ this.ticker = new AnimationFrame();
+ this.stateMgr = new StateManager(this);
+ // NOTE: SavegameManager uses the passed storage, but savegames always
+ // use Application#storage
+ this.savegameMgr = new SavegameManager(this, this.storage);
+ this.inputMgr = new InputDistributor(this);
+ this.backgroundResourceLoader = new BackgroundResourcesLoader(this);
+ this.clientApi = new ClientAPI(this);
+
+ this.sound = new Sound(this);
+
+ // Track if the window is focused (only relevant for browser)
+ this.focused = true;
+
+ // Track if the window is visible
+ this.pageVisible = true;
+
+ /** @type {TypedTrackedState} */
+ this.trackedIsRenderable = new TrackedState(this.onAppRenderableStateChanged, this);
+
+ /** @type {TypedTrackedState} */
+ this.trackedIsPlaying = new TrackedState(this.onAppPlayingStateChanged, this);
+
+ // Dimensions
+ this.screenWidth = 0;
+ this.screenHeight = 0;
+
+ // Store the timestamp where we last checked for a screen resize, since orientationchange is unreliable with cordova
+ this.lastResizeCheck = null;
+
+ // Store the mouse position, or null if not available
+ /** @type {Vector|null} */
+ this.mousePosition = null;
+
+ this.registerStates();
+ this.registerEventListeners();
+
+ Loader.linkAppAfterBoot(this);
+
+ this.stateMgr.moveToState("PreloadState");
+
+ // Starting rendering
+ this.ticker.frameEmitted.add(this.onFrameEmitted, this);
+ this.ticker.bgFrameEmitted.add(this.onBackgroundFrame, this);
+ this.ticker.start();
+
+ window.focus();
+
+ MOD_SIGNALS.appBooted.dispatch();
+ }
+
+ /**
+ * Registers all game states
+ */
+ registerStates() {
+ /** @type {Array} */
+ const states = [
+ PreloadState,
+ MainMenuState,
+ InGameState,
+ SettingsState,
+ KeybindingsState,
+ AboutState,
+ ChangelogState,
+ PuzzleMenuState,
+ LoginState,
+ ModsState,
+ ];
+
+ for (let i = 0; i < states.length; ++i) {
+ this.stateMgr.register(states[i]);
+ }
+ }
+
+ /**
+ * Registers all event listeners
+ */
+ registerEventListeners() {
+ window.addEventListener("focus", this.onFocus.bind(this));
+ window.addEventListener("blur", this.onBlur.bind(this));
+
+ window.addEventListener("resize", () => this.checkResize(), true);
+ window.addEventListener("orientationchange", () => this.checkResize(), true);
+
+ window.addEventListener("mousemove", this.handleMousemove.bind(this));
+ window.addEventListener("mouseout", this.handleMousemove.bind(this));
+ window.addEventListener("mouseover", this.handleMousemove.bind(this));
+ window.addEventListener("mouseleave", this.handleMousemove.bind(this));
+
+ // Unload events
+ window.addEventListener("beforeunload", this.onBeforeUnload.bind(this), true);
+
+ document.addEventListener("visibilitychange", this.handleVisibilityChange.bind(this), false);
+
+ // Track touches so we can update the focus appropriately
+ document.addEventListener("touchstart", this.updateFocusAfterUserInteraction.bind(this), true);
+ document.addEventListener("touchend", this.updateFocusAfterUserInteraction.bind(this), true);
+ }
+
+ /**
+ * Checks the focus after a touch
+ * @param {TouchEvent} event
+ */
+ updateFocusAfterUserInteraction(event) {
+ const target = /** @type {HTMLElement} */ (event.target);
+ if (!target || !target.tagName) {
+ // Safety check
+ logger.warn("Invalid touchstart/touchend event:", event);
+ return;
+ }
+
+ // When clicking an element which is not the currently focused one, defocus it
+ if (target !== document.activeElement) {
+ // @ts-ignore
+ if (document.activeElement.blur) {
+ // @ts-ignore
+ document.activeElement.blur();
+ }
+ }
+
+ // If we click an input field, focus it now
+ if (target.tagName.toLowerCase() === "input") {
+ // We *really* need the focus
+ waitNextFrame().then(() => target.focus());
+ }
+ }
+
+ /**
+ * Handles a page visibility change event
+ * @param {Event} event
+ */
+ handleVisibilityChange(event) {
+ window.focus();
+ const pageVisible = !document.hidden;
+ if (pageVisible !== this.pageVisible) {
+ this.pageVisible = pageVisible;
+ logger.log("Visibility changed:", this.pageVisible);
+ this.trackedIsRenderable.set(this.isRenderable());
+ }
+ }
+
+ /**
+ * Handles a mouse move event
+ * @param {MouseEvent} event
+ */
+ handleMousemove(event) {
+ this.mousePosition = new Vector(event.clientX, event.clientY);
+ }
+
+ /**
+ * Internal on focus handler
+ */
+ onFocus() {
+ this.focused = true;
+ }
+
+ /**
+ * Internal blur handler
+ */
+ onBlur() {
+ this.focused = false;
+ }
+
+ /**
+ * Returns if the app is currently visible
+ */
+ isRenderable() {
+ return this.pageVisible;
+ }
+
+ onAppRenderableStateChanged(renderable) {
+ logger.log("Application renderable:", renderable);
+ window.focus();
+ const currentState = this.stateMgr.getCurrentState();
+ if (!renderable) {
+ if (currentState) {
+ currentState.onAppPause();
+ }
+ } else {
+ if (currentState) {
+ currentState.onAppResume();
+ }
+ this.checkResize();
+ }
+
+ this.sound.onPageRenderableStateChanged(renderable);
+ }
+
+ onAppPlayingStateChanged(playing) {
+ // TODO: Check for usages and alternatives. This can be turned into a singal.
+ }
+
+ /**
+ * Internal before-unload handler
+ */
+ onBeforeUnload(event) {}
+
+ /**
+ * Deinitializes the application
+ */
+ deinitialize() {
+ return this.sound.deinitialize();
+ }
+
+ /**
+ * Background frame update callback
+ * @param {number} dt
+ */
+ onBackgroundFrame(dt) {
+ if (this.isRenderable()) {
+ return;
+ }
+
+ const currentState = this.stateMgr.getCurrentState();
+ if (currentState) {
+ currentState.onBackgroundTick(dt);
+ }
+ }
+
+ /**
+ * Frame update callback
+ * @param {number} dt
+ */
+ onFrameEmitted(dt) {
+ if (!this.isRenderable()) {
+ return;
+ }
+
+ const time = performance.now();
+
+ // Periodically check for resizes, this is expensive (takes 2-3ms so only do it once in a while!)
+ if (!this.lastResizeCheck || time - this.lastResizeCheck > 1000) {
+ this.checkResize();
+ this.lastResizeCheck = time;
+ }
+
+ const currentState = this.stateMgr.getCurrentState();
+ this.trackedIsPlaying.set(currentState && currentState.getIsIngame());
+ if (currentState) {
+ currentState.onRender(dt);
+ }
+ }
+
+ /**
+ * Checks if the app resized. Only does this once in a while
+ * @param {boolean} forceUpdate Forced update of the dimensions
+ */
+ checkResize(forceUpdate = false) {
+ const w = window.innerWidth;
+ const h = window.innerHeight;
+ if (this.screenWidth !== w || this.screenHeight !== h || forceUpdate) {
+ this.screenWidth = w;
+ this.screenHeight = h;
+ const currentState = this.stateMgr.getCurrentState();
+ if (currentState) {
+ currentState.onResized(this.screenWidth, this.screenHeight);
+ }
+
+ const scale = this.getEffectiveUiScale();
+ document.documentElement.style.fontSize = `${round2Digits(scale * 10)}px`;
+ window.focus();
+ }
+ }
+
+ /**
+ * Returns the effective ui sclae
+ */
+ getEffectiveUiScale() {
+ return this.platformWrapper.getUiScale() * this.settings.getInterfaceScaleValue();
+ }
+
+ /**
+ * Callback after ui scale has changed
+ */
+ updateAfterUiScaleChanged() {
+ this.checkResize(true);
+ }
+}
diff --git a/src/js/changelog.js b/src/js/changelog.js
index de7cd029..a80a2047 100644
--- a/src/js/changelog.js
+++ b/src/js/changelog.js
@@ -1,443 +1,423 @@
-export const CHANGELOG = [
- {
- version: "1.5.6",
- date: "09.12.2022",
- entries: [
- "⚠️ We are currently prototyping Shapez 2! Click here to find out more. ⚠️ ",
- "Minor fixes & improvements",
- "Updated translations",
- ],
- },
- {
- version: "1.5.5",
- date: "20.06.2022",
- entries: [
- "You can now play the full version in your browser! Click here to read all details.",
- "Reworked the tutorial to be simpler and more interactive",
- "General polishing",
- "Fix being unable to delete savegame when the savegame file was deleted externally",
- "New sfx when unlocking upgrades",
- "Updated translations",
- ],
- },
- {
- version: "1.5.3",
- date: "05.06.2022",
- entries: [
- "Fixed buildings not being lockable in the Puzzle DLC Editor",
- "Fixed issues launching the game with proton",
- "Updated translations",
- ],
- },
- {
- version: "1.5.2",
- date: "02.06.2022",
- entries: [
- "Attempted to fix the 'vram glitch', where the map background would not redraw anymore, especially in fullscreen. If the issue still persists, please let me know in the discord server!",
- "The game has been renamed from 'shapez.io' to 'shapez', since it is not really an .io game",
- "Various performance improvements",
- "Upgrades should now show the full precision",
- "UI Polishing & Cleanup",
- "Updated translations",
- "PS: We are already working on shapez 2, more information will follow in the discord soon!",
- ],
- },
- {
- version: "1.5.1",
- date: "25.02.2022",
- entries: [
- "This version adds an official modloader! You can now load mods by extracting them and placing the .js file in the mods/ folder of the game.",
- "Mods can be found here ",
- "When holding shift while placing a belt, the indicator now becomes red when crossing buildings",
- "Lots of performance improvements, leading to up to 50% more FPS",
- ],
- },
- {
- version: "1.4.4",
- date: "29.08.2021",
- entries: [
- "Hotfix: Fixed the balancer not distributing items evenly, caused by the 1.4.3 update. Sorry for any inconveniences!",
- ],
- },
- {
- version: "1.4.3",
- date: "28.08.2021",
- entries: [
- "You can now hold 'ALT' while hovering a building to see its output! (Thanks to Sense101) (PS: There is now a setting to have it always on!)",
- "The map overview should now be much more performant! As a consequence, you can now zoom out farther! (Thanks to PFedak)",
- "Puzzle DLC: There is now a 'next puzzle' button!",
- "Puzzle DLC: There is now a search function!",
- "Edit signal dialog now has the previous signal filled (Thanks to EmeraldBlock)",
- "Further performance improvements (Thanks to PFedak)",
- "Improved puzzle validation (Thanks to Sense101)",
- "Input fields in dialogs should now automatically focus",
- "Fix selected building being deselected at level up (Thanks to EmeraldBlock)",
- "Updated translations",
- ],
- },
- {
- version: "1.4.2",
- date: "24.06.2021",
- entries: [
- "Puzzle DLC: Goal acceptors now reset after getting no items for a while (This should prevent being able to 'cheat' puzzles) (by Sense101)",
- "Puzzle DLC: Added button to clear all buildings / reset the puzzle (by Sense101)",
- "Puzzle DLC: Allow copy-paste in puzzle mode (by Sense101)",
- "Fixed level achievements being given on the wrong level (by DJ1TJOO)",
- "Fixed blueprint not properly clearing on right click",
- "Updated translations",
- ],
- },
- {
- version: "1.4.1",
- date: "22.06.2021",
- entries: [
- "The Puzzle DLC is now available on Steam!",
- "The Soundtrack is now also available to wishlist and will be released within the next days, including the new music from the Puzzle DLC!",
- ],
- },
- {
- version: "1.4.0",
- date: "04.06.2021",
- entries: [
- "Belts in blueprints should now always paste correctly",
- "You can now clear belts by selecting them and then pressing 'B'",
- "Preparations for the Puzzle DLC , coming June 22nd!",
- ],
- },
- {
- version: "1.3.1",
- date: "16.04.2021",
- entries: G_CHINA_VERSION
- ? [
- "第13关的交付目标更改为:中国古代指南针。(感谢玩家:凯风入心 创作并提供",
- "第17关的交付目标更改为:永乐通宝。(感谢玩家:金天赐 创作并提供",
- "第22关的交付目标更改为:凤凰。(感谢玩家:我没得眼镜 创作并提供",
- "第23关的交付目标更改为:古代车轮。(感谢玩家:我没得眼镜 创作并提供",
- "第24关的交付目标更改为:大熊猫。(感谢玩家:窝囸倪现任 创作并提供",
-
- "修复了一些特定情况下偶尔会发生的存档损坏问题",
- "修复了成就更新后有时候游戏崩溃的问题",
- ]
- : [
- "Fixed savegames getting corrupt in rare conditions",
- "Fixed game crashing sometimes since the achievements update",
- ],
- },
- {
- version: "1.3.0",
- date: "12.03.2020",
- skin: "achievements",
- entries: [
- "There are now 45 Steam Achievements! ",
- "Fixed constant signals being editable from the regular layer",
- "Fixed items still overlapping sometimes between buildings and belts",
- "The game is now available in finnish, italian, romanian and ukrainian! (Thanks to all contributors!)",
- "Updated translations (Thanks to all contributors!)",
- ],
- },
- {
- version: "1.2.2",
- date: "07.12.2020",
- entries: [
- "Fix item readers and some other buildings slowing up belts, especially if they stalled (inspired by Keterr's fix)",
- "Added the ability to edit constant signals by left clicking them",
- "Prevent items from being rendered on each other when a belt stalls (inspired by Keterr)",
- "You can now add markers in the wire layer (partially by daanbreur)",
- "Allow to cycle backwards in the toolbar with SHIFT + Tab (idea by EmeraldBlock)",
- "Allow to cycle variants backwards with SHIFT + T",
- "Upgrade numbers now use roman numerals until tier 50 (by LeopoldTal)",
- "Add button to unpin shapes from the left side (by artemisSystem)",
- "Fix middle mouse button also placing blueprints (by Eiim)",
- "Hide wires grid when using the 'Disable Grid' setting (by EmeraldBlock)",
- "Fix UI using multiple different save icons",
- "Updated translations (Thanks to all contributors!)",
- ],
- },
- {
- version: "1.2.1",
- date: "31.10.2020",
- entries: [
- "Fixed stacking bug for level 26 which required restarting the game",
- "Fix reward notification being too long sometimes (by LeopoldTal)",
- "Use locale decimal separator on belt reader display (by LeopoldTal)",
- "Vastly improved performance when saving games (by LeopoldTal)",
- "Prevent some antivirus programs blocking the opening of external links (by LeopoldTal)",
- "Match tutorials to the correct painter variants (by LeopoldTal)",
- "Prevent throughput goals containing fractional numbers (by CEbbinghaus)",
- "Updated translations and added Hungarian",
- ],
- },
- {
- version: "1.2.0",
- date: "09.10.2020",
- entries: [
- "⚠️⚠️This update is HUGE, view the full changelog here ! ⚠️⚠️",
- ],
- },
- {
- version: "1.1.18",
- date: "27.06.2020",
- entries: [
- "Huge performance improvements - up to double fps and tick-rate! This will wipe out all current items on belts.",
- "Reduce story shapes required until unlocking blueprints",
- "Allow clicking on variants to select them",
- "Add 'copy key' button to shape viewer",
- "Add more FPS to the belt animation and fix belt animation seeming to go 'backwards' on high belt speeds",
- "Fix deconstruct sound being played when right clicking hub",
- "Allow clicking 'Q' over a shape or color patch to automatically select the miner building (by Gerdon262)",
- "Update belt placement performance on huge factories (by Phlosioneer)",
- "Fix duplicate waypoints with a shape not rendering (by hexy)",
- "Fix smart tunnel placement deleting wrong tunnels (by mordof)",
- "Add setting (on by default) to store the last used rotation per building instead of globally storing it (by Magos)",
- "Added chinese (traditional) translation",
- "Updated translations",
- ],
- },
- {
- version: "1.1.17",
- date: "22.06.2020",
- entries: [
- "Color blind mode! You can now activate it in the settings and it will show you which color is below your cursor (Either resource or on the belt)",
- "Add info buttons to all shapes so you can figure out how they are built! (And also, which colors they have)",
- "Allow configuring autosave interval and disabling it in the settings",
- "The smart-tunnel placement has been reworked to properly replace belts. Thus the setting has been turned on again by default",
- "The soundtrack now has a higher quality on the standalone version than the web version",
- "Add setting to disable cut/delete warnings (by hexy)",
- "Fix bug where belts in blueprints don't orient correctly (by hexy)",
- "Fix camera moving weird after dragging and holding (by hexy)",
- "Fix keybinding for pipette showing while pasting blueprints",
- "Improve visibility of shape background in dark mode",
- "Added sound when destroying a building",
- "Added swedish translation",
- "Update tutorial image for tier 2 tunnels to explain mix/match (by jimmyshadow1)",
- ],
- },
- {
- version: "1.1.16",
- date: "21.06.2020",
- entries: [
- "You can now pickup buildings below your cursor with 'Q'!",
- "The game soundtrack has been extended! There are now 4 songs with over 13 minutes of playtime from Peppsen !",
- "Refactor keybindings overlay to show more appropriate keybindings",
- "Show keybindings for area-select in the upper left instead",
- "Automatically deselect area when selecting a new building",
- "Raise markers limit from 14 characters to 71 (by Joker-vD)",
- "Optimize performance by caching extractor items (by Phlosioneer)",
- "Added setting to enable compact building infos, which only show ratios and hide the image / description",
- "Apply dark theme to menu as well (by dengr1065)",
- "Fix belt planner not placing the last belt",
- "Fix buildings getting deleted when right clicking while placing a blueprint",
- "Fix for exporting screenshots for huge bases (It was showing an empty file) (by xSparfuchs)",
- "Fix buttons not responding when using right click directly after left click (by davidburhans)",
- "Fix hub marker being hidden by building info panel",
- "Disable dialog background blur since it can cause performance issues",
- "Added simplified chinese translations",
- "Update translations (Thanks to all translators!)",
- ],
- },
- {
- version: "1.1.15",
- date: "17.06.2020",
- entries: [
- "You can now place straight belts (and tunnels) by holding SHIFT! (For you, @giantwaffle ❤️)",
- "Added continue button to main menu and add separate 'New game' button (by jaysc)",
- "Added setting to disable smart tunnel placement introduced with the last update",
- "Added setting to disable vignette",
- "Update translations",
- ],
- },
- {
- version: "1.1.14",
- date: "16.06.2020",
- entries: [
- "There is now an indicator (compass) to the HUB for the HUB Marker!",
- "You can now include shape short keys in markers to render shape icons instead of text!",
- "Added mirrored variant of the painter",
- "When placing tunnels, unnecessary belts inbetween are now removed!",
- "You can now drag tunnels and they will automatically expand! (Just try it out, its intuitive)",
- ],
- },
- {
- version: "1.1.13",
- date: "15.06.2020",
- entries: [
- "Added shift modifier for faster pan (by jaysc)",
- "Added Japanese translations",
- "Added Portuguese (Portugal) translations",
- "Updated icon for Spanish (Latin America) - It was showing a Spanish flag before",
- "Updated existing translations",
- ],
- },
- {
- version: "1.1.12",
- date: "14.06.2020",
- entries: [
- "Huge performance improvements! The game should now run up to 60% faster!",
- "Added norwegian translation",
- ],
- },
- {
- version: "1.1.11",
- date: "13.06.2020",
- entries: [
- "Pinned shapes are now smart, they dynamically update their goal and also unpin when no longer required. Completed objectives are now rendered transparent.",
- "You can now cut areas, and also paste the last blueprint again! (by hexy)",
- "You can now export your whole base as an image by pressing F3!",
- "Improve upgrade number rounding, so there are no goals like '37.4k', instead it will now be '35k'",
- "You can now configure the camera movement speed when using WASD (by mini-bomba)",
- "Selecting an area now is relative to the world and thus does not move when moving the screen (by Dimava)",
- "Allow higher tick-rates up to 500hz (This will burn your PC!)",
- "Fix bug regarding number rounding",
- "Fix dialog text being hardly readable in dark theme",
- "Fix app not starting when the savegames were corrupted - there is now a better error message as well.",
- "Further translation updates - Big thanks to all contributors!",
- ],
- },
- {
- version: "1.1.10",
- date: "12.06.2020",
- entries: [
- "There are now linux builds on steam! Please report any issues in the Discord!",
- "Steam cloud saves are now available!",
- "Added and update more translations (Big thank you to all translators!)",
- "Prevent invalid connection if existing underground tunnel entrance exists (by jaysc)",
- ],
- },
- {
- version: "1.1.9",
- date: "11.06.2020",
- entries: [
- "Support for translations! Interested in helping out? Check out the translation guide !",
- "Update stacker artwork to clarify how it works",
- "Update keybinding hints on the top left to be more accurate",
- "Make it more clear when blueprints are unlocked when trying to use them",
- "Fix pinned shape icons not being visible in dark mode",
- "Fix being able to select buildings via hotkeys in map overview mode",
- "Make shapes unpinnable in the upgrades tab (By hexy)",
- ],
- },
- {
- version: "1.1.8",
- date: "07.06.2020",
- entries: [
- "You can now purchase the standalone on steam! View steam page ",
- "Added ability to create markers in the demo, but only two.",
- "Contest #01 has ended! I'll now work through the entries, select the 5 I like most and present them to the community to vote for!",
- ],
- },
- {
- version: "1.1.7",
- date: "04.06.2020",
- entries: ["HOTFIX: Fix savegames not showing up on the standalone version"],
- },
- {
- version: "1.1.6",
- date: "04.06.2020",
- entries: [
- "The steam release will happen on the 7th of June - Be sure to add it to your wishlist! View on steam ",
- "Fixed level complete dialog being blurred when the shop was opened before",
- "Standalone: Increased icon visibility for windows builds",
- "Web version: Fixed firefox not loading the game when browsing in private mode",
- ],
- },
-
- {
- version: "1.1.5",
- date: "03.06.2020",
- entries: ["Added weekly contests!"],
- },
- {
- version: "1.1.4",
- date: "01.06.2020",
- entries: ["Add 'interactive' tutorial for the first level to improve onboarding experience"],
- },
- {
- version: "1.1.3",
- date: "01.06.2020",
- entries: [
- "Added setting to configure zoom / mouse wheel / touchpad sensitivity",
- "Fix belts being too slow when copied via blueprint (by Dimava)",
- "Allow binding mouse buttons to actions (by Dimava)",
- "Increase readability of certain HUD elements",
- ],
- },
- {
- version: "1.1.2",
- date: "30.05.2020",
- entries: [
- "The official trailer is now ready! Check it out here !",
- "The steam page is now live!",
- "Experimental linux builds are now available! Please give me feedback on them in the Discord",
- "Allow hovering pinned shapes to enlarge them",
- "Allow deselecting blueprints with right click and 'Q'",
- "Move default key for deleting from 'X' to 'DEL'",
- "Show confirmation when deleting more than 100 buildings",
- "Reintroduce 'SPACE' keybinding to center on map",
- "Improved keybinding hints",
- "Fixed some keybindings showing as 'undefined'",
- ],
- },
- {
- version: "1.1.1",
- date: "28.05.2020",
- entries: ["Fix crash when 'Show Hints' setting was turned off"],
- },
- {
- version: "1.1.0",
- date: "28.05.2020",
- entries: [
- "BLUEPRINTS! They are unlocked at level 12 and cost a special shape to build.",
- "MAP MARKERS! Press 'M' to create a waypoint and be able to jump to it",
- "Savegame levels are now shown in the main menu. For existing games, save them again to make the level show up.",
- "Allow holding SHIFT to rotate counter clockwise",
- "Added confirmation when deleting more than 500 buildings at a time",
- "Added background to toolbar to increase contrast",
- "Further decerase requirements of first levels",
- "Pinned shapes now are saved",
- "Allow placing extractors anywhere again, but they don't work at all if not placed on a resource",
- "Show dialog explaining some keybindings after completing level 4",
- "Fix keys being stuck when opening a dialog",
- "Swapped shape order for painting upgrades",
- "Allow changing all keybindings, including CTRL, ALT and SHIFT (by Dimava)",
- "Fix cycling through keybindings selecting locked buildings as well (by Dimava)",
- "There is now a github action, checking all pull requests with eslint. (by mrHedgehog)",
- ],
- },
- {
- version: "1.0.4",
- date: "26.05.2020",
- entries: [
- "Reduce cost of first painting upgrade, and change 'Shape Processing' to 'Cutting, Rotating & Stacking'",
- "Add dialog after completing level 2 to check out the upgrades tab.",
- "Allow changing the keybindings in the demo version",
- ],
- },
- {
- version: "1.0.3",
- date: "24.05.2020",
- entries: [
- "Reduced the amount of shapes required for the first 5 levels to make it easier to get into the game.",
- ],
- },
- {
- version: "1.0.2",
- date: "23.05.2020",
- entries: [
- "Introduced changelog",
- "Removed 'early access' label because the game isn't actually early access - its in a pretty good state already! (No worries, a lot more updates will follow!)",
- "Added a 'Show hint' button which shows a small video for almost all levels to help out",
- "Now showing proper descriptions when completing levels, with instructions on what the gained reward does.",
- "Show a landing page on mobile devices about the game not being ready to be played on mobile yet",
- "Fix painters and mixers being affected by the shape processors upgrade and not the painter one",
- "Added 'multiplace' setting which is equivalent to holding SHIFT all the time",
- "Added keybindings to zoom in / zoom out",
- "Tunnels now also show connection lines to tunnel exits, instead of just tunnel entries",
- "Lots of minor fixes and improvements",
- ],
- },
- {
- version: "1.0.1",
- date: "21.05.2020",
- entries: ["Initial release!"],
- },
-];
+export const CHANGELOG = [
+ {
+ version: "1.5.6",
+ date: "09.12.2022",
+ entries: [
+ "⚠️ We are currently prototyping Shapez 2! Click here to find out more. ⚠️ ",
+ "Minor fixes & improvements",
+ "Updated translations",
+ ],
+ },
+ {
+ version: "1.5.5",
+ date: "20.06.2022",
+ entries: [
+ "You can now play the full version in your browser! Click here to read all details.",
+ "Reworked the tutorial to be simpler and more interactive",
+ "General polishing",
+ "Fix being unable to delete savegame when the savegame file was deleted externally",
+ "New sfx when unlocking upgrades",
+ "Updated translations",
+ ],
+ },
+ {
+ version: "1.5.3",
+ date: "05.06.2022",
+ entries: [
+ "Fixed buildings not being lockable in the Puzzle DLC Editor",
+ "Fixed issues launching the game with proton",
+ "Updated translations",
+ ],
+ },
+ {
+ version: "1.5.2",
+ date: "02.06.2022",
+ entries: [
+ "Attempted to fix the 'vram glitch', where the map background would not redraw anymore, especially in fullscreen. If the issue still persists, please let me know in the discord server!",
+ "The game has been renamed from 'shapez.io' to 'shapez', since it is not really an .io game",
+ "Various performance improvements",
+ "Upgrades should now show the full precision",
+ "UI Polishing & Cleanup",
+ "Updated translations",
+ "PS: We are already working on shapez 2, more information will follow in the discord soon!",
+ ],
+ },
+ {
+ version: "1.5.1",
+ date: "25.02.2022",
+ entries: [
+ "This version adds an official modloader! You can now load mods by extracting them and placing the .js file in the mods/ folder of the game.",
+ "Mods can be found here ",
+ "When holding shift while placing a belt, the indicator now becomes red when crossing buildings",
+ "Lots of performance improvements, leading to up to 50% more FPS",
+ ],
+ },
+ {
+ version: "1.4.4",
+ date: "29.08.2021",
+ entries: [
+ "Hotfix: Fixed the balancer not distributing items evenly, caused by the 1.4.3 update. Sorry for any inconveniences!",
+ ],
+ },
+ {
+ version: "1.4.3",
+ date: "28.08.2021",
+ entries: [
+ "You can now hold 'ALT' while hovering a building to see its output! (Thanks to Sense101) (PS: There is now a setting to have it always on!)",
+ "The map overview should now be much more performant! As a consequence, you can now zoom out farther! (Thanks to PFedak)",
+ "Puzzle DLC: There is now a 'next puzzle' button!",
+ "Puzzle DLC: There is now a search function!",
+ "Edit signal dialog now has the previous signal filled (Thanks to EmeraldBlock)",
+ "Further performance improvements (Thanks to PFedak)",
+ "Improved puzzle validation (Thanks to Sense101)",
+ "Input fields in dialogs should now automatically focus",
+ "Fix selected building being deselected at level up (Thanks to EmeraldBlock)",
+ "Updated translations",
+ ],
+ },
+ {
+ version: "1.4.2",
+ date: "24.06.2021",
+ entries: [
+ "Puzzle DLC: Goal acceptors now reset after getting no items for a while (This should prevent being able to 'cheat' puzzles) (by Sense101)",
+ "Puzzle DLC: Added button to clear all buildings / reset the puzzle (by Sense101)",
+ "Puzzle DLC: Allow copy-paste in puzzle mode (by Sense101)",
+ "Fixed level achievements being given on the wrong level (by DJ1TJOO)",
+ "Fixed blueprint not properly clearing on right click",
+ "Updated translations",
+ ],
+ },
+ {
+ version: "1.4.1",
+ date: "22.06.2021",
+ entries: [
+ "The Puzzle DLC is now available on Steam!",
+ "The Soundtrack is now also available to wishlist and will be released within the next days, including the new music from the Puzzle DLC!",
+ ],
+ },
+ {
+ version: "1.4.0",
+ date: "04.06.2021",
+ entries: [
+ "Belts in blueprints should now always paste correctly",
+ "You can now clear belts by selecting them and then pressing 'B'",
+ "Preparations for the Puzzle DLC , coming June 22nd!",
+ ],
+ },
+ {
+ version: "1.3.0",
+ date: "12.03.2020",
+ entries: [
+ "There are now 45 Steam Achievements! ",
+ "Fixed constant signals being editable from the regular layer",
+ "Fixed items still overlapping sometimes between buildings and belts",
+ "The game is now available in finnish, italian, romanian and ukrainian! (Thanks to all contributors!)",
+ "Updated translations (Thanks to all contributors!)",
+ ],
+ },
+ {
+ version: "1.2.2",
+ date: "07.12.2020",
+ entries: [
+ "Fix item readers and some other buildings slowing up belts, especially if they stalled (inspired by Keterr's fix)",
+ "Added the ability to edit constant signals by left clicking them",
+ "Prevent items from being rendered on each other when a belt stalls (inspired by Keterr)",
+ "You can now add markers in the wire layer (partially by daanbreur)",
+ "Allow to cycle backwards in the toolbar with SHIFT + Tab (idea by EmeraldBlock)",
+ "Allow to cycle variants backwards with SHIFT + T",
+ "Upgrade numbers now use roman numerals until tier 50 (by LeopoldTal)",
+ "Add button to unpin shapes from the left side (by artemisSystem)",
+ "Fix middle mouse button also placing blueprints (by Eiim)",
+ "Hide wires grid when using the 'Disable Grid' setting (by EmeraldBlock)",
+ "Fix UI using multiple different save icons",
+ "Updated translations (Thanks to all contributors!)",
+ ],
+ },
+ {
+ version: "1.2.1",
+ date: "31.10.2020",
+ entries: [
+ "Fixed stacking bug for level 26 which required restarting the game",
+ "Fix reward notification being too long sometimes (by LeopoldTal)",
+ "Use locale decimal separator on belt reader display (by LeopoldTal)",
+ "Vastly improved performance when saving games (by LeopoldTal)",
+ "Prevent some antivirus programs blocking the opening of external links (by LeopoldTal)",
+ "Match tutorials to the correct painter variants (by LeopoldTal)",
+ "Prevent throughput goals containing fractional numbers (by CEbbinghaus)",
+ "Updated translations and added Hungarian",
+ ],
+ },
+ {
+ version: "1.2.0",
+ date: "09.10.2020",
+ entries: [
+ "⚠️⚠️This update is HUGE, view the full changelog here ! ⚠️⚠️",
+ ],
+ },
+ {
+ version: "1.1.18",
+ date: "27.06.2020",
+ entries: [
+ "Huge performance improvements - up to double fps and tick-rate! This will wipe out all current items on belts.",
+ "Reduce story shapes required until unlocking blueprints",
+ "Allow clicking on variants to select them",
+ "Add 'copy key' button to shape viewer",
+ "Add more FPS to the belt animation and fix belt animation seeming to go 'backwards' on high belt speeds",
+ "Fix deconstruct sound being played when right clicking hub",
+ "Allow clicking 'Q' over a shape or color patch to automatically select the miner building (by Gerdon262)",
+ "Update belt placement performance on huge factories (by Phlosioneer)",
+ "Fix duplicate waypoints with a shape not rendering (by hexy)",
+ "Fix smart tunnel placement deleting wrong tunnels (by mordof)",
+ "Add setting (on by default) to store the last used rotation per building instead of globally storing it (by Magos)",
+ "Added chinese (traditional) translation",
+ "Updated translations",
+ ],
+ },
+ {
+ version: "1.1.17",
+ date: "22.06.2020",
+ entries: [
+ "Color blind mode! You can now activate it in the settings and it will show you which color is below your cursor (Either resource or on the belt)",
+ "Add info buttons to all shapes so you can figure out how they are built! (And also, which colors they have)",
+ "Allow configuring autosave interval and disabling it in the settings",
+ "The smart-tunnel placement has been reworked to properly replace belts. Thus the setting has been turned on again by default",
+ "The soundtrack now has a higher quality on the standalone version than the web version",
+ "Add setting to disable cut/delete warnings (by hexy)",
+ "Fix bug where belts in blueprints don't orient correctly (by hexy)",
+ "Fix camera moving weird after dragging and holding (by hexy)",
+ "Fix keybinding for pipette showing while pasting blueprints",
+ "Improve visibility of shape background in dark mode",
+ "Added sound when destroying a building",
+ "Added swedish translation",
+ "Update tutorial image for tier 2 tunnels to explain mix/match (by jimmyshadow1)",
+ ],
+ },
+ {
+ version: "1.1.16",
+ date: "21.06.2020",
+ entries: [
+ "You can now pickup buildings below your cursor with 'Q'!",
+ "The game soundtrack has been extended! There are now 4 songs with over 13 minutes of playtime from Peppsen !",
+ "Refactor keybindings overlay to show more appropriate keybindings",
+ "Show keybindings for area-select in the upper left instead",
+ "Automatically deselect area when selecting a new building",
+ "Raise markers limit from 14 characters to 71 (by Joker-vD)",
+ "Optimize performance by caching extractor items (by Phlosioneer)",
+ "Added setting to enable compact building infos, which only show ratios and hide the image / description",
+ "Apply dark theme to menu as well (by dengr1065)",
+ "Fix belt planner not placing the last belt",
+ "Fix buildings getting deleted when right clicking while placing a blueprint",
+ "Fix for exporting screenshots for huge bases (It was showing an empty file) (by xSparfuchs)",
+ "Fix buttons not responding when using right click directly after left click (by davidburhans)",
+ "Fix hub marker being hidden by building info panel",
+ "Disable dialog background blur since it can cause performance issues",
+ "Added simplified chinese translations",
+ "Update translations (Thanks to all translators!)",
+ ],
+ },
+ {
+ version: "1.1.15",
+ date: "17.06.2020",
+ entries: [
+ "You can now place straight belts (and tunnels) by holding SHIFT! (For you, @giantwaffle ❤️)",
+ "Added continue button to main menu and add separate 'New game' button (by jaysc)",
+ "Added setting to disable smart tunnel placement introduced with the last update",
+ "Added setting to disable vignette",
+ "Update translations",
+ ],
+ },
+ {
+ version: "1.1.14",
+ date: "16.06.2020",
+ entries: [
+ "There is now an indicator (compass) to the HUB for the HUB Marker!",
+ "You can now include shape short keys in markers to render shape icons instead of text!",
+ "Added mirrored variant of the painter",
+ "When placing tunnels, unnecessary belts inbetween are now removed!",
+ "You can now drag tunnels and they will automatically expand! (Just try it out, its intuitive)",
+ ],
+ },
+ {
+ version: "1.1.13",
+ date: "15.06.2020",
+ entries: [
+ "Added shift modifier for faster pan (by jaysc)",
+ "Added Japanese translations",
+ "Added Portuguese (Portugal) translations",
+ "Updated icon for Spanish (Latin America) - It was showing a Spanish flag before",
+ "Updated existing translations",
+ ],
+ },
+ {
+ version: "1.1.12",
+ date: "14.06.2020",
+ entries: [
+ "Huge performance improvements! The game should now run up to 60% faster!",
+ "Added norwegian translation",
+ ],
+ },
+ {
+ version: "1.1.11",
+ date: "13.06.2020",
+ entries: [
+ "Pinned shapes are now smart, they dynamically update their goal and also unpin when no longer required. Completed objectives are now rendered transparent.",
+ "You can now cut areas, and also paste the last blueprint again! (by hexy)",
+ "You can now export your whole base as an image by pressing F3!",
+ "Improve upgrade number rounding, so there are no goals like '37.4k', instead it will now be '35k'",
+ "You can now configure the camera movement speed when using WASD (by mini-bomba)",
+ "Selecting an area now is relative to the world and thus does not move when moving the screen (by Dimava)",
+ "Allow higher tick-rates up to 500hz (This will burn your PC!)",
+ "Fix bug regarding number rounding",
+ "Fix dialog text being hardly readable in dark theme",
+ "Fix app not starting when the savegames were corrupted - there is now a better error message as well.",
+ "Further translation updates - Big thanks to all contributors!",
+ ],
+ },
+ {
+ version: "1.1.10",
+ date: "12.06.2020",
+ entries: [
+ "There are now linux builds on steam! Please report any issues in the Discord!",
+ "Steam cloud saves are now available!",
+ "Added and update more translations (Big thank you to all translators!)",
+ "Prevent invalid connection if existing underground tunnel entrance exists (by jaysc)",
+ ],
+ },
+ {
+ version: "1.1.9",
+ date: "11.06.2020",
+ entries: [
+ "Support for translations! Interested in helping out? Check out the translation guide !",
+ "Update stacker artwork to clarify how it works",
+ "Update keybinding hints on the top left to be more accurate",
+ "Make it more clear when blueprints are unlocked when trying to use them",
+ "Fix pinned shape icons not being visible in dark mode",
+ "Fix being able to select buildings via hotkeys in map overview mode",
+ "Make shapes unpinnable in the upgrades tab (By hexy)",
+ ],
+ },
+ {
+ version: "1.1.8",
+ date: "07.06.2020",
+ entries: [
+ "You can now purchase the standalone on steam! View steam page ",
+ "Added ability to create markers in the demo, but only two.",
+ "Contest #01 has ended! I'll now work through the entries, select the 5 I like most and present them to the community to vote for!",
+ ],
+ },
+ {
+ version: "1.1.7",
+ date: "04.06.2020",
+ entries: ["HOTFIX: Fix savegames not showing up on the standalone version"],
+ },
+ {
+ version: "1.1.6",
+ date: "04.06.2020",
+ entries: [
+ "The steam release will happen on the 7th of June - Be sure to add it to your wishlist! View on steam ",
+ "Fixed level complete dialog being blurred when the shop was opened before",
+ "Standalone: Increased icon visibility for windows builds",
+ "Web version: Fixed firefox not loading the game when browsing in private mode",
+ ],
+ },
+
+ {
+ version: "1.1.5",
+ date: "03.06.2020",
+ entries: ["Added weekly contests!"],
+ },
+ {
+ version: "1.1.4",
+ date: "01.06.2020",
+ entries: ["Add 'interactive' tutorial for the first level to improve onboarding experience"],
+ },
+ {
+ version: "1.1.3",
+ date: "01.06.2020",
+ entries: [
+ "Added setting to configure zoom / mouse wheel / touchpad sensitivity",
+ "Fix belts being too slow when copied via blueprint (by Dimava)",
+ "Allow binding mouse buttons to actions (by Dimava)",
+ "Increase readability of certain HUD elements",
+ ],
+ },
+ {
+ version: "1.1.2",
+ date: "30.05.2020",
+ entries: [
+ "The official trailer is now ready! Check it out here !",
+ "The steam page is now live!",
+ "Experimental linux builds are now available! Please give me feedback on them in the Discord",
+ "Allow hovering pinned shapes to enlarge them",
+ "Allow deselecting blueprints with right click and 'Q'",
+ "Move default key for deleting from 'X' to 'DEL'",
+ "Show confirmation when deleting more than 100 buildings",
+ "Reintroduce 'SPACE' keybinding to center on map",
+ "Improved keybinding hints",
+ "Fixed some keybindings showing as 'undefined'",
+ ],
+ },
+ {
+ version: "1.1.1",
+ date: "28.05.2020",
+ entries: ["Fix crash when 'Show Hints' setting was turned off"],
+ },
+ {
+ version: "1.1.0",
+ date: "28.05.2020",
+ entries: [
+ "BLUEPRINTS! They are unlocked at level 12 and cost a special shape to build.",
+ "MAP MARKERS! Press 'M' to create a waypoint and be able to jump to it",
+ "Savegame levels are now shown in the main menu. For existing games, save them again to make the level show up.",
+ "Allow holding SHIFT to rotate counter clockwise",
+ "Added confirmation when deleting more than 500 buildings at a time",
+ "Added background to toolbar to increase contrast",
+ "Further decerase requirements of first levels",
+ "Pinned shapes now are saved",
+ "Allow placing extractors anywhere again, but they don't work at all if not placed on a resource",
+ "Show dialog explaining some keybindings after completing level 4",
+ "Fix keys being stuck when opening a dialog",
+ "Swapped shape order for painting upgrades",
+ "Allow changing all keybindings, including CTRL, ALT and SHIFT (by Dimava)",
+ "Fix cycling through keybindings selecting locked buildings as well (by Dimava)",
+ "There is now a github action, checking all pull requests with eslint. (by mrHedgehog)",
+ ],
+ },
+ {
+ version: "1.0.4",
+ date: "26.05.2020",
+ entries: [
+ "Reduce cost of first painting upgrade, and change 'Shape Processing' to 'Cutting, Rotating & Stacking'",
+ "Add dialog after completing level 2 to check out the upgrades tab.",
+ "Allow changing the keybindings in the demo version",
+ ],
+ },
+ {
+ version: "1.0.3",
+ date: "24.05.2020",
+ entries: [
+ "Reduced the amount of shapes required for the first 5 levels to make it easier to get into the game.",
+ ],
+ },
+ {
+ version: "1.0.2",
+ date: "23.05.2020",
+ entries: [
+ "Introduced changelog",
+ "Removed 'early access' label because the game isn't actually early access - its in a pretty good state already! (No worries, a lot more updates will follow!)",
+ "Added a 'Show hint' button which shows a small video for almost all levels to help out",
+ "Now showing proper descriptions when completing levels, with instructions on what the gained reward does.",
+ "Show a landing page on mobile devices about the game not being ready to be played on mobile yet",
+ "Fix painters and mixers being affected by the shape processors upgrade and not the painter one",
+ "Added 'multiplace' setting which is equivalent to holding SHIFT all the time",
+ "Added keybindings to zoom in / zoom out",
+ "Tunnels now also show connection lines to tunnel exits, instead of just tunnel entries",
+ "Lots of minor fixes and improvements",
+ ],
+ },
+ {
+ version: "1.0.1",
+ date: "21.05.2020",
+ entries: ["Initial release!"],
+ },
+];
diff --git a/src/js/core/animation_frame.js b/src/js/core/animation_frame.js
index 6aa629a5..dc846dd8 100644
--- a/src/js/core/animation_frame.js
+++ b/src/js/core/animation_frame.js
@@ -1,8 +1,5 @@
import { Signal } from "./signal";
-// @ts-ignore
-import BackgroundAnimationFrameEmitterWorker from "../webworkers/background_animation_frame_emittter.worker";
-
import { createLogger } from "./logging";
const logger = createLogger("animation_frame");
@@ -11,7 +8,9 @@ const resetDtMs = 16;
export class AnimationFrame {
constructor() {
+ /** @type {Signal<[number]>} */
this.frameEmitted = new Signal();
+ /** @type {Signal<[number]>} */
this.bgFrameEmitted = new Signal();
this.lastTime = performance.now();
@@ -19,7 +18,9 @@ export class AnimationFrame {
this.boundMethod = this.handleAnimationFrame.bind(this);
- this.backgroundWorker = new BackgroundAnimationFrameEmitterWorker();
+ this.backgroundWorker = new Worker(
+ new URL("../webworkers/background_animation_frame_emittter", import.meta.url)
+ );
this.backgroundWorker.addEventListener("error", err => {
logger.error("Error in background fps worker:", err);
});
@@ -40,7 +41,6 @@ export class AnimationFrame {
}
start() {
- assertAlways(window.requestAnimationFrame, "requestAnimationFrame is not supported!");
this.handleAnimationFrame();
}
@@ -51,11 +51,7 @@ export class AnimationFrame {
dt = resetDtMs;
}
- try {
- this.frameEmitted.dispatch(dt);
- } catch (ex) {
- console.error(ex);
- }
+ this.frameEmitted.dispatch(dt);
this.lastTime = time;
window.requestAnimationFrame(this.boundMethod);
}
diff --git a/src/js/core/async_compression.js b/src/js/core/async_compression.js
deleted file mode 100644
index ddc780cc..00000000
--- a/src/js/core/async_compression.js
+++ /dev/null
@@ -1,120 +0,0 @@
-// @ts-ignore
-import CompressionWorker from "../webworkers/compression.worker";
-
-import { createLogger } from "./logging";
-import { round2Digits } from "./utils";
-
-const logger = createLogger("async_compression");
-
-export let compressionPrefix = String.fromCodePoint(1);
-
-function checkCryptPrefix(prefix) {
- try {
- window.localStorage.setItem("prefix_test", prefix);
- window.localStorage.removeItem("prefix_test");
- return true;
- } catch (ex) {
- logger.warn("Prefix '" + prefix + "' not available");
- return false;
- }
-}
-
-if (!checkCryptPrefix(compressionPrefix)) {
- logger.warn("Switching to basic prefix");
- compressionPrefix = " ";
- if (!checkCryptPrefix(compressionPrefix)) {
- logger.warn("Prefix not available, ls seems to be unavailable");
- }
-}
-
-/**
- * @typedef {{
- * errorHandler: function(any) : void,
- * resolver: function(any) : void,
- * startTime: number
- * }} JobEntry
- */
-
-class AsynCompression {
- constructor() {
- this.worker = new CompressionWorker();
-
- this.currentJobId = 1000;
-
- /** @type {Object.} */
- this.currentJobs = {};
-
- this.worker.addEventListener("message", event => {
- const { jobId, result } = event.data;
- const jobData = this.currentJobs[jobId];
- if (!jobData) {
- logger.error("Failed to resolve job result, job id", jobId, "is not known");
- return;
- }
-
- const duration = performance.now() - jobData.startTime;
- logger.log(
- "Got job",
- jobId,
- "response within",
- round2Digits(duration),
- "ms: ",
- result.length,
- "bytes"
- );
- const resolver = jobData.resolver;
- delete this.currentJobs[jobId];
- resolver(result);
- });
-
- this.worker.addEventListener("error", err => {
- logger.error("Got error from webworker:", err, "aborting all jobs");
- const failureCalls = [];
- for (const jobId in this.currentJobs) {
- failureCalls.push(this.currentJobs[jobId].errorHandler);
- }
- this.currentJobs = {};
- for (let i = 0; i < failureCalls.length; ++i) {
- failureCalls[i](err);
- }
- });
- }
-
- /**
- * Compresses any object
- * @param {any} obj
- */
- compressObjectAsync(obj) {
- logger.log("Compressing object async (optimized)");
- return this.internalQueueJob("compressObject", {
- obj,
- compressionPrefix,
- });
- }
-
- /**
- * Queues a new job
- * @param {string} job
- * @param {any} data
- * @returns {Promise}
- */
- internalQueueJob(job, data) {
- const jobId = ++this.currentJobId;
- return new Promise((resolve, reject) => {
- const errorHandler = err => {
- logger.error("Failed to compress job", jobId, ":", err);
- reject(err);
- };
- this.currentJobs[jobId] = {
- errorHandler,
- resolver: resolve,
- startTime: performance.now(),
- };
-
- logger.log("Posting job", job, "/", jobId);
- this.worker.postMessage({ jobId, job, data });
- });
- }
-}
-
-export const asyncCompressor = new AsynCompression();
diff --git a/src/js/core/atlas_definitions.js b/src/js/core/atlas_definitions.js
index 38d36b59..176b2364 100644
--- a/src/js/core/atlas_definitions.js
+++ b/src/js/core/atlas_definitions.js
@@ -41,10 +41,13 @@ export class AtlasDefinition {
}
/** @type {AtlasDefinition[]} **/
-export const atlasFiles = require
- // @ts-ignore
- .context("../../../res_built/atlas/", false, /.*\.json/i)
- .keys()
- .map(f => f.replace(/^\.\//gi, ""))
- .map(f => require("../../../res_built/atlas/" + f))
- .map(data => new AtlasDefinition(data));
+export const atlasFiles = (
+ await Promise.all(
+ import.meta
+ // @ts-ignore
+ .webpackContext("../../../res_built/atlas/", { recursive: false, regExp: /.*\.json/i })
+ .keys()
+ .map(f => f.replace(/^\.\//gi, ""))
+ .map(f => import("../../../res_built/atlas/" + f))
+ )
+).map(data => new AtlasDefinition(data.default));
diff --git a/src/js/core/background_resources_loader.js b/src/js/core/background_resources_loader.js
index 01e74479..d0489503 100644
--- a/src/js/core/background_resources_loader.js
+++ b/src/js/core/background_resources_loader.js
@@ -1,257 +1,214 @@
-/* typehints:start */
-import { Application } from "../application";
-/* typehints:end */
-
-import { initSpriteCache } from "../game/meta_building_registry";
-import { MUSIC, SOUNDS } from "../platform/sound";
-import { T } from "../translations";
-import { AtlasDefinition, atlasFiles } from "./atlas_definitions";
-import { cachebust } from "./cachebust";
-import { Loader } from "./loader";
-import { createLogger } from "./logging";
-import { Signal } from "./signal";
-import { clamp, getLogoSprite, timeoutPromise } from "./utils";
-
-const logger = createLogger("background_loader");
-
-const MAIN_MENU_ASSETS = {
- sprites: [getLogoSprite()],
- sounds: [SOUNDS.uiClick, SOUNDS.uiError, SOUNDS.dialogError, SOUNDS.dialogOk],
- atlas: [],
- css: [],
-};
-
-const INGAME_ASSETS = {
- sprites: [],
- sounds: [
- ...Array.from(Object.values(MUSIC)),
- ...Array.from(Object.values(SOUNDS)).filter(sound => !MAIN_MENU_ASSETS.sounds.includes(sound)),
- ],
- atlas: atlasFiles,
- css: ["async-resources.css"],
-};
-
-if (G_IS_STANDALONE) {
- MAIN_MENU_ASSETS.sounds = [...Array.from(Object.values(MUSIC)), ...Array.from(Object.values(SOUNDS))];
- INGAME_ASSETS.sounds = [];
-}
-
-const LOADER_TIMEOUT_PER_RESOURCE = 180000;
-
-// Cloudflare does not send content-length headers with brotli compression,
-// so store the actual (compressed) file sizes so we can show a progress bar.
-const HARDCODED_FILE_SIZES = {
- "async-resources.css": 2216145,
-};
-
-export class BackgroundResourcesLoader {
- /**
- *
- * @param {Application} app
- */
- constructor(app) {
- this.app = app;
-
- this.mainMenuPromise = null;
- this.ingamePromise = null;
-
- this.resourceStateChangedSignal = new Signal();
- }
-
- getMainMenuPromise() {
- if (this.mainMenuPromise) {
- return this.mainMenuPromise;
- }
-
- logger.log("⏰ Loading main menu assets");
- return (this.mainMenuPromise = this.loadAssets(MAIN_MENU_ASSETS));
- }
-
- getIngamePromise() {
- if (this.ingamePromise) {
- return this.ingamePromise;
- }
- logger.log("⏰ Loading ingame assets");
- const promise = this.loadAssets(INGAME_ASSETS).then(() => initSpriteCache());
- return (this.ingamePromise = promise);
- }
-
- /**
- *
- * @param {object} param0
- * @param {string[]} param0.sprites
- * @param {string[]} param0.sounds
- * @param {AtlasDefinition[]} param0.atlas
- * @param {string[]} param0.css
- */
- async loadAssets({ sprites, sounds, atlas, css }) {
- /**
- * @type {((progressHandler: (progress: number) => void) => Promise)[]}
- */
- let promiseFunctions = [];
-
- // CSS
- for (let i = 0; i < css.length; ++i) {
- promiseFunctions.push(progress =>
- timeoutPromise(this.internalPreloadCss(css[i], progress), LOADER_TIMEOUT_PER_RESOURCE).catch(
- err => {
- logger.error("Failed to load css:", css[i], err);
- throw new Error("HUD Stylesheet " + css[i] + " failed to load: " + err);
- }
- )
- );
- }
-
- // ATLAS FILES
- for (let i = 0; i < atlas.length; ++i) {
- promiseFunctions.push(progress =>
- timeoutPromise(Loader.preloadAtlas(atlas[i], progress), LOADER_TIMEOUT_PER_RESOURCE).catch(
- err => {
- logger.error("Failed to load atlas:", atlas[i].sourceFileName, err);
- throw new Error("Atlas " + atlas[i].sourceFileName + " failed to load: " + err);
- }
- )
- );
- }
-
- // HUD Sprites
- for (let i = 0; i < sprites.length; ++i) {
- promiseFunctions.push(progress =>
- timeoutPromise(
- Loader.preloadCSSSprite(sprites[i], progress),
- LOADER_TIMEOUT_PER_RESOURCE
- ).catch(err => {
- logger.error("Failed to load css sprite:", sprites[i], err);
- throw new Error("HUD Sprite " + sprites[i] + " failed to load: " + err);
- })
- );
- }
-
- // SFX & Music
- for (let i = 0; i < sounds.length; ++i) {
- promiseFunctions.push(progress =>
- timeoutPromise(this.app.sound.loadSound(sounds[i]), LOADER_TIMEOUT_PER_RESOURCE).catch(
- err => {
- logger.warn("Failed to load sound, will not be available:", sounds[i], err);
- }
- )
- );
- }
-
- const originalAmount = promiseFunctions.length;
- const start = performance.now();
-
- logger.log("⏰ Preloading", originalAmount, "assets");
-
- let progress = 0;
- this.resourceStateChangedSignal.dispatch({ progress });
- let promises = [];
-
- for (let i = 0; i < promiseFunctions.length; i++) {
- let lastIndividualProgress = 0;
- const progressHandler = individualProgress => {
- const delta = clamp(individualProgress) - lastIndividualProgress;
- lastIndividualProgress = clamp(individualProgress);
- progress += delta / originalAmount;
- this.resourceStateChangedSignal.dispatch({ progress });
- };
- promises.push(
- promiseFunctions[i](progressHandler).then(() => {
- progressHandler(1);
- })
- );
- }
- await Promise.all(promises);
-
- logger.log("⏰ Preloaded assets in", Math.round(performance.now() - start), "ms");
- }
-
- /**
- * Shows an error when a resource failed to load and allows to reload the game
- */
- showLoaderError(dialogs, err) {
- if (G_IS_STANDALONE) {
- dialogs
- .showWarning(
- T.dialogs.resourceLoadFailed.title,
- T.dialogs.resourceLoadFailed.descSteamDemo + " " + err,
- ["retry"]
- )
- .retry.add(() => window.location.reload());
- } else {
- dialogs
- .showWarning(
- T.dialogs.resourceLoadFailed.title,
- T.dialogs.resourceLoadFailed.descWeb.replace(
- "",
- `${T.dialogs.resourceLoadFailed.demoLinkText} `
- ) +
- " " +
- err,
- ["retry"]
- )
- .retry.add(() => window.location.reload());
- }
- }
-
- preloadWithProgress(src, progressHandler) {
- return new Promise((resolve, reject) => {
- const xhr = new XMLHttpRequest();
- let notifiedNotComputable = false;
-
- const fullUrl = cachebust(src);
- xhr.open("GET", fullUrl, true);
- xhr.responseType = "arraybuffer";
- xhr.onprogress = function (ev) {
- if (ev.lengthComputable) {
- progressHandler(ev.loaded / ev.total);
- } else {
- if (window.location.search.includes("alwaysLogFileSize")) {
- console.warn("Progress:", src, ev.loaded);
- }
-
- if (HARDCODED_FILE_SIZES[src]) {
- progressHandler(clamp(ev.loaded / HARDCODED_FILE_SIZES[src]));
- } else {
- if (!notifiedNotComputable) {
- notifiedNotComputable = true;
- console.warn("Progress not computable:", src, ev.loaded);
- progressHandler(0);
- }
- }
- }
- };
-
- xhr.onloadend = function () {
- if (!xhr.status.toString().match(/^2/)) {
- reject(fullUrl + ": " + xhr.status + " " + xhr.statusText);
- } else {
- if (!notifiedNotComputable) {
- progressHandler(1);
- }
-
- const options = {};
- const headers = xhr.getAllResponseHeaders();
- const contentType = headers.match(/^Content-Type:\s*(.*?)$/im);
- if (contentType && contentType[1]) {
- options.type = contentType[1].split(";")[0];
- }
- const blob = new Blob([this.response], options);
- resolve(window.URL.createObjectURL(blob));
- }
- };
- xhr.send();
- });
- }
-
- internalPreloadCss(src, progressHandler) {
- return this.preloadWithProgress(src, progressHandler).then(blobSrc => {
- var styleElement = document.createElement("link");
- styleElement.href = blobSrc;
- styleElement.rel = "stylesheet";
- styleElement.setAttribute("media", "all");
- styleElement.type = "text/css";
- document.head.appendChild(styleElement);
- });
- }
-}
+/* typehints:start */
+import { Application } from "../application";
+/* typehints:end */
+
+import { initSpriteCache } from "../game/meta_building_registry";
+import { MUSIC, SOUNDS } from "../platform/sound";
+import { T } from "../translations";
+import { AtlasDefinition, atlasFiles } from "./atlas_definitions";
+import { Loader } from "./loader";
+import { createLogger } from "./logging";
+import { Signal } from "./signal";
+import { clamp, timeoutPromise } from "./utils";
+
+const logger = createLogger("background_loader");
+
+const MAIN_MENU_ASSETS = {
+ sprites: ["logo.png"],
+ sounds: [SOUNDS.uiClick, SOUNDS.uiError, SOUNDS.dialogError, SOUNDS.dialogOk],
+ atlas: [],
+ css: [],
+};
+
+const INGAME_ASSETS = {
+ sprites: [],
+ sounds: [
+ ...Array.from(Object.values(MUSIC)),
+ ...Array.from(Object.values(SOUNDS)).filter(sound => !MAIN_MENU_ASSETS.sounds.includes(sound)),
+ ],
+ atlas: atlasFiles,
+ css: ["async-resources.css"],
+};
+
+MAIN_MENU_ASSETS.sounds = [...Array.from(Object.values(MUSIC)), ...Array.from(Object.values(SOUNDS))];
+INGAME_ASSETS.sounds = [];
+
+const LOADER_TIMEOUT_PER_RESOURCE = 180000;
+
+export class BackgroundResourcesLoader {
+ /**
+ *
+ * @param {Application} app
+ */
+ constructor(app) {
+ this.app = app;
+
+ this.mainMenuPromise = null;
+ this.ingamePromise = null;
+
+ /** @type {Signal<[{ progress: number }]>} */
+ this.resourceStateChangedSignal = new Signal();
+ }
+
+ getMainMenuPromise() {
+ if (this.mainMenuPromise) {
+ return this.mainMenuPromise;
+ }
+
+ logger.log("⏰ Loading main menu assets");
+ return (this.mainMenuPromise = this.loadAssets(MAIN_MENU_ASSETS));
+ }
+
+ getIngamePromise() {
+ if (this.ingamePromise) {
+ return this.ingamePromise;
+ }
+ logger.log("⏰ Loading ingame assets");
+ const promise = this.loadAssets(INGAME_ASSETS).then(() => initSpriteCache());
+ return (this.ingamePromise = promise);
+ }
+
+ /**
+ *
+ * @param {object} param0
+ * @param {string[]} param0.sprites
+ * @param {string[]} param0.sounds
+ * @param {AtlasDefinition[]} param0.atlas
+ * @param {string[]} param0.css
+ */
+ async loadAssets({ sprites, sounds, atlas, css }) {
+ /**
+ * @type {((progressHandler: (progress: number) => void) => Promise)[]}
+ */
+ const promiseFunctions = [];
+
+ // CSS
+ for (let i = 0; i < css.length; ++i) {
+ promiseFunctions.push(progress =>
+ timeoutPromise(this.internalPreloadCss(css[i], progress), LOADER_TIMEOUT_PER_RESOURCE).catch(
+ err => {
+ logger.error("Failed to load css:", css[i], err);
+ throw new Error("HUD Stylesheet " + css[i] + " failed to load: " + err);
+ }
+ )
+ );
+ }
+
+ // ATLAS FILES
+ for (let i = 0; i < atlas.length; ++i) {
+ promiseFunctions.push(progress =>
+ timeoutPromise(Loader.preloadAtlas(atlas[i], progress), LOADER_TIMEOUT_PER_RESOURCE).catch(
+ err => {
+ logger.error("Failed to load atlas:", atlas[i].sourceFileName, err);
+ throw new Error("Atlas " + atlas[i].sourceFileName + " failed to load: " + err);
+ }
+ )
+ );
+ }
+
+ // HUD Sprites
+ for (let i = 0; i < sprites.length; ++i) {
+ promiseFunctions.push(progress =>
+ timeoutPromise(
+ Loader.preloadCSSSprite(sprites[i], progress),
+ LOADER_TIMEOUT_PER_RESOURCE
+ ).catch(err => {
+ logger.error("Failed to load css sprite:", sprites[i], err);
+ throw new Error("HUD Sprite " + sprites[i] + " failed to load: " + err);
+ })
+ );
+ }
+
+ // SFX & Music
+ for (let i = 0; i < sounds.length; ++i) {
+ promiseFunctions.push(() =>
+ timeoutPromise(this.app.sound.loadSound(sounds[i]), LOADER_TIMEOUT_PER_RESOURCE).catch(
+ err => {
+ logger.warn("Failed to load sound, will not be available:", sounds[i], err);
+ }
+ )
+ );
+ }
+
+ const originalAmount = promiseFunctions.length;
+ const start = performance.now();
+
+ logger.log("⏰ Preloading", originalAmount, "assets");
+
+ let progress = 0;
+ this.resourceStateChangedSignal.dispatch({ progress });
+ const promises = [];
+
+ for (let i = 0; i < promiseFunctions.length; i++) {
+ let lastIndividualProgress = 0;
+ const progressHandler = individualProgress => {
+ const delta = clamp(individualProgress) - lastIndividualProgress;
+ lastIndividualProgress = clamp(individualProgress);
+ progress += delta / originalAmount;
+ this.resourceStateChangedSignal.dispatch({ progress });
+ };
+ promises.push(
+ promiseFunctions[i](progressHandler).then(() => {
+ progressHandler(1);
+ })
+ );
+ }
+ await Promise.all(promises);
+
+ logger.log("⏰ Preloaded assets in", Math.round(performance.now() - start), "ms");
+ }
+
+ /**
+ * Shows an error when a resource failed to load and allows to reload the game
+ */
+ showLoaderError(dialogs, err) {
+ dialogs
+ .showWarning(
+ T.dialogs.resourceLoadFailed.title,
+ T.dialogs.resourceLoadFailed.descSteamDemo + " " + err,
+ ["retry"]
+ )
+ .retry.add(() => window.location.reload());
+ }
+
+ preloadWithProgress(src, progressHandler) {
+ return new Promise((resolve, reject) => {
+ const xhr = new XMLHttpRequest();
+
+ xhr.open("GET", src, true);
+ xhr.responseType = "arraybuffer";
+ xhr.onprogress = function (ev) {
+ if (ev.lengthComputable) {
+ progressHandler(ev.loaded / ev.total);
+ }
+ };
+
+ xhr.onloadend = function () {
+ if (!xhr.status.toString().match(/^2/)) {
+ reject(src + ": " + xhr.status + " " + xhr.statusText);
+ } else {
+ const options = {};
+ const headers = xhr.getAllResponseHeaders();
+ const contentType = headers.match(/^Content-Type:\s*(.*?)$/im);
+ if (contentType && contentType[1]) {
+ options.type = contentType[1].split(";")[0];
+ }
+ const blob = new Blob([this.response], options);
+ resolve(window.URL.createObjectURL(blob));
+ }
+ };
+ xhr.send();
+ });
+ }
+
+ internalPreloadCss(src, progressHandler) {
+ return this.preloadWithProgress(src, progressHandler).then(blobSrc => {
+ const styleElement = document.createElement("link");
+ styleElement.href = blobSrc;
+ styleElement.rel = "stylesheet";
+ styleElement.setAttribute("media", "all");
+ styleElement.type = "text/css";
+ document.head.appendChild(styleElement);
+ });
+ }
+}
diff --git a/src/js/core/buffer_maintainer.js b/src/js/core/buffer_maintainer.js
index 1d6bffb9..410a8244 100644
--- a/src/js/core/buffer_maintainer.js
+++ b/src/js/core/buffer_maintainer.js
@@ -1,7 +1,6 @@
import { GameRoot } from "../game/root";
-import { clearBufferBacklog, freeCanvas, getBufferStats, makeOffscreenBuffer } from "./buffer_utils";
+import { clearBufferBacklog, freeCanvas, makeOffscreenBuffer } from "./buffer_utils";
import { createLogger } from "./logging";
-import { round1Digit } from "./utils";
/**
* @typedef {{
@@ -35,7 +34,7 @@ export class BufferMaintainer {
* Returns the buffer stats
*/
getStats() {
- let stats = {
+ const stats = {
rootKeys: 0,
subKeys: 0,
vramBytes: 0,
@@ -59,25 +58,16 @@ export class BufferMaintainer {
* for a few iterations
*/
garbargeCollect() {
- let totalKeys = 0;
- let deletedKeys = 0;
const minIteration = this.iterationIndex;
this.cache.forEach((subCache, key) => {
- let unusedSubKeys = [];
+ const unusedSubKeys = [];
// Filter sub cache
subCache.forEach((cacheEntry, subKey) => {
- if (
- cacheEntry.lastUse < minIteration ||
- // @ts-ignore
- cacheEntry.canvas._contextLost
- ) {
+ if (cacheEntry.lastUse < minIteration) {
unusedSubKeys.push(subKey);
freeCanvas(cacheEntry.canvas);
- ++deletedKeys;
- } else {
- ++totalKeys;
}
});
@@ -90,30 +80,6 @@ export class BufferMaintainer {
// Make sure our backlog never gets too big
clearBufferBacklog();
- // if (G_IS_DEV) {
- // const bufferStats = getBufferStats();
- // const mbUsed = round1Digit(bufferStats.vramUsage / (1024 * 1024));
- // logger.log(
- // "GC: Remove",
- // (deletedKeys + "").padStart(4),
- // ", Remain",
- // (totalKeys + "").padStart(4),
- // "(",
- // (bufferStats.bufferCount + "").padStart(4),
- // "total",
- // ")",
-
- // "(",
- // (bufferStats.backlogSize + "").padStart(4),
- // "backlog",
- // ")",
-
- // "VRAM:",
- // mbUsed,
- // "MB"
- // );
- // }
-
++this.iterationIndex;
}
@@ -180,7 +146,7 @@ export class BufferMaintainer {
*
*/
getForKeyOrNullNoUpdate({ key, subKey }) {
- let parent = this.cache.get(key);
+ const parent = this.cache.get(key);
if (!parent) {
return null;
}
diff --git a/src/js/core/buffer_utils.js b/src/js/core/buffer_utils.js
index 0048b214..9434a5e8 100644
--- a/src/js/core/buffer_utils.js
+++ b/src/js/core/buffer_utils.js
@@ -1,30 +1,9 @@
import { globalConfig } from "./config";
-import { fastArrayDelete } from "./utils";
import { createLogger } from "./logging";
+import { fastArrayDelete } from "./utils";
const logger = createLogger("buffer_utils");
-/**
- * Enables images smoothing on a context
- * @param {CanvasRenderingContext2D} context
- */
-export function enableImageSmoothing(context) {
- context.imageSmoothingEnabled = true;
- context.webkitImageSmoothingEnabled = true;
-
- // @ts-ignore
- context.imageSmoothingQuality = globalConfig.smoothing.quality;
-}
-
-/**
- * Disables image smoothing on a context
- * @param {CanvasRenderingContext2D} context
- */
-export function disableImageSmoothing(context) {
- context.imageSmoothingEnabled = false;
- context.webkitImageSmoothingEnabled = false;
-}
-
/**
* @typedef {{
* canvas: HTMLCanvasElement,
@@ -103,15 +82,7 @@ export function clearBufferBacklog() {
* @returns {[HTMLCanvasElement, CanvasRenderingContext2D]}
*/
export function makeOffscreenBuffer(w, h, { smooth = true, reusable = true, label = "buffer" }) {
- assert(w > 0 && h > 0, "W or H < 0");
- if (w % 1 !== 0 || h % 1 !== 0) {
- // console.warn("Subpixel offscreen buffer size:", w, h);
- }
- if (w < 1 || h < 1) {
- logger.error("Offscreen buffer size < 0:", w, "x", h);
- w = Math.max(1, w);
- h = Math.max(1, h);
- }
+ assert(w >= 1 && h >= 1, "Invalid offscreen buffer size: W or H < 1");
const recommendedSize = 1024 * 1024;
if (w * h > recommendedSize) {
@@ -161,29 +132,13 @@ export function makeOffscreenBuffer(w, h, { smooth = true, reusable = true, labe
// Initial state
context.save();
-
- canvas.addEventListener("webglcontextlost", () => {
- console.warn("canvas::webglcontextlost", canvas);
- // @ts-ignore
- canvas._contextLost = true;
- });
- canvas.addEventListener("contextlost", () => {
- console.warn("canvas::contextlost", canvas);
- // @ts-ignore
- canvas._contextLost = true;
- });
}
- // @ts-ignore
- canvas._contextLost = false;
// @ts-ignore
canvas.label = label;
- if (smooth) {
- enableImageSmoothing(context);
- } else {
- disableImageSmoothing(context);
- }
+ context.imageSmoothingEnabled = smooth;
+ context.imageSmoothingQuality = globalConfig.smoothing.quality;
if (reusable) {
registerCanvas(canvas, context);
diff --git a/src/js/core/cachebust.js b/src/js/core/cachebust.js
deleted file mode 100644
index 26be0449..00000000
--- a/src/js/core/cachebust.js
+++ /dev/null
@@ -1,10 +0,0 @@
-/**
- * Generates a cachebuster string. This only modifies the path in the browser version
- * @param {string} path
- */
-export function cachebust(path) {
- if (G_IS_BROWSER && !G_IS_STANDALONE && !G_IS_DEV) {
- return "/v/" + G_BUILD_COMMIT_HASH + "/" + path;
- }
- return path;
-}
diff --git a/src/js/core/click_detector.js b/src/js/core/click_detector.js
index fb62f0f1..9b1b52c9 100644
--- a/src/js/core/click_detector.js
+++ b/src/js/core/click_detector.js
@@ -1,465 +1,474 @@
-import { createLogger } from "../core/logging";
-import { Signal } from "../core/signal";
-import { fastArrayDelete, fastArrayDeleteValueIfContained } from "./utils";
-import { Vector } from "./vector";
-import { IS_MOBILE, SUPPORT_TOUCH } from "./config";
-import { SOUNDS } from "../platform/sound";
-import { GLOBAL_APP } from "./globals";
-
-const logger = createLogger("click_detector");
-
-export const MAX_MOVE_DISTANCE_PX = IS_MOBILE ? 20 : 80;
-
-// For debugging
-const registerClickDetectors = G_IS_DEV && true;
-if (registerClickDetectors) {
- /** @type {Array} */
- window.activeClickDetectors = [];
-}
-
-// Store active click detectors so we can cancel them
-/** @type {Array} */
-const ongoingClickDetectors = [];
-
-// Store when the last touch event was registered, to avoid accepting a touch *and* a click event
-
-export let clickDetectorGlobals = {
- lastTouchTime: -1000,
-};
-
-/**
- * Click detector creation payload typehints
- * @typedef {{
- * consumeEvents?: boolean,
- * preventDefault?: boolean,
- * applyCssClass?: string,
- * captureTouchmove?: boolean,
- * targetOnly?: boolean,
- * maxDistance?: number,
- * clickSound?: string,
- * preventClick?: boolean,
- * }} ClickDetectorConstructorArgs
- */
-
-// Detects clicks
-export class ClickDetector {
- /**
- *
- * @param {Element} element
- * @param {object} param1
- * @param {boolean=} param1.consumeEvents Whether to call stopPropagation
- * (Useful for nested elements where the parent has a click handler as wel)
- * @param {boolean=} param1.preventDefault Whether to call preventDefault (Usually makes the handler faster)
- * @param {string=} param1.applyCssClass The css class to add while the element is pressed
- * @param {boolean=} param1.captureTouchmove Whether to capture touchmove events as well
- * @param {boolean=} param1.targetOnly Whether to also accept clicks on child elements (e.target !== element)
- * @param {number=} param1.maxDistance The maximum distance in pixels to accept clicks
- * @param {string=} param1.clickSound Sound key to play on touchdown
- * @param {boolean=} param1.preventClick Whether to prevent click events
- */
- constructor(
- element,
- {
- consumeEvents = false,
- preventDefault = true,
- applyCssClass = "pressed",
- captureTouchmove = false,
- targetOnly = false,
- maxDistance = MAX_MOVE_DISTANCE_PX,
- clickSound = SOUNDS.uiClick,
- preventClick = false,
- }
- ) {
- assert(element, "No element given!");
- this.clickDownPosition = null;
-
- this.consumeEvents = consumeEvents;
- this.preventDefault = preventDefault;
- this.applyCssClass = applyCssClass;
- this.captureTouchmove = captureTouchmove;
- this.targetOnly = targetOnly;
- this.clickSound = clickSound;
- this.maxDistance = maxDistance;
- this.preventClick = preventClick;
-
- // Signals
- this.click = new Signal();
- this.rightClick = new Signal();
- this.touchstart = new Signal();
- this.touchmove = new Signal();
- this.touchend = new Signal();
- this.touchcancel = new Signal();
-
- // Simple signals which just receive the touch position
- this.touchstartSimple = new Signal();
- this.touchmoveSimple = new Signal();
- this.touchendSimple = new Signal();
-
- // Store time of touch start
- this.clickStartTime = null;
-
- // A click can be cancelled if another detector registers a click
- this.cancelled = false;
-
- this.internalBindTo(/** @type {HTMLElement} */ (element));
- }
-
- /**
- * Cleans up all event listeners of this detector
- */
- cleanup() {
- if (this.element) {
- if (registerClickDetectors) {
- const index = window.activeClickDetectors.indexOf(this);
- if (index < 0) {
- logger.error("Click detector cleanup but is not active");
- } else {
- window.activeClickDetectors.splice(index, 1);
- }
- }
- const options = this.internalGetEventListenerOptions();
-
- if (SUPPORT_TOUCH) {
- this.element.removeEventListener("touchstart", this.handlerTouchStart, options);
- this.element.removeEventListener("touchend", this.handlerTouchEnd, options);
- this.element.removeEventListener("touchcancel", this.handlerTouchCancel, options);
- }
-
- this.element.removeEventListener("mouseup", this.handlerTouchStart, options);
- this.element.removeEventListener("mousedown", this.handlerTouchEnd, options);
- this.element.removeEventListener("mouseout", this.handlerTouchCancel, options);
-
- if (this.captureTouchmove) {
- if (SUPPORT_TOUCH) {
- this.element.removeEventListener("touchmove", this.handlerTouchMove, options);
- }
- this.element.removeEventListener("mousemove", this.handlerTouchMove, options);
- }
-
- if (this.preventClick) {
- this.element.removeEventListener("click", this.handlerPreventClick, options);
- }
-
- this.click.removeAll();
- this.touchstart.removeAll();
- this.touchmove.removeAll();
- this.touchend.removeAll();
- this.touchcancel.removeAll();
-
- this.element = null;
- }
- }
-
- // INTERNAL METHODS
-
- /**
- *
- * @param {Event} event
- */
- internalPreventClick(event) {
- window.focus();
- event.preventDefault();
- }
-
- /**
- * Internal method to get the options to pass to an event listener
- */
- internalGetEventListenerOptions() {
- return {
- capture: this.consumeEvents,
- passive: !this.preventDefault,
- };
- }
-
- /**
- * Binds the click detector to an element
- * @param {HTMLElement} element
- */
- internalBindTo(element) {
- const options = this.internalGetEventListenerOptions();
-
- this.handlerTouchStart = this.internalOnPointerDown.bind(this);
- this.handlerTouchEnd = this.internalOnPointerEnd.bind(this);
- this.handlerTouchMove = this.internalOnPointerMove.bind(this);
- this.handlerTouchCancel = this.internalOnTouchCancel.bind(this);
-
- if (this.preventClick) {
- this.handlerPreventClick = this.internalPreventClick.bind(this);
- element.addEventListener("click", this.handlerPreventClick, options);
- }
-
- if (SUPPORT_TOUCH) {
- element.addEventListener("touchstart", this.handlerTouchStart, options);
- element.addEventListener("touchend", this.handlerTouchEnd, options);
- element.addEventListener("touchcancel", this.handlerTouchCancel, options);
- }
-
- element.addEventListener("mousedown", this.handlerTouchStart, options);
- element.addEventListener("mouseup", this.handlerTouchEnd, options);
- element.addEventListener("mouseout", this.handlerTouchCancel, options);
-
- if (this.captureTouchmove) {
- if (SUPPORT_TOUCH) {
- element.addEventListener("touchmove", this.handlerTouchMove, options);
- }
- element.addEventListener("mousemove", this.handlerTouchMove, options);
- }
-
- if (registerClickDetectors) {
- window.activeClickDetectors.push(this);
- }
- this.element = element;
- }
-
- /**
- * Returns if the bound element is currently in the DOM.
- */
- internalIsDomElementAttached() {
- return this.element && document.documentElement.contains(this.element);
- }
-
- /**
- * Checks if the given event is relevant for this detector
- * @param {TouchEvent|MouseEvent} event
- */
- internalEventPreHandler(event, expectedRemainingTouches = 1) {
- if (!this.element) {
- // Already cleaned up
- return false;
- }
-
- if (this.targetOnly && event.target !== this.element) {
- // Clicked a child element
- return false;
- }
-
- // Stop any propagation and defaults if configured
- if (this.consumeEvents && event.cancelable) {
- event.stopPropagation();
- }
-
- if (this.preventDefault && event.cancelable) {
- event.preventDefault();
- }
-
- if (window.TouchEvent && event instanceof TouchEvent) {
- clickDetectorGlobals.lastTouchTime = performance.now();
-
- // console.log("Got touches", event.targetTouches.length, "vs", expectedRemainingTouches);
- if (event.targetTouches.length !== expectedRemainingTouches) {
- return false;
- }
- }
-
- if (event instanceof MouseEvent) {
- if (performance.now() - clickDetectorGlobals.lastTouchTime < 1000.0) {
- return false;
- }
- }
-
- return true;
- }
-
- /**
- * Extracts the mous position from an event
- * @param {TouchEvent|MouseEvent} event
- * @returns {Vector} The client space position
- */
- static extractPointerPosition(event) {
- if (window.TouchEvent && event instanceof TouchEvent) {
- if (event.changedTouches.length !== 1) {
- logger.warn(
- "Got unexpected target touches:",
- event.targetTouches.length,
- "->",
- event.targetTouches
- );
- return new Vector(0, 0);
- }
-
- const touch = event.changedTouches[0];
- return new Vector(touch.clientX, touch.clientY);
- }
-
- if (event instanceof MouseEvent) {
- return new Vector(event.clientX, event.clientY);
- }
-
- assertAlways(false, "Got unknown event: " + event);
-
- return new Vector(0, 0);
- }
-
- /**
- * Cacnels all ongoing events on this detector
- */
- cancelOngoingEvents() {
- if (this.applyCssClass && this.element) {
- this.element.classList.remove(this.applyCssClass);
- }
- this.clickDownPosition = null;
- this.clickStartTime = null;
- this.cancelled = true;
- fastArrayDeleteValueIfContained(ongoingClickDetectors, this);
- }
-
- /**
- * Internal pointer down handler
- * @param {TouchEvent|MouseEvent} event
- */
- internalOnPointerDown(event) {
- window.focus();
-
- if (!this.internalEventPreHandler(event, 1)) {
- return false;
- }
-
- const position = /** @type {typeof ClickDetector} */ (this.constructor).extractPointerPosition(event);
-
- if (event instanceof MouseEvent) {
- const isRightClick = event.button === 2;
- if (isRightClick) {
- // Ignore right clicks
- this.rightClick.dispatch(position, event);
- this.cancelled = true;
- this.clickDownPosition = null;
- return;
- }
- }
-
- if (this.clickDownPosition) {
- logger.warn("Ignoring double click");
- return false;
- }
-
- this.cancelled = false;
- this.touchstart.dispatch(event);
-
- // Store where the touch started
- this.clickDownPosition = position;
- this.clickStartTime = performance.now();
- this.touchstartSimple.dispatch(this.clickDownPosition.x, this.clickDownPosition.y);
-
- // If we are not currently within a click, register it
- if (ongoingClickDetectors.indexOf(this) < 0) {
- ongoingClickDetectors.push(this);
- } else {
- logger.warn("Click detector got pointer down of active pointer twice");
- }
-
- // If we should apply any classes, do this now
- if (this.applyCssClass) {
- this.element.classList.add(this.applyCssClass);
- }
-
- // If we should play any sound, do this
- if (this.clickSound) {
- GLOBAL_APP.sound.playUiSound(this.clickSound);
- }
-
- return false;
- }
-
- /**
- * Internal pointer move handler
- * @param {TouchEvent|MouseEvent} event
- */
- internalOnPointerMove(event) {
- if (!this.internalEventPreHandler(event, 1)) {
- return false;
- }
- this.touchmove.dispatch(event);
- const pos = /** @type {typeof ClickDetector} */ (this.constructor).extractPointerPosition(event);
- this.touchmoveSimple.dispatch(pos.x, pos.y);
- return false;
- }
-
- /**
- * Internal pointer end handler
- * @param {TouchEvent|MouseEvent} event
- */
- internalOnPointerEnd(event) {
- window.focus();
-
- if (!this.internalEventPreHandler(event, 0)) {
- return false;
- }
-
- if (this.cancelled) {
- // warn(this, "Not dispatching touchend on cancelled listener");
- return false;
- }
-
- if (event instanceof MouseEvent) {
- const isRightClick = event.button === 2;
- if (isRightClick) {
- return;
- }
- }
-
- const index = ongoingClickDetectors.indexOf(this);
- if (index < 0) {
- logger.warn("Got pointer end but click detector is not in pressed state");
- } else {
- fastArrayDelete(ongoingClickDetectors, index);
- }
-
- let dispatchClick = false;
- let dispatchClickPos = null;
-
- // Check for correct down position, otherwise must have pinched or so
- if (this.clickDownPosition) {
- const pos = /** @type {typeof ClickDetector} */ (this.constructor).extractPointerPosition(event);
- const distance = pos.distance(this.clickDownPosition);
- if (!IS_MOBILE || distance <= this.maxDistance) {
- dispatchClick = true;
- dispatchClickPos = pos;
- } else {
- console.warn("[ClickDetector] Touch does not count as click:", "(was", distance, ")");
- }
- }
-
- this.clickDownPosition = null;
- this.clickStartTime = null;
-
- if (this.applyCssClass) {
- this.element.classList.remove(this.applyCssClass);
- }
-
- // Dispatch in the end to avoid the element getting invalidated
- // Also make sure that the element is still in the dom
- if (this.internalIsDomElementAttached()) {
- this.touchend.dispatch(event);
- this.touchendSimple.dispatch();
-
- if (dispatchClick) {
- const detectors = ongoingClickDetectors.slice();
- for (let i = 0; i < detectors.length; ++i) {
- detectors[i].cancelOngoingEvents();
- }
- this.click.dispatch(dispatchClickPos, event);
- }
- }
- return false;
- }
-
- /**
- * Internal touch cancel handler
- * @param {TouchEvent|MouseEvent} event
- */
- internalOnTouchCancel(event) {
- if (!this.internalEventPreHandler(event, 0)) {
- return false;
- }
-
- if (this.cancelled) {
- // warn(this, "Not dispatching touchcancel on cancelled listener");
- return false;
- }
-
- this.cancelOngoingEvents();
- this.touchcancel.dispatch(event);
- this.touchendSimple.dispatch(event);
- return false;
- }
-}
+import { createLogger } from "../core/logging";
+import { Signal } from "../core/signal";
+import { fastArrayDelete, fastArrayDeleteValueIfContained } from "./utils";
+import { Vector } from "./vector";
+import { IS_MOBILE, SUPPORT_TOUCH } from "./config";
+import { SOUNDS } from "../platform/sound";
+import { GLOBAL_APP } from "./globals";
+
+const logger = createLogger("click_detector");
+
+export const MAX_MOVE_DISTANCE_PX = IS_MOBILE ? 20 : 80;
+
+// For debugging
+const registerClickDetectors = G_IS_DEV && true;
+if (registerClickDetectors) {
+ /** @type {Array} */
+ window.activeClickDetectors = [];
+}
+
+// Store active click detectors so we can cancel them
+/** @type {Array} */
+const ongoingClickDetectors = [];
+
+// Store when the last touch event was registered, to avoid accepting a touch *and* a click event
+
+export let clickDetectorGlobals = {
+ lastTouchTime: -1000,
+};
+
+/**
+ * Click detector creation payload typehints
+ * @typedef {{
+ * consumeEvents?: boolean,
+ * preventDefault?: boolean,
+ * applyCssClass?: string,
+ * captureTouchmove?: boolean,
+ * targetOnly?: boolean,
+ * maxDistance?: number,
+ * clickSound?: string,
+ * preventClick?: boolean,
+ * }} ClickDetectorConstructorArgs
+ */
+
+// Detects clicks
+export class ClickDetector {
+ /**
+ *
+ * @param {Element} element
+ * @param {object} param1
+ * @param {boolean=} param1.consumeEvents Whether to call stopPropagation
+ * (Useful for nested elements where the parent has a click handler as wel)
+ * @param {boolean=} param1.preventDefault Whether to call preventDefault (Usually makes the handler faster)
+ * @param {string=} param1.applyCssClass The css class to add while the element is pressed
+ * @param {boolean=} param1.captureTouchmove Whether to capture touchmove events as well
+ * @param {boolean=} param1.targetOnly Whether to also accept clicks on child elements (e.target !== element)
+ * @param {number=} param1.maxDistance The maximum distance in pixels to accept clicks
+ * @param {string=} param1.clickSound Sound key to play on touchdown
+ * @param {boolean=} param1.preventClick Whether to prevent click events
+ */
+ constructor(
+ element,
+ {
+ consumeEvents = false,
+ preventDefault = true,
+ applyCssClass = "pressed",
+ captureTouchmove = false,
+ targetOnly = false,
+ maxDistance = MAX_MOVE_DISTANCE_PX,
+ clickSound = SOUNDS.uiClick,
+ preventClick = false,
+ }
+ ) {
+ assert(element, "No element given!");
+ this.clickDownPosition = null;
+
+ this.consumeEvents = consumeEvents;
+ this.preventDefault = preventDefault;
+ this.applyCssClass = applyCssClass;
+ this.captureTouchmove = captureTouchmove;
+ this.targetOnly = targetOnly;
+ this.clickSound = clickSound;
+ this.maxDistance = maxDistance;
+ this.preventClick = preventClick;
+
+ // Signals
+ /** @type {Signal<[Vector, TouchEvent | MouseEvent]>} */
+ this.click = new Signal();
+ /** @type {Signal<[Vector, MouseEvent]>} */
+ this.rightClick = new Signal();
+ /** @type {Signal<[TouchEvent | MouseEvent]>} */
+ this.touchstart = new Signal();
+ /** @type {Signal<[TouchEvent | MouseEvent]>} */
+ this.touchmove = new Signal();
+ /** @type {Signal<[TouchEvent | MouseEvent]>} */
+ this.touchend = new Signal();
+ /** @type {Signal<[TouchEvent | MouseEvent]>} */
+ this.touchcancel = new Signal();
+
+ // Simple signals which just receive the touch position
+ /** @type {Signal<[number, number]>} */
+ this.touchstartSimple = new Signal();
+ /** @type {Signal<[number, number]>} */
+ this.touchmoveSimple = new Signal();
+ /** @type {Signal<[(TouchEvent | MouseEvent)?]>} */
+ this.touchendSimple = new Signal();
+
+ // Store time of touch start
+ this.clickStartTime = null;
+
+ // A click can be cancelled if another detector registers a click
+ this.cancelled = false;
+
+ this.internalBindTo(/** @type {HTMLElement} */ (element));
+ }
+
+ /**
+ * Cleans up all event listeners of this detector
+ */
+ cleanup() {
+ if (this.element) {
+ if (registerClickDetectors) {
+ const index = window.activeClickDetectors.indexOf(this);
+ if (index < 0) {
+ logger.error("Click detector cleanup but is not active");
+ } else {
+ window.activeClickDetectors.splice(index, 1);
+ }
+ }
+ const options = this.internalGetEventListenerOptions();
+
+ if (SUPPORT_TOUCH) {
+ this.element.removeEventListener("touchstart", this.handlerTouchStart, options);
+ this.element.removeEventListener("touchend", this.handlerTouchEnd, options);
+ this.element.removeEventListener("touchcancel", this.handlerTouchCancel, options);
+ }
+
+ this.element.removeEventListener("mouseup", this.handlerTouchStart, options);
+ this.element.removeEventListener("mousedown", this.handlerTouchEnd, options);
+ this.element.removeEventListener("mouseout", this.handlerTouchCancel, options);
+
+ if (this.captureTouchmove) {
+ if (SUPPORT_TOUCH) {
+ this.element.removeEventListener("touchmove", this.handlerTouchMove, options);
+ }
+ this.element.removeEventListener("mousemove", this.handlerTouchMove, options);
+ }
+
+ if (this.preventClick) {
+ this.element.removeEventListener("click", this.handlerPreventClick, options);
+ }
+
+ this.click.removeAll();
+ this.touchstart.removeAll();
+ this.touchmove.removeAll();
+ this.touchend.removeAll();
+ this.touchcancel.removeAll();
+
+ this.element = null;
+ }
+ }
+
+ // INTERNAL METHODS
+
+ /**
+ *
+ * @param {Event} event
+ */
+ internalPreventClick(event) {
+ window.focus();
+ event.preventDefault();
+ }
+
+ /**
+ * Internal method to get the options to pass to an event listener
+ */
+ internalGetEventListenerOptions() {
+ return {
+ capture: this.consumeEvents,
+ passive: !this.preventDefault,
+ };
+ }
+
+ /**
+ * Binds the click detector to an element
+ * @param {HTMLElement} element
+ */
+ internalBindTo(element) {
+ const options = this.internalGetEventListenerOptions();
+
+ this.handlerTouchStart = this.internalOnPointerDown.bind(this);
+ this.handlerTouchEnd = this.internalOnPointerEnd.bind(this);
+ this.handlerTouchMove = this.internalOnPointerMove.bind(this);
+ this.handlerTouchCancel = this.internalOnTouchCancel.bind(this);
+
+ if (this.preventClick) {
+ this.handlerPreventClick = this.internalPreventClick.bind(this);
+ element.addEventListener("click", this.handlerPreventClick, options);
+ }
+
+ if (SUPPORT_TOUCH) {
+ element.addEventListener("touchstart", this.handlerTouchStart, options);
+ element.addEventListener("touchend", this.handlerTouchEnd, options);
+ element.addEventListener("touchcancel", this.handlerTouchCancel, options);
+ }
+
+ element.addEventListener("mousedown", this.handlerTouchStart, options);
+ element.addEventListener("mouseup", this.handlerTouchEnd, options);
+ element.addEventListener("mouseout", this.handlerTouchCancel, options);
+
+ if (this.captureTouchmove) {
+ if (SUPPORT_TOUCH) {
+ element.addEventListener("touchmove", this.handlerTouchMove, options);
+ }
+ element.addEventListener("mousemove", this.handlerTouchMove, options);
+ }
+
+ if (registerClickDetectors) {
+ window.activeClickDetectors.push(this);
+ }
+ this.element = element;
+ }
+
+ /**
+ * Returns if the bound element is currently in the DOM.
+ */
+ internalIsDomElementAttached() {
+ return this.element && document.documentElement.contains(this.element);
+ }
+
+ /**
+ * Checks if the given event is relevant for this detector
+ * @param {TouchEvent|MouseEvent} event
+ */
+ internalEventPreHandler(event, expectedRemainingTouches = 1) {
+ if (!this.element) {
+ // Already cleaned up
+ return false;
+ }
+
+ if (this.targetOnly && event.target !== this.element) {
+ // Clicked a child element
+ return false;
+ }
+
+ // Stop any propagation and defaults if configured
+ if (this.consumeEvents && event.cancelable) {
+ event.stopPropagation();
+ }
+
+ if (this.preventDefault && event.cancelable) {
+ event.preventDefault();
+ }
+
+ if (window.TouchEvent && event instanceof TouchEvent) {
+ clickDetectorGlobals.lastTouchTime = performance.now();
+
+ // console.log("Got touches", event.targetTouches.length, "vs", expectedRemainingTouches);
+ if (event.targetTouches.length !== expectedRemainingTouches) {
+ return false;
+ }
+ }
+
+ if (event instanceof MouseEvent) {
+ if (performance.now() - clickDetectorGlobals.lastTouchTime < 1000.0) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Extracts the mous position from an event
+ * @param {TouchEvent|MouseEvent} event
+ * @returns {Vector} The client space position
+ */
+ static extractPointerPosition(event) {
+ if (window.TouchEvent && event instanceof TouchEvent) {
+ if (event.changedTouches.length !== 1) {
+ logger.warn(
+ "Got unexpected target touches:",
+ event.targetTouches.length,
+ "->",
+ event.targetTouches
+ );
+ return new Vector(0, 0);
+ }
+
+ const touch = event.changedTouches[0];
+ return new Vector(touch.clientX, touch.clientY);
+ }
+
+ if (event instanceof MouseEvent) {
+ return new Vector(event.clientX, event.clientY);
+ }
+
+ assertAlways(false, "Got unknown event: " + event);
+
+ return new Vector(0, 0);
+ }
+
+ /**
+ * Cacnels all ongoing events on this detector
+ */
+ cancelOngoingEvents() {
+ if (this.applyCssClass && this.element) {
+ this.element.classList.remove(this.applyCssClass);
+ }
+ this.clickDownPosition = null;
+ this.clickStartTime = null;
+ this.cancelled = true;
+ fastArrayDeleteValueIfContained(ongoingClickDetectors, this);
+ }
+
+ /**
+ * Internal pointer down handler
+ * @param {TouchEvent|MouseEvent} event
+ */
+ internalOnPointerDown(event) {
+ window.focus();
+
+ if (!this.internalEventPreHandler(event, 1)) {
+ return false;
+ }
+
+ const position = /** @type {typeof ClickDetector} */ (this.constructor).extractPointerPosition(event);
+
+ if (event instanceof MouseEvent) {
+ const isRightClick = event.button === 2;
+ if (isRightClick) {
+ // Ignore right clicks
+ this.rightClick.dispatch(position, event);
+ this.cancelled = true;
+ this.clickDownPosition = null;
+ return;
+ }
+ }
+
+ if (this.clickDownPosition) {
+ logger.warn("Ignoring double click");
+ return false;
+ }
+
+ this.cancelled = false;
+ this.touchstart.dispatch(event);
+
+ // Store where the touch started
+ this.clickDownPosition = position;
+ this.clickStartTime = performance.now();
+ this.touchstartSimple.dispatch(this.clickDownPosition.x, this.clickDownPosition.y);
+
+ // If we are not currently within a click, register it
+ if (ongoingClickDetectors.indexOf(this) < 0) {
+ ongoingClickDetectors.push(this);
+ } else {
+ logger.warn("Click detector got pointer down of active pointer twice");
+ }
+
+ // If we should apply any classes, do this now
+ if (this.applyCssClass) {
+ this.element.classList.add(this.applyCssClass);
+ }
+
+ // If we should play any sound, do this
+ if (this.clickSound) {
+ GLOBAL_APP.sound.playUiSound(this.clickSound);
+ }
+
+ return false;
+ }
+
+ /**
+ * Internal pointer move handler
+ * @param {TouchEvent|MouseEvent} event
+ */
+ internalOnPointerMove(event) {
+ if (!this.internalEventPreHandler(event, 1)) {
+ return false;
+ }
+ this.touchmove.dispatch(event);
+ const pos = /** @type {typeof ClickDetector} */ (this.constructor).extractPointerPosition(event);
+ this.touchmoveSimple.dispatch(pos.x, pos.y);
+ return false;
+ }
+
+ /**
+ * Internal pointer end handler
+ * @param {TouchEvent|MouseEvent} event
+ */
+ internalOnPointerEnd(event) {
+ window.focus();
+
+ if (!this.internalEventPreHandler(event, 0)) {
+ return false;
+ }
+
+ if (this.cancelled) {
+ // warn(this, "Not dispatching touchend on cancelled listener");
+ return false;
+ }
+
+ if (event instanceof MouseEvent) {
+ const isRightClick = event.button === 2;
+ if (isRightClick) {
+ return;
+ }
+ }
+
+ const index = ongoingClickDetectors.indexOf(this);
+ if (index < 0) {
+ logger.warn("Got pointer end but click detector is not in pressed state");
+ } else {
+ fastArrayDelete(ongoingClickDetectors, index);
+ }
+
+ let dispatchClick = false;
+ let dispatchClickPos = null;
+
+ // Check for correct down position, otherwise must have pinched or so
+ if (this.clickDownPosition) {
+ const pos = /** @type {typeof ClickDetector} */ (this.constructor).extractPointerPosition(event);
+ const distance = pos.distance(this.clickDownPosition);
+ if (!IS_MOBILE || distance <= this.maxDistance) {
+ dispatchClick = true;
+ dispatchClickPos = pos;
+ } else {
+ console.warn("[ClickDetector] Touch does not count as click:", "(was", distance, ")");
+ }
+ }
+
+ this.clickDownPosition = null;
+ this.clickStartTime = null;
+
+ if (this.applyCssClass) {
+ this.element.classList.remove(this.applyCssClass);
+ }
+
+ // Dispatch in the end to avoid the element getting invalidated
+ // Also make sure that the element is still in the dom
+ if (this.internalIsDomElementAttached()) {
+ this.touchend.dispatch(event);
+ this.touchendSimple.dispatch();
+
+ if (dispatchClick) {
+ const detectors = ongoingClickDetectors.slice();
+ for (let i = 0; i < detectors.length; ++i) {
+ detectors[i].cancelOngoingEvents();
+ }
+ this.click.dispatch(dispatchClickPos, event);
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Internal touch cancel handler
+ * @param {TouchEvent|MouseEvent} event
+ */
+ internalOnTouchCancel(event) {
+ if (!this.internalEventPreHandler(event, 0)) {
+ return false;
+ }
+
+ if (this.cancelled) {
+ // warn(this, "Not dispatching touchcancel on cancelled listener");
+ return false;
+ }
+
+ this.cancelOngoingEvents();
+ this.touchcancel.dispatch(event);
+ this.touchendSimple.dispatch(event);
+ return false;
+ }
+}
diff --git a/src/js/core/compression.ts b/src/js/core/compression.ts
new file mode 100644
index 00000000..e131332b
--- /dev/null
+++ b/src/js/core/compression.ts
@@ -0,0 +1,56 @@
+export interface Compression {
+ compress(data: unknown): Promise;
+ decompress(data: Uint8Array): Promise;
+}
+
+type CompressionWorkerResponse = { result: T; error: null } | { result: null; error: Error };
+
+export class DefaultCompression implements Compression {
+ compress(data: unknown): Promise {
+ const { promise, reject, resolve } = Promise.withResolvers();
+
+ // NOTE: new URL(...) has to be inlined for webpack to process it correctly
+ const worker = new Worker(new URL("../webworkers/compression", import.meta.url));
+ worker.addEventListener("error", ev => reject(ev.message));
+
+ worker.addEventListener("message", ev => {
+ const response = ev.data as CompressionWorkerResponse;
+ if (response.error !== null) {
+ reject(response.error);
+ return;
+ }
+
+ resolve(response.result);
+ });
+
+ this.scheduleWorkerTermination(worker);
+ worker.postMessage(data);
+ return promise;
+ }
+
+ decompress(data: Uint8Array): Promise {
+ const { promise, reject, resolve } = Promise.withResolvers();
+
+ const worker = new Worker(new URL("../webworkers/decompression", import.meta.url));
+ worker.addEventListener("error", ev => reject(new Error(ev.message)));
+
+ worker.addEventListener("message", ev => {
+ const response = ev.data as CompressionWorkerResponse;
+ if (response.error !== null) {
+ reject(response.error);
+ return;
+ }
+
+ resolve(response.result);
+ });
+
+ this.scheduleWorkerTermination(worker);
+ worker.postMessage(data, [data.buffer]);
+ return promise;
+ }
+
+ private scheduleWorkerTermination(worker: Worker): void {
+ worker.addEventListener("message", () => worker.terminate(), { once: true });
+ worker.addEventListener("error", () => worker.terminate(), { once: true });
+ }
+}
diff --git a/src/js/core/config.js b/src/js/core/config.js
deleted file mode 100644
index d5a04832..00000000
--- a/src/js/core/config.js
+++ /dev/null
@@ -1,179 +0,0 @@
-/* typehints:start */
-import { Application } from "../application";
-/* typehints:end */
-
-export const IS_DEBUG =
- G_IS_DEV &&
- typeof window !== "undefined" &&
- window.location.port === "3005" &&
- (window.location.host.indexOf("localhost:") >= 0 || window.location.host.indexOf("192.168.0.") >= 0) &&
- window.location.search.indexOf("nodebug") < 0;
-
-export const SUPPORT_TOUCH = false;
-
-const smoothCanvas = true;
-
-export const THIRDPARTY_URLS = {
- discord: "https://discord.gg/HN7EVzV",
- github: "https://github.com/tobspr-games/shapez.io",
- reddit: "https://www.reddit.com/r/shapezio",
- shapeViewer: "https://viewer.shapez.io",
-
- twitter: "https://twitter.com/tobspr",
- patreon: "https://www.patreon.com/tobsprgames",
- privacyPolicy: "https://tobspr.io/privacy.html",
-
- standaloneCampaignLink: "https://get.shapez.io/bundle/$campaign",
- puzzleDlcStorePage: "https://get.shapez.io/mm_puzzle_dlc?target=dlc",
-
- levelTutorialVideos: {
- 21: "https://www.youtube.com/watch?v=0nUfRLMCcgo&",
- 25: "https://www.youtube.com/watch?v=7OCV1g40Iew&",
- 26: "https://www.youtube.com/watch?v=gfm6dS1dCoY",
- },
-
- modBrowser: "https://shapez.mod.io/",
-};
-
-/**
- * @param {Application} app
- * @param {string} campaign
- */
-export function openStandaloneLink(app, campaign) {
- const discount = globalConfig.currentDiscount > 0 ? "_discount" + globalConfig.currentDiscount : "";
- const steamSuffix = G_IS_STEAM_DEMO ? "_steamdemo" : "";
- const event = campaign + discount + steamSuffix;
- app.platformWrapper.openExternalLink(THIRDPARTY_URLS.standaloneCampaignLink.replace("$campaign", event));
- app.gameAnalytics.noteMinor("g.stdlink." + event);
-}
-
-export const globalConfig = {
- // Size of a single tile in Pixels.
- // NOTICE: Update webpack.production.config too!
- tileSize: 32,
- halfTileSize: 16,
-
- // Which dpi the assets have
- assetsDpi: 192 / 32,
- assetsSharpness: 1.5,
- shapesSharpness: 1.3,
-
- // Achievements
- achievementSliceDuration: 10, // Seconds
-
- // Production analytics
- statisticsGraphDpi: 2.5,
- statisticsGraphSlices: 100,
- analyticsSliceDurationSeconds: G_IS_DEV ? 1 : 10,
-
- minimumTickRate: 25,
- maximumTickRate: 500,
-
- // Map
- mapChunkSize: 16,
- chunkAggregateSize: 4,
- mapChunkOverviewMinZoom: 0.9,
- mapChunkWorldSize: null, // COMPUTED
-
- maxBeltShapeBundleSize: 20,
-
- // Belt speeds
- // NOTICE: Update webpack.production.config too!
- beltSpeedItemsPerSecond: 2,
- minerSpeedItemsPerSecond: 0, // COMPUTED
-
- defaultItemDiameter: 20,
-
- itemSpacingOnBelts: 0.63,
-
- wiresSpeedItemsPerSecond: 6,
-
- undergroundBeltMaxTilesByTier: [5, 9],
-
- readerAnalyzeIntervalSeconds: 10,
-
- goalAcceptorItemsRequired: 12,
- goalAcceptorsPerProducer: 5,
- puzzleModeSpeed: 3,
- puzzleMinBoundsSize: 2,
- puzzleMaxBoundsSize: 20,
- puzzleValidationDurationSeconds: 30,
-
- buildingSpeeds: {
- cutter: 1 / 4,
- cutterQuad: 1 / 4,
- rotater: 1 / 1,
- rotaterCCW: 1 / 1,
- rotater180: 1 / 1,
- painter: 1 / 6,
- painterDouble: 1 / 8,
- painterQuad: 1 / 2,
- mixer: 1 / 5,
- stacker: 1 / 8,
- },
-
- // Zooming
- initialZoom: 1.9,
- minZoomLevel: 0.1,
- maxZoomLevel: 3,
-
- // Global game speed
- gameSpeed: 1,
-
- warmupTimeSecondsFast: 0.25,
- warmupTimeSecondsRegular: 0.25,
-
- smoothing: {
- smoothMainCanvas: smoothCanvas && true,
- quality: "low", // Low is CRUCIAL for mobile performance!
- },
-
- rendering: {},
- debug: require("./config.local").default,
-
- currentDiscount: 0,
-
- // Secret vars
- info: {
- // Binary file salt
- file: "Ec'])@^+*9zMevK3uMV4432x9%iK'=",
-
- // Savegame salt
- sgSalt: "}95Q3%8/.837Lqym_BJx%q7)pAHJbF",
-
- // Analytics key
- analyticsApiKey: "baf6a50f0cc7dfdec5a0e21c88a1c69a4b34bc4a",
- },
-};
-
-export const IS_MOBILE = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent);
-
-// Automatic calculations
-globalConfig.minerSpeedItemsPerSecond = globalConfig.beltSpeedItemsPerSecond / 5;
-
-globalConfig.mapChunkWorldSize = globalConfig.mapChunkSize * globalConfig.tileSize;
-
-// Dynamic calculations
-if (globalConfig.debug.disableMapOverview) {
- globalConfig.mapChunkOverviewMinZoom = 0;
-}
-
-// Stuff for making the trailer
-if (G_IS_DEV && globalConfig.debug.renderForTrailer) {
- globalConfig.debug.framePausesBetweenTicks = 32;
- // globalConfig.mapChunkOverviewMinZoom = 0.0;
- // globalConfig.debug.instantBelts = true;
- // globalConfig.debug.instantProcessors = true;
- // globalConfig.debug.instantMiners = true;
- globalConfig.debug.disableSavegameWrite = true;
- // globalConfig.beltSpeedItemsPerSecond *= 2;
-}
-
-if (globalConfig.debug.fastGameEnter) {
- globalConfig.debug.noArtificialDelays = true;
-}
-
-if (G_IS_DEV && globalConfig.debug.noArtificialDelays) {
- globalConfig.warmupTimeSecondsFast = 0;
- globalConfig.warmupTimeSecondsRegular = 0;
-}
diff --git a/src/js/core/config.local.template.js b/src/js/core/config.local.template.js
index 9a432b56..d1f6cea0 100644
--- a/src/js/core/config.local.template.js
+++ b/src/js/core/config.local.template.js
@@ -1,126 +1,114 @@
-export default {
- // You can set any debug options here!
- /* dev:start */
- // -----------------------------------------------------------------------------------
- // Quickly enters the game and skips the main menu - good for fast iterating
- // fastGameEnter: true,
- // -----------------------------------------------------------------------------------
- // Skips any delays like transitions between states and such
- // noArtificialDelays: true,
- // -----------------------------------------------------------------------------------
- // Disables writing of savegames, useful for testing the same savegame over and over
- // disableSavegameWrite: true,
- // -----------------------------------------------------------------------------------
- // Shows bounds of all entities
- // showEntityBounds: true,
- // -----------------------------------------------------------------------------------
- // Shows arrows for every ejector / acceptor
- // showAcceptorEjectors: true,
- // -----------------------------------------------------------------------------------
- // Disables the music (Overrides any setting, can cause weird behaviour)
- // disableMusic: true,
- // -----------------------------------------------------------------------------------
- // Do not render static map entities (=most buildings)
- // doNotRenderStatics: true,
- // -----------------------------------------------------------------------------------
- // Allow to zoom freely without limits
- // disableZoomLimits: true,
- // -----------------------------------------------------------------------------------
- // All rewards can be unlocked by passing just 1 of any shape
- // rewardsInstant: true,
- // -----------------------------------------------------------------------------------
- // Unlocks all buildings
- // allBuildingsUnlocked: true,
- // -----------------------------------------------------------------------------------
- // Disables cost of blueprints
- // blueprintsNoCost: true,
- // -----------------------------------------------------------------------------------
- // Disables cost of upgrades
- // upgradesNoCost: true,
- // -----------------------------------------------------------------------------------
- // Disables the dialog when completing a level
- // disableUnlockDialog: true,
- // -----------------------------------------------------------------------------------
- // Disables the simulation - This effectively pauses the game.
- // disableLogicTicks: true,
- // -----------------------------------------------------------------------------------
- // Test the rendering if everything is clipped out properly
- // testClipping: true,
- // -----------------------------------------------------------------------------------
- // Allows to render slower, useful for recording at half speed to avoid stuttering
- // framePausesBetweenTicks: 250,
- // -----------------------------------------------------------------------------------
- // Replace all translations with emojis to see which texts are translateable
- // testTranslations: true,
- // -----------------------------------------------------------------------------------
- // Enables an inspector which shows information about the entity below the cursor
- // enableEntityInspector: true,
- // -----------------------------------------------------------------------------------
- // Enables ads in the local build (normally they are deactivated there)
- // testAds: true,
- // -----------------------------------------------------------------------------------
- // Allows unlocked achievements to be logged to console in the local build
- // testAchievements: true,
- // -----------------------------------------------------------------------------------
- // Enables use of (some) existing flags within the puzzle mode context
- // testPuzzleMode: true,
- // -----------------------------------------------------------------------------------
- // Disables the automatic switch to an overview when zooming out
- // disableMapOverview: true,
- // -----------------------------------------------------------------------------------
- // Disables the notification when there are new entries in the changelog since last played
- // disableUpgradeNotification: true,
- // -----------------------------------------------------------------------------------
- // Makes belts almost infinitely fast
- // instantBelts: true,
- // -----------------------------------------------------------------------------------
- // Makes item processors almost infinitely fast
- // instantProcessors: true,
- // -----------------------------------------------------------------------------------
- // Makes miners almost infinitely fast
- // instantMiners: true,
- // -----------------------------------------------------------------------------------
- // When using fastGameEnter, controls whether a new game is started or the last one is resumed
- // resumeGameOnFastEnter: true,
- // -----------------------------------------------------------------------------------
- // Special option used to render the trailer
- // renderForTrailer: true,
- // -----------------------------------------------------------------------------------
- // Whether to render changes
- // renderChanges: true,
- // -----------------------------------------------------------------------------------
- // Whether to render belt paths
- // renderBeltPaths: true,
- // -----------------------------------------------------------------------------------
- // Whether to check belt paths
- // checkBeltPaths: true,
- // -----------------------------------------------------------------------------------
- // Whether to items / s instead of items / m in stats
- // detailedStatistics: true,
- // -----------------------------------------------------------------------------------
- // Shows detailed information about which atlas is used
- // showAtlasInfo: true,
- // -----------------------------------------------------------------------------------
- // Renders the rotation of all wires
- // renderWireRotations: true,
- // -----------------------------------------------------------------------------------
- // Renders information about wire networks
- // renderWireNetworkInfos: true,
- // -----------------------------------------------------------------------------------
- // Disables ejector animations and processing
- // disableEjectorProcessing: true,
- // -----------------------------------------------------------------------------------
- // Allows manual ticking
- // manualTickOnly: true,
- // -----------------------------------------------------------------------------------
- // Disables slow asserts, useful for debugging performance
- // disableSlowAsserts: true,
- // -----------------------------------------------------------------------------------
- // Allows to load a mod from an external source for developing it
- // externalModUrl: "http://localhost:3005/combined.js",
- // -----------------------------------------------------------------------------------
- // Visualizes the shape grouping on belts
- // showShapeGrouping: true
- // -----------------------------------------------------------------------------------
- /* dev:end */
-};
+export default {
+ // You can set any debug options here!
+ /* dev:start */
+ // -----------------------------------------------------------------------------------
+ // Quickly enters the game and skips the main menu - good for fast iterating
+ // fastGameEnter: true,
+ // -----------------------------------------------------------------------------------
+ // Skips any delays like transitions between states and such
+ // noArtificialDelays: true,
+ // -----------------------------------------------------------------------------------
+ // Disables writing of savegames, useful for testing the same savegame over and over
+ // disableSavegameWrite: true,
+ // -----------------------------------------------------------------------------------
+ // Shows bounds of all entities
+ // showEntityBounds: true,
+ // -----------------------------------------------------------------------------------
+ // Shows arrows for every ejector / acceptor
+ // showAcceptorEjectors: true,
+ // -----------------------------------------------------------------------------------
+ // Disables the music (Overrides any setting, can cause weird behaviour)
+ // disableMusic: true,
+ // -----------------------------------------------------------------------------------
+ // Do not render static map entities (=most buildings)
+ // doNotRenderStatics: true,
+ // -----------------------------------------------------------------------------------
+ // Allow to zoom freely without limits
+ // disableZoomLimits: true,
+ // -----------------------------------------------------------------------------------
+ // All rewards can be unlocked by passing just 1 of any shape
+ // rewardsInstant: true,
+ // -----------------------------------------------------------------------------------
+ // Unlocks all buildings
+ // allBuildingsUnlocked: true,
+ // -----------------------------------------------------------------------------------
+ // Disables cost of blueprints
+ // blueprintsNoCost: true,
+ // -----------------------------------------------------------------------------------
+ // Disables cost of upgrades
+ // upgradesNoCost: true,
+ // -----------------------------------------------------------------------------------
+ // Disables the dialog when completing a level
+ // disableUnlockDialog: true,
+ // -----------------------------------------------------------------------------------
+ // Disables the simulation - This effectively pauses the game.
+ // disableLogicTicks: true,
+ // -----------------------------------------------------------------------------------
+ // Test the rendering if everything is clipped out properly
+ // testClipping: true,
+ // -----------------------------------------------------------------------------------
+ // Allows to render slower, useful for recording at half speed to avoid stuttering
+ // framePausesBetweenTicks: 250,
+ // -----------------------------------------------------------------------------------
+ // Replace all translations with emojis to see which texts are translateable
+ // testTranslations: true,
+ // -----------------------------------------------------------------------------------
+ // Enables an inspector which shows information about the entity below the cursor
+ // enableEntityInspector: true,
+ // -----------------------------------------------------------------------------------
+ // Enables use of (some) existing flags within the puzzle mode context
+ // testPuzzleMode: true,
+ // -----------------------------------------------------------------------------------
+ // Disables the automatic switch to an overview when zooming out
+ // disableMapOverview: true,
+ // -----------------------------------------------------------------------------------
+ // Disables the notification when there are new entries in the changelog since last played
+ // disableUpgradeNotification: true,
+ // -----------------------------------------------------------------------------------
+ // Makes belts almost infinitely fast
+ // instantBelts: true,
+ // -----------------------------------------------------------------------------------
+ // Makes item processors almost infinitely fast
+ // instantProcessors: true,
+ // -----------------------------------------------------------------------------------
+ // Makes miners almost infinitely fast
+ // instantMiners: true,
+ // -----------------------------------------------------------------------------------
+ // When using fastGameEnter, controls whether a new game is started or the last one is resumed
+ // resumeGameOnFastEnter: true,
+ // -----------------------------------------------------------------------------------
+ // Whether to render changes
+ // renderChanges: true,
+ // -----------------------------------------------------------------------------------
+ // Whether to render belt paths
+ // renderBeltPaths: true,
+ // -----------------------------------------------------------------------------------
+ // Whether to check belt paths
+ // checkBeltPaths: true,
+ // -----------------------------------------------------------------------------------
+ // Whether to items / s instead of items / m in stats
+ // detailedStatistics: true,
+ // -----------------------------------------------------------------------------------
+ // Shows detailed information about which atlas is used
+ // showAtlasInfo: true,
+ // -----------------------------------------------------------------------------------
+ // Renders the rotation of all wires
+ // renderWireRotations: true,
+ // -----------------------------------------------------------------------------------
+ // Renders information about wire networks
+ // renderWireNetworkInfos: true,
+ // -----------------------------------------------------------------------------------
+ // Disables ejector animations and processing
+ // disableEjectorProcessing: true,
+ // -----------------------------------------------------------------------------------
+ // Allows manual ticking
+ // manualTickOnly: true,
+ // -----------------------------------------------------------------------------------
+ // Disables slow asserts, useful for debugging performance
+ // disableSlowAsserts: true,
+ // -----------------------------------------------------------------------------------
+ // Visualizes the shape grouping on belts
+ // showShapeGrouping: true
+ // -----------------------------------------------------------------------------------
+ /* dev:end */
+};
diff --git a/src/js/core/config.ts b/src/js/core/config.ts
new file mode 100644
index 00000000..aaa116c6
--- /dev/null
+++ b/src/js/core/config.ts
@@ -0,0 +1,105 @@
+import debug from "./config.local";
+
+export const THIRDPARTY_URLS = {
+ discord: "https://discord.gg/HN7EVzV",
+ github: "https://github.com/tobspr-games/shapez.io",
+ reddit: "https://www.reddit.com/r/shapezio",
+ shapeViewer: "https://viewer.shapez.io",
+
+ patreon: "https://www.patreon.com/tobsprgames",
+ privacyPolicy: "https://tobspr.io/privacy.html",
+
+ levelTutorialVideos: {
+ 21: "https://www.youtube.com/watch?v=0nUfRLMCcgo&",
+ 25: "https://www.youtube.com/watch?v=7OCV1g40Iew&",
+ 26: "https://www.youtube.com/watch?v=gfm6dS1dCoY",
+ },
+};
+
+export const globalConfig = {
+ // Size of a single tile in Pixels.
+ tileSize: 32,
+ halfTileSize: 16,
+
+ // Which dpi the assets have
+ assetsDpi: 192 / 32,
+ assetsSharpness: 1.5,
+ shapesSharpness: 1.3,
+
+ // Production analytics
+ statisticsGraphDpi: 2.5,
+ statisticsGraphSlices: 100,
+ analyticsSliceDurationSeconds: G_IS_DEV ? 1 : 10,
+
+ // Map
+ mapChunkSize: 16,
+ chunkAggregateSize: 4,
+ mapChunkOverviewMinZoom: 0.9,
+ mapChunkWorldSize: null, // COMPUTED
+
+ maxBeltShapeBundleSize: 20,
+
+ // Belt speeds
+ beltSpeedItemsPerSecond: 2,
+ minerSpeedItemsPerSecond: 0, // COMPUTED
+
+ defaultItemDiameter: 20,
+
+ itemSpacingOnBelts: 0.63,
+
+ undergroundBeltMaxTilesByTier: [5, 9],
+
+ readerAnalyzeIntervalSeconds: 10,
+
+ goalAcceptorItemsRequired: 12,
+ goalAcceptorsPerProducer: 5,
+ puzzleModeSpeed: 3,
+ puzzleMinBoundsSize: 2,
+ puzzleMaxBoundsSize: 20,
+ puzzleValidationDurationSeconds: 30,
+
+ buildingSpeeds: {
+ cutter: 1 / 4,
+ cutterQuad: 1 / 4,
+ rotator: 1 / 1,
+ rotatorCCW: 1 / 1,
+ rotator180: 1 / 1,
+ painter: 1 / 6,
+ painterDouble: 1 / 8,
+ painterQuad: 1 / 2,
+ mixer: 1 / 5,
+ stacker: 1 / 8,
+ },
+
+ warmupTimeSecondsFast: 0.25,
+ warmupTimeSecondsRegular: 0.25,
+
+ smoothing: {
+ smoothMainCanvas: true,
+ quality: "low" as ImageSmoothingQuality, // Low is CRUCIAL for mobile performance!
+ },
+
+ debug,
+};
+
+export const IS_MOBILE = navigator.userAgentData.mobile;
+export const SUPPORT_TOUCH = IS_MOBILE;
+
+// Automatic calculations
+globalConfig.minerSpeedItemsPerSecond = globalConfig.beltSpeedItemsPerSecond / 5;
+
+globalConfig.mapChunkWorldSize = globalConfig.mapChunkSize * globalConfig.tileSize;
+
+// Dynamic calculations
+if (globalConfig.debug.disableMapOverview) {
+ globalConfig.mapChunkOverviewMinZoom = 0;
+}
+
+if (globalConfig.debug.fastGameEnter) {
+ globalConfig.debug.noArtificialDelays = true;
+}
+
+if (G_IS_DEV && globalConfig.debug.noArtificialDelays) {
+ globalConfig.warmupTimeSecondsFast = 0;
+ globalConfig.warmupTimeSecondsRegular = 0;
+}
diff --git a/src/js/core/dpi_manager.js b/src/js/core/dpi_manager.js
index 4fb792c0..842dd779 100644
--- a/src/js/core/dpi_manager.js
+++ b/src/js/core/dpi_manager.js
@@ -41,13 +41,9 @@ export function prepareHighDPIContext(context, smooth = true) {
if (smooth) {
context.imageSmoothingEnabled = true;
- context.webkitImageSmoothingEnabled = true;
-
- // @ts-ignore
context.imageSmoothingQuality = globalConfig.smoothing.quality;
} else {
context.imageSmoothingEnabled = false;
- context.webkitImageSmoothingEnabled = false;
}
}
diff --git a/src/js/core/draw_parameters.js b/src/js/core/draw_parameters.js
index 95e71bf2..193c788d 100644
--- a/src/js/core/draw_parameters.js
+++ b/src/js/core/draw_parameters.js
@@ -1,25 +1,25 @@
-import { globalConfig } from "./config";
-
-/**
- * @typedef {import("../game/root").GameRoot} GameRoot
- * @typedef {import("./rectangle").Rectangle} Rectangle
- */
-
-export class DrawParameters {
- constructor({ context, visibleRect, desiredAtlasScale, zoomLevel, root }) {
- /** @type {CanvasRenderingContext2D} */
- this.context = context;
-
- /** @type {Rectangle} */
- this.visibleRect = visibleRect;
-
- /** @type {string} */
- this.desiredAtlasScale = desiredAtlasScale;
-
- /** @type {number} */
- this.zoomLevel = zoomLevel;
-
- /** @type {GameRoot} */
- this.root = root;
- }
-}
+import { globalConfig } from "./config";
+
+/**
+ * @typedef {import("../game/root").GameRoot} GameRoot
+ * @typedef {import("./rectangle").Rectangle} Rectangle
+ */
+
+export class DrawParameters {
+ constructor({ context, visibleRect, desiredAtlasScale, zoomLevel, root }) {
+ /** @type {CanvasRenderingContext2D} */
+ this.context = context;
+
+ /** @type {Rectangle} */
+ this.visibleRect = visibleRect;
+
+ /** @type {string} */
+ this.desiredAtlasScale = desiredAtlasScale;
+
+ /** @type {number} */
+ this.zoomLevel = zoomLevel;
+
+ /** @type {GameRoot} */
+ this.root = root;
+ }
+}
diff --git a/src/js/core/draw_utils.js b/src/js/core/draw_utils.js
index d5183cfb..93652d11 100644
--- a/src/js/core/draw_utils.js
+++ b/src/js/core/draw_utils.js
@@ -9,42 +9,6 @@ import { Rectangle } from "./rectangle";
const logger = createLogger("draw_utils");
-export function initDrawUtils() {
- CanvasRenderingContext2D.prototype.beginRoundedRect = function (x, y, w, h, r) {
- this.beginPath();
-
- if (r < 0.05) {
- this.rect(x, y, w, h);
- return;
- }
-
- if (w < 2 * r) {
- r = w / 2;
- }
-
- if (h < 2 * r) {
- r = h / 2;
- }
-
- this.moveTo(x + r, y);
- this.arcTo(x + w, y, x + w, y + h, r);
- this.arcTo(x + w, y + h, x, y + h, r);
- this.arcTo(x, y + h, x, y, r);
- this.arcTo(x, y, x + w, y, r);
- };
-
- CanvasRenderingContext2D.prototype.beginCircle = function (x, y, r) {
- this.beginPath();
-
- if (r < 0.05) {
- this.rect(x, y, 1, 1);
- return;
- }
-
- this.arc(x, y, r, 0, 2.0 * Math.PI);
- };
-}
-
/**
*
* @param {object} param0
@@ -83,8 +47,20 @@ let warningsShown = 0;
* @param {number} param0.h
* @param {number} param0.originalW
* @param {number} param0.originalH
+ * @param {boolean=} param0.pixelAligned
+ * Whether to round the canvas coordinates, to avoid issues with transparency between tiling images
*/
-export function drawSpriteClipped({ parameters, sprite, x, y, w, h, originalW, originalH }) {
+export function drawSpriteClipped({
+ parameters,
+ sprite,
+ x,
+ y,
+ w,
+ h,
+ originalW,
+ originalH,
+ pixelAligned = false,
+}) {
const rect = new Rectangle(x, y, w, h);
const intersection = rect.getIntersection(parameters.visibleRect);
if (!intersection) {
@@ -103,6 +79,39 @@ export function drawSpriteClipped({ parameters, sprite, x, y, w, h, originalW, o
return;
}
+ if (!pixelAligned) {
+ parameters.context.drawImage(
+ sprite,
+
+ // src pos and size
+ ((intersection.x - x) / w) * originalW,
+ ((intersection.y - y) / h) * originalH,
+ (originalW * intersection.w) / w,
+ (originalH * intersection.h) / h,
+
+ // dest pos and size
+ intersection.x,
+ intersection.y,
+ intersection.w,
+ intersection.h
+ );
+ return;
+ }
+
+ const matrix = parameters.context.getTransform();
+ let { x: x1, y: y1 } = matrix.transformPoint(new DOMPoint(intersection.x, intersection.y));
+ let { x: x2, y: y2 } = matrix.transformPoint(
+ new DOMPoint(intersection.x + intersection.w, intersection.y + intersection.h)
+ );
+ x1 = Math.round(x1);
+ y1 = Math.round(y1);
+ x2 = Math.round(x2);
+ y2 = Math.round(y2);
+ if (x2 - x1 == 0 || y2 - y1 == 0) {
+ return;
+ }
+
+ parameters.context.resetTransform();
parameters.context.drawImage(
sprite,
@@ -113,9 +122,10 @@ export function drawSpriteClipped({ parameters, sprite, x, y, w, h, originalW, o
(originalH * intersection.h) / h,
// dest pos and size
- intersection.x,
- intersection.y,
- intersection.w,
- intersection.h
+ x1,
+ y1,
+ x2 - x1,
+ y2 - y1
);
+ parameters.context.setTransform(matrix);
}
diff --git a/src/js/core/error_handler.tsx b/src/js/core/error_handler.tsx
new file mode 100644
index 00000000..e2e3bd38
--- /dev/null
+++ b/src/js/core/error_handler.tsx
@@ -0,0 +1,160 @@
+import { MODS } from "@/mods/modloader";
+import { T } from "@/translations";
+import copy from "clipboard-copy";
+import { BUILD_OPTIONS } from "./globals";
+import { removeAllChildren } from "./utils";
+
+export class ErrorHandler {
+ isActive = true;
+
+ constructor() {
+ window.addEventListener("error", this.onError.bind(this));
+ window.addEventListener("unhandledrejection", this.onUnhandledRejection.bind(this));
+ }
+
+ private onError(ev: ErrorEvent) {
+ if (!this.isActive) {
+ return;
+ }
+
+ // Don't trigger more than once
+ this.isActive = false;
+
+ const screen = new ErrorScreen(ev.error, ev.filename, ev.lineno, ev.colno);
+ screen.show();
+ }
+
+ private onUnhandledRejection(ev: PromiseRejectionEvent) {
+ const error = ev.reason instanceof Error ? ev.reason : new Error(ev.reason);
+
+ // Avoid logging the error twice
+ ev.preventDefault();
+
+ // Turn the unhandled rejection into a regular error event
+ throw new Error("Unhandled Promise rejection", { cause: error });
+ }
+}
+
+export class ErrorScreen {
+ private error: Error;
+ private file?: string;
+ private line?: number;
+ private column?: number;
+
+ constructor(error: Error, file?: string, line?: number, column?: number) {
+ this.error = error;
+ this.file = file;
+ this.line = line;
+ this.column = column;
+ }
+
+ show() {
+ // Set the global to stop future callback handlers
+ window.APP_ERROR_OCCURED = true;
+
+ removeAllChildren(document.body);
+ document.body.id = "errorHandler";
+ document.body.className = "";
+
+ const layout = this.createLayout();
+ if (Array.isArray(layout)) {
+ document.body.append(...layout);
+ } else {
+ document.body.append(layout);
+ }
+ }
+
+ private createLayout(): HTMLElement | HTMLElement[] {
+ const btnCopy = {T.errorHandler.actions.copy} ;
+ const btnRestart = {T.errorHandler.actions.restart} ;
+
+ btnCopy.addEventListener("click", this.copyErrorLog.bind(this));
+ btnRestart.addEventListener("click", this.restart.bind(this));
+
+ return (
+ <>
+
+ {this.recursiveStack}
+
+ {T.errorHandler.labels.loadedMods}
+
{this.loadedMods}
+
+
+
+ {btnCopy}
+ {btnRestart}
+
+ >
+ );
+ }
+
+ private copyErrorLog(ev: MouseEvent) {
+ let log = `shapez Error Log - ${new Date().toISOString()}\n\n`;
+
+ log += this.recursiveStack;
+ log += `\n\nLoaded Mods:\n${this.loadedMods}`;
+ log += `\n\nBuild Information:\n${this.buildInformation}`;
+
+ copy(log);
+
+ if (ev.target instanceof HTMLButtonElement) {
+ ev.target.innerText = T.errorHandler.actions.copyDone;
+ ev.target.classList.add("success");
+ }
+ }
+
+ private restart() {
+ // performRestart may not be available yet
+ location.reload();
+ }
+
+ private get source(): string {
+ return `${this.file} (${this.line}:${this.column})`;
+ }
+
+ private get recursiveStack(): string {
+ // Follow the error cause chain
+ let current = this.error;
+ let stack = current.stack;
+
+ while (current.cause instanceof Error) {
+ current = current.cause;
+ stack += `\nCaused by: ${current.stack}`;
+ }
+
+ return stack;
+ }
+
+ private get loadedMods(): string {
+ const mods: string[] = [];
+ const activeMods = MODS.activeMods;
+
+ for (const mod of MODS.allMods) {
+ const isActive = activeMods.includes(mod);
+ const prefix = isActive ? "*" : "";
+
+ const id = mod.mod.id;
+ const version = mod.mod.metadata.version;
+
+ mods.push(`${prefix}${id}@${version} (${mod.source})`);
+ }
+
+ return mods.join("\n");
+ }
+
+ private get buildInformation(): string {
+ const info: string[] = [];
+
+ for (const [key, value] of Object.entries(BUILD_OPTIONS)) {
+ info.push(`${key}: ${JSON.stringify(value)}`);
+ }
+
+ return info.join("\n");
+ }
+}
diff --git a/src/js/core/factory.js b/src/js/core/factory.ts
similarity index 69%
rename from src/js/core/factory.js
rename to src/js/core/factory.ts
index f2587f69..b30513b4 100644
--- a/src/js/core/factory.js
+++ b/src/js/core/factory.ts
@@ -3,21 +3,19 @@ import { createLogger } from "./logging";
const logger = createLogger("factory");
// simple factory pattern
-export class Factory {
- constructor(id) {
- this.id = id;
+export class Factory {
+ // Store array as well as dictionary, to speed up lookups
+ public entries: Class[] = [];
+ public entryIds: string[] = [];
+ public idToEntry: Record> = {};
- // Store array as well as dictionary, to speed up lookups
- this.entries = [];
- this.entryIds = [];
- this.idToEntry = {};
- }
+ constructor(public id: string) {}
getId() {
return this.id;
}
- register(entry) {
+ register(entry: Class & { getId(): string }) {
// Extract id
const id = entry.getId();
assert(id, "Factory: Invalid id for class: " + entry);
@@ -33,19 +31,15 @@ export class Factory {
/**
* Checks if a given id is registered
- * @param {string} id
- * @returns {boolean}
*/
- hasId(id) {
+ hasId(id: string): boolean {
return !!this.idToEntry[id];
}
/**
* Finds an instance by a given id
- * @param {string} id
- * @returns {object}
*/
- findById(id) {
+ findById(id: string): Class {
const entry = this.idToEntry[id];
if (!entry) {
logger.error("Object with id", id, "is not registered on factory", this.id, "!");
@@ -57,25 +51,22 @@ export class Factory {
/**
* Returns all entries
- * @returns {Array}
*/
- getEntries() {
+ getEntries(): Class[] {
return this.entries;
}
/**
* Returns all registered ids
- * @returns {Array}
*/
- getAllIds() {
+ getAllIds(): string[] {
return this.entryIds;
}
/**
* Returns amount of stored entries
- * @returns {number}
*/
- getNumEntries() {
+ getNumEntries(): number {
return this.entries.length;
}
}
diff --git a/src/js/core/game_state.js b/src/js/core/game_state.ts
similarity index 68%
rename from src/js/core/game_state.js
rename to src/js/core/game_state.ts
index 6f276e99..1a452ca1 100644
--- a/src/js/core/game_state.js
+++ b/src/js/core/game_state.ts
@@ -1,15 +1,12 @@
-/* typehints:start */
-import { Application } from "../application";
-import { StateManager } from "./state_manager";
-/* typehints:end */
-
-import { globalConfig } from "./config";
+import { MUSIC } from "@/platform/sound";
+import type { Application } from "../application";
import { ClickDetector } from "./click_detector";
-import { logSection, createLogger } from "./logging";
+import { globalConfig } from "./config";
import { InputReceiver } from "./input_receiver";
-import { waitNextFrame } from "./utils";
+import { createLogger, logSection } from "./logging";
import { RequestChannel } from "./request_channel";
-import { MUSIC } from "../platform/sound";
+import type { StateManager } from "./state_manager";
+import { waitNextFrame } from "./utils";
const logger = createLogger("game_state");
@@ -17,49 +14,41 @@ const logger = createLogger("game_state");
* Basic state of the game state machine. This is the base of the whole game
*/
export class GameState {
+ public app: Application = null;
+ public readonly key: string;
+ public inputReceiver: InputReceiver;
+
+ /** A channel we can use to perform async ops */
+ protected asyncChannel = new RequestChannel();
+ protected clickDetectors: ClickDetector[] = [];
+
+ /** @todo review this */
+ protected htmlElement: HTMLElement | undefined;
+
+ private stateManager: StateManager = null;
+
+ /** Store if we are currently fading out */
+ private fadingOut = false;
+
/**
* Constructs a new state with the given id
- * @param {string} key The id of the state. We use ids to refer to states because otherwise we get
- * circular references
+ * @param key The id of the state. We use ids to refer to states because otherwise we get
+ * circular references
*/
- constructor(key) {
+ constructor(key: string) {
this.key = key;
- /** @type {StateManager} */
- this.stateManager = null;
-
- /** @type {Application} */
- this.app = null;
-
- // Store if we are currently fading out
- this.fadingOut = false;
-
- /** @type {Array} */
- this.clickDetectors = [];
-
// Every state captures keyboard events by default
- this.inputReciever = new InputReceiver("state-" + key);
- this.inputReciever.backButton.add(this.onBackButton, this);
-
- // A channel we can use to perform async ops
- this.asyncChannel = new RequestChannel();
+ this.inputReceiver = new InputReceiver("state-" + key);
+ this.inputReceiver.backButton.add(this.onBackButton, this);
}
//// GETTERS / HELPER METHODS ////
- /**
- * Returns the states key
- * @returns {string}
- */
- getKey() {
- return this.key;
- }
-
/**
* Returns the html element of the state
- * @returns {HTMLElement}
*/
- getDivElement() {
+ getDivElement(): HTMLElement {
return document.getElementById("state_" + this.key);
}
@@ -120,9 +109,9 @@ export class GameState {
/**
* Callback when entering the state, to be overriddemn
- * @param {any} payload Arbitrary data passed from the state which we are transferring from
+ * @param payload Arbitrary data passed from the state which we are transferring from
*/
- onEnter(payload) {}
+ onEnter(payload: {}) {}
/**
* Callback when leaving the state
@@ -141,22 +130,22 @@ export class GameState {
/**
* Render callback
- * @param {number} dt Delta time in ms since last render
+ * @param dt Delta time in ms since last render
*/
- onRender(dt) {}
+ onRender(dt: number) {}
/**
* Background tick callback, called while the game is inactiev
- * @param {number} dt Delta time in ms since last tick
+ * @param dt Delta time in ms since last tick
*/
- onBackgroundTick(dt) {}
+ onBackgroundTick(dt: number) {}
/**
* Called when the screen resized
- * @param {number} w window/screen width
- * @param {number} h window/screen height
+ * @param w window/screen width
+ * @param h window/screen height
*/
- onResized(w, h) {}
+ onResized(w: number, h: number) {}
/**
* Internal backbutton handler, called when the hardware back button is pressed or
@@ -168,9 +157,9 @@ export class GameState {
/**
* Should return how many mulliseconds to fade in / out the state. Not recommended to override!
- * @returns {number} Time in milliseconds to fade out
+ * @returns Time in milliseconds to fade out
*/
- getInOutFadeTime() {
+ getInOutFadeTime(): number {
if (globalConfig.debug.noArtificialDelays) {
return 0;
}
@@ -180,39 +169,45 @@ export class GameState {
/**
* Should return whether to fade in the game state. This will then apply the right css classes
* for the fadein.
- * @returns {boolean}
*/
- getHasFadeIn() {
+ getHasFadeIn(): boolean {
return true;
}
/**
* Should return whether to fade out the game state. This will then apply the right css classes
* for the fadeout and wait the delay before moving states
- * @returns {boolean}
*/
- getHasFadeOut() {
+ getHasFadeOut(): boolean {
return true;
}
/**
* Returns if this state should get paused if it does not have focus
- * @returns {boolean} true to pause the updating of the game
+ * @returns true to pause the updating of the game
*/
- getPauseOnFocusLost() {
+ getPauseOnFocusLost(): boolean {
return true;
}
/**
* Should return the html code of the state.
- * @returns {string}
- * @abstract
+ * @deprecated use {@link getContentLayout} instead
*/
- getInnerHTML() {
- abstract;
+ getInnerHTML(): string {
return "";
}
+ /**
+ * Should return the element(s) to be displayed in the state.
+ * If not overridden, {@link getInnerHTML} will be used to provide the layout.
+ */
+ protected getContentLayout(): Node {
+ const template = document.createElement("template");
+ template.innerHTML = this.getInnerHTML();
+ return template.content;
+ }
+
/**
* Returns if the state has an unload confirmation, this is the
* "Are you sure you want to leave the page" message.
@@ -223,25 +218,22 @@ export class GameState {
/**
* Should return the theme music for this state
- * @returns {string|null}
*/
- getThemeMusic() {
+ getThemeMusic(): string | null {
return MUSIC.menu;
}
/**
* Should return true if the player is currently ingame
- * @returns {boolean}
*/
- getIsIngame() {
+ getIsIngame(): boolean {
return false;
}
/**
* Should return whether to clear the whole body content before entering the state.
- * @returns {boolean}
*/
- getRemovePreviousContent() {
+ getRemovePreviousContent(): boolean {
return true;
}
@@ -251,9 +243,8 @@ export class GameState {
/**
* Internal callback from the manager. Do not override!
- * @param {StateManager} stateManager
*/
- internalRegisterCallback(stateManager, app) {
+ internalRegisterCallback(stateManager: StateManager, app: Application) {
assert(stateManager, "No state manager");
assert(app, "No app");
this.stateManager = stateManager;
@@ -262,12 +253,12 @@ export class GameState {
/**
* Internal callback when entering the state. Do not override!
- * @param {any} payload Arbitrary data passed from the state which we are transferring from
- * @param {boolean} callCallback Whether to call the onEnter callback
+ * @param payload Arbitrary data passed from the state which we are transferring from
+ * @param callCallback Whether to call the onEnter callback
*/
- internalEnterCallback(payload, callCallback = true) {
+ internalEnterCallback(payload: any, callCallback = true) {
logSection(this.key, "#26a69a");
- this.app.inputMgr.pushReciever(this.inputReciever);
+ this.app.inputMgr.pushReceiver(this.inputReceiver);
this.htmlElement = this.getDivElement();
this.htmlElement.classList.add("active");
@@ -293,7 +284,7 @@ export class GameState {
this.onLeave();
this.htmlElement.classList.remove("active");
- this.app.inputMgr.popReciever(this.inputReciever);
+ this.app.inputMgr.popReceiver(this.inputReceiver);
this.internalCleanUpClickDetectors();
this.asyncChannel.cancelAll();
}
@@ -325,18 +316,27 @@ export class GameState {
}
/**
- * Internal method to get the HTML of the game state.
- * @returns {string}
+ * Internal method to get all elements of the game state. Can be
+ * called from subclasses to provide support for both HTMLElements
+ * and HTML strings.
*/
- internalGetFullHtml() {
- return this.getInnerHTML();
+ internalGetWrappedContent(): Node {
+ const elements = this.getContentLayout();
+
+ if (Array.isArray(elements)) {
+ const fragment = document.createDocumentFragment();
+ fragment.append(...(elements as Node[]));
+ return fragment;
+ }
+
+ return elements;
}
/**
* Internal method to compute the time to fade in / out
- * @returns {number} time to fade in / out in ms
+ * @returns time to fade in / out in ms
*/
- internalGetFadeInOutTime() {
+ internalGetFadeInOutTime(): number {
if (G_IS_DEV && globalConfig.debug.fastGameEnter) {
return 1;
}
diff --git a/src/js/core/global_registries.js b/src/js/core/global_registries.js
deleted file mode 100644
index 723bf567..00000000
--- a/src/js/core/global_registries.js
+++ /dev/null
@@ -1,39 +0,0 @@
-import { SingletonFactory } from "./singleton_factory";
-import { Factory } from "./factory";
-
-/**
- * @typedef {import("../game/time/base_game_speed").BaseGameSpeed} BaseGameSpeed
- * @typedef {import("../game/component").Component} Component
- * @typedef {import("../game/base_item").BaseItem} BaseItem
- * @typedef {import("../game/game_mode").GameMode} GameMode
- * @typedef {import("../game/meta_building").MetaBuilding} MetaBuilding
-
-
-// These factories are here to remove circular dependencies
-
-/** @type {SingletonFactoryTemplate} */
-export let gMetaBuildingRegistry = new SingletonFactory();
-
-/** @type {Object.>>} */
-export let gBuildingsByCategory = null;
-
-/** @type {FactoryTemplate} */
-export let gComponentRegistry = new Factory("component");
-
-/** @type {FactoryTemplate} */
-export let gGameModeRegistry = new Factory("gameMode");
-
-/** @type {FactoryTemplate} */
-export let gGameSpeedRegistry = new Factory("gamespeed");
-
-/** @type {FactoryTemplate} */
-export let gItemRegistry = new Factory("item");
-
-// Helpers
-
-/**
- * @param {Object.>>} buildings
- */
-export function initBuildingsByCategory(buildings) {
- gBuildingsByCategory = buildings;
-}
diff --git a/src/js/core/global_registries.ts b/src/js/core/global_registries.ts
new file mode 100644
index 00000000..10780474
--- /dev/null
+++ b/src/js/core/global_registries.ts
@@ -0,0 +1,20 @@
+import type { BaseGameSpeed } from "../game/time/base_game_speed";
+import type { Component } from "../game/component";
+import type { BaseItem } from "../game/base_item";
+import type { GameMode } from "../game/game_mode";
+import type { MetaBuilding } from "../game/meta_building";
+
+import { SingletonFactory } from "./singleton_factory";
+import { Factory } from "./factory";
+
+// These factories are here to remove circular dependencies
+
+export const gMetaBuildingRegistry = new SingletonFactory("metaBuilding");
+
+export const gComponentRegistry = new Factory("component");
+
+export const gGameModeRegistry = new Factory("gameMode");
+
+export const gGameSpeedRegistry = new Factory("gameSpeed");
+
+export const gItemRegistry = new Factory("item");
diff --git a/src/js/core/globals.js b/src/js/core/globals.js
index 55238e85..4d901996 100644
--- a/src/js/core/globals.js
+++ b/src/js/core/globals.js
@@ -12,19 +12,14 @@ export let GLOBAL_APP = null;
* @param {Application} app
*/
export function setGlobalApp(app) {
- assert(!GLOBAL_APP, "Create application twice!");
+ assert(!GLOBAL_APP, "Tried to set GLOBAL_APP twice");
GLOBAL_APP = app;
}
export const BUILD_OPTIONS = {
- HAVE_ASSERT: G_HAVE_ASSERT,
APP_ENVIRONMENT: G_APP_ENVIRONMENT,
- CHINA_VERSION: G_CHINA_VERSION,
- WEGAME_VERSION: G_WEGAME_VERSION,
IS_DEV: G_IS_DEV,
IS_RELEASE: G_IS_RELEASE,
- IS_BROWSER: G_IS_BROWSER,
- IS_STANDALONE: G_IS_STANDALONE,
BUILD_TIME: G_BUILD_TIME,
BUILD_COMMIT_HASH: G_BUILD_COMMIT_HASH,
BUILD_VERSION: G_BUILD_VERSION,
diff --git a/src/js/core/input_distributor.js b/src/js/core/input_distributor.ts
similarity index 52%
rename from src/js/core/input_distributor.js
rename to src/js/core/input_distributor.ts
index be5440a9..dad0417b 100644
--- a/src/js/core/input_distributor.js
+++ b/src/js/core/input_distributor.ts
@@ -1,139 +1,104 @@
-/* typehints:start */
-import { Application } from "../application";
-import { InputReceiver } from "./input_receiver";
-/* typehints:end */
+import type { Application } from "../application";
+import type { InputReceiver, ReceiverId } from "./input_receiver";
-import { Signal, STOP_PROPAGATION } from "./signal";
import { createLogger } from "./logging";
+import { Signal, STOP_PROPAGATION } from "./signal";
import { arrayDeleteValue, fastArrayDeleteValue } from "./utils";
const logger = createLogger("input_distributor");
export class InputDistributor {
+ public receiverStack: InputReceiver[] = [];
+ public filters: ((arg: string) => boolean)[] = [];
+
/**
- *
- * @param {Application} app
+ * All keys which are currently down
*/
- constructor(app) {
- this.app = app;
-
- /** @type {Array} */
- this.recieverStack = [];
-
- /** @type {Array} */
- this.filters = [];
-
- /**
- * All keys which are currently down
- */
- this.keysDown = new Set();
+ public keysDown = new Set();
+ constructor(public app: Application) {
this.bindToEvents();
}
/**
* Attaches a new filter which can filter and reject events
- * @param {function(any): boolean} filter
*/
- installFilter(filter) {
+ installFilter(filter: (arg: string) => boolean) {
this.filters.push(filter);
}
/**
* Removes an attached filter
- * @param {function(any) : boolean} filter
*/
- dismountFilter(filter) {
+ dismountFilter(filter: (arg: string) => boolean) {
fastArrayDeleteValue(this.filters, filter);
}
- /**
- * @param {InputReceiver} reciever
- */
- pushReciever(reciever) {
- if (this.isRecieverAttached(reciever)) {
- assert(false, "Can not add reciever " + reciever.context + " twice");
- logger.error("Can not add reciever", reciever.context, "twice");
+ pushReceiver(receiver: InputReceiver) {
+ if (this.isReceiverAttached(receiver)) {
+ assert(false, "Can not add receiver " + receiver.context + " twice");
+ logger.error("Can not add receiver", receiver.context, "twice");
return;
}
- this.recieverStack.push(reciever);
+ this.receiverStack.push(receiver);
- if (this.recieverStack.length > 10) {
+ if (this.receiverStack.length > 10) {
logger.error(
- "Reciever stack is huge, probably some dead receivers arround:",
- this.recieverStack.map(x => x.context)
+ "Receiver stack is huge, probably some dead receivers arround:",
+ this.receiverStack.map(x => x.context)
);
}
}
- /**
- * @param {InputReceiver} reciever
- */
- popReciever(reciever) {
- if (this.recieverStack.indexOf(reciever) < 0) {
- assert(false, "Can not pop reciever " + reciever.context + " since its not contained");
- logger.error("Can not pop reciever", reciever.context, "since its not contained");
+ popReceiver(receiver: InputReceiver) {
+ if (this.receiverStack.indexOf(receiver) < 0) {
+ assert(false, "Can not pop receiver " + receiver.context + " since its not contained");
+ logger.error("Can not pop receiver", receiver.context, "since its not contained");
return;
}
- if (this.recieverStack[this.recieverStack.length - 1] !== reciever) {
+ if (this.receiverStack[this.receiverStack.length - 1] !== receiver) {
logger.warn(
- "Popping reciever",
- reciever.context,
+ "Popping receiver",
+ receiver.context,
"which is not on top of the stack. Stack is: ",
- this.recieverStack.map(x => x.context)
+ this.receiverStack.map(x => x.context)
);
}
- arrayDeleteValue(this.recieverStack, reciever);
+ arrayDeleteValue(this.receiverStack, receiver);
}
- /**
- * @param {InputReceiver} reciever
- */
- isRecieverAttached(reciever) {
- return this.recieverStack.indexOf(reciever) >= 0;
+ isReceiverAttached(receiver: InputReceiver) {
+ return this.receiverStack.indexOf(receiver) >= 0;
}
- /**
- * @param {InputReceiver} reciever
- */
- isRecieverOnTop(reciever) {
+ isReceiverOnTop(receiver: InputReceiver) {
return (
- this.isRecieverAttached(reciever) &&
- this.recieverStack[this.recieverStack.length - 1] === reciever
+ this.isReceiverAttached(receiver) &&
+ this.receiverStack[this.receiverStack.length - 1] === receiver
);
}
- /**
- * @param {InputReceiver} reciever
- */
- makeSureAttachedAndOnTop(reciever) {
- this.makeSureDetached(reciever);
- this.pushReciever(reciever);
+ makeSureAttachedAndOnTop(receiver: InputReceiver) {
+ this.makeSureDetached(receiver);
+ this.pushReceiver(receiver);
}
- /**
- * @param {InputReceiver} reciever
- */
- makeSureDetached(reciever) {
- if (this.isRecieverAttached(reciever)) {
- arrayDeleteValue(this.recieverStack, reciever);
+ makeSureDetached(receiver: InputReceiver) {
+ if (this.isReceiverAttached(receiver)) {
+ arrayDeleteValue(this.receiverStack, receiver);
}
}
- /**
- *
- * @param {InputReceiver} reciever
- */
- destroyReceiver(reciever) {
- this.makeSureDetached(reciever);
- reciever.cleanup();
+ destroyReceiver(receiver: InputReceiver) {
+ this.makeSureDetached(receiver);
+ receiver.cleanup();
}
// Internal
- getTopReciever() {
- if (this.recieverStack.length > 0) {
- return this.recieverStack[this.recieverStack.length - 1];
+ getTopReceiver() {
+ if (this.receiverStack.length > 0) {
+ return this.receiverStack[this.receiverStack.length - 1];
}
return null;
}
@@ -153,7 +118,10 @@ export class InputDistributor {
document.addEventListener("paste", this.handlePaste.bind(this));
}
- forwardToReceiver(eventId, payload = null) {
+ forwardToReceiver(
+ eventId: T,
+ payload: Parameters[0] = null
+ ) {
// Check filters
for (let i = 0; i < this.filters.length; ++i) {
if (!this.filters[i](eventId)) {
@@ -161,20 +129,18 @@ export class InputDistributor {
}
}
- const reciever = this.getTopReciever();
- if (!reciever) {
- logger.warn("Dismissing event because not reciever was found:", eventId);
+ const receiver = this.getTopReceiver();
+ if (!receiver) {
+ logger.warn("Dismissing event because not receiver was found:", eventId);
return;
}
- const signal = reciever[eventId];
+ const signal = receiver[eventId];
assert(signal instanceof Signal, "Not a valid event id");
- return signal.dispatch(payload);
+ // probably not possible to type properly, since the types of `signal` and `payload` are correlated
+ return signal.dispatch(payload as never);
}
- /**
- * @param {Event} event
- */
- handleBackButton(event) {
+ handleBackButton(event: Event) {
event.preventDefault();
event.stopPropagation();
this.forwardToReceiver("backButton");
@@ -184,21 +150,15 @@ export class InputDistributor {
* Handles when the page got blurred
*/
handleBlur() {
- this.forwardToReceiver("pageBlur", {});
+ this.forwardToReceiver("pageBlur");
this.keysDown.clear();
}
- /**
- *
- */
- handlePaste(ev) {
+ handlePaste(ev: ClipboardEvent) {
this.forwardToReceiver("paste", ev);
}
- /**
- * @param {KeyboardEvent | MouseEvent} event
- */
- handleKeyMouseDown(event) {
+ handleKeyMouseDown(event: KeyboardEvent | MouseEvent) {
const keyCode = event instanceof MouseEvent ? event.button + 1 : event.keyCode;
if (
keyCode === 4 || // MB4
@@ -236,10 +196,7 @@ export class InputDistributor {
}
}
- /**
- * @param {KeyboardEvent | MouseEvent} event
- */
- handleKeyMouseUp(event) {
+ handleKeyMouseUp(event: KeyboardEvent | MouseEvent) {
const keyCode = event instanceof MouseEvent ? event.button + 1 : event.keyCode;
this.keysDown.delete(keyCode);
diff --git a/src/js/core/input_receiver.js b/src/js/core/input_receiver.js
deleted file mode 100644
index 164ab84b..00000000
--- a/src/js/core/input_receiver.js
+++ /dev/null
@@ -1,27 +0,0 @@
-import { Signal } from "./signal";
-
-export class InputReceiver {
- constructor(context = "unknown") {
- this.context = context;
-
- this.backButton = new Signal();
-
- this.keydown = new Signal();
- this.keyup = new Signal();
- this.pageBlur = new Signal();
-
- // Dispatched on destroy
- this.destroyed = new Signal();
-
- this.paste = new Signal();
- }
-
- cleanup() {
- this.backButton.removeAll();
- this.keydown.removeAll();
- this.keyup.removeAll();
- this.paste.removeAll();
-
- this.destroyed.dispatch();
- }
-}
diff --git a/src/js/core/input_receiver.ts b/src/js/core/input_receiver.ts
new file mode 100644
index 00000000..da9a4934
--- /dev/null
+++ b/src/js/core/input_receiver.ts
@@ -0,0 +1,47 @@
+import { Signal } from "./signal";
+
+export type KeydownEvent = {
+ keyCode: number;
+ shift: boolean;
+ alt: boolean;
+ ctrl: boolean;
+ initial: boolean;
+ event: KeyboardEvent | MouseEvent;
+};
+export type KeyupEvent = {
+ keyCode: number;
+ shift: boolean;
+ alt: boolean;
+};
+
+export class InputReceiver {
+ public backButton = new Signal();
+
+ public keydown = new Signal<[KeydownEvent]>();
+ public keyup = new Signal<[KeyupEvent]>();
+ public pageBlur = new Signal();
+
+ // Dispatched on destroy
+ public destroyed = new Signal();
+
+ public paste = new Signal<[ClipboardEvent]>();
+
+ constructor(public context: string = "unknown") {}
+
+ cleanup() {
+ this.backButton.removeAll();
+ this.keydown.removeAll();
+ this.keyup.removeAll();
+ this.paste.removeAll();
+
+ this.destroyed.dispatch();
+ }
+}
+
+export type ReceiverId = keyof {
+ [K in keyof InputReceiver as InputReceiver[K] extends Signal
+ ? K extends "destroyed"
+ ? never
+ : K
+ : never]: unknown;
+};
diff --git a/src/js/core/keycodes.ts b/src/js/core/keycodes.ts
new file mode 100644
index 00000000..d2e1df33
--- /dev/null
+++ b/src/js/core/keycodes.ts
@@ -0,0 +1,194 @@
+import { T } from "@/translations";
+
+export function keyToKeyCode(key: string) {
+ return key.toUpperCase().charCodeAt(0);
+}
+
+export const KEYCODES = {
+ Tab: 9,
+ Enter: 13,
+
+ Shift: 16,
+ Ctrl: 17,
+ Alt: 18,
+
+ Escape: 27,
+
+ Space: 32,
+
+ ArrowLeft: 37,
+ ArrowUp: 38,
+ ArrowRight: 39,
+ ArrowDown: 40,
+
+ Delete: 46,
+
+ F1: 112,
+ F2: 113,
+ F3: 114,
+ F4: 115,
+ F5: 116,
+ F6: 117,
+ F7: 118,
+ F8: 119,
+ F9: 120,
+ F10: 121,
+ F11: 122,
+ F12: 123,
+
+ Plus: 187,
+ Minus: 189,
+};
+
+export const KEYCODE_LMB = 1;
+export const KEYCODE_MMB = 2;
+export const KEYCODE_RMB = 3;
+
+export function getStringForKeyCode(code: number): string {
+ // @todo: Refactor into dictionary
+ switch (code) {
+ case KEYCODE_LMB:
+ return "LMB";
+ case KEYCODE_MMB:
+ return "MMB";
+ case KEYCODE_RMB:
+ return "RMB";
+ case 4:
+ return "MB4";
+ case 5:
+ return "MB5";
+ case 8:
+ return "⌫";
+ case KEYCODES.Tab:
+ return T.global.keys.tab;
+ case KEYCODES.Enter:
+ return "⏎";
+ case KEYCODES.Shift:
+ return "⇪";
+ case KEYCODES.Ctrl:
+ return T.global.keys.control;
+ case KEYCODES.Alt:
+ return T.global.keys.alt;
+ case 19:
+ return "PAUSE";
+ case 20:
+ return "CAPS";
+ case KEYCODES.Escape:
+ return T.global.keys.escape;
+ case KEYCODES.Space:
+ return T.global.keys.space;
+ case 33:
+ return "PGUP";
+ case 34:
+ return "PGDOWN";
+ case 35:
+ return "END";
+ case 36:
+ return "HOME";
+ case KEYCODES.ArrowLeft:
+ return "⬅";
+ case KEYCODES.ArrowUp:
+ return "⬆";
+ case KEYCODES.ArrowRight:
+ return "➡";
+ case KEYCODES.ArrowDown:
+ return "⬇";
+ case 44:
+ return "PRNT";
+ case 45:
+ return "INS";
+ case 46:
+ return "DEL";
+ case 93:
+ return "SEL";
+ case 96:
+ return "NUM 0";
+ case 97:
+ return "NUM 1";
+ case 98:
+ return "NUM 2";
+ case 99:
+ return "NUM 3";
+ case 100:
+ return "NUM 4";
+ case 101:
+ return "NUM 5";
+ case 102:
+ return "NUM 6";
+ case 103:
+ return "NUM 7";
+ case 104:
+ return "NUM 8";
+ case 105:
+ return "NUM 9";
+ case 106:
+ return "*";
+ case 107:
+ return "+";
+ case 109:
+ return "-";
+ case 110:
+ return ".";
+ case 111:
+ return "/";
+ case KEYCODES.F1:
+ return "F1";
+ case KEYCODES.F2:
+ return "F2";
+ case KEYCODES.F3:
+ return "F3";
+ case KEYCODES.F4:
+ return "F4";
+ case KEYCODES.F5:
+ return "F5";
+ case KEYCODES.F6:
+ return "F6";
+ case KEYCODES.F7:
+ return "F7";
+ case KEYCODES.F8:
+ return "F8";
+ case KEYCODES.F9:
+ return "F9";
+ case KEYCODES.F10:
+ return "F10";
+ case KEYCODES.F11:
+ return "F11";
+ case KEYCODES.F12:
+ return "F12";
+
+ case 144:
+ return "NUMLOCK";
+ case 145:
+ return "SCRLOCK";
+ case 182:
+ return "COMP";
+ case 183:
+ return "CALC";
+ case 186:
+ return ";";
+ case 187:
+ return "+";
+ case 188:
+ return ",";
+ case 189:
+ return "-";
+ case 190:
+ return ".";
+ case 191:
+ return "/";
+ case 192:
+ return "`";
+ case 219:
+ return "[";
+ case 220:
+ return "\\";
+ case 221:
+ return "]";
+ case 222:
+ return "'";
+ }
+
+ return (48 <= code && code <= 57) || (65 <= code && code <= 90)
+ ? String.fromCharCode(code)
+ : "[" + code + "]";
+}
diff --git a/src/js/core/loader.js b/src/js/core/loader.js
index 29afa123..d9f4bbe0 100644
--- a/src/js/core/loader.js
+++ b/src/js/core/loader.js
@@ -1,208 +1,207 @@
-import { makeOffscreenBuffer } from "./buffer_utils";
-import { AtlasSprite, BaseSprite, RegularSprite, SpriteAtlasLink } from "./sprites";
-import { cachebust } from "./cachebust";
-import { createLogger } from "./logging";
-
-/**
- * @typedef {import("../application").Application} Application
- * @typedef {import("./atlas_definitions").AtlasDefinition} AtlasDefinition;
- */
-
-const logger = createLogger("loader");
-
-const missingSpriteIds = {};
-
-class LoaderImpl {
- constructor() {
- this.app = null;
-
- /** @type {Map} */
- this.sprites = new Map();
-
- this.rawImages = [];
- }
-
- /**
- * @param {Application} app
- */
- linkAppAfterBoot(app) {
- this.app = app;
- this.makeSpriteNotFoundCanvas();
- }
-
- /**
- * Fetches a given sprite from the cache
- * @param {string} key
- * @returns {BaseSprite}
- */
- getSpriteInternal(key) {
- const sprite = this.sprites.get(key);
- if (!sprite) {
- if (!missingSpriteIds[key]) {
- // Only show error once
- missingSpriteIds[key] = true;
- logger.error("Sprite '" + key + "' not found!");
- }
- return this.spriteNotFoundSprite;
- }
- return sprite;
- }
-
- /**
- * Returns an atlas sprite from the cache
- * @param {string} key
- * @returns {AtlasSprite}
- */
- getSprite(key) {
- const sprite = this.getSpriteInternal(key);
- assert(sprite instanceof AtlasSprite || sprite === this.spriteNotFoundSprite, "Not an atlas sprite");
- return /** @type {AtlasSprite} */ (sprite);
- }
-
- /**
- * Returns a regular sprite from the cache
- * @param {string} key
- * @returns {RegularSprite}
- */
- getRegularSprite(key) {
- const sprite = this.getSpriteInternal(key);
- assert(
- sprite instanceof RegularSprite || sprite === this.spriteNotFoundSprite,
- "Not a regular sprite"
- );
- return /** @type {RegularSprite} */ (sprite);
- }
-
- /**
- *
- * @param {string} key
- * @param {(progress: number) => void} progressHandler
- * @returns {Promise}
- */
- internalPreloadImage(key, progressHandler) {
- return this.app.backgroundResourceLoader
- .preloadWithProgress("res/" + key, progress => {
- progressHandler(progress);
- })
- .then(url => {
- return new Promise((resolve, reject) => {
- const image = new Image();
- image.addEventListener("load", () => resolve(image));
- image.addEventListener("error", err =>
- reject("Failed to load sprite " + key + ": " + err)
- );
- image.src = url;
- });
- });
- }
-
- /**
- * Preloads a sprite
- * @param {string} key
- * @param {(progress: number) => void} progressHandler
- * @returns {Promise}
- */
- preloadCSSSprite(key, progressHandler) {
- return this.internalPreloadImage(key, progressHandler).then(image => {
- if (key.indexOf("game_misc") >= 0) {
- // Allow access to regular sprites
- this.sprites.set(key, new RegularSprite(image, image.width, image.height));
- }
- this.rawImages.push(image);
- });
- }
-
- /**
- * Preloads an atlas
- * @param {AtlasDefinition} atlas
- * @param {(progress: number) => void} progressHandler
- * @returns {Promise}
- */
- preloadAtlas(atlas, progressHandler) {
- return this.internalPreloadImage(atlas.getFullSourcePath(), progressHandler).then(image => {
- // @ts-ignore
- image.label = atlas.sourceFileName;
- return this.internalParseAtlas(atlas, image);
- });
- }
-
- /**
- *
- * @param {AtlasDefinition} atlas
- * @param {HTMLImageElement} loadedImage
- */
- internalParseAtlas({ meta: { scale }, sourceData }, loadedImage) {
- this.rawImages.push(loadedImage);
-
- for (const spriteName in sourceData) {
- const { frame, sourceSize, spriteSourceSize } = sourceData[spriteName];
-
- let sprite = /** @type {AtlasSprite} */ (this.sprites.get(spriteName));
-
- if (!sprite) {
- sprite = new AtlasSprite(spriteName);
- this.sprites.set(spriteName, sprite);
- }
- if (sprite.frozen) {
- continue;
- }
-
- const link = new SpriteAtlasLink({
- packedX: frame.x,
- packedY: frame.y,
- packedW: frame.w,
- packedH: frame.h,
- packOffsetX: spriteSourceSize.x,
- packOffsetY: spriteSourceSize.y,
- atlas: loadedImage,
- w: sourceSize.w,
- h: sourceSize.h,
- });
-
- sprite.linksByResolution[scale] = link;
- }
- }
-
- /**
- * Makes the canvas which shows the question mark, shown when a sprite was not found
- */
- makeSpriteNotFoundCanvas() {
- const dims = 128;
-
- const [canvas, context] = makeOffscreenBuffer(dims, dims, {
- smooth: false,
- label: "not-found-sprite",
- });
- context.fillStyle = "#f77";
- context.fillRect(0, 0, dims, dims);
-
- context.textAlign = "center";
- context.textBaseline = "middle";
- context.fillStyle = "#eee";
- context.font = "25px Arial";
- context.fillText("???", dims / 2, dims / 2);
-
- // TODO: Not sure why this is set here
- // @ts-ignore
- canvas.src = "not-found";
-
- const sprite = new AtlasSprite("not-found");
- ["0.1", "0.25", "0.5", "0.75", "1"].forEach(resolution => {
- sprite.linksByResolution[resolution] = new SpriteAtlasLink({
- packedX: 0,
- packedY: 0,
- w: dims,
- h: dims,
- packOffsetX: 0,
- packOffsetY: 0,
- packedW: dims,
- packedH: dims,
- atlas: canvas,
- });
- });
-
- this.spriteNotFoundSprite = sprite;
- }
-}
-
-export const Loader = new LoaderImpl();
+import { makeOffscreenBuffer } from "./buffer_utils";
+import { AtlasSprite, BaseSprite, RegularSprite, SpriteAtlasLink } from "./sprites";
+import { createLogger } from "./logging";
+
+/**
+ * @typedef {import("../application").Application} Application
+ * @typedef {import("./atlas_definitions").AtlasDefinition} AtlasDefinition;
+ */
+
+const logger = createLogger("loader");
+
+const missingSpriteIds = {};
+
+class LoaderImpl {
+ constructor() {
+ this.app = null;
+
+ /** @type {Map} */
+ this.sprites = new Map();
+
+ this.rawImages = [];
+ }
+
+ /**
+ * @param {Application} app
+ */
+ linkAppAfterBoot(app) {
+ this.app = app;
+ this.makeSpriteNotFoundCanvas();
+ }
+
+ /**
+ * Fetches a given sprite from the cache
+ * @param {string} key
+ * @returns {BaseSprite}
+ */
+ getSpriteInternal(key) {
+ const sprite = this.sprites.get(key);
+ if (!sprite) {
+ if (!missingSpriteIds[key]) {
+ // Only show error once
+ missingSpriteIds[key] = true;
+ logger.error("Sprite '" + key + "' not found!");
+ }
+ return this.spriteNotFoundSprite;
+ }
+ return sprite;
+ }
+
+ /**
+ * Returns an atlas sprite from the cache
+ * @param {string} key
+ * @returns {AtlasSprite}
+ */
+ getSprite(key) {
+ const sprite = this.getSpriteInternal(key);
+ assert(sprite instanceof AtlasSprite || sprite === this.spriteNotFoundSprite, "Not an atlas sprite");
+ return /** @type {AtlasSprite} */ (sprite);
+ }
+
+ /**
+ * Returns a regular sprite from the cache
+ * @param {string} key
+ * @returns {RegularSprite}
+ */
+ getRegularSprite(key) {
+ const sprite = this.getSpriteInternal(key);
+ assert(
+ sprite instanceof RegularSprite || sprite === this.spriteNotFoundSprite,
+ "Not a regular sprite"
+ );
+ return /** @type {RegularSprite} */ (sprite);
+ }
+
+ /**
+ *
+ * @param {string} key
+ * @param {(progress: number) => void} progressHandler
+ * @returns {Promise}
+ */
+ internalPreloadImage(key, progressHandler) {
+ return this.app.backgroundResourceLoader
+ .preloadWithProgress("res/" + key, progress => {
+ progressHandler(progress);
+ })
+ .then(url => {
+ return new Promise((resolve, reject) => {
+ const image = new Image();
+ image.addEventListener("load", () => resolve(image));
+ image.addEventListener("error", err =>
+ reject("Failed to load sprite " + key + ": " + err)
+ );
+ image.src = url;
+ });
+ });
+ }
+
+ /**
+ * Preloads a sprite
+ * @param {string} key
+ * @param {(progress: number) => void} progressHandler
+ * @returns {Promise}
+ */
+ preloadCSSSprite(key, progressHandler) {
+ return this.internalPreloadImage(key, progressHandler).then(image => {
+ if (key.indexOf("game_misc") >= 0) {
+ // Allow access to regular sprites
+ this.sprites.set(key, new RegularSprite(image, image.width, image.height));
+ }
+ this.rawImages.push(image);
+ });
+ }
+
+ /**
+ * Preloads an atlas
+ * @param {AtlasDefinition} atlas
+ * @param {(progress: number) => void} progressHandler
+ * @returns {Promise}
+ */
+ preloadAtlas(atlas, progressHandler) {
+ return this.internalPreloadImage(atlas.getFullSourcePath(), progressHandler).then(image => {
+ // @ts-ignore
+ image.label = atlas.sourceFileName;
+ return this.internalParseAtlas(atlas, image);
+ });
+ }
+
+ /**
+ *
+ * @param {AtlasDefinition} atlas
+ * @param {HTMLImageElement} loadedImage
+ */
+ internalParseAtlas({ meta: { scale }, sourceData }, loadedImage) {
+ this.rawImages.push(loadedImage);
+
+ for (const spriteName in sourceData) {
+ const { frame, sourceSize, spriteSourceSize } = sourceData[spriteName];
+
+ let sprite = /** @type {AtlasSprite} */ (this.sprites.get(spriteName));
+
+ if (!sprite) {
+ sprite = new AtlasSprite(spriteName);
+ this.sprites.set(spriteName, sprite);
+ }
+ if (sprite.frozen) {
+ continue;
+ }
+
+ const link = new SpriteAtlasLink({
+ packedX: frame.x,
+ packedY: frame.y,
+ packedW: frame.w,
+ packedH: frame.h,
+ packOffsetX: spriteSourceSize.x,
+ packOffsetY: spriteSourceSize.y,
+ atlas: loadedImage,
+ w: sourceSize.w,
+ h: sourceSize.h,
+ });
+
+ sprite.linksByResolution[scale] = link;
+ }
+ }
+
+ /**
+ * Makes the canvas which shows the question mark, shown when a sprite was not found
+ */
+ makeSpriteNotFoundCanvas() {
+ const dims = 128;
+
+ const [canvas, context] = makeOffscreenBuffer(dims, dims, {
+ smooth: false,
+ label: "not-found-sprite",
+ });
+ context.fillStyle = "#f77";
+ context.fillRect(0, 0, dims, dims);
+
+ context.textAlign = "center";
+ context.textBaseline = "middle";
+ context.fillStyle = "#eee";
+ context.font = "25px Arial";
+ context.fillText("???", dims / 2, dims / 2);
+
+ // TODO: Not sure why this is set here
+ // @ts-ignore
+ canvas.src = "not-found";
+
+ const sprite = new AtlasSprite("not-found");
+ ["0.1", "0.25", "0.5", "0.75", "1"].forEach(resolution => {
+ sprite.linksByResolution[resolution] = new SpriteAtlasLink({
+ packedX: 0,
+ packedY: 0,
+ w: dims,
+ h: dims,
+ packOffsetX: 0,
+ packOffsetY: 0,
+ packedW: dims,
+ packedH: dims,
+ atlas: canvas,
+ });
+ });
+
+ this.spriteNotFoundSprite = sprite;
+ }
+}
+
+export const Loader = new LoaderImpl();
diff --git a/src/js/core/logging.js b/src/js/core/logging.js
deleted file mode 100644
index f3e938e5..00000000
--- a/src/js/core/logging.js
+++ /dev/null
@@ -1,247 +0,0 @@
-import { globalConfig } from "../core/config";
-const circularJson = require("circular-json");
-
-/*
-Logging functions
-- To be extended
-*/
-
-/**
- * Base logger class
- */
-class Logger {
- constructor(context) {
- this.context = context;
- }
-
- debug(...args) {
- globalDebug(this.context, ...args);
- }
-
- log(...args) {
- globalLog(this.context, ...args);
- }
-
- warn(...args) {
- globalWarn(this.context, ...args);
- }
-
- error(...args) {
- globalError(this.context, ...args);
- }
-}
-
-export function createLogger(context) {
- return new Logger(context);
-}
-
-function prepareObjectForLogging(obj, maxDepth = 1) {
- if (!window.Sentry) {
- // Not required without sentry
- return obj;
- }
-
- if (typeof obj !== "object" && !Array.isArray(obj)) {
- return obj;
- }
- const result = {};
- for (const key in obj) {
- const val = obj[key];
-
- if (typeof val === "object") {
- if (maxDepth > 0) {
- result[key] = prepareObjectForLogging(val, maxDepth - 1);
- } else {
- result[key] = "[object]";
- }
- } else {
- result[key] = val;
- }
- }
- return result;
-}
-
-/**
- * Serializes an error
- * @param {Error|ErrorEvent} err
- */
-export function serializeError(err) {
- if (!err) {
- return null;
- }
- const result = {
- type: err.constructor.name,
- };
-
- if (err instanceof Error) {
- result.message = err.message;
- result.name = err.name;
- result.stack = err.stack;
- result.type = "{type.Error}";
- } else if (err instanceof ErrorEvent) {
- result.filename = err.filename;
- result.message = err.message;
- result.lineno = err.lineno;
- result.colno = err.colno;
- result.type = "{type.ErrorEvent}";
-
- if (err.error) {
- result.error = serializeError(err.error);
- } else {
- result.error = "{not-provided}";
- }
- } else {
- result.type = "{unkown-type:" + typeof err + "}";
- }
-
- return result;
-}
-
-/**
- * Serializes an event
- * @param {Event} event
- */
-function serializeEvent(event) {
- let result = {
- type: "{type.Event:" + typeof event + "}",
- };
- result.eventType = event.type;
- return result;
-}
-
-/**
- * Prepares a json payload
- * @param {string} key
- * @param {any} value
- */
-function preparePayload(key, value) {
- if (value instanceof Error || value instanceof ErrorEvent) {
- return serializeError(value);
- }
- if (value instanceof Event) {
- return serializeEvent(value);
- }
- if (typeof value === "undefined") {
- return null;
- }
- return value;
-}
-
-/**
- * Stringifies an object containing circular references and errors
- * @param {any} payload
- */
-export function stringifyObjectContainingErrors(payload) {
- return circularJson.stringify(payload, preparePayload);
-}
-
-export function globalDebug(context, ...args) {
- if (G_IS_DEV) {
- logInternal(context, console.log, prepareArgsForLogging(args));
- }
-}
-
-export function globalLog(context, ...args) {
- // eslint-disable-next-line no-console
- logInternal(context, console.log, prepareArgsForLogging(args));
-}
-
-export function globalWarn(context, ...args) {
- // eslint-disable-next-line no-console
- logInternal(context, console.warn, prepareArgsForLogging(args));
-}
-
-export function globalError(context, ...args) {
- args = prepareArgsForLogging(args);
- // eslint-disable-next-line no-console
- logInternal(context, console.error, args);
-
- if (window.Sentry) {
- window.Sentry.withScope(scope => {
- scope.setExtra("args", args);
- window.Sentry.captureMessage(internalBuildStringFromArgs(args), "error");
- });
- }
-}
-
-function prepareArgsForLogging(args) {
- let result = [];
- for (let i = 0; i < args.length; ++i) {
- result.push(prepareObjectForLogging(args[i]));
- }
- return result;
-}
-
-/**
- * @param {Array} args
- */
-function internalBuildStringFromArgs(args) {
- let result = [];
-
- for (let i = 0; i < args.length; ++i) {
- let arg = args[i];
- if (
- typeof arg === "string" ||
- typeof arg === "number" ||
- typeof arg === "boolean" ||
- arg === null ||
- arg === undefined
- ) {
- result.push("" + arg);
- } else if (arg instanceof Error) {
- result.push(arg.message);
- } else {
- result.push("[object]");
- }
- }
- return result.join(" ");
-}
-
-export function logSection(name, color) {
- while (name.length <= 14) {
- name = " " + name + " ";
- }
- name = name.padEnd(19, " ");
-
- const lineCss =
- "letter-spacing: -3px; color: " + color + "; font-size: 6px; background: #eee; color: #eee;";
- const line = "%c----------------------------";
- console.log("\n" + line + " %c" + name + " " + line + "\n", lineCss, "color: " + color, lineCss);
-}
-
-function extractHandleContext(handle) {
- let context = handle || "unknown";
- if (handle && handle.constructor && handle.constructor.name) {
- context = handle.constructor.name;
- if (context === "String") {
- context = handle;
- }
- }
-
- if (handle && handle.name) {
- context = handle.name;
- }
- return context + "";
-}
-
-function logInternal(handle, consoleMethod, args) {
- const context = extractHandleContext(handle).padEnd(20, " ");
- const labelColor = handle && handle.LOG_LABEL_COLOR ? handle.LOG_LABEL_COLOR : "#aaa";
-
- if (G_IS_DEV && globalConfig.debug.logTimestamps) {
- const timestamp = "⏱ %c" + (Math.floor(performance.now()) + "").padEnd(6, " ") + "";
- consoleMethod.call(
- console,
- timestamp + " %c" + context,
- "color: #7f7;",
- "color: " + labelColor + ";",
- ...args
- );
- } else {
- // if (G_IS_DEV && !globalConfig.debug.disableLoggingLogSources) {
- consoleMethod.call(console, "%c" + context, "color: " + labelColor, ...args);
- // } else {
- // consoleMethod.call(console, ...args);
- // }
- }
-}
diff --git a/src/js/core/logging.ts b/src/js/core/logging.ts
new file mode 100644
index 00000000..3e958789
--- /dev/null
+++ b/src/js/core/logging.ts
@@ -0,0 +1,60 @@
+export class Logger {
+ /**
+ * A simple {@link console} wrapper that retains the location of log calls.
+ * @param context Label to be displayed in each log message
+ * @param color Optional label color override
+ * @param debug Whether to log {@link Logger.debug} messages
+ */
+ constructor(context: string, color = "#aaa", debug = G_IS_DEV) {
+ const label = "%c" + context.padEnd(20, " ");
+ const style = `color: ${color}`;
+
+ if (debug) {
+ this.debug = console.debug.bind(console, label, style);
+ }
+
+ this.log = console.log.bind(console, label, style);
+ this.warn = console.warn.bind(console, label, style);
+ this.error = console.error.bind(console, label, style);
+ }
+
+ // @ts-expect-error parameters are actually used
+ debug(...args: unknown[]) {}
+ // @ts-expect-error same
+ log(...args: unknown[]) {}
+ // @ts-expect-error same
+ warn(...args: unknown[]) {}
+ // @ts-expect-error same
+ error(...args: unknown[]) {}
+}
+
+/**
+ * @deprecated Use the {@link Logger} constructor instead
+ * @param handle Object to be used as the logger label
+ * @returns A {@link Logger} instance
+ */
+export function createLogger(handle: unknown) {
+ const context = extractHandleContext(handle);
+ return new Logger(context);
+}
+
+export function logSection(name, color) {
+ while (name.length <= 14) {
+ name = " " + name + " ";
+ }
+ name = name.padEnd(19, " ");
+
+ const lineCss =
+ "letter-spacing: -3px; color: " + color + "; font-size: 6px; background: #eee; color: #eee;";
+ const line = "%c----------------------------";
+ console.log("\n" + line + " %c" + name + " " + line + "\n", lineCss, "color: " + color, lineCss);
+}
+
+function extractHandleContext(handle: unknown) {
+ handle ??= "unknown";
+ if (typeof handle === "string") {
+ return handle;
+ }
+
+ return handle.constructor.name;
+}
diff --git a/src/js/core/lzstring.js b/src/js/core/lzstring.js
deleted file mode 100644
index 79d0523c..00000000
--- a/src/js/core/lzstring.js
+++ /dev/null
@@ -1,493 +0,0 @@
-// Copyright (c) 2013 Pieroxy
-// This work is free. You can redistribute it and/or modify it
-// under the terms of the WTFPL, Version 2
-// For more information see LICENSE.txt or http://www.wtfpl.net/
-//
-// For more information, the home page:
-// http://pieroxy.net/blog/pages/lz-string/testing.html
-//
-// LZ-based compression algorithm, version 1.4.4
-
-const fromCharCode = String.fromCharCode;
-const hasOwnProperty = Object.prototype.hasOwnProperty;
-
-const keyStrUriSafe = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-$";
-const baseReverseDic = {};
-
-function getBaseValue(alphabet, character) {
- if (!baseReverseDic[alphabet]) {
- baseReverseDic[alphabet] = {};
- for (let i = 0; i < alphabet.length; i++) {
- baseReverseDic[alphabet][alphabet.charAt(i)] = i;
- }
- }
- return baseReverseDic[alphabet][character];
-}
-
-//compress into uint8array (UCS-2 big endian format)
-export function compressU8(uncompressed) {
- let compressed = compress(uncompressed);
- let buf = new Uint8Array(compressed.length * 2); // 2 bytes per character
-
- for (let i = 0, TotalLen = compressed.length; i < TotalLen; i++) {
- let current_value = compressed.charCodeAt(i);
- buf[i * 2] = current_value >>> 8;
- buf[i * 2 + 1] = current_value % 256;
- }
- return buf;
-}
-
-// Compreses with header
-/**
- * @param {string} uncompressed
- * @param {number} header
- */
-export function compressU8WHeader(uncompressed, header) {
- let compressed = compress(uncompressed);
- let buf = new Uint8Array(2 + compressed.length * 2); // 2 bytes per character
-
- buf[0] = header >>> 8;
- buf[1] = header % 256;
- for (let i = 0, TotalLen = compressed.length; i < TotalLen; i++) {
- let current_value = compressed.charCodeAt(i);
- buf[2 + i * 2] = current_value >>> 8;
- buf[2 + i * 2 + 1] = current_value % 256;
- }
- return buf;
-}
-
-//decompress from uint8array (UCS-2 big endian format)
-/**
- *
- * @param {Uint8Array} compressed
- */
-export function decompressU8WHeader(compressed) {
- // let buf = new Array(compressed.length / 2); // 2 bytes per character
- // for (let i = 0, TotalLen = buf.length; i < TotalLen; i++) {
- // buf[i] = compressed[i * 2] * 256 + compressed[i * 2 + 1];
- // }
-
- // let result = [];
- // buf.forEach(function (c) {
- // result.push(fromCharCode(c));
- // });
- let result = [];
- for (let i = 2, n = compressed.length; i < n; i += 2) {
- const code = compressed[i] * 256 + compressed[i + 1];
- result.push(fromCharCode(code));
- }
- return decompress(result.join(""));
-}
-
-//compress into a string that is already URI encoded
-export function compressX64(input) {
- if (input == null) return "";
- return _compress(input, 6, function (a) {
- return keyStrUriSafe.charAt(a);
- });
-}
-
-//decompress from an output of compressToEncodedURIComponent
-export function decompressX64(input) {
- if (input == null) return "";
- if (input == "") return null;
- input = input.replace(/ /g, "+");
- return _decompress(input.length, 32, function (index) {
- return getBaseValue(keyStrUriSafe, input.charAt(index));
- });
-}
-
-function compress(uncompressed) {
- return _compress(uncompressed, 16, function (a) {
- return fromCharCode(a);
- });
-}
-
-function _compress(uncompressed, bitsPerChar, getCharFromInt) {
- if (uncompressed == null) return "";
- let i,
- value,
- context_dictionary = {},
- context_dictionaryToCreate = {},
- context_c = "",
- context_wc = "",
- context_w = "",
- context_enlargeIn = 2, // Compensate for the first entry which should not count
- context_dictSize = 3,
- context_numBits = 2,
- context_data = [],
- context_data_val = 0,
- context_data_position = 0,
- ii;
-
- for (ii = 0; ii < uncompressed.length; ii += 1) {
- context_c = uncompressed.charAt(ii);
- if (!hasOwnProperty.call(context_dictionary, context_c)) {
- context_dictionary[context_c] = context_dictSize++;
- context_dictionaryToCreate[context_c] = true;
- }
-
- context_wc = context_w + context_c;
- if (hasOwnProperty.call(context_dictionary, context_wc)) {
- context_w = context_wc;
- } else {
- if (hasOwnProperty.call(context_dictionaryToCreate, context_w)) {
- if (context_w.charCodeAt(0) < 256) {
- for (i = 0; i < context_numBits; i++) {
- context_data_val = context_data_val << 1;
- if (context_data_position == bitsPerChar - 1) {
- context_data_position = 0;
- context_data.push(getCharFromInt(context_data_val));
- context_data_val = 0;
- } else {
- context_data_position++;
- }
- }
- value = context_w.charCodeAt(0);
- for (i = 0; i < 8; i++) {
- context_data_val = (context_data_val << 1) | (value & 1);
- if (context_data_position == bitsPerChar - 1) {
- context_data_position = 0;
- context_data.push(getCharFromInt(context_data_val));
- context_data_val = 0;
- } else {
- context_data_position++;
- }
- value = value >> 1;
- }
- } else {
- value = 1;
- for (i = 0; i < context_numBits; i++) {
- context_data_val = (context_data_val << 1) | value;
- if (context_data_position == bitsPerChar - 1) {
- context_data_position = 0;
- context_data.push(getCharFromInt(context_data_val));
- context_data_val = 0;
- } else {
- context_data_position++;
- }
- value = 0;
- }
- value = context_w.charCodeAt(0);
- for (i = 0; i < 16; i++) {
- context_data_val = (context_data_val << 1) | (value & 1);
- if (context_data_position == bitsPerChar - 1) {
- context_data_position = 0;
- context_data.push(getCharFromInt(context_data_val));
- context_data_val = 0;
- } else {
- context_data_position++;
- }
- value = value >> 1;
- }
- }
- context_enlargeIn--;
- if (context_enlargeIn == 0) {
- context_enlargeIn = Math.pow(2, context_numBits);
- context_numBits++;
- }
- delete context_dictionaryToCreate[context_w];
- } else {
- value = context_dictionary[context_w];
- for (i = 0; i < context_numBits; i++) {
- context_data_val = (context_data_val << 1) | (value & 1);
- if (context_data_position == bitsPerChar - 1) {
- context_data_position = 0;
- context_data.push(getCharFromInt(context_data_val));
- context_data_val = 0;
- } else {
- context_data_position++;
- }
- value = value >> 1;
- }
- }
- context_enlargeIn--;
- if (context_enlargeIn == 0) {
- context_enlargeIn = Math.pow(2, context_numBits);
- context_numBits++;
- }
- // Add wc to the dictionary.
- context_dictionary[context_wc] = context_dictSize++;
- context_w = String(context_c);
- }
- }
-
- // Output the code for w.
- if (context_w !== "") {
- if (hasOwnProperty.call(context_dictionaryToCreate, context_w)) {
- if (context_w.charCodeAt(0) < 256) {
- for (i = 0; i < context_numBits; i++) {
- context_data_val = context_data_val << 1;
- if (context_data_position == bitsPerChar - 1) {
- context_data_position = 0;
- context_data.push(getCharFromInt(context_data_val));
- context_data_val = 0;
- } else {
- context_data_position++;
- }
- }
- value = context_w.charCodeAt(0);
- for (i = 0; i < 8; i++) {
- context_data_val = (context_data_val << 1) | (value & 1);
- if (context_data_position == bitsPerChar - 1) {
- context_data_position = 0;
- context_data.push(getCharFromInt(context_data_val));
- context_data_val = 0;
- } else {
- context_data_position++;
- }
- value = value >> 1;
- }
- } else {
- value = 1;
- for (i = 0; i < context_numBits; i++) {
- context_data_val = (context_data_val << 1) | value;
- if (context_data_position == bitsPerChar - 1) {
- context_data_position = 0;
- context_data.push(getCharFromInt(context_data_val));
- context_data_val = 0;
- } else {
- context_data_position++;
- }
- value = 0;
- }
- value = context_w.charCodeAt(0);
- for (i = 0; i < 16; i++) {
- context_data_val = (context_data_val << 1) | (value & 1);
- if (context_data_position == bitsPerChar - 1) {
- context_data_position = 0;
- context_data.push(getCharFromInt(context_data_val));
- context_data_val = 0;
- } else {
- context_data_position++;
- }
- value = value >> 1;
- }
- }
- context_enlargeIn--;
- if (context_enlargeIn == 0) {
- context_enlargeIn = Math.pow(2, context_numBits);
- context_numBits++;
- }
- delete context_dictionaryToCreate[context_w];
- } else {
- value = context_dictionary[context_w];
- for (i = 0; i < context_numBits; i++) {
- context_data_val = (context_data_val << 1) | (value & 1);
- if (context_data_position == bitsPerChar - 1) {
- context_data_position = 0;
- context_data.push(getCharFromInt(context_data_val));
- context_data_val = 0;
- } else {
- context_data_position++;
- }
- value = value >> 1;
- }
- }
- context_enlargeIn--;
- if (context_enlargeIn == 0) {
- context_enlargeIn = Math.pow(2, context_numBits);
- context_numBits++;
- }
- }
-
- // Mark the end of the stream
- value = 2;
- for (i = 0; i < context_numBits; i++) {
- context_data_val = (context_data_val << 1) | (value & 1);
- if (context_data_position == bitsPerChar - 1) {
- context_data_position = 0;
- context_data.push(getCharFromInt(context_data_val));
- context_data_val = 0;
- } else {
- context_data_position++;
- }
- value = value >> 1;
- }
-
- // Flush the last char
- // eslint-disable-next-line no-constant-condition
- while (true) {
- context_data_val = context_data_val << 1;
- if (context_data_position == bitsPerChar - 1) {
- context_data.push(getCharFromInt(context_data_val));
- break;
- } else context_data_position++;
- }
- return context_data.join("");
-}
-
-function decompress(compressed) {
- if (compressed == null) return "";
- if (compressed == "") return null;
- return _decompress(compressed.length, 32768, function (index) {
- return compressed.charCodeAt(index);
- });
-}
-
-function _decompress(length, resetValue, getNextValue) {
- let dictionary = [],
- next,
- enlargeIn = 4,
- dictSize = 4,
- numBits = 3,
- entry = "",
- result = [],
- i,
- w,
- bits,
- resb,
- maxpower,
- power,
- c,
- data = { val: getNextValue(0), position: resetValue, index: 1 };
-
- for (i = 0; i < 3; i += 1) {
- dictionary[i] = i;
- }
-
- bits = 0;
- maxpower = Math.pow(2, 2);
- power = 1;
- while (power != maxpower) {
- resb = data.val & data.position;
- data.position >>= 1;
- if (data.position == 0) {
- data.position = resetValue;
- data.val = getNextValue(data.index++);
- }
- bits |= (resb > 0 ? 1 : 0) * power;
- power <<= 1;
- }
-
- switch ((next = bits)) {
- case 0:
- bits = 0;
- maxpower = Math.pow(2, 8);
- power = 1;
- while (power != maxpower) {
- resb = data.val & data.position;
- data.position >>= 1;
- if (data.position == 0) {
- data.position = resetValue;
- data.val = getNextValue(data.index++);
- }
- bits |= (resb > 0 ? 1 : 0) * power;
- power <<= 1;
- }
- c = fromCharCode(bits);
- break;
- case 1:
- bits = 0;
- maxpower = Math.pow(2, 16);
- power = 1;
- while (power != maxpower) {
- resb = data.val & data.position;
- data.position >>= 1;
- if (data.position == 0) {
- data.position = resetValue;
- data.val = getNextValue(data.index++);
- }
- bits |= (resb > 0 ? 1 : 0) * power;
- power <<= 1;
- }
- c = fromCharCode(bits);
- break;
- case 2:
- return "";
- }
- dictionary[3] = c;
- w = c;
- result.push(c);
-
- // eslint-disable-next-line no-constant-condition
- while (true) {
- if (data.index > length) {
- return "";
- }
-
- bits = 0;
- maxpower = Math.pow(2, numBits);
- power = 1;
- while (power != maxpower) {
- resb = data.val & data.position;
- data.position >>= 1;
- if (data.position == 0) {
- data.position = resetValue;
- data.val = getNextValue(data.index++);
- }
- bits |= (resb > 0 ? 1 : 0) * power;
- power <<= 1;
- }
-
- switch ((c = bits)) {
- case 0:
- bits = 0;
- maxpower = Math.pow(2, 8);
- power = 1;
- while (power != maxpower) {
- resb = data.val & data.position;
- data.position >>= 1;
- if (data.position == 0) {
- data.position = resetValue;
- data.val = getNextValue(data.index++);
- }
- bits |= (resb > 0 ? 1 : 0) * power;
- power <<= 1;
- }
-
- dictionary[dictSize++] = fromCharCode(bits);
- c = dictSize - 1;
- enlargeIn--;
- break;
- case 1:
- bits = 0;
- maxpower = Math.pow(2, 16);
- power = 1;
- while (power != maxpower) {
- resb = data.val & data.position;
- data.position >>= 1;
- if (data.position == 0) {
- data.position = resetValue;
- data.val = getNextValue(data.index++);
- }
- bits |= (resb > 0 ? 1 : 0) * power;
- power <<= 1;
- }
- dictionary[dictSize++] = fromCharCode(bits);
- c = dictSize - 1;
- enlargeIn--;
- break;
- case 2:
- return result.join("");
- }
-
- if (enlargeIn == 0) {
- enlargeIn = Math.pow(2, numBits);
- numBits++;
- }
-
- if (dictionary[c]) {
- // @ts-ignore
- entry = dictionary[c];
- } else {
- if (c === dictSize) {
- entry = w + w.charAt(0);
- } else {
- return null;
- }
- }
- result.push(entry);
-
- // Add w+entry[0] to the dictionary.
- dictionary[dictSize++] = w + entry.charAt(0);
- enlargeIn--;
-
- w = entry;
-
- if (enlargeIn == 0) {
- enlargeIn = Math.pow(2, numBits);
- numBits++;
- }
- }
-}
diff --git a/src/js/core/modal_dialog_elements.js b/src/js/core/modal_dialog_elements.ts
similarity index 72%
rename from src/js/core/modal_dialog_elements.js
rename to src/js/core/modal_dialog_elements.ts
index e90f322d..90353132 100644
--- a/src/js/core/modal_dialog_elements.js
+++ b/src/js/core/modal_dialog_elements.ts
@@ -1,467 +1,504 @@
-/* typehints:start */
-import { Application } from "../application";
-/* typehints:end */
-
-import { Signal, STOP_PROPAGATION } from "./signal";
-import { arrayDeleteValue, waitNextFrame } from "./utils";
-import { ClickDetector } from "./click_detector";
-import { SOUNDS } from "../platform/sound";
-import { InputReceiver } from "./input_receiver";
-import { FormElement } from "./modal_dialog_forms";
-import { globalConfig } from "./config";
-import { getStringForKeyCode } from "../game/key_action_mapper";
-import { createLogger } from "./logging";
-import { T } from "../translations";
-
-/*
- * ***************************************************
- *
- * LEGACY CODE WARNING
- *
- * This is old code from yorg3.io and needs to be refactored
- * @TODO
- *
- * ***************************************************
- */
-
-const kbEnter = 13;
-const kbCancel = 27;
-
-const logger = createLogger("dialogs");
-
-/**
- * Basic text based dialog
- */
-export class Dialog {
- /**
- *
- * Constructs a new dialog with the given options
- * @param {object} param0
- * @param {Application} param0.app
- * @param {string} param0.title Title of the dialog
- * @param {string} param0.contentHTML Inner dialog html
- * @param {Array} param0.buttons
- * Button list, each button contains of up to 3 parts separated by ':'.
- * Part 0: The id, one of the one defined in dialog_buttons.yaml
- * Part 1: The style, either good, bad or misc
- * Part 2 (optional): Additional parameters separated by '/', available are:
- * timeout: This button is only available after some waiting time
- * kb_enter: This button is triggered by the enter key
- * kb_escape This button is triggered by the escape key
- * @param {string=} param0.type The dialog type, either "info" or "warn"
- * @param {boolean=} param0.closeButton Whether this dialog has a close button
- */
- constructor({ app, title, contentHTML, buttons, type = "info", closeButton = false }) {
- this.app = app;
- this.title = title;
- this.contentHTML = contentHTML;
- this.type = type;
- this.buttonIds = buttons;
- this.closeButton = closeButton;
-
- this.closeRequested = new Signal();
- this.buttonSignals = {};
-
- for (let i = 0; i < buttons.length; ++i) {
- if (G_IS_DEV && globalConfig.debug.disableTimedButtons) {
- this.buttonIds[i] = this.buttonIds[i].replace(":timeout", "");
- }
-
- const buttonId = this.buttonIds[i].split(":")[0];
- this.buttonSignals[buttonId] = new Signal();
- }
-
- this.valueChosen = new Signal();
-
- this.timeouts = [];
- this.clickDetectors = [];
-
- this.inputReciever = new InputReceiver("dialog-" + this.title);
-
- this.inputReciever.keydown.add(this.handleKeydown, this);
-
- this.enterHandler = null;
- this.escapeHandler = null;
- }
-
- /**
- * Internal keydown handler
- * @param {object} param0
- * @param {number} param0.keyCode
- * @param {boolean} param0.shift
- * @param {boolean} param0.alt
- * @param {boolean} param0.ctrl
- */
- handleKeydown({ keyCode, shift, alt, ctrl }) {
- if (keyCode === kbEnter && this.enterHandler) {
- this.internalButtonHandler(this.enterHandler);
- return STOP_PROPAGATION;
- }
-
- if (keyCode === kbCancel && this.escapeHandler) {
- this.internalButtonHandler(this.escapeHandler);
- return STOP_PROPAGATION;
- }
- }
-
- internalButtonHandler(id, ...payload) {
- this.app.inputMgr.popReciever(this.inputReciever);
-
- if (id !== "close-button") {
- this.buttonSignals[id].dispatch(...payload);
- }
- this.closeRequested.dispatch();
- }
-
- createElement() {
- const elem = document.createElement("div");
- elem.classList.add("ingameDialog");
-
- this.dialogElem = document.createElement("div");
- this.dialogElem.classList.add("dialogInner");
-
- if (this.type) {
- this.dialogElem.classList.add(this.type);
- }
- elem.appendChild(this.dialogElem);
-
- const title = document.createElement("h1");
- title.innerText = this.title;
- title.classList.add("title");
- this.dialogElem.appendChild(title);
-
- if (this.closeButton) {
- this.dialogElem.classList.add("hasCloseButton");
-
- const closeBtn = document.createElement("button");
- closeBtn.classList.add("closeButton");
-
- this.trackClicks(closeBtn, () => this.internalButtonHandler("close-button"), {
- applyCssClass: "pressedSmallElement",
- });
-
- title.appendChild(closeBtn);
- this.inputReciever.backButton.add(() => this.internalButtonHandler("close-button"));
- }
-
- const content = document.createElement("div");
- content.classList.add("content");
- content.innerHTML = this.contentHTML;
- this.dialogElem.appendChild(content);
-
- if (this.buttonIds.length > 0) {
- const buttons = document.createElement("div");
- buttons.classList.add("buttons");
-
- // Create buttons
- for (let i = 0; i < this.buttonIds.length; ++i) {
- const [buttonId, buttonStyle, rawParams] = this.buttonIds[i].split(":");
-
- const button = document.createElement("button");
- button.classList.add("button");
- button.classList.add("styledButton");
- button.classList.add(buttonStyle);
- button.innerText = T.dialogs.buttons[buttonId];
-
- const params = (rawParams || "").split("/");
- const useTimeout = params.indexOf("timeout") >= 0;
-
- const isEnter = params.indexOf("enter") >= 0;
- const isEscape = params.indexOf("escape") >= 0;
-
- if (isEscape && this.closeButton) {
- logger.warn("Showing dialog with close button, and additional cancel button");
- }
-
- if (useTimeout) {
- button.classList.add("timedButton");
- const timeout = setTimeout(() => {
- button.classList.remove("timedButton");
- arrayDeleteValue(this.timeouts, timeout);
- }, 1000);
- this.timeouts.push(timeout);
- }
- if (isEnter || isEscape) {
- // if (this.app.settings.getShowKeyboardShortcuts()) {
- // Show keybinding
- const spacer = document.createElement("code");
- spacer.classList.add("keybinding");
- spacer.innerHTML = getStringForKeyCode(isEnter ? kbEnter : kbCancel);
- button.appendChild(spacer);
- // }
-
- if (isEnter) {
- this.enterHandler = buttonId;
- }
- if (isEscape) {
- this.escapeHandler = buttonId;
- }
- }
-
- this.trackClicks(button, () => this.internalButtonHandler(buttonId));
- buttons.appendChild(button);
- }
-
- this.dialogElem.appendChild(buttons);
- } else {
- this.dialogElem.classList.add("buttonless");
- }
-
- this.element = elem;
- this.app.inputMgr.pushReciever(this.inputReciever);
-
- return this.element;
- }
-
- setIndex(index) {
- this.element.style.zIndex = index;
- }
-
- destroy() {
- if (!this.element) {
- assert(false, "Tried to destroy dialog twice");
- return;
- }
- // We need to do this here, because if the backbutton event gets
- // dispatched to the modal dialogs, it will not call the internalButtonHandler,
- // and thus our receiver stays attached the whole time
- this.app.inputMgr.destroyReceiver(this.inputReciever);
-
- for (let i = 0; i < this.clickDetectors.length; ++i) {
- this.clickDetectors[i].cleanup();
- }
- this.clickDetectors = [];
-
- this.element.remove();
- this.element = null;
-
- for (let i = 0; i < this.timeouts.length; ++i) {
- clearTimeout(this.timeouts[i]);
- }
- this.timeouts = [];
- }
-
- hide() {
- this.element.classList.remove("visible");
- }
-
- show() {
- this.element.classList.add("visible");
- }
-
- /**
- * Helper method to track clicks on an element
- * @param {Element} elem
- * @param {function():void} handler
- * @param {import("./click_detector").ClickDetectorConstructorArgs=} args
- * @returns {ClickDetector}
- */
- trackClicks(elem, handler, args = {}) {
- const detector = new ClickDetector(elem, args);
- detector.click.add(handler, this);
- this.clickDetectors.push(detector);
- return detector;
- }
-}
-
-/**
- * Dialog which simply shows a loading spinner
- */
-export class DialogLoading extends Dialog {
- constructor(app, text = "") {
- super({
- app,
- title: "",
- contentHTML: "",
- buttons: [],
- type: "loading",
- });
-
- // Loading dialog can not get closed with back button
- this.inputReciever.backButton.removeAll();
- this.inputReciever.context = "dialog-loading";
-
- this.text = text;
- }
-
- createElement() {
- const elem = document.createElement("div");
- elem.classList.add("ingameDialog");
- elem.classList.add("loadingDialog");
- this.element = elem;
-
- if (this.text) {
- const text = document.createElement("div");
- text.classList.add("text");
- text.innerText = this.text;
- elem.appendChild(text);
- }
-
- const loader = document.createElement("div");
- loader.classList.add("prefab_LoadingTextWithAnim");
- loader.classList.add("loadingIndicator");
- elem.appendChild(loader);
-
- this.app.inputMgr.pushReciever(this.inputReciever);
-
- return elem;
- }
-}
-
-export class DialogOptionChooser extends Dialog {
- constructor({ app, title, options }) {
- let html = "";
-
- options.options.forEach(({ value, text, desc = null, iconPrefix = null }) => {
- const descHtml = desc ? `
${desc} ` : "";
- let iconHtml = iconPrefix ? `
` : "";
- html += `
-
- ${iconHtml}
- ${text}
- ${descHtml}
-
- `;
- });
-
- html += "
";
- super({
- app,
- title,
- contentHTML: html,
- buttons: [],
- type: "info",
- closeButton: true,
- });
-
- this.options = options;
- this.initialOption = options.active;
-
- this.buttonSignals.optionSelected = new Signal();
- }
-
- createElement() {
- const div = super.createElement();
- this.dialogElem.classList.add("optionChooserDialog");
-
- div.querySelectorAll("[data-optionvalue]").forEach(handle => {
- const value = handle.getAttribute("data-optionvalue");
- if (!handle) {
- logger.error("Failed to bind option value in dialog:", value);
- return;
- }
- // Need click detector here to forward elements, otherwise scrolling does not work
- const detector = new ClickDetector(handle, {
- consumeEvents: false,
- preventDefault: false,
- clickSound: null,
- applyCssClass: "pressedOption",
- targetOnly: true,
- });
- this.clickDetectors.push(detector);
-
- if (value !== this.initialOption) {
- detector.click.add(() => {
- const selected = div.querySelector(".option.active");
- if (selected) {
- selected.classList.remove("active");
- } else {
- logger.warn("No selected option");
- }
- handle.classList.add("active");
- this.app.sound.playUiSound(SOUNDS.uiClick);
- this.internalButtonHandler("optionSelected", value);
- });
- }
- });
- return div;
- }
-}
-
-export class DialogWithForm extends Dialog {
- /**
- *
- * @param {object} param0
- * @param {Application} param0.app
- * @param {string} param0.title
- * @param {string} param0.desc
- * @param {array=} param0.buttons
- * @param {string=} param0.confirmButtonId
- * @param {string=} param0.extraButton
- * @param {boolean=} param0.closeButton
- * @param {Array} param0.formElements
- */
- constructor({
- app,
- title,
- desc,
- formElements,
- buttons = ["cancel", "ok:good"],
- confirmButtonId = "ok",
- closeButton = true,
- }) {
- let html = "";
- html += desc + " ";
- for (let i = 0; i < formElements.length; ++i) {
- html += formElements[i].getHtml();
- }
-
- super({
- app,
- title: title,
- contentHTML: html,
- buttons: buttons,
- type: "info",
- closeButton,
- });
- this.confirmButtonId = confirmButtonId;
- this.formElements = formElements;
-
- this.enterHandler = confirmButtonId;
- }
-
- internalButtonHandler(id, ...payload) {
- if (id === this.confirmButtonId) {
- if (this.hasAnyInvalid()) {
- this.dialogElem.classList.remove("errorShake");
- waitNextFrame().then(() => {
- if (this.dialogElem) {
- this.dialogElem.classList.add("errorShake");
- }
- });
- this.app.sound.playUiSound(SOUNDS.uiError);
- return;
- }
- }
-
- super.internalButtonHandler(id, payload);
- }
-
- hasAnyInvalid() {
- for (let i = 0; i < this.formElements.length; ++i) {
- if (!this.formElements[i].isValid()) {
- return true;
- }
- }
- return false;
- }
-
- createElement() {
- const div = super.createElement();
-
- for (let i = 0; i < this.formElements.length; ++i) {
- const elem = this.formElements[i];
- elem.bindEvents(div, this.clickDetectors);
- // elem.valueChosen.add(this.closeRequested.dispatch, this.closeRequested);
- elem.valueChosen.add(this.valueChosen.dispatch, this.valueChosen);
- }
-
- waitNextFrame().then(() => {
- this.formElements[this.formElements.length - 1].focus();
- });
-
- return div;
- }
-}
+import type { Application } from "../application";
+
+import { SOUNDS } from "../platform/sound";
+import { T } from "../translations";
+import { ClickDetector, ClickDetectorConstructorArgs } from "./click_detector";
+import { globalConfig } from "./config";
+import { InputReceiver, KeydownEvent } from "./input_receiver";
+import { getStringForKeyCode } from "./keycodes";
+import { createLogger } from "./logging";
+import { FormElement } from "./modal_dialog_forms";
+import { Signal, STOP_PROPAGATION } from "./signal";
+import { arrayDeleteValue, waitNextFrame } from "./utils";
+
+/*
+ * ***************************************************
+ *
+ * LEGACY CODE WARNING
+ *
+ * This is old code from yorg3.io and needs to be refactored
+ * @TODO
+ *
+ * ***************************************************
+ */
+
+const kbEnter = 13;
+const kbCancel = 27;
+
+const logger = createLogger("dialogs");
+
+export type DialogButtonStr = `${T}:${string}` | T;
+export type DialogButtonType = "info" | "loading" | "warning";
+
+/**
+ * Basic text based dialog
+ */
+export class Dialog {
+ public title: string;
+ public app: Application;
+ public contentHTML: string;
+ public type: string;
+ public buttonIds: string[];
+ public closeButton: boolean;
+ public dialogElem: HTMLDivElement;
+ public element: HTMLDivElement;
+
+ public closeRequested = new Signal();
+ public buttonSignals = {} as Record>;
+
+ public valueChosen = new Signal<[unknown]>();
+
+ public timeouts: number[] = [];
+ public clickDetectors: ClickDetector[] = [];
+
+ public inputReceiver: InputReceiver;
+ public enterHandler: T = null;
+ public escapeHandler: T = null;
+
+ /**
+ *
+ * Constructs a new dialog with the given options
+ * @param param0
+ * @param param0.title Title of the dialog
+ * @param param0.contentHTML Inner dialog html
+ * @param param0.buttons
+ * Button list, each button contains of up to 3 parts separated by ':'.
+ * Part 0: The id, one of the one defined in dialog_buttons.yaml
+ * Part 1: The style, either good, bad or misc
+ * Part 2 (optional): Additional parameters separated by '/', available are:
+ * timeout: This button is only available after some waiting time
+ * kb_enter: This button is triggered by the enter key
+ * kb_escape This button is triggered by the escape key
+ * @param param0.type The dialog type, either "info", "warning", or "loading"
+ * @param param0.closeButton Whether this dialog has a close button
+ */
+ constructor({
+ app,
+ title,
+ contentHTML,
+ buttons,
+ type = "info",
+ closeButton = false,
+ }: {
+ app: Application;
+ title: string;
+ contentHTML: string;
+ buttons?: DialogButtonStr[];
+ type?: DialogButtonType;
+ closeButton?: boolean;
+ }) {
+ this.app = app;
+ this.title = title;
+ this.contentHTML = contentHTML;
+ this.type = type;
+ this.buttonIds = buttons;
+ this.closeButton = closeButton;
+
+ for (let i = 0; i < buttons.length; ++i) {
+ if (G_IS_DEV && globalConfig.debug.disableTimedButtons) {
+ this.buttonIds[i] = this.buttonIds[i].replace(":timeout", "");
+ }
+
+ const buttonId = this.buttonIds[i].split(":")[0];
+ this.buttonSignals[buttonId] = new Signal();
+ }
+
+ this.inputReceiver = new InputReceiver("dialog-" + this.title);
+
+ this.inputReceiver.keydown.add(this.handleKeydown, this);
+ }
+
+ /**
+ * Internal keydown handler
+ */
+ handleKeydown({ keyCode, shift, alt, ctrl }: KeydownEvent): void | STOP_PROPAGATION {
+ if (keyCode === kbEnter && this.enterHandler) {
+ this.internalButtonHandler(this.enterHandler);
+ return STOP_PROPAGATION;
+ }
+
+ if (keyCode === kbCancel && this.escapeHandler) {
+ this.internalButtonHandler(this.escapeHandler);
+ return STOP_PROPAGATION;
+ }
+ }
+
+ internalButtonHandler(id: T | "close-button", ...payload: U | []) {
+ this.app.inputMgr.popReceiver(this.inputReceiver);
+
+ if (id !== "close-button") {
+ this.buttonSignals[id].dispatch(...payload);
+ }
+ this.closeRequested.dispatch();
+ }
+
+ createElement() {
+ const elem = document.createElement("div");
+ elem.classList.add("ingameDialog");
+
+ this.dialogElem = document.createElement("div");
+ this.dialogElem.classList.add("dialogInner");
+
+ if (this.type) {
+ this.dialogElem.classList.add(this.type); // @TODO: `this.type` seems unused
+ }
+ elem.appendChild(this.dialogElem);
+
+ const title = document.createElement("h1");
+ title.innerText = this.title;
+ title.classList.add("title");
+ this.dialogElem.appendChild(title);
+
+ if (this.closeButton) {
+ this.dialogElem.classList.add("hasCloseButton");
+
+ const closeBtn = document.createElement("button");
+ closeBtn.classList.add("closeButton");
+
+ this.trackClicks(closeBtn, () => this.internalButtonHandler("close-button"), {
+ applyCssClass: "pressedSmallElement",
+ });
+
+ title.appendChild(closeBtn);
+ this.inputReceiver.backButton.add(() => this.internalButtonHandler("close-button"));
+ }
+
+ const content = document.createElement("div");
+ content.classList.add("content");
+ content.innerHTML = this.contentHTML;
+ this.dialogElem.appendChild(content);
+
+ if (this.buttonIds.length > 0) {
+ const buttons = document.createElement("div");
+ buttons.classList.add("buttons");
+
+ // Create buttons
+ for (let i = 0; i < this.buttonIds.length; ++i) {
+ const [buttonId, buttonStyle, rawParams] = this.buttonIds[i].split(":") as [
+ T,
+ string,
+ string?,
+ ]; // @TODO: some button strings omit `buttonStyle`
+
+ const button = document.createElement("button");
+ button.classList.add("button");
+ button.classList.add("styledButton");
+ button.classList.add(buttonStyle);
+ button.innerText = T.dialogs.buttons[buttonId as string];
+
+ const params = (rawParams || "").split("/");
+ const useTimeout = params.indexOf("timeout") >= 0;
+
+ const isEnter = params.indexOf("enter") >= 0;
+ const isEscape = params.indexOf("escape") >= 0;
+
+ if (isEscape && this.closeButton) {
+ logger.warn("Showing dialog with close button, and additional cancel button");
+ }
+
+ if (useTimeout) {
+ button.classList.add("timedButton");
+ const timeout = setTimeout(() => {
+ button.classList.remove("timedButton");
+ arrayDeleteValue(this.timeouts, timeout);
+ }, 1000) as unknown as number; // @TODO: @types/node should not be affecting this
+ this.timeouts.push(timeout);
+ }
+ if (isEnter || isEscape) {
+ // if (this.app.settings.getShowKeyboardShortcuts()) {
+ // Show keybinding
+ const spacer = document.createElement("kbd");
+ spacer.innerHTML = getStringForKeyCode(isEnter ? kbEnter : kbCancel);
+ button.appendChild(spacer);
+ // }
+
+ if (isEnter) {
+ this.enterHandler = buttonId;
+ }
+ if (isEscape) {
+ this.escapeHandler = buttonId;
+ }
+ }
+
+ this.trackClicks(button, () => this.internalButtonHandler(buttonId));
+ buttons.appendChild(button);
+ }
+
+ this.dialogElem.appendChild(buttons);
+ } else {
+ this.dialogElem.classList.add("buttonless");
+ }
+
+ this.element = elem;
+ this.app.inputMgr.pushReceiver(this.inputReceiver);
+
+ return this.element;
+ }
+
+ setIndex(index: string) {
+ this.element.style.zIndex = index;
+ }
+
+ destroy() {
+ if (!this.element) {
+ assert(false, "Tried to destroy dialog twice");
+ return;
+ }
+ // We need to do this here, because if the backbutton event gets
+ // dispatched to the modal dialogs, it will not call the internalButtonHandler,
+ // and thus our receiver stays attached the whole time
+ this.app.inputMgr.destroyReceiver(this.inputReceiver);
+
+ for (let i = 0; i < this.clickDetectors.length; ++i) {
+ this.clickDetectors[i].cleanup();
+ }
+ this.clickDetectors = [];
+
+ this.element.remove();
+ this.element = null;
+
+ for (let i = 0; i < this.timeouts.length; ++i) {
+ clearTimeout(this.timeouts[i]);
+ }
+ this.timeouts = [];
+ }
+
+ hide() {
+ this.element.classList.remove("visible");
+ }
+
+ show() {
+ this.element.classList.add("visible");
+ }
+
+ /**
+ * Helper method to track clicks on an element
+ */
+ trackClicks(elem: Element, handler: () => void, args: ClickDetectorConstructorArgs = {}) {
+ const detector = new ClickDetector(elem, args);
+ detector.click.add(handler, this);
+ this.clickDetectors.push(detector);
+ return detector;
+ }
+}
+
+/**
+ * Dialog which simply shows a loading spinner
+ */
+export class DialogLoading extends Dialog {
+ constructor(
+ app: Application,
+ public text = ""
+ ) {
+ super({
+ app,
+ title: "",
+ contentHTML: "",
+ buttons: [],
+ type: "loading",
+ });
+
+ // Loading dialog can not get closed with back button
+ this.inputReceiver.backButton.removeAll();
+ this.inputReceiver.context = "dialog-loading";
+ }
+
+ createElement() {
+ const elem = document.createElement("div");
+ elem.classList.add("ingameDialog");
+ elem.classList.add("loadingDialog");
+ this.element = elem;
+
+ if (this.text) {
+ const text = document.createElement("div");
+ text.classList.add("text");
+ text.innerText = this.text;
+ elem.appendChild(text);
+ }
+
+ const loader = document.createElement("div");
+ loader.classList.add("prefab_LoadingTextWithAnim");
+ loader.classList.add("loadingIndicator");
+ elem.appendChild(loader);
+
+ this.app.inputMgr.pushReceiver(this.inputReceiver);
+
+ return elem;
+ }
+}
+
+type DialogOptionChooserOption = { value: string; text: string; desc?: string; iconPrefix?: string };
+export class DialogOptionChooser extends Dialog<"optionSelected", [string]> {
+ public options: {
+ options: DialogOptionChooserOption[];
+ active: string;
+ };
+ public initialOption: string;
+
+ constructor({
+ app,
+ title,
+ options,
+ }: {
+ app: Application;
+ title: string;
+ options: {
+ options: DialogOptionChooserOption[];
+ active: string;
+ };
+ }) {
+ let html = "";
+
+ options.options.forEach(({ value, text, desc = null, iconPrefix = null }) => {
+ const descHtml = desc ? `
${desc} ` : "";
+ const iconHtml = iconPrefix ? `
` : "";
+ html += `
+
+ ${iconHtml}
+ ${text}
+ ${descHtml}
+
+ `;
+ });
+
+ html += "
";
+ super({
+ app,
+ title,
+ contentHTML: html,
+ buttons: [],
+ type: "info",
+ closeButton: true,
+ });
+
+ this.options = options;
+ this.initialOption = options.active;
+
+ this.buttonSignals.optionSelected = new Signal();
+ }
+
+ createElement() {
+ const div = super.createElement();
+ this.dialogElem.classList.add("optionChooserDialog");
+
+ div.querySelectorAll("[data-optionvalue]").forEach(handle => {
+ const value = handle.getAttribute("data-optionvalue");
+ if (!handle) {
+ logger.error("Failed to bind option value in dialog:", value);
+ return;
+ }
+ // Need click detector here to forward elements, otherwise scrolling does not work
+ const detector = new ClickDetector(handle, {
+ consumeEvents: false,
+ preventDefault: false,
+ clickSound: null,
+ applyCssClass: "pressedOption",
+ targetOnly: true,
+ });
+ this.clickDetectors.push(detector);
+
+ if (value !== this.initialOption) {
+ detector.click.add(() => {
+ const selected = div.querySelector(".option.active");
+ if (selected) {
+ selected.classList.remove("active");
+ } else {
+ logger.warn("No selected option");
+ }
+ handle.classList.add("active");
+ this.app.sound.playUiSound(SOUNDS.uiClick);
+ this.internalButtonHandler("optionSelected", value);
+ });
+ }
+ });
+ return div;
+ }
+}
+
+export class DialogWithForm extends Dialog {
+ public confirmButtonId: string;
+ // `FormElement` is invariant so `unknown` and `never` don't work
+ public formElements: FormElement[];
+
+ constructor({
+ app,
+ title,
+ desc,
+ formElements,
+ buttons = ["cancel", "ok:good"] as any,
+ confirmButtonId = "ok" as any,
+ closeButton = true,
+ }: {
+ app: Application;
+ title: string;
+ desc: string;
+ formElements: FormElement[];
+ buttons?: DialogButtonStr[];
+ confirmButtonId?: T;
+ closeButton?: boolean;
+ }) {
+ let html = "";
+ html += desc + " ";
+ for (let i = 0; i < formElements.length; ++i) {
+ html += formElements[i].getHtml();
+ }
+
+ super({
+ app,
+ title: title,
+ contentHTML: html,
+ buttons: buttons,
+ type: "info",
+ closeButton,
+ });
+ this.confirmButtonId = confirmButtonId;
+ this.formElements = formElements;
+
+ this.enterHandler = confirmButtonId;
+ }
+
+ internalButtonHandler(id: T | "close-button", ...payload: []) {
+ if (id === this.confirmButtonId) {
+ if (this.hasAnyInvalid()) {
+ this.dialogElem.classList.remove("errorShake");
+ waitNextFrame().then(() => {
+ if (this.dialogElem) {
+ this.dialogElem.classList.add("errorShake");
+ }
+ });
+ this.app.sound.playUiSound(SOUNDS.uiError);
+ return;
+ }
+ }
+
+ super.internalButtonHandler(id, ...payload);
+ }
+
+ hasAnyInvalid() {
+ for (let i = 0; i < this.formElements.length; ++i) {
+ if (!this.formElements[i].isValid()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ createElement() {
+ const div = super.createElement();
+
+ for (let i = 0; i < this.formElements.length; ++i) {
+ const elem = this.formElements[i];
+ elem.bindEvents(div, this.clickDetectors);
+ // elem.valueChosen.add(this.closeRequested.dispatch, this.closeRequested);
+ elem.valueChosen.add(this.valueChosen.dispatch, this.valueChosen);
+ }
+
+ waitNextFrame().then(() => {
+ this.formElements[this.formElements.length - 1].focus();
+ });
+
+ return div;
+ }
+}
diff --git a/src/js/core/modal_dialog_forms.js b/src/js/core/modal_dialog_forms.ts
similarity index 69%
rename from src/js/core/modal_dialog_forms.js
rename to src/js/core/modal_dialog_forms.ts
index a4e617f8..437264c9 100644
--- a/src/js/core/modal_dialog_forms.js
+++ b/src/js/core/modal_dialog_forms.ts
@@ -1,249 +1,241 @@
-import { BaseItem } from "../game/base_item";
-import { ClickDetector } from "./click_detector";
-import { Signal } from "./signal";
-
-/*
- * ***************************************************
- *
- * LEGACY CODE WARNING
- *
- * This is old code from yorg3.io and needs to be refactored
- * @TODO
- *
- * ***************************************************
- */
-
-export class FormElement {
- constructor(id, label) {
- this.id = id;
- this.label = label;
-
- this.valueChosen = new Signal();
- }
-
- getHtml() {
- abstract;
- return "";
- }
-
- getFormElement(parent) {
- return parent.querySelector("[data-formId='" + this.id + "']");
- }
-
- bindEvents(parent, clickTrackers) {
- abstract;
- }
-
- focus() {}
-
- isValid() {
- return true;
- }
-
- /** @returns {any} */
- getValue() {
- abstract;
- }
-}
-
-export class FormElementInput extends FormElement {
- constructor({ id, label = null, placeholder, defaultValue = "", inputType = "text", validator = null }) {
- super(id, label);
- this.placeholder = placeholder;
- this.defaultValue = defaultValue;
- this.inputType = inputType;
- this.validator = validator;
-
- this.element = null;
- }
-
- getHtml() {
- let classes = [];
- let inputType = "text";
- let maxlength = 256;
- switch (this.inputType) {
- case "text": {
- classes.push("input-text");
- break;
- }
-
- case "email": {
- classes.push("input-email");
- inputType = "email";
- break;
- }
-
- case "token": {
- classes.push("input-token");
- inputType = "text";
- maxlength = 4;
- break;
- }
- }
-
- return `
-
- ${this.label ? `${this.label} ` : ""}
-
-
- `;
- }
-
- bindEvents(parent, clickTrackers) {
- this.element = this.getFormElement(parent);
- this.element.addEventListener("input", event => this.updateErrorState());
- this.updateErrorState();
- }
-
- updateErrorState() {
- this.element.classList.toggle("errored", !this.isValid());
-
- // profanity filter
- if (G_WEGAME_VERSION) {
- const value = String(this.element.value);
-
- ipcRenderer.invoke("profanity-check", value).then(newValue => {
- if (value !== newValue && this.element) {
- this.element.value = newValue;
- }
- });
- }
- }
-
- isValid() {
- return !this.validator || this.validator(this.element.value);
- }
-
- getValue() {
- return this.element.value;
- }
-
- setValue(value) {
- this.element.value = value;
- this.updateErrorState();
- }
-
- focus() {
- this.element.focus();
- this.element.select();
- }
-}
-
-export class FormElementCheckbox extends FormElement {
- constructor({ id, label, defaultValue = true }) {
- super(id, label);
- this.defaultValue = defaultValue;
- this.value = this.defaultValue;
-
- this.element = null;
- }
-
- getHtml() {
- return `
-
- `;
- }
-
- bindEvents(parent, clickTrackers) {
- this.element = this.getFormElement(parent);
- const detector = new ClickDetector(this.element, {
- consumeEvents: false,
- preventDefault: false,
- });
- clickTrackers.push(detector);
- detector.click.add(this.toggle, this);
- }
-
- getValue() {
- return this.value;
- }
-
- toggle() {
- this.value = !this.value;
- this.element.classList.toggle("checked", this.value);
- }
-
- focus(parent) {}
-}
-
-export class FormElementItemChooser extends FormElement {
- /**
- *
- * @param {object} param0
- * @param {string} param0.id
- * @param {string=} param0.label
- * @param {Array} param0.items
- */
- constructor({ id, label, items = [] }) {
- super(id, label);
- this.items = items;
- this.element = null;
-
- /**
- * @type {BaseItem}
- */
- this.chosenItem = null;
- }
-
- getHtml() {
- let classes = [];
-
- return `
-
- `;
- }
-
- /**
- * @param {HTMLElement} parent
- * @param {Array} clickTrackers
- */
- bindEvents(parent, clickTrackers) {
- this.element = this.getFormElement(parent);
-
- for (let i = 0; i < this.items.length; ++i) {
- const item = this.items[i];
-
- const canvas = document.createElement("canvas");
- canvas.width = 128;
- canvas.height = 128;
- const context = canvas.getContext("2d");
- item.drawFullSizeOnCanvas(context, 128);
- this.element.appendChild(canvas);
-
- const detector = new ClickDetector(canvas, {});
- clickTrackers.push(detector);
- detector.click.add(() => {
- this.chosenItem = item;
- this.valueChosen.dispatch(item);
- });
- }
- }
-
- isValid() {
- return true;
- }
-
- getValue() {
- return null;
- }
-
- focus() {}
-}
+import { BaseItem } from "../game/base_item";
+import { ClickDetector } from "./click_detector";
+import { Signal } from "./signal";
+
+/*
+ * ***************************************************
+ *
+ * LEGACY CODE WARNING
+ *
+ * This is old code from yorg3.io and needs to be refactored
+ * @TODO
+ *
+ * ***************************************************
+ */
+
+export abstract class FormElement {
+ public valueChosen = new Signal<[T]>();
+
+ constructor(
+ public id: string,
+ public label: string
+ ) {}
+
+ abstract getHtml(): string;
+
+ getFormElement(parent: HTMLElement): HTMLElement {
+ return parent.querySelector("[data-formId='" + this.id + "']");
+ }
+
+ abstract bindEvents(parent: HTMLDivElement, clickTrackers: ClickDetector[]): void;
+
+ focus() {}
+
+ isValid() {
+ return true;
+ }
+
+ abstract getValue(): T;
+}
+
+export class FormElementInput extends FormElement {
+ public placeholder: string;
+ public defaultValue: string;
+ public inputType: "text" | "email" | "token";
+ public validator: (value: string) => boolean;
+
+ public element: HTMLInputElement = null;
+
+ constructor({
+ id,
+ label = null,
+ placeholder,
+ defaultValue = "",
+ inputType = "text",
+ validator = null,
+ }: {
+ id: string;
+ label?: string;
+ placeholder: string;
+ defaultValue?: string;
+ inputType?: "text" | "email" | "token";
+ validator?: (value: string) => boolean;
+ }) {
+ super(id, label);
+ this.placeholder = placeholder;
+ this.defaultValue = defaultValue;
+ this.inputType = inputType;
+ this.validator = validator;
+ }
+
+ getHtml() {
+ const classes = [];
+ let inputType = "text";
+ let maxlength = 256;
+ // @TODO: `inputType` and these classes are unused
+ switch (this.inputType) {
+ case "text": {
+ classes.push("input-text");
+ break;
+ }
+
+ case "email": {
+ classes.push("input-email");
+ inputType = "email";
+ break;
+ }
+
+ case "token": {
+ classes.push("input-token");
+ inputType = "text";
+ maxlength = 4;
+ break;
+ }
+ }
+
+ return `
+
+ ${this.label ? `${this.label} ` : ""}
+
+
+ `;
+ }
+
+ bindEvents(parent: HTMLDivElement, clickTrackers: ClickDetector[]) {
+ this.element = this.getFormElement(parent) as HTMLInputElement;
+ this.element.addEventListener("input", event => this.updateErrorState());
+ this.updateErrorState();
+ }
+
+ updateErrorState() {
+ this.element.classList.toggle("errored", !this.isValid());
+ }
+
+ isValid() {
+ return !this.validator || this.validator(this.element.value);
+ }
+
+ getValue() {
+ return this.element.value;
+ }
+
+ setValue(value: string) {
+ this.element.value = value;
+ this.updateErrorState();
+ }
+
+ focus() {
+ this.element.focus();
+ this.element.select();
+ }
+}
+
+export class FormElementCheckbox extends FormElement {
+ public defaultValue: boolean;
+ public value: boolean;
+ public element: HTMLDivElement;
+
+ constructor({ id, label, defaultValue = true }) {
+ super(id, label);
+ this.defaultValue = defaultValue;
+ this.value = this.defaultValue;
+
+ this.element = null;
+ }
+
+ getHtml() {
+ return `
+
+ `;
+ }
+
+ bindEvents(parent: HTMLDivElement, clickTrackers: ClickDetector[]) {
+ this.element = this.getFormElement(parent) as HTMLDivElement;
+ const detector = new ClickDetector(this.element, {
+ consumeEvents: false,
+ preventDefault: false,
+ });
+ clickTrackers.push(detector);
+ detector.click.add(this.toggle, this);
+ }
+
+ getValue() {
+ return this.value;
+ }
+
+ toggle() {
+ this.value = !this.value;
+ this.element.classList.toggle("checked", this.value);
+ }
+
+ focus() {}
+}
+
+export class FormElementItemChooser extends FormElement {
+ public items: BaseItem[];
+ public element: HTMLDivElement = null;
+ public chosenItem: BaseItem = null;
+
+ constructor({ id, label, items = [] }: { id: string; label: string; items: BaseItem[] }) {
+ super(id, label);
+ this.items = items;
+ }
+
+ getHtml() {
+ const classes = [];
+
+ return `
+
+ `;
+ }
+
+ bindEvents(parent: HTMLElement, clickTrackers: ClickDetector[]) {
+ this.element = this.getFormElement(parent) as HTMLDivElement;
+
+ for (let i = 0; i < this.items.length; ++i) {
+ const item = this.items[i];
+
+ const canvas = document.createElement("canvas");
+ canvas.width = 128;
+ canvas.height = 128;
+ const context = canvas.getContext("2d");
+ item.drawFullSizeOnCanvas(context, 128);
+ this.element.appendChild(canvas);
+
+ const detector = new ClickDetector(canvas, {});
+ clickTrackers.push(detector);
+ detector.click.add(() => {
+ this.chosenItem = item;
+ this.valueChosen.dispatch(item);
+ });
+ }
+ }
+
+ isValid() {
+ return true;
+ }
+
+ getValue() {
+ return null;
+ }
+
+ focus() {}
+}
diff --git a/src/js/core/polyfills.js b/src/js/core/polyfills.js
deleted file mode 100644
index 52c17911..00000000
--- a/src/js/core/polyfills.js
+++ /dev/null
@@ -1,123 +0,0 @@
-function mathPolyfills() {
- // Converts from degrees to radians.
- Math.radians = function (degrees) {
- return (degrees * Math.PI) / 180.0;
- };
-
- // Converts from radians to degrees.
- Math.degrees = function (radians) {
- return (radians * 180.0) / Math.PI;
- };
-}
-
-function stringPolyfills() {
- // https://github.com/uxitten/polyfill/blob/master/string.polyfill.js
- // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padStart
- if (!String.prototype.padStart) {
- String.prototype.padStart = function padStart(targetLength, padString) {
- targetLength = targetLength >> 0; //truncate if number, or convert non-number to 0;
- padString = String(typeof padString !== "undefined" ? padString : " ");
- if (this.length >= targetLength) {
- return String(this);
- } else {
- targetLength = targetLength - this.length;
- if (targetLength > padString.length) {
- padString += padString.repeat(targetLength / padString.length); //append to original to ensure we are longer than needed
- }
- return padString.slice(0, targetLength) + String(this);
- }
- };
- }
-
- // https://github.com/uxitten/polyfill/blob/master/string.polyfill.js
- // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padEnd
- if (!String.prototype.padEnd) {
- String.prototype.padEnd = function padEnd(targetLength, padString) {
- targetLength = targetLength >> 0; //floor if number or convert non-number to 0;
- padString = String(typeof padString !== "undefined" ? padString : " ");
- if (this.length > targetLength) {
- return String(this);
- } else {
- targetLength = targetLength - this.length;
- if (targetLength > padString.length) {
- padString += padString.repeat(targetLength / padString.length); //append to original to ensure we are longer than needed
- }
- return String(this) + padString.slice(0, targetLength);
- }
- };
- }
-}
-
-function objectPolyfills() {
- // https://github.com/tc39/proposal-object-values-entries/blob/master/polyfill.js
-
- // @ts-ignore
- const reduce = Function.bind.call(Function.call, Array.prototype.reduce);
- // @ts-ignore
- const isEnumerable = Function.bind.call(Function.call, Object.prototype.propertyIsEnumerable);
- // @ts-ignore
- const concat = Function.bind.call(Function.call, Array.prototype.concat);
- const keys = Reflect.ownKeys;
-
- // @ts-ignore
- if (!Object.values) {
- // @ts-ignore
- Object.values = function values(O) {
- return reduce(
- keys(O),
- (v, k) => concat(v, typeof k === "string" && isEnumerable(O, k) ? [O[k]] : []),
- []
- );
- };
- }
-
- if (!Object.entries) {
- // @ts-ignore
- Object.entries = function entries(O) {
- return reduce(
- keys(O),
- (e, k) => concat(e, typeof k === "string" && isEnumerable(O, k) ? [[k, O[k]]] : []),
- []
- );
- };
- }
-}
-
-function domPolyfills() {
- // from:https://github.com/jserz/js_piece/blob/master/DOM/ChildNode/remove()/remove().md
- (function (arr) {
- arr.forEach(function (item) {
- if (item.hasOwnProperty("remove")) {
- return;
- }
- Object.defineProperty(item, "remove", {
- configurable: true,
- enumerable: true,
- writable: true,
- value: function remove() {
- this.parentNode.removeChild(this);
- },
- });
- });
- })([Element.prototype, CharacterData.prototype, DocumentType.prototype]);
-}
-
-function initPolyfills() {
- mathPolyfills();
- stringPolyfills();
- objectPolyfills();
- domPolyfills();
-}
-
-function initExtensions() {
- String.prototype.replaceAll = function (search, replacement) {
- var target = this;
- return target.split(search).join(replacement);
- };
-}
-
-// Fetch polyfill
-import "whatwg-fetch";
-// Other polyfills
-initPolyfills();
-initExtensions();
diff --git a/src/js/core/polyfills.ts b/src/js/core/polyfills.ts
new file mode 100644
index 00000000..e9a2bd28
--- /dev/null
+++ b/src/js/core/polyfills.ts
@@ -0,0 +1,21 @@
+// Converts from degrees to radians.
+Math.radians = function (degrees: number): number {
+ return (degrees * Math.PI) / 180.0;
+};
+
+// Converts from radians to degrees.
+Math.degrees = function (radians: number): number {
+ return (radians * 180.0) / Math.PI;
+};
+
+// Begins a path and draws a circle.
+CanvasRenderingContext2D.prototype.beginCircle = function (x: number, y: number, r: number): void {
+ this.beginPath();
+
+ if (r < 0.05) {
+ this.rect(x, y, 1, 1);
+ return;
+ }
+
+ this.arc(x, y, r, 0, 2.0 * Math.PI);
+};
diff --git a/src/js/core/query_parameters.js b/src/js/core/query_parameters.js
deleted file mode 100644
index 5d145644..00000000
--- a/src/js/core/query_parameters.js
+++ /dev/null
@@ -1,29 +0,0 @@
-const queryString = require("query-string");
-const options = queryString.parse(location.search);
-
-export let queryParamOptions = {
- embedProvider: null,
- abtVariant: null,
- campaign: null,
- fbclid: null,
- gclid: null,
-};
-
-if (options.embed) {
- queryParamOptions.embedProvider = options.embed;
-}
-
-if (options.abtVariant) {
- queryParamOptions.abtVariant = options.abtVariant;
-}
-
-if (options.fbclid) {
- queryParamOptions.fbclid = options.fbclid;
-}
-
-if (options.gclid) {
- queryParamOptions.gclid = options.gclid;
-}
-if (options.utm_campaign) {
- queryParamOptions.campaign = options.utm_campaign;
-}
diff --git a/src/js/core/read_write_proxy.js b/src/js/core/read_write_proxy.js
index 7c96149b..0ce9f987 100644
--- a/src/js/core/read_write_proxy.js
+++ b/src/js/core/read_write_proxy.js
@@ -1,343 +1,244 @@
-/* typehints:start */
-import { Application } from "../application";
-/* typehints:end */
-
-import { sha1, CRC_PREFIX, computeCrc } from "./sensitive_utils.encrypt";
-import { createLogger } from "./logging";
-import { FILE_NOT_FOUND } from "../platform/storage";
-import { accessNestedPropertyReverse } from "./utils";
-import { IS_DEBUG, globalConfig } from "./config";
-import { ExplainedResult } from "./explained_result";
-import { decompressX64, compressX64 } from "./lzstring";
-import { asyncCompressor, compressionPrefix } from "./async_compression";
-import { compressObject, decompressObject } from "../savegame/savegame_compressor";
-
-const debounce = require("debounce-promise");
-
-const logger = createLogger("read_write_proxy");
-
-const salt = accessNestedPropertyReverse(globalConfig, ["file", "info"]);
-
-// Helper which only writes / reads if verify() works. Also performs migration
-export class ReadWriteProxy {
- constructor(app, filename) {
- /** @type {Application} */
- this.app = app;
-
- this.filename = filename;
-
- /** @type {object} */
- this.currentData = null;
-
- // TODO: EXTREMELY HACKY! To verify we need to do this a step later
- if (G_IS_DEV && IS_DEBUG) {
- setTimeout(() => {
- assert(
- this.verify(this.getDefaultData()).result,
- "Verify() failed for default data: " + this.verify(this.getDefaultData()).reason
- );
- });
- }
-
- /**
- * Store a debounced handler to prevent double writes
- */
- this.debouncedWrite = debounce(this.doWriteAsync.bind(this), 50);
- }
-
- // -- Methods to override
-
- /** @returns {ExplainedResult} */
- verify(data) {
- abstract;
- return ExplainedResult.bad();
- }
-
- // Should return the default data
- getDefaultData() {
- abstract;
- return {};
- }
-
- // Should return the current version as an integer
- getCurrentVersion() {
- abstract;
- return 0;
- }
-
- // Should migrate the data (Modify in place)
- /** @returns {ExplainedResult} */
- migrate(data) {
- abstract;
- return ExplainedResult.bad();
- }
-
- // -- / Methods
-
- // Resets whole data, returns promise
- resetEverythingAsync() {
- logger.warn("Reset data to default");
- this.currentData = this.getDefaultData();
- return this.writeAsync();
- }
-
- /**
- *
- * @param {object} obj
- */
- static serializeObject(obj) {
- const jsonString = JSON.stringify(compressObject(obj));
- const checksum = computeCrc(jsonString + salt);
- return compressionPrefix + compressX64(checksum + jsonString);
- }
-
- /**
- *
- * @param {object} text
- */
- static deserializeObject(text) {
- const decompressed = decompressX64(text.substr(compressionPrefix.length));
- if (!decompressed) {
- // LZ string decompression failure
- throw new Error("bad-content / decompression-failed");
- }
- if (decompressed.length < 40) {
- // String too short
- throw new Error("bad-content / payload-too-small");
- }
-
- // Compare stored checksum with actual checksum
- const checksum = decompressed.substring(0, 40);
- const jsonString = decompressed.substr(40);
-
- const desiredChecksum = checksum.startsWith(CRC_PREFIX)
- ? computeCrc(jsonString + salt)
- : sha1(jsonString + salt);
-
- if (desiredChecksum !== checksum) {
- // Checksum mismatch
- throw new Error("bad-content / checksum-mismatch");
- }
-
- const parsed = JSON.parse(jsonString);
- const decoded = decompressObject(parsed);
- return decoded;
- }
-
- /**
- * Writes the data asychronously, fails if verify() fails.
- * Debounces the operation by up to 50ms
- * @returns {Promise}
- */
- writeAsync() {
- const verifyResult = this.internalVerifyEntry(this.currentData);
-
- if (!verifyResult.result) {
- logger.error("Tried to write invalid data to", this.filename, "reason:", verifyResult.reason);
- return Promise.reject(verifyResult.reason);
- }
-
- return this.debouncedWrite();
- }
-
- /**
- * Actually writes the data asychronously
- * @returns {Promise}
- */
- doWriteAsync() {
- return asyncCompressor
- .compressObjectAsync(this.currentData)
- .then(compressed => {
- return this.app.storage.writeFileAsync(this.filename, compressed);
- })
- .then(() => {
- logger.log("📄 Wrote", this.filename);
- })
- .catch(err => {
- logger.error("Failed to write", this.filename, ":", err);
- throw err;
- });
- }
-
- // Reads the data asynchronously, fails if verify() fails
- readAsync() {
- // Start read request
- return (
- this.app.storage
- .readFileAsync(this.filename)
-
- // Check for errors during read
- .catch(err => {
- if (err === FILE_NOT_FOUND) {
- logger.log("File not found, using default data");
-
- // File not found or unreadable, assume default file
- return Promise.resolve(null);
- }
-
- return Promise.reject("file-error: " + err);
- })
-
- // Decrypt data (if its encrypted)
- // @ts-ignore
- .then(rawData => {
- if (rawData == null) {
- // So, the file has not been found, use default data
- return JSON.stringify(compressObject(this.getDefaultData()));
- }
-
- if (rawData.startsWith(compressionPrefix)) {
- const decompressed = decompressX64(rawData.substr(compressionPrefix.length));
- if (!decompressed) {
- // LZ string decompression failure
- return Promise.reject("bad-content / decompression-failed");
- }
- if (decompressed.length < 40) {
- // String too short
- return Promise.reject("bad-content / payload-too-small");
- }
-
- // Compare stored checksum with actual checksum
- const checksum = decompressed.substring(0, 40);
- const jsonString = decompressed.substr(40);
-
- const desiredChecksum = checksum.startsWith(CRC_PREFIX)
- ? computeCrc(jsonString + salt)
- : sha1(jsonString + salt);
-
- if (desiredChecksum !== checksum) {
- // Checksum mismatch
- return Promise.reject(
- "bad-content / checksum-mismatch: " + desiredChecksum + " vs " + checksum
- );
- }
- return jsonString;
- } else {
- if (!G_IS_DEV) {
- return Promise.reject("bad-content / missing-compression");
- }
- }
- return rawData;
- })
-
- // Parse JSON, this could throw but that's fine
- .then(res => {
- try {
- return JSON.parse(res);
- } catch (ex) {
- logger.error(
- "Failed to parse file content of",
- this.filename,
- ":",
- ex,
- "(content was:",
- res,
- ")"
- );
- throw new Error("invalid-serialized-data");
- }
- })
-
- // Decompress
- .then(compressed => decompressObject(compressed))
-
- // Verify basic structure
- .then(contents => {
- const result = this.internalVerifyBasicStructure(contents);
- if (!result.isGood()) {
- return Promise.reject("verify-failed: " + result.reason);
- }
- return contents;
- })
-
- // Check version and migrate if required
- .then(contents => {
- if (contents.version > this.getCurrentVersion()) {
- return Promise.reject("stored-data-is-newer");
- }
-
- if (contents.version < this.getCurrentVersion()) {
- logger.log(
- "Trying to migrate data object from version",
- contents.version,
- "to",
- this.getCurrentVersion()
- );
- const migrationResult = this.migrate(contents); // modify in place
- if (migrationResult.isBad()) {
- return Promise.reject("migration-failed: " + migrationResult.reason);
- }
- }
- return contents;
- })
-
- // Verify
- .then(contents => {
- const verifyResult = this.internalVerifyEntry(contents);
- if (!verifyResult.result) {
- logger.error(
- "Read invalid data from",
- this.filename,
- "reason:",
- verifyResult.reason,
- "contents:",
- contents
- );
- return Promise.reject("invalid-data: " + verifyResult.reason);
- }
- return contents;
- })
-
- // Store
- .then(contents => {
- this.currentData = contents;
- logger.log("📄 Read data with version", this.currentData.version, "from", this.filename);
- return contents;
- })
-
- // Catchall
- .catch(err => {
- return Promise.reject("Failed to read " + this.filename + ": " + err);
- })
- );
- }
-
- /**
- * Deletes the file
- * @returns {Promise}
- */
- deleteAsync() {
- return this.app.storage.deleteFileAsync(this.filename);
- }
-
- // Internal
-
- /** @returns {ExplainedResult} */
- internalVerifyBasicStructure(data) {
- if (!data) {
- return ExplainedResult.bad("Data is empty");
- }
- if (!Number.isInteger(data.version) || data.version < 0) {
- return ExplainedResult.bad(
- `Data has invalid version: ${data.version} (expected ${this.getCurrentVersion()})`
- );
- }
-
- return ExplainedResult.good();
- }
-
- /** @returns {ExplainedResult} */
- internalVerifyEntry(data) {
- if (data.version !== this.getCurrentVersion()) {
- return ExplainedResult.bad(
- "Version mismatch, got " + data.version + " and expected " + this.getCurrentVersion()
- );
- }
-
- const verifyStructureError = this.internalVerifyBasicStructure(data);
- if (!verifyStructureError.isGood()) {
- return verifyStructureError;
- }
- return this.verify(data);
- }
-}
+/* typehints:start */
+import { Storage } from "@/platform/storage";
+/* typehints:end */
+
+import { FsError } from "@/platform/fs_error";
+import { ExplainedResult } from "./explained_result";
+import { createLogger } from "./logging";
+
+import debounce from "debounce-promise";
+
+const logger = createLogger("read_write_proxy");
+
+// Helper which only writes / reads if verify() works. Also performs migration
+export class ReadWriteProxy {
+ constructor(storage, filename) {
+ /** @type {Storage} */
+ this.storage = storage;
+
+ this.filename = filename;
+
+ /** @type {object} */
+ this.currentData = null;
+
+ // TODO: EXTREMELY HACKY! To verify we need to do this a step later
+ if (G_IS_DEV) {
+ setTimeout(() => {
+ assert(
+ this.verify(this.getDefaultData()).result,
+ "Verify() failed for default data: " + this.verify(this.getDefaultData()).reason
+ );
+ });
+ }
+
+ /**
+ * Store a debounced handler to prevent double writes
+ */
+ this.debouncedWrite = debounce(this.doWriteAsync.bind(this), 50);
+ }
+
+ // -- Methods to override
+
+ /** @returns {ExplainedResult} */
+ verify(data) {
+ abstract;
+ return ExplainedResult.bad();
+ }
+
+ // Should return the default data
+ getDefaultData() {
+ abstract;
+ return {};
+ }
+
+ // Should return the current version as an integer
+ getCurrentVersion() {
+ abstract;
+ return 0;
+ }
+
+ // Should migrate the data (Modify in place)
+ /** @returns {ExplainedResult} */
+ migrate(data) {
+ abstract;
+ return ExplainedResult.bad();
+ }
+
+ // -- / Methods
+
+ // Resets whole data, returns promise
+ resetEverythingAsync() {
+ logger.warn("Reset data to default");
+ this.currentData = this.getDefaultData();
+ return this.writeAsync();
+ }
+
+ /**
+ *
+ * @param {object} obj
+ */
+ static serializeObject(obj) {
+ // TODO: Remove redundant method
+ return obj;
+ }
+
+ /**
+ *
+ * @param {object} text
+ */
+ static deserializeObject(text) {
+ // TODO: Remove redundant method
+ return text;
+ }
+
+ /**
+ * Writes the data asychronously, fails if verify() fails.
+ * Debounces the operation by up to 50ms
+ * @returns {Promise}
+ */
+ writeAsync() {
+ const verifyResult = this.internalVerifyEntry(this.currentData);
+
+ if (!verifyResult.result) {
+ logger.error("Tried to write invalid data to", this.filename, "reason:", verifyResult.reason);
+ return Promise.reject(verifyResult.reason);
+ }
+
+ return this.debouncedWrite();
+ }
+
+ /**
+ * Actually writes the data asychronously
+ * @returns {Promise}
+ */
+ doWriteAsync() {
+ return this.storage
+ .writeFileAsync(this.filename, this.currentData)
+ .then(() => {
+ logger.log("📄 Wrote", this.filename);
+ })
+ .catch(err => {
+ logger.error("Failed to write", this.filename, ":", err);
+ throw err;
+ });
+ }
+
+ // Reads the data asynchronously, fails if verify() fails
+ readAsync() {
+ // Start read request
+ return (
+ this.storage
+ .readFileAsync(this.filename)
+
+ // Check for errors during read
+ .catch(err => {
+ if (err instanceof FsError && err.isFileNotFound()) {
+ logger.log("File not found, using default data");
+
+ // File not found or unreadable, assume default file
+ return Promise.resolve(this.getDefaultData());
+ }
+
+ return Promise.reject("file-error: " + err);
+ })
+
+ // Verify basic structure
+ .then(contents => {
+ const result = this.internalVerifyBasicStructure(contents);
+ if (!result.isGood()) {
+ return Promise.reject("verify-failed: " + result.reason);
+ }
+ return contents;
+ })
+
+ // Check version and migrate if required
+ .then(contents => {
+ if (contents.version > this.getCurrentVersion()) {
+ return Promise.reject("stored-data-is-newer");
+ }
+
+ if (contents.version < this.getCurrentVersion()) {
+ logger.log(
+ "Trying to migrate data object from version",
+ contents.version,
+ "to",
+ this.getCurrentVersion()
+ );
+ const migrationResult = this.migrate(contents); // modify in place
+ if (migrationResult.isBad()) {
+ return Promise.reject("migration-failed: " + migrationResult.reason);
+ }
+ }
+ return contents;
+ })
+
+ // Verify
+ .then(contents => {
+ const verifyResult = this.internalVerifyEntry(contents);
+ if (!verifyResult.result) {
+ logger.error(
+ "Read invalid data from",
+ this.filename,
+ "reason:",
+ verifyResult.reason,
+ "contents:",
+ contents
+ );
+ return Promise.reject("invalid-data: " + verifyResult.reason);
+ }
+ return contents;
+ })
+
+ // Store
+ .then(contents => {
+ this.currentData = contents;
+ logger.log("📄 Read data with version", this.currentData.version, "from", this.filename);
+ return contents;
+ })
+
+ // Catchall
+ .catch(err => {
+ return Promise.reject("Failed to read " + this.filename + ": " + err);
+ })
+ );
+ }
+
+ /**
+ * Deletes the file
+ * @returns {Promise}
+ */
+ deleteAsync() {
+ return this.storage.deleteFileAsync(this.filename);
+ }
+
+ // Internal
+
+ /** @returns {ExplainedResult} */
+ internalVerifyBasicStructure(data) {
+ if (!data) {
+ return ExplainedResult.bad("Data is empty");
+ }
+ if (!Number.isInteger(data.version) || data.version < 0) {
+ return ExplainedResult.bad(
+ `Data has invalid version: ${data.version} (expected ${this.getCurrentVersion()})`
+ );
+ }
+
+ return ExplainedResult.good();
+ }
+
+ /** @returns {ExplainedResult} */
+ internalVerifyEntry(data) {
+ if (data.version !== this.getCurrentVersion()) {
+ return ExplainedResult.bad(
+ "Version mismatch, got " + data.version + " and expected " + this.getCurrentVersion()
+ );
+ }
+
+ const verifyStructureError = this.internalVerifyBasicStructure(data);
+ if (!verifyStructureError.isGood()) {
+ return verifyStructureError;
+ }
+ return this.verify(data);
+ }
+}
diff --git a/src/js/core/restriction_manager.js b/src/js/core/restriction_manager.js
deleted file mode 100644
index 33783b58..00000000
--- a/src/js/core/restriction_manager.js
+++ /dev/null
@@ -1,134 +0,0 @@
-/* typehints:start */
-import { Application } from "../application";
-/* typehints:end */
-import { ExplainedResult } from "./explained_result";
-import { ReadWriteProxy } from "./read_write_proxy";
-import { WEB_STEAM_SSO_AUTHENTICATED } from "./steam_sso";
-
-export class RestrictionManager extends ReadWriteProxy {
- /**
- * @param {Application} app
- */
- constructor(app) {
- super(app, "restriction-flags.bin");
-
- this.currentData = this.getDefaultData();
- }
-
- // -- RW Proxy Impl
-
- /**
- * @param {any} data
- */
- verify(data) {
- return ExplainedResult.good();
- }
-
- /**
- */
- getDefaultData() {
- return {
- version: this.getCurrentVersion(),
- };
- }
-
- /**
- */
- getCurrentVersion() {
- return 1;
- }
-
- /**
- * @param {any} data
- */
- migrate(data) {
- return ExplainedResult.good();
- }
-
- initialize() {
- return this.readAsync();
- }
-
- // -- End RW Proxy Impl
-
- /**
- * Returns if the app is currently running as the limited version
- * @returns {boolean}
- */
- isLimitedVersion() {
- if (G_IS_STEAM_DEMO) {
- return true;
- }
-
- if (G_IS_STANDALONE) {
- // Standalone is never limited
- return false;
- }
-
- if (WEB_STEAM_SSO_AUTHENTICATED) {
- return false;
- }
-
- if (G_IS_DEV) {
- return typeof window !== "undefined" && window.location.search.indexOf("demo") >= 0;
- }
-
- return true;
- }
-
- /**
- * Returns if the app markets the standalone version on steam
- * @returns {boolean}
- */
- getIsStandaloneMarketingActive() {
- return this.isLimitedVersion();
- }
-
- /**
- * Returns if exporting the base as a screenshot is possible
- * @returns {boolean}
- */
- getIsExportingScreenshotsPossible() {
- return !this.isLimitedVersion();
- }
-
- /**
- * Returns the maximum number of supported waypoints
- * @returns {number}
- */
- getMaximumWaypoints() {
- return this.isLimitedVersion() ? 2 : 1e20;
- }
-
- /**
- * Returns if the user has unlimited savegames
- * @returns {boolean}
- */
- getHasUnlimitedSavegames() {
- return !this.isLimitedVersion();
- }
-
- /**
- * Returns if the app has all settings available
- * @returns {boolean}
- */
- getHasExtendedSettings() {
- return !this.isLimitedVersion();
- }
-
- /**
- * Returns if all upgrades are available
- * @returns {boolean}
- */
- getHasExtendedUpgrades() {
- return !this.isLimitedVersion();
- }
-
- /**
- * Returns if all levels & freeplay is available
- * @returns {boolean}
- */
- getHasExtendedLevelsAndFreeplay() {
- return !this.isLimitedVersion();
- }
-}
diff --git a/src/js/core/rng.js b/src/js/core/rng.js
deleted file mode 100644
index 7a6766cd..00000000
--- a/src/js/core/rng.js
+++ /dev/null
@@ -1,129 +0,0 @@
-// ALEA RNG
-
-function Mash() {
- var n = 0xefc8249d;
- return function (data) {
- data = data.toString();
- for (var i = 0; i < data.length; i++) {
- n += data.charCodeAt(i);
- var h = 0.02519603282416938 * n;
- n = h >>> 0;
- h -= n;
- h *= n;
- n = h >>> 0;
- h -= n;
- n += h * 0x100000000; // 2^32
- }
- return (n >>> 0) * 2.3283064365386963e-10; // 2^-32
- };
-}
-
-/**
- * @param {number|string} seed
- */
-function makeNewRng(seed) {
- // Johannes Baagøe , 2010
- var c = 1;
- var mash = Mash();
- let s0 = mash(" ");
- let s1 = mash(" ");
- let s2 = mash(" ");
-
- s0 -= mash(seed);
- if (s0 < 0) {
- s0 += 1;
- }
- s1 -= mash(seed);
- if (s1 < 0) {
- s1 += 1;
- }
- s2 -= mash(seed);
- if (s2 < 0) {
- s2 += 1;
- }
- mash = null;
-
- var random = function () {
- var t = 2091639 * s0 + c * 2.3283064365386963e-10; // 2^-32
- s0 = s1;
- s1 = s2;
- return (s2 = t - (c = t | 0));
- };
-
- random.exportState = function () {
- return [s0, s1, s2, c];
- };
-
- random.importState = function (i) {
- s0 = +i[0] || 0;
- s1 = +i[1] || 0;
- s2 = +i[2] || 0;
- c = +i[3] || 0;
- };
-
- return random;
-}
-
-export class RandomNumberGenerator {
- /**
- *
- * @param {number|string=} seed
- */
- constructor(seed) {
- this.internalRng = makeNewRng(seed || Math.random());
- }
-
- /**
- * Re-seeds the generator
- * @param {number|string} seed
- */
- reseed(seed) {
- this.internalRng = makeNewRng(seed || Math.random());
- }
-
- /**
- * @returns {number} between 0 and 1
- */
- next() {
- return this.internalRng();
- }
-
- /**
- * Random choice of an array
- * @param {array} array
- */
- choice(array) {
- const index = this.nextIntRange(0, array.length);
- return array[index];
- }
-
- /**
- * @param {number} min
- * @param {number} max
- * @returns {number} Integer in range [min, max[
- */
- nextIntRange(min, max) {
- assert(Number.isFinite(min), "Minimum is no integer");
- assert(Number.isFinite(max), "Maximum is no integer");
- assert(max > min, "rng: max <= min");
- return Math.floor(this.next() * (max - min) + min);
- }
-
- /**
- * @param {number} min
- * @param {number} max
- * @returns {number} Number in range [min, max[
- */
- nextRange(min, max) {
- assert(max > min, "rng: max <= min");
- return this.next() * (max - min) + min;
- }
-
- /**
- * Updates the seed
- * @param {number} seed
- */
- setSeed(seed) {
- this.internalRng = makeNewRng(seed);
- }
-}
diff --git a/src/js/core/rng.ts b/src/js/core/rng.ts
new file mode 100644
index 00000000..50bed98d
--- /dev/null
+++ b/src/js/core/rng.ts
@@ -0,0 +1,81 @@
+class Alea {
+ private n = 0xefc8249d;
+ private c = 1;
+
+ private s0: number;
+ private s1: number;
+ private s2: number;
+
+ constructor(seed: string) {
+ // Johannes Baagøe , 2010
+ this.s0 = this.mash(" ");
+ this.s1 = this.mash(" ");
+ this.s2 = this.mash(" ");
+
+ this.s0 -= this.mash(seed);
+ if (this.s0 < 0) {
+ this.s0 += 1;
+ }
+ this.s1 -= this.mash(seed);
+ if (this.s1 < 0) {
+ this.s1 += 1;
+ }
+ this.s2 -= this.mash(seed);
+ if (this.s2 < 0) {
+ this.s2 += 1;
+ }
+ }
+
+ protected next(): number {
+ const t = 2091639 * this.s0 + this.c * 2.3283064365386963e-10; // 2^-32
+ this.s0 = this.s1;
+ this.s1 = this.s2;
+ return (this.s2 = t - (this.c = t | 0));
+ }
+
+ private mash(data: string): number {
+ for (let i = 0; i < data.length; i++) {
+ this.n += data.charCodeAt(i);
+ let h = 0.02519603282416938 * this.n;
+ this.n = h >>> 0;
+ h -= this.n;
+ h *= this.n;
+ this.n = h >>> 0;
+ h -= this.n;
+ this.n += h * 0x100000000; // 2^32
+ }
+ return (this.n >>> 0) * 2.3283064365386963e-10; // 2^-32
+ }
+}
+
+export class RandomNumberGenerator extends Alea {
+ constructor(seed: string | number = Math.random()) {
+ super(seed.toString());
+ }
+
+ /**
+ * Random choice of an array
+ */
+ choice(array: T[]): T {
+ const index = this.nextIntRange(0, array.length);
+ return array[index];
+ }
+
+ /**
+ * @returns Integer in range [min, max]
+ */
+ nextIntRange(min: number, max: number): number {
+ assert(Number.isFinite(min), "Minimum is no integer");
+ assert(Number.isFinite(max), "Maximum is no integer");
+ assert(max > min, "rng: max <= min");
+ return Math.floor(this.next() * (max - min) + min);
+ }
+
+ /**
+ * @returns Number in range [min, max]
+ */
+ nextRange(min: number, max: number): number {
+ assert(max > min, "rng: max <= min");
+ return this.next() * (max - min) + min;
+ }
+}
diff --git a/src/js/core/sensitive_utils.encrypt.js b/src/js/core/sensitive_utils.encrypt.js
deleted file mode 100644
index 5a83bf76..00000000
--- a/src/js/core/sensitive_utils.encrypt.js
+++ /dev/null
@@ -1,23 +0,0 @@
-import { createHash } from "rusha";
-import crc32 from "crc/crc32";
-import { decompressX64 } from "./lzstring";
-
-export function sha1(str) {
- return createHash().update(str).digest("hex");
-}
-
-// Window.location.host
-export function getNameOfProvider() {
- return window[decompressX64("DYewxghgLgliB2Q")][decompressX64("BYewzgLgdghgtgUyA")];
-}
-
-// Distinguish legacy crc prefixes
-export const CRC_PREFIX = "crc32".padEnd(32, "-");
-
-/**
- * Computes the crc for a given string
- * @param {string} str
- */
-export function computeCrc(str) {
- return CRC_PREFIX + crc32(str).toString(16).padStart(8, "0");
-}
diff --git a/src/js/core/signal.js b/src/js/core/signal.ts
similarity index 67%
rename from src/js/core/signal.js
rename to src/js/core/signal.ts
index 2dbc9f93..52b27387 100644
--- a/src/js/core/signal.js
+++ b/src/js/core/signal.ts
@@ -1,17 +1,16 @@
-export const STOP_PROPAGATION = "stop_propagation";
+export const STOP_PROPAGATION = "stop_propagation" as const;
+export type STOP_PROPAGATION = typeof STOP_PROPAGATION;
-export class Signal {
- constructor() {
- this.receivers = [];
- this.modifyCount = 0;
- }
+export type SignalReceiver = (...args: T) => STOP_PROPAGATION | void;
+
+export class Signal {
+ public receivers: { receiver: SignalReceiver; scope: object }[] = [];
+ public modifyCount: number = 0;
/**
* Adds a new signal listener
- * @param {function} receiver
- * @param {object} scope
*/
- add(receiver, scope = null) {
+ add(receiver: SignalReceiver, scope: object = null) {
assert(receiver, "receiver is null");
this.receivers.push({ receiver, scope });
++this.modifyCount;
@@ -19,10 +18,8 @@ export class Signal {
/**
* Adds a new signal listener
- * @param {function} receiver
- * @param {object} scope
*/
- addToTop(receiver, scope = null) {
+ addToTop(receiver: SignalReceiver, scope: object = null) {
assert(receiver, "receiver is null");
this.receivers.unshift({ receiver, scope });
++this.modifyCount;
@@ -30,15 +27,14 @@ export class Signal {
/**
* Dispatches the signal
- * @param {...any} payload
*/
- dispatch() {
+ dispatch(...payload: T): void | STOP_PROPAGATION {
const modifyState = this.modifyCount;
const n = this.receivers.length;
for (let i = 0; i < n; ++i) {
const { receiver, scope } = this.receivers[i];
- if (receiver.apply(scope, arguments) === STOP_PROPAGATION) {
+ if (receiver.apply(scope, payload) === STOP_PROPAGATION) {
return STOP_PROPAGATION;
}
@@ -51,9 +47,8 @@ export class Signal {
/**
* Removes a receiver
- * @param {function} receiver
*/
- remove(receiver) {
+ remove(receiver: SignalReceiver) {
let index = null;
const n = this.receivers.length;
for (let i = 0; i < n; ++i) {
diff --git a/src/js/core/singleton_factory.js b/src/js/core/singleton_factory.ts
similarity index 73%
rename from src/js/core/singleton_factory.js
rename to src/js/core/singleton_factory.ts
index 7fa38bd3..141611cb 100644
--- a/src/js/core/singleton_factory.js
+++ b/src/js/core/singleton_factory.ts
@@ -3,20 +3,18 @@ import { createLogger } from "./logging";
const logger = createLogger("singleton_factory");
// simple factory pattern
-export class SingletonFactory {
- constructor(id) {
- this.id = id;
+export class SingletonFactory {
+ // Store array as well as dictionary, to speed up lookups
+ public entries: T[] = [];
+ public idToEntry: Record = {};
- // Store array as well as dictionary, to speed up lookups
- this.entries = [];
- this.idToEntry = {};
- }
+ constructor(public id: string) {}
getId() {
return this.id;
}
- register(classHandle) {
+ register(classHandle: Class) {
// First, construct instance
const instance = new classHandle();
@@ -34,19 +32,15 @@ export class SingletonFactory {
/**
* Checks if a given id is registered
- * @param {string} id
- * @returns {boolean}
*/
- hasId(id) {
+ hasId(id: string): boolean {
return !!this.idToEntry[id];
}
/**
* Finds an instance by a given id
- * @param {string} id
- * @returns {object}
*/
- findById(id) {
+ findById(id: string): T {
const entry = this.idToEntry[id];
if (!entry) {
logger.error("Object with id", id, "is not registered!");
@@ -58,10 +52,8 @@ export class SingletonFactory {
/**
* Finds an instance by its constructor (The class handle)
- * @param {object} classHandle
- * @returns {object}
*/
- findByClass(classHandle) {
+ findByClass(classHandle: Class): T {
for (let i = 0; i < this.entries.length; ++i) {
if (this.entries[i] instanceof classHandle) {
return this.entries[i];
@@ -73,25 +65,22 @@ export class SingletonFactory {
/**
* Returns all entries
- * @returns {Array}
*/
- getEntries() {
+ getEntries(): T[] {
return this.entries;
}
/**
* Returns all registered ids
- * @returns {Array}
*/
- getAllIds() {
+ getAllIds(): string[] {
return Object.keys(this.idToEntry);
}
/**
* Returns amount of stored entries
- * @returns {number}
*/
- getNumEntries() {
+ getNumEntries(): number {
return this.entries.length;
}
}
diff --git a/src/js/core/sprites.js b/src/js/core/sprites.js
index 4caa599c..e47b380b 100644
--- a/src/js/core/sprites.js
+++ b/src/js/core/sprites.js
@@ -1,428 +1,425 @@
-import { DrawParameters } from "./draw_parameters";
-import { Rectangle } from "./rectangle";
-import { round3Digits } from "./utils";
-
-export const ORIGINAL_SPRITE_SCALE = "0.75";
-export const FULL_CLIP_RECT = new Rectangle(0, 0, 1, 1);
-
-const EXTRUDE = 0.1;
-
-export class BaseSprite {
- /**
- * Returns the raw handle
- * @returns {HTMLImageElement|HTMLCanvasElement}
- * @abstract
- */
- getRawTexture() {
- abstract;
- return null;
- }
-
- /**
- * Draws the sprite
- * @param {CanvasRenderingContext2D} context
- * @param {number} x
- * @param {number} y
- * @param {number} w
- * @param {number} h
- */
- draw(context, x, y, w, h) {
- // eslint-disable-line no-unused-vars
- abstract;
- }
-}
-
-/**
- * Position of a sprite within an atlas
- */
-export class SpriteAtlasLink {
- /**
- *
- * @param {object} param0
- * @param {number} param0.packedX
- * @param {number} param0.packedY
- * @param {number} param0.packOffsetX
- * @param {number} param0.packOffsetY
- * @param {number} param0.packedW
- * @param {number} param0.packedH
- * @param {number} param0.w
- * @param {number} param0.h
- * @param {HTMLImageElement|HTMLCanvasElement} param0.atlas
- */
- constructor({ w, h, packedX, packedY, packOffsetX, packOffsetY, packedW, packedH, atlas }) {
- this.packedX = packedX;
- this.packedY = packedY;
- this.packedW = packedW;
- this.packedH = packedH;
- this.packOffsetX = packOffsetX;
- this.packOffsetY = packOffsetY;
- this.atlas = atlas;
- this.w = w;
- this.h = h;
- }
-}
-
-export class AtlasSprite extends BaseSprite {
- /**
- *
- * @param {string} spriteName
- */
- constructor(spriteName = "sprite") {
- super();
- /** @type {Object.} */
- this.linksByResolution = {};
- this.spriteName = spriteName;
-
- this.frozen = false;
- }
-
- getRawTexture() {
- return this.linksByResolution[ORIGINAL_SPRITE_SCALE].atlas;
- }
-
- /**
- * Draws the sprite onto a regular context using no contexts
- * @see {BaseSprite.draw}
- */
- draw(context, x, y, w, h) {
- if (G_IS_DEV) {
- assert(context instanceof CanvasRenderingContext2D, "Not a valid context");
- }
-
- const link = this.linksByResolution[ORIGINAL_SPRITE_SCALE];
-
- if (!link) {
- throw new Error(
- "draw: Link for " +
- this.spriteName +
- " not known: " +
- ORIGINAL_SPRITE_SCALE +
- " (having " +
- Object.keys(this.linksByResolution) +
- ")"
- );
- }
-
- const width = w || link.w;
- const height = h || link.h;
-
- const scaleW = width / link.w;
- const scaleH = height / link.h;
-
- context.drawImage(
- link.atlas,
-
- link.packedX,
- link.packedY,
- link.packedW,
- link.packedH,
-
- x + link.packOffsetX * scaleW,
- y + link.packOffsetY * scaleH,
- link.packedW * scaleW,
- link.packedH * scaleH
- );
- }
-
- /**
- *
- * @param {DrawParameters} parameters
- * @param {number} x
- * @param {number} y
- * @param {number} size
- * @param {boolean=} clipping
- */
- drawCachedCentered(parameters, x, y, size, clipping = true) {
- this.drawCached(parameters, x - size / 2, y - size / 2, size, size, clipping);
- }
-
- /**
- *
- * @param {CanvasRenderingContext2D} context
- * @param {number} x
- * @param {number} y
- * @param {number} size
- */
- drawCentered(context, x, y, size) {
- this.draw(context, x - size / 2, y - size / 2, size, size);
- }
-
- /**
- * Draws the sprite
- * @param {DrawParameters} parameters
- * @param {number} x
- * @param {number} y
- * @param {number} w
- * @param {number} h
- * @param {boolean=} clipping Whether to perform culling
- */
- drawCached(parameters, x, y, w = null, h = null, clipping = true) {
- if (G_IS_DEV) {
- assert(parameters instanceof DrawParameters, "Not a valid context");
- assert(!!w && w > 0, "Not a valid width:" + w);
- assert(!!h && h > 0, "Not a valid height:" + h);
- }
-
- const visibleRect = parameters.visibleRect;
-
- const scale = parameters.desiredAtlasScale;
- const link = this.linksByResolution[scale];
-
- if (!link) {
- throw new Error(
- "drawCached: Link for " +
- this.spriteName +
- " at scale " +
- scale +
- " not known (having " +
- Object.keys(this.linksByResolution) +
- ")"
- );
- }
-
- const scaleW = w / link.w;
- const scaleH = h / link.h;
-
- let destX = x + link.packOffsetX * scaleW;
- let destY = y + link.packOffsetY * scaleH;
- let destW = link.packedW * scaleW;
- let destH = link.packedH * scaleH;
-
- let srcX = link.packedX;
- let srcY = link.packedY;
- let srcW = link.packedW;
- let srcH = link.packedH;
-
- let intersection = null;
-
- if (clipping) {
- const rect = new Rectangle(destX, destY, destW, destH);
- intersection = rect.getIntersection(visibleRect);
- if (!intersection) {
- return;
- }
-
- srcX += (intersection.x - destX) / scaleW;
- srcY += (intersection.y - destY) / scaleH;
-
- srcW *= intersection.w / destW;
- srcH *= intersection.h / destH;
-
- destX = intersection.x;
- destY = intersection.y;
-
- destW = intersection.w;
- destH = intersection.h;
- }
-
- parameters.context.drawImage(
- link.atlas,
-
- // atlas src pos
- srcX,
- srcY,
-
- // atlas src size
- srcW,
- srcH,
-
- // dest pos and size
- destX - EXTRUDE,
- destY - EXTRUDE,
- destW + 2 * EXTRUDE,
- destH + 2 * EXTRUDE
- );
- }
-
- /**
- * Draws a subset of the sprite. Does NO culling
- * @param {DrawParameters} parameters
- * @param {number} x
- * @param {number} y
- * @param {number} w
- * @param {number} h
- * @param {Rectangle=} clipRect The rectangle in local space (0 ... 1) to draw of the image
- */
- drawCachedWithClipRect(parameters, x, y, w = null, h = null, clipRect = FULL_CLIP_RECT) {
- if (G_IS_DEV) {
- assert(parameters instanceof DrawParameters, "Not a valid context");
- assert(!!w && w > 0, "Not a valid width:" + w);
- assert(!!h && h > 0, "Not a valid height:" + h);
- assert(clipRect, "No clip rect given!");
- }
-
- const scale = parameters.desiredAtlasScale;
- const link = this.linksByResolution[scale];
-
- if (!link) {
- throw new Error(
- "drawCachedWithClipRect: Link for " +
- this.spriteName +
- " at scale " +
- scale +
- " not known (having " +
- Object.keys(this.linksByResolution) +
- ")"
- );
- }
-
- const scaleW = w / link.w;
- const scaleH = h / link.h;
-
- let destX = x + link.packOffsetX * scaleW + clipRect.x * w;
- let destY = y + link.packOffsetY * scaleH + clipRect.y * h;
- let destW = link.packedW * scaleW * clipRect.w;
- let destH = link.packedH * scaleH * clipRect.h;
-
- let srcX = link.packedX + clipRect.x * link.packedW;
- let srcY = link.packedY + clipRect.y * link.packedH;
- let srcW = link.packedW * clipRect.w;
- let srcH = link.packedH * clipRect.h;
-
- parameters.context.drawImage(
- link.atlas,
-
- // atlas src pos
- srcX,
- srcY,
-
- // atlas src siize
- srcW,
- srcH,
-
- // dest pos and size
- destX - EXTRUDE,
- destY - EXTRUDE,
- destW + 2 * EXTRUDE,
- destH + 2 * EXTRUDE
- );
- }
-
- /**
- * Renders into an html element
- * @param {HTMLElement} element
- * @param {number} w
- * @param {number} h
- */
- renderToHTMLElement(element, w = 1, h = 1) {
- element.style.position = "relative";
- element.innerHTML = this.getAsHTML(w, h);
- }
-
- /**
- * Returns the html to render as icon
- * @param {number} w
- * @param {number} h
- */
- getAsHTML(w, h) {
- const link = this.linksByResolution["0.5"];
-
- if (!link) {
- throw new Error(
- "getAsHTML: Link for " +
- this.spriteName +
- " at scale 0.5" +
- " not known (having " +
- Object.keys(this.linksByResolution) +
- ")"
- );
- }
-
- // Find out how much we have to scale it so that it fits
- const scaleX = w / link.w;
- const scaleY = h / link.h;
-
- // Find out how big the scaled atlas is
- const atlasW = link.atlas.width * scaleX;
- const atlasH = link.atlas.height * scaleY;
-
- // @ts-ignore
- const srcSafe = link.atlas.src.replaceAll("\\", "/");
-
- // Find out how big we render the sprite
- const widthAbsolute = scaleX * link.packedW;
- const heightAbsolute = scaleY * link.packedH;
-
- // Compute the position in the relative container
- const leftRelative = (link.packOffsetX * scaleX) / w;
- const topRelative = (link.packOffsetY * scaleY) / h;
- const widthRelative = widthAbsolute / w;
- const heightRelative = heightAbsolute / h;
-
- // Scale the atlas relative to the width and height of the element
- const bgW = atlasW / widthAbsolute;
- const bgH = atlasH / heightAbsolute;
-
- // Figure out what the position of the atlas is
- const bgX = link.packedX * scaleX;
- const bgY = link.packedY * scaleY;
-
- // Fuck you, whoever thought its a good idea to make background-position work like it does now
- const bgXRelative = -bgX / (widthAbsolute - atlasW);
- const bgYRelative = -bgY / (heightAbsolute - atlasH);
-
- return `
-
- `;
- }
-}
-
-export class RegularSprite extends BaseSprite {
- constructor(sprite, w, h) {
- super();
- this.w = w;
- this.h = h;
- this.sprite = sprite;
- }
-
- getRawTexture() {
- return this.sprite;
- }
-
- /**
- * Draws the sprite, do *not* use this for sprites which are rendered! Only for drawing
- * images into buffers
- * @param {CanvasRenderingContext2D} context
- * @param {number} x
- * @param {number} y
- * @param {number} w
- * @param {number} h
- */
- draw(context, x, y, w, h) {
- assert(context, "No context given");
- assert(x !== undefined, "No x given");
- assert(y !== undefined, "No y given");
- assert(w !== undefined, "No width given");
- assert(h !== undefined, "No height given");
- context.drawImage(this.sprite, x, y, w, h);
- }
-
- /**
- * Draws the sprite, do *not* use this for sprites which are rendered! Only for drawing
- * images into buffers
- * @param {CanvasRenderingContext2D} context
- * @param {number} x
- * @param {number} y
- * @param {number} w
- * @param {number} h
- */
- drawCentered(context, x, y, w, h) {
- assert(context, "No context given");
- assert(x !== undefined, "No x given");
- assert(y !== undefined, "No y given");
- assert(w !== undefined, "No width given");
- assert(h !== undefined, "No height given");
- context.drawImage(this.sprite, x - w / 2, y - h / 2, w, h);
- }
-}
+import { DrawParameters } from "./draw_parameters";
+import { Rectangle } from "./rectangle";
+import { round3Digits } from "./utils";
+
+export const ORIGINAL_SPRITE_SCALE = "0.75";
+export const FULL_CLIP_RECT = new Rectangle(0, 0, 1, 1);
+
+export class BaseSprite {
+ /**
+ * Returns the raw handle
+ * @returns {HTMLImageElement|HTMLCanvasElement}
+ * @abstract
+ */
+ getRawTexture() {
+ abstract;
+ return null;
+ }
+
+ /**
+ * Draws the sprite
+ * @param {CanvasRenderingContext2D} context
+ * @param {number} x
+ * @param {number} y
+ * @param {number} w
+ * @param {number} h
+ */
+ draw(context, x, y, w, h) {
+ abstract;
+ }
+}
+
+/**
+ * Position of a sprite within an atlas
+ */
+export class SpriteAtlasLink {
+ /**
+ *
+ * @param {object} param0
+ * @param {number} param0.packedX
+ * @param {number} param0.packedY
+ * @param {number} param0.packOffsetX
+ * @param {number} param0.packOffsetY
+ * @param {number} param0.packedW
+ * @param {number} param0.packedH
+ * @param {number} param0.w
+ * @param {number} param0.h
+ * @param {HTMLImageElement|HTMLCanvasElement} param0.atlas
+ */
+ constructor({ w, h, packedX, packedY, packOffsetX, packOffsetY, packedW, packedH, atlas }) {
+ this.packedX = packedX;
+ this.packedY = packedY;
+ this.packedW = packedW;
+ this.packedH = packedH;
+ this.packOffsetX = packOffsetX;
+ this.packOffsetY = packOffsetY;
+ this.atlas = atlas;
+ this.w = w;
+ this.h = h;
+ }
+}
+
+export class AtlasSprite extends BaseSprite {
+ /**
+ *
+ * @param {string} spriteName
+ */
+ constructor(spriteName = "sprite") {
+ super();
+ /** @type {Object.} */
+ this.linksByResolution = {};
+ this.spriteName = spriteName;
+
+ this.frozen = false;
+ }
+
+ getRawTexture() {
+ return this.linksByResolution[ORIGINAL_SPRITE_SCALE].atlas;
+ }
+
+ /**
+ * Draws the sprite onto a regular context using no contexts
+ * @see {BaseSprite.draw}
+ */
+ draw(context, x, y, w, h) {
+ if (G_IS_DEV) {
+ assert(context instanceof CanvasRenderingContext2D, "Not a valid context");
+ }
+
+ const link = this.linksByResolution[ORIGINAL_SPRITE_SCALE];
+
+ if (!link) {
+ throw new Error(
+ "draw: Link for " +
+ this.spriteName +
+ " not known: " +
+ ORIGINAL_SPRITE_SCALE +
+ " (having " +
+ Object.keys(this.linksByResolution) +
+ ")"
+ );
+ }
+
+ const width = w || link.w;
+ const height = h || link.h;
+
+ const scaleW = width / link.w;
+ const scaleH = height / link.h;
+
+ context.drawImage(
+ link.atlas,
+
+ link.packedX,
+ link.packedY,
+ link.packedW,
+ link.packedH,
+
+ x + link.packOffsetX * scaleW,
+ y + link.packOffsetY * scaleH,
+ link.packedW * scaleW,
+ link.packedH * scaleH
+ );
+ }
+
+ /**
+ *
+ * @param {DrawParameters} parameters
+ * @param {number} x
+ * @param {number} y
+ * @param {number} size
+ * @param {boolean=} clipping
+ */
+ drawCachedCentered(parameters, x, y, size, clipping = true) {
+ this.drawCached(parameters, x - size / 2, y - size / 2, size, size, clipping);
+ }
+
+ /**
+ *
+ * @param {CanvasRenderingContext2D} context
+ * @param {number} x
+ * @param {number} y
+ * @param {number} size
+ */
+ drawCentered(context, x, y, size) {
+ this.draw(context, x - size / 2, y - size / 2, size, size);
+ }
+
+ /**
+ * Draws the sprite
+ * @param {DrawParameters} parameters
+ * @param {number} x
+ * @param {number} y
+ * @param {number} w
+ * @param {number} h
+ * @param {boolean=} clipping Whether to perform culling
+ */
+ drawCached(parameters, x, y, w = null, h = null, clipping = true) {
+ if (G_IS_DEV) {
+ assert(parameters instanceof DrawParameters, "Not a valid context");
+ assert(!!w && w > 0, "Not a valid width:" + w);
+ assert(!!h && h > 0, "Not a valid height:" + h);
+ }
+
+ const visibleRect = parameters.visibleRect;
+
+ const scale = parameters.desiredAtlasScale;
+ const link = this.linksByResolution[scale];
+
+ if (!link) {
+ throw new Error(
+ "drawCached: Link for " +
+ this.spriteName +
+ " at scale " +
+ scale +
+ " not known (having " +
+ Object.keys(this.linksByResolution) +
+ ")"
+ );
+ }
+
+ const scaleW = w / link.w;
+ const scaleH = h / link.h;
+
+ let destX = x + link.packOffsetX * scaleW;
+ let destY = y + link.packOffsetY * scaleH;
+ let destW = link.packedW * scaleW;
+ let destH = link.packedH * scaleH;
+
+ let srcX = link.packedX;
+ let srcY = link.packedY;
+ let srcW = link.packedW;
+ let srcH = link.packedH;
+
+ let intersection = null;
+
+ if (clipping) {
+ const rect = new Rectangle(destX, destY, destW, destH);
+ intersection = rect.getIntersection(visibleRect);
+ if (!intersection) {
+ return;
+ }
+
+ srcX += (intersection.x - destX) / scaleW;
+ srcY += (intersection.y - destY) / scaleH;
+
+ srcW *= intersection.w / destW;
+ srcH *= intersection.h / destH;
+
+ destX = intersection.x;
+ destY = intersection.y;
+
+ destW = intersection.w;
+ destH = intersection.h;
+ }
+
+ parameters.context.drawImage(
+ link.atlas,
+
+ // atlas src pos
+ srcX,
+ srcY,
+
+ // atlas src size
+ srcW,
+ srcH,
+
+ // dest pos and size
+ destX,
+ destY,
+ destW,
+ destH
+ );
+ }
+
+ /**
+ * Draws a subset of the sprite. Does NO culling
+ * @param {DrawParameters} parameters
+ * @param {number} x
+ * @param {number} y
+ * @param {number} w
+ * @param {number} h
+ * @param {Rectangle=} clipRect The rectangle in local space (0 ... 1) to draw of the image
+ */
+ drawCachedWithClipRect(parameters, x, y, w = null, h = null, clipRect = FULL_CLIP_RECT) {
+ if (G_IS_DEV) {
+ assert(parameters instanceof DrawParameters, "Not a valid context");
+ assert(!!w && w > 0, "Not a valid width:" + w);
+ assert(!!h && h > 0, "Not a valid height:" + h);
+ assert(clipRect, "No clip rect given!");
+ }
+
+ const scale = parameters.desiredAtlasScale;
+ const link = this.linksByResolution[scale];
+
+ if (!link) {
+ throw new Error(
+ "drawCachedWithClipRect: Link for " +
+ this.spriteName +
+ " at scale " +
+ scale +
+ " not known (having " +
+ Object.keys(this.linksByResolution) +
+ ")"
+ );
+ }
+
+ const scaleW = w / link.w;
+ const scaleH = h / link.h;
+
+ let destX = x + link.packOffsetX * scaleW + clipRect.x * w;
+ let destY = y + link.packOffsetY * scaleH + clipRect.y * h;
+ let destW = link.packedW * scaleW * clipRect.w;
+ let destH = link.packedH * scaleH * clipRect.h;
+
+ let srcX = link.packedX + clipRect.x * link.packedW;
+ let srcY = link.packedY + clipRect.y * link.packedH;
+ let srcW = link.packedW * clipRect.w;
+ let srcH = link.packedH * clipRect.h;
+
+ parameters.context.drawImage(
+ link.atlas,
+
+ // atlas src pos
+ srcX,
+ srcY,
+
+ // atlas src siize
+ srcW,
+ srcH,
+
+ // dest pos and size
+ destX,
+ destY,
+ destW,
+ destH
+ );
+ }
+
+ /**
+ * Renders into an html element
+ * @param {HTMLElement} element
+ * @param {number} w
+ * @param {number} h
+ */
+ renderToHTMLElement(element, w = 1, h = 1) {
+ element.style.position = "relative";
+ element.innerHTML = this.getAsHTML(w, h);
+ }
+
+ /**
+ * Returns the html to render as icon
+ * @param {number} w
+ * @param {number} h
+ */
+ getAsHTML(w, h) {
+ const link = this.linksByResolution["0.5"];
+
+ if (!link) {
+ throw new Error(
+ "getAsHTML: Link for " +
+ this.spriteName +
+ " at scale 0.5" +
+ " not known (having " +
+ Object.keys(this.linksByResolution) +
+ ")"
+ );
+ }
+
+ // Find out how much we have to scale it so that it fits
+ const scaleX = w / link.w;
+ const scaleY = h / link.h;
+
+ // Find out how big the scaled atlas is
+ const atlasW = link.atlas.width * scaleX;
+ const atlasH = link.atlas.height * scaleY;
+
+ // @ts-ignore
+ const srcSafe = link.atlas.src.replaceAll("\\", "/");
+
+ // Find out how big we render the sprite
+ const widthAbsolute = scaleX * link.packedW;
+ const heightAbsolute = scaleY * link.packedH;
+
+ // Compute the position in the relative container
+ const leftRelative = (link.packOffsetX * scaleX) / w;
+ const topRelative = (link.packOffsetY * scaleY) / h;
+ const widthRelative = widthAbsolute / w;
+ const heightRelative = heightAbsolute / h;
+
+ // Scale the atlas relative to the width and height of the element
+ const bgW = atlasW / widthAbsolute;
+ const bgH = atlasH / heightAbsolute;
+
+ // Figure out what the position of the atlas is
+ const bgX = link.packedX * scaleX;
+ const bgY = link.packedY * scaleY;
+
+ // Fuck you, whoever thought its a good idea to make background-position work like it does now
+ const bgXRelative = -bgX / (widthAbsolute - atlasW);
+ const bgYRelative = -bgY / (heightAbsolute - atlasH);
+
+ return `
+
+ `;
+ }
+}
+
+export class RegularSprite extends BaseSprite {
+ constructor(sprite, w, h) {
+ super();
+ this.w = w;
+ this.h = h;
+ this.sprite = sprite;
+ }
+
+ getRawTexture() {
+ return this.sprite;
+ }
+
+ /**
+ * Draws the sprite, do *not* use this for sprites which are rendered! Only for drawing
+ * images into buffers
+ * @param {CanvasRenderingContext2D} context
+ * @param {number} x
+ * @param {number} y
+ * @param {number} w
+ * @param {number} h
+ */
+ draw(context, x, y, w, h) {
+ assert(context, "No context given");
+ assert(x !== undefined, "No x given");
+ assert(y !== undefined, "No y given");
+ assert(w !== undefined, "No width given");
+ assert(h !== undefined, "No height given");
+ context.drawImage(this.sprite, x, y, w, h);
+ }
+
+ /**
+ * Draws the sprite, do *not* use this for sprites which are rendered! Only for drawing
+ * images into buffers
+ * @param {CanvasRenderingContext2D} context
+ * @param {number} x
+ * @param {number} y
+ * @param {number} w
+ * @param {number} h
+ */
+ drawCentered(context, x, y, w, h) {
+ assert(context, "No context given");
+ assert(x !== undefined, "No x given");
+ assert(y !== undefined, "No y given");
+ assert(w !== undefined, "No width given");
+ assert(h !== undefined, "No height given");
+ context.drawImage(this.sprite, x - w / 2, y - h / 2, w, h);
+ }
+}
diff --git a/src/js/core/stale_area_detector.js b/src/js/core/stale_area_detector.js
index 631d0327..23247235 100644
--- a/src/js/core/stale_area_detector.js
+++ b/src/js/core/stale_area_detector.js
@@ -1,90 +1,91 @@
-import { Component } from "../game/component";
-import { Entity } from "../game/entity";
-import { globalConfig } from "./config";
-import { createLogger } from "./logging";
-import { Rectangle } from "./rectangle";
-
-const logger = createLogger("stale_areas");
-
-export class StaleAreaDetector {
- /**
- *
- * @param {object} param0
- * @param {import("../game/root").GameRoot} param0.root
- * @param {string} param0.name The name for reference
- * @param {(Rectangle) => void} param0.recomputeMethod Method which recomputes the given area
- */
- constructor({ root, name, recomputeMethod }) {
- this.root = root;
- this.name = name;
- this.recomputeMethod = recomputeMethod;
-
- /** @type {Rectangle} */
- this.staleArea = null;
- }
-
- /**
- * Invalidates the given area
- * @param {Rectangle} area
- */
- invalidate(area) {
- // logger.log(this.name, "invalidated", area.toString());
- if (this.staleArea) {
- this.staleArea = this.staleArea.getUnion(area);
- } else {
- this.staleArea = area.clone();
- }
- }
-
- /**
- * Makes this detector recompute the area of an entity whenever
- * it changes in any way
- * @param {Array} components
- * @param {number} tilesAround How many tiles arround to expand the area
- */
- recomputeOnComponentsChanged(components, tilesAround) {
- const componentIds = components.map(component => component.getId());
-
- /**
- * Internal checker method
- * @param {Entity} entity
- */
- const checker = entity => {
- if (!this.root.gameInitialized) {
- return;
- }
-
- // Check for all components
- for (let i = 0; i < componentIds.length; ++i) {
- if (entity.components[componentIds[i]]) {
- // Entity is relevant, compute affected area
- const area = entity.components.StaticMapEntity.getTileSpaceBounds().expandedInAllDirections(
- tilesAround
- );
- this.invalidate(area);
- return;
- }
- }
- };
-
- this.root.signals.entityAdded.add(checker);
- this.root.signals.entityChanged.add(checker);
- this.root.signals.entityComponentRemoved.add(checker);
- this.root.signals.entityGotNewComponent.add(checker);
- this.root.signals.entityDestroyed.add(checker);
- }
-
- /**
- * Updates the stale area
- */
- update() {
- if (this.staleArea) {
- if (G_IS_DEV && globalConfig.debug.renderChanges) {
- logger.log(this.name, "is recomputing", this.staleArea.toString());
- this.root.hud.parts.changesDebugger.renderChange(this.name, this.staleArea, "#fd145b");
- }
- this.recomputeMethod(this.staleArea);
- this.staleArea = null;
- }
- }
-}
+import { Component } from "../game/component";
+import { Entity } from "../game/entity";
+import { globalConfig } from "./config";
+import { createLogger } from "./logging";
+import { Rectangle } from "./rectangle";
+
+const logger = createLogger("stale_areas");
+
+export class StaleAreaDetector {
+ /**
+ *
+ * @param {object} param0
+ * @param {import("../game/root").GameRoot} param0.root
+ * @param {string} param0.name The name for reference
+ * @param {(Rectangle) => void} param0.recomputeMethod Method which recomputes the given area
+ */
+ constructor({ root, name, recomputeMethod }) {
+ this.root = root;
+ this.name = name;
+ this.recomputeMethod = recomputeMethod;
+
+ /** @type {Rectangle} */
+ this.staleArea = null;
+ }
+
+ /**
+ * Invalidates the given area
+ * @param {Rectangle} area
+ */
+ invalidate(area) {
+ // logger.log(this.name, "invalidated", area.toString());
+ if (this.staleArea) {
+ this.staleArea = this.staleArea.getUnion(area);
+ } else {
+ this.staleArea = area.clone();
+ }
+ }
+
+ /**
+ * Makes this detector recompute the area of an entity whenever
+ * it changes in any way
+ * @param {Array} components
+ * @param {number} tilesAround How many tiles arround to expand the area
+ */
+ recomputeOnComponentsChanged(components, tilesAround) {
+ const componentIds = components.map(component => component.getId());
+
+ /**
+ * Internal checker method
+ * @param {Entity} entity
+ */
+ const checker = entity => {
+ if (!this.root.gameInitialized) {
+ return;
+ }
+
+ // Check for all components
+ for (let i = 0; i < componentIds.length; ++i) {
+ if (entity.components[componentIds[i]]) {
+ // Entity is relevant, compute affected area
+ const area =
+ entity.components.StaticMapEntity.getTileSpaceBounds().expandedInAllDirections(
+ tilesAround
+ );
+ this.invalidate(area);
+ return;
+ }
+ }
+ };
+
+ this.root.signals.entityAdded.add(checker);
+ this.root.signals.entityChanged.add(checker);
+ this.root.signals.entityComponentRemoved.add(checker);
+ this.root.signals.entityGotNewComponent.add(checker);
+ this.root.signals.entityDestroyed.add(checker);
+ }
+
+ /**
+ * Updates the stale area
+ */
+ update() {
+ if (this.staleArea) {
+ if (G_IS_DEV && globalConfig.debug.renderChanges) {
+ logger.log(this.name, "is recomputing", this.staleArea.toString());
+ this.root.hud.parts.changesDebugger.renderChange(this.name, this.staleArea, "#fd145b");
+ }
+ this.recomputeMethod(this.staleArea);
+ this.staleArea = null;
+ }
+ }
+}
diff --git a/src/js/core/state_manager.js b/src/js/core/state_manager.js
index 70b4b7f4..52815d27 100644
--- a/src/js/core/state_manager.js
+++ b/src/js/core/state_manager.js
@@ -2,10 +2,10 @@
import { Application } from "../application";
/* typehints:end*/
+import { MOD_SIGNALS } from "../mods/mod_signals";
import { GameState } from "./game_state";
import { createLogger } from "./logging";
-import { waitNextFrame, removeAllChildren } from "./utils";
-import { MOD_SIGNALS } from "../mods/mod_signals";
+import { removeAllChildren, waitNextFrame } from "./utils";
const logger = createLogger("state_manager");
@@ -34,7 +34,7 @@ export class StateManager {
// Create a dummy to retrieve the key
const dummy = new stateClass();
assert(dummy instanceof GameState, "Not a state!");
- const key = dummy.getKey();
+ const key = dummy.key;
assert(!this.stateClasses[key], `State '${key}' is already registered!`);
this.stateClasses[key] = stateClass;
}
@@ -61,7 +61,7 @@ export class StateManager {
}
if (this.currentState) {
- if (key === this.currentState.getKey()) {
+ if (key === this.currentState.key) {
logger.error(`State '${key}' is already active!`);
return false;
}
@@ -69,7 +69,7 @@ export class StateManager {
// Remove all references
for (const stateKey in this.currentState) {
- if (this.currentState.hasOwnProperty(stateKey)) {
+ if (Object.hasOwn(this.currentState, stateKey)) {
delete this.currentState[stateKey];
}
}
@@ -88,25 +88,20 @@ export class StateManager {
document.body.id = "state_" + key;
if (this.currentState.getRemovePreviousContent()) {
- document.body.innerHTML = this.currentState.internalGetFullHtml();
+ const content = this.currentState.internalGetWrappedContent();
+ document.body.append(content);
}
const dialogParent = document.createElement("div");
dialogParent.classList.add("modalDialogParent");
document.body.appendChild(dialogParent);
- try {
- this.currentState.internalEnterCallback(payload);
- } catch (ex) {
- console.error(ex);
- throw ex;
- }
+
+ this.currentState.internalEnterCallback(payload);
this.app.sound.playThemeMusic(this.currentState.getThemeMusic());
this.currentState.onResized(this.app.screenWidth, this.app.screenHeight);
- this.app.analytics.trackStateEnter(key);
-
window.history.pushState(
{
key,
diff --git a/src/js/core/steam_sso.js b/src/js/core/steam_sso.js
deleted file mode 100644
index 67c6d582..00000000
--- a/src/js/core/steam_sso.js
+++ /dev/null
@@ -1,89 +0,0 @@
-import { T } from "../translations";
-import { openStandaloneLink } from "./config";
-
-export let WEB_STEAM_SSO_AUTHENTICATED = false;
-
-export async function authorizeViaSSOToken(app, dialogs) {
- if (G_IS_STANDALONE) {
- return;
- }
-
- if (window.location.search.includes("sso_logout_silent")) {
- window.localStorage.setItem("steam_sso_auth_token", "");
- window.location.replace("/");
- return new Promise(() => null);
- }
-
- if (window.location.search.includes("sso_logout")) {
- const { ok } = dialogs.showWarning(T.dialogs.steamSsoError.title, T.dialogs.steamSsoError.desc);
- window.localStorage.setItem("steam_sso_auth_token", "");
- ok.add(() => window.location.replace("/"));
- return new Promise(() => null);
- }
-
- if (window.location.search.includes("steam_sso_no_ownership")) {
- const { ok, getStandalone } = dialogs.showWarning(
- T.dialogs.steamSsoNoOwnership.title,
- T.dialogs.steamSsoNoOwnership.desc,
- ["ok", "getStandalone:good"]
- );
- window.localStorage.setItem("steam_sso_auth_token", "");
- getStandalone.add(() => {
- openStandaloneLink(app, "sso_ownership");
- window.location.replace("/");
- });
- ok.add(() => window.location.replace("/"));
- return new Promise(() => null);
- }
-
- const token = window.localStorage.getItem("steam_sso_auth_token");
- if (!token) {
- return Promise.resolve();
- }
-
- const apiUrl = app.clientApi.getEndpoint();
- console.warn("Authorizing via token:", token);
-
- const verify = async () => {
- const token = window.localStorage.getItem("steam_sso_auth_token");
- if (!token) {
- window.location.replace("?sso_logout");
- return;
- }
-
- try {
- const response = await Promise.race([
- fetch(apiUrl + "/v1/sso/refresh", {
- method: "POST",
- body: token,
- headers: {
- "x-api-key": "d5c54aaa491f200709afff082c153ef2",
- },
- }),
- new Promise((resolve, reject) => {
- setTimeout(() => reject("timeout exceeded"), 20000);
- }),
- ]);
-
- const responseText = await response.json();
- if (!responseText.token) {
- console.warn("Failed to register");
- window.localStorage.setItem("steam_sso_auth_token", "");
- window.location.replace("?sso_logout");
- return;
- }
-
- window.localStorage.setItem("steam_sso_auth_token", responseText.token);
- app.clientApi.token = responseText.token;
- WEB_STEAM_SSO_AUTHENTICATED = true;
- } catch (ex) {
- console.warn("Auth failure", ex);
- window.localStorage.setItem("steam_sso_auth_token", "");
- window.location.replace("/");
- return new Promise(() => null);
- }
- };
-
- await verify();
- setInterval(verify, 120000);
-}
diff --git a/src/js/core/textual_game_state.js b/src/js/core/textual_game_state.tsx
similarity index 69%
rename from src/js/core/textual_game_state.js
rename to src/js/core/textual_game_state.tsx
index 52a1f946..8cc2a0d7 100644
--- a/src/js/core/textual_game_state.js
+++ b/src/js/core/textual_game_state.tsx
@@ -1,20 +1,24 @@
import { HUDModalDialogs } from "../game/hud/parts/modal_dialogs";
import { GameState } from "./game_state";
-import { T } from "../translations";
/**
* Baseclass for all game states which are structured similary: A header with back button + some
* scrollable content.
*/
-export class TextualGameState extends GameState {
- ///// INTERFACE ////
+export abstract class TextualGameState extends GameState {
+ private backToStateId: string | null = null;
+ private backToStatePayload: {} | null = null;
+
+ protected headerElement: HTMLElement;
+ protected containerElement: HTMLElement;
+ protected dialogs: HUDModalDialogs;
/**
* Should return the states inner html. If not overriden, will create a scrollable container
* with the content of getMainContentHTML()
- * @returns {string}
+ * @deprecated
*/
- getInnerHTML() {
+ getInnerHTML(): string {
return `
${this.getMainContentHTML()}
@@ -24,17 +28,43 @@ export class TextualGameState extends GameState {
/**
* Should return the states HTML content.
+ * @deprecated
*/
- getMainContentHTML() {
+ getMainContentHTML(): string {
return "";
}
+ /**
+ * Should return the element(s) to be displayed in the state.
+ * If not overridden, a default layout consisting of a back button,
+ * title, and content returned by {@link getInitialContent}.
+ */
+ protected override getContentLayout(): Node {
+ const initialContent = this.getInitialContent();
+ const content = initialContent !== null &&
{initialContent}
;
+
+ return (
+ <>
+
+
{content || super.getContentLayout()}
+ >
+ );
+ }
+
+ protected getInitialContent(): Node {
+ return null;
+ }
+
/**
* Should return the title of the game state. If null, no title and back button will
* get created
- * @returns {string|null}
*/
- getStateHeaderTitle() {
+ protected getStateHeaderTitle(): string | null {
return null;
}
@@ -44,7 +74,7 @@ export class TextualGameState extends GameState {
* Back button handler, can be overridden. Per default it goes back to the main menu,
* or if coming from the game it moves back to the game again.
*/
- onBackButton() {
+ override onBackButton() {
if (this.backToStateId) {
this.moveToState(this.backToStateId, this.backToStatePayload);
} else {
@@ -61,9 +91,9 @@ export class TextualGameState extends GameState {
/**
* Goes to a new state, telling him to go back to this state later
- * @param {string} stateId
+ * @param stateId
*/
- moveToStateAddGoBack(stateId) {
+ moveToStateAddGoBack(stateId: string) {
this.moveToState(stateId, {
backToStateId: this.key,
backToStatePayload: {
@@ -89,43 +119,20 @@ export class TextualGameState extends GameState {
}
}
- /**
- * Overrides the GameState implementation to provide our own html
- */
- internalGetFullHtml() {
- let headerHtml = "";
- if (this.getStateHeaderTitle()) {
- headerHtml = `
- `;
- }
-
- return `
- ${headerHtml}
-
- ${this.getInnerHTML()}
-
-
- `;
- }
-
//// INTERNALS /////
/**
* Overrides the GameState leave callback to cleanup stuff
*/
- internalLeaveCallback() {
+ override internalLeaveCallback() {
super.internalLeaveCallback();
this.dialogs.cleanup();
}
/**
* Overrides the GameState enter callback to setup required stuff
- * @param {any} payload
*/
- internalEnterCallback(payload) {
+ override internalEnterCallback(payload: any) {
super.internalEnterCallback(payload, false);
if (payload.backToStateId) {
this.backToStateId = payload.backToStateId;
diff --git a/src/js/core/tracked_state.js b/src/js/core/tracked_state.ts
similarity index 69%
rename from src/js/core/tracked_state.js
rename to src/js/core/tracked_state.ts
index 1a538bc6..f5da2ab4 100644
--- a/src/js/core/tracked_state.js
+++ b/src/js/core/tracked_state.ts
@@ -1,7 +1,10 @@
-export class TrackedState {
- constructor(callbackMethod = null, callbackScope = null) {
- this.lastSeenValue = null;
+export type TrackedStateCallback
= (value: T) => void;
+export class TrackedState {
+ public lastSeenValue: T = null;
+ public callback: TrackedStateCallback;
+
+ constructor(callbackMethod: TrackedStateCallback = null, callbackScope: unknown = null) {
if (callbackMethod) {
this.callback = callbackMethod;
if (callbackScope) {
@@ -10,7 +13,7 @@ export class TrackedState {
}
}
- set(value, changeHandler = null, changeScope = null) {
+ set(value: T, changeHandler: TrackedStateCallback = null, changeScope: unknown = null) {
if (value !== this.lastSeenValue) {
// Copy value since the changeHandler call could actually modify our lastSeenValue
const valueCopy = value;
@@ -29,11 +32,11 @@ export class TrackedState {
}
}
- setSilent(value) {
+ setSilent(value: T) {
this.lastSeenValue = value;
}
- get() {
+ get(): T {
return this.lastSeenValue;
}
}
diff --git a/src/js/core/utils.js b/src/js/core/utils.js
index 9e2126b1..87ec41ff 100644
--- a/src/js/core/utils.js
+++ b/src/js/core/utils.js
@@ -1,790 +1,666 @@
-import { T } from "../translations";
-import { rando } from "@nastyox/rando.js";
-import { WEB_STEAM_SSO_AUTHENTICATED } from "./steam_sso";
-
-const bigNumberSuffixTranslationKeys = ["thousands", "millions", "billions", "trillions"];
-
-/**
- * Returns a platform name
- * @returns {"android" | "browser" | "ios" | "standalone" | "unknown"}
- */
-export function getPlatformName() {
- if (G_IS_STANDALONE) {
- return "standalone";
- } else if (G_IS_BROWSER) {
- return "browser";
- }
- return "unknown";
-}
-
-/**
- * Makes a new 2D array with undefined contents
- * @param {number} w
- * @param {number} h
- * @returns {Array>}
- */
-export function make2DUndefinedArray(w, h) {
- const result = new Array(w);
- for (let x = 0; x < w; ++x) {
- result[x] = new Array(h);
- }
- return result;
-}
-
-/**
- * Creates a new map (an empty object without any props)
- */
-export function newEmptyMap() {
- return Object.create(null);
-}
-
-/**
- * Returns a random integer in the range [start,end]
- * @param {number} start
- * @param {number} end
- */
-export function randomInt(start, end) {
- return rando(start, end);
-}
-
-/**
- * Access an object in a very annoying way, used for obsfuscation.
- * @param {any} obj
- * @param {Array} keys
- */
-export function accessNestedPropertyReverse(obj, keys) {
- let result = obj;
- for (let i = keys.length - 1; i >= 0; --i) {
- result = result[keys[i]];
- }
- return result;
-}
-
-/**
- * Chooses a random entry of an array
- * @template T
- * @param {T[]} arr
- * @returns {T}
- */
-export function randomChoice(arr) {
- return arr[Math.floor(Math.random() * arr.length)];
-}
-
-/**
- * Deletes from an array by swapping with the last element
- * @param {Array} array
- * @param {number} index
- */
-export function fastArrayDelete(array, index) {
- if (index < 0 || index >= array.length) {
- throw new Error("Out of bounds");
- }
- // When the element is not the last element
- if (index !== array.length - 1) {
- // Get the last element, and swap it with the one we want to delete
- const last = array[array.length - 1];
- array[index] = last;
- }
-
- // Finally remove the last element
- array.length -= 1;
-}
-
-/**
- * Deletes from an array by swapping with the last element. Searches
- * for the value in the array first
- * @param {Array} array
- * @param {any} value
- */
-export function fastArrayDeleteValue(array, value) {
- if (array == null) {
- throw new Error("Tried to delete from non array!");
- }
- const index = array.indexOf(value);
- if (index < 0) {
- console.error("Value", value, "not contained in array:", array, "!");
- return value;
- }
- return fastArrayDelete(array, index);
-}
-
-/**
- * @see fastArrayDeleteValue
- * @param {Array} array
- * @param {any} value
- */
-export function fastArrayDeleteValueIfContained(array, value) {
- if (array == null) {
- throw new Error("Tried to delete from non array!");
- }
- const index = array.indexOf(value);
- if (index < 0) {
- return value;
- }
- return fastArrayDelete(array, index);
-}
-
-/**
- * Deletes from an array at the given index
- * @param {Array} array
- * @param {number} index
- */
-export function arrayDelete(array, index) {
- if (index < 0 || index >= array.length) {
- throw new Error("Out of bounds");
- }
- array.splice(index, 1);
-}
-
-/**
- * Deletes the given value from an array
- * @param {Array} array
- * @param {any} value
- */
-export function arrayDeleteValue(array, value) {
- if (array == null) {
- throw new Error("Tried to delete from non array!");
- }
- const index = array.indexOf(value);
- if (index < 0) {
- console.error("Value", value, "not contained in array:", array, "!");
- return value;
- }
- return arrayDelete(array, index);
-}
-
-/**
- * Compare two floats for epsilon equality
- * @param {number} a
- * @param {number} b
- * @returns {boolean}
- */
-export function epsilonCompare(a, b, epsilon = 1e-5) {
- return Math.abs(a - b) < epsilon;
-}
-
-/**
- * Interpolates two numbers
- * @param {number} a
- * @param {number} b
- * @param {number} x Mix factor, 0 means 100% a, 1 means 100%b, rest is interpolated
- */
-export function lerp(a, b, x) {
- return a * (1 - x) + b * x;
-}
-
-/**
- * Finds a value which is nice to display, e.g. 15669 -> 15000. Also handles fractional stuff
- * @param {number} num
- */
-export function findNiceValue(num) {
- if (num > 1e8) {
- return num;
- }
- if (num < 0.00001) {
- return 0;
- }
-
- let roundAmount = 1;
- if (num > 50000) {
- roundAmount = 10000;
- } else if (num > 20000) {
- roundAmount = 5000;
- } else if (num > 5000) {
- roundAmount = 1000;
- } else if (num > 2000) {
- roundAmount = 500;
- } else if (num > 1000) {
- roundAmount = 100;
- } else if (num > 100) {
- roundAmount = 20;
- } else if (num > 20) {
- roundAmount = 5;
- }
-
- const niceValue = Math.floor(num / roundAmount) * roundAmount;
- if (num >= 10) {
- return Math.round(niceValue);
- }
- if (num >= 1) {
- return Math.round(niceValue * 10) / 10;
- }
-
- return Math.round(niceValue * 100) / 100;
-}
-
-/**
- * Finds a nice integer value
- * @see findNiceValue
- * @param {number} num
- */
-export function findNiceIntegerValue(num) {
- return Math.ceil(findNiceValue(num));
-}
-
-/**
- * Formats a big number
- * @param {number} num
- * @param {string=} separator The decimal separator for numbers like 50.1 (separator='.')
- * @returns {string}
- */
-export function formatBigNumber(num, separator = T.global.decimalSeparator) {
- const sign = num < 0 ? "-" : "";
- num = Math.abs(num);
-
- if (num > 1e54) {
- return sign + T.global.infinite;
- }
-
- if (num < 10 && !Number.isInteger(num)) {
- return sign + num.toFixed(2);
- }
- if (num < 50 && !Number.isInteger(num)) {
- return sign + num.toFixed(1);
- }
- num = Math.floor(num);
-
- if (num < 1000) {
- return sign + "" + num;
- } else {
- let leadingDigits = num;
- let suffix = "";
- for (let suffixIndex = 0; suffixIndex < bigNumberSuffixTranslationKeys.length; ++suffixIndex) {
- leadingDigits = leadingDigits / 1000;
- suffix = T.global.suffix[bigNumberSuffixTranslationKeys[suffixIndex]];
- if (leadingDigits < 1000) {
- break;
- }
- }
- const leadingDigitsRounded = round1Digit(leadingDigits);
- const leadingDigitsNoTrailingDecimal = leadingDigitsRounded
- .toString()
- .replace(".0", "")
- .replace(".", separator);
- return sign + leadingDigitsNoTrailingDecimal + suffix;
- }
-}
-
-/**
- * Formats a big number, but does not add any suffix and instead uses its full representation
- * @param {number} num
- * @param {string=} divider The divider for numbers like 50,000 (divider=',')
- * @returns {string}
- */
-export function formatBigNumberFull(num, divider = T.global.thousandsDivider) {
- if (num < 1000) {
- return num + "";
- }
- if (num > 1e54) {
- return T.global.infinite;
- }
- let rest = num;
- let out = "";
- while (rest >= 1000) {
- out = (rest % 1000).toString().padStart(3, "0") + divider + out;
- rest = Math.floor(rest / 1000);
- }
- out = rest + divider + out;
-
- return out.substring(0, out.length - 1);
-}
-
-/**
- * Waits two frames so the ui is updated
- * @returns {Promise}
- */
-export function waitNextFrame() {
- return new Promise(function (resolve) {
- window.requestAnimationFrame(function () {
- window.requestAnimationFrame(function () {
- resolve();
- });
- });
- });
-}
-
-/**
- * Rounds 1 digit
- * @param {number} n
- * @returns {number}
- */
-export function round1Digit(n) {
- return Math.floor(n * 10.0) / 10.0;
-}
-
-/**
- * Rounds 2 digits
- * @param {number} n
- * @returns {number}
- */
-export function round2Digits(n) {
- return Math.floor(n * 100.0) / 100.0;
-}
-
-/**
- * Rounds 3 digits
- * @param {number} n
- * @returns {number}
- */
-export function round3Digits(n) {
- return Math.floor(n * 1000.0) / 1000.0;
-}
-
-/**
- * Rounds 4 digits
- * @param {number} n
- * @returns {number}
- */
-export function round4Digits(n) {
- return Math.floor(n * 10000.0) / 10000.0;
-}
-
-/**
- * Clamps a value between [min, max]
- * @param {number} v
- * @param {number=} minimum Default 0
- * @param {number=} maximum Default 1
- */
-export function clamp(v, minimum = 0, maximum = 1) {
- return Math.max(minimum, Math.min(maximum, v));
-}
-
-/**
- * Helper method to create a new div element
- * @param {string=} id
- * @param {Array=} classes
- * @param {string=} innerHTML
- */
-export function makeDivElement(id = null, classes = [], innerHTML = "") {
- const div = document.createElement("div");
- if (id) {
- div.id = id;
- }
- for (let i = 0; i < classes.length; ++i) {
- div.classList.add(classes[i]);
- }
- div.innerHTML = innerHTML;
- return div;
-}
-
-/**
- * Helper method to create a new div
- * @param {Element} parent
- * @param {string=} id
- * @param {Array=} classes
- * @param {string=} innerHTML
- */
-export function makeDiv(parent, id = null, classes = [], innerHTML = "") {
- const div = makeDivElement(id, classes, innerHTML);
- parent.appendChild(div);
- return div;
-}
-
-/**
- * Helper method to create a new button element
- * @param {Array=} classes
- * @param {string=} innerHTML
- */
-export function makeButtonElement(classes = [], innerHTML = "") {
- const element = document.createElement("button");
- for (let i = 0; i < classes.length; ++i) {
- element.classList.add(classes[i]);
- }
- element.classList.add("styledButton");
- element.innerHTML = innerHTML;
- return element;
-}
-
-/**
- * Helper method to create a new button
- * @param {Element} parent
- * @param {Array=} classes
- * @param {string=} innerHTML
- */
-export function makeButton(parent, classes = [], innerHTML = "") {
- const element = makeButtonElement(classes, innerHTML);
- parent.appendChild(element);
- return element;
-}
-
-/**
- * Removes all children of the given element
- * @param {Element} elem
- */
-export function removeAllChildren(elem) {
- if (elem) {
- var range = document.createRange();
- range.selectNodeContents(elem);
- range.deleteContents();
- }
-}
-
-/**
- * Returns if the game supports this browser
- */
-export function isSupportedBrowser() {
- // please note,
- // that IE11 now returns undefined again for window.chrome
- // and new Opera 30 outputs true for window.chrome
- // but needs to check if window.opr is not undefined
- // and new IE Edge outputs to true now for window.chrome
- // and if not iOS Chrome check
- // so use the below updated condition
-
- if (G_IS_STANDALONE) {
- return true;
- }
-
- // @ts-ignore
- var isChromium = window.chrome;
- var winNav = window.navigator;
- var vendorName = winNav.vendor;
- // @ts-ignore
- var isIEedge = winNav.userAgent.indexOf("Edge") > -1;
- var isIOSChrome = winNav.userAgent.match("CriOS");
-
- if (isIOSChrome) {
- // is Google Chrome on IOS
- return false;
- } else if (
- isChromium !== null &&
- typeof isChromium !== "undefined" &&
- vendorName === "Google Inc." &&
- isIEedge === false
- ) {
- // is Google Chrome
- return true;
- } else {
- // not Google Chrome
- return false;
- }
-}
-
-/**
- * Formats an amount of seconds into something like "5s ago"
- * @param {number} secs Seconds
- * @returns {string}
- */
-export function formatSecondsToTimeAgo(secs) {
- const seconds = Math.floor(secs);
- const minutes = Math.floor(seconds / 60);
- const hours = Math.floor(minutes / 60);
- const days = Math.floor(hours / 24);
-
- if (seconds < 60) {
- if (seconds === 1) {
- return T.global.time.oneSecondAgo;
- }
- return T.global.time.xSecondsAgo.replace("", "" + seconds);
- } else if (minutes < 60) {
- if (minutes === 1) {
- return T.global.time.oneMinuteAgo;
- }
- return T.global.time.xMinutesAgo.replace("", "" + minutes);
- } else if (hours < 24) {
- if (hours === 1) {
- return T.global.time.oneHourAgo;
- }
- return T.global.time.xHoursAgo.replace("", "" + hours);
- } else {
- if (days === 1) {
- return T.global.time.oneDayAgo;
- }
- return T.global.time.xDaysAgo.replace("", "" + days);
- }
-}
-
-/**
- * Formats seconds into a readable string like "5h 23m"
- * @param {number} secs Seconds
- * @returns {string}
- */
-export function formatSeconds(secs) {
- const trans = T.global.time;
- secs = Math.ceil(secs);
- if (secs < 60) {
- return trans.secondsShort.replace("", "" + secs);
- } else if (secs < 60 * 60) {
- const minutes = Math.floor(secs / 60);
- const seconds = secs % 60;
- return trans.minutesAndSecondsShort
- .replace("", "" + seconds)
- .replace("", "" + minutes);
- } else {
- const hours = Math.floor(secs / 3600);
- const minutes = Math.floor(secs / 60) % 60;
- return trans.hoursAndMinutesShort.replace("", "" + minutes).replace("", "" + hours);
- }
-}
-
-/**
- * Formats a number like 2.51 to "2.5"
- * @param {number} speed
- * @param {string=} separator The decimal separator for numbers like 50.1 (separator='.')
- */
-export function round1DigitLocalized(speed, separator = T.global.decimalSeparator) {
- return round1Digit(speed).toString().replace(".", separator);
-}
-
-/**
- * Formats a number like 2.51 to "2.51 items / s"
- * @param {number} speed
- * @param {boolean=} double
- * @param {string=} separator The decimal separator for numbers like 50.1 (separator='.')
- */
-export function formatItemsPerSecond(speed, double = false, separator = T.global.decimalSeparator) {
- return (
- (speed === 1.0
- ? T.ingame.buildingPlacement.infoTexts.oneItemPerSecond
- : T.ingame.buildingPlacement.infoTexts.itemsPerSecond.replace(
- "",
- round2Digits(speed).toString().replace(".", separator)
- )) + (double ? " " + T.ingame.buildingPlacement.infoTexts.itemsPerSecondDouble : "")
- );
-}
-
-/**
- * Rotates a flat 3x3 matrix clockwise
- * Entries:
- * 0 lo
- * 1 mo
- * 2 ro
- * 3 lm
- * 4 mm
- * 5 rm
- * 6 lu
- * 7 mu
- * 8 ru
- * @param {Array} flatMatrix
- */
-
-export function rotateFlatMatrix3x3(flatMatrix) {
- return [
- flatMatrix[6],
- flatMatrix[3],
- flatMatrix[0],
- flatMatrix[7],
- flatMatrix[4],
- flatMatrix[1],
- flatMatrix[8],
- flatMatrix[5],
- flatMatrix[2],
- ];
-}
-
-/**
- * Generates rotated variants of the matrix
- * @param {Array} originalMatrix
- * @returns {Object>}
- */
-export function generateMatrixRotations(originalMatrix) {
- const result = {
- 0: originalMatrix,
- };
-
- originalMatrix = rotateFlatMatrix3x3(originalMatrix);
- result[90] = originalMatrix;
-
- originalMatrix = rotateFlatMatrix3x3(originalMatrix);
- result[180] = originalMatrix;
-
- originalMatrix = rotateFlatMatrix3x3(originalMatrix);
- result[270] = originalMatrix;
-
- return result;
-}
-
-/**
- *
- * @typedef {{
- * top: any,
- * right: any,
- * bottom: any,
- * left: any
- * }} DirectionalObject
- */
-
-/**
- * Rotates a directional object
- * @param {DirectionalObject} obj
- * @returns {DirectionalObject}
- */
-export function rotateDirectionalObject(obj, rotation) {
- const queue = [obj.top, obj.right, obj.bottom, obj.left];
- while (rotation !== 0) {
- rotation -= 90;
- queue.push(queue.shift());
- }
-
- return {
- top: queue[0],
- right: queue[1],
- bottom: queue[2],
- left: queue[3],
- };
-}
-
-/**
- * Modulo which works for negative numbers
- * @param {number} n
- * @param {number} m
- */
-export function safeModulo(n, m) {
- return ((n % m) + m) % m;
-}
-
-/**
- * Returns a smooth pulse between 0 and 1
- * @param {number} time time in seconds
- * @returns {number}
- */
-export function smoothPulse(time) {
- return Math.sin(time * 4) * 0.5 + 0.5;
-}
-
-/**
- * Fills in a tag
- * @param {string} translation
- * @param {string} link
- */
-export function fillInLinkIntoTranslation(translation, link) {
- return translation
- .replace(" ", "")
- .replace("", " ");
-}
-
-/**
- * Generates a file download
- * @param {string} filename
- * @param {string} text
- */
-export function generateFileDownload(filename, text) {
- var element = document.createElement("a");
- element.setAttribute("href", "data:text/plain;charset=utf-8," + encodeURIComponent(text));
- element.setAttribute("download", filename);
-
- element.style.display = "none";
- document.body.appendChild(element);
-
- element.click();
- document.body.removeChild(element);
-}
-
-/**
- * Starts a file chooser
- * @param {string} acceptedType
- */
-export function startFileChoose(acceptedType = ".bin") {
- var input = document.createElement("input");
- input.type = "file";
- input.accept = acceptedType;
-
- return new Promise(resolve => {
- input.onchange = _ => resolve(input.files[0]);
- input.click();
- });
-}
-
-const MAX_ROMAN_NUMBER = 49;
-const romanLiteralsCache = ["0"];
-
-/**
- *
- * @param {number} number
- * @returns {string}
- */
-export function getRomanNumber(number) {
- if (G_WEGAME_VERSION) {
- return String(number);
- }
-
- number = Math.max(0, Math.round(number));
- if (romanLiteralsCache[number]) {
- return romanLiteralsCache[number];
- }
-
- if (number > MAX_ROMAN_NUMBER) {
- return String(number);
- }
-
- function formatDigit(digit, unit, quintuple, decuple) {
- switch (digit) {
- case 0:
- return "";
- case 1: // I
- return unit;
- case 2: // II
- return unit + unit;
- case 3: // III
- return unit + unit + unit;
- case 4: // IV
- return unit + quintuple;
- case 9: // IX
- return unit + decuple;
- default:
- // V, VI, VII, VIII
- return quintuple + formatDigit(digit - 5, unit, quintuple, decuple);
- }
- }
-
- let thousands = Math.floor(number / 1000);
- let thousandsPart = "";
- while (thousands > 0) {
- thousandsPart += "M";
- thousands -= 1;
- }
-
- const hundreds = Math.floor((number % 1000) / 100);
- const hundredsPart = formatDigit(hundreds, "C", "D", "M");
-
- const tens = Math.floor((number % 100) / 10);
- const tensPart = formatDigit(tens, "X", "L", "C");
-
- const units = number % 10;
- const unitsPart = formatDigit(units, "I", "V", "X");
-
- const formatted = thousandsPart + hundredsPart + tensPart + unitsPart;
-
- romanLiteralsCache[number] = formatted;
- return formatted;
-}
-
-/**
- * Returns the appropriate logo sprite path
- */
-export function getLogoSprite() {
- if (G_WEGAME_VERSION) {
- return "logo_wegame.png";
- }
-
- if (G_IS_STEAM_DEMO) {
- return "logo_demo.png";
- }
-
- if (G_CHINA_VERSION) {
- return "logo_cn.png";
- }
-
- if (G_IS_STANDALONE || WEB_STEAM_SSO_AUTHENTICATED) {
- return "logo.png";
- }
-
- if (G_IS_BROWSER) {
- return "logo_demo.png";
- }
-
- return "logo.png";
-}
-
-/**
- * Rejects a promise after X ms
- * @param {Promise} promise
- */
-export function timeoutPromise(promise, timeout = 30000) {
- return Promise.race([
- new Promise((resolve, reject) => {
- setTimeout(() => reject("timeout of " + timeout + " ms exceeded"), timeout);
- }),
- promise,
- ]);
-}
+import { T } from "../translations";
+
+const bigNumberSuffixTranslationKeys = ["thousands", "millions", "billions", "trillions"];
+
+/**
+ * Returns a platform name
+ * @returns {"standalone"}
+ */
+export function getPlatformName() {
+ return "standalone";
+}
+
+/**
+ * Makes a new 2D array with undefined contents
+ * @param {number} w
+ * @param {number} h
+ * @returns {Array>}
+ */
+export function make2DUndefinedArray(w, h) {
+ const result = new Array(w);
+ for (let x = 0; x < w; ++x) {
+ result[x] = new Array(h);
+ }
+ return result;
+}
+
+/**
+ * Creates a new map (an empty object without any props)
+ */
+export function newEmptyMap() {
+ return Object.create(null);
+}
+
+/**
+ * Returns a random integer in the range [start,end]
+ * @param {number} start
+ * @param {number} end
+ */
+export function randomInt(start, end) {
+ return Math.floor(Math.random() * (end - start + 1) + start);
+}
+
+/**
+ * Chooses a random entry of an array
+ * @template T
+ * @param {T[]} arr
+ * @returns {T}
+ */
+export function randomChoice(arr) {
+ return arr[Math.floor(Math.random() * arr.length)];
+}
+
+/**
+ * Deletes from an array by swapping with the last element
+ * @param {Array} array
+ * @param {number} index
+ */
+export function fastArrayDelete(array, index) {
+ if (index < 0 || index >= array.length) {
+ throw new Error("Out of bounds");
+ }
+ // When the element is not the last element
+ if (index !== array.length - 1) {
+ // Get the last element, and swap it with the one we want to delete
+ const last = array[array.length - 1];
+ array[index] = last;
+ }
+
+ // Finally remove the last element
+ array.length -= 1;
+}
+
+/**
+ * Deletes from an array by swapping with the last element. Searches
+ * for the value in the array first
+ * @param {Array} array
+ * @param {any} value
+ */
+export function fastArrayDeleteValue(array, value) {
+ if (array == null) {
+ throw new Error("Tried to delete from non array!");
+ }
+ const index = array.indexOf(value);
+ if (index < 0) {
+ console.error("Value", value, "not contained in array:", array, "!");
+ return value;
+ }
+ return fastArrayDelete(array, index);
+}
+
+/**
+ * @see fastArrayDeleteValue
+ * @param {Array} array
+ * @param {any} value
+ */
+export function fastArrayDeleteValueIfContained(array, value) {
+ if (array == null) {
+ throw new Error("Tried to delete from non array!");
+ }
+ const index = array.indexOf(value);
+ if (index < 0) {
+ return value;
+ }
+ return fastArrayDelete(array, index);
+}
+
+/**
+ * Deletes from an array at the given index
+ * @param {Array} array
+ * @param {number} index
+ */
+export function arrayDelete(array, index) {
+ if (index < 0 || index >= array.length) {
+ throw new Error("Out of bounds");
+ }
+ array.splice(index, 1);
+}
+
+/**
+ * Deletes the given value from an array
+ * @param {Array} array
+ * @param {any} value
+ */
+export function arrayDeleteValue(array, value) {
+ if (array == null) {
+ throw new Error("Tried to delete from non array!");
+ }
+ const index = array.indexOf(value);
+ if (index < 0) {
+ console.error("Value", value, "not contained in array:", array, "!");
+ return value;
+ }
+ return arrayDelete(array, index);
+}
+
+/**
+ * Compare two floats for epsilon equality
+ * @param {number} a
+ * @param {number} b
+ * @returns {boolean}
+ */
+export function epsilonCompare(a, b, epsilon = 1e-5) {
+ return Math.abs(a - b) < epsilon;
+}
+
+/**
+ * Interpolates two numbers
+ * @param {number} a
+ * @param {number} b
+ * @param {number} x Mix factor, 0 means 100% a, 1 means 100%b, rest is interpolated
+ */
+export function lerp(a, b, x) {
+ return a * (1 - x) + b * x;
+}
+
+/**
+ * Finds a value which is nice to display, e.g. 15669 -> 15000. Also handles fractional stuff
+ * @param {number} num
+ */
+export function findNiceValue(num) {
+ if (num > 1e8) {
+ return num;
+ }
+ if (num < 0.00001) {
+ return 0;
+ }
+
+ let roundAmount = 1;
+ if (num > 50000) {
+ roundAmount = 10000;
+ } else if (num > 20000) {
+ roundAmount = 5000;
+ } else if (num > 5000) {
+ roundAmount = 1000;
+ } else if (num > 2000) {
+ roundAmount = 500;
+ } else if (num > 1000) {
+ roundAmount = 100;
+ } else if (num > 100) {
+ roundAmount = 20;
+ } else if (num > 20) {
+ roundAmount = 5;
+ }
+
+ const niceValue = Math.floor(num / roundAmount) * roundAmount;
+ if (num >= 10) {
+ return Math.round(niceValue);
+ }
+ if (num >= 1) {
+ return Math.round(niceValue * 10) / 10;
+ }
+
+ return Math.round(niceValue * 100) / 100;
+}
+
+/**
+ * Finds a nice integer value
+ * @see findNiceValue
+ * @param {number} num
+ */
+export function findNiceIntegerValue(num) {
+ return Math.ceil(findNiceValue(num));
+}
+
+/**
+ * Formats a big number
+ * @param {number} num
+ * @param {string=} separator The decimal separator for numbers like 50.1 (separator='.')
+ * @returns {string}
+ */
+export function formatBigNumber(num, separator = T.global.decimalSeparator) {
+ const sign = num < 0 ? "-" : "";
+ num = Math.abs(num);
+
+ if (num > 1e54) {
+ return sign + T.global.infinite;
+ }
+
+ if (num < 10 && !Number.isInteger(num)) {
+ return sign + num.toFixed(2);
+ }
+ if (num < 50 && !Number.isInteger(num)) {
+ return sign + num.toFixed(1);
+ }
+ num = Math.floor(num);
+
+ if (num < 1000) {
+ return sign + "" + num;
+ } else {
+ let leadingDigits = num;
+ let suffix = "";
+ for (let suffixIndex = 0; suffixIndex < bigNumberSuffixTranslationKeys.length; ++suffixIndex) {
+ leadingDigits = leadingDigits / 1000;
+ suffix = T.global.suffix[bigNumberSuffixTranslationKeys[suffixIndex]];
+ if (leadingDigits < 1000) {
+ break;
+ }
+ }
+ const leadingDigitsRounded = round1Digit(leadingDigits);
+ const leadingDigitsNoTrailingDecimal = leadingDigitsRounded
+ .toString()
+ .replace(".0", "")
+ .replace(".", separator);
+ return sign + leadingDigitsNoTrailingDecimal + suffix;
+ }
+}
+
+/**
+ * Formats a big number, but does not add any suffix and instead uses its full representation
+ * @param {number} num
+ * @param {string=} divider The divider for numbers like 50,000 (divider=',')
+ * @returns {string}
+ */
+export function formatBigNumberFull(num, divider = T.global.thousandsDivider) {
+ if (num < 1000) {
+ return num + "";
+ }
+ if (num > 1e54) {
+ return T.global.infinite;
+ }
+ let rest = num;
+ let out = "";
+ while (rest >= 1000) {
+ out = (rest % 1000).toString().padStart(3, "0") + divider + out;
+ rest = Math.floor(rest / 1000);
+ }
+ out = rest + divider + out;
+
+ return out.substring(0, out.length - 1);
+}
+
+/**
+ * Waits two frames so the ui is updated
+ * @returns {Promise}
+ */
+export function waitNextFrame() {
+ return new Promise(function (resolve) {
+ window.requestAnimationFrame(function () {
+ window.requestAnimationFrame(function () {
+ resolve();
+ });
+ });
+ });
+}
+
+/**
+ * Rounds 1 digit
+ * @param {number} n
+ * @returns {number}
+ */
+export function round1Digit(n) {
+ return Math.floor(n * 10.0) / 10.0;
+}
+
+/**
+ * Rounds 2 digits
+ * @param {number} n
+ * @returns {number}
+ */
+export function round2Digits(n) {
+ return Math.floor(n * 100.0) / 100.0;
+}
+
+/**
+ * Rounds 3 digits
+ * @param {number} n
+ * @returns {number}
+ */
+export function round3Digits(n) {
+ return Math.floor(n * 1000.0) / 1000.0;
+}
+
+/**
+ * Rounds 4 digits
+ * @param {number} n
+ * @returns {number}
+ */
+export function round4Digits(n) {
+ return Math.floor(n * 10000.0) / 10000.0;
+}
+
+/**
+ * Clamps a value between [min, max]
+ * @param {number} v
+ * @param {number=} minimum Default 0
+ * @param {number=} maximum Default 1
+ */
+export function clamp(v, minimum = 0, maximum = 1) {
+ return Math.max(minimum, Math.min(maximum, v));
+}
+
+/**
+ * Helper method to create a new div element
+ * @param {string=} id
+ * @param {Array=} classes
+ * @param {string=} innerHTML
+ */
+export function makeDivElement(id = null, classes = [], innerHTML = "") {
+ const div = document.createElement("div");
+ if (id) {
+ div.id = id;
+ }
+ for (let i = 0; i < classes.length; ++i) {
+ div.classList.add(classes[i]);
+ }
+ div.innerHTML = innerHTML;
+ return div;
+}
+
+/**
+ * Helper method to create a new div
+ * @param {Element} parent
+ * @param {string=} id
+ * @param {Array=} classes
+ * @param {string=} innerHTML
+ */
+export function makeDiv(parent, id = null, classes = [], innerHTML = "") {
+ const div = makeDivElement(id, classes, innerHTML);
+ parent.appendChild(div);
+ return div;
+}
+
+/**
+ * Helper method to create a new button element
+ * @param {Array=} classes
+ * @param {string=} innerHTML
+ */
+export function makeButtonElement(classes = [], innerHTML = "") {
+ const element = document.createElement("button");
+ for (let i = 0; i < classes.length; ++i) {
+ element.classList.add(classes[i]);
+ }
+ element.classList.add("styledButton");
+ element.innerHTML = innerHTML;
+ return element;
+}
+
+/**
+ * Helper method to create a new button
+ * @param {Element} parent
+ * @param {Array=} classes
+ * @param {string=} innerHTML
+ */
+export function makeButton(parent, classes = [], innerHTML = "") {
+ const element = makeButtonElement(classes, innerHTML);
+ parent.appendChild(element);
+ return element;
+}
+
+/**
+ * Removes all children of the given element
+ * @param {Element} elem
+ */
+export function removeAllChildren(elem) {
+ if (elem) {
+ const range = document.createRange();
+ range.selectNodeContents(elem);
+ range.deleteContents();
+ }
+}
+
+/**
+ * Formats an amount of seconds into something like "5s ago"
+ * @param {number} secs Seconds
+ * @returns {string}
+ */
+export function formatSecondsToTimeAgo(secs) {
+ const seconds = Math.floor(secs);
+ const minutes = Math.floor(seconds / 60);
+ const hours = Math.floor(minutes / 60);
+ const days = Math.floor(hours / 24);
+
+ if (seconds < 60) {
+ if (seconds === 1) {
+ return T.global.time.oneSecondAgo;
+ }
+ return T.global.time.xSecondsAgo.replace("", "" + seconds);
+ } else if (minutes < 60) {
+ if (minutes === 1) {
+ return T.global.time.oneMinuteAgo;
+ }
+ return T.global.time.xMinutesAgo.replace("", "" + minutes);
+ } else if (hours < 24) {
+ if (hours === 1) {
+ return T.global.time.oneHourAgo;
+ }
+ return T.global.time.xHoursAgo.replace("", "" + hours);
+ } else {
+ if (days === 1) {
+ return T.global.time.oneDayAgo;
+ }
+ return T.global.time.xDaysAgo.replace("", "" + days);
+ }
+}
+
+/**
+ * Formats seconds into a readable string like "5h 23m"
+ * @param {number} secs Seconds
+ * @returns {string}
+ */
+export function formatSeconds(secs) {
+ const trans = T.global.time;
+ secs = Math.ceil(secs);
+ if (secs < 60) {
+ return trans.secondsShort.replace("", "" + secs);
+ } else if (secs < 60 * 60) {
+ const minutes = Math.floor(secs / 60);
+ const seconds = secs % 60;
+ return trans.minutesAndSecondsShort
+ .replace("", "" + seconds)
+ .replace("", "" + minutes);
+ } else {
+ const hours = Math.floor(secs / 3600);
+ const minutes = Math.floor(secs / 60) % 60;
+ return trans.hoursAndMinutesShort.replace("", "" + minutes).replace("", "" + hours);
+ }
+}
+
+/**
+ * Formats a number like 2.51 to "2.5"
+ * @param {number} speed
+ * @param {string=} separator The decimal separator for numbers like 50.1 (separator='.')
+ */
+export function round1DigitLocalized(speed, separator = T.global.decimalSeparator) {
+ return round1Digit(speed).toString().replace(".", separator);
+}
+
+/**
+ * Formats a number like 2.51 to "2.51 items / s"
+ * @param {number} speed
+ * @param {boolean=} double
+ * @param {string=} separator The decimal separator for numbers like 50.1 (separator='.')
+ */
+export function formatItemsPerSecond(speed, double = false, separator = T.global.decimalSeparator) {
+ return (
+ (speed === 1.0
+ ? T.ingame.buildingPlacement.infoTexts.oneItemPerSecond
+ : T.ingame.buildingPlacement.infoTexts.itemsPerSecond.replace(
+ "",
+ round2Digits(speed).toString().replace(".", separator)
+ )) + (double ? " " + T.ingame.buildingPlacement.infoTexts.itemsPerSecondDouble : "")
+ );
+}
+
+/**
+ * Rotates a flat 3x3 matrix clockwise
+ * Entries:
+ * 0 lo
+ * 1 mo
+ * 2 ro
+ * 3 lm
+ * 4 mm
+ * 5 rm
+ * 6 lu
+ * 7 mu
+ * 8 ru
+ * @param {Array} flatMatrix
+ */
+
+export function rotateFlatMatrix3x3(flatMatrix) {
+ return [
+ flatMatrix[6],
+ flatMatrix[3],
+ flatMatrix[0],
+ flatMatrix[7],
+ flatMatrix[4],
+ flatMatrix[1],
+ flatMatrix[8],
+ flatMatrix[5],
+ flatMatrix[2],
+ ];
+}
+
+/**
+ * Generates rotated variants of the matrix
+ * @param {Array} originalMatrix
+ * @returns {Object>}
+ */
+export function generateMatrixRotations(originalMatrix) {
+ const result = {
+ 0: originalMatrix,
+ };
+
+ originalMatrix = rotateFlatMatrix3x3(originalMatrix);
+ result[90] = originalMatrix;
+
+ originalMatrix = rotateFlatMatrix3x3(originalMatrix);
+ result[180] = originalMatrix;
+
+ originalMatrix = rotateFlatMatrix3x3(originalMatrix);
+ result[270] = originalMatrix;
+
+ return result;
+}
+
+/**
+ *
+ * @typedef {{
+ * top: any,
+ * right: any,
+ * bottom: any,
+ * left: any
+ * }} DirectionalObject
+ */
+
+/**
+ * Rotates a directional object
+ * @param {DirectionalObject} obj
+ * @returns {DirectionalObject}
+ */
+export function rotateDirectionalObject(obj, rotation) {
+ const queue = [obj.top, obj.right, obj.bottom, obj.left];
+ while (rotation !== 0) {
+ rotation -= 90;
+ queue.push(queue.shift());
+ }
+
+ return {
+ top: queue[0],
+ right: queue[1],
+ bottom: queue[2],
+ left: queue[3],
+ };
+}
+
+/**
+ * Modulo which works for negative numbers
+ * @param {number} n
+ * @param {number} m
+ */
+export function safeModulo(n, m) {
+ return ((n % m) + m) % m;
+}
+
+/**
+ * Returns a smooth pulse between 0 and 1
+ * @param {number} time time in seconds
+ * @returns {number}
+ */
+export function smoothPulse(time) {
+ return Math.sin(time * 4) * 0.5 + 0.5;
+}
+
+/**
+ * Fills in a tag
+ * @param {string} translation
+ * @param {string} link
+ */
+export function fillInLinkIntoTranslation(translation, link) {
+ return translation
+ .replace(" ", "")
+ .replace("", " ");
+}
+
+const MAX_ROMAN_NUMBER = 49;
+const romanLiteralsCache = ["0"];
+
+/**
+ *
+ * @param {number} number
+ * @returns {string}
+ */
+export function getRomanNumber(number) {
+ number = Math.max(0, Math.round(number));
+ if (romanLiteralsCache[number]) {
+ return romanLiteralsCache[number];
+ }
+
+ if (number > MAX_ROMAN_NUMBER) {
+ return String(number);
+ }
+
+ function formatDigit(digit, unit, quintuple, decuple) {
+ switch (digit) {
+ case 0:
+ return "";
+ case 1: // I
+ return unit;
+ case 2: // II
+ return unit + unit;
+ case 3: // III
+ return unit + unit + unit;
+ case 4: // IV
+ return unit + quintuple;
+ case 9: // IX
+ return unit + decuple;
+ default:
+ // V, VI, VII, VIII
+ return quintuple + formatDigit(digit - 5, unit, quintuple, decuple);
+ }
+ }
+
+ let thousands = Math.floor(number / 1000);
+ let thousandsPart = "";
+ while (thousands > 0) {
+ thousandsPart += "M";
+ thousands -= 1;
+ }
+
+ const hundreds = Math.floor((number % 1000) / 100);
+ const hundredsPart = formatDigit(hundreds, "C", "D", "M");
+
+ const tens = Math.floor((number % 100) / 10);
+ const tensPart = formatDigit(tens, "X", "L", "C");
+
+ const units = number % 10;
+ const unitsPart = formatDigit(units, "I", "V", "X");
+
+ const formatted = thousandsPart + hundredsPart + tensPart + unitsPart;
+
+ romanLiteralsCache[number] = formatted;
+ return formatted;
+}
+
+/**
+ * Rejects a promise after X ms
+ * @param {Promise} promise
+ */
+export function timeoutPromise(promise, timeout = 30000) {
+ return Promise.race([
+ new Promise((resolve, reject) => {
+ setTimeout(() => reject("timeout of " + timeout + " ms exceeded"), timeout);
+ }),
+ promise,
+ ]);
+}
diff --git a/src/js/core/vector.js b/src/js/core/vector.js
index 50fa9433..9525f5b3 100644
--- a/src/js/core/vector.js
+++ b/src/js/core/vector.js
@@ -489,7 +489,6 @@ export class Vector {
}
default: {
assertAlways(false, "Invalid fast inplace rotation: " + angle);
- return this;
}
}
// return new Vector(this.x * cos - this.y * sin, this.x * sin + this.y * cos);
@@ -519,7 +518,6 @@ export class Vector {
}
default: {
assertAlways(false, "Invalid fast inplace rotation: " + angle);
- return new Vector();
}
}
}
@@ -593,7 +591,6 @@ export class Vector {
}
default:
assertAlways(false, "Invalid angle: " + angle);
- return;
}
}
@@ -603,7 +600,7 @@ export class Vector {
* @returns {Boolean}
*/
equalsEpsilon(v, epsilon = 1e-5) {
- return Math.abs(this.x - v.x) < 1e-5 && Math.abs(this.y - v.y) < epsilon;
+ return Math.abs(this.x - v.x) < epsilon && Math.abs(this.y - v.y) < epsilon;
}
/**
diff --git a/src/js/game/achievement_proxy.js b/src/js/game/achievement_proxy.js
deleted file mode 100644
index 9077b283..00000000
--- a/src/js/game/achievement_proxy.js
+++ /dev/null
@@ -1,154 +0,0 @@
-/* typehints:start */
-import { Entity } from "./entity";
-import { GameRoot } from "./root";
-/* typehints:end */
-
-import { globalConfig } from "../core/config";
-import { createLogger } from "../core/logging";
-import { ACHIEVEMENTS } from "../platform/achievement_provider";
-import { getBuildingDataFromCode } from "./building_codes";
-
-const logger = createLogger("achievement_proxy");
-
-const ROTATER = "rotater";
-const DEFAULT = "default";
-
-export class AchievementProxy {
- /** @param {GameRoot} root */
- constructor(root) {
- this.root = root;
- this.provider = this.root.app.achievementProvider;
- this.disabled = true;
-
- if (G_IS_DEV && globalConfig.debug.testAchievements) {
- // still enable the proxy
- } else if (!this.provider.hasAchievements()) {
- return;
- }
-
- this.sliceTime = 0;
-
- this.root.signals.postLoadHook.add(this.onLoad, this);
- }
-
- onLoad() {
- if (!this.root.gameMode.hasAchievements()) {
- logger.log("Disabling achievements because game mode does not have achievements");
- this.disabled = true;
- return;
- }
-
- this.provider
- .onLoad(this.root)
- .then(() => {
- this.disabled = false;
- logger.log("Recieving achievement signals");
- this.initialize();
- })
- .catch(err => {
- this.disabled = true;
- logger.error("Ignoring achievement signals", err);
- });
- }
-
- initialize() {
- this.root.signals.achievementCheck.dispatch(ACHIEVEMENTS.darkMode, null);
-
- if (this.has(ACHIEVEMENTS.mam)) {
- this.root.signals.entityAdded.add(this.onMamFailure, this);
- this.root.signals.entityDestroyed.add(this.onMamFailure, this);
- this.root.signals.storyGoalCompleted.add(this.onStoryGoalCompleted, this);
- }
-
- if (this.has(ACHIEVEMENTS.noInverseRotater)) {
- this.root.signals.entityAdded.add(this.onEntityAdded, this);
- }
-
- this.startSlice();
- }
-
- startSlice() {
- this.sliceTime = this.root.time.now();
-
- this.root.signals.bulkAchievementCheck.dispatch(
- ACHIEVEMENTS.storeShape,
- this.sliceTime,
- ACHIEVEMENTS.throughputBp25,
- this.sliceTime,
- ACHIEVEMENTS.throughputBp50,
- this.sliceTime,
- ACHIEVEMENTS.throughputLogo25,
- this.sliceTime,
- ACHIEVEMENTS.throughputLogo50,
- this.sliceTime,
- ACHIEVEMENTS.throughputRocket10,
- this.sliceTime,
- ACHIEVEMENTS.throughputRocket20,
- this.sliceTime,
- ACHIEVEMENTS.play1h,
- this.sliceTime,
- ACHIEVEMENTS.play10h,
- this.sliceTime,
- ACHIEVEMENTS.play20h,
- this.sliceTime
- );
- }
-
- update() {
- if (this.disabled) {
- return;
- }
-
- if (this.root.time.now() - this.sliceTime > globalConfig.achievementSliceDuration) {
- this.startSlice();
- }
- }
-
- /**
- * @param {string} key
- * @returns {boolean}
- */
- has(key) {
- if (!this.provider.collection) {
- return false;
- }
- return this.provider.collection.map.has(key);
- }
-
- /** @param {Entity} entity */
- onEntityAdded(entity) {
- if (!entity.components.StaticMapEntity) {
- return;
- }
-
- const building = getBuildingDataFromCode(entity.components.StaticMapEntity.code);
-
- if (building.metaInstance.id !== ROTATER) {
- return;
- }
-
- if (building.variant === DEFAULT) {
- return;
- }
-
- this.root.savegame.currentData.stats.usedInverseRotater = true;
- this.root.signals.entityAdded.remove(this.onEntityAdded);
- }
-
- /** @param {number} level */
- onStoryGoalCompleted(level) {
- if (level > 26) {
- this.root.signals.entityAdded.add(this.onMamFailure, this);
- this.root.signals.entityDestroyed.add(this.onMamFailure, this);
- }
-
- this.root.signals.achievementCheck.dispatch(ACHIEVEMENTS.mam, null);
-
- // reset on every level
- this.root.savegame.currentData.stats.failedMam = false;
- }
-
- onMamFailure() {
- this.root.savegame.currentData.stats.failedMam = true;
- }
-}
diff --git a/src/js/game/automatic_save.js b/src/js/game/automatic_save.js
index 9d841966..eeccfe78 100644
--- a/src/js/game/automatic_save.js
+++ b/src/js/game/automatic_save.js
@@ -1,79 +1,79 @@
-import { globalConfig } from "../core/config";
-import { createLogger } from "../core/logging";
-import { GameRoot } from "./root";
-
-// How important it is that a savegame is created
-/**
- * @enum {number}
- */
-export const enumSavePriority = {
- regular: 2,
- asap: 100,
-};
-
-const logger = createLogger("autosave");
-
-export class AutomaticSave {
- constructor(root) {
- /** @type {GameRoot} */
- this.root = root;
-
- // Store the current maximum save importance
- this.saveImportance = enumSavePriority.regular;
-
- this.lastSaveAttempt = -1000;
- }
-
- setSaveImportance(importance) {
- this.saveImportance = Math.max(this.saveImportance, importance);
- }
-
- doSave() {
- if (G_IS_DEV && globalConfig.debug.disableSavegameWrite) {
- return;
- }
-
- this.root.gameState.doSave();
- this.saveImportance = enumSavePriority.regular;
- }
-
- update() {
- if (!this.root.gameInitialized) {
- // Bad idea
- return;
- }
-
- const saveInterval = this.root.app.settings.getAutosaveIntervalSeconds();
- if (!saveInterval) {
- // Disabled
- return;
- }
-
- // Check when the last save was, but make sure that if it fails, we don't spam
- const lastSaveTime = Math.max(this.lastSaveAttempt, this.root.savegame.getRealLastUpdate());
-
- const secondsSinceLastSave = (Date.now() - lastSaveTime) / 1000.0;
- let shouldSave = false;
-
- switch (this.saveImportance) {
- case enumSavePriority.asap:
- // High always should save
- shouldSave = true;
- break;
-
- case enumSavePriority.regular:
- // Could determine if there is a good / bad point here
- shouldSave = secondsSinceLastSave > saveInterval;
- break;
-
- default:
- assert(false, "Unknown save prio: " + this.saveImportance);
- break;
- }
- if (shouldSave) {
- logger.log("Saving automatically");
- this.lastSaveAttempt = Date.now();
- this.doSave();
- }
- }
-}
+import { globalConfig } from "../core/config";
+import { createLogger } from "../core/logging";
+import { GameRoot } from "./root";
+
+// How important it is that a savegame is created
+/**
+ * @enum {number}
+ */
+export const enumSavePriority = {
+ regular: 2,
+ asap: 100,
+};
+
+const logger = createLogger("autosave");
+
+export class AutomaticSave {
+ constructor(root) {
+ /** @type {GameRoot} */
+ this.root = root;
+
+ // Store the current maximum save importance
+ this.saveImportance = enumSavePriority.regular;
+
+ this.lastSaveAttempt = -1000;
+ }
+
+ setSaveImportance(importance) {
+ this.saveImportance = Math.max(this.saveImportance, importance);
+ }
+
+ doSave() {
+ if (G_IS_DEV && globalConfig.debug.disableSavegameWrite) {
+ return;
+ }
+
+ this.root.gameState.doSave();
+ this.saveImportance = enumSavePriority.regular;
+ }
+
+ update() {
+ if (!this.root.gameInitialized) {
+ // Bad idea
+ return;
+ }
+
+ const saveInterval = this.root.app.settings.getAutosaveIntervalSeconds();
+ if (!saveInterval) {
+ // Disabled
+ return;
+ }
+
+ // Check when the last save was, but make sure that if it fails, we don't spam
+ const lastSaveTime = Math.max(this.lastSaveAttempt, this.root.savegame.getRealLastUpdate());
+
+ const secondsSinceLastSave = (Date.now() - lastSaveTime) / 1000.0;
+ let shouldSave = false;
+
+ switch (this.saveImportance) {
+ case enumSavePriority.asap:
+ // High always should save
+ shouldSave = true;
+ break;
+
+ case enumSavePriority.regular:
+ // Could determine if there is a good / bad point here
+ shouldSave = secondsSinceLastSave > saveInterval;
+ break;
+
+ default:
+ assert(false, "Unknown save prio: " + this.saveImportance);
+ break;
+ }
+ if (shouldSave) {
+ logger.log("Saving automatically");
+ this.lastSaveAttempt = Date.now();
+ this.doSave();
+ }
+ }
+}
diff --git a/src/js/game/base_item.js b/src/js/game/base_item.js
index a6b38a08..d5861415 100644
--- a/src/js/game/base_item.js
+++ b/src/js/game/base_item.js
@@ -1,101 +1,101 @@
-import { globalConfig } from "../core/config";
-import { DrawParameters } from "../core/draw_parameters";
-import { BasicSerializableObject } from "../savegame/serialization";
-
-/**
- * Class for items on belts etc. Not an entity for performance reasons
- */
-export class BaseItem extends BasicSerializableObject {
- constructor() {
- super();
- this._type = this.getItemType();
- }
-
- static getId() {
- return "base_item";
- }
-
- /** @returns {import("../savegame/serialization").Schema} */
- static getSchema() {
- return {};
- }
-
- /** @returns {ItemType} **/
- getItemType() {
- abstract;
- return "shape";
- }
-
- /**
- * Returns a string id of the item
- * @returns {string}
- * @abstract
- */
- getAsCopyableKey() {
- abstract;
- return "";
- }
-
- /**
- * Returns if the item equals the other itme
- * @param {BaseItem} other
- * @returns {boolean}
- */
- equals(other) {
- if (this.getItemType() !== other.getItemType()) {
- return false;
- }
- return this.equalsImpl(other);
- }
-
- /**
- * Override for custom comparison
- * @param {BaseItem} other
- * @returns {boolean}
- * @abstract
- */
- equalsImpl(other) {
- abstract;
- return false;
- }
-
- /**
- * Draws the item to a canvas
- * @param {CanvasRenderingContext2D} context
- * @param {number} size
- * @abstract
- */
- drawFullSizeOnCanvas(context, size) {
- abstract;
- }
-
- /**
- * Draws the item at the given position
- * @param {number} x
- * @param {number} y
- * @param {DrawParameters} parameters
- * @param {number=} diameter
- */
- drawItemCenteredClipped(x, y, parameters, diameter = globalConfig.defaultItemDiameter) {
- if (parameters.visibleRect.containsCircle(x, y, diameter / 2)) {
- this.drawItemCenteredImpl(x, y, parameters, diameter);
- }
- }
-
- /**
- * INTERNAL
- * @param {number} x
- * @param {number} y
- * @param {DrawParameters} parameters
- * @param {number=} diameter
- * @abstract
- */
- drawItemCenteredImpl(x, y, parameters, diameter = globalConfig.defaultItemDiameter) {
- abstract;
- }
-
- getBackgroundColorAsResource() {
- abstract;
- return "";
- }
-}
+import { globalConfig } from "../core/config";
+import { DrawParameters } from "../core/draw_parameters";
+import { BasicSerializableObject } from "../savegame/serialization";
+
+/**
+ * Class for items on belts etc. Not an entity for performance reasons
+ */
+export class BaseItem extends BasicSerializableObject {
+ constructor() {
+ super();
+ this._type = this.getItemType();
+ }
+
+ static getId() {
+ return "base_item";
+ }
+
+ /** @returns {import("../savegame/serialization").Schema} */
+ static getSchema() {
+ return {};
+ }
+
+ /** @returns {ItemType} **/
+ getItemType() {
+ abstract;
+ return "shape";
+ }
+
+ /**
+ * Returns a string id of the item
+ * @returns {string}
+ * @abstract
+ */
+ getAsCopyableKey() {
+ abstract;
+ return "";
+ }
+
+ /**
+ * Returns if the item equals the other itme
+ * @param {BaseItem} other
+ * @returns {boolean}
+ */
+ equals(other) {
+ if (this.getItemType() !== other.getItemType()) {
+ return false;
+ }
+ return this.equalsImpl(other);
+ }
+
+ /**
+ * Override for custom comparison
+ * @param {BaseItem} other
+ * @returns {boolean}
+ * @abstract
+ */
+ equalsImpl(other) {
+ abstract;
+ return false;
+ }
+
+ /**
+ * Draws the item to a canvas
+ * @param {CanvasRenderingContext2D} context
+ * @param {number} size
+ * @abstract
+ */
+ drawFullSizeOnCanvas(context, size) {
+ abstract;
+ }
+
+ /**
+ * Draws the item at the given position
+ * @param {number} x
+ * @param {number} y
+ * @param {DrawParameters} parameters
+ * @param {number=} diameter
+ */
+ drawItemCenteredClipped(x, y, parameters, diameter = globalConfig.defaultItemDiameter) {
+ if (parameters.visibleRect.containsCircle(x, y, diameter / 2)) {
+ this.drawItemCenteredImpl(x, y, parameters, diameter);
+ }
+ }
+
+ /**
+ * INTERNAL
+ * @param {number} x
+ * @param {number} y
+ * @param {DrawParameters} parameters
+ * @param {number=} diameter
+ * @abstract
+ */
+ drawItemCenteredImpl(x, y, parameters, diameter = globalConfig.defaultItemDiameter) {
+ abstract;
+ }
+
+ getBackgroundColorAsResource() {
+ abstract;
+ return "";
+ }
+}
diff --git a/src/js/game/belt_path.js b/src/js/game/belt_path.js
index 9ef4a3f3..dbb298a1 100644
--- a/src/js/game/belt_path.js
+++ b/src/js/game/belt_path.js
@@ -1,1661 +1,1662 @@
-import { globalConfig } from "../core/config";
-import { smoothenDpi } from "../core/dpi_manager";
-import { DrawParameters } from "../core/draw_parameters";
-import { createLogger } from "../core/logging";
-import { Rectangle } from "../core/rectangle";
-import { ORIGINAL_SPRITE_SCALE } from "../core/sprites";
-import { clamp, epsilonCompare, round4Digits } from "../core/utils";
-import { enumDirection, enumDirectionToVector, enumInvertedDirections, Vector } from "../core/vector";
-import { BasicSerializableObject, types } from "../savegame/serialization";
-import { BaseItem } from "./base_item";
-import { Entity } from "./entity";
-import { typeItemSingleton } from "./item_resolver";
-import { GameRoot } from "./root";
-
-const logger = createLogger("belt_path");
-
-// Helpers for more semantic access into interleaved arrays
-
-const DEBUG = G_IS_DEV && false;
-
-/**
- * Stores a path of belts, used for optimizing performance
- */
-export class BeltPath extends BasicSerializableObject {
- static getId() {
- return "BeltPath";
- }
-
- static getSchema() {
- return {
- entityPath: types.array(types.entity),
- items: types.array(types.pair(types.ufloat, typeItemSingleton)),
- spacingToFirstItem: types.ufloat,
- };
- }
-
- /**
- * Creates a path from a serialized object
- * @param {GameRoot} root
- * @param {Object} data
- * @returns {BeltPath|string}
- */
- static fromSerialized(root, data) {
- // Create fake object which looks like a belt path but skips the constructor
- const fakeObject = /** @type {BeltPath} */ (Object.create(BeltPath.prototype));
- fakeObject.root = root;
-
- // Deserialize the data
- const errorCodeDeserialize = fakeObject.deserialize(data);
- if (errorCodeDeserialize) {
- return errorCodeDeserialize;
- }
-
- // Compute other properties
- fakeObject.init(false);
-
- return fakeObject;
- }
-
- /**
- * @param {GameRoot} root
- * @param {Array} entityPath
- */
- constructor(root, entityPath) {
- super();
- this.root = root;
-
- assert(entityPath.length > 0, "invalid entity path");
- this.entityPath = entityPath;
-
- /**
- * Stores the items sorted, and their distance to the previous item (or start)
- * Layout: [distanceToNext, item]
- * @type {Array<[number, BaseItem]>}
- */
- this.items = [];
-
- /**
- * Stores the spacing to the first item
- */
-
- this.init();
-
- if (G_IS_DEV && globalConfig.debug.checkBeltPaths) {
- this.debug_checkIntegrity("constructor");
- }
- }
- /**
- * Initializes the path by computing the properties which are not saved
- * @param {boolean} computeSpacing Whether to also compute the spacing
- */
- init(computeSpacing = true) {
- this.onPathChanged();
-
- this.totalLength = this.computeTotalLength();
-
- if (computeSpacing) {
- this.spacingToFirstItem = this.totalLength;
- }
-
- /**
- * Current bounds of this path
- * @type {Rectangle}
- */
- this.worldBounds = this.computeBounds();
-
- // Connect the belts
- for (let i = 0; i < this.entityPath.length; ++i) {
- this.entityPath[i].components.Belt.assignedPath = this;
- }
- }
-
- /**
- * Clears all items
- */
- clearAllItems() {
- this.items = [];
- this.spacingToFirstItem = this.totalLength;
- this.numCompressedItemsAfterFirstItem = 0;
- }
-
- /**
- * Returns whether this path can accept a new item
- * @returns {boolean}
- */
- canAcceptItem() {
- return this.spacingToFirstItem >= globalConfig.itemSpacingOnBelts;
- }
-
- /**
- * Tries to accept the item
- * @param {BaseItem} item
- */
- tryAcceptItem(item) {
- if (this.spacingToFirstItem >= globalConfig.itemSpacingOnBelts) {
- // So, since we already need one tick to accept this item we will add this directly.
- const beltProgressPerTick =
- this.root.hubGoals.getBeltBaseSpeed() *
- this.root.dynamicTickrate.deltaSeconds *
- globalConfig.itemSpacingOnBelts;
-
- // First, compute how much progress we can make *at max*
- const maxProgress = Math.max(0, this.spacingToFirstItem - globalConfig.itemSpacingOnBelts);
- const initialProgress = Math.min(maxProgress, beltProgressPerTick);
-
- this.items.unshift([this.spacingToFirstItem - initialProgress, item]);
- this.spacingToFirstItem = initialProgress;
-
- if (G_IS_DEV && globalConfig.debug.checkBeltPaths) {
- this.debug_checkIntegrity("accept-item");
- }
-
- return true;
- }
- return false;
- }
-
- /**
- * SLOW / Tries to find the item closest to the given tile
- * @param {Vector} tile
- * @returns {BaseItem|null}
- */
- findItemAtTile(tile) {
- // @TODO: This breaks color blind mode otherwise
- return null;
- }
-
- /**
- * Computes the tile bounds of the path
- * @returns {Rectangle}
- */
- computeBounds() {
- let bounds = this.entityPath[0].components.StaticMapEntity.getTileSpaceBounds();
- for (let i = 1; i < this.entityPath.length; ++i) {
- const staticComp = this.entityPath[i].components.StaticMapEntity;
- const otherBounds = staticComp.getTileSpaceBounds();
- bounds = bounds.getUnion(otherBounds);
- }
- return bounds.allScaled(globalConfig.tileSize);
- }
-
- /**
- * Recomputes cache variables once the path was changed
- */
- onPathChanged() {
- this.boundAcceptor = this.computeAcceptingEntityAndSlot().acceptor;
-
- /**
- * How many items past the first item are compressed
- */
- this.numCompressedItemsAfterFirstItem = 0;
- }
-
- /**
- * Called by the belt system when the surroundings changed
- */
- onSurroundingsChanged() {
- this.onPathChanged();
- }
-
- /**
- * Finds the entity which accepts our items
- * @param {boolean=} debug_Silent Whether debug output should be silent
- * @return { { acceptor?: (BaseItem, number?) => boolean, entity?: Entity } }
- */
- computeAcceptingEntityAndSlot(debug_Silent = false) {
- DEBUG && !debug_Silent && logger.log("Recomputing acceptor target");
-
- const lastEntity = this.entityPath[this.entityPath.length - 1];
- const lastStatic = lastEntity.components.StaticMapEntity;
- const lastBeltComp = lastEntity.components.Belt;
-
- // Figure out where and into which direction we eject items
- const ejectSlotWsTile = lastStatic.localTileToWorld(new Vector(0, 0));
- const ejectSlotWsDirection = lastStatic.localDirectionToWorld(lastBeltComp.direction);
- const ejectSlotWsDirectionVector = enumDirectionToVector[ejectSlotWsDirection];
- const ejectSlotTargetWsTile = ejectSlotWsTile.add(ejectSlotWsDirectionVector);
-
- // Try to find the given acceptor component to take the item
- const targetEntity = this.root.map.getLayerContentXY(
- ejectSlotTargetWsTile.x,
- ejectSlotTargetWsTile.y,
- "regular"
- );
-
- if (!targetEntity) {
- return {};
- }
-
- const noSimplifiedBelts = !this.root.app.settings.getAllSettings().simplifiedBelts;
-
- DEBUG && !debug_Silent && logger.log(" Found target entity", targetEntity.uid);
- const targetStaticComp = targetEntity.components.StaticMapEntity;
- const targetBeltComp = targetEntity.components.Belt;
-
- // Check for belts (special case)
- if (targetBeltComp) {
- const beltAcceptingDirection = targetStaticComp.localDirectionToWorld(enumDirection.top);
- DEBUG &&
- !debug_Silent &&
- logger.log(
- " Entity is accepting items from",
- ejectSlotWsDirection,
- "vs",
- beltAcceptingDirection,
- "Rotation:",
- targetStaticComp.rotation
- );
- if (ejectSlotWsDirection === beltAcceptingDirection) {
- return {
- entity: targetEntity,
- acceptor: item => {
- const path = targetBeltComp.assignedPath;
- assert(path, "belt has no path");
- return path.tryAcceptItem(item);
- },
- };
- }
- }
-
- // Check for item acceptors
- const targetAcceptorComp = targetEntity.components.ItemAcceptor;
- if (!targetAcceptorComp) {
- // Entity doesn't accept items
- return {};
- }
-
- const ejectingDirection = targetStaticComp.worldDirectionToLocal(ejectSlotWsDirection);
- const matchingSlot = targetAcceptorComp.findMatchingSlot(
- targetStaticComp.worldToLocalTile(ejectSlotTargetWsTile),
- ejectingDirection
- );
-
- if (!matchingSlot) {
- // No matching slot found
- return {};
- }
-
- const matchingSlotIndex = matchingSlot.index;
- const passOver = this.computePassOverFunctionWithoutBelts(targetEntity, matchingSlotIndex);
- if (!passOver) {
- return {};
- }
-
- const matchingDirection = enumInvertedDirections[ejectingDirection];
- const filter = matchingSlot.slot.filter;
-
- return {
- entity: targetEntity,
- acceptor: function (item, remainingProgress = 0.0) {
- // Check if the acceptor has a filter
- if (filter && item._type !== filter) {
- return false;
- }
-
- // Try to pass over
- if (passOver(item, matchingSlotIndex)) {
- // Trigger animation on the acceptor comp
- if (noSimplifiedBelts) {
- targetAcceptorComp.onItemAccepted(
- matchingSlotIndex,
- matchingDirection,
- item,
- remainingProgress
- );
- }
- return true;
- }
- return false;
- },
- };
- }
-
- /**
- * Computes a method to pass over the item to the entity
- * @param {Entity} entity
- * @param {number} matchingSlotIndex
- * @returns {(item: BaseItem, slotIndex: number) => boolean | void}
- */
- computePassOverFunctionWithoutBelts(entity, matchingSlotIndex) {
- const systems = this.root.systemMgr.systems;
- const hubGoals = this.root.hubGoals;
-
- // NOTICE: THIS IS COPIED FROM THE ITEM EJECTOR SYSTEM FOR PEROFMANCE REASONS
-
- const itemProcessorComp = entity.components.ItemProcessor;
- if (itemProcessorComp) {
- // Its an item processor ..
- return function (item) {
- // Check for potential filters
- if (!systems.itemProcessor.checkRequirements(entity, item, matchingSlotIndex)) {
- return;
- }
- return itemProcessorComp.tryTakeItem(item, matchingSlotIndex);
- };
- }
-
- const undergroundBeltComp = entity.components.UndergroundBelt;
- if (undergroundBeltComp) {
- // Its an underground belt. yay.
- return function (item) {
- return undergroundBeltComp.tryAcceptExternalItem(
- item,
- hubGoals.getUndergroundBeltBaseSpeed()
- );
- };
- }
-
- const storageComp = entity.components.Storage;
- if (storageComp) {
- // It's a storage
- return function (item) {
- if (storageComp.canAcceptItem(item)) {
- storageComp.takeItem(item);
- return true;
- }
- };
- }
-
- const filterComp = entity.components.Filter;
- if (filterComp) {
- // It's a filter! Unfortunately the filter has to know a lot about it's
- // surrounding state and components, so it can't be within the component itself.
- return function (item) {
- if (systems.filter.tryAcceptItem(entity, matchingSlotIndex, item)) {
- return true;
- }
- };
- }
- }
-
- // Following code will be compiled out outside of dev versions
- /* dev:start */
-
- /**
- * Helper to throw an error on mismatch
- * @param {string} change
- * @param {Array} reason
- */
- debug_failIntegrity(change, ...reason) {
- throw new Error("belt path invalid (" + change + "): " + reason.map(i => "" + i).join(" "));
- }
-
- /**
- * Checks if this path is valid
- */
- debug_checkIntegrity(currentChange = "change") {
- const fail = (...args) => this.debug_failIntegrity(currentChange, ...args);
-
- // Check for empty path
- if (this.entityPath.length === 0) {
- return fail("Belt path is empty");
- }
-
- // Check for mismatching length
- const totalLength = this.computeTotalLength();
- if (!epsilonCompare(this.totalLength, totalLength, 0.01)) {
- return this.debug_failIntegrity(
- currentChange,
- "Total length mismatch, stored =",
- this.totalLength,
- "but correct is",
- totalLength
- );
- }
-
- // Check for misconnected entities
- for (let i = 0; i < this.entityPath.length - 1; ++i) {
- const entity = this.entityPath[i];
- if (entity.destroyed) {
- return fail("Reference to destroyed entity " + entity.uid);
- }
-
- const followUp = this.root.systemMgr.systems.belt.findFollowUpEntity(entity);
- if (!followUp) {
- return fail(
- "Follow up entity for the",
- i,
- "-th entity (total length",
- this.entityPath.length,
- ") was null!"
- );
- }
- if (followUp !== this.entityPath[i + 1]) {
- return fail(
- "Follow up entity mismatch, stored is",
- this.entityPath[i + 1].uid,
- "but real one is",
- followUp.uid
- );
- }
- if (entity.components.Belt.assignedPath !== this) {
- return fail(
- "Entity with uid",
- entity.uid,
- "doesn't have this path assigned, but this path contains the entity."
- );
- }
- }
-
- // Check spacing
- if (this.spacingToFirstItem > this.totalLength + 0.005) {
- return fail(
- currentChange,
- "spacing to first item (",
- this.spacingToFirstItem,
- ") is greater than total length (",
- this.totalLength,
- ")"
- );
- }
-
- // Check distance if empty
- if (this.items.length === 0 && !epsilonCompare(this.spacingToFirstItem, this.totalLength, 0.01)) {
- return fail(
- currentChange,
- "Path is empty but spacing to first item (",
- this.spacingToFirstItem,
- ") does not equal total length (",
- this.totalLength,
- ")"
- );
- }
-
- // Check items etc
- let currentPos = this.spacingToFirstItem;
- for (let i = 0; i < this.items.length; ++i) {
- const item = this.items[i];
-
- if (item[0 /* nextDistance */] < 0 || item[0 /* nextDistance */] > this.totalLength + 0.02) {
- return fail(
- "Item has invalid offset to next item: ",
- item[0 /* nextDistance */],
- "(total length:",
- this.totalLength,
- ")"
- );
- }
-
- currentPos += item[0 /* nextDistance */];
- }
-
- // Check the total sum matches
- if (!epsilonCompare(currentPos, this.totalLength, 0.01)) {
- return fail(
- "total sum (",
- currentPos,
- ") of first item spacing (",
- this.spacingToFirstItem,
- ") and items does not match total length (",
- this.totalLength,
- ") -> items: " + this.items.map(i => i[0 /* nextDistance */]).join("|")
- );
- }
-
- // Check bounds
- const actualBounds = this.computeBounds();
- if (!actualBounds.equalsEpsilon(this.worldBounds, 0.01)) {
- return fail("Bounds are stale");
- }
-
- // Check acceptor
- const acceptor = this.computeAcceptingEntityAndSlot(true).acceptor;
- if (!!acceptor !== !!this.boundAcceptor) {
- return fail("Acceptor target mismatch, acceptor", !!acceptor, "vs stored", !!this.boundAcceptor);
- }
-
- // Check first nonzero offset
- let firstNonzero = 0;
- for (let i = this.items.length - 2; i >= 0; --i) {
- if (this.items[i][0 /* nextDistance */] < globalConfig.itemSpacingOnBelts + 1e-5) {
- ++firstNonzero;
- } else {
- break;
- }
- }
-
- // Should warn, but this check isn't actually accurate
- // if (firstNonzero !== this.numCompressedItemsAfterFirstItem) {
- // console.warn(
- // "First nonzero index is " +
- // firstNonzero +
- // " but stored is " +
- // this.numCompressedItemsAfterFirstItem
- // );
- // }
- }
-
- /* dev:end */
-
- /**
- * Extends the belt path by the given belt
- * @param {Entity} entity
- */
- extendOnEnd(entity) {
- DEBUG && logger.log("Extending belt path by entity at", entity.components.StaticMapEntity.origin);
-
- const beltComp = entity.components.Belt;
-
- // Append the entity
- this.entityPath.push(entity);
- this.onPathChanged();
-
- // Extend the path length
- const additionalLength = beltComp.getEffectiveLengthTiles();
- this.totalLength += additionalLength;
- DEBUG && logger.log(" Extended total length by", additionalLength, "to", this.totalLength);
-
- // If we have no item, just update the distance to the first item
- if (this.items.length === 0) {
- this.spacingToFirstItem = this.totalLength;
- DEBUG && logger.log(" Extended spacing to first to", this.totalLength, "(= total length)");
- } else {
- // Otherwise, update the next-distance of the last item
- const lastItem = this.items[this.items.length - 1];
- DEBUG &&
- logger.log(
- " Extended spacing of last item from",
- lastItem[0 /* nextDistance */],
- "to",
- lastItem[0 /* nextDistance */] + additionalLength
- );
- lastItem[0 /* nextDistance */] += additionalLength;
- }
-
- // Assign reference
- beltComp.assignedPath = this;
-
- // Update bounds
- this.worldBounds = this.computeBounds();
-
- if (G_IS_DEV && globalConfig.debug.checkBeltPaths) {
- this.debug_checkIntegrity("extend-on-end");
- }
- }
-
- /**
- * Extends the path with the given entity on the beginning
- * @param {Entity} entity
- */
- extendOnBeginning(entity) {
- const beltComp = entity.components.Belt;
-
- DEBUG && logger.log("Extending the path on the beginning");
-
- // All items on that belt are simply lost (for now)
-
- const length = beltComp.getEffectiveLengthTiles();
-
- // Extend the length of this path
- this.totalLength += length;
-
- // Simply adjust the first item spacing cuz we have no items contained
- this.spacingToFirstItem += length;
-
- // Set handles and append entity
- beltComp.assignedPath = this;
- this.entityPath.unshift(entity);
- this.onPathChanged();
-
- // Update bounds
- this.worldBounds = this.computeBounds();
-
- if (G_IS_DEV && globalConfig.debug.checkBeltPaths) {
- this.debug_checkIntegrity("extend-on-begin");
- }
- }
-
- /**
- * Returns if the given entity is the end entity of the path
- * @param {Entity} entity
- * @returns {boolean}
- */
- isEndEntity(entity) {
- return this.entityPath[this.entityPath.length - 1] === entity;
- }
-
- /**
- * Returns if the given entity is the start entity of the path
- * @param {Entity} entity
- * @returns {boolean}
- */
- isStartEntity(entity) {
- return this.entityPath[0] === entity;
- }
-
- /**
- * Splits this path at the given entity by removing it, and
- * returning the new secondary paht
- * @param {Entity} entity
- * @returns {BeltPath}
- */
- deleteEntityOnPathSplitIntoTwo(entity) {
- DEBUG && logger.log("Splitting path at entity", entity.components.StaticMapEntity.origin);
-
- // First, find where the current path ends
- const beltComp = entity.components.Belt;
- beltComp.assignedPath = null;
-
- const entityLength = beltComp.getEffectiveLengthTiles();
- assert(this.entityPath.indexOf(entity) >= 0, "Entity not contained for split");
- assert(this.entityPath.indexOf(entity) !== 0, "Entity is first");
- assert(this.entityPath.indexOf(entity) !== this.entityPath.length - 1, "Entity is last");
-
- let firstPathEntityCount = 0;
- let firstPathLength = 0;
- let firstPathEndEntity = null;
-
- for (let i = 0; i < this.entityPath.length; ++i) {
- const otherEntity = this.entityPath[i];
- if (otherEntity === entity) {
- DEBUG && logger.log("Found entity at", i, "of length", firstPathLength);
- break;
- }
-
- ++firstPathEntityCount;
- firstPathEndEntity = otherEntity;
- firstPathLength += otherEntity.components.Belt.getEffectiveLengthTiles();
- }
-
- DEBUG &&
- logger.log(
- "First path ends at",
- firstPathLength,
- "and entity",
- firstPathEndEntity.components.StaticMapEntity.origin,
- "and has",
- firstPathEntityCount,
- "entities"
- );
-
- // Compute length of second path
- const secondPathLength = this.totalLength - firstPathLength - entityLength;
- const secondPathStart = firstPathLength + entityLength;
- const secondEntities = this.entityPath.splice(firstPathEntityCount + 1);
- DEBUG &&
- logger.log(
- "Second path starts at",
- secondPathStart,
- "and has a length of ",
- secondPathLength,
- "with",
- secondEntities.length,
- "entities"
- );
-
- // Remove the last item
- this.entityPath.pop();
-
- DEBUG && logger.log("Splitting", this.items.length, "items");
- DEBUG &&
- logger.log(
- "Old items are",
- this.items.map(i => i[0 /* nextDistance */])
- );
-
- // Create second path
- const secondPath = new BeltPath(this.root, secondEntities);
-
- // Remove all items which are no longer relevant and transfer them to the second path
- let itemPos = this.spacingToFirstItem;
- for (let i = 0; i < this.items.length; ++i) {
- const item = this.items[i];
- const distanceToNext = item[0 /* nextDistance */];
-
- DEBUG && logger.log(" Checking item at", itemPos, "with distance of", distanceToNext, "to next");
-
- // Check if this item is past the first path
- if (itemPos >= firstPathLength) {
- // Remove it from the first path
- this.items.splice(i, 1);
- i -= 1;
- DEBUG &&
- logger.log(" Removed item from first path since its no longer contained @", itemPos);
-
- // Check if its on the second path (otherwise its on the removed belt and simply lost)
- if (itemPos >= secondPathStart) {
- // Put item on second path
- secondPath.items.push([distanceToNext, item[1 /* item */]]);
- DEBUG &&
- logger.log(
- " Put item to second path @",
- itemPos,
- "with distance to next =",
- distanceToNext
- );
-
- // If it was the first item, adjust the distance to the first item
- if (secondPath.items.length === 1) {
- DEBUG && logger.log(" Sinc it was the first, set sapcing of first to", itemPos);
- secondPath.spacingToFirstItem = itemPos - secondPathStart;
- }
- } else {
- DEBUG && logger.log(" Item was on the removed belt, so its gone - forever!");
- }
- } else {
- // Seems this item is on the first path (so all good), so just make sure it doesn't
- // have a nextDistance which is bigger than the total path length
- const clampedDistanceToNext = Math.min(itemPos + distanceToNext, firstPathLength) - itemPos;
- if (clampedDistanceToNext < distanceToNext) {
- DEBUG &&
- logger.log(
- "Correcting next distance (first path) from",
- distanceToNext,
- "to",
- clampedDistanceToNext
- );
- item[0 /* nextDistance */] = clampedDistanceToNext;
- }
- }
-
- // Advance items
- itemPos += distanceToNext;
- }
-
- DEBUG &&
- logger.log(
- "New items are",
- this.items.map(i => i[0 /* nextDistance */])
- );
-
- DEBUG &&
- logger.log(
- "And second path items are",
- secondPath.items.map(i => i[0 /* nextDistance */])
- );
-
- // Adjust our total length
- this.totalLength = firstPathLength;
-
- // Make sure that if we are empty, we set our first distance properly
- if (this.items.length === 0) {
- this.spacingToFirstItem = this.totalLength;
- }
-
- this.onPathChanged();
- secondPath.onPathChanged();
-
- // Update bounds
- this.worldBounds = this.computeBounds();
-
- if (G_IS_DEV && globalConfig.debug.checkBeltPaths) {
- this.debug_checkIntegrity("split-two-first");
- secondPath.debug_checkIntegrity("split-two-second");
- }
-
- return secondPath;
- }
-
- /**
- * Deletes the last entity
- * @param {Entity} entity
- */
- deleteEntityOnEnd(entity) {
- assert(
- this.entityPath[this.entityPath.length - 1] === entity,
- "Not actually the last entity (instead " + this.entityPath.indexOf(entity) + ")"
- );
-
- // Ok, first remove the entity
- const beltComp = entity.components.Belt;
- const beltLength = beltComp.getEffectiveLengthTiles();
-
- DEBUG &&
- logger.log(
- "Deleting last entity on path with length",
- this.entityPath.length,
- "(reducing",
- this.totalLength,
- " by",
- beltLength,
- ")"
- );
- this.totalLength -= beltLength;
- this.entityPath.pop();
- this.onPathChanged();
-
- DEBUG &&
- logger.log(
- " New path has length of",
- this.totalLength,
- "with",
- this.entityPath.length,
- "entities"
- );
-
- // This is just for sanity
- beltComp.assignedPath = null;
-
- // Clean up items
- if (this.items.length === 0) {
- // Simple case with no items, just update the first item spacing
- this.spacingToFirstItem = this.totalLength;
- } else {
- // Ok, make sure we simply drop all items which are no longer contained
- let itemOffset = this.spacingToFirstItem;
- let lastItemOffset = itemOffset;
-
- DEBUG && logger.log(" Adjusting", this.items.length, "items");
-
- for (let i = 0; i < this.items.length; ++i) {
- const item = this.items[i];
-
- // Get rid of items past this path
- if (itemOffset >= this.totalLength) {
- DEBUG && logger.log("Dropping item (current index=", i, ")");
- this.items.splice(i, 1);
- i -= 1;
- continue;
- }
-
- DEBUG &&
- logger.log(
- "Item",
- i,
- "is at",
- itemOffset,
- "with next offset",
- item[0 /* nextDistance */]
- );
- lastItemOffset = itemOffset;
- itemOffset += item[0 /* nextDistance */];
- }
-
- // If we still have an item, make sure the last item matches
- if (this.items.length > 0) {
- // We can easily compute the next distance since we know where the last item is now
- const lastDistance = this.totalLength - lastItemOffset;
- assert(
- lastDistance >= 0.0,
- "Last item distance mismatch: " +
- lastDistance +
- " -> Total length was " +
- this.totalLength +
- " and lastItemOffset was " +
- lastItemOffset
- );
-
- DEBUG &&
- logger.log(
- "Adjusted distance of last item: it is at",
- lastItemOffset,
- "so it has a distance of",
- lastDistance,
- "to the end (",
- this.totalLength,
- ")"
- );
- this.items[this.items.length - 1][0 /* nextDistance */] = lastDistance;
- } else {
- DEBUG && logger.log(" Removed all items so we'll update spacing to total length");
-
- // We removed all items so update our spacing
- this.spacingToFirstItem = this.totalLength;
- }
- }
-
- // Update bounds
- this.worldBounds = this.computeBounds();
-
- if (G_IS_DEV && globalConfig.debug.checkBeltPaths) {
- this.debug_checkIntegrity("delete-on-end");
- }
- }
-
- /**
- * Deletes the entity of the start of the path
- * @see deleteEntityOnEnd
- * @param {Entity} entity
- */
- deleteEntityOnStart(entity) {
- assert(
- entity === this.entityPath[0],
- "Not actually the start entity (instead " + this.entityPath.indexOf(entity) + ")"
- );
-
- // Ok, first remove the entity
- const beltComp = entity.components.Belt;
- const beltLength = beltComp.getEffectiveLengthTiles();
-
- DEBUG &&
- logger.log(
- "Deleting first entity on path with length",
- this.entityPath.length,
- "(reducing",
- this.totalLength,
- " by",
- beltLength,
- ")"
- );
- this.totalLength -= beltLength;
- this.entityPath.shift();
- this.onPathChanged();
-
- DEBUG &&
- logger.log(
- " New path has length of",
- this.totalLength,
- "with",
- this.entityPath.length,
- "entities"
- );
-
- // This is just for sanity
- beltComp.assignedPath = null;
-
- // Clean up items
- if (this.items.length === 0) {
- // Simple case with no items, just update the first item spacing
- this.spacingToFirstItem = this.totalLength;
- } else {
- // Simple case, we had no item on the beginning -> all good
- if (this.spacingToFirstItem >= beltLength) {
- DEBUG &&
- logger.log(
- " No item on the first place, so we can just adjust the spacing (spacing=",
- this.spacingToFirstItem,
- ") removed =",
- beltLength
- );
- this.spacingToFirstItem -= beltLength;
- } else {
- // Welp, okay we need to drop all items which are < beltLength and adjust
- // the other item offsets as well
-
- DEBUG &&
- logger.log(
- " We have at least one item in the beginning, drop those and adjust spacing (first item @",
- this.spacingToFirstItem,
- ") since we removed",
- beltLength,
- "length from path"
- );
- DEBUG &&
- logger.log(
- " Items:",
- this.items.map(i => i[0 /* nextDistance */])
- );
-
- // Find offset to first item
- let itemOffset = this.spacingToFirstItem;
- for (let i = 0; i < this.items.length; ++i) {
- const item = this.items[i];
- if (itemOffset <= beltLength) {
- DEBUG &&
- logger.log(
- " -> Dropping item with index",
- i,
- "at",
- itemOffset,
- "since it was on the removed belt"
- );
- // This item must be dropped
- this.items.splice(i, 1);
- i -= 1;
- itemOffset += item[0 /* nextDistance */];
- continue;
- } else {
- // This item can be kept, thus its the first we know
- break;
- }
- }
-
- if (this.items.length > 0) {
- DEBUG &&
- logger.log(
- " Offset of first non-dropped item was at:",
- itemOffset,
- "-> setting spacing to it (total length=",
- this.totalLength,
- ")"
- );
-
- this.spacingToFirstItem = itemOffset - beltLength;
- assert(
- this.spacingToFirstItem >= 0.0,
- "Invalid spacing after delete on start: " + this.spacingToFirstItem
- );
- } else {
- DEBUG && logger.log(" We dropped all items, simply set spacing to total length");
- // We dropped all items, simple one
- this.spacingToFirstItem = this.totalLength;
- }
- }
- }
-
- // Update bounds
- this.worldBounds = this.computeBounds();
-
- if (G_IS_DEV && globalConfig.debug.checkBeltPaths) {
- this.debug_checkIntegrity("delete-on-start");
- }
- }
-
- /**
- * Extends the path by the given other path
- * @param {BeltPath} otherPath
- */
- extendByPath(otherPath) {
- assert(otherPath !== this, "Circular path dependency");
-
- const entities = otherPath.entityPath;
- DEBUG && logger.log("Extending path by other path, starting to add entities");
-
- const oldLength = this.totalLength;
-
- DEBUG && logger.log(" Adding", entities.length, "new entities, current length =", this.totalLength);
-
- // First, append entities
- for (let i = 0; i < entities.length; ++i) {
- const entity = entities[i];
- const beltComp = entity.components.Belt;
-
- // Add to path and update references
- this.entityPath.push(entity);
- beltComp.assignedPath = this;
-
- // Update our length
- const additionalLength = beltComp.getEffectiveLengthTiles();
- this.totalLength += additionalLength;
- }
-
- DEBUG &&
- logger.log(
- " Path is now",
- this.entityPath.length,
- "entities and has a length of",
- this.totalLength
- );
-
- // Now, update the distance of our last item
- if (this.items.length !== 0) {
- const lastItem = this.items[this.items.length - 1];
- lastItem[0 /* nextDistance */] += otherPath.spacingToFirstItem;
- DEBUG &&
- logger.log(
- " Add distance to last item, effectively being",
- lastItem[0 /* nextDistance */],
- "now"
- );
- } else {
- // Seems we have no items, update our first item distance
- this.spacingToFirstItem = oldLength + otherPath.spacingToFirstItem;
- DEBUG &&
- logger.log(
- " We had no items, so our new spacing to first is old length (",
- oldLength,
- ") plus others spacing to first (",
- otherPath.spacingToFirstItem,
- ") =",
- this.spacingToFirstItem
- );
- }
-
- DEBUG && logger.log(" Pushing", otherPath.items.length, "items from other path");
-
- // Aaand push the other paths items
- for (let i = 0; i < otherPath.items.length; ++i) {
- const item = otherPath.items[i];
- this.items.push([item[0 /* nextDistance */], item[1 /* item */]]);
- }
-
- // Update bounds
- this.worldBounds = this.computeBounds();
-
- this.onPathChanged();
-
- if (G_IS_DEV && globalConfig.debug.checkBeltPaths) {
- this.debug_checkIntegrity("extend-by-path");
- }
- }
-
- /**
- * Computes the total length of the path
- * @returns {number}
- */
- computeTotalLength() {
- let length = 0;
- for (let i = 0; i < this.entityPath.length; ++i) {
- const entity = this.entityPath[i];
- length += entity.components.Belt.getEffectiveLengthTiles();
- }
- return length;
- }
-
- /**
- * Performs one tick
- */
- update() {
- if (G_IS_DEV && globalConfig.debug.checkBeltPaths) {
- this.debug_checkIntegrity("pre-update");
- }
-
- // Skip empty belts
- if (this.items.length === 0) {
- return;
- }
-
- // Divide by item spacing on belts since we use throughput and not speed
- let beltSpeed =
- this.root.hubGoals.getBeltBaseSpeed() *
- this.root.dynamicTickrate.deltaSeconds *
- globalConfig.itemSpacingOnBelts;
-
- if (G_IS_DEV && globalConfig.debug.instantBelts) {
- beltSpeed *= 100;
- }
-
- // Store whether this is the first item we processed, so premature
- // item ejection is available
- let isFirstItemProcessed = true;
-
- // Store how much velocity (strictly its distance, not velocity) we have to distribute over all items
- let remainingVelocity = beltSpeed;
-
- // Store the last item we processed, so we can skip clashed ones
- let lastItemProcessed;
-
- for (lastItemProcessed = this.items.length - 1; lastItemProcessed >= 0; --lastItemProcessed) {
- const nextDistanceAndItem = this.items[lastItemProcessed];
-
- // Compute how much spacing we need at least
- const minimumSpacing =
- lastItemProcessed === this.items.length - 1 ? 0 : globalConfig.itemSpacingOnBelts;
-
- // Compute how much we can advance
- let clampedProgress = nextDistanceAndItem[0 /* nextDistance */] - minimumSpacing;
-
- // Make sure we don't advance more than the remaining velocity has stored
- if (remainingVelocity < clampedProgress) {
- clampedProgress = remainingVelocity;
- }
-
- // Make sure we don't advance back
- if (clampedProgress < 0) {
- clampedProgress = 0;
- }
-
- // Reduce our velocity by the amount we consumed
- remainingVelocity -= clampedProgress;
-
- // Reduce the spacing
- nextDistanceAndItem[0 /* nextDistance */] -= clampedProgress;
-
- // Advance all items behind by the progress we made
- this.spacingToFirstItem += clampedProgress;
-
- // If the last item can be ejected, eject it and reduce the spacing, because otherwise
- // we lose velocity
- if (isFirstItemProcessed && nextDistanceAndItem[0 /* nextDistance */] < 1e-7) {
- // Store how much velocity we "lost" because we bumped the item to the end of the
- // belt but couldn't move it any farther. We need this to tell the item acceptor
- // animation to start a tad later, so everything matches up. Yes I'm a perfectionist.
- const excessVelocity = beltSpeed - clampedProgress;
-
- // Try to directly get rid of the item
- if (
- this.boundAcceptor &&
- this.boundAcceptor(nextDistanceAndItem[1 /* item */], excessVelocity)
- ) {
- this.items.pop();
-
- const itemBehind = this.items[lastItemProcessed - 1];
- if (itemBehind && this.numCompressedItemsAfterFirstItem > 0) {
- // So, with the next tick we will skip this item, but it actually has the potential
- // to process farther -> If we don't advance here, we loose a tiny bit of progress
- // every tick which causes the belt to be slower than it actually is.
- // Also see #999
- const fixupProgress = Math.max(
- 0,
- Math.min(remainingVelocity, itemBehind[0 /* nextDistance */])
- );
-
- // See above
- itemBehind[0 /* nextDistance */] -= fixupProgress;
- remainingVelocity -= fixupProgress;
- this.spacingToFirstItem += fixupProgress;
- }
-
- // Reduce the number of compressed items since the first item no longer exists
- this.numCompressedItemsAfterFirstItem = Math.max(
- 0,
- this.numCompressedItemsAfterFirstItem - 1
- );
- }
- }
-
- if (isFirstItemProcessed) {
- // Skip N null items after first items
- lastItemProcessed -= this.numCompressedItemsAfterFirstItem;
- }
-
- isFirstItemProcessed = false;
- if (remainingVelocity < 1e-7) {
- break;
- }
- }
-
- // Compute compressed item count
- this.numCompressedItemsAfterFirstItem = Math.max(
- 0,
- this.numCompressedItemsAfterFirstItem,
- this.items.length - 2 - lastItemProcessed
- );
-
- // Check if we have an item which is ready to be emitted
- const lastItem = this.items[this.items.length - 1];
- if (lastItem && lastItem[0 /* nextDistance */] === 0) {
- if (this.boundAcceptor && this.boundAcceptor(lastItem[1 /* item */])) {
- this.items.pop();
- this.numCompressedItemsAfterFirstItem = Math.max(
- 0,
- this.numCompressedItemsAfterFirstItem - 1
- );
- }
- }
-
- if (G_IS_DEV && globalConfig.debug.checkBeltPaths) {
- this.debug_checkIntegrity("post-update");
- }
- }
-
- /**
- * Computes a world space position from the given progress
- * @param {number} progress
- * @returns {Vector}
- */
- computePositionFromProgress(progress) {
- let currentLength = 0;
-
- // floating point issues ..
- assert(progress <= this.totalLength + 0.02, "Progress too big: " + progress);
-
- for (let i = 0; i < this.entityPath.length; ++i) {
- const beltComp = this.entityPath[i].components.Belt;
- const localLength = beltComp.getEffectiveLengthTiles();
-
- if (currentLength + localLength >= progress || i === this.entityPath.length - 1) {
- // Min required here due to floating point issues
- const localProgress = Math.min(1.0, progress - currentLength);
-
- assert(localProgress >= 0.0, "Invalid local progress: " + localProgress);
- const localSpace = beltComp.transformBeltToLocalSpace(localProgress);
- return this.entityPath[i].components.StaticMapEntity.localTileToWorld(localSpace);
- }
- currentLength += localLength;
- }
-
- assert(false, "invalid progress: " + progress + " (max: " + this.totalLength + ")");
- }
-
- /**
- *
- * @param {DrawParameters} parameters
- */
- drawDebug(parameters) {
- if (!parameters.visibleRect.containsRect(this.worldBounds)) {
- return;
- }
-
- parameters.context.fillStyle = "#d79a25";
- parameters.context.strokeStyle = "#d79a25";
- parameters.context.beginPath();
-
- for (let i = 0; i < this.entityPath.length; ++i) {
- const entity = this.entityPath[i];
- const pos = entity.components.StaticMapEntity;
- const worldPos = pos.origin.toWorldSpaceCenterOfTile();
-
- if (i === 0) {
- parameters.context.moveTo(worldPos.x, worldPos.y);
- } else {
- parameters.context.lineTo(worldPos.x, worldPos.y);
- }
- }
- parameters.context.stroke();
-
- // Items
- let progress = this.spacingToFirstItem;
- for (let i = 0; i < this.items.length; ++i) {
- const nextDistanceAndItem = this.items[i];
- const worldPos = this.computePositionFromProgress(progress).toWorldSpaceCenterOfTile();
- parameters.context.fillStyle = "#268e4d";
- parameters.context.beginRoundedRect(worldPos.x - 5, worldPos.y - 5, 10, 10, 3);
- parameters.context.fill();
- parameters.context.font = "6px GameFont";
- parameters.context.fillStyle = "#111";
- parameters.context.fillText(
- "" + round4Digits(nextDistanceAndItem[0 /* nextDistance */]),
- worldPos.x + 5,
- worldPos.y + 2
- );
- progress += nextDistanceAndItem[0 /* nextDistance */];
-
- if (this.items.length - 1 - this.numCompressedItemsAfterFirstItem === i) {
- parameters.context.fillStyle = "red";
- parameters.context.fillRect(worldPos.x + 5, worldPos.y, 20, 3);
- }
- }
-
- for (let i = 0; i < this.entityPath.length; ++i) {
- const entity = this.entityPath[i];
- parameters.context.fillStyle = "#d79a25";
- const pos = entity.components.StaticMapEntity;
- const worldPos = pos.origin.toWorldSpaceCenterOfTile();
- parameters.context.beginCircle(worldPos.x, worldPos.y, i === 0 ? 5 : 3);
- parameters.context.fill();
- }
-
- for (let progress = 0; progress <= this.totalLength + 0.01; progress += 0.2) {
- const worldPos = this.computePositionFromProgress(progress).toWorldSpaceCenterOfTile();
- parameters.context.fillStyle = "red";
- parameters.context.beginCircle(worldPos.x, worldPos.y, 1);
- parameters.context.fill();
- }
-
- const firstItemIndicator = this.computePositionFromProgress(
- this.spacingToFirstItem
- ).toWorldSpaceCenterOfTile();
- parameters.context.fillStyle = "purple";
- parameters.context.fillRect(firstItemIndicator.x - 3, firstItemIndicator.y - 1, 6, 2);
- }
-
- /**
- * Checks if this belt path should render simplified
- */
- checkIsPotatoMode() {
- // POTATO Mode: Only show items when belt is hovered
- if (!this.root.app.settings.getAllSettings().simplifiedBelts) {
- return false;
- }
-
- if (this.root.currentLayer !== "regular") {
- // Not in regular layer
- return true;
- }
-
- const mousePos = this.root.app.mousePosition;
- if (!mousePos) {
- // Mouse not registered
- return true;
- }
-
- const tile = this.root.camera.screenToWorld(mousePos).toTileSpace();
- const contents = this.root.map.getLayerContentXY(tile.x, tile.y, "regular");
- if (!contents || !contents.components.Belt) {
- // Nothing below
- return true;
- }
-
- if (contents.components.Belt.assignedPath !== this) {
- // Not this path
- return true;
- }
- return false;
- }
-
- /**
- * Draws the path
- * @param {DrawParameters} parameters
- */
- draw(parameters) {
- if (!parameters.visibleRect.containsRect(this.worldBounds)) {
- return;
- }
-
- if (this.items.length === 0) {
- // Early out
- return;
- }
-
- if (this.checkIsPotatoMode()) {
- const firstItem = this.items[0];
- if (this.entityPath.length > 1 && firstItem) {
- const medianBeltIndex = clamp(
- Math.round(this.entityPath.length / 2 - 1),
- 0,
- this.entityPath.length - 1
- );
- const medianBelt = this.entityPath[medianBeltIndex];
- const beltComp = medianBelt.components.Belt;
- const staticComp = medianBelt.components.StaticMapEntity;
- const centerPosLocal = beltComp.transformBeltToLocalSpace(
- this.entityPath.length % 2 === 0 ? beltComp.getEffectiveLengthTiles() : 0.5
- );
- const centerPos = staticComp.localTileToWorld(centerPosLocal).toWorldSpaceCenterOfTile();
-
- parameters.context.globalAlpha = 0.5;
- firstItem[1 /* item */].drawItemCenteredClipped(centerPos.x, centerPos.y, parameters);
- parameters.context.globalAlpha = 1;
- }
-
- return;
- }
-
- let currentItemPos = this.spacingToFirstItem;
- let currentItemIndex = 0;
-
- let trackPos = 0.0;
-
- /**
- * @type {Array<[Vector, BaseItem]>}
- */
- let drawStack = [];
- let drawStackProp = "";
-
- // Iterate whole track and check items
- for (let i = 0; i < this.entityPath.length; ++i) {
- const entity = this.entityPath[i];
- const beltComp = entity.components.Belt;
- const beltLength = beltComp.getEffectiveLengthTiles();
-
- // Check if the current items are on the belt
- while (trackPos + beltLength >= currentItemPos - 1e-5) {
- // It's on the belt, render it now
- const staticComp = entity.components.StaticMapEntity;
- assert(
- currentItemPos - trackPos >= 0,
- "invalid track pos: " + currentItemPos + " vs " + trackPos + " (l =" + beltLength + ")"
- );
-
- const localPos = beltComp.transformBeltToLocalSpace(currentItemPos - trackPos);
- const worldPos = staticComp.localTileToWorld(localPos).toWorldSpaceCenterOfTile();
-
- const distanceAndItem = this.items[currentItemIndex];
- const item = distanceAndItem[1 /* item */];
- const nextItemDistance = distanceAndItem[0 /* nextDistance */];
-
- if (
- !parameters.visibleRect.containsCircle(
- worldPos.x,
- worldPos.y,
- globalConfig.defaultItemDiameter
- )
- ) {
- // this one isn't visible, do not append it
- // Start a new stack
- this.drawDrawStack(drawStack, parameters, drawStackProp);
- drawStack = [];
- drawStackProp = "";
- } else {
- if (drawStack.length > 1) {
- // Check if we can append to the stack, since its already a stack of two same items
- const referenceItem = drawStack[0];
-
- if (
- referenceItem[1].equals(item) &&
- Math.abs(referenceItem[0][drawStackProp] - worldPos[drawStackProp]) < 0.001
- ) {
- // Will continue stack
- } else {
- // Start a new stack, since item doesn't follow in row
- this.drawDrawStack(drawStack, parameters, drawStackProp);
- drawStack = [];
- drawStackProp = "";
- }
- } else if (drawStack.length === 1) {
- const firstItem = drawStack[0];
-
- // Check if we can make it a stack
- if (firstItem[1 /* item */].equals(item)) {
- // Same item, check if it is either horizontal or vertical
- const startPos = firstItem[0 /* pos */];
-
- if (Math.abs(startPos.x - worldPos.x) < 0.001) {
- drawStackProp = "x";
- } else if (Math.abs(startPos.y - worldPos.y) < 0.001) {
- drawStackProp = "y";
- } else {
- // Start a new stack
- this.drawDrawStack(drawStack, parameters, drawStackProp);
- drawStack = [];
- drawStackProp = "";
- }
- } else {
- // Start a new stack, since item doesn't equal
- this.drawDrawStack(drawStack, parameters, drawStackProp);
- drawStack = [];
- drawStackProp = "";
- }
- } else {
- // First item of stack, do nothing
- }
-
- drawStack.push([worldPos, item]);
- }
-
- // Check for the next item
- currentItemPos += nextItemDistance;
- ++currentItemIndex;
-
- if (
- nextItemDistance > globalConfig.itemSpacingOnBelts + 0.001 ||
- drawStack.length > globalConfig.maxBeltShapeBundleSize
- ) {
- // If next item is not directly following, abort drawing
- this.drawDrawStack(drawStack, parameters, drawStackProp);
- drawStack = [];
- drawStackProp = "";
- }
-
- if (currentItemIndex >= this.items.length) {
- // We rendered all items
-
- this.drawDrawStack(drawStack, parameters, drawStackProp);
- return;
- }
- }
-
- trackPos += beltLength;
- }
-
- this.drawDrawStack(drawStack, parameters, drawStackProp);
- }
-
- /**
- *
- * @param {HTMLCanvasElement} canvas
- * @param {CanvasRenderingContext2D} context
- * @param {number} w
- * @param {number} h
- * @param {number} dpi
- * @param {object} param0
- * @param {string} param0.direction
- * @param {Array<[Vector, BaseItem]>} param0.stack
- * @param {GameRoot} param0.root
- * @param {number} param0.zoomLevel
- */
- drawShapesInARow(canvas, context, w, h, dpi, { direction, stack, root, zoomLevel }) {
- context.scale(dpi, dpi);
-
- if (G_IS_DEV && globalConfig.debug.showShapeGrouping) {
- context.fillStyle = "rgba(0, 0, 255, 0.5)";
- context.fillRect(0, 0, w, h);
- }
-
- const parameters = new DrawParameters({
- context,
- desiredAtlasScale: ORIGINAL_SPRITE_SCALE,
- root,
- visibleRect: new Rectangle(-1000, -1000, 2000, 2000),
- zoomLevel,
- });
-
- const itemSize = globalConfig.itemSpacingOnBelts * globalConfig.tileSize;
- const item = stack[0];
- const pos = new Vector(itemSize / 2, itemSize / 2);
-
- for (let i = 0; i < stack.length; i++) {
- item[1].drawItemCenteredClipped(pos.x, pos.y, parameters, globalConfig.defaultItemDiameter);
- pos[direction] += globalConfig.itemSpacingOnBelts * globalConfig.tileSize;
- }
- }
-
- /**
- * @param {Array<[Vector, BaseItem]>} stack
- * @param {DrawParameters} parameters
- */
- drawDrawStack(stack, parameters, directionProp) {
- if (stack.length === 0) {
- return;
- }
-
- const firstItem = stack[0];
- const firstItemPos = firstItem[0];
- if (stack.length === 1) {
- firstItem[1].drawItemCenteredClipped(
- firstItemPos.x,
- firstItemPos.y,
- parameters,
- globalConfig.defaultItemDiameter
- );
- return;
- }
-
- const itemSize = globalConfig.itemSpacingOnBelts * globalConfig.tileSize;
- const inverseDirection = directionProp === "x" ? "y" : "x";
-
- const dimensions = new Vector(itemSize, itemSize);
- dimensions[inverseDirection] *= stack.length;
-
- const directionVector = firstItemPos.copy().sub(stack[1][0]);
-
- const dpi = smoothenDpi(globalConfig.shapesSharpness * parameters.zoomLevel);
-
- const sprite = this.root.buffers.getForKey({
- key: "beltpaths",
- subKey:
- "stack-" +
- directionProp +
- "-" +
- dpi +
- "#" +
- stack.length +
- "#" +
- firstItem[1].getItemType() +
- "#" +
- firstItem[1].serialize(),
- dpi,
- w: dimensions.x,
- h: dimensions.y,
- redrawMethod: this.drawShapesInARow.bind(this),
- additionalParams: {
- direction: inverseDirection,
- stack,
- root: this.root,
- zoomLevel: parameters.zoomLevel,
- },
- });
-
- const anchor = directionVector[inverseDirection] < 0 ? firstItem : stack[stack.length - 1];
-
- parameters.context.drawImage(
- sprite,
- anchor[0].x - itemSize / 2,
- anchor[0].y - itemSize / 2,
- dimensions.x,
- dimensions.y
- );
- }
-}
+import { globalConfig } from "../core/config";
+import { smoothenDpi } from "../core/dpi_manager";
+import { DrawParameters } from "../core/draw_parameters";
+import { createLogger } from "../core/logging";
+import { Rectangle } from "../core/rectangle";
+import { ORIGINAL_SPRITE_SCALE } from "../core/sprites";
+import { clamp, epsilonCompare, round4Digits } from "../core/utils";
+import { enumDirection, enumDirectionToVector, enumInvertedDirections, Vector } from "../core/vector";
+import { BasicSerializableObject, types } from "../savegame/serialization";
+import { BaseItem } from "./base_item";
+import { Entity } from "./entity";
+import { typeItemSingleton } from "./item_resolver";
+import { GameRoot } from "./root";
+
+const logger = createLogger("belt_path");
+
+// Helpers for more semantic access into interleaved arrays
+
+const DEBUG = G_IS_DEV && false;
+
+/**
+ * Stores a path of belts, used for optimizing performance
+ */
+export class BeltPath extends BasicSerializableObject {
+ static getId() {
+ return "BeltPath";
+ }
+
+ static getSchema() {
+ return {
+ entityPath: types.array(types.entity),
+ items: types.array(types.pair(types.ufloat, typeItemSingleton)),
+ spacingToFirstItem: types.ufloat,
+ };
+ }
+
+ /**
+ * Creates a path from a serialized object
+ * @param {GameRoot} root
+ * @param {Object} data
+ * @returns {BeltPath|string}
+ */
+ static fromSerialized(root, data) {
+ // Create fake object which looks like a belt path but skips the constructor
+ const fakeObject = /** @type {BeltPath} */ (Object.create(BeltPath.prototype));
+ fakeObject.root = root;
+
+ // Deserialize the data
+ const errorCodeDeserialize = fakeObject.deserialize(data);
+ if (errorCodeDeserialize) {
+ return errorCodeDeserialize;
+ }
+
+ // Compute other properties
+ fakeObject.init(false);
+
+ return fakeObject;
+ }
+
+ /**
+ * @param {GameRoot} root
+ * @param {Array} entityPath
+ */
+ constructor(root, entityPath) {
+ super();
+ this.root = root;
+
+ assert(entityPath.length > 0, "invalid entity path");
+ this.entityPath = entityPath;
+
+ /**
+ * Stores the items sorted, and their distance to the previous item (or start)
+ * Layout: [distanceToNext, item]
+ * @type {Array<[number, BaseItem]>}
+ */
+ this.items = [];
+
+ /**
+ * Stores the spacing to the first item
+ */
+
+ this.init();
+
+ if (G_IS_DEV && globalConfig.debug.checkBeltPaths) {
+ this.debug_checkIntegrity("constructor");
+ }
+ }
+ /**
+ * Initializes the path by computing the properties which are not saved
+ * @param {boolean} computeSpacing Whether to also compute the spacing
+ */
+ init(computeSpacing = true) {
+ this.onPathChanged();
+
+ this.totalLength = this.computeTotalLength();
+
+ if (computeSpacing) {
+ this.spacingToFirstItem = this.totalLength;
+ }
+
+ /**
+ * Current bounds of this path
+ * @type {Rectangle}
+ */
+ this.worldBounds = this.computeBounds();
+
+ // Connect the belts
+ for (let i = 0; i < this.entityPath.length; ++i) {
+ this.entityPath[i].components.Belt.assignedPath = this;
+ }
+ }
+
+ /**
+ * Clears all items
+ */
+ clearAllItems() {
+ this.items = [];
+ this.spacingToFirstItem = this.totalLength;
+ this.numCompressedItemsAfterFirstItem = 0;
+ }
+
+ /**
+ * Returns whether this path can accept a new item
+ * @returns {boolean}
+ */
+ canAcceptItem() {
+ return this.spacingToFirstItem >= globalConfig.itemSpacingOnBelts;
+ }
+
+ /**
+ * Tries to accept the item
+ * @param {BaseItem} item
+ */
+ tryAcceptItem(item) {
+ if (this.spacingToFirstItem >= globalConfig.itemSpacingOnBelts) {
+ // So, since we already need one tick to accept this item we will add this directly.
+ const beltProgressPerTick =
+ this.root.hubGoals.getBeltBaseSpeed() *
+ this.root.dynamicTickrate.deltaSeconds *
+ globalConfig.itemSpacingOnBelts;
+
+ // First, compute how much progress we can make *at max*
+ const maxProgress = Math.max(0, this.spacingToFirstItem - globalConfig.itemSpacingOnBelts);
+ const initialProgress = Math.min(maxProgress, beltProgressPerTick);
+
+ this.items.unshift([this.spacingToFirstItem - initialProgress, item]);
+ this.spacingToFirstItem = initialProgress;
+
+ if (G_IS_DEV && globalConfig.debug.checkBeltPaths) {
+ this.debug_checkIntegrity("accept-item");
+ }
+
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * SLOW / Tries to find the item closest to the given tile
+ * @param {Vector} tile
+ * @returns {BaseItem|null}
+ */
+ findItemAtTile(tile) {
+ // @TODO: This breaks color blind mode otherwise
+ return null;
+ }
+
+ /**
+ * Computes the tile bounds of the path
+ * @returns {Rectangle}
+ */
+ computeBounds() {
+ let bounds = this.entityPath[0].components.StaticMapEntity.getTileSpaceBounds();
+ for (let i = 1; i < this.entityPath.length; ++i) {
+ const staticComp = this.entityPath[i].components.StaticMapEntity;
+ const otherBounds = staticComp.getTileSpaceBounds();
+ bounds = bounds.getUnion(otherBounds);
+ }
+ return bounds.allScaled(globalConfig.tileSize);
+ }
+
+ /**
+ * Recomputes cache variables once the path was changed
+ */
+ onPathChanged() {
+ this.boundAcceptor = this.computeAcceptingEntityAndSlot().acceptor;
+
+ /**
+ * How many items past the first item are compressed
+ */
+ this.numCompressedItemsAfterFirstItem = 0;
+ }
+
+ /**
+ * Called by the belt system when the surroundings changed
+ */
+ onSurroundingsChanged() {
+ this.onPathChanged();
+ }
+
+ /**
+ * Finds the entity which accepts our items
+ * @param {boolean=} debug_Silent Whether debug output should be silent
+ * @return { { acceptor?: (BaseItem, number?) => boolean, entity?: Entity } }
+ */
+ computeAcceptingEntityAndSlot(debug_Silent = false) {
+ DEBUG && !debug_Silent && logger.log("Recomputing acceptor target");
+
+ const lastEntity = this.entityPath[this.entityPath.length - 1];
+ const lastStatic = lastEntity.components.StaticMapEntity;
+ const lastBeltComp = lastEntity.components.Belt;
+
+ // Figure out where and into which direction we eject items
+ const ejectSlotWsTile = lastStatic.localTileToWorld(new Vector(0, 0));
+ const ejectSlotWsDirection = lastStatic.localDirectionToWorld(lastBeltComp.direction);
+ const ejectSlotWsDirectionVector = enumDirectionToVector[ejectSlotWsDirection];
+ const ejectSlotTargetWsTile = ejectSlotWsTile.add(ejectSlotWsDirectionVector);
+
+ // Try to find the given acceptor component to take the item
+ const targetEntity = this.root.map.getLayerContentXY(
+ ejectSlotTargetWsTile.x,
+ ejectSlotTargetWsTile.y,
+ "regular"
+ );
+
+ if (!targetEntity) {
+ return {};
+ }
+
+ const noSimplifiedBelts = !this.root.app.settings.getAllSettings().simplifiedBelts;
+
+ DEBUG && !debug_Silent && logger.log(" Found target entity", targetEntity.uid);
+ const targetStaticComp = targetEntity.components.StaticMapEntity;
+ const targetBeltComp = targetEntity.components.Belt;
+
+ // Check for belts (special case)
+ if (targetBeltComp) {
+ const beltAcceptingDirection = targetStaticComp.localDirectionToWorld(enumDirection.top);
+ DEBUG &&
+ !debug_Silent &&
+ logger.log(
+ " Entity is accepting items from",
+ ejectSlotWsDirection,
+ "vs",
+ beltAcceptingDirection,
+ "Rotation:",
+ targetStaticComp.rotation
+ );
+ if (ejectSlotWsDirection === beltAcceptingDirection) {
+ return {
+ entity: targetEntity,
+ acceptor: item => {
+ const path = targetBeltComp.assignedPath;
+ assert(path, "belt has no path");
+ return path.tryAcceptItem(item);
+ },
+ };
+ }
+ }
+
+ // Check for item acceptors
+ const targetAcceptorComp = targetEntity.components.ItemAcceptor;
+ if (!targetAcceptorComp) {
+ // Entity doesn't accept items
+ return {};
+ }
+
+ const ejectingDirection = targetStaticComp.worldDirectionToLocal(ejectSlotWsDirection);
+ const matchingSlot = targetAcceptorComp.findMatchingSlot(
+ targetStaticComp.worldToLocalTile(ejectSlotTargetWsTile),
+ ejectingDirection
+ );
+
+ if (!matchingSlot) {
+ // No matching slot found
+ return {};
+ }
+
+ const matchingSlotIndex = matchingSlot.index;
+ const passOver = this.computePassOverFunctionWithoutBelts(targetEntity, matchingSlotIndex);
+ if (!passOver) {
+ return {};
+ }
+
+ const matchingDirection = enumInvertedDirections[ejectingDirection];
+ const filter = matchingSlot.slot.filter;
+
+ return {
+ entity: targetEntity,
+ acceptor: function (item, remainingProgress = 0.0) {
+ // Check if the acceptor has a filter
+ if (filter && item._type !== filter) {
+ return false;
+ }
+
+ // Try to pass over
+ if (passOver(item, matchingSlotIndex)) {
+ // Trigger animation on the acceptor comp
+ if (noSimplifiedBelts) {
+ targetAcceptorComp.onItemAccepted(
+ matchingSlotIndex,
+ matchingDirection,
+ item,
+ remainingProgress
+ );
+ }
+ return true;
+ }
+ return false;
+ },
+ };
+ }
+
+ /**
+ * Computes a method to pass over the item to the entity
+ * @param {Entity} entity
+ * @param {number} matchingSlotIndex
+ * @returns {(item: BaseItem, slotIndex: number) => boolean | void}
+ */
+ computePassOverFunctionWithoutBelts(entity, matchingSlotIndex) {
+ const systems = this.root.systemMgr.systems;
+ const hubGoals = this.root.hubGoals;
+
+ // NOTICE: THIS IS COPIED FROM THE ITEM EJECTOR SYSTEM FOR PEROFMANCE REASONS
+
+ const itemProcessorComp = entity.components.ItemProcessor;
+ if (itemProcessorComp) {
+ // Its an item processor ..
+ return function (item) {
+ // Check for potential filters
+ if (!systems.itemProcessor.checkRequirements(entity, item, matchingSlotIndex)) {
+ return;
+ }
+ return itemProcessorComp.tryTakeItem(item, matchingSlotIndex);
+ };
+ }
+
+ const undergroundBeltComp = entity.components.UndergroundBelt;
+ if (undergroundBeltComp) {
+ // Its an underground belt. yay.
+ return function (item) {
+ return undergroundBeltComp.tryAcceptExternalItem(
+ item,
+ hubGoals.getUndergroundBeltBaseSpeed()
+ );
+ };
+ }
+
+ const storageComp = entity.components.Storage;
+ if (storageComp) {
+ // It's a storage
+ return function (item) {
+ if (storageComp.canAcceptItem(item)) {
+ storageComp.takeItem(item);
+ return true;
+ }
+ };
+ }
+
+ const filterComp = entity.components.Filter;
+ if (filterComp) {
+ // It's a filter! Unfortunately the filter has to know a lot about it's
+ // surrounding state and components, so it can't be within the component itself.
+ return function (item) {
+ if (systems.filter.tryAcceptItem(entity, matchingSlotIndex, item)) {
+ return true;
+ }
+ };
+ }
+ }
+
+ // Following code will be compiled out outside of dev versions
+ /* dev:start */
+
+ /**
+ * Helper to throw an error on mismatch
+ * @param {string} change
+ * @param {Array} reason
+ */
+ debug_failIntegrity(change, ...reason) {
+ throw new Error("belt path invalid (" + change + "): " + reason.map(i => "" + i).join(" "));
+ }
+
+ /**
+ * Checks if this path is valid
+ */
+ debug_checkIntegrity(currentChange = "change") {
+ const fail = (...args) => this.debug_failIntegrity(currentChange, ...args);
+
+ // Check for empty path
+ if (this.entityPath.length === 0) {
+ return fail("Belt path is empty");
+ }
+
+ // Check for mismatching length
+ const totalLength = this.computeTotalLength();
+ if (!epsilonCompare(this.totalLength, totalLength, 0.01)) {
+ return this.debug_failIntegrity(
+ currentChange,
+ "Total length mismatch, stored =",
+ this.totalLength,
+ "but correct is",
+ totalLength
+ );
+ }
+
+ // Check for misconnected entities
+ for (let i = 0; i < this.entityPath.length - 1; ++i) {
+ const entity = this.entityPath[i];
+ if (entity.destroyed) {
+ return fail("Reference to destroyed entity " + entity.uid);
+ }
+
+ const followUp = this.root.systemMgr.systems.belt.findFollowUpEntity(entity);
+ if (!followUp) {
+ return fail(
+ "Follow up entity for the",
+ i,
+ "-th entity (total length",
+ this.entityPath.length,
+ ") was null!"
+ );
+ }
+ if (followUp !== this.entityPath[i + 1]) {
+ return fail(
+ "Follow up entity mismatch, stored is",
+ this.entityPath[i + 1].uid,
+ "but real one is",
+ followUp.uid
+ );
+ }
+ if (entity.components.Belt.assignedPath !== this) {
+ return fail(
+ "Entity with uid",
+ entity.uid,
+ "doesn't have this path assigned, but this path contains the entity."
+ );
+ }
+ }
+
+ // Check spacing
+ if (this.spacingToFirstItem > this.totalLength + 0.005) {
+ return fail(
+ currentChange,
+ "spacing to first item (",
+ this.spacingToFirstItem,
+ ") is greater than total length (",
+ this.totalLength,
+ ")"
+ );
+ }
+
+ // Check distance if empty
+ if (this.items.length === 0 && !epsilonCompare(this.spacingToFirstItem, this.totalLength, 0.01)) {
+ return fail(
+ currentChange,
+ "Path is empty but spacing to first item (",
+ this.spacingToFirstItem,
+ ") does not equal total length (",
+ this.totalLength,
+ ")"
+ );
+ }
+
+ // Check items etc
+ let currentPos = this.spacingToFirstItem;
+ for (let i = 0; i < this.items.length; ++i) {
+ const item = this.items[i];
+
+ if (item[0 /* nextDistance */] < 0 || item[0 /* nextDistance */] > this.totalLength + 0.02) {
+ return fail(
+ "Item has invalid offset to next item: ",
+ item[0 /* nextDistance */],
+ "(total length:",
+ this.totalLength,
+ ")"
+ );
+ }
+
+ currentPos += item[0 /* nextDistance */];
+ }
+
+ // Check the total sum matches
+ if (!epsilonCompare(currentPos, this.totalLength, 0.01)) {
+ return fail(
+ "total sum (",
+ currentPos,
+ ") of first item spacing (",
+ this.spacingToFirstItem,
+ ") and items does not match total length (",
+ this.totalLength,
+ ") -> items: " + this.items.map(i => i[0 /* nextDistance */]).join("|")
+ );
+ }
+
+ // Check bounds
+ const actualBounds = this.computeBounds();
+ if (!actualBounds.equalsEpsilon(this.worldBounds, 0.01)) {
+ return fail("Bounds are stale");
+ }
+
+ // Check acceptor
+ const acceptor = this.computeAcceptingEntityAndSlot(true).acceptor;
+ if (!!acceptor !== !!this.boundAcceptor) {
+ return fail("Acceptor target mismatch, acceptor", !!acceptor, "vs stored", !!this.boundAcceptor);
+ }
+
+ // Check first nonzero offset
+ let firstNonzero = 0;
+ for (let i = this.items.length - 2; i >= 0; --i) {
+ if (this.items[i][0 /* nextDistance */] < globalConfig.itemSpacingOnBelts + 1e-5) {
+ ++firstNonzero;
+ } else {
+ break;
+ }
+ }
+
+ // Should warn, but this check isn't actually accurate
+ // if (firstNonzero !== this.numCompressedItemsAfterFirstItem) {
+ // console.warn(
+ // "First nonzero index is " +
+ // firstNonzero +
+ // " but stored is " +
+ // this.numCompressedItemsAfterFirstItem
+ // );
+ // }
+ }
+
+ /* dev:end */
+
+ /**
+ * Extends the belt path by the given belt
+ * @param {Entity} entity
+ */
+ extendOnEnd(entity) {
+ DEBUG && logger.log("Extending belt path by entity at", entity.components.StaticMapEntity.origin);
+
+ const beltComp = entity.components.Belt;
+
+ // Append the entity
+ this.entityPath.push(entity);
+ this.onPathChanged();
+
+ // Extend the path length
+ const additionalLength = beltComp.getEffectiveLengthTiles();
+ this.totalLength += additionalLength;
+ DEBUG && logger.log(" Extended total length by", additionalLength, "to", this.totalLength);
+
+ // If we have no item, just update the distance to the first item
+ if (this.items.length === 0) {
+ this.spacingToFirstItem = this.totalLength;
+ DEBUG && logger.log(" Extended spacing to first to", this.totalLength, "(= total length)");
+ } else {
+ // Otherwise, update the next-distance of the last item
+ const lastItem = this.items[this.items.length - 1];
+ DEBUG &&
+ logger.log(
+ " Extended spacing of last item from",
+ lastItem[0 /* nextDistance */],
+ "to",
+ lastItem[0 /* nextDistance */] + additionalLength
+ );
+ lastItem[0 /* nextDistance */] += additionalLength;
+ }
+
+ // Assign reference
+ beltComp.assignedPath = this;
+
+ // Update bounds
+ this.worldBounds = this.computeBounds();
+
+ if (G_IS_DEV && globalConfig.debug.checkBeltPaths) {
+ this.debug_checkIntegrity("extend-on-end");
+ }
+ }
+
+ /**
+ * Extends the path with the given entity on the beginning
+ * @param {Entity} entity
+ */
+ extendOnBeginning(entity) {
+ const beltComp = entity.components.Belt;
+
+ DEBUG && logger.log("Extending the path on the beginning");
+
+ // All items on that belt are simply lost (for now)
+
+ const length = beltComp.getEffectiveLengthTiles();
+
+ // Extend the length of this path
+ this.totalLength += length;
+
+ // Simply adjust the first item spacing cuz we have no items contained
+ this.spacingToFirstItem += length;
+
+ // Set handles and append entity
+ beltComp.assignedPath = this;
+ this.entityPath.unshift(entity);
+ this.onPathChanged();
+
+ // Update bounds
+ this.worldBounds = this.computeBounds();
+
+ if (G_IS_DEV && globalConfig.debug.checkBeltPaths) {
+ this.debug_checkIntegrity("extend-on-begin");
+ }
+ }
+
+ /**
+ * Returns if the given entity is the end entity of the path
+ * @param {Entity} entity
+ * @returns {boolean}
+ */
+ isEndEntity(entity) {
+ return this.entityPath[this.entityPath.length - 1] === entity;
+ }
+
+ /**
+ * Returns if the given entity is the start entity of the path
+ * @param {Entity} entity
+ * @returns {boolean}
+ */
+ isStartEntity(entity) {
+ return this.entityPath[0] === entity;
+ }
+
+ /**
+ * Splits this path at the given entity by removing it, and
+ * returning the new secondary paht
+ * @param {Entity} entity
+ * @returns {BeltPath}
+ */
+ deleteEntityOnPathSplitIntoTwo(entity) {
+ DEBUG && logger.log("Splitting path at entity", entity.components.StaticMapEntity.origin);
+
+ // First, find where the current path ends
+ const beltComp = entity.components.Belt;
+ beltComp.assignedPath = null;
+
+ const entityLength = beltComp.getEffectiveLengthTiles();
+ assert(this.entityPath.indexOf(entity) >= 0, "Entity not contained for split");
+ assert(this.entityPath.indexOf(entity) !== 0, "Entity is first");
+ assert(this.entityPath.indexOf(entity) !== this.entityPath.length - 1, "Entity is last");
+
+ let firstPathEntityCount = 0;
+ let firstPathLength = 0;
+ let firstPathEndEntity = null;
+
+ for (let i = 0; i < this.entityPath.length; ++i) {
+ const otherEntity = this.entityPath[i];
+ if (otherEntity === entity) {
+ DEBUG && logger.log("Found entity at", i, "of length", firstPathLength);
+ break;
+ }
+
+ ++firstPathEntityCount;
+ firstPathEndEntity = otherEntity;
+ firstPathLength += otherEntity.components.Belt.getEffectiveLengthTiles();
+ }
+
+ DEBUG &&
+ logger.log(
+ "First path ends at",
+ firstPathLength,
+ "and entity",
+ firstPathEndEntity.components.StaticMapEntity.origin,
+ "and has",
+ firstPathEntityCount,
+ "entities"
+ );
+
+ // Compute length of second path
+ const secondPathLength = this.totalLength - firstPathLength - entityLength;
+ const secondPathStart = firstPathLength + entityLength;
+ const secondEntities = this.entityPath.splice(firstPathEntityCount + 1);
+ DEBUG &&
+ logger.log(
+ "Second path starts at",
+ secondPathStart,
+ "and has a length of ",
+ secondPathLength,
+ "with",
+ secondEntities.length,
+ "entities"
+ );
+
+ // Remove the last item
+ this.entityPath.pop();
+
+ DEBUG && logger.log("Splitting", this.items.length, "items");
+ DEBUG &&
+ logger.log(
+ "Old items are",
+ this.items.map(i => i[0 /* nextDistance */])
+ );
+
+ // Create second path
+ const secondPath = new BeltPath(this.root, secondEntities);
+
+ // Remove all items which are no longer relevant and transfer them to the second path
+ let itemPos = this.spacingToFirstItem;
+ for (let i = 0; i < this.items.length; ++i) {
+ const item = this.items[i];
+ const distanceToNext = item[0 /* nextDistance */];
+
+ DEBUG && logger.log(" Checking item at", itemPos, "with distance of", distanceToNext, "to next");
+
+ // Check if this item is past the first path
+ if (itemPos >= firstPathLength) {
+ // Remove it from the first path
+ this.items.splice(i, 1);
+ i -= 1;
+ DEBUG &&
+ logger.log(" Removed item from first path since its no longer contained @", itemPos);
+
+ // Check if its on the second path (otherwise its on the removed belt and simply lost)
+ if (itemPos >= secondPathStart) {
+ // Put item on second path
+ secondPath.items.push([distanceToNext, item[1 /* item */]]);
+ DEBUG &&
+ logger.log(
+ " Put item to second path @",
+ itemPos,
+ "with distance to next =",
+ distanceToNext
+ );
+
+ // If it was the first item, adjust the distance to the first item
+ if (secondPath.items.length === 1) {
+ DEBUG && logger.log(" Sinc it was the first, set sapcing of first to", itemPos);
+ secondPath.spacingToFirstItem = itemPos - secondPathStart;
+ }
+ } else {
+ DEBUG && logger.log(" Item was on the removed belt, so its gone - forever!");
+ }
+ } else {
+ // Seems this item is on the first path (so all good), so just make sure it doesn't
+ // have a nextDistance which is bigger than the total path length
+ const clampedDistanceToNext = Math.min(itemPos + distanceToNext, firstPathLength) - itemPos;
+ if (clampedDistanceToNext < distanceToNext) {
+ DEBUG &&
+ logger.log(
+ "Correcting next distance (first path) from",
+ distanceToNext,
+ "to",
+ clampedDistanceToNext
+ );
+ item[0 /* nextDistance */] = clampedDistanceToNext;
+ }
+ }
+
+ // Advance items
+ itemPos += distanceToNext;
+ }
+
+ DEBUG &&
+ logger.log(
+ "New items are",
+ this.items.map(i => i[0 /* nextDistance */])
+ );
+
+ DEBUG &&
+ logger.log(
+ "And second path items are",
+ secondPath.items.map(i => i[0 /* nextDistance */])
+ );
+
+ // Adjust our total length
+ this.totalLength = firstPathLength;
+
+ // Make sure that if we are empty, we set our first distance properly
+ if (this.items.length === 0) {
+ this.spacingToFirstItem = this.totalLength;
+ }
+
+ this.onPathChanged();
+ secondPath.onPathChanged();
+
+ // Update bounds
+ this.worldBounds = this.computeBounds();
+
+ if (G_IS_DEV && globalConfig.debug.checkBeltPaths) {
+ this.debug_checkIntegrity("split-two-first");
+ secondPath.debug_checkIntegrity("split-two-second");
+ }
+
+ return secondPath;
+ }
+
+ /**
+ * Deletes the last entity
+ * @param {Entity} entity
+ */
+ deleteEntityOnEnd(entity) {
+ assert(
+ this.entityPath[this.entityPath.length - 1] === entity,
+ "Not actually the last entity (instead " + this.entityPath.indexOf(entity) + ")"
+ );
+
+ // Ok, first remove the entity
+ const beltComp = entity.components.Belt;
+ const beltLength = beltComp.getEffectiveLengthTiles();
+
+ DEBUG &&
+ logger.log(
+ "Deleting last entity on path with length",
+ this.entityPath.length,
+ "(reducing",
+ this.totalLength,
+ " by",
+ beltLength,
+ ")"
+ );
+ this.totalLength -= beltLength;
+ this.entityPath.pop();
+ this.onPathChanged();
+
+ DEBUG &&
+ logger.log(
+ " New path has length of",
+ this.totalLength,
+ "with",
+ this.entityPath.length,
+ "entities"
+ );
+
+ // This is just for sanity
+ beltComp.assignedPath = null;
+
+ // Clean up items
+ if (this.items.length === 0) {
+ // Simple case with no items, just update the first item spacing
+ this.spacingToFirstItem = this.totalLength;
+ } else {
+ // Ok, make sure we simply drop all items which are no longer contained
+ let itemOffset = this.spacingToFirstItem;
+ let lastItemOffset = itemOffset;
+
+ DEBUG && logger.log(" Adjusting", this.items.length, "items");
+
+ for (let i = 0; i < this.items.length; ++i) {
+ const item = this.items[i];
+
+ // Get rid of items past this path
+ if (itemOffset >= this.totalLength) {
+ DEBUG && logger.log("Dropping item (current index=", i, ")");
+ this.items.splice(i, 1);
+ i -= 1;
+ continue;
+ }
+
+ DEBUG &&
+ logger.log(
+ "Item",
+ i,
+ "is at",
+ itemOffset,
+ "with next offset",
+ item[0 /* nextDistance */]
+ );
+ lastItemOffset = itemOffset;
+ itemOffset += item[0 /* nextDistance */];
+ }
+
+ // If we still have an item, make sure the last item matches
+ if (this.items.length > 0) {
+ // We can easily compute the next distance since we know where the last item is now
+ const lastDistance = this.totalLength - lastItemOffset;
+ assert(
+ lastDistance >= 0.0,
+ "Last item distance mismatch: " +
+ lastDistance +
+ " -> Total length was " +
+ this.totalLength +
+ " and lastItemOffset was " +
+ lastItemOffset
+ );
+
+ DEBUG &&
+ logger.log(
+ "Adjusted distance of last item: it is at",
+ lastItemOffset,
+ "so it has a distance of",
+ lastDistance,
+ "to the end (",
+ this.totalLength,
+ ")"
+ );
+ this.items[this.items.length - 1][0 /* nextDistance */] = lastDistance;
+ } else {
+ DEBUG && logger.log(" Removed all items so we'll update spacing to total length");
+
+ // We removed all items so update our spacing
+ this.spacingToFirstItem = this.totalLength;
+ }
+ }
+
+ // Update bounds
+ this.worldBounds = this.computeBounds();
+
+ if (G_IS_DEV && globalConfig.debug.checkBeltPaths) {
+ this.debug_checkIntegrity("delete-on-end");
+ }
+ }
+
+ /**
+ * Deletes the entity of the start of the path
+ * @see deleteEntityOnEnd
+ * @param {Entity} entity
+ */
+ deleteEntityOnStart(entity) {
+ assert(
+ entity === this.entityPath[0],
+ "Not actually the start entity (instead " + this.entityPath.indexOf(entity) + ")"
+ );
+
+ // Ok, first remove the entity
+ const beltComp = entity.components.Belt;
+ const beltLength = beltComp.getEffectiveLengthTiles();
+
+ DEBUG &&
+ logger.log(
+ "Deleting first entity on path with length",
+ this.entityPath.length,
+ "(reducing",
+ this.totalLength,
+ " by",
+ beltLength,
+ ")"
+ );
+ this.totalLength -= beltLength;
+ this.entityPath.shift();
+ this.onPathChanged();
+
+ DEBUG &&
+ logger.log(
+ " New path has length of",
+ this.totalLength,
+ "with",
+ this.entityPath.length,
+ "entities"
+ );
+
+ // This is just for sanity
+ beltComp.assignedPath = null;
+
+ // Clean up items
+ if (this.items.length === 0) {
+ // Simple case with no items, just update the first item spacing
+ this.spacingToFirstItem = this.totalLength;
+ } else {
+ // Simple case, we had no item on the beginning -> all good
+ if (this.spacingToFirstItem >= beltLength) {
+ DEBUG &&
+ logger.log(
+ " No item on the first place, so we can just adjust the spacing (spacing=",
+ this.spacingToFirstItem,
+ ") removed =",
+ beltLength
+ );
+ this.spacingToFirstItem -= beltLength;
+ } else {
+ // Welp, okay we need to drop all items which are < beltLength and adjust
+ // the other item offsets as well
+
+ DEBUG &&
+ logger.log(
+ " We have at least one item in the beginning, drop those and adjust spacing (first item @",
+ this.spacingToFirstItem,
+ ") since we removed",
+ beltLength,
+ "length from path"
+ );
+ DEBUG &&
+ logger.log(
+ " Items:",
+ this.items.map(i => i[0 /* nextDistance */])
+ );
+
+ // Find offset to first item
+ let itemOffset = this.spacingToFirstItem;
+ for (let i = 0; i < this.items.length; ++i) {
+ const item = this.items[i];
+ if (itemOffset <= beltLength) {
+ DEBUG &&
+ logger.log(
+ " -> Dropping item with index",
+ i,
+ "at",
+ itemOffset,
+ "since it was on the removed belt"
+ );
+ // This item must be dropped
+ this.items.splice(i, 1);
+ i -= 1;
+ itemOffset += item[0 /* nextDistance */];
+ continue;
+ } else {
+ // This item can be kept, thus its the first we know
+ break;
+ }
+ }
+
+ if (this.items.length > 0) {
+ DEBUG &&
+ logger.log(
+ " Offset of first non-dropped item was at:",
+ itemOffset,
+ "-> setting spacing to it (total length=",
+ this.totalLength,
+ ")"
+ );
+
+ this.spacingToFirstItem = itemOffset - beltLength;
+ assert(
+ this.spacingToFirstItem >= 0.0,
+ "Invalid spacing after delete on start: " + this.spacingToFirstItem
+ );
+ } else {
+ DEBUG && logger.log(" We dropped all items, simply set spacing to total length");
+ // We dropped all items, simple one
+ this.spacingToFirstItem = this.totalLength;
+ }
+ }
+ }
+
+ // Update bounds
+ this.worldBounds = this.computeBounds();
+
+ if (G_IS_DEV && globalConfig.debug.checkBeltPaths) {
+ this.debug_checkIntegrity("delete-on-start");
+ }
+ }
+
+ /**
+ * Extends the path by the given other path
+ * @param {BeltPath} otherPath
+ */
+ extendByPath(otherPath) {
+ assert(otherPath !== this, "Circular path dependency");
+
+ const entities = otherPath.entityPath;
+ DEBUG && logger.log("Extending path by other path, starting to add entities");
+
+ const oldLength = this.totalLength;
+
+ DEBUG && logger.log(" Adding", entities.length, "new entities, current length =", this.totalLength);
+
+ // First, append entities
+ for (let i = 0; i < entities.length; ++i) {
+ const entity = entities[i];
+ const beltComp = entity.components.Belt;
+
+ // Add to path and update references
+ this.entityPath.push(entity);
+ beltComp.assignedPath = this;
+
+ // Update our length
+ const additionalLength = beltComp.getEffectiveLengthTiles();
+ this.totalLength += additionalLength;
+ }
+
+ DEBUG &&
+ logger.log(
+ " Path is now",
+ this.entityPath.length,
+ "entities and has a length of",
+ this.totalLength
+ );
+
+ // Now, update the distance of our last item
+ if (this.items.length !== 0) {
+ const lastItem = this.items[this.items.length - 1];
+ lastItem[0 /* nextDistance */] += otherPath.spacingToFirstItem;
+ DEBUG &&
+ logger.log(
+ " Add distance to last item, effectively being",
+ lastItem[0 /* nextDistance */],
+ "now"
+ );
+ } else {
+ // Seems we have no items, update our first item distance
+ this.spacingToFirstItem = oldLength + otherPath.spacingToFirstItem;
+ DEBUG &&
+ logger.log(
+ " We had no items, so our new spacing to first is old length (",
+ oldLength,
+ ") plus others spacing to first (",
+ otherPath.spacingToFirstItem,
+ ") =",
+ this.spacingToFirstItem
+ );
+ }
+
+ DEBUG && logger.log(" Pushing", otherPath.items.length, "items from other path");
+
+ // Aaand push the other paths items
+ for (let i = 0; i < otherPath.items.length; ++i) {
+ const item = otherPath.items[i];
+ this.items.push([item[0 /* nextDistance */], item[1 /* item */]]);
+ }
+
+ // Update bounds
+ this.worldBounds = this.computeBounds();
+
+ this.onPathChanged();
+
+ if (G_IS_DEV && globalConfig.debug.checkBeltPaths) {
+ this.debug_checkIntegrity("extend-by-path");
+ }
+ }
+
+ /**
+ * Computes the total length of the path
+ * @returns {number}
+ */
+ computeTotalLength() {
+ let length = 0;
+ for (let i = 0; i < this.entityPath.length; ++i) {
+ const entity = this.entityPath[i];
+ length += entity.components.Belt.getEffectiveLengthTiles();
+ }
+ return length;
+ }
+
+ /**
+ * Performs one tick
+ */
+ update() {
+ if (G_IS_DEV && globalConfig.debug.checkBeltPaths) {
+ this.debug_checkIntegrity("pre-update");
+ }
+
+ // Skip empty belts
+ if (this.items.length === 0) {
+ return;
+ }
+
+ // Divide by item spacing on belts since we use throughput and not speed
+ let beltSpeed =
+ this.root.hubGoals.getBeltBaseSpeed() *
+ this.root.dynamicTickrate.deltaSeconds *
+ globalConfig.itemSpacingOnBelts;
+
+ if (G_IS_DEV && globalConfig.debug.instantBelts) {
+ beltSpeed *= 100;
+ }
+
+ // Store whether this is the first item we processed, so premature
+ // item ejection is available
+ let isFirstItemProcessed = true;
+
+ // Store how much velocity (strictly its distance, not velocity) we have to distribute over all items
+ let remainingVelocity = beltSpeed;
+
+ // Store the last item we processed, so we can skip clashed ones
+ let lastItemProcessed;
+
+ for (lastItemProcessed = this.items.length - 1; lastItemProcessed >= 0; --lastItemProcessed) {
+ const nextDistanceAndItem = this.items[lastItemProcessed];
+
+ // Compute how much spacing we need at least
+ const minimumSpacing =
+ lastItemProcessed === this.items.length - 1 ? 0 : globalConfig.itemSpacingOnBelts;
+
+ // Compute how much we can advance
+ let clampedProgress = nextDistanceAndItem[0 /* nextDistance */] - minimumSpacing;
+
+ // Make sure we don't advance more than the remaining velocity has stored
+ if (remainingVelocity < clampedProgress) {
+ clampedProgress = remainingVelocity;
+ }
+
+ // Make sure we don't advance back
+ if (clampedProgress < 0) {
+ clampedProgress = 0;
+ }
+
+ // Reduce our velocity by the amount we consumed
+ remainingVelocity -= clampedProgress;
+
+ // Reduce the spacing
+ nextDistanceAndItem[0 /* nextDistance */] -= clampedProgress;
+
+ // Advance all items behind by the progress we made
+ this.spacingToFirstItem += clampedProgress;
+
+ // If the last item can be ejected, eject it and reduce the spacing, because otherwise
+ // we lose velocity
+ if (isFirstItemProcessed && nextDistanceAndItem[0 /* nextDistance */] < 1e-7) {
+ // Store how much velocity we "lost" because we bumped the item to the end of the
+ // belt but couldn't move it any farther. We need this to tell the item acceptor
+ // animation to start a tad later, so everything matches up. Yes I'm a perfectionist.
+ const excessVelocity = beltSpeed - clampedProgress;
+
+ // Try to directly get rid of the item
+ if (
+ this.boundAcceptor &&
+ this.boundAcceptor(nextDistanceAndItem[1 /* item */], excessVelocity)
+ ) {
+ this.items.pop();
+
+ const itemBehind = this.items[lastItemProcessed - 1];
+ if (itemBehind && this.numCompressedItemsAfterFirstItem > 0) {
+ // So, with the next tick we will skip this item, but it actually has the potential
+ // to process farther -> If we don't advance here, we loose a tiny bit of progress
+ // every tick which causes the belt to be slower than it actually is.
+ // Also see #999
+ const fixupProgress = Math.max(
+ 0,
+ Math.min(remainingVelocity, itemBehind[0 /* nextDistance */])
+ );
+
+ // See above
+ itemBehind[0 /* nextDistance */] -= fixupProgress;
+ remainingVelocity -= fixupProgress;
+ this.spacingToFirstItem += fixupProgress;
+ }
+
+ // Reduce the number of compressed items since the first item no longer exists
+ this.numCompressedItemsAfterFirstItem = Math.max(
+ 0,
+ this.numCompressedItemsAfterFirstItem - 1
+ );
+ }
+ }
+
+ if (isFirstItemProcessed) {
+ // Skip N null items after first items
+ lastItemProcessed -= this.numCompressedItemsAfterFirstItem;
+ }
+
+ isFirstItemProcessed = false;
+ if (remainingVelocity < 1e-7) {
+ break;
+ }
+ }
+
+ // Compute compressed item count
+ this.numCompressedItemsAfterFirstItem = Math.max(
+ 0,
+ this.numCompressedItemsAfterFirstItem,
+ this.items.length - 2 - lastItemProcessed
+ );
+
+ // Check if we have an item which is ready to be emitted
+ const lastItem = this.items[this.items.length - 1];
+ if (lastItem && lastItem[0 /* nextDistance */] === 0) {
+ if (this.boundAcceptor && this.boundAcceptor(lastItem[1 /* item */])) {
+ this.items.pop();
+ this.numCompressedItemsAfterFirstItem = Math.max(
+ 0,
+ this.numCompressedItemsAfterFirstItem - 1
+ );
+ }
+ }
+
+ if (G_IS_DEV && globalConfig.debug.checkBeltPaths) {
+ this.debug_checkIntegrity("post-update");
+ }
+ }
+
+ /**
+ * Computes a world space position from the given progress
+ * @param {number} progress
+ * @returns {Vector}
+ */
+ computePositionFromProgress(progress) {
+ let currentLength = 0;
+
+ // floating point issues ..
+ assert(progress <= this.totalLength + 0.02, "Progress too big: " + progress);
+
+ for (let i = 0; i < this.entityPath.length; ++i) {
+ const beltComp = this.entityPath[i].components.Belt;
+ const localLength = beltComp.getEffectiveLengthTiles();
+
+ if (currentLength + localLength >= progress || i === this.entityPath.length - 1) {
+ // Min required here due to floating point issues
+ const localProgress = Math.min(1.0, progress - currentLength);
+
+ assert(localProgress >= 0.0, "Invalid local progress: " + localProgress);
+ const localSpace = beltComp.transformBeltToLocalSpace(localProgress);
+ return this.entityPath[i].components.StaticMapEntity.localTileToWorld(localSpace);
+ }
+ currentLength += localLength;
+ }
+
+ assert(false, "invalid progress: " + progress + " (max: " + this.totalLength + ")");
+ }
+
+ /**
+ *
+ * @param {DrawParameters} parameters
+ */
+ drawDebug(parameters) {
+ if (!parameters.visibleRect.containsRect(this.worldBounds)) {
+ return;
+ }
+
+ parameters.context.fillStyle = "#d79a25";
+ parameters.context.strokeStyle = "#d79a25";
+ parameters.context.beginPath();
+
+ for (let i = 0; i < this.entityPath.length; ++i) {
+ const entity = this.entityPath[i];
+ const pos = entity.components.StaticMapEntity;
+ const worldPos = pos.origin.toWorldSpaceCenterOfTile();
+
+ if (i === 0) {
+ parameters.context.moveTo(worldPos.x, worldPos.y);
+ } else {
+ parameters.context.lineTo(worldPos.x, worldPos.y);
+ }
+ }
+ parameters.context.stroke();
+
+ // Items
+ let progress = this.spacingToFirstItem;
+ for (let i = 0; i < this.items.length; ++i) {
+ const nextDistanceAndItem = this.items[i];
+ const worldPos = this.computePositionFromProgress(progress).toWorldSpaceCenterOfTile();
+ parameters.context.fillStyle = "#268e4d";
+ parameters.context.beginPath();
+ parameters.context.roundRect(worldPos.x - 5, worldPos.y - 5, 10, 10, 3);
+ parameters.context.fill();
+ parameters.context.font = "6px GameFont";
+ parameters.context.fillStyle = "#111";
+ parameters.context.fillText(
+ "" + round4Digits(nextDistanceAndItem[0 /* nextDistance */]),
+ worldPos.x + 5,
+ worldPos.y + 2
+ );
+ progress += nextDistanceAndItem[0 /* nextDistance */];
+
+ if (this.items.length - 1 - this.numCompressedItemsAfterFirstItem === i) {
+ parameters.context.fillStyle = "red";
+ parameters.context.fillRect(worldPos.x + 5, worldPos.y, 20, 3);
+ }
+ }
+
+ for (let i = 0; i < this.entityPath.length; ++i) {
+ const entity = this.entityPath[i];
+ parameters.context.fillStyle = "#d79a25";
+ const pos = entity.components.StaticMapEntity;
+ const worldPos = pos.origin.toWorldSpaceCenterOfTile();
+ parameters.context.beginCircle(worldPos.x, worldPos.y, i === 0 ? 5 : 3);
+ parameters.context.fill();
+ }
+
+ for (let progress = 0; progress <= this.totalLength + 0.01; progress += 0.2) {
+ const worldPos = this.computePositionFromProgress(progress).toWorldSpaceCenterOfTile();
+ parameters.context.fillStyle = "red";
+ parameters.context.beginCircle(worldPos.x, worldPos.y, 1);
+ parameters.context.fill();
+ }
+
+ const firstItemIndicator = this.computePositionFromProgress(
+ this.spacingToFirstItem
+ ).toWorldSpaceCenterOfTile();
+ parameters.context.fillStyle = "purple";
+ parameters.context.fillRect(firstItemIndicator.x - 3, firstItemIndicator.y - 1, 6, 2);
+ }
+
+ /**
+ * Checks if this belt path should render simplified
+ */
+ checkIsPotatoMode() {
+ // POTATO Mode: Only show items when belt is hovered
+ if (!this.root.app.settings.getAllSettings().simplifiedBelts) {
+ return false;
+ }
+
+ if (this.root.currentLayer !== "regular") {
+ // Not in regular layer
+ return true;
+ }
+
+ const mousePos = this.root.app.mousePosition;
+ if (!mousePos) {
+ // Mouse not registered
+ return true;
+ }
+
+ const tile = this.root.camera.screenToWorld(mousePos).toTileSpace();
+ const contents = this.root.map.getLayerContentXY(tile.x, tile.y, "regular");
+ if (!contents || !contents.components.Belt) {
+ // Nothing below
+ return true;
+ }
+
+ if (contents.components.Belt.assignedPath !== this) {
+ // Not this path
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Draws the path
+ * @param {DrawParameters} parameters
+ */
+ draw(parameters) {
+ if (!parameters.visibleRect.containsRect(this.worldBounds)) {
+ return;
+ }
+
+ if (this.items.length === 0) {
+ // Early out
+ return;
+ }
+
+ if (this.checkIsPotatoMode()) {
+ const firstItem = this.items[0];
+ if (this.entityPath.length > 1 && firstItem) {
+ const medianBeltIndex = clamp(
+ Math.round(this.entityPath.length / 2 - 1),
+ 0,
+ this.entityPath.length - 1
+ );
+ const medianBelt = this.entityPath[medianBeltIndex];
+ const beltComp = medianBelt.components.Belt;
+ const staticComp = medianBelt.components.StaticMapEntity;
+ const centerPosLocal = beltComp.transformBeltToLocalSpace(
+ this.entityPath.length % 2 === 0 ? beltComp.getEffectiveLengthTiles() : 0.5
+ );
+ const centerPos = staticComp.localTileToWorld(centerPosLocal).toWorldSpaceCenterOfTile();
+
+ parameters.context.globalAlpha = 0.5;
+ firstItem[1 /* item */].drawItemCenteredClipped(centerPos.x, centerPos.y, parameters);
+ parameters.context.globalAlpha = 1;
+ }
+
+ return;
+ }
+
+ let currentItemPos = this.spacingToFirstItem;
+ let currentItemIndex = 0;
+
+ let trackPos = 0.0;
+
+ /**
+ * @type {Array<[Vector, BaseItem]>}
+ */
+ let drawStack = [];
+ let drawStackProp = "";
+
+ // Iterate whole track and check items
+ for (let i = 0; i < this.entityPath.length; ++i) {
+ const entity = this.entityPath[i];
+ const beltComp = entity.components.Belt;
+ const beltLength = beltComp.getEffectiveLengthTiles();
+
+ // Check if the current items are on the belt
+ while (trackPos + beltLength >= currentItemPos - 1e-5) {
+ // It's on the belt, render it now
+ const staticComp = entity.components.StaticMapEntity;
+ assert(
+ currentItemPos - trackPos >= 0,
+ "invalid track pos: " + currentItemPos + " vs " + trackPos + " (l =" + beltLength + ")"
+ );
+
+ const localPos = beltComp.transformBeltToLocalSpace(currentItemPos - trackPos);
+ const worldPos = staticComp.localTileToWorld(localPos).toWorldSpaceCenterOfTile();
+
+ const distanceAndItem = this.items[currentItemIndex];
+ const item = distanceAndItem[1 /* item */];
+ const nextItemDistance = distanceAndItem[0 /* nextDistance */];
+
+ if (
+ !parameters.visibleRect.containsCircle(
+ worldPos.x,
+ worldPos.y,
+ globalConfig.defaultItemDiameter
+ )
+ ) {
+ // this one isn't visible, do not append it
+ // Start a new stack
+ this.drawDrawStack(drawStack, parameters, drawStackProp);
+ drawStack = [];
+ drawStackProp = "";
+ } else {
+ if (drawStack.length > 1) {
+ // Check if we can append to the stack, since its already a stack of two same items
+ const referenceItem = drawStack[0];
+
+ if (
+ referenceItem[1].equals(item) &&
+ Math.abs(referenceItem[0][drawStackProp] - worldPos[drawStackProp]) < 0.001
+ ) {
+ // Will continue stack
+ } else {
+ // Start a new stack, since item doesn't follow in row
+ this.drawDrawStack(drawStack, parameters, drawStackProp);
+ drawStack = [];
+ drawStackProp = "";
+ }
+ } else if (drawStack.length === 1) {
+ const firstItem = drawStack[0];
+
+ // Check if we can make it a stack
+ if (firstItem[1 /* item */].equals(item)) {
+ // Same item, check if it is either horizontal or vertical
+ const startPos = firstItem[0 /* pos */];
+
+ if (Math.abs(startPos.x - worldPos.x) < 0.001) {
+ drawStackProp = "x";
+ } else if (Math.abs(startPos.y - worldPos.y) < 0.001) {
+ drawStackProp = "y";
+ } else {
+ // Start a new stack
+ this.drawDrawStack(drawStack, parameters, drawStackProp);
+ drawStack = [];
+ drawStackProp = "";
+ }
+ } else {
+ // Start a new stack, since item doesn't equal
+ this.drawDrawStack(drawStack, parameters, drawStackProp);
+ drawStack = [];
+ drawStackProp = "";
+ }
+ } else {
+ // First item of stack, do nothing
+ }
+
+ drawStack.push([worldPos, item]);
+ }
+
+ // Check for the next item
+ currentItemPos += nextItemDistance;
+ ++currentItemIndex;
+
+ if (
+ nextItemDistance > globalConfig.itemSpacingOnBelts + 0.001 ||
+ drawStack.length > globalConfig.maxBeltShapeBundleSize
+ ) {
+ // If next item is not directly following, abort drawing
+ this.drawDrawStack(drawStack, parameters, drawStackProp);
+ drawStack = [];
+ drawStackProp = "";
+ }
+
+ if (currentItemIndex >= this.items.length) {
+ // We rendered all items
+
+ this.drawDrawStack(drawStack, parameters, drawStackProp);
+ return;
+ }
+ }
+
+ trackPos += beltLength;
+ }
+
+ this.drawDrawStack(drawStack, parameters, drawStackProp);
+ }
+
+ /**
+ *
+ * @param {HTMLCanvasElement} canvas
+ * @param {CanvasRenderingContext2D} context
+ * @param {number} w
+ * @param {number} h
+ * @param {number} dpi
+ * @param {object} param0
+ * @param {string} param0.direction
+ * @param {Array<[Vector, BaseItem]>} param0.stack
+ * @param {GameRoot} param0.root
+ * @param {number} param0.zoomLevel
+ */
+ drawShapesInARow(canvas, context, w, h, dpi, { direction, stack, root, zoomLevel }) {
+ context.scale(dpi, dpi);
+
+ if (G_IS_DEV && globalConfig.debug.showShapeGrouping) {
+ context.fillStyle = "rgba(0, 0, 255, 0.5)";
+ context.fillRect(0, 0, w, h);
+ }
+
+ const parameters = new DrawParameters({
+ context,
+ desiredAtlasScale: ORIGINAL_SPRITE_SCALE,
+ root,
+ visibleRect: new Rectangle(-1000, -1000, 2000, 2000),
+ zoomLevel,
+ });
+
+ const itemSize = globalConfig.itemSpacingOnBelts * globalConfig.tileSize;
+ const item = stack[0];
+ const pos = new Vector(itemSize / 2, itemSize / 2);
+
+ for (let i = 0; i < stack.length; i++) {
+ item[1].drawItemCenteredClipped(pos.x, pos.y, parameters, globalConfig.defaultItemDiameter);
+ pos[direction] += globalConfig.itemSpacingOnBelts * globalConfig.tileSize;
+ }
+ }
+
+ /**
+ * @param {Array<[Vector, BaseItem]>} stack
+ * @param {DrawParameters} parameters
+ */
+ drawDrawStack(stack, parameters, directionProp) {
+ if (stack.length === 0) {
+ return;
+ }
+
+ const firstItem = stack[0];
+ const firstItemPos = firstItem[0];
+ if (stack.length === 1) {
+ firstItem[1].drawItemCenteredClipped(
+ firstItemPos.x,
+ firstItemPos.y,
+ parameters,
+ globalConfig.defaultItemDiameter
+ );
+ return;
+ }
+
+ const itemSize = globalConfig.itemSpacingOnBelts * globalConfig.tileSize;
+ const inverseDirection = directionProp === "x" ? "y" : "x";
+
+ const dimensions = new Vector(itemSize, itemSize);
+ dimensions[inverseDirection] *= stack.length;
+
+ const directionVector = firstItemPos.copy().sub(stack[1][0]);
+
+ const dpi = smoothenDpi(globalConfig.shapesSharpness * parameters.zoomLevel);
+
+ const sprite = this.root.buffers.getForKey({
+ key: "beltpaths",
+ subKey:
+ "stack-" +
+ directionProp +
+ "-" +
+ dpi +
+ "#" +
+ stack.length +
+ "#" +
+ firstItem[1].getItemType() +
+ "#" +
+ firstItem[1].serialize(),
+ dpi,
+ w: dimensions.x,
+ h: dimensions.y,
+ redrawMethod: this.drawShapesInARow.bind(this),
+ additionalParams: {
+ direction: inverseDirection,
+ stack,
+ root: this.root,
+ zoomLevel: parameters.zoomLevel,
+ },
+ });
+
+ const anchor = directionVector[inverseDirection] < 0 ? firstItem : stack[stack.length - 1];
+
+ parameters.context.drawImage(
+ sprite,
+ anchor[0].x - itemSize / 2,
+ anchor[0].y - itemSize / 2,
+ dimensions.x,
+ dimensions.y
+ );
+ }
+}
diff --git a/src/js/game/blueprint.js b/src/js/game/blueprint.js
index 14848485..34e4ed23 100644
--- a/src/js/game/blueprint.js
+++ b/src/js/game/blueprint.js
@@ -3,7 +3,6 @@ import { DrawParameters } from "../core/draw_parameters";
import { findNiceIntegerValue } from "../core/utils";
import { Vector } from "../core/vector";
import { Entity } from "./entity";
-import { ACHIEVEMENTS } from "../platform/achievement_provider";
import { GameRoot } from "./root";
export class Blueprint {
@@ -88,7 +87,13 @@ export class Blueprint {
parameters.context.globalAlpha = 1;
}
- staticComp.drawSpriteOnBoundsClipped(parameters, staticComp.getBlueprintSprite(), 0, newPos);
+ staticComp.drawSpriteOnBoundsClipped(
+ parameters,
+ staticComp.getBlueprintSprite(),
+ 0,
+ newPos,
+ true
+ );
}
parameters.context.globalAlpha = 1;
}
@@ -172,13 +177,6 @@ export class Blueprint {
count++;
}
- root.signals.bulkAchievementCheck.dispatch(
- ACHIEVEMENTS.placeBlueprint,
- count,
- ACHIEVEMENTS.placeBp1000,
- count
- );
-
return count !== 0;
});
});
diff --git a/src/js/game/building_codes.js b/src/js/game/building_codes.js
index 1d178daf..7dd853ba 100644
--- a/src/js/game/building_codes.js
+++ b/src/js/game/building_codes.js
@@ -1,109 +1,109 @@
-/* typehints:start */
-import { MetaBuilding } from "./meta_building";
-import { AtlasSprite } from "../core/sprites";
-import { Vector } from "../core/vector";
-/* typehints:end */
-
-import { gMetaBuildingRegistry } from "../core/global_registries";
-
-/**
- * @typedef {{
- * metaClass: typeof MetaBuilding,
- * metaInstance?: MetaBuilding,
- * variant?: string,
- * rotationVariant?: number,
- * tileSize?: Vector,
- * sprite?: AtlasSprite,
- * blueprintSprite?: AtlasSprite,
- * silhouetteColor?: string
- * }} BuildingVariantIdentifier
- */
-
-/**
- * Stores a lookup table for all building variants (for better performance)
- * @type {Object}
- */
-export const gBuildingVariants = {
- // Set later
-};
-
-/**
- * Mapping from 'metaBuildingId/variant/rotationVariant' to building code
- * @type {Map}
- */
-const variantsCache = new Map();
-
-/**
- * Registers a new variant
- * @param {number|string} code
- * @param {typeof MetaBuilding} meta
- * @param {string} variant
- * @param {number} rotationVariant
- */
-export function registerBuildingVariant(
- code,
- meta,
- variant = "default" /* @TODO: Circular dependency, actually its defaultBuildingVariant */,
- rotationVariant = 0
-) {
- assert(!gBuildingVariants[code], "Duplicate id: " + code);
- gBuildingVariants[code] = {
- metaClass: meta,
- metaInstance: gMetaBuildingRegistry.findByClass(meta),
- variant,
- rotationVariant,
- // @ts-ignore
- tileSize: new meta().getDimensions(variant),
- };
-}
-
-/**
- * Hashes the combination of buildng, variant and rotation variant
- * @param {string} buildingId
- * @param {string} variant
- * @param {number} rotationVariant
- * @returns
- */
-function generateBuildingHash(buildingId, variant, rotationVariant) {
- return buildingId + "/" + variant + "/" + rotationVariant;
-}
-
-/**
- *
- * @param {string|number} code
- * @returns {BuildingVariantIdentifier}
- */
-export function getBuildingDataFromCode(code) {
- assert(gBuildingVariants[code], "Invalid building code: " + code);
- return gBuildingVariants[code];
-}
-
-/**
- * Builds the cache for the codes
- */
-export function buildBuildingCodeCache() {
- for (const code in gBuildingVariants) {
- const data = gBuildingVariants[code];
- const hash = generateBuildingHash(data.metaInstance.getId(), data.variant, data.rotationVariant);
- variantsCache.set(hash, isNaN(+code) ? code : +code);
- }
-}
-
-/**
- * Finds the code for a given variant
- * @param {MetaBuilding} metaBuilding
- * @param {string} variant
- * @param {number} rotationVariant
- * @returns {number|string}
- */
-export function getCodeFromBuildingData(metaBuilding, variant, rotationVariant) {
- const hash = generateBuildingHash(metaBuilding.getId(), variant, rotationVariant);
- const result = variantsCache.get(hash);
- if (G_IS_DEV) {
- if (!result) {
- console.warn("Known hashes:", Array.from(variantsCache.keys()));
- assertAlways(false, "Building not found by data: " + hash);
- }
- }
- return result;
-}
+/* typehints:start */
+import { MetaBuilding } from "./meta_building";
+import { AtlasSprite } from "../core/sprites";
+import { Vector } from "../core/vector";
+/* typehints:end */
+
+import { gMetaBuildingRegistry } from "../core/global_registries";
+
+/**
+ * @typedef {{
+ * metaClass: typeof MetaBuilding,
+ * metaInstance?: MetaBuilding,
+ * variant?: string,
+ * rotationVariant?: number,
+ * tileSize?: Vector,
+ * sprite?: AtlasSprite,
+ * blueprintSprite?: AtlasSprite,
+ * silhouetteColor?: string
+ * }} BuildingVariantIdentifier
+ */
+
+/**
+ * Stores a lookup table for all building variants (for better performance)
+ * @type {Object}
+ */
+export const gBuildingVariants = {
+ // Set later
+};
+
+/**
+ * Mapping from 'metaBuildingId/variant/rotationVariant' to building code
+ * @type {Map}
+ */
+const variantsCache = new Map();
+
+/**
+ * Registers a new variant
+ * @param {number|string} code
+ * @param {typeof MetaBuilding} meta
+ * @param {string} variant
+ * @param {number} rotationVariant
+ */
+export function registerBuildingVariant(
+ code,
+ meta,
+ variant = "default" /* @TODO: Circular dependency, actually its defaultBuildingVariant */,
+ rotationVariant = 0
+) {
+ assert(!gBuildingVariants[code], "Duplicate id: " + code);
+ gBuildingVariants[code] = {
+ metaClass: meta,
+ metaInstance: gMetaBuildingRegistry.findByClass(meta),
+ variant,
+ rotationVariant,
+ // @ts-ignore
+ tileSize: new meta().getDimensions(variant),
+ };
+}
+
+/**
+ * Hashes the combination of buildng, variant and rotation variant
+ * @param {string} buildingId
+ * @param {string} variant
+ * @param {number} rotationVariant
+ * @returns
+ */
+function generateBuildingHash(buildingId, variant, rotationVariant) {
+ return buildingId + "/" + variant + "/" + rotationVariant;
+}
+
+/**
+ *
+ * @param {string|number} code
+ * @returns {BuildingVariantIdentifier}
+ */
+export function getBuildingDataFromCode(code) {
+ assert(gBuildingVariants[code], "Invalid building code: " + code);
+ return gBuildingVariants[code];
+}
+
+/**
+ * Builds the cache for the codes
+ */
+export function buildBuildingCodeCache() {
+ for (const code in gBuildingVariants) {
+ const data = gBuildingVariants[code];
+ const hash = generateBuildingHash(data.metaInstance.getId(), data.variant, data.rotationVariant);
+ variantsCache.set(hash, isNaN(+code) ? code : +code);
+ }
+}
+
+/**
+ * Finds the code for a given variant
+ * @param {MetaBuilding} metaBuilding
+ * @param {string} variant
+ * @param {number} rotationVariant
+ * @returns {number|string}
+ */
+export function getCodeFromBuildingData(metaBuilding, variant, rotationVariant) {
+ const hash = generateBuildingHash(metaBuilding.getId(), variant, rotationVariant);
+ const result = variantsCache.get(hash);
+ if (G_IS_DEV) {
+ if (!result) {
+ console.warn("Known hashes:", Array.from(variantsCache.keys()));
+ assertAlways(false, "Building not found by data: " + hash);
+ }
+ }
+ return result;
+}
diff --git a/src/js/game/buildings/analyzer.js b/src/js/game/buildings/analyzer.js
index 13597d7b..68cfbfa2 100644
--- a/src/js/game/buildings/analyzer.js
+++ b/src/js/game/buildings/analyzer.js
@@ -1,88 +1,88 @@
-import { generateMatrixRotations } from "../../core/utils";
-import { enumDirection, Vector } from "../../core/vector";
-import { enumLogicGateType, LogicGateComponent } from "../components/logic_gate";
-import { enumPinSlotType, WiredPinsComponent } from "../components/wired_pins";
-import { Entity } from "../entity";
-import { defaultBuildingVariant, MetaBuilding } from "../meta_building";
-import { GameRoot } from "../root";
-import { enumHubGoalRewards } from "../tutorial_goals";
-
-const overlayMatrix = generateMatrixRotations([1, 1, 0, 1, 1, 1, 0, 1, 0]);
-
-export class MetaAnalyzerBuilding extends MetaBuilding {
- constructor() {
- super("analyzer");
- }
-
- static getAllVariantCombinations() {
- return [
- {
- internalId: 43,
- variant: defaultBuildingVariant,
- },
- ];
- }
-
- getSilhouetteColor() {
- return "#3a52bc";
- }
-
- /**
- * @param {GameRoot} root
- */
- getIsUnlocked(root) {
- return root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_virtual_processing);
- }
-
- /** @returns {"wires"} **/
- getLayer() {
- return "wires";
- }
-
- getDimensions() {
- return new Vector(1, 1);
- }
-
- getRenderPins() {
- // We already have it included
- return false;
- }
-
- getSpecialOverlayRenderMatrix(rotation, rotationVariant, variant) {
- return overlayMatrix[rotation];
- }
-
- /**
- * Creates the entity at the given location
- * @param {Entity} entity
- */
- setupEntityComponents(entity) {
- entity.addComponent(
- new WiredPinsComponent({
- slots: [
- {
- pos: new Vector(0, 0),
- direction: enumDirection.left,
- type: enumPinSlotType.logicalEjector,
- },
- {
- pos: new Vector(0, 0),
- direction: enumDirection.right,
- type: enumPinSlotType.logicalEjector,
- },
- {
- pos: new Vector(0, 0),
- direction: enumDirection.bottom,
- type: enumPinSlotType.logicalAcceptor,
- },
- ],
- })
- );
-
- entity.addComponent(
- new LogicGateComponent({
- type: enumLogicGateType.analyzer,
- })
- );
- }
-}
+import { generateMatrixRotations } from "../../core/utils";
+import { enumDirection, Vector } from "../../core/vector";
+import { enumLogicGateType, LogicGateComponent } from "../components/logic_gate";
+import { enumPinSlotType, WiredPinsComponent } from "../components/wired_pins";
+import { Entity } from "../entity";
+import { defaultBuildingVariant, MetaBuilding } from "../meta_building";
+import { GameRoot } from "../root";
+import { enumHubGoalRewards } from "../tutorial_goals";
+
+const overlayMatrix = generateMatrixRotations([1, 1, 0, 1, 1, 1, 0, 1, 0]);
+
+export class MetaAnalyzerBuilding extends MetaBuilding {
+ constructor() {
+ super("analyzer");
+ }
+
+ static getAllVariantCombinations() {
+ return [
+ {
+ internalId: 43,
+ variant: defaultBuildingVariant,
+ },
+ ];
+ }
+
+ getSilhouetteColor() {
+ return "#3a52bc";
+ }
+
+ /**
+ * @param {GameRoot} root
+ */
+ getIsUnlocked(root) {
+ return root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_virtual_processing);
+ }
+
+ /** @returns {"wires"} **/
+ getLayer() {
+ return "wires";
+ }
+
+ getDimensions() {
+ return new Vector(1, 1);
+ }
+
+ getRenderPins() {
+ // We already have it included
+ return false;
+ }
+
+ getSpecialOverlayRenderMatrix(rotation, rotationVariant, variant) {
+ return overlayMatrix[rotation];
+ }
+
+ /**
+ * Creates the entity at the given location
+ * @param {Entity} entity
+ */
+ setupEntityComponents(entity) {
+ entity.addComponent(
+ new WiredPinsComponent({
+ slots: [
+ {
+ pos: new Vector(0, 0),
+ direction: enumDirection.left,
+ type: enumPinSlotType.logicalEjector,
+ },
+ {
+ pos: new Vector(0, 0),
+ direction: enumDirection.right,
+ type: enumPinSlotType.logicalEjector,
+ },
+ {
+ pos: new Vector(0, 0),
+ direction: enumDirection.bottom,
+ type: enumPinSlotType.logicalAcceptor,
+ },
+ ],
+ })
+ );
+
+ entity.addComponent(
+ new LogicGateComponent({
+ type: enumLogicGateType.analyzer,
+ })
+ );
+ }
+}
diff --git a/src/js/game/buildings/balancer.js b/src/js/game/buildings/balancer.js
index ce685a9a..181bcb87 100644
--- a/src/js/game/buildings/balancer.js
+++ b/src/js/game/buildings/balancer.js
@@ -1,261 +1,261 @@
-import { enumDirection, Vector } from "../../core/vector";
-import { ItemAcceptorComponent } from "../components/item_acceptor";
-import { ItemEjectorComponent } from "../components/item_ejector";
-import { enumItemProcessorTypes, ItemProcessorComponent } from "../components/item_processor";
-import { Entity } from "../entity";
-import { MetaBuilding, defaultBuildingVariant } from "../meta_building";
-import { GameRoot } from "../root";
-import { enumHubGoalRewards } from "../tutorial_goals";
-import { T } from "../../translations";
-import { formatItemsPerSecond, generateMatrixRotations } from "../../core/utils";
-import { BeltUnderlaysComponent } from "../components/belt_underlays";
-
-/** @enum {string} */
-export const enumBalancerVariants = {
- merger: "merger",
- mergerInverse: "merger-inverse",
- splitter: "splitter",
- splitterInverse: "splitter-inverse",
-};
-
-const overlayMatrices = {
- [defaultBuildingVariant]: null,
- [enumBalancerVariants.merger]: generateMatrixRotations([0, 1, 0, 0, 1, 1, 0, 1, 0]),
- [enumBalancerVariants.mergerInverse]: generateMatrixRotations([0, 1, 0, 1, 1, 0, 0, 1, 0]),
- [enumBalancerVariants.splitter]: generateMatrixRotations([0, 1, 0, 0, 1, 1, 0, 1, 0]),
- [enumBalancerVariants.splitterInverse]: generateMatrixRotations([0, 1, 0, 1, 1, 0, 0, 1, 0]),
-};
-
-export class MetaBalancerBuilding extends MetaBuilding {
- constructor() {
- super("balancer");
- }
-
- static getAllVariantCombinations() {
- return [
- {
- internalId: 4,
- variant: defaultBuildingVariant,
- },
- {
- internalId: 5,
- variant: enumBalancerVariants.merger,
- },
- {
- internalId: 6,
- variant: enumBalancerVariants.mergerInverse,
- },
- {
- internalId: 47,
- variant: enumBalancerVariants.splitter,
- },
- {
- internalId: 48,
- variant: enumBalancerVariants.splitterInverse,
- },
- ];
- }
-
- getDimensions(variant) {
- switch (variant) {
- case defaultBuildingVariant:
- return new Vector(2, 1);
- case enumBalancerVariants.merger:
- case enumBalancerVariants.mergerInverse:
- case enumBalancerVariants.splitter:
- case enumBalancerVariants.splitterInverse:
- return new Vector(1, 1);
- default:
- assertAlways(false, "Unknown balancer variant: " + variant);
- }
- }
-
- /**
- * @param {number} rotation
- * @param {number} rotationVariant
- * @param {string} variant
- * @param {Entity} entity
- * @returns {Array|null}
- */
- getSpecialOverlayRenderMatrix(rotation, rotationVariant, variant, entity) {
- const matrix = overlayMatrices[variant];
- if (matrix) {
- return matrix[rotation];
- }
- return null;
- }
-
- /**
- * @param {GameRoot} root
- * @param {string} variant
- * @returns {Array<[string, string]>}
- */
- getAdditionalStatistics(root, variant) {
- if (root.gameMode.throughputDoesNotMatter()) {
- return [];
- }
-
- let speedMultiplier = 2;
- switch (variant) {
- case enumBalancerVariants.merger:
- case enumBalancerVariants.mergerInverse:
- case enumBalancerVariants.splitter:
- case enumBalancerVariants.splitterInverse:
- speedMultiplier = 1;
- }
-
- const speed =
- (root.hubGoals.getProcessorBaseSpeed(enumItemProcessorTypes.balancer) / 2) * speedMultiplier;
- return [[T.ingame.buildingPlacement.infoTexts.speed, formatItemsPerSecond(speed)]];
- }
-
- getSilhouetteColor() {
- return "#555759";
- }
-
- /**
- * @param {GameRoot} root
- */
- getAvailableVariants(root) {
- const deterministic = root.gameMode.getIsDeterministic();
-
- let available = deterministic ? [] : [defaultBuildingVariant];
-
- if (!deterministic && root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_merger)) {
- available.push(enumBalancerVariants.merger, enumBalancerVariants.mergerInverse);
- }
-
- if (root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_splitter)) {
- available.push(enumBalancerVariants.splitter, enumBalancerVariants.splitterInverse);
- }
-
- return available;
- }
-
- /**
- * @param {GameRoot} root
- */
- getIsUnlocked(root) {
- return root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_balancer);
- }
-
- /**
- * Creates the entity at the given location
- * @param {Entity} entity
- */
- setupEntityComponents(entity) {
- entity.addComponent(
- new ItemAcceptorComponent({
- slots: [], // set later
- })
- );
-
- entity.addComponent(
- new ItemProcessorComponent({
- inputsPerCharge: 1,
- processorType: enumItemProcessorTypes.balancer,
- })
- );
-
- entity.addComponent(
- new ItemEjectorComponent({
- slots: [], // set later
- renderFloatingItems: false,
- })
- );
-
- entity.addComponent(new BeltUnderlaysComponent({ underlays: [] }));
- }
-
- /**
- *
- * @param {Entity} entity
- * @param {number} rotationVariant
- * @param {string} variant
- */
- updateVariants(entity, rotationVariant, variant) {
- switch (variant) {
- case defaultBuildingVariant: {
- entity.components.ItemAcceptor.setSlots([
- {
- pos: new Vector(0, 0),
- direction: enumDirection.bottom,
- },
- {
- pos: new Vector(1, 0),
- direction: enumDirection.bottom,
- },
- ]);
-
- entity.components.ItemEjector.setSlots([
- { pos: new Vector(0, 0), direction: enumDirection.top },
- { pos: new Vector(1, 0), direction: enumDirection.top },
- ]);
-
- entity.components.BeltUnderlays.underlays = [
- { pos: new Vector(0, 0), direction: enumDirection.top },
- { pos: new Vector(1, 0), direction: enumDirection.top },
- ];
-
- break;
- }
- case enumBalancerVariants.merger:
- case enumBalancerVariants.mergerInverse: {
- entity.components.ItemAcceptor.setSlots([
- {
- pos: new Vector(0, 0),
- direction: enumDirection.bottom,
- },
- {
- pos: new Vector(0, 0),
- direction:
- variant === enumBalancerVariants.mergerInverse
- ? enumDirection.left
- : enumDirection.right,
- },
- ]);
-
- entity.components.ItemEjector.setSlots([
- { pos: new Vector(0, 0), direction: enumDirection.top },
- ]);
-
- entity.components.BeltUnderlays.underlays = [
- { pos: new Vector(0, 0), direction: enumDirection.top },
- ];
-
- break;
- }
- case enumBalancerVariants.splitter:
- case enumBalancerVariants.splitterInverse: {
- entity.components.ItemAcceptor.setSlots([
- {
- pos: new Vector(0, 0),
- direction: enumDirection.bottom,
- },
- ]);
-
- entity.components.ItemEjector.setSlots([
- {
- pos: new Vector(0, 0),
- direction: enumDirection.top,
- },
- {
- pos: new Vector(0, 0),
- direction:
- variant === enumBalancerVariants.splitterInverse
- ? enumDirection.left
- : enumDirection.right,
- },
- ]);
-
- entity.components.BeltUnderlays.underlays = [
- { pos: new Vector(0, 0), direction: enumDirection.top },
- ];
-
- break;
- }
- default:
- assertAlways(false, "Unknown balancer variant: " + variant);
- }
- }
-}
+import { enumDirection, Vector } from "../../core/vector";
+import { ItemAcceptorComponent } from "../components/item_acceptor";
+import { ItemEjectorComponent } from "../components/item_ejector";
+import { enumItemProcessorTypes, ItemProcessorComponent } from "../components/item_processor";
+import { Entity } from "../entity";
+import { MetaBuilding, defaultBuildingVariant } from "../meta_building";
+import { GameRoot } from "../root";
+import { enumHubGoalRewards } from "../tutorial_goals";
+import { T } from "../../translations";
+import { formatItemsPerSecond, generateMatrixRotations } from "../../core/utils";
+import { BeltUnderlaysComponent } from "../components/belt_underlays";
+
+/** @enum {string} */
+export const enumBalancerVariants = {
+ merger: "merger",
+ mergerInverse: "merger-inverse",
+ splitter: "splitter",
+ splitterInverse: "splitter-inverse",
+};
+
+const overlayMatrices = {
+ [defaultBuildingVariant]: null,
+ [enumBalancerVariants.merger]: generateMatrixRotations([0, 1, 0, 0, 1, 1, 0, 1, 0]),
+ [enumBalancerVariants.mergerInverse]: generateMatrixRotations([0, 1, 0, 1, 1, 0, 0, 1, 0]),
+ [enumBalancerVariants.splitter]: generateMatrixRotations([0, 1, 0, 0, 1, 1, 0, 1, 0]),
+ [enumBalancerVariants.splitterInverse]: generateMatrixRotations([0, 1, 0, 1, 1, 0, 0, 1, 0]),
+};
+
+export class MetaBalancerBuilding extends MetaBuilding {
+ constructor() {
+ super("balancer");
+ }
+
+ static getAllVariantCombinations() {
+ return [
+ {
+ internalId: 4,
+ variant: defaultBuildingVariant,
+ },
+ {
+ internalId: 5,
+ variant: enumBalancerVariants.merger,
+ },
+ {
+ internalId: 6,
+ variant: enumBalancerVariants.mergerInverse,
+ },
+ {
+ internalId: 47,
+ variant: enumBalancerVariants.splitter,
+ },
+ {
+ internalId: 48,
+ variant: enumBalancerVariants.splitterInverse,
+ },
+ ];
+ }
+
+ getDimensions(variant) {
+ switch (variant) {
+ case defaultBuildingVariant:
+ return new Vector(2, 1);
+ case enumBalancerVariants.merger:
+ case enumBalancerVariants.mergerInverse:
+ case enumBalancerVariants.splitter:
+ case enumBalancerVariants.splitterInverse:
+ return new Vector(1, 1);
+ default:
+ assertAlways(false, "Unknown balancer variant: " + variant);
+ }
+ }
+
+ /**
+ * @param {number} rotation
+ * @param {number} rotationVariant
+ * @param {string} variant
+ * @param {Entity} entity
+ * @returns {Array|null}
+ */
+ getSpecialOverlayRenderMatrix(rotation, rotationVariant, variant, entity) {
+ const matrix = overlayMatrices[variant];
+ if (matrix) {
+ return matrix[rotation];
+ }
+ return null;
+ }
+
+ /**
+ * @param {GameRoot} root
+ * @param {string} variant
+ * @returns {Array<[string, string]>}
+ */
+ getAdditionalStatistics(root, variant) {
+ if (root.gameMode.throughputDoesNotMatter()) {
+ return [];
+ }
+
+ let speedMultiplier = 2;
+ switch (variant) {
+ case enumBalancerVariants.merger:
+ case enumBalancerVariants.mergerInverse:
+ case enumBalancerVariants.splitter:
+ case enumBalancerVariants.splitterInverse:
+ speedMultiplier = 1;
+ }
+
+ const speed =
+ (root.hubGoals.getProcessorBaseSpeed(enumItemProcessorTypes.balancer) / 2) * speedMultiplier;
+ return [[T.ingame.buildingPlacement.infoTexts.speed, formatItemsPerSecond(speed)]];
+ }
+
+ getSilhouetteColor() {
+ return "#555759";
+ }
+
+ /**
+ * @param {GameRoot} root
+ */
+ getAvailableVariants(root) {
+ const deterministic = root.gameMode.getIsDeterministic();
+
+ let available = deterministic ? [] : [defaultBuildingVariant];
+
+ if (!deterministic && root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_merger)) {
+ available.push(enumBalancerVariants.merger, enumBalancerVariants.mergerInverse);
+ }
+
+ if (root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_splitter)) {
+ available.push(enumBalancerVariants.splitter, enumBalancerVariants.splitterInverse);
+ }
+
+ return available;
+ }
+
+ /**
+ * @param {GameRoot} root
+ */
+ getIsUnlocked(root) {
+ return root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_balancer);
+ }
+
+ /**
+ * Creates the entity at the given location
+ * @param {Entity} entity
+ */
+ setupEntityComponents(entity) {
+ entity.addComponent(
+ new ItemAcceptorComponent({
+ slots: [], // set later
+ })
+ );
+
+ entity.addComponent(
+ new ItemProcessorComponent({
+ inputsPerCharge: 1,
+ processorType: enumItemProcessorTypes.balancer,
+ })
+ );
+
+ entity.addComponent(
+ new ItemEjectorComponent({
+ slots: [], // set later
+ renderFloatingItems: false,
+ })
+ );
+
+ entity.addComponent(new BeltUnderlaysComponent({ underlays: [] }));
+ }
+
+ /**
+ *
+ * @param {Entity} entity
+ * @param {number} rotationVariant
+ * @param {string} variant
+ */
+ updateVariants(entity, rotationVariant, variant) {
+ switch (variant) {
+ case defaultBuildingVariant: {
+ entity.components.ItemAcceptor.setSlots([
+ {
+ pos: new Vector(0, 0),
+ direction: enumDirection.bottom,
+ },
+ {
+ pos: new Vector(1, 0),
+ direction: enumDirection.bottom,
+ },
+ ]);
+
+ entity.components.ItemEjector.setSlots([
+ { pos: new Vector(0, 0), direction: enumDirection.top },
+ { pos: new Vector(1, 0), direction: enumDirection.top },
+ ]);
+
+ entity.components.BeltUnderlays.underlays = [
+ { pos: new Vector(0, 0), direction: enumDirection.top },
+ { pos: new Vector(1, 0), direction: enumDirection.top },
+ ];
+
+ break;
+ }
+ case enumBalancerVariants.merger:
+ case enumBalancerVariants.mergerInverse: {
+ entity.components.ItemAcceptor.setSlots([
+ {
+ pos: new Vector(0, 0),
+ direction: enumDirection.bottom,
+ },
+ {
+ pos: new Vector(0, 0),
+ direction:
+ variant === enumBalancerVariants.mergerInverse
+ ? enumDirection.left
+ : enumDirection.right,
+ },
+ ]);
+
+ entity.components.ItemEjector.setSlots([
+ { pos: new Vector(0, 0), direction: enumDirection.top },
+ ]);
+
+ entity.components.BeltUnderlays.underlays = [
+ { pos: new Vector(0, 0), direction: enumDirection.top },
+ ];
+
+ break;
+ }
+ case enumBalancerVariants.splitter:
+ case enumBalancerVariants.splitterInverse: {
+ entity.components.ItemAcceptor.setSlots([
+ {
+ pos: new Vector(0, 0),
+ direction: enumDirection.bottom,
+ },
+ ]);
+
+ entity.components.ItemEjector.setSlots([
+ {
+ pos: new Vector(0, 0),
+ direction: enumDirection.top,
+ },
+ {
+ pos: new Vector(0, 0),
+ direction:
+ variant === enumBalancerVariants.splitterInverse
+ ? enumDirection.left
+ : enumDirection.right,
+ },
+ ]);
+
+ entity.components.BeltUnderlays.underlays = [
+ { pos: new Vector(0, 0), direction: enumDirection.top },
+ ];
+
+ break;
+ }
+ default:
+ assertAlways(false, "Unknown balancer variant: " + variant);
+ }
+ }
+}
diff --git a/src/js/game/buildings/belt.js b/src/js/game/buildings/belt.js
index 11a53cdf..14d629db 100644
--- a/src/js/game/buildings/belt.js
+++ b/src/js/game/buildings/belt.js
@@ -1,252 +1,252 @@
-import { Loader } from "../../core/loader";
-import { formatItemsPerSecond, generateMatrixRotations } from "../../core/utils";
-import { enumAngleToDirection, enumDirection, Vector } from "../../core/vector";
-import { SOUNDS } from "../../platform/sound";
-import { T } from "../../translations";
-import { BeltComponent } from "../components/belt";
-import { Entity } from "../entity";
-import { defaultBuildingVariant, MetaBuilding } from "../meta_building";
-import { GameRoot } from "../root";
-import { THEME } from "../theme";
-
-export const arrayBeltVariantToRotation = [enumDirection.top, enumDirection.left, enumDirection.right];
-
-export const beltOverlayMatrices = {
- [enumDirection.top]: generateMatrixRotations([0, 1, 0, 0, 1, 0, 0, 1, 0]),
- [enumDirection.left]: generateMatrixRotations([0, 0, 0, 1, 1, 0, 0, 1, 0]),
- [enumDirection.right]: generateMatrixRotations([0, 0, 0, 0, 1, 1, 0, 1, 0]),
-};
-
-export class MetaBeltBuilding extends MetaBuilding {
- constructor() {
- super("belt");
- }
-
- static getAllVariantCombinations() {
- return [
- {
- internalId: 1,
- variant: defaultBuildingVariant,
- rotationVariant: 0,
- },
- {
- internalId: 2,
- variant: defaultBuildingVariant,
- rotationVariant: 1,
- },
- {
- internalId: 3,
- variant: defaultBuildingVariant,
- rotationVariant: 2,
- },
- ];
- }
-
- getSilhouetteColor() {
- return THEME.map.chunkOverview.beltColor;
- }
-
- getPlacementSound() {
- return SOUNDS.placeBelt;
- }
-
- getHasDirectionLockAvailable() {
- return true;
- }
- getStayInPlacementMode() {
- return true;
- }
-
- getRotateAutomaticallyWhilePlacing() {
- return true;
- }
-
- getSprite() {
- return null;
- }
-
- getIsReplaceable() {
- return true;
- }
-
- /**
- * @param {GameRoot} root
- * @param {string} variant
- * @returns {Array<[string, string]>}
- */
- getAdditionalStatistics(root, variant) {
- if (root.gameMode.throughputDoesNotMatter()) {
- return [];
- }
- const beltSpeed = root.hubGoals.getBeltBaseSpeed();
- return [[T.ingame.buildingPlacement.infoTexts.speed, formatItemsPerSecond(beltSpeed)]];
- }
-
- getPreviewSprite(rotationVariant) {
- switch (arrayBeltVariantToRotation[rotationVariant]) {
- case enumDirection.top: {
- return Loader.getSprite("sprites/buildings/belt_top.png");
- }
- case enumDirection.left: {
- return Loader.getSprite("sprites/buildings/belt_left.png");
- }
- case enumDirection.right: {
- return Loader.getSprite("sprites/buildings/belt_right.png");
- }
- default: {
- assertAlways(false, "Invalid belt rotation variant");
- }
- }
- }
-
- getBlueprintSprite(rotationVariant) {
- switch (arrayBeltVariantToRotation[rotationVariant]) {
- case enumDirection.top: {
- return Loader.getSprite("sprites/blueprints/belt_top.png");
- }
- case enumDirection.left: {
- return Loader.getSprite("sprites/blueprints/belt_left.png");
- }
- case enumDirection.right: {
- return Loader.getSprite("sprites/blueprints/belt_right.png");
- }
- default: {
- assertAlways(false, "Invalid belt rotation variant");
- }
- }
- }
-
- /**
- *
- * @param {number} rotation
- * @param {number} rotationVariant
- * @param {string} variant
- * @param {Entity} entity
- */
- getSpecialOverlayRenderMatrix(rotation, rotationVariant, variant, entity) {
- return beltOverlayMatrices[entity.components.Belt.direction][rotation];
- }
-
- /**
- * Creates the entity at the given location
- * @param {Entity} entity
- */
- setupEntityComponents(entity) {
- entity.addComponent(
- new BeltComponent({
- direction: enumDirection.top, // updated later
- })
- );
- }
-
- /**
- *
- * @param {Entity} entity
- * @param {number} rotationVariant
- */
- updateVariants(entity, rotationVariant) {
- entity.components.Belt.direction = arrayBeltVariantToRotation[rotationVariant];
- }
-
- /**
- * Should compute the optimal rotation variant on the given tile
- * @param {object} param0
- * @param {GameRoot} param0.root
- * @param {Vector} param0.tile
- * @param {number} param0.rotation
- * @param {string} param0.variant
- * @param {Layer} param0.layer
- * @return {{ rotation: number, rotationVariant: number, connectedEntities?: Array }}
- */
- computeOptimalDirectionAndRotationVariantAtTile({ root, tile, rotation, variant, layer }) {
- const topDirection = enumAngleToDirection[rotation];
- const rightDirection = enumAngleToDirection[(rotation + 90) % 360];
- const bottomDirection = enumAngleToDirection[(rotation + 180) % 360];
- const leftDirection = enumAngleToDirection[(rotation + 270) % 360];
-
- const { ejectors, acceptors } = root.logic.getEjectorsAndAcceptorsAtTile(tile);
-
- let hasBottomEjector = false;
- let hasRightEjector = false;
- let hasLeftEjector = false;
-
- let hasTopAcceptor = false;
- let hasLeftAcceptor = false;
- let hasRightAcceptor = false;
-
- // Check all ejectors
- for (let i = 0; i < ejectors.length; ++i) {
- const ejector = ejectors[i];
-
- if (ejector.toDirection === topDirection) {
- hasBottomEjector = true;
- } else if (ejector.toDirection === leftDirection) {
- hasRightEjector = true;
- } else if (ejector.toDirection === rightDirection) {
- hasLeftEjector = true;
- }
- }
-
- // Check all acceptors
- for (let i = 0; i < acceptors.length; ++i) {
- const acceptor = acceptors[i];
- if (acceptor.fromDirection === bottomDirection) {
- hasTopAcceptor = true;
- } else if (acceptor.fromDirection === rightDirection) {
- hasLeftAcceptor = true;
- } else if (acceptor.fromDirection === leftDirection) {
- hasRightAcceptor = true;
- }
- }
-
- // Soo .. if there is any ejector below us we always prioritize
- // this ejector
- if (!hasBottomEjector) {
- // When something ejects to us from the left and nothing from the right,
- // do a curve from the left to the top
-
- if (hasRightEjector && !hasLeftEjector) {
- return {
- rotation: (rotation + 270) % 360,
- rotationVariant: 2,
- };
- }
-
- // When something ejects to us from the right and nothing from the left,
- // do a curve from the right to the top
- if (hasLeftEjector && !hasRightEjector) {
- return {
- rotation: (rotation + 90) % 360,
- rotationVariant: 1,
- };
- }
- }
-
- // When there is a top acceptor, ignore sides
- // NOTICE: This makes the belt prefer side turns *way* too much!
- if (!hasTopAcceptor) {
- // When there is an acceptor to the right but no acceptor to the left,
- // do a turn to the right
- if (hasRightAcceptor && !hasLeftAcceptor) {
- return {
- rotation,
- rotationVariant: 2,
- };
- }
-
- // When there is an acceptor to the left but no acceptor to the right,
- // do a turn to the left
- if (hasLeftAcceptor && !hasRightAcceptor) {
- return {
- rotation,
- rotationVariant: 1,
- };
- }
- }
-
- return {
- rotation,
- rotationVariant: 0,
- };
- }
-}
+import { Loader } from "../../core/loader";
+import { formatItemsPerSecond, generateMatrixRotations } from "../../core/utils";
+import { enumAngleToDirection, enumDirection, Vector } from "../../core/vector";
+import { SOUNDS } from "../../platform/sound";
+import { T } from "../../translations";
+import { BeltComponent } from "../components/belt";
+import { Entity } from "../entity";
+import { defaultBuildingVariant, MetaBuilding } from "../meta_building";
+import { GameRoot } from "../root";
+import { THEME } from "../theme";
+
+export const arrayBeltVariantToRotation = [enumDirection.top, enumDirection.left, enumDirection.right];
+
+export const beltOverlayMatrices = {
+ [enumDirection.top]: generateMatrixRotations([0, 1, 0, 0, 1, 0, 0, 1, 0]),
+ [enumDirection.left]: generateMatrixRotations([0, 0, 0, 1, 1, 0, 0, 1, 0]),
+ [enumDirection.right]: generateMatrixRotations([0, 0, 0, 0, 1, 1, 0, 1, 0]),
+};
+
+export class MetaBeltBuilding extends MetaBuilding {
+ constructor() {
+ super("belt");
+ }
+
+ static getAllVariantCombinations() {
+ return [
+ {
+ internalId: 1,
+ variant: defaultBuildingVariant,
+ rotationVariant: 0,
+ },
+ {
+ internalId: 2,
+ variant: defaultBuildingVariant,
+ rotationVariant: 1,
+ },
+ {
+ internalId: 3,
+ variant: defaultBuildingVariant,
+ rotationVariant: 2,
+ },
+ ];
+ }
+
+ getSilhouetteColor() {
+ return THEME.map.chunkOverview.beltColor;
+ }
+
+ getPlacementSound() {
+ return SOUNDS.placeBelt;
+ }
+
+ getHasDirectionLockAvailable() {
+ return true;
+ }
+ getStayInPlacementMode() {
+ return true;
+ }
+
+ getRotateAutomaticallyWhilePlacing() {
+ return true;
+ }
+
+ getSprite() {
+ return null;
+ }
+
+ getIsReplaceable() {
+ return true;
+ }
+
+ /**
+ * @param {GameRoot} root
+ * @param {string} variant
+ * @returns {Array<[string, string]>}
+ */
+ getAdditionalStatistics(root, variant) {
+ if (root.gameMode.throughputDoesNotMatter()) {
+ return [];
+ }
+ const beltSpeed = root.hubGoals.getBeltBaseSpeed();
+ return [[T.ingame.buildingPlacement.infoTexts.speed, formatItemsPerSecond(beltSpeed)]];
+ }
+
+ getPreviewSprite(rotationVariant) {
+ switch (arrayBeltVariantToRotation[rotationVariant]) {
+ case enumDirection.top: {
+ return Loader.getSprite("sprites/buildings/belt_top.png");
+ }
+ case enumDirection.left: {
+ return Loader.getSprite("sprites/buildings/belt_left.png");
+ }
+ case enumDirection.right: {
+ return Loader.getSprite("sprites/buildings/belt_right.png");
+ }
+ default: {
+ assertAlways(false, "Invalid belt rotation variant");
+ }
+ }
+ }
+
+ getBlueprintSprite(rotationVariant) {
+ switch (arrayBeltVariantToRotation[rotationVariant]) {
+ case enumDirection.top: {
+ return Loader.getSprite("sprites/blueprints/belt_top.png");
+ }
+ case enumDirection.left: {
+ return Loader.getSprite("sprites/blueprints/belt_left.png");
+ }
+ case enumDirection.right: {
+ return Loader.getSprite("sprites/blueprints/belt_right.png");
+ }
+ default: {
+ assertAlways(false, "Invalid belt rotation variant");
+ }
+ }
+ }
+
+ /**
+ *
+ * @param {number} rotation
+ * @param {number} rotationVariant
+ * @param {string} variant
+ * @param {Entity} entity
+ */
+ getSpecialOverlayRenderMatrix(rotation, rotationVariant, variant, entity) {
+ return beltOverlayMatrices[entity.components.Belt.direction][rotation];
+ }
+
+ /**
+ * Creates the entity at the given location
+ * @param {Entity} entity
+ */
+ setupEntityComponents(entity) {
+ entity.addComponent(
+ new BeltComponent({
+ direction: enumDirection.top, // updated later
+ })
+ );
+ }
+
+ /**
+ *
+ * @param {Entity} entity
+ * @param {number} rotationVariant
+ */
+ updateVariants(entity, rotationVariant) {
+ entity.components.Belt.direction = arrayBeltVariantToRotation[rotationVariant];
+ }
+
+ /**
+ * Should compute the optimal rotation variant on the given tile
+ * @param {object} param0
+ * @param {GameRoot} param0.root
+ * @param {Vector} param0.tile
+ * @param {number} param0.rotation
+ * @param {string} param0.variant
+ * @param {Layer} param0.layer
+ * @return {{ rotation: number, rotationVariant: number, connectedEntities?: Array }}
+ */
+ computeOptimalDirectionAndRotationVariantAtTile({ root, tile, rotation, variant, layer }) {
+ const topDirection = enumAngleToDirection[rotation];
+ const rightDirection = enumAngleToDirection[(rotation + 90) % 360];
+ const bottomDirection = enumAngleToDirection[(rotation + 180) % 360];
+ const leftDirection = enumAngleToDirection[(rotation + 270) % 360];
+
+ const { ejectors, acceptors } = root.logic.getEjectorsAndAcceptorsAtTile(tile);
+
+ let hasBottomEjector = false;
+ let hasRightEjector = false;
+ let hasLeftEjector = false;
+
+ let hasTopAcceptor = false;
+ let hasLeftAcceptor = false;
+ let hasRightAcceptor = false;
+
+ // Check all ejectors
+ for (let i = 0; i < ejectors.length; ++i) {
+ const ejector = ejectors[i];
+
+ if (ejector.toDirection === topDirection) {
+ hasBottomEjector = true;
+ } else if (ejector.toDirection === leftDirection) {
+ hasRightEjector = true;
+ } else if (ejector.toDirection === rightDirection) {
+ hasLeftEjector = true;
+ }
+ }
+
+ // Check all acceptors
+ for (let i = 0; i < acceptors.length; ++i) {
+ const acceptor = acceptors[i];
+ if (acceptor.fromDirection === bottomDirection) {
+ hasTopAcceptor = true;
+ } else if (acceptor.fromDirection === rightDirection) {
+ hasLeftAcceptor = true;
+ } else if (acceptor.fromDirection === leftDirection) {
+ hasRightAcceptor = true;
+ }
+ }
+
+ // Soo .. if there is any ejector below us we always prioritize
+ // this ejector
+ if (!hasBottomEjector) {
+ // When something ejects to us from the left and nothing from the right,
+ // do a curve from the left to the top
+
+ if (hasRightEjector && !hasLeftEjector) {
+ return {
+ rotation: (rotation + 270) % 360,
+ rotationVariant: 2,
+ };
+ }
+
+ // When something ejects to us from the right and nothing from the left,
+ // do a curve from the right to the top
+ if (hasLeftEjector && !hasRightEjector) {
+ return {
+ rotation: (rotation + 90) % 360,
+ rotationVariant: 1,
+ };
+ }
+ }
+
+ // When there is a top acceptor, ignore sides
+ // NOTICE: This makes the belt prefer side turns *way* too much!
+ if (!hasTopAcceptor) {
+ // When there is an acceptor to the right but no acceptor to the left,
+ // do a turn to the right
+ if (hasRightAcceptor && !hasLeftAcceptor) {
+ return {
+ rotation,
+ rotationVariant: 2,
+ };
+ }
+
+ // When there is an acceptor to the left but no acceptor to the right,
+ // do a turn to the left
+ if (hasLeftAcceptor && !hasRightAcceptor) {
+ return {
+ rotation,
+ rotationVariant: 1,
+ };
+ }
+ }
+
+ return {
+ rotation,
+ rotationVariant: 0,
+ };
+ }
+}
diff --git a/src/js/game/buildings/comparator.js b/src/js/game/buildings/comparator.js
index 1f45dbbb..f6dc727b 100644
--- a/src/js/game/buildings/comparator.js
+++ b/src/js/game/buildings/comparator.js
@@ -1,81 +1,81 @@
-import { enumDirection, Vector } from "../../core/vector";
-import { enumLogicGateType, LogicGateComponent } from "../components/logic_gate";
-import { enumPinSlotType, WiredPinsComponent } from "../components/wired_pins";
-import { Entity } from "../entity";
-import { defaultBuildingVariant, MetaBuilding } from "../meta_building";
-import { GameRoot } from "../root";
-import { enumHubGoalRewards } from "../tutorial_goals";
-
-export class MetaComparatorBuilding extends MetaBuilding {
- constructor() {
- super("comparator");
- }
-
- static getAllVariantCombinations() {
- return [
- {
- internalId: 46,
- variant: defaultBuildingVariant,
- },
- ];
- }
-
- getSilhouetteColor() {
- return "#823cab";
- }
-
- /**
- * @param {GameRoot} root
- */
- getIsUnlocked(root) {
- return root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_virtual_processing);
- }
-
- /** @returns {"wires"} **/
- getLayer() {
- return "wires";
- }
-
- getDimensions() {
- return new Vector(1, 1);
- }
-
- getRenderPins() {
- // We already have it included
- return false;
- }
-
- /**
- * Creates the entity at the given location
- * @param {Entity} entity
- */
- setupEntityComponents(entity) {
- entity.addComponent(
- new WiredPinsComponent({
- slots: [
- {
- pos: new Vector(0, 0),
- direction: enumDirection.top,
- type: enumPinSlotType.logicalEjector,
- },
- {
- pos: new Vector(0, 0),
- direction: enumDirection.left,
- type: enumPinSlotType.logicalAcceptor,
- },
- {
- pos: new Vector(0, 0),
- direction: enumDirection.right,
- type: enumPinSlotType.logicalAcceptor,
- },
- ],
- })
- );
-
- entity.addComponent(
- new LogicGateComponent({
- type: enumLogicGateType.compare,
- })
- );
- }
-}
+import { enumDirection, Vector } from "../../core/vector";
+import { enumLogicGateType, LogicGateComponent } from "../components/logic_gate";
+import { enumPinSlotType, WiredPinsComponent } from "../components/wired_pins";
+import { Entity } from "../entity";
+import { defaultBuildingVariant, MetaBuilding } from "../meta_building";
+import { GameRoot } from "../root";
+import { enumHubGoalRewards } from "../tutorial_goals";
+
+export class MetaComparatorBuilding extends MetaBuilding {
+ constructor() {
+ super("comparator");
+ }
+
+ static getAllVariantCombinations() {
+ return [
+ {
+ internalId: 46,
+ variant: defaultBuildingVariant,
+ },
+ ];
+ }
+
+ getSilhouetteColor() {
+ return "#823cab";
+ }
+
+ /**
+ * @param {GameRoot} root
+ */
+ getIsUnlocked(root) {
+ return root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_virtual_processing);
+ }
+
+ /** @returns {"wires"} **/
+ getLayer() {
+ return "wires";
+ }
+
+ getDimensions() {
+ return new Vector(1, 1);
+ }
+
+ getRenderPins() {
+ // We already have it included
+ return false;
+ }
+
+ /**
+ * Creates the entity at the given location
+ * @param {Entity} entity
+ */
+ setupEntityComponents(entity) {
+ entity.addComponent(
+ new WiredPinsComponent({
+ slots: [
+ {
+ pos: new Vector(0, 0),
+ direction: enumDirection.top,
+ type: enumPinSlotType.logicalEjector,
+ },
+ {
+ pos: new Vector(0, 0),
+ direction: enumDirection.left,
+ type: enumPinSlotType.logicalAcceptor,
+ },
+ {
+ pos: new Vector(0, 0),
+ direction: enumDirection.right,
+ type: enumPinSlotType.logicalAcceptor,
+ },
+ ],
+ })
+ );
+
+ entity.addComponent(
+ new LogicGateComponent({
+ type: enumLogicGateType.compare,
+ })
+ );
+ }
+}
diff --git a/src/js/game/buildings/constant_signal.js b/src/js/game/buildings/constant_signal.js
index 2bb72def..d4056309 100644
--- a/src/js/game/buildings/constant_signal.js
+++ b/src/js/game/buildings/constant_signal.js
@@ -1,72 +1,72 @@
-import { enumDirection, Vector } from "../../core/vector";
-import { enumPinSlotType, WiredPinsComponent } from "../components/wired_pins";
-import { Entity } from "../entity";
-import { defaultBuildingVariant, MetaBuilding } from "../meta_building";
-import { GameRoot } from "../root";
-import { ConstantSignalComponent } from "../components/constant_signal";
-import { generateMatrixRotations } from "../../core/utils";
-import { enumHubGoalRewards } from "../tutorial_goals";
-
-const overlayMatrix = generateMatrixRotations([0, 1, 0, 1, 1, 1, 1, 1, 1]);
-
-export class MetaConstantSignalBuilding extends MetaBuilding {
- constructor() {
- super("constant_signal");
- }
-
- static getAllVariantCombinations() {
- return [
- {
- internalId: 31,
- variant: defaultBuildingVariant,
- },
- ];
- }
-
- getSilhouetteColor() {
- return "#2b84fd";
- }
-
- /**
- * @param {GameRoot} root
- */
- getIsUnlocked(root) {
- return root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_constant_signal);
- }
-
- /** @returns {"wires"} **/
- getLayer() {
- return "wires";
- }
-
- getDimensions() {
- return new Vector(1, 1);
- }
-
- getRenderPins() {
- return false;
- }
-
- getSpecialOverlayRenderMatrix(rotation) {
- return overlayMatrix[rotation];
- }
-
- /**
- * Creates the entity at the given location
- * @param {Entity} entity
- */
- setupEntityComponents(entity) {
- entity.addComponent(
- new WiredPinsComponent({
- slots: [
- {
- pos: new Vector(0, 0),
- direction: enumDirection.top,
- type: enumPinSlotType.logicalEjector,
- },
- ],
- })
- );
- entity.addComponent(new ConstantSignalComponent({}));
- }
-}
+import { enumDirection, Vector } from "../../core/vector";
+import { enumPinSlotType, WiredPinsComponent } from "../components/wired_pins";
+import { Entity } from "../entity";
+import { defaultBuildingVariant, MetaBuilding } from "../meta_building";
+import { GameRoot } from "../root";
+import { ConstantSignalComponent } from "../components/constant_signal";
+import { generateMatrixRotations } from "../../core/utils";
+import { enumHubGoalRewards } from "../tutorial_goals";
+
+const overlayMatrix = generateMatrixRotations([0, 1, 0, 1, 1, 1, 1, 1, 1]);
+
+export class MetaConstantSignalBuilding extends MetaBuilding {
+ constructor() {
+ super("constant_signal");
+ }
+
+ static getAllVariantCombinations() {
+ return [
+ {
+ internalId: 31,
+ variant: defaultBuildingVariant,
+ },
+ ];
+ }
+
+ getSilhouetteColor() {
+ return "#2b84fd";
+ }
+
+ /**
+ * @param {GameRoot} root
+ */
+ getIsUnlocked(root) {
+ return root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_constant_signal);
+ }
+
+ /** @returns {"wires"} **/
+ getLayer() {
+ return "wires";
+ }
+
+ getDimensions() {
+ return new Vector(1, 1);
+ }
+
+ getRenderPins() {
+ return false;
+ }
+
+ getSpecialOverlayRenderMatrix(rotation) {
+ return overlayMatrix[rotation];
+ }
+
+ /**
+ * Creates the entity at the given location
+ * @param {Entity} entity
+ */
+ setupEntityComponents(entity) {
+ entity.addComponent(
+ new WiredPinsComponent({
+ slots: [
+ {
+ pos: new Vector(0, 0),
+ direction: enumDirection.top,
+ type: enumPinSlotType.logicalEjector,
+ },
+ ],
+ })
+ );
+ entity.addComponent(new ConstantSignalComponent({}));
+ }
+}
diff --git a/src/js/game/buildings/cutter.js b/src/js/game/buildings/cutter.js
index 21acdaa0..dd71b527 100644
--- a/src/js/game/buildings/cutter.js
+++ b/src/js/game/buildings/cutter.js
@@ -1,138 +1,138 @@
-import { formatItemsPerSecond } from "../../core/utils";
-import { enumDirection, Vector } from "../../core/vector";
-import { T } from "../../translations";
-import { ItemAcceptorComponent } from "../components/item_acceptor";
-import { ItemEjectorComponent } from "../components/item_ejector";
-import { enumItemProcessorTypes, ItemProcessorComponent } from "../components/item_processor";
-import { Entity } from "../entity";
-import { defaultBuildingVariant, MetaBuilding } from "../meta_building";
-import { GameRoot } from "../root";
-import { enumHubGoalRewards } from "../tutorial_goals";
-
-/** @enum {string} */
-export const enumCutterVariants = { quad: "quad" };
-
-export class MetaCutterBuilding extends MetaBuilding {
- constructor() {
- super("cutter");
- }
-
- static getAllVariantCombinations() {
- return [
- {
- internalId: 9,
- variant: defaultBuildingVariant,
- },
- {
- internalId: 10,
- variant: enumCutterVariants.quad,
- },
- ];
- }
-
- getSilhouetteColor() {
- return "#7dcda2";
- }
-
- getDimensions(variant) {
- switch (variant) {
- case defaultBuildingVariant:
- return new Vector(2, 1);
- case enumCutterVariants.quad:
- return new Vector(4, 1);
- default:
- assertAlways(false, "Unknown cutter variant: " + variant);
- }
- }
-
- /**
- * @param {GameRoot} root
- * @param {string} variant
- * @returns {Array<[string, string]>}
- */
- getAdditionalStatistics(root, variant) {
- if (root.gameMode.throughputDoesNotMatter()) {
- return [];
- }
- const speed = root.hubGoals.getProcessorBaseSpeed(
- variant === enumCutterVariants.quad
- ? enumItemProcessorTypes.cutterQuad
- : enumItemProcessorTypes.cutter
- );
- return [[T.ingame.buildingPlacement.infoTexts.speed, formatItemsPerSecond(speed)]];
- }
-
- /**
- * @param {GameRoot} root
- */
- getAvailableVariants(root) {
- if (root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_cutter_quad)) {
- return [defaultBuildingVariant, enumCutterVariants.quad];
- }
- return super.getAvailableVariants(root);
- }
-
- /**
- * @param {GameRoot} root
- */
- getIsUnlocked(root) {
- return root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_cutter_and_trash);
- }
-
- /**
- * Creates the entity at the given location
- * @param {Entity} entity
- */
- setupEntityComponents(entity) {
- entity.addComponent(
- new ItemProcessorComponent({
- inputsPerCharge: 1,
- processorType: enumItemProcessorTypes.cutter,
- })
- );
- entity.addComponent(new ItemEjectorComponent({}));
- entity.addComponent(
- new ItemAcceptorComponent({
- slots: [
- {
- pos: new Vector(0, 0),
- direction: enumDirection.bottom,
- filter: "shape",
- },
- ],
- })
- );
- }
-
- /**
- *
- * @param {Entity} entity
- * @param {number} rotationVariant
- * @param {string} variant
- */
- updateVariants(entity, rotationVariant, variant) {
- switch (variant) {
- case defaultBuildingVariant: {
- entity.components.ItemEjector.setSlots([
- { pos: new Vector(0, 0), direction: enumDirection.top },
- { pos: new Vector(1, 0), direction: enumDirection.top },
- ]);
- entity.components.ItemProcessor.type = enumItemProcessorTypes.cutter;
- break;
- }
- case enumCutterVariants.quad: {
- entity.components.ItemEjector.setSlots([
- { pos: new Vector(0, 0), direction: enumDirection.top },
- { pos: new Vector(1, 0), direction: enumDirection.top },
- { pos: new Vector(2, 0), direction: enumDirection.top },
- { pos: new Vector(3, 0), direction: enumDirection.top },
- ]);
- entity.components.ItemProcessor.type = enumItemProcessorTypes.cutterQuad;
- break;
- }
-
- default:
- assertAlways(false, "Unknown painter variant: " + variant);
- }
- }
-}
+import { formatItemsPerSecond } from "../../core/utils";
+import { enumDirection, Vector } from "../../core/vector";
+import { T } from "../../translations";
+import { ItemAcceptorComponent } from "../components/item_acceptor";
+import { ItemEjectorComponent } from "../components/item_ejector";
+import { enumItemProcessorTypes, ItemProcessorComponent } from "../components/item_processor";
+import { Entity } from "../entity";
+import { defaultBuildingVariant, MetaBuilding } from "../meta_building";
+import { GameRoot } from "../root";
+import { enumHubGoalRewards } from "../tutorial_goals";
+
+/** @enum {string} */
+export const enumCutterVariants = { quad: "quad" };
+
+export class MetaCutterBuilding extends MetaBuilding {
+ constructor() {
+ super("cutter");
+ }
+
+ static getAllVariantCombinations() {
+ return [
+ {
+ internalId: 9,
+ variant: defaultBuildingVariant,
+ },
+ {
+ internalId: 10,
+ variant: enumCutterVariants.quad,
+ },
+ ];
+ }
+
+ getSilhouetteColor() {
+ return "#7dcda2";
+ }
+
+ getDimensions(variant) {
+ switch (variant) {
+ case defaultBuildingVariant:
+ return new Vector(2, 1);
+ case enumCutterVariants.quad:
+ return new Vector(4, 1);
+ default:
+ assertAlways(false, "Unknown cutter variant: " + variant);
+ }
+ }
+
+ /**
+ * @param {GameRoot} root
+ * @param {string} variant
+ * @returns {Array<[string, string]>}
+ */
+ getAdditionalStatistics(root, variant) {
+ if (root.gameMode.throughputDoesNotMatter()) {
+ return [];
+ }
+ const speed = root.hubGoals.getProcessorBaseSpeed(
+ variant === enumCutterVariants.quad
+ ? enumItemProcessorTypes.cutterQuad
+ : enumItemProcessorTypes.cutter
+ );
+ return [[T.ingame.buildingPlacement.infoTexts.speed, formatItemsPerSecond(speed)]];
+ }
+
+ /**
+ * @param {GameRoot} root
+ */
+ getAvailableVariants(root) {
+ if (root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_cutter_quad)) {
+ return [defaultBuildingVariant, enumCutterVariants.quad];
+ }
+ return super.getAvailableVariants(root);
+ }
+
+ /**
+ * @param {GameRoot} root
+ */
+ getIsUnlocked(root) {
+ return root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_cutter_and_trash);
+ }
+
+ /**
+ * Creates the entity at the given location
+ * @param {Entity} entity
+ */
+ setupEntityComponents(entity) {
+ entity.addComponent(
+ new ItemProcessorComponent({
+ inputsPerCharge: 1,
+ processorType: enumItemProcessorTypes.cutter,
+ })
+ );
+ entity.addComponent(new ItemEjectorComponent({}));
+ entity.addComponent(
+ new ItemAcceptorComponent({
+ slots: [
+ {
+ pos: new Vector(0, 0),
+ direction: enumDirection.bottom,
+ filter: "shape",
+ },
+ ],
+ })
+ );
+ }
+
+ /**
+ *
+ * @param {Entity} entity
+ * @param {number} rotationVariant
+ * @param {string} variant
+ */
+ updateVariants(entity, rotationVariant, variant) {
+ switch (variant) {
+ case defaultBuildingVariant: {
+ entity.components.ItemEjector.setSlots([
+ { pos: new Vector(0, 0), direction: enumDirection.top },
+ { pos: new Vector(1, 0), direction: enumDirection.top },
+ ]);
+ entity.components.ItemProcessor.type = enumItemProcessorTypes.cutter;
+ break;
+ }
+ case enumCutterVariants.quad: {
+ entity.components.ItemEjector.setSlots([
+ { pos: new Vector(0, 0), direction: enumDirection.top },
+ { pos: new Vector(1, 0), direction: enumDirection.top },
+ { pos: new Vector(2, 0), direction: enumDirection.top },
+ { pos: new Vector(3, 0), direction: enumDirection.top },
+ ]);
+ entity.components.ItemProcessor.type = enumItemProcessorTypes.cutterQuad;
+ break;
+ }
+
+ default:
+ assertAlways(false, "Unknown painter variant: " + variant);
+ }
+ }
+}
diff --git a/src/js/game/buildings/display.js b/src/js/game/buildings/display.js
index 7c1277c2..a3819ec2 100644
--- a/src/js/game/buildings/display.js
+++ b/src/js/game/buildings/display.js
@@ -1,60 +1,60 @@
-import { enumDirection, Vector } from "../../core/vector";
-import { enumPinSlotType, WiredPinsComponent } from "../components/wired_pins";
-import { Entity } from "../entity";
-import { defaultBuildingVariant, MetaBuilding } from "../meta_building";
-import { GameRoot } from "../root";
-import { DisplayComponent } from "../components/display";
-import { enumHubGoalRewards } from "../tutorial_goals";
-
-export class MetaDisplayBuilding extends MetaBuilding {
- constructor() {
- super("display");
- }
-
- static getAllVariantCombinations() {
- return [
- {
- internalId: 40,
- variant: defaultBuildingVariant,
- },
- ];
- }
-
- getSilhouetteColor() {
- return "#aaaaaa";
- }
-
- /**
- * @param {GameRoot} root
- */
- getIsUnlocked(root) {
- return root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_display);
- }
-
- getDimensions() {
- return new Vector(1, 1);
- }
-
- getShowWiresLayerPreview() {
- return true;
- }
-
- /**
- * Creates the entity at the given location
- * @param {Entity} entity
- */
- setupEntityComponents(entity) {
- entity.addComponent(
- new WiredPinsComponent({
- slots: [
- {
- pos: new Vector(0, 0),
- direction: enumDirection.bottom,
- type: enumPinSlotType.logicalAcceptor,
- },
- ],
- })
- );
- entity.addComponent(new DisplayComponent());
- }
-}
+import { enumDirection, Vector } from "../../core/vector";
+import { enumPinSlotType, WiredPinsComponent } from "../components/wired_pins";
+import { Entity } from "../entity";
+import { defaultBuildingVariant, MetaBuilding } from "../meta_building";
+import { GameRoot } from "../root";
+import { DisplayComponent } from "../components/display";
+import { enumHubGoalRewards } from "../tutorial_goals";
+
+export class MetaDisplayBuilding extends MetaBuilding {
+ constructor() {
+ super("display");
+ }
+
+ static getAllVariantCombinations() {
+ return [
+ {
+ internalId: 40,
+ variant: defaultBuildingVariant,
+ },
+ ];
+ }
+
+ getSilhouetteColor() {
+ return "#aaaaaa";
+ }
+
+ /**
+ * @param {GameRoot} root
+ */
+ getIsUnlocked(root) {
+ return root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_display);
+ }
+
+ getDimensions() {
+ return new Vector(1, 1);
+ }
+
+ getShowWiresLayerPreview() {
+ return true;
+ }
+
+ /**
+ * Creates the entity at the given location
+ * @param {Entity} entity
+ */
+ setupEntityComponents(entity) {
+ entity.addComponent(
+ new WiredPinsComponent({
+ slots: [
+ {
+ pos: new Vector(0, 0),
+ direction: enumDirection.bottom,
+ type: enumPinSlotType.logicalAcceptor,
+ },
+ ],
+ })
+ );
+ entity.addComponent(new DisplayComponent());
+ }
+}
diff --git a/src/js/game/buildings/filter.js b/src/js/game/buildings/filter.js
index f8c29b1f..9276159f 100644
--- a/src/js/game/buildings/filter.js
+++ b/src/js/game/buildings/filter.js
@@ -1,104 +1,104 @@
-import { formatItemsPerSecond } from "../../core/utils";
-import { enumDirection, Vector } from "../../core/vector";
-import { T } from "../../translations";
-import { FilterComponent } from "../components/filter";
-import { ItemAcceptorComponent } from "../components/item_acceptor";
-import { ItemEjectorComponent } from "../components/item_ejector";
-import { enumPinSlotType, WiredPinsComponent } from "../components/wired_pins";
-import { Entity } from "../entity";
-import { defaultBuildingVariant, MetaBuilding } from "../meta_building";
-import { GameRoot } from "../root";
-import { enumHubGoalRewards } from "../tutorial_goals";
-
-export class MetaFilterBuilding extends MetaBuilding {
- constructor() {
- super("filter");
- }
-
- static getAllVariantCombinations() {
- return [
- {
- internalId: 37,
- variant: defaultBuildingVariant,
- },
- ];
- }
-
- getSilhouetteColor() {
- return "#c45c2e";
- }
-
- /**
- * @param {GameRoot} root
- */
- getIsUnlocked(root) {
- return root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_filter);
- }
-
- getDimensions() {
- return new Vector(2, 1);
- }
-
- getShowWiresLayerPreview() {
- return true;
- }
-
- /**
- * @param {GameRoot} root
- * @param {string} variant
- * @returns {Array<[string, string]>}
- */
- getAdditionalStatistics(root, variant) {
- if (root.gameMode.throughputDoesNotMatter()) {
- return [];
- }
- const beltSpeed = root.hubGoals.getBeltBaseSpeed();
- return [[T.ingame.buildingPlacement.infoTexts.speed, formatItemsPerSecond(beltSpeed)]];
- }
-
- /**
- * Creates the entity at the given location
- * @param {Entity} entity
- */
- setupEntityComponents(entity) {
- entity.addComponent(
- new WiredPinsComponent({
- slots: [
- {
- pos: new Vector(0, 0),
- direction: enumDirection.left,
- type: enumPinSlotType.logicalAcceptor,
- },
- ],
- })
- );
-
- entity.addComponent(
- new ItemAcceptorComponent({
- slots: [
- {
- pos: new Vector(0, 0),
- direction: enumDirection.bottom,
- },
- ],
- })
- );
-
- entity.addComponent(
- new ItemEjectorComponent({
- slots: [
- {
- pos: new Vector(0, 0),
- direction: enumDirection.top,
- },
- {
- pos: new Vector(1, 0),
- direction: enumDirection.right,
- },
- ],
- })
- );
-
- entity.addComponent(new FilterComponent());
- }
-}
+import { formatItemsPerSecond } from "../../core/utils";
+import { enumDirection, Vector } from "../../core/vector";
+import { T } from "../../translations";
+import { FilterComponent } from "../components/filter";
+import { ItemAcceptorComponent } from "../components/item_acceptor";
+import { ItemEjectorComponent } from "../components/item_ejector";
+import { enumPinSlotType, WiredPinsComponent } from "../components/wired_pins";
+import { Entity } from "../entity";
+import { defaultBuildingVariant, MetaBuilding } from "../meta_building";
+import { GameRoot } from "../root";
+import { enumHubGoalRewards } from "../tutorial_goals";
+
+export class MetaFilterBuilding extends MetaBuilding {
+ constructor() {
+ super("filter");
+ }
+
+ static getAllVariantCombinations() {
+ return [
+ {
+ internalId: 37,
+ variant: defaultBuildingVariant,
+ },
+ ];
+ }
+
+ getSilhouetteColor() {
+ return "#c45c2e";
+ }
+
+ /**
+ * @param {GameRoot} root
+ */
+ getIsUnlocked(root) {
+ return root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_filter);
+ }
+
+ getDimensions() {
+ return new Vector(2, 1);
+ }
+
+ getShowWiresLayerPreview() {
+ return true;
+ }
+
+ /**
+ * @param {GameRoot} root
+ * @param {string} variant
+ * @returns {Array<[string, string]>}
+ */
+ getAdditionalStatistics(root, variant) {
+ if (root.gameMode.throughputDoesNotMatter()) {
+ return [];
+ }
+ const beltSpeed = root.hubGoals.getBeltBaseSpeed();
+ return [[T.ingame.buildingPlacement.infoTexts.speed, formatItemsPerSecond(beltSpeed)]];
+ }
+
+ /**
+ * Creates the entity at the given location
+ * @param {Entity} entity
+ */
+ setupEntityComponents(entity) {
+ entity.addComponent(
+ new WiredPinsComponent({
+ slots: [
+ {
+ pos: new Vector(0, 0),
+ direction: enumDirection.left,
+ type: enumPinSlotType.logicalAcceptor,
+ },
+ ],
+ })
+ );
+
+ entity.addComponent(
+ new ItemAcceptorComponent({
+ slots: [
+ {
+ pos: new Vector(0, 0),
+ direction: enumDirection.bottom,
+ },
+ ],
+ })
+ );
+
+ entity.addComponent(
+ new ItemEjectorComponent({
+ slots: [
+ {
+ pos: new Vector(0, 0),
+ direction: enumDirection.top,
+ },
+ {
+ pos: new Vector(1, 0),
+ direction: enumDirection.right,
+ },
+ ],
+ })
+ );
+
+ entity.addComponent(new FilterComponent());
+ }
+}
diff --git a/src/js/game/buildings/hub.js b/src/js/game/buildings/hub.js
index a0a9227e..7620ebfe 100644
--- a/src/js/game/buildings/hub.js
+++ b/src/js/game/buildings/hub.js
@@ -36,11 +36,6 @@ export class MetaHubBuilding extends MetaBuilding {
return null;
}
- getSprite() {
- // We render it ourself
- return null;
- }
-
getIsRemovable() {
return false;
}
diff --git a/src/js/game/buildings/item_producer.js b/src/js/game/buildings/item_producer.js
index a367beae..f6378931 100644
--- a/src/js/game/buildings/item_producer.js
+++ b/src/js/game/buildings/item_producer.js
@@ -1,53 +1,53 @@
-import { enumDirection, Vector } from "../../core/vector";
-import { ItemEjectorComponent } from "../components/item_ejector";
-import { ItemProducerComponent } from "../components/item_producer";
-import { enumPinSlotType, WiredPinsComponent } from "../components/wired_pins";
-import { Entity } from "../entity";
-import { defaultBuildingVariant, MetaBuilding } from "../meta_building";
-
-export class MetaItemProducerBuilding extends MetaBuilding {
- constructor() {
- super("item_producer");
- }
-
- static getAllVariantCombinations() {
- return [
- {
- internalId: 61,
- variant: defaultBuildingVariant,
- },
- ];
- }
-
- getSilhouetteColor() {
- return "#b37dcd";
- }
-
- getShowWiresLayerPreview() {
- return true;
- }
-
- /**
- * Creates the entity at the given location
- * @param {Entity} entity
- */
- setupEntityComponents(entity) {
- entity.addComponent(
- new ItemEjectorComponent({
- slots: [{ pos: new Vector(0, 0), direction: enumDirection.top }],
- })
- );
- entity.addComponent(
- new WiredPinsComponent({
- slots: [
- {
- pos: new Vector(0, 0),
- type: enumPinSlotType.logicalAcceptor,
- direction: enumDirection.bottom,
- },
- ],
- })
- );
- entity.addComponent(new ItemProducerComponent({}));
- }
-}
+import { enumDirection, Vector } from "../../core/vector";
+import { ItemEjectorComponent } from "../components/item_ejector";
+import { ItemProducerComponent } from "../components/item_producer";
+import { enumPinSlotType, WiredPinsComponent } from "../components/wired_pins";
+import { Entity } from "../entity";
+import { defaultBuildingVariant, MetaBuilding } from "../meta_building";
+
+export class MetaItemProducerBuilding extends MetaBuilding {
+ constructor() {
+ super("item_producer");
+ }
+
+ static getAllVariantCombinations() {
+ return [
+ {
+ internalId: 61,
+ variant: defaultBuildingVariant,
+ },
+ ];
+ }
+
+ getSilhouetteColor() {
+ return "#b37dcd";
+ }
+
+ getShowWiresLayerPreview() {
+ return true;
+ }
+
+ /**
+ * Creates the entity at the given location
+ * @param {Entity} entity
+ */
+ setupEntityComponents(entity) {
+ entity.addComponent(
+ new ItemEjectorComponent({
+ slots: [{ pos: new Vector(0, 0), direction: enumDirection.top }],
+ })
+ );
+ entity.addComponent(
+ new WiredPinsComponent({
+ slots: [
+ {
+ pos: new Vector(0, 0),
+ type: enumPinSlotType.logicalAcceptor,
+ direction: enumDirection.bottom,
+ },
+ ],
+ })
+ );
+ entity.addComponent(new ItemProducerComponent({}));
+ }
+}
diff --git a/src/js/game/buildings/lever.js b/src/js/game/buildings/lever.js
index 970a4bc6..5f593e8b 100644
--- a/src/js/game/buildings/lever.js
+++ b/src/js/game/buildings/lever.js
@@ -1,66 +1,66 @@
-import { enumDirection, Vector } from "../../core/vector";
-import { enumPinSlotType, WiredPinsComponent } from "../components/wired_pins";
-import { Entity } from "../entity";
-import { defaultBuildingVariant, MetaBuilding } from "../meta_building";
-import { GameRoot } from "../root";
-import { LeverComponent } from "../components/lever";
-import { enumHubGoalRewards } from "../tutorial_goals";
-
-export class MetaLeverBuilding extends MetaBuilding {
- constructor() {
- super("lever");
- }
-
- static getAllVariantCombinations() {
- return [
- {
- internalId: 33,
- variant: defaultBuildingVariant,
- },
- ];
- }
-
- getSilhouetteColor() {
- // @todo: Render differently based on if its activated or not
- return "#1a678b";
- }
-
- /**
- * @param {GameRoot} root
- */
- getIsUnlocked(root) {
- return root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_wires_painter_and_levers);
- }
-
- getDimensions() {
- return new Vector(1, 1);
- }
-
- getSprite() {
- return null;
- }
-
- getShowWiresLayerPreview() {
- return true;
- }
-
- /**
- * Creates the entity at the given location
- * @param {Entity} entity
- */
- setupEntityComponents(entity) {
- entity.addComponent(
- new WiredPinsComponent({
- slots: [
- {
- pos: new Vector(0, 0),
- direction: enumDirection.top,
- type: enumPinSlotType.logicalEjector,
- },
- ],
- })
- );
-
- entity.addComponent(new LeverComponent({}));
- }
-}
+import { enumDirection, Vector } from "../../core/vector";
+import { enumPinSlotType, WiredPinsComponent } from "../components/wired_pins";
+import { Entity } from "../entity";
+import { defaultBuildingVariant, MetaBuilding } from "../meta_building";
+import { GameRoot } from "../root";
+import { LeverComponent } from "../components/lever";
+import { enumHubGoalRewards } from "../tutorial_goals";
+
+export class MetaLeverBuilding extends MetaBuilding {
+ constructor() {
+ super("lever");
+ }
+
+ static getAllVariantCombinations() {
+ return [
+ {
+ internalId: 33,
+ variant: defaultBuildingVariant,
+ },
+ ];
+ }
+
+ getSilhouetteColor() {
+ // @todo: Render differently based on if its activated or not
+ return "#1a678b";
+ }
+
+ /**
+ * @param {GameRoot} root
+ */
+ getIsUnlocked(root) {
+ return root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_wires_painter_and_levers);
+ }
+
+ getDimensions() {
+ return new Vector(1, 1);
+ }
+
+ getSprite() {
+ return null;
+ }
+
+ getShowWiresLayerPreview() {
+ return true;
+ }
+
+ /**
+ * Creates the entity at the given location
+ * @param {Entity} entity
+ */
+ setupEntityComponents(entity) {
+ entity.addComponent(
+ new WiredPinsComponent({
+ slots: [
+ {
+ pos: new Vector(0, 0),
+ direction: enumDirection.top,
+ type: enumPinSlotType.logicalEjector,
+ },
+ ],
+ })
+ );
+
+ entity.addComponent(new LeverComponent({}));
+ }
+}
diff --git a/src/js/game/buildings/logic_gate.js b/src/js/game/buildings/logic_gate.js
index bd5e1940..0052363e 100644
--- a/src/js/game/buildings/logic_gate.js
+++ b/src/js/game/buildings/logic_gate.js
@@ -1,172 +1,172 @@
-import { enumDirection, Vector } from "../../core/vector";
-import { enumPinSlotType, WiredPinsComponent } from "../components/wired_pins";
-import { Entity } from "../entity";
-import { MetaBuilding, defaultBuildingVariant } from "../meta_building";
-import { GameRoot } from "../root";
-import { enumLogicGateType, LogicGateComponent } from "../components/logic_gate";
-import { generateMatrixRotations } from "../../core/utils";
-import { enumHubGoalRewards } from "../tutorial_goals";
-
-/** @enum {string} */
-export const enumLogicGateVariants = {
- not: "not",
- xor: "xor",
- or: "or",
-};
-
-/** @enum {string} */
-const enumVariantToGate = {
- [defaultBuildingVariant]: enumLogicGateType.and,
- [enumLogicGateVariants.not]: enumLogicGateType.not,
- [enumLogicGateVariants.xor]: enumLogicGateType.xor,
- [enumLogicGateVariants.or]: enumLogicGateType.or,
-};
-
-const overlayMatrices = {
- [defaultBuildingVariant]: generateMatrixRotations([0, 1, 0, 1, 1, 1, 0, 1, 1]),
- [enumLogicGateVariants.xor]: generateMatrixRotations([0, 1, 0, 1, 1, 1, 0, 1, 1]),
- [enumLogicGateVariants.or]: generateMatrixRotations([0, 1, 0, 1, 1, 1, 0, 1, 1]),
- [enumLogicGateVariants.not]: generateMatrixRotations([0, 1, 0, 0, 1, 0, 0, 1, 0]),
-};
-
-const colors = {
- [defaultBuildingVariant]: "#f48d41",
- [enumLogicGateVariants.xor]: "#f4a241",
- [enumLogicGateVariants.or]: "#f4d041",
- [enumLogicGateVariants.not]: "#f44184",
-};
-
-export class MetaLogicGateBuilding extends MetaBuilding {
- constructor() {
- super("logic_gate");
- }
-
- static getAllVariantCombinations() {
- return [
- {
- internalId: 32,
- variant: defaultBuildingVariant,
- },
- {
- internalId: 34,
- variant: enumLogicGateVariants.not,
- },
- {
- internalId: 35,
- variant: enumLogicGateVariants.xor,
- },
- {
- internalId: 36,
- variant: enumLogicGateVariants.or,
- },
- ];
- }
-
- getSilhouetteColor(variant) {
- return colors[variant];
- }
-
- /**
- * @param {GameRoot} root
- */
- getIsUnlocked(root) {
- return root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_logic_gates);
- }
-
- /** @returns {"wires"} **/
- getLayer() {
- return "wires";
- }
-
- getDimensions() {
- return new Vector(1, 1);
- }
-
- getSpecialOverlayRenderMatrix(rotation, rotationVariant, variant) {
- return overlayMatrices[variant][rotation];
- }
-
- getAvailableVariants() {
- return [
- defaultBuildingVariant,
- enumLogicGateVariants.or,
- enumLogicGateVariants.not,
- enumLogicGateVariants.xor,
- ];
- }
-
- getRenderPins() {
- // We already have it included
- return false;
- }
-
- /**
- *
- * @param {Entity} entity
- * @param {number} rotationVariant
- */
- updateVariants(entity, rotationVariant, variant) {
- const gateType = enumVariantToGate[variant];
- entity.components.LogicGate.type = gateType;
-
- const pinComp = entity.components.WiredPins;
-
- switch (gateType) {
- case enumLogicGateType.and:
- case enumLogicGateType.xor:
- case enumLogicGateType.or: {
- pinComp.setSlots([
- {
- pos: new Vector(0, 0),
- direction: enumDirection.top,
- type: enumPinSlotType.logicalEjector,
- },
- {
- pos: new Vector(0, 0),
- direction: enumDirection.left,
- type: enumPinSlotType.logicalAcceptor,
- },
- {
- pos: new Vector(0, 0),
- direction: enumDirection.right,
- type: enumPinSlotType.logicalAcceptor,
- },
- ]);
- break;
- }
-
- case enumLogicGateType.not: {
- pinComp.setSlots([
- {
- pos: new Vector(0, 0),
- direction: enumDirection.top,
- type: enumPinSlotType.logicalEjector,
- },
- {
- pos: new Vector(0, 0),
- direction: enumDirection.bottom,
- type: enumPinSlotType.logicalAcceptor,
- },
- ]);
- break;
- }
-
- default:
- assertAlways("unknown logic gate type: " + gateType);
- }
- }
-
- /**
- * Creates the entity at the given location
- * @param {Entity} entity
- */
- setupEntityComponents(entity) {
- entity.addComponent(
- new WiredPinsComponent({
- slots: [],
- })
- );
-
- entity.addComponent(new LogicGateComponent({}));
- }
-}
+import { enumDirection, Vector } from "../../core/vector";
+import { enumPinSlotType, WiredPinsComponent } from "../components/wired_pins";
+import { Entity } from "../entity";
+import { MetaBuilding, defaultBuildingVariant } from "../meta_building";
+import { GameRoot } from "../root";
+import { enumLogicGateType, LogicGateComponent } from "../components/logic_gate";
+import { generateMatrixRotations } from "../../core/utils";
+import { enumHubGoalRewards } from "../tutorial_goals";
+
+/** @enum {string} */
+export const enumLogicGateVariants = {
+ not: "not",
+ xor: "xor",
+ or: "or",
+};
+
+/** @enum {string} */
+const enumVariantToGate = {
+ [defaultBuildingVariant]: enumLogicGateType.and,
+ [enumLogicGateVariants.not]: enumLogicGateType.not,
+ [enumLogicGateVariants.xor]: enumLogicGateType.xor,
+ [enumLogicGateVariants.or]: enumLogicGateType.or,
+};
+
+const overlayMatrices = {
+ [defaultBuildingVariant]: generateMatrixRotations([0, 1, 0, 1, 1, 1, 0, 1, 1]),
+ [enumLogicGateVariants.xor]: generateMatrixRotations([0, 1, 0, 1, 1, 1, 0, 1, 1]),
+ [enumLogicGateVariants.or]: generateMatrixRotations([0, 1, 0, 1, 1, 1, 0, 1, 1]),
+ [enumLogicGateVariants.not]: generateMatrixRotations([0, 1, 0, 0, 1, 0, 0, 1, 0]),
+};
+
+const colors = {
+ [defaultBuildingVariant]: "#f48d41",
+ [enumLogicGateVariants.xor]: "#f4a241",
+ [enumLogicGateVariants.or]: "#f4d041",
+ [enumLogicGateVariants.not]: "#f44184",
+};
+
+export class MetaLogicGateBuilding extends MetaBuilding {
+ constructor() {
+ super("logic_gate");
+ }
+
+ static getAllVariantCombinations() {
+ return [
+ {
+ internalId: 32,
+ variant: defaultBuildingVariant,
+ },
+ {
+ internalId: 34,
+ variant: enumLogicGateVariants.not,
+ },
+ {
+ internalId: 35,
+ variant: enumLogicGateVariants.xor,
+ },
+ {
+ internalId: 36,
+ variant: enumLogicGateVariants.or,
+ },
+ ];
+ }
+
+ getSilhouetteColor(variant) {
+ return colors[variant];
+ }
+
+ /**
+ * @param {GameRoot} root
+ */
+ getIsUnlocked(root) {
+ return root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_logic_gates);
+ }
+
+ /** @returns {"wires"} **/
+ getLayer() {
+ return "wires";
+ }
+
+ getDimensions() {
+ return new Vector(1, 1);
+ }
+
+ getSpecialOverlayRenderMatrix(rotation, rotationVariant, variant) {
+ return overlayMatrices[variant][rotation];
+ }
+
+ getAvailableVariants() {
+ return [
+ defaultBuildingVariant,
+ enumLogicGateVariants.or,
+ enumLogicGateVariants.not,
+ enumLogicGateVariants.xor,
+ ];
+ }
+
+ getRenderPins() {
+ // We already have it included
+ return false;
+ }
+
+ /**
+ *
+ * @param {Entity} entity
+ * @param {number} rotationVariant
+ */
+ updateVariants(entity, rotationVariant, variant) {
+ const gateType = enumVariantToGate[variant];
+ entity.components.LogicGate.type = gateType;
+
+ const pinComp = entity.components.WiredPins;
+
+ switch (gateType) {
+ case enumLogicGateType.and:
+ case enumLogicGateType.xor:
+ case enumLogicGateType.or: {
+ pinComp.setSlots([
+ {
+ pos: new Vector(0, 0),
+ direction: enumDirection.top,
+ type: enumPinSlotType.logicalEjector,
+ },
+ {
+ pos: new Vector(0, 0),
+ direction: enumDirection.left,
+ type: enumPinSlotType.logicalAcceptor,
+ },
+ {
+ pos: new Vector(0, 0),
+ direction: enumDirection.right,
+ type: enumPinSlotType.logicalAcceptor,
+ },
+ ]);
+ break;
+ }
+
+ case enumLogicGateType.not: {
+ pinComp.setSlots([
+ {
+ pos: new Vector(0, 0),
+ direction: enumDirection.top,
+ type: enumPinSlotType.logicalEjector,
+ },
+ {
+ pos: new Vector(0, 0),
+ direction: enumDirection.bottom,
+ type: enumPinSlotType.logicalAcceptor,
+ },
+ ]);
+ break;
+ }
+
+ default:
+ assertAlways("unknown logic gate type: " + gateType);
+ }
+ }
+
+ /**
+ * Creates the entity at the given location
+ * @param {Entity} entity
+ */
+ setupEntityComponents(entity) {
+ entity.addComponent(
+ new WiredPinsComponent({
+ slots: [],
+ })
+ );
+
+ entity.addComponent(new LogicGateComponent({}));
+ }
+}
diff --git a/src/js/game/buildings/miner.js b/src/js/game/buildings/miner.js
index b086a562..5365b67f 100644
--- a/src/js/game/buildings/miner.js
+++ b/src/js/game/buildings/miner.js
@@ -1,97 +1,97 @@
-import { enumDirection, Vector } from "../../core/vector";
-import { ItemEjectorComponent } from "../components/item_ejector";
-import { MinerComponent } from "../components/miner";
-import { Entity } from "../entity";
-import { MetaBuilding, defaultBuildingVariant } from "../meta_building";
-import { GameRoot } from "../root";
-import { enumHubGoalRewards } from "../tutorial_goals";
-import { T } from "../../translations";
-import { formatItemsPerSecond, generateMatrixRotations } from "../../core/utils";
-
-/** @enum {string} */
-export const enumMinerVariants = { chainable: "chainable" };
-
-const overlayMatrix = {
- [defaultBuildingVariant]: generateMatrixRotations([1, 1, 1, 1, 0, 1, 1, 1, 1]),
- [enumMinerVariants.chainable]: generateMatrixRotations([0, 1, 0, 1, 1, 1, 1, 1, 1]),
-};
-
-export class MetaMinerBuilding extends MetaBuilding {
- constructor() {
- super("miner");
- }
-
- static getAllVariantCombinations() {
- return [
- {
- internalId: 7,
- variant: defaultBuildingVariant,
- },
- {
- internalId: 8,
- variant: enumMinerVariants.chainable,
- },
- ];
- }
-
- getSilhouetteColor() {
- return "#b37dcd";
- }
-
- /**
- * @param {GameRoot} root
- * @param {string} variant
- * @returns {Array<[string, string]>}
- */
- getAdditionalStatistics(root, variant) {
- if (root.gameMode.throughputDoesNotMatter()) {
- return [];
- }
- const speed = root.hubGoals.getMinerBaseSpeed();
- return [[T.ingame.buildingPlacement.infoTexts.speed, formatItemsPerSecond(speed)]];
- }
-
- /**
- *
- * @param {GameRoot} root
- */
- getAvailableVariants(root) {
- if (root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_miner_chainable)) {
- return [enumMinerVariants.chainable];
- }
- return super.getAvailableVariants(root);
- }
-
- /**
- * @param {number} rotation
- * @param {number} rotationVariant
- * @param {string} variant
- * @param {Entity} entity
- */
- getSpecialOverlayRenderMatrix(rotation, rotationVariant, variant, entity) {
- return overlayMatrix[variant][rotation];
- }
-
- /**
- * Creates the entity at the given location
- * @param {Entity} entity
- */
- setupEntityComponents(entity) {
- entity.addComponent(new MinerComponent({}));
- entity.addComponent(
- new ItemEjectorComponent({
- slots: [{ pos: new Vector(0, 0), direction: enumDirection.top }],
- })
- );
- }
-
- /**
- *
- * @param {Entity} entity
- * @param {number} rotationVariant
- * @param {string} variant
- */
- updateVariants(entity, rotationVariant, variant) {
- entity.components.Miner.chainable = variant === enumMinerVariants.chainable;
- }
-}
+import { enumDirection, Vector } from "../../core/vector";
+import { ItemEjectorComponent } from "../components/item_ejector";
+import { MinerComponent } from "../components/miner";
+import { Entity } from "../entity";
+import { MetaBuilding, defaultBuildingVariant } from "../meta_building";
+import { GameRoot } from "../root";
+import { enumHubGoalRewards } from "../tutorial_goals";
+import { T } from "../../translations";
+import { formatItemsPerSecond, generateMatrixRotations } from "../../core/utils";
+
+/** @enum {string} */
+export const enumMinerVariants = { chainable: "chainable" };
+
+const overlayMatrix = {
+ [defaultBuildingVariant]: generateMatrixRotations([1, 1, 1, 1, 0, 1, 1, 1, 1]),
+ [enumMinerVariants.chainable]: generateMatrixRotations([0, 1, 0, 1, 1, 1, 1, 1, 1]),
+};
+
+export class MetaMinerBuilding extends MetaBuilding {
+ constructor() {
+ super("miner");
+ }
+
+ static getAllVariantCombinations() {
+ return [
+ {
+ internalId: 7,
+ variant: defaultBuildingVariant,
+ },
+ {
+ internalId: 8,
+ variant: enumMinerVariants.chainable,
+ },
+ ];
+ }
+
+ getSilhouetteColor() {
+ return "#b37dcd";
+ }
+
+ /**
+ * @param {GameRoot} root
+ * @param {string} variant
+ * @returns {Array<[string, string]>}
+ */
+ getAdditionalStatistics(root, variant) {
+ if (root.gameMode.throughputDoesNotMatter()) {
+ return [];
+ }
+ const speed = root.hubGoals.getMinerBaseSpeed();
+ return [[T.ingame.buildingPlacement.infoTexts.speed, formatItemsPerSecond(speed)]];
+ }
+
+ /**
+ *
+ * @param {GameRoot} root
+ */
+ getAvailableVariants(root) {
+ if (root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_miner_chainable)) {
+ return [enumMinerVariants.chainable];
+ }
+ return super.getAvailableVariants(root);
+ }
+
+ /**
+ * @param {number} rotation
+ * @param {number} rotationVariant
+ * @param {string} variant
+ * @param {Entity} entity
+ */
+ getSpecialOverlayRenderMatrix(rotation, rotationVariant, variant, entity) {
+ return overlayMatrix[variant][rotation];
+ }
+
+ /**
+ * Creates the entity at the given location
+ * @param {Entity} entity
+ */
+ setupEntityComponents(entity) {
+ entity.addComponent(new MinerComponent({}));
+ entity.addComponent(
+ new ItemEjectorComponent({
+ slots: [{ pos: new Vector(0, 0), direction: enumDirection.top }],
+ })
+ );
+ }
+
+ /**
+ *
+ * @param {Entity} entity
+ * @param {number} rotationVariant
+ * @param {string} variant
+ */
+ updateVariants(entity, rotationVariant, variant) {
+ entity.components.Miner.chainable = variant === enumMinerVariants.chainable;
+ }
+}
diff --git a/src/js/game/buildings/reader.js b/src/js/game/buildings/reader.js
index 5c9307c3..417d2fcb 100644
--- a/src/js/game/buildings/reader.js
+++ b/src/js/game/buildings/reader.js
@@ -1,124 +1,124 @@
-import { enumDirection, Vector } from "../../core/vector";
-import { ItemAcceptorComponent } from "../components/item_acceptor";
-import { ItemEjectorComponent } from "../components/item_ejector";
-import { enumItemProcessorTypes, ItemProcessorComponent } from "../components/item_processor";
-import { enumPinSlotType, WiredPinsComponent } from "../components/wired_pins";
-import { Entity } from "../entity";
-import { defaultBuildingVariant, MetaBuilding } from "../meta_building";
-import { GameRoot } from "../root";
-import { BeltUnderlaysComponent } from "../components/belt_underlays";
-import { BeltReaderComponent } from "../components/belt_reader";
-import { enumHubGoalRewards } from "../tutorial_goals";
-import { generateMatrixRotations } from "../../core/utils";
-
-const overlayMatrix = generateMatrixRotations([0, 1, 0, 0, 1, 0, 0, 1, 0]);
-
-export class MetaReaderBuilding extends MetaBuilding {
- constructor() {
- super("reader");
- }
-
- static getAllVariantCombinations() {
- return [
- {
- internalId: 49,
- variant: defaultBuildingVariant,
- },
- ];
- }
-
- getSilhouetteColor() {
- return "#25fff2";
- }
-
- /**
- * @param {GameRoot} root
- */
- getIsUnlocked(root) {
- return root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_belt_reader);
- }
-
- getDimensions() {
- return new Vector(1, 1);
- }
-
- getShowWiresLayerPreview() {
- return true;
- }
-
- /**
- * @param {number} rotation
- * @param {number} rotationVariant
- * @param {string} variant
- * @param {Entity} entity
- * @returns {Array|null}
- */
- getSpecialOverlayRenderMatrix(rotation, rotationVariant, variant, entity) {
- return overlayMatrix[rotation];
- }
-
- /**
- * Creates the entity at the given location
- * @param {Entity} entity
- */
- setupEntityComponents(entity) {
- entity.addComponent(
- new WiredPinsComponent({
- slots: [
- {
- pos: new Vector(0, 0),
- direction: enumDirection.right,
- type: enumPinSlotType.logicalEjector,
- },
- {
- pos: new Vector(0, 0),
- direction: enumDirection.left,
- type: enumPinSlotType.logicalEjector,
- },
- ],
- })
- );
-
- entity.addComponent(
- new ItemAcceptorComponent({
- slots: [
- {
- pos: new Vector(0, 0),
- direction: enumDirection.bottom,
- },
- ],
- })
- );
-
- entity.addComponent(
- new ItemEjectorComponent({
- slots: [
- {
- pos: new Vector(0, 0),
- direction: enumDirection.top,
- },
- ],
- })
- );
-
- entity.addComponent(
- new ItemProcessorComponent({
- processorType: enumItemProcessorTypes.reader,
- inputsPerCharge: 1,
- })
- );
-
- entity.addComponent(
- new BeltUnderlaysComponent({
- underlays: [
- {
- pos: new Vector(0, 0),
- direction: enumDirection.top,
- },
- ],
- })
- );
-
- entity.addComponent(new BeltReaderComponent());
- }
-}
+import { enumDirection, Vector } from "../../core/vector";
+import { ItemAcceptorComponent } from "../components/item_acceptor";
+import { ItemEjectorComponent } from "../components/item_ejector";
+import { enumItemProcessorTypes, ItemProcessorComponent } from "../components/item_processor";
+import { enumPinSlotType, WiredPinsComponent } from "../components/wired_pins";
+import { Entity } from "../entity";
+import { defaultBuildingVariant, MetaBuilding } from "../meta_building";
+import { GameRoot } from "../root";
+import { BeltUnderlaysComponent } from "../components/belt_underlays";
+import { BeltReaderComponent } from "../components/belt_reader";
+import { enumHubGoalRewards } from "../tutorial_goals";
+import { generateMatrixRotations } from "../../core/utils";
+
+const overlayMatrix = generateMatrixRotations([0, 1, 0, 0, 1, 0, 0, 1, 0]);
+
+export class MetaReaderBuilding extends MetaBuilding {
+ constructor() {
+ super("reader");
+ }
+
+ static getAllVariantCombinations() {
+ return [
+ {
+ internalId: 49,
+ variant: defaultBuildingVariant,
+ },
+ ];
+ }
+
+ getSilhouetteColor() {
+ return "#25fff2";
+ }
+
+ /**
+ * @param {GameRoot} root
+ */
+ getIsUnlocked(root) {
+ return root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_belt_reader);
+ }
+
+ getDimensions() {
+ return new Vector(1, 1);
+ }
+
+ getShowWiresLayerPreview() {
+ return true;
+ }
+
+ /**
+ * @param {number} rotation
+ * @param {number} rotationVariant
+ * @param {string} variant
+ * @param {Entity} entity
+ * @returns {Array|null}
+ */
+ getSpecialOverlayRenderMatrix(rotation, rotationVariant, variant, entity) {
+ return overlayMatrix[rotation];
+ }
+
+ /**
+ * Creates the entity at the given location
+ * @param {Entity} entity
+ */
+ setupEntityComponents(entity) {
+ entity.addComponent(
+ new WiredPinsComponent({
+ slots: [
+ {
+ pos: new Vector(0, 0),
+ direction: enumDirection.right,
+ type: enumPinSlotType.logicalEjector,
+ },
+ {
+ pos: new Vector(0, 0),
+ direction: enumDirection.left,
+ type: enumPinSlotType.logicalEjector,
+ },
+ ],
+ })
+ );
+
+ entity.addComponent(
+ new ItemAcceptorComponent({
+ slots: [
+ {
+ pos: new Vector(0, 0),
+ direction: enumDirection.bottom,
+ },
+ ],
+ })
+ );
+
+ entity.addComponent(
+ new ItemEjectorComponent({
+ slots: [
+ {
+ pos: new Vector(0, 0),
+ direction: enumDirection.top,
+ },
+ ],
+ })
+ );
+
+ entity.addComponent(
+ new ItemProcessorComponent({
+ processorType: enumItemProcessorTypes.reader,
+ inputsPerCharge: 1,
+ })
+ );
+
+ entity.addComponent(
+ new BeltUnderlaysComponent({
+ underlays: [
+ {
+ pos: new Vector(0, 0),
+ direction: enumDirection.top,
+ },
+ ],
+ })
+ );
+
+ entity.addComponent(new BeltReaderComponent());
+ }
+}
diff --git a/src/js/game/buildings/rotater.js b/src/js/game/buildings/rotator.js
similarity index 78%
rename from src/js/game/buildings/rotater.js
rename to src/js/game/buildings/rotator.js
index e1080767..b0a86f67 100644
--- a/src/js/game/buildings/rotater.js
+++ b/src/js/game/buildings/rotator.js
@@ -1,163 +1,163 @@
-import { formatItemsPerSecond, generateMatrixRotations } from "../../core/utils";
-import { enumDirection, Vector } from "../../core/vector";
-import { T } from "../../translations";
-import { ItemAcceptorComponent } from "../components/item_acceptor";
-import { ItemEjectorComponent } from "../components/item_ejector";
-import { enumItemProcessorTypes, ItemProcessorComponent } from "../components/item_processor";
-import { Entity } from "../entity";
-import { defaultBuildingVariant, MetaBuilding } from "../meta_building";
-import { GameRoot } from "../root";
-import { enumHubGoalRewards } from "../tutorial_goals";
-
-/** @enum {string} */
-export const enumRotaterVariants = { ccw: "ccw", rotate180: "rotate180" };
-
-const overlayMatrices = {
- [defaultBuildingVariant]: generateMatrixRotations([0, 1, 1, 1, 1, 0, 0, 1, 1]),
- [enumRotaterVariants.ccw]: generateMatrixRotations([1, 1, 0, 0, 1, 1, 1, 1, 0]),
- [enumRotaterVariants.rotate180]: generateMatrixRotations([1, 1, 0, 1, 1, 1, 0, 1, 1]),
-};
-
-export class MetaRotaterBuilding extends MetaBuilding {
- constructor() {
- super("rotater");
- }
-
- static getAllVariantCombinations() {
- return [
- {
- internalId: 11,
- variant: defaultBuildingVariant,
- },
- {
- internalId: 12,
- variant: enumRotaterVariants.ccw,
- },
- {
- internalId: 13,
- variant: enumRotaterVariants.rotate180,
- },
- ];
- }
-
- getSilhouetteColor() {
- return "#7dc6cd";
- }
-
- /**
- * @param {number} rotation
- * @param {number} rotationVariant
- * @param {string} variant
- * @param {Entity} entity
- * @returns {Array|null}
- */
- getSpecialOverlayRenderMatrix(rotation, rotationVariant, variant, entity) {
- const matrix = overlayMatrices[variant];
- if (matrix) {
- return matrix[rotation];
- }
- return null;
- }
-
- /**
- * @param {GameRoot} root
- * @param {string} variant
- * @returns {Array<[string, string]>}
- */
- getAdditionalStatistics(root, variant) {
- if (root.gameMode.throughputDoesNotMatter()) {
- return [];
- }
- switch (variant) {
- case defaultBuildingVariant: {
- const speed = root.hubGoals.getProcessorBaseSpeed(enumItemProcessorTypes.rotater);
- return [[T.ingame.buildingPlacement.infoTexts.speed, formatItemsPerSecond(speed)]];
- }
- case enumRotaterVariants.ccw: {
- const speed = root.hubGoals.getProcessorBaseSpeed(enumItemProcessorTypes.rotaterCCW);
- return [[T.ingame.buildingPlacement.infoTexts.speed, formatItemsPerSecond(speed)]];
- }
- case enumRotaterVariants.rotate180: {
- const speed = root.hubGoals.getProcessorBaseSpeed(enumItemProcessorTypes.rotater180);
- return [[T.ingame.buildingPlacement.infoTexts.speed, formatItemsPerSecond(speed)]];
- }
- }
- }
-
- /**
- *
- * @param {GameRoot} root
- */
- getAvailableVariants(root) {
- let variants = [defaultBuildingVariant];
- if (root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_rotater_ccw)) {
- variants.push(enumRotaterVariants.ccw);
- }
- if (root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_rotater_180)) {
- variants.push(enumRotaterVariants.rotate180);
- }
- return variants;
- }
-
- /**
- * @param {GameRoot} root
- */
- getIsUnlocked(root) {
- return root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_rotater);
- }
-
- /**
- * Creates the entity at the given location
- * @param {Entity} entity
- */
- setupEntityComponents(entity) {
- entity.addComponent(
- new ItemProcessorComponent({
- inputsPerCharge: 1,
- processorType: enumItemProcessorTypes.rotater,
- })
- );
-
- entity.addComponent(
- new ItemEjectorComponent({
- slots: [{ pos: new Vector(0, 0), direction: enumDirection.top }],
- })
- );
- entity.addComponent(
- new ItemAcceptorComponent({
- slots: [
- {
- pos: new Vector(0, 0),
- direction: enumDirection.bottom,
- filter: "shape",
- },
- ],
- })
- );
- }
-
- /**
- *
- * @param {Entity} entity
- * @param {number} rotationVariant
- * @param {string} variant
- */
- updateVariants(entity, rotationVariant, variant) {
- switch (variant) {
- case defaultBuildingVariant: {
- entity.components.ItemProcessor.type = enumItemProcessorTypes.rotater;
- break;
- }
- case enumRotaterVariants.ccw: {
- entity.components.ItemProcessor.type = enumItemProcessorTypes.rotaterCCW;
- break;
- }
- case enumRotaterVariants.rotate180: {
- entity.components.ItemProcessor.type = enumItemProcessorTypes.rotater180;
- break;
- }
- default:
- assertAlways(false, "Unknown rotater variant: " + variant);
- }
- }
-}
+import { formatItemsPerSecond, generateMatrixRotations } from "../../core/utils";
+import { enumDirection, Vector } from "../../core/vector";
+import { T } from "../../translations";
+import { ItemAcceptorComponent } from "../components/item_acceptor";
+import { ItemEjectorComponent } from "../components/item_ejector";
+import { enumItemProcessorTypes, ItemProcessorComponent } from "../components/item_processor";
+import { Entity } from "../entity";
+import { defaultBuildingVariant, MetaBuilding } from "../meta_building";
+import { GameRoot } from "../root";
+import { enumHubGoalRewards } from "../tutorial_goals";
+
+/** @enum {string} */
+export const enumRotatorVariants = { ccw: "ccw", rotate180: "rotate180" };
+
+const overlayMatrices = {
+ [defaultBuildingVariant]: generateMatrixRotations([0, 1, 1, 1, 1, 0, 0, 1, 1]),
+ [enumRotatorVariants.ccw]: generateMatrixRotations([1, 1, 0, 0, 1, 1, 1, 1, 0]),
+ [enumRotatorVariants.rotate180]: generateMatrixRotations([1, 1, 0, 1, 1, 1, 0, 1, 1]),
+};
+
+export class MetaRotatorBuilding extends MetaBuilding {
+ constructor() {
+ super("rotator");
+ }
+
+ static getAllVariantCombinations() {
+ return [
+ {
+ internalId: 11,
+ variant: defaultBuildingVariant,
+ },
+ {
+ internalId: 12,
+ variant: enumRotatorVariants.ccw,
+ },
+ {
+ internalId: 13,
+ variant: enumRotatorVariants.rotate180,
+ },
+ ];
+ }
+
+ getSilhouetteColor() {
+ return "#7dc6cd";
+ }
+
+ /**
+ * @param {number} rotation
+ * @param {number} rotationVariant
+ * @param {string} variant
+ * @param {Entity} entity
+ * @returns {Array|null}
+ */
+ getSpecialOverlayRenderMatrix(rotation, rotationVariant, variant, entity) {
+ const matrix = overlayMatrices[variant];
+ if (matrix) {
+ return matrix[rotation];
+ }
+ return null;
+ }
+
+ /**
+ * @param {GameRoot} root
+ * @param {string} variant
+ * @returns {Array<[string, string]>}
+ */
+ getAdditionalStatistics(root, variant) {
+ if (root.gameMode.throughputDoesNotMatter()) {
+ return [];
+ }
+ switch (variant) {
+ case defaultBuildingVariant: {
+ const speed = root.hubGoals.getProcessorBaseSpeed(enumItemProcessorTypes.rotator);
+ return [[T.ingame.buildingPlacement.infoTexts.speed, formatItemsPerSecond(speed)]];
+ }
+ case enumRotatorVariants.ccw: {
+ const speed = root.hubGoals.getProcessorBaseSpeed(enumItemProcessorTypes.rotatorCCW);
+ return [[T.ingame.buildingPlacement.infoTexts.speed, formatItemsPerSecond(speed)]];
+ }
+ case enumRotatorVariants.rotate180: {
+ const speed = root.hubGoals.getProcessorBaseSpeed(enumItemProcessorTypes.rotator180);
+ return [[T.ingame.buildingPlacement.infoTexts.speed, formatItemsPerSecond(speed)]];
+ }
+ }
+ }
+
+ /**
+ *
+ * @param {GameRoot} root
+ */
+ getAvailableVariants(root) {
+ let variants = [defaultBuildingVariant];
+ if (root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_rotator_ccw)) {
+ variants.push(enumRotatorVariants.ccw);
+ }
+ if (root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_rotator_180)) {
+ variants.push(enumRotatorVariants.rotate180);
+ }
+ return variants;
+ }
+
+ /**
+ * @param {GameRoot} root
+ */
+ getIsUnlocked(root) {
+ return root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_rotator);
+ }
+
+ /**
+ * Creates the entity at the given location
+ * @param {Entity} entity
+ */
+ setupEntityComponents(entity) {
+ entity.addComponent(
+ new ItemProcessorComponent({
+ inputsPerCharge: 1,
+ processorType: enumItemProcessorTypes.rotator,
+ })
+ );
+
+ entity.addComponent(
+ new ItemEjectorComponent({
+ slots: [{ pos: new Vector(0, 0), direction: enumDirection.top }],
+ })
+ );
+ entity.addComponent(
+ new ItemAcceptorComponent({
+ slots: [
+ {
+ pos: new Vector(0, 0),
+ direction: enumDirection.bottom,
+ filter: "shape",
+ },
+ ],
+ })
+ );
+ }
+
+ /**
+ *
+ * @param {Entity} entity
+ * @param {number} rotationVariant
+ * @param {string} variant
+ */
+ updateVariants(entity, rotationVariant, variant) {
+ switch (variant) {
+ case defaultBuildingVariant: {
+ entity.components.ItemProcessor.type = enumItemProcessorTypes.rotator;
+ break;
+ }
+ case enumRotatorVariants.ccw: {
+ entity.components.ItemProcessor.type = enumItemProcessorTypes.rotatorCCW;
+ break;
+ }
+ case enumRotatorVariants.rotate180: {
+ entity.components.ItemProcessor.type = enumItemProcessorTypes.rotator180;
+ break;
+ }
+ default:
+ assertAlways(false, "Unknown rotator variant: " + variant);
+ }
+ }
+}
diff --git a/src/js/game/buildings/storage.js b/src/js/game/buildings/storage.js
index 78f398be..4a8d39c5 100644
--- a/src/js/game/buildings/storage.js
+++ b/src/js/game/buildings/storage.js
@@ -1,110 +1,110 @@
-import { formatBigNumber } from "../../core/utils";
-import { enumDirection, Vector } from "../../core/vector";
-import { T } from "../../translations";
-import { ItemAcceptorComponent } from "../components/item_acceptor";
-import { ItemEjectorComponent } from "../components/item_ejector";
-import { StorageComponent } from "../components/storage";
-import { enumPinSlotType, WiredPinsComponent } from "../components/wired_pins";
-import { Entity } from "../entity";
-import { defaultBuildingVariant, MetaBuilding } from "../meta_building";
-import { GameRoot } from "../root";
-import { enumHubGoalRewards } from "../tutorial_goals";
-
-const storageSize = 5000;
-
-export class MetaStorageBuilding extends MetaBuilding {
- constructor() {
- super("storage");
- }
-
- static getAllVariantCombinations() {
- return [
- {
- internalId: 21,
- variant: defaultBuildingVariant,
- },
- ];
- }
-
- getSilhouetteColor() {
- return "#bbdf6d";
- }
-
- /**
- * @returns {Array<[string, string]>}
- */
- getAdditionalStatistics(root, variant) {
- return [[T.ingame.buildingPlacement.infoTexts.storage, formatBigNumber(storageSize)]];
- }
-
- getDimensions() {
- return new Vector(2, 2);
- }
-
- /**
- * @param {GameRoot} root
- */
- getIsUnlocked(root) {
- return root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_storage);
- }
-
- /**
- * Creates the entity at the given location
- * @param {Entity} entity
- */
- setupEntityComponents(entity) {
- // Required, since the item processor needs this.
- entity.addComponent(
- new ItemEjectorComponent({
- slots: [
- {
- pos: new Vector(0, 0),
- direction: enumDirection.top,
- },
- {
- pos: new Vector(1, 0),
- direction: enumDirection.top,
- },
- ],
- })
- );
-
- entity.addComponent(
- new ItemAcceptorComponent({
- slots: [
- {
- pos: new Vector(0, 1),
- direction: enumDirection.bottom,
- },
- {
- pos: new Vector(1, 1),
- direction: enumDirection.bottom,
- },
- ],
- })
- );
-
- entity.addComponent(
- new StorageComponent({
- maximumStorage: storageSize,
- })
- );
-
- entity.addComponent(
- new WiredPinsComponent({
- slots: [
- {
- pos: new Vector(1, 1),
- direction: enumDirection.right,
- type: enumPinSlotType.logicalEjector,
- },
- {
- pos: new Vector(0, 1),
- direction: enumDirection.left,
- type: enumPinSlotType.logicalEjector,
- },
- ],
- })
- );
- }
-}
+import { formatBigNumber } from "../../core/utils";
+import { enumDirection, Vector } from "../../core/vector";
+import { T } from "../../translations";
+import { ItemAcceptorComponent } from "../components/item_acceptor";
+import { ItemEjectorComponent } from "../components/item_ejector";
+import { StorageComponent } from "../components/storage";
+import { enumPinSlotType, WiredPinsComponent } from "../components/wired_pins";
+import { Entity } from "../entity";
+import { defaultBuildingVariant, MetaBuilding } from "../meta_building";
+import { GameRoot } from "../root";
+import { enumHubGoalRewards } from "../tutorial_goals";
+
+const storageSize = 5000;
+
+export class MetaStorageBuilding extends MetaBuilding {
+ constructor() {
+ super("storage");
+ }
+
+ static getAllVariantCombinations() {
+ return [
+ {
+ internalId: 21,
+ variant: defaultBuildingVariant,
+ },
+ ];
+ }
+
+ getSilhouetteColor() {
+ return "#bbdf6d";
+ }
+
+ /**
+ * @returns {Array<[string, string]>}
+ */
+ getAdditionalStatistics(root, variant) {
+ return [[T.ingame.buildingPlacement.infoTexts.storage, formatBigNumber(storageSize)]];
+ }
+
+ getDimensions() {
+ return new Vector(2, 2);
+ }
+
+ /**
+ * @param {GameRoot} root
+ */
+ getIsUnlocked(root) {
+ return root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_storage);
+ }
+
+ /**
+ * Creates the entity at the given location
+ * @param {Entity} entity
+ */
+ setupEntityComponents(entity) {
+ // Required, since the item processor needs this.
+ entity.addComponent(
+ new ItemEjectorComponent({
+ slots: [
+ {
+ pos: new Vector(0, 0),
+ direction: enumDirection.top,
+ },
+ {
+ pos: new Vector(1, 0),
+ direction: enumDirection.top,
+ },
+ ],
+ })
+ );
+
+ entity.addComponent(
+ new ItemAcceptorComponent({
+ slots: [
+ {
+ pos: new Vector(0, 1),
+ direction: enumDirection.bottom,
+ },
+ {
+ pos: new Vector(1, 1),
+ direction: enumDirection.bottom,
+ },
+ ],
+ })
+ );
+
+ entity.addComponent(
+ new StorageComponent({
+ maximumStorage: storageSize,
+ })
+ );
+
+ entity.addComponent(
+ new WiredPinsComponent({
+ slots: [
+ {
+ pos: new Vector(1, 1),
+ direction: enumDirection.right,
+ type: enumPinSlotType.logicalEjector,
+ },
+ {
+ pos: new Vector(0, 1),
+ direction: enumDirection.left,
+ type: enumPinSlotType.logicalEjector,
+ },
+ ],
+ })
+ );
+ }
+}
diff --git a/src/js/game/buildings/transistor.js b/src/js/game/buildings/transistor.js
index 1505903a..8db1dbac 100644
--- a/src/js/game/buildings/transistor.js
+++ b/src/js/game/buildings/transistor.js
@@ -1,114 +1,114 @@
-import { generateMatrixRotations } from "../../core/utils";
-import { enumDirection, Vector } from "../../core/vector";
-import { enumLogicGateType, LogicGateComponent } from "../components/logic_gate";
-import { enumPinSlotType, WiredPinsComponent } from "../components/wired_pins";
-import { Entity } from "../entity";
-import { defaultBuildingVariant, MetaBuilding } from "../meta_building";
-import { GameRoot } from "../root";
-import { enumHubGoalRewards } from "../tutorial_goals";
-
-/** @enum {string} */
-export const enumTransistorVariants = {
- mirrored: "mirrored",
-};
-
-const overlayMatrices = {
- [defaultBuildingVariant]: generateMatrixRotations([0, 1, 0, 1, 1, 0, 0, 1, 0]),
- [enumTransistorVariants.mirrored]: generateMatrixRotations([0, 1, 0, 0, 1, 1, 0, 1, 0]),
-};
-
-export class MetaTransistorBuilding extends MetaBuilding {
- constructor() {
- super("transistor");
- }
-
- static getAllVariantCombinations() {
- return [
- {
- internalId: 38,
- variant: defaultBuildingVariant,
- },
- {
- internalId: 60,
- variant: enumTransistorVariants.mirrored,
- },
- ];
- }
-
- getSilhouetteColor() {
- return "#bc3a61";
- }
-
- /**
- * @param {GameRoot} root
- */
- getIsUnlocked(root) {
- return root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_logic_gates);
- }
-
- /** @returns {"wires"} **/
- getLayer() {
- return "wires";
- }
-
- getDimensions() {
- return new Vector(1, 1);
- }
-
- getAvailableVariants() {
- return [defaultBuildingVariant, enumTransistorVariants.mirrored];
- }
-
- getSpecialOverlayRenderMatrix(rotation, rotationVariant, variant) {
- return overlayMatrices[variant][rotation];
- }
-
- getRenderPins() {
- // We already have it included
- return false;
- }
-
- /**
- *
- * @param {Entity} entity
- * @param {number} rotationVariant
- */
- updateVariants(entity, rotationVariant, variant) {
- entity.components.WiredPins.slots[1].direction =
- variant === enumTransistorVariants.mirrored ? enumDirection.right : enumDirection.left;
- }
-
- /**
- * Creates the entity at the given location
- * @param {Entity} entity
- */
- setupEntityComponents(entity) {
- entity.addComponent(
- new WiredPinsComponent({
- slots: [
- {
- pos: new Vector(0, 0),
- direction: enumDirection.top,
- type: enumPinSlotType.logicalEjector,
- },
- {
- pos: new Vector(0, 0),
- direction: enumDirection.left,
- type: enumPinSlotType.logicalAcceptor,
- },
- {
- pos: new Vector(0, 0),
- direction: enumDirection.bottom,
- type: enumPinSlotType.logicalAcceptor,
- },
- ],
- })
- );
-
- entity.addComponent(
- new LogicGateComponent({
- type: enumLogicGateType.transistor,
- })
- );
- }
-}
+import { generateMatrixRotations } from "../../core/utils";
+import { enumDirection, Vector } from "../../core/vector";
+import { enumLogicGateType, LogicGateComponent } from "../components/logic_gate";
+import { enumPinSlotType, WiredPinsComponent } from "../components/wired_pins";
+import { Entity } from "../entity";
+import { defaultBuildingVariant, MetaBuilding } from "../meta_building";
+import { GameRoot } from "../root";
+import { enumHubGoalRewards } from "../tutorial_goals";
+
+/** @enum {string} */
+export const enumTransistorVariants = {
+ mirrored: "mirrored",
+};
+
+const overlayMatrices = {
+ [defaultBuildingVariant]: generateMatrixRotations([0, 1, 0, 1, 1, 0, 0, 1, 0]),
+ [enumTransistorVariants.mirrored]: generateMatrixRotations([0, 1, 0, 0, 1, 1, 0, 1, 0]),
+};
+
+export class MetaTransistorBuilding extends MetaBuilding {
+ constructor() {
+ super("transistor");
+ }
+
+ static getAllVariantCombinations() {
+ return [
+ {
+ internalId: 38,
+ variant: defaultBuildingVariant,
+ },
+ {
+ internalId: 60,
+ variant: enumTransistorVariants.mirrored,
+ },
+ ];
+ }
+
+ getSilhouetteColor() {
+ return "#bc3a61";
+ }
+
+ /**
+ * @param {GameRoot} root
+ */
+ getIsUnlocked(root) {
+ return root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_logic_gates);
+ }
+
+ /** @returns {"wires"} **/
+ getLayer() {
+ return "wires";
+ }
+
+ getDimensions() {
+ return new Vector(1, 1);
+ }
+
+ getAvailableVariants() {
+ return [defaultBuildingVariant, enumTransistorVariants.mirrored];
+ }
+
+ getSpecialOverlayRenderMatrix(rotation, rotationVariant, variant) {
+ return overlayMatrices[variant][rotation];
+ }
+
+ getRenderPins() {
+ // We already have it included
+ return false;
+ }
+
+ /**
+ *
+ * @param {Entity} entity
+ * @param {number} rotationVariant
+ */
+ updateVariants(entity, rotationVariant, variant) {
+ entity.components.WiredPins.slots[1].direction =
+ variant === enumTransistorVariants.mirrored ? enumDirection.right : enumDirection.left;
+ }
+
+ /**
+ * Creates the entity at the given location
+ * @param {Entity} entity
+ */
+ setupEntityComponents(entity) {
+ entity.addComponent(
+ new WiredPinsComponent({
+ slots: [
+ {
+ pos: new Vector(0, 0),
+ direction: enumDirection.top,
+ type: enumPinSlotType.logicalEjector,
+ },
+ {
+ pos: new Vector(0, 0),
+ direction: enumDirection.left,
+ type: enumPinSlotType.logicalAcceptor,
+ },
+ {
+ pos: new Vector(0, 0),
+ direction: enumDirection.bottom,
+ type: enumPinSlotType.logicalAcceptor,
+ },
+ ],
+ })
+ );
+
+ entity.addComponent(
+ new LogicGateComponent({
+ type: enumLogicGateType.transistor,
+ })
+ );
+ }
+}
diff --git a/src/js/game/buildings/trash.js b/src/js/game/buildings/trash.js
index fcf7f11f..87dbcf09 100644
--- a/src/js/game/buildings/trash.js
+++ b/src/js/game/buildings/trash.js
@@ -1,6 +1,5 @@
import { generateMatrixRotations } from "../../core/utils";
import { enumDirection, Vector } from "../../core/vector";
-import { ACHIEVEMENTS } from "../../platform/achievement_provider";
import { ItemAcceptorComponent } from "../components/item_acceptor";
import { enumItemProcessorTypes, ItemProcessorComponent } from "../components/item_processor";
import { Entity } from "../entity";
@@ -47,25 +46,6 @@ export class MetaTrashBuilding extends MetaBuilding {
return root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_cutter_and_trash);
}
- addAchievementReceiver(entity) {
- if (!entity.root) {
- return;
- }
-
- const itemProcessor = entity.components.ItemProcessor;
- const tryTakeItem = itemProcessor.tryTakeItem.bind(itemProcessor);
-
- itemProcessor.tryTakeItem = () => {
- const taken = tryTakeItem(...arguments);
-
- if (taken) {
- entity.root.signals.achievementCheck.dispatch(ACHIEVEMENTS.trash1000, 1);
- }
-
- return taken;
- };
- }
-
/**
* Creates the entity at the given location
* @param {Entity} entity
@@ -100,7 +80,5 @@ export class MetaTrashBuilding extends MetaBuilding {
processorType: enumItemProcessorTypes.trash,
})
);
-
- this.addAchievementReceiver(entity);
}
}
diff --git a/src/js/game/buildings/underground_belt.js b/src/js/game/buildings/underground_belt.js
index 7009ebd7..e9d0e8e9 100644
--- a/src/js/game/buildings/underground_belt.js
+++ b/src/js/game/buildings/underground_belt.js
@@ -1,300 +1,300 @@
-import { Loader } from "../../core/loader";
-import { enumDirection, Vector, enumAngleToDirection, enumDirectionToVector } from "../../core/vector";
-import { ItemAcceptorComponent } from "../components/item_acceptor";
-import { ItemEjectorComponent } from "../components/item_ejector";
-import { enumUndergroundBeltMode, UndergroundBeltComponent } from "../components/underground_belt";
-import { Entity } from "../entity";
-import { MetaBuilding, defaultBuildingVariant } from "../meta_building";
-import { GameRoot } from "../root";
-import { globalConfig } from "../../core/config";
-import { enumHubGoalRewards } from "../tutorial_goals";
-import { formatItemsPerSecond, generateMatrixRotations } from "../../core/utils";
-import { T } from "../../translations";
-
-/** @enum {string} */
-export const arrayUndergroundRotationVariantToMode = [
- enumUndergroundBeltMode.sender,
- enumUndergroundBeltMode.receiver,
-];
-
-/** @enum {string} */
-export const enumUndergroundBeltVariants = { tier2: "tier2" };
-
-export const enumUndergroundBeltVariantToTier = {
- [defaultBuildingVariant]: 0,
- [enumUndergroundBeltVariants.tier2]: 1,
-};
-
-const colorsByRotationVariant = ["#6d9dff", "#71ff9c"];
-
-const overlayMatrices = [
- // Sender
- generateMatrixRotations([1, 1, 1, 0, 1, 0, 0, 1, 0]),
-
- // Receiver
- generateMatrixRotations([0, 1, 0, 0, 1, 0, 1, 1, 1]),
-];
-
-export class MetaUndergroundBeltBuilding extends MetaBuilding {
- constructor() {
- super("underground_belt");
- }
-
- static getAllVariantCombinations() {
- return [
- {
- internalId: 22,
- variant: defaultBuildingVariant,
- rotationVariant: 0,
- },
- {
- internalId: 23,
- variant: defaultBuildingVariant,
- rotationVariant: 1,
- },
- {
- internalId: 24,
- variant: enumUndergroundBeltVariants.tier2,
- rotationVariant: 0,
- },
- {
- internalId: 25,
- variant: enumUndergroundBeltVariants.tier2,
- rotationVariant: 1,
- },
- ];
- }
-
- getSilhouetteColor(variant, rotationVariant) {
- return colorsByRotationVariant[rotationVariant];
- }
-
- getFlipOrientationAfterPlacement() {
- return true;
- }
-
- getStayInPlacementMode() {
- return true;
- }
-
- /**
- * @param {number} rotation
- * @param {number} rotationVariant
- * @param {string} variant
- * @param {Entity} entity
- */
- getSpecialOverlayRenderMatrix(rotation, rotationVariant, variant, entity) {
- return overlayMatrices[rotationVariant][rotation];
- }
-
- /**
- * @param {GameRoot} root
- * @param {string} variant
- * @returns {Array<[string, string]>}
- */
- getAdditionalStatistics(root, variant) {
- const rangeTiles =
- globalConfig.undergroundBeltMaxTilesByTier[enumUndergroundBeltVariantToTier[variant]];
-
- const beltSpeed = root.hubGoals.getUndergroundBeltBaseSpeed();
-
- /** @type {Array<[string, string]>} */
- const stats = [
- [
- T.ingame.buildingPlacement.infoTexts.range,
- T.ingame.buildingPlacement.infoTexts.tiles.replace("", "" + rangeTiles),
- ],
- ];
-
- if (root.gameMode.throughputDoesNotMatter()) {
- return stats;
- }
- stats.push([T.ingame.buildingPlacement.infoTexts.speed, formatItemsPerSecond(beltSpeed)]);
-
- return stats;
- }
-
- /**
- * @param {GameRoot} root
- */
- getAvailableVariants(root) {
- if (root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_underground_belt_tier_2)) {
- return [defaultBuildingVariant, enumUndergroundBeltVariants.tier2];
- }
- return super.getAvailableVariants(root);
- }
-
- /**
- * @param {number} rotationVariant
- * @param {string} variant
- */
- getPreviewSprite(rotationVariant, variant) {
- let suffix = "";
- if (variant !== defaultBuildingVariant) {
- suffix = "-" + variant;
- }
-
- switch (arrayUndergroundRotationVariantToMode[rotationVariant]) {
- case enumUndergroundBeltMode.sender:
- return Loader.getSprite("sprites/buildings/underground_belt_entry" + suffix + ".png");
- case enumUndergroundBeltMode.receiver:
- return Loader.getSprite("sprites/buildings/underground_belt_exit" + suffix + ".png");
- default:
- assertAlways(false, "Invalid rotation variant");
- }
- }
-
- /**
- * @param {number} rotationVariant
- * @param {string} variant
- */
- getBlueprintSprite(rotationVariant, variant) {
- let suffix = "";
- if (variant !== defaultBuildingVariant) {
- suffix = "-" + variant;
- }
-
- switch (arrayUndergroundRotationVariantToMode[rotationVariant]) {
- case enumUndergroundBeltMode.sender:
- return Loader.getSprite("sprites/blueprints/underground_belt_entry" + suffix + ".png");
- case enumUndergroundBeltMode.receiver:
- return Loader.getSprite("sprites/blueprints/underground_belt_exit" + suffix + ".png");
- default:
- assertAlways(false, "Invalid rotation variant");
- }
- }
-
- /**
- * @param {number} rotationVariant
- * @param {string} variant
- */
- getSprite(rotationVariant, variant) {
- return this.getPreviewSprite(rotationVariant, variant);
- }
-
- /**
- * @param {GameRoot} root
- */
- getIsUnlocked(root) {
- return root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_tunnel);
- }
-
- /**
- * Creates the entity at the given location
- * @param {Entity} entity
- */
- setupEntityComponents(entity) {
- // Required, since the item processor needs this.
- entity.addComponent(
- new ItemEjectorComponent({
- slots: [],
- })
- );
-
- entity.addComponent(new UndergroundBeltComponent({}));
- entity.addComponent(
- new ItemAcceptorComponent({
- slots: [],
- })
- );
- }
-
- /**
- * Should compute the optimal rotation variant on the given tile
- * @param {object} param0
- * @param {GameRoot} param0.root
- * @param {Vector} param0.tile
- * @param {number} param0.rotation
- * @param {string} param0.variant
- * @param {Layer} param0.layer
- * @return {{ rotation: number, rotationVariant: number, connectedEntities?: Array }}
- */
- computeOptimalDirectionAndRotationVariantAtTile({ root, tile, rotation, variant, layer }) {
- const searchDirection = enumAngleToDirection[rotation];
- const searchVector = enumDirectionToVector[searchDirection];
- const tier = enumUndergroundBeltVariantToTier[variant];
-
- const targetRotation = (rotation + 180) % 360;
- const targetSenderRotation = rotation;
-
- for (
- let searchOffset = 1;
- searchOffset <= globalConfig.undergroundBeltMaxTilesByTier[tier];
- ++searchOffset
- ) {
- tile = tile.addScalars(searchVector.x, searchVector.y);
-
- const contents = root.map.getTileContent(tile, "regular");
- if (contents) {
- const undergroundComp = contents.components.UndergroundBelt;
- if (undergroundComp && undergroundComp.tier === tier) {
- const staticComp = contents.components.StaticMapEntity;
- if (staticComp.rotation === targetRotation) {
- if (undergroundComp.mode !== enumUndergroundBeltMode.sender) {
- // If we encounter an underground receiver on our way which is also faced in our direction, we don't accept that
- break;
- }
- return {
- rotation: targetRotation,
- rotationVariant: 1,
- connectedEntities: [contents],
- };
- } else if (staticComp.rotation === targetSenderRotation) {
- // Draw connections to receivers
- if (undergroundComp.mode === enumUndergroundBeltMode.receiver) {
- return {
- rotation: rotation,
- rotationVariant: 0,
- connectedEntities: [contents],
- };
- } else {
- break;
- }
- }
- }
- }
- }
-
- return {
- rotation,
- rotationVariant: 0,
- };
- }
-
- /**
- *
- * @param {Entity} entity
- * @param {number} rotationVariant
- * @param {string} variant
- */
- updateVariants(entity, rotationVariant, variant) {
- entity.components.UndergroundBelt.tier = enumUndergroundBeltVariantToTier[variant];
-
- switch (arrayUndergroundRotationVariantToMode[rotationVariant]) {
- case enumUndergroundBeltMode.sender: {
- entity.components.UndergroundBelt.mode = enumUndergroundBeltMode.sender;
- entity.components.ItemEjector.setSlots([]);
- entity.components.ItemAcceptor.setSlots([
- {
- pos: new Vector(0, 0),
- direction: enumDirection.bottom,
- },
- ]);
- return;
- }
- case enumUndergroundBeltMode.receiver: {
- entity.components.UndergroundBelt.mode = enumUndergroundBeltMode.receiver;
- entity.components.ItemAcceptor.setSlots([]);
- entity.components.ItemEjector.setSlots([
- {
- pos: new Vector(0, 0),
- direction: enumDirection.top,
- },
- ]);
- return;
- }
- default:
- assertAlways(false, "Invalid rotation variant");
- }
- }
-}
+import { Loader } from "../../core/loader";
+import { enumDirection, Vector, enumAngleToDirection, enumDirectionToVector } from "../../core/vector";
+import { ItemAcceptorComponent } from "../components/item_acceptor";
+import { ItemEjectorComponent } from "../components/item_ejector";
+import { enumUndergroundBeltMode, UndergroundBeltComponent } from "../components/underground_belt";
+import { Entity } from "../entity";
+import { MetaBuilding, defaultBuildingVariant } from "../meta_building";
+import { GameRoot } from "../root";
+import { globalConfig } from "../../core/config";
+import { enumHubGoalRewards } from "../tutorial_goals";
+import { formatItemsPerSecond, generateMatrixRotations } from "../../core/utils";
+import { T } from "../../translations";
+
+/** @enum {string} */
+export const arrayUndergroundRotationVariantToMode = [
+ enumUndergroundBeltMode.sender,
+ enumUndergroundBeltMode.receiver,
+];
+
+/** @enum {string} */
+export const enumUndergroundBeltVariants = { tier2: "tier2" };
+
+export const enumUndergroundBeltVariantToTier = {
+ [defaultBuildingVariant]: 0,
+ [enumUndergroundBeltVariants.tier2]: 1,
+};
+
+const colorsByRotationVariant = ["#6d9dff", "#71ff9c"];
+
+const overlayMatrices = [
+ // Sender
+ generateMatrixRotations([1, 1, 1, 0, 1, 0, 0, 1, 0]),
+
+ // Receiver
+ generateMatrixRotations([0, 1, 0, 0, 1, 0, 1, 1, 1]),
+];
+
+export class MetaUndergroundBeltBuilding extends MetaBuilding {
+ constructor() {
+ super("underground_belt");
+ }
+
+ static getAllVariantCombinations() {
+ return [
+ {
+ internalId: 22,
+ variant: defaultBuildingVariant,
+ rotationVariant: 0,
+ },
+ {
+ internalId: 23,
+ variant: defaultBuildingVariant,
+ rotationVariant: 1,
+ },
+ {
+ internalId: 24,
+ variant: enumUndergroundBeltVariants.tier2,
+ rotationVariant: 0,
+ },
+ {
+ internalId: 25,
+ variant: enumUndergroundBeltVariants.tier2,
+ rotationVariant: 1,
+ },
+ ];
+ }
+
+ getSilhouetteColor(variant, rotationVariant) {
+ return colorsByRotationVariant[rotationVariant];
+ }
+
+ getFlipOrientationAfterPlacement() {
+ return true;
+ }
+
+ getStayInPlacementMode() {
+ return true;
+ }
+
+ /**
+ * @param {number} rotation
+ * @param {number} rotationVariant
+ * @param {string} variant
+ * @param {Entity} entity
+ */
+ getSpecialOverlayRenderMatrix(rotation, rotationVariant, variant, entity) {
+ return overlayMatrices[rotationVariant][rotation];
+ }
+
+ /**
+ * @param {GameRoot} root
+ * @param {string} variant
+ * @returns {Array<[string, string]>}
+ */
+ getAdditionalStatistics(root, variant) {
+ const rangeTiles =
+ globalConfig.undergroundBeltMaxTilesByTier[enumUndergroundBeltVariantToTier[variant]];
+
+ const beltSpeed = root.hubGoals.getUndergroundBeltBaseSpeed();
+
+ /** @type {Array<[string, string]>} */
+ const stats = [
+ [
+ T.ingame.buildingPlacement.infoTexts.range,
+ T.ingame.buildingPlacement.infoTexts.tiles.replace("", "" + rangeTiles),
+ ],
+ ];
+
+ if (root.gameMode.throughputDoesNotMatter()) {
+ return stats;
+ }
+ stats.push([T.ingame.buildingPlacement.infoTexts.speed, formatItemsPerSecond(beltSpeed)]);
+
+ return stats;
+ }
+
+ /**
+ * @param {GameRoot} root
+ */
+ getAvailableVariants(root) {
+ if (root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_underground_belt_tier_2)) {
+ return [defaultBuildingVariant, enumUndergroundBeltVariants.tier2];
+ }
+ return super.getAvailableVariants(root);
+ }
+
+ /**
+ * @param {number} rotationVariant
+ * @param {string} variant
+ */
+ getPreviewSprite(rotationVariant, variant) {
+ let suffix = "";
+ if (variant !== defaultBuildingVariant) {
+ suffix = "-" + variant;
+ }
+
+ switch (arrayUndergroundRotationVariantToMode[rotationVariant]) {
+ case enumUndergroundBeltMode.sender:
+ return Loader.getSprite("sprites/buildings/underground_belt_entry" + suffix + ".png");
+ case enumUndergroundBeltMode.receiver:
+ return Loader.getSprite("sprites/buildings/underground_belt_exit" + suffix + ".png");
+ default:
+ assertAlways(false, "Invalid rotation variant");
+ }
+ }
+
+ /**
+ * @param {number} rotationVariant
+ * @param {string} variant
+ */
+ getBlueprintSprite(rotationVariant, variant) {
+ let suffix = "";
+ if (variant !== defaultBuildingVariant) {
+ suffix = "-" + variant;
+ }
+
+ switch (arrayUndergroundRotationVariantToMode[rotationVariant]) {
+ case enumUndergroundBeltMode.sender:
+ return Loader.getSprite("sprites/blueprints/underground_belt_entry" + suffix + ".png");
+ case enumUndergroundBeltMode.receiver:
+ return Loader.getSprite("sprites/blueprints/underground_belt_exit" + suffix + ".png");
+ default:
+ assertAlways(false, "Invalid rotation variant");
+ }
+ }
+
+ /**
+ * @param {number} rotationVariant
+ * @param {string} variant
+ */
+ getSprite(rotationVariant, variant) {
+ return this.getPreviewSprite(rotationVariant, variant);
+ }
+
+ /**
+ * @param {GameRoot} root
+ */
+ getIsUnlocked(root) {
+ return root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_tunnel);
+ }
+
+ /**
+ * Creates the entity at the given location
+ * @param {Entity} entity
+ */
+ setupEntityComponents(entity) {
+ // Required, since the item processor needs this.
+ entity.addComponent(
+ new ItemEjectorComponent({
+ slots: [],
+ })
+ );
+
+ entity.addComponent(new UndergroundBeltComponent({}));
+ entity.addComponent(
+ new ItemAcceptorComponent({
+ slots: [],
+ })
+ );
+ }
+
+ /**
+ * Should compute the optimal rotation variant on the given tile
+ * @param {object} param0
+ * @param {GameRoot} param0.root
+ * @param {Vector} param0.tile
+ * @param {number} param0.rotation
+ * @param {string} param0.variant
+ * @param {Layer} param0.layer
+ * @return {{ rotation: number, rotationVariant: number, connectedEntities?: Array }}
+ */
+ computeOptimalDirectionAndRotationVariantAtTile({ root, tile, rotation, variant, layer }) {
+ const searchDirection = enumAngleToDirection[rotation];
+ const searchVector = enumDirectionToVector[searchDirection];
+ const tier = enumUndergroundBeltVariantToTier[variant];
+
+ const targetRotation = (rotation + 180) % 360;
+ const targetSenderRotation = rotation;
+
+ for (
+ let searchOffset = 1;
+ searchOffset <= globalConfig.undergroundBeltMaxTilesByTier[tier];
+ ++searchOffset
+ ) {
+ tile = tile.addScalars(searchVector.x, searchVector.y);
+
+ const contents = root.map.getTileContent(tile, "regular");
+ if (contents) {
+ const undergroundComp = contents.components.UndergroundBelt;
+ if (undergroundComp && undergroundComp.tier === tier) {
+ const staticComp = contents.components.StaticMapEntity;
+ if (staticComp.rotation === targetRotation) {
+ if (undergroundComp.mode !== enumUndergroundBeltMode.sender) {
+ // If we encounter an underground receiver on our way which is also faced in our direction, we don't accept that
+ break;
+ }
+ return {
+ rotation: targetRotation,
+ rotationVariant: 1,
+ connectedEntities: [contents],
+ };
+ } else if (staticComp.rotation === targetSenderRotation) {
+ // Draw connections to receivers
+ if (undergroundComp.mode === enumUndergroundBeltMode.receiver) {
+ return {
+ rotation: rotation,
+ rotationVariant: 0,
+ connectedEntities: [contents],
+ };
+ } else {
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ return {
+ rotation,
+ rotationVariant: 0,
+ };
+ }
+
+ /**
+ *
+ * @param {Entity} entity
+ * @param {number} rotationVariant
+ * @param {string} variant
+ */
+ updateVariants(entity, rotationVariant, variant) {
+ entity.components.UndergroundBelt.tier = enumUndergroundBeltVariantToTier[variant];
+
+ switch (arrayUndergroundRotationVariantToMode[rotationVariant]) {
+ case enumUndergroundBeltMode.sender: {
+ entity.components.UndergroundBelt.mode = enumUndergroundBeltMode.sender;
+ entity.components.ItemEjector.setSlots([]);
+ entity.components.ItemAcceptor.setSlots([
+ {
+ pos: new Vector(0, 0),
+ direction: enumDirection.bottom,
+ },
+ ]);
+ return;
+ }
+ case enumUndergroundBeltMode.receiver: {
+ entity.components.UndergroundBelt.mode = enumUndergroundBeltMode.receiver;
+ entity.components.ItemAcceptor.setSlots([]);
+ entity.components.ItemEjector.setSlots([
+ {
+ pos: new Vector(0, 0),
+ direction: enumDirection.top,
+ },
+ ]);
+ return;
+ }
+ default:
+ assertAlways(false, "Invalid rotation variant");
+ }
+ }
+}
diff --git a/src/js/game/buildings/virtual_processor.js b/src/js/game/buildings/virtual_processor.js
index b42ceb5d..477a4bd9 100644
--- a/src/js/game/buildings/virtual_processor.js
+++ b/src/js/game/buildings/virtual_processor.js
@@ -1,188 +1,188 @@
-import { Vector, enumDirection } from "../../core/vector";
-import { LogicGateComponent, enumLogicGateType } from "../components/logic_gate";
-import { WiredPinsComponent, enumPinSlotType } from "../components/wired_pins";
-import { Entity } from "../entity";
-import { defaultBuildingVariant, MetaBuilding } from "../meta_building";
-import { GameRoot } from "../root";
-import { enumHubGoalRewards } from "../tutorial_goals";
-import { MetaCutterBuilding } from "./cutter";
-import { MetaPainterBuilding } from "./painter";
-import { MetaRotaterBuilding } from "./rotater";
-import { MetaStackerBuilding } from "./stacker";
-
-/** @enum {string} */
-export const enumVirtualProcessorVariants = {
- rotater: "rotater",
- unstacker: "unstacker",
- stacker: "stacker",
- painter: "painter",
-};
-
-/** @enum {string} */
-const enumVariantToGate = {
- [defaultBuildingVariant]: enumLogicGateType.cutter,
- [enumVirtualProcessorVariants.rotater]: enumLogicGateType.rotater,
- [enumVirtualProcessorVariants.unstacker]: enumLogicGateType.unstacker,
- [enumVirtualProcessorVariants.stacker]: enumLogicGateType.stacker,
- [enumVirtualProcessorVariants.painter]: enumLogicGateType.painter,
-};
-
-const colors = {
- [defaultBuildingVariant]: new MetaCutterBuilding().getSilhouetteColor(),
- [enumVirtualProcessorVariants.rotater]: new MetaRotaterBuilding().getSilhouetteColor(),
- [enumVirtualProcessorVariants.unstacker]: new MetaStackerBuilding().getSilhouetteColor(),
- [enumVirtualProcessorVariants.stacker]: new MetaStackerBuilding().getSilhouetteColor(),
- [enumVirtualProcessorVariants.painter]: new MetaPainterBuilding().getSilhouetteColor(),
-};
-
-export class MetaVirtualProcessorBuilding extends MetaBuilding {
- constructor() {
- super("virtual_processor");
- }
-
- static getAllVariantCombinations() {
- return [
- {
- internalId: 42,
- variant: defaultBuildingVariant,
- },
- {
- internalId: 44,
- variant: enumVirtualProcessorVariants.rotater,
- },
- {
- internalId: 45,
- variant: enumVirtualProcessorVariants.unstacker,
- },
- {
- internalId: 50,
- variant: enumVirtualProcessorVariants.stacker,
- },
- {
- internalId: 51,
- variant: enumVirtualProcessorVariants.painter,
- },
- ];
- }
-
- getSilhouetteColor(variant) {
- return colors[variant];
- }
-
- /**
- * @param {GameRoot} root
- */
- getIsUnlocked(root) {
- return root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_virtual_processing);
- }
-
- /** @returns {"wires"} **/
- getLayer() {
- return "wires";
- }
-
- getDimensions() {
- return new Vector(1, 1);
- }
-
- getAvailableVariants() {
- return [
- defaultBuildingVariant,
- enumVirtualProcessorVariants.rotater,
- enumVirtualProcessorVariants.stacker,
- enumVirtualProcessorVariants.painter,
- enumVirtualProcessorVariants.unstacker,
- ];
- }
-
- getRenderPins() {
- // We already have it included
- return false;
- }
-
- /**
- *
- * @param {Entity} entity
- * @param {number} rotationVariant
- */
- updateVariants(entity, rotationVariant, variant) {
- const gateType = enumVariantToGate[variant];
- entity.components.LogicGate.type = gateType;
- const pinComp = entity.components.WiredPins;
- switch (gateType) {
- case enumLogicGateType.cutter:
- case enumLogicGateType.unstacker: {
- pinComp.setSlots([
- {
- pos: new Vector(0, 0),
- direction: enumDirection.left,
- type: enumPinSlotType.logicalEjector,
- },
- {
- pos: new Vector(0, 0),
- direction: enumDirection.right,
- type: enumPinSlotType.logicalEjector,
- },
- {
- pos: new Vector(0, 0),
- direction: enumDirection.bottom,
- type: enumPinSlotType.logicalAcceptor,
- },
- ]);
- break;
- }
- case enumLogicGateType.rotater: {
- pinComp.setSlots([
- {
- pos: new Vector(0, 0),
- direction: enumDirection.top,
- type: enumPinSlotType.logicalEjector,
- },
- {
- pos: new Vector(0, 0),
- direction: enumDirection.bottom,
- type: enumPinSlotType.logicalAcceptor,
- },
- ]);
- break;
- }
- case enumLogicGateType.stacker:
- case enumLogicGateType.painter: {
- pinComp.setSlots([
- {
- pos: new Vector(0, 0),
- direction: enumDirection.top,
- type: enumPinSlotType.logicalEjector,
- },
- {
- pos: new Vector(0, 0),
- direction: enumDirection.bottom,
- type: enumPinSlotType.logicalAcceptor,
- },
- {
- pos: new Vector(0, 0),
- direction: enumDirection.right,
- type: enumPinSlotType.logicalAcceptor,
- },
- ]);
- break;
- }
- default:
- assertAlways("unknown logic gate type: " + gateType);
- }
- }
-
- /**
- * Creates the entity at the given location
- * @param {Entity} entity
- */
- setupEntityComponents(entity) {
- entity.addComponent(
- new WiredPinsComponent({
- slots: [],
- })
- );
-
- entity.addComponent(new LogicGateComponent({}));
- }
-}
+import { Vector, enumDirection } from "../../core/vector";
+import { LogicGateComponent, enumLogicGateType } from "../components/logic_gate";
+import { WiredPinsComponent, enumPinSlotType } from "../components/wired_pins";
+import { Entity } from "../entity";
+import { MetaBuilding, defaultBuildingVariant } from "../meta_building";
+import { GameRoot } from "../root";
+import { enumHubGoalRewards } from "../tutorial_goals";
+import { MetaCutterBuilding } from "./cutter";
+import { MetaPainterBuilding } from "./painter";
+import { MetaRotatorBuilding } from "./rotator";
+import { MetaStackerBuilding } from "./stacker";
+
+/** @enum {string} */
+export const enumVirtualProcessorVariants = {
+ rotator: "rotator",
+ unstacker: "unstacker",
+ stacker: "stacker",
+ painter: "painter",
+};
+
+/** @enum {string} */
+const enumVariantToGate = {
+ [defaultBuildingVariant]: enumLogicGateType.cutter,
+ [enumVirtualProcessorVariants.rotator]: enumLogicGateType.rotator,
+ [enumVirtualProcessorVariants.unstacker]: enumLogicGateType.unstacker,
+ [enumVirtualProcessorVariants.stacker]: enumLogicGateType.stacker,
+ [enumVirtualProcessorVariants.painter]: enumLogicGateType.painter,
+};
+
+const colors = {
+ [defaultBuildingVariant]: new MetaCutterBuilding().getSilhouetteColor(),
+ [enumVirtualProcessorVariants.rotator]: new MetaRotatorBuilding().getSilhouetteColor(),
+ [enumVirtualProcessorVariants.unstacker]: new MetaStackerBuilding().getSilhouetteColor(),
+ [enumVirtualProcessorVariants.stacker]: new MetaStackerBuilding().getSilhouetteColor(),
+ [enumVirtualProcessorVariants.painter]: new MetaPainterBuilding().getSilhouetteColor(),
+};
+
+export class MetaVirtualProcessorBuilding extends MetaBuilding {
+ constructor() {
+ super("virtual_processor");
+ }
+
+ static getAllVariantCombinations() {
+ return [
+ {
+ internalId: 42,
+ variant: defaultBuildingVariant,
+ },
+ {
+ internalId: 44,
+ variant: enumVirtualProcessorVariants.rotator,
+ },
+ {
+ internalId: 45,
+ variant: enumVirtualProcessorVariants.unstacker,
+ },
+ {
+ internalId: 50,
+ variant: enumVirtualProcessorVariants.stacker,
+ },
+ {
+ internalId: 51,
+ variant: enumVirtualProcessorVariants.painter,
+ },
+ ];
+ }
+
+ getSilhouetteColor(variant) {
+ return colors[variant];
+ }
+
+ /**
+ * @param {GameRoot} root
+ */
+ getIsUnlocked(root) {
+ return root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_virtual_processing);
+ }
+
+ /** @returns {"wires"} **/
+ getLayer() {
+ return "wires";
+ }
+
+ getDimensions() {
+ return new Vector(1, 1);
+ }
+
+ getAvailableVariants() {
+ return [
+ defaultBuildingVariant,
+ enumVirtualProcessorVariants.rotator,
+ enumVirtualProcessorVariants.stacker,
+ enumVirtualProcessorVariants.painter,
+ enumVirtualProcessorVariants.unstacker,
+ ];
+ }
+
+ getRenderPins() {
+ // We already have it included
+ return false;
+ }
+
+ /**
+ *
+ * @param {Entity} entity
+ * @param {number} rotationVariant
+ */
+ updateVariants(entity, rotationVariant, variant) {
+ const gateType = enumVariantToGate[variant];
+ entity.components.LogicGate.type = gateType;
+ const pinComp = entity.components.WiredPins;
+ switch (gateType) {
+ case enumLogicGateType.cutter:
+ case enumLogicGateType.unstacker: {
+ pinComp.setSlots([
+ {
+ pos: new Vector(0, 0),
+ direction: enumDirection.left,
+ type: enumPinSlotType.logicalEjector,
+ },
+ {
+ pos: new Vector(0, 0),
+ direction: enumDirection.right,
+ type: enumPinSlotType.logicalEjector,
+ },
+ {
+ pos: new Vector(0, 0),
+ direction: enumDirection.bottom,
+ type: enumPinSlotType.logicalAcceptor,
+ },
+ ]);
+ break;
+ }
+ case enumLogicGateType.rotator: {
+ pinComp.setSlots([
+ {
+ pos: new Vector(0, 0),
+ direction: enumDirection.top,
+ type: enumPinSlotType.logicalEjector,
+ },
+ {
+ pos: new Vector(0, 0),
+ direction: enumDirection.bottom,
+ type: enumPinSlotType.logicalAcceptor,
+ },
+ ]);
+ break;
+ }
+ case enumLogicGateType.stacker:
+ case enumLogicGateType.painter: {
+ pinComp.setSlots([
+ {
+ pos: new Vector(0, 0),
+ direction: enumDirection.top,
+ type: enumPinSlotType.logicalEjector,
+ },
+ {
+ pos: new Vector(0, 0),
+ direction: enumDirection.bottom,
+ type: enumPinSlotType.logicalAcceptor,
+ },
+ {
+ pos: new Vector(0, 0),
+ direction: enumDirection.right,
+ type: enumPinSlotType.logicalAcceptor,
+ },
+ ]);
+ break;
+ }
+ default:
+ assertAlways("unknown logic gate type: " + gateType);
+ }
+ }
+
+ /**
+ * Creates the entity at the given location
+ * @param {Entity} entity
+ */
+ setupEntityComponents(entity) {
+ entity.addComponent(
+ new WiredPinsComponent({
+ slots: [],
+ })
+ );
+
+ entity.addComponent(new LogicGateComponent({}));
+ }
+}
diff --git a/src/js/game/buildings/wire.js b/src/js/game/buildings/wire.js
index c69dbfa1..1c2fced5 100644
--- a/src/js/game/buildings/wire.js
+++ b/src/js/game/buildings/wire.js
@@ -1,315 +1,315 @@
-import { Loader } from "../../core/loader";
-import { generateMatrixRotations } from "../../core/utils";
-import { enumDirection, Vector } from "../../core/vector";
-import { SOUNDS } from "../../platform/sound";
-import { enumWireType, enumWireVariant, WireComponent } from "../components/wire";
-import { Entity } from "../entity";
-import { defaultBuildingVariant, MetaBuilding } from "../meta_building";
-import { GameRoot } from "../root";
-import { enumHubGoalRewards } from "../tutorial_goals";
-
-export const arrayWireRotationVariantToType = [
- enumWireType.forward,
- enumWireType.turn,
- enumWireType.split,
- enumWireType.cross,
-];
-
-export const wireOverlayMatrices = {
- [enumWireType.forward]: generateMatrixRotations([0, 1, 0, 0, 1, 0, 0, 1, 0]),
- [enumWireType.split]: generateMatrixRotations([0, 0, 0, 1, 1, 1, 0, 1, 0]),
- [enumWireType.turn]: generateMatrixRotations([0, 0, 0, 0, 1, 1, 0, 1, 0]),
- [enumWireType.cross]: generateMatrixRotations([0, 1, 0, 1, 1, 1, 0, 1, 0]),
-};
-
-/** @enum {string} */
-export const wireVariants = {
- second: "second",
-};
-
-const enumWireVariantToVariant = {
- [defaultBuildingVariant]: enumWireVariant.first,
- [wireVariants.second]: enumWireVariant.second,
-};
-
-export class MetaWireBuilding extends MetaBuilding {
- constructor() {
- super("wire");
- }
-
- static getAllVariantCombinations() {
- return [
- {
- internalId: 27,
- variant: defaultBuildingVariant,
- rotationVariant: 0,
- },
- {
- internalId: 28,
- variant: defaultBuildingVariant,
- rotationVariant: 1,
- },
- {
- internalId: 29,
- variant: defaultBuildingVariant,
- rotationVariant: 2,
- },
- {
- internalId: 30,
- variant: defaultBuildingVariant,
- rotationVariant: 3,
- },
- {
- internalId: 52,
- variant: enumWireVariant.second,
- rotationVariant: 0,
- },
- {
- internalId: 53,
- variant: enumWireVariant.second,
- rotationVariant: 1,
- },
- {
- internalId: 54,
- variant: enumWireVariant.second,
- rotationVariant: 2,
- },
- {
- internalId: 55,
- variant: enumWireVariant.second,
- rotationVariant: 3,
- },
- ];
- }
-
- getHasDirectionLockAvailable() {
- return true;
- }
-
- getSilhouetteColor() {
- return "#61ef6f";
- }
-
- getAvailableVariants() {
- return [defaultBuildingVariant, wireVariants.second];
- }
-
- getDimensions() {
- return new Vector(1, 1);
- }
-
- getStayInPlacementMode() {
- return true;
- }
-
- getPlacementSound() {
- return SOUNDS.placeBelt;
- }
-
- getRotateAutomaticallyWhilePlacing() {
- return true;
- }
-
- /** @returns {"wires"} **/
- getLayer() {
- return "wires";
- }
-
- getSprite() {
- return null;
- }
-
- getIsReplaceable() {
- return true;
- }
-
- /**
- * @param {GameRoot} root
- */
- getIsUnlocked(root) {
- return root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_wires_painter_and_levers);
- }
-
- /**
- * Creates the entity at the given location
- * @param {Entity} entity
- */
- setupEntityComponents(entity) {
- entity.addComponent(new WireComponent({}));
- }
-
- /**
- *
- * @param {Entity} entity
- * @param {number} rotationVariant
- * @param {string} variant
- */
- updateVariants(entity, rotationVariant, variant) {
- entity.components.Wire.type = arrayWireRotationVariantToType[rotationVariant];
- entity.components.Wire.variant = enumWireVariantToVariant[variant];
- }
-
- /**
- *
- * @param {number} rotation
- * @param {number} rotationVariant
- * @param {string} variant
- * @param {Entity} entity
- */
- getSpecialOverlayRenderMatrix(rotation, rotationVariant, variant, entity) {
- return wireOverlayMatrices[entity.components.Wire.type][rotation];
- }
-
- /**
- *
- * @param {number} rotationVariant
- * @param {string} variant
- * @returns {import("../../core/draw_utils").AtlasSprite}
- */
- getPreviewSprite(rotationVariant, variant) {
- const wireVariant = enumWireVariantToVariant[variant];
- switch (arrayWireRotationVariantToType[rotationVariant]) {
- case enumWireType.forward: {
- return Loader.getSprite("sprites/wires/sets/" + wireVariant + "_forward.png");
- }
- case enumWireType.turn: {
- return Loader.getSprite("sprites/wires/sets/" + wireVariant + "_turn.png");
- }
- case enumWireType.split: {
- return Loader.getSprite("sprites/wires/sets/" + wireVariant + "_split.png");
- }
- case enumWireType.cross: {
- return Loader.getSprite("sprites/wires/sets/" + wireVariant + "_cross.png");
- }
- default: {
- assertAlways(false, "Invalid wire rotation variant");
- }
- }
- }
-
- getBlueprintSprite(rotationVariant, variant) {
- return this.getPreviewSprite(rotationVariant, variant);
- }
-
- /**
- * Should compute the optimal rotation variant on the given tile
- * @param {object} param0
- * @param {GameRoot} param0.root
- * @param {Vector} param0.tile
- * @param {number} param0.rotation
- * @param {string} param0.variant
- * @param {string} param0.layer
- * @return {{ rotation: number, rotationVariant: number, connectedEntities?: Array }}
- */
- computeOptimalDirectionAndRotationVariantAtTile({ root, tile, rotation, variant, layer }) {
- const wireVariant = enumWireVariantToVariant[variant];
- const connections = {
- top: root.logic.computeWireEdgeStatus({ tile, wireVariant, edge: enumDirection.top }),
- right: root.logic.computeWireEdgeStatus({ tile, wireVariant, edge: enumDirection.right }),
- bottom: root.logic.computeWireEdgeStatus({ tile, wireVariant, edge: enumDirection.bottom }),
- left: root.logic.computeWireEdgeStatus({ tile, wireVariant, edge: enumDirection.left }),
- };
-
- let flag = 0;
- flag |= connections.top ? 0x1000 : 0;
- flag |= connections.right ? 0x100 : 0;
- flag |= connections.bottom ? 0x10 : 0;
- flag |= connections.left ? 0x1 : 0;
-
- let targetType = enumWireType.forward;
-
- // First, reset rotation
- rotation = 0;
-
- switch (flag) {
- case 0x0000:
- // Nothing
- break;
-
- case 0x0001:
- // Left
- rotation += 90;
- break;
-
- case 0x0010:
- // Bottom
- // END
- break;
-
- case 0x0011:
- // Bottom | Left
- targetType = enumWireType.turn;
- rotation += 90;
- break;
-
- case 0x0100:
- // Right
- rotation += 90;
- break;
-
- case 0x0101:
- // Right | Left
- rotation += 90;
- break;
-
- case 0x0110:
- // Right | Bottom
- targetType = enumWireType.turn;
- break;
-
- case 0x0111:
- // Right | Bottom | Left
- targetType = enumWireType.split;
- break;
-
- case 0x1000:
- // Top
- break;
-
- case 0x1001:
- // Top | Left
- targetType = enumWireType.turn;
- rotation += 180;
- break;
-
- case 0x1010:
- // Top | Bottom
- break;
-
- case 0x1011:
- // Top | Bottom | Left
- targetType = enumWireType.split;
- rotation += 90;
- break;
-
- case 0x1100:
- // Top | Right
- targetType = enumWireType.turn;
- rotation -= 90;
- break;
-
- case 0x1101:
- // Top | Right | Left
- targetType = enumWireType.split;
- rotation += 180;
- break;
-
- case 0x1110:
- // Top | Right | Bottom
- targetType = enumWireType.split;
- rotation -= 90;
- break;
-
- case 0x1111:
- // Top | Right | Bottom | Left
- targetType = enumWireType.cross;
- break;
- }
-
- return {
- // Clamp rotation
- rotation: (rotation + 360 * 10) % 360,
- rotationVariant: arrayWireRotationVariantToType.indexOf(targetType),
- };
- }
-}
+import { Loader } from "../../core/loader";
+import { generateMatrixRotations } from "../../core/utils";
+import { enumDirection, Vector } from "../../core/vector";
+import { SOUNDS } from "../../platform/sound";
+import { enumWireType, enumWireVariant, WireComponent } from "../components/wire";
+import { Entity } from "../entity";
+import { defaultBuildingVariant, MetaBuilding } from "../meta_building";
+import { GameRoot } from "../root";
+import { enumHubGoalRewards } from "../tutorial_goals";
+
+export const arrayWireRotationVariantToType = [
+ enumWireType.forward,
+ enumWireType.turn,
+ enumWireType.split,
+ enumWireType.cross,
+];
+
+export const wireOverlayMatrices = {
+ [enumWireType.forward]: generateMatrixRotations([0, 1, 0, 0, 1, 0, 0, 1, 0]),
+ [enumWireType.split]: generateMatrixRotations([0, 0, 0, 1, 1, 1, 0, 1, 0]),
+ [enumWireType.turn]: generateMatrixRotations([0, 0, 0, 0, 1, 1, 0, 1, 0]),
+ [enumWireType.cross]: generateMatrixRotations([0, 1, 0, 1, 1, 1, 0, 1, 0]),
+};
+
+/** @enum {string} */
+export const wireVariants = {
+ second: "second",
+};
+
+const enumWireVariantToVariant = {
+ [defaultBuildingVariant]: enumWireVariant.first,
+ [wireVariants.second]: enumWireVariant.second,
+};
+
+export class MetaWireBuilding extends MetaBuilding {
+ constructor() {
+ super("wire");
+ }
+
+ static getAllVariantCombinations() {
+ return [
+ {
+ internalId: 27,
+ variant: defaultBuildingVariant,
+ rotationVariant: 0,
+ },
+ {
+ internalId: 28,
+ variant: defaultBuildingVariant,
+ rotationVariant: 1,
+ },
+ {
+ internalId: 29,
+ variant: defaultBuildingVariant,
+ rotationVariant: 2,
+ },
+ {
+ internalId: 30,
+ variant: defaultBuildingVariant,
+ rotationVariant: 3,
+ },
+ {
+ internalId: 52,
+ variant: enumWireVariant.second,
+ rotationVariant: 0,
+ },
+ {
+ internalId: 53,
+ variant: enumWireVariant.second,
+ rotationVariant: 1,
+ },
+ {
+ internalId: 54,
+ variant: enumWireVariant.second,
+ rotationVariant: 2,
+ },
+ {
+ internalId: 55,
+ variant: enumWireVariant.second,
+ rotationVariant: 3,
+ },
+ ];
+ }
+
+ getHasDirectionLockAvailable() {
+ return true;
+ }
+
+ getSilhouetteColor() {
+ return "#61ef6f";
+ }
+
+ getAvailableVariants() {
+ return [defaultBuildingVariant, wireVariants.second];
+ }
+
+ getDimensions() {
+ return new Vector(1, 1);
+ }
+
+ getStayInPlacementMode() {
+ return true;
+ }
+
+ getPlacementSound() {
+ return SOUNDS.placeBelt;
+ }
+
+ getRotateAutomaticallyWhilePlacing() {
+ return true;
+ }
+
+ /** @returns {"wires"} **/
+ getLayer() {
+ return "wires";
+ }
+
+ getSprite() {
+ return null;
+ }
+
+ getIsReplaceable() {
+ return true;
+ }
+
+ /**
+ * @param {GameRoot} root
+ */
+ getIsUnlocked(root) {
+ return root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_wires_painter_and_levers);
+ }
+
+ /**
+ * Creates the entity at the given location
+ * @param {Entity} entity
+ */
+ setupEntityComponents(entity) {
+ entity.addComponent(new WireComponent({}));
+ }
+
+ /**
+ *
+ * @param {Entity} entity
+ * @param {number} rotationVariant
+ * @param {string} variant
+ */
+ updateVariants(entity, rotationVariant, variant) {
+ entity.components.Wire.type = arrayWireRotationVariantToType[rotationVariant];
+ entity.components.Wire.variant = enumWireVariantToVariant[variant];
+ }
+
+ /**
+ *
+ * @param {number} rotation
+ * @param {number} rotationVariant
+ * @param {string} variant
+ * @param {Entity} entity
+ */
+ getSpecialOverlayRenderMatrix(rotation, rotationVariant, variant, entity) {
+ return wireOverlayMatrices[entity.components.Wire.type][rotation];
+ }
+
+ /**
+ *
+ * @param {number} rotationVariant
+ * @param {string} variant
+ * @returns {import("../../core/draw_utils").AtlasSprite}
+ */
+ getPreviewSprite(rotationVariant, variant) {
+ const wireVariant = enumWireVariantToVariant[variant];
+ switch (arrayWireRotationVariantToType[rotationVariant]) {
+ case enumWireType.forward: {
+ return Loader.getSprite("sprites/wires/sets/" + wireVariant + "_forward.png");
+ }
+ case enumWireType.turn: {
+ return Loader.getSprite("sprites/wires/sets/" + wireVariant + "_turn.png");
+ }
+ case enumWireType.split: {
+ return Loader.getSprite("sprites/wires/sets/" + wireVariant + "_split.png");
+ }
+ case enumWireType.cross: {
+ return Loader.getSprite("sprites/wires/sets/" + wireVariant + "_cross.png");
+ }
+ default: {
+ assertAlways(false, "Invalid wire rotation variant");
+ }
+ }
+ }
+
+ getBlueprintSprite(rotationVariant, variant) {
+ return this.getPreviewSprite(rotationVariant, variant);
+ }
+
+ /**
+ * Should compute the optimal rotation variant on the given tile
+ * @param {object} param0
+ * @param {GameRoot} param0.root
+ * @param {Vector} param0.tile
+ * @param {number} param0.rotation
+ * @param {string} param0.variant
+ * @param {string} param0.layer
+ * @return {{ rotation: number, rotationVariant: number, connectedEntities?: Array }}
+ */
+ computeOptimalDirectionAndRotationVariantAtTile({ root, tile, rotation, variant, layer }) {
+ const wireVariant = enumWireVariantToVariant[variant];
+ const connections = {
+ top: root.logic.computeWireEdgeStatus({ tile, wireVariant, edge: enumDirection.top }),
+ right: root.logic.computeWireEdgeStatus({ tile, wireVariant, edge: enumDirection.right }),
+ bottom: root.logic.computeWireEdgeStatus({ tile, wireVariant, edge: enumDirection.bottom }),
+ left: root.logic.computeWireEdgeStatus({ tile, wireVariant, edge: enumDirection.left }),
+ };
+
+ let flag = 0;
+ flag |= connections.top ? 0x1000 : 0;
+ flag |= connections.right ? 0x100 : 0;
+ flag |= connections.bottom ? 0x10 : 0;
+ flag |= connections.left ? 0x1 : 0;
+
+ let targetType = enumWireType.forward;
+
+ // First, reset rotation
+ rotation = 0;
+
+ switch (flag) {
+ case 0x0000:
+ // Nothing
+ break;
+
+ case 0x0001:
+ // Left
+ rotation += 90;
+ break;
+
+ case 0x0010:
+ // Bottom
+ // END
+ break;
+
+ case 0x0011:
+ // Bottom | Left
+ targetType = enumWireType.turn;
+ rotation += 90;
+ break;
+
+ case 0x0100:
+ // Right
+ rotation += 90;
+ break;
+
+ case 0x0101:
+ // Right | Left
+ rotation += 90;
+ break;
+
+ case 0x0110:
+ // Right | Bottom
+ targetType = enumWireType.turn;
+ break;
+
+ case 0x0111:
+ // Right | Bottom | Left
+ targetType = enumWireType.split;
+ break;
+
+ case 0x1000:
+ // Top
+ break;
+
+ case 0x1001:
+ // Top | Left
+ targetType = enumWireType.turn;
+ rotation += 180;
+ break;
+
+ case 0x1010:
+ // Top | Bottom
+ break;
+
+ case 0x1011:
+ // Top | Bottom | Left
+ targetType = enumWireType.split;
+ rotation += 90;
+ break;
+
+ case 0x1100:
+ // Top | Right
+ targetType = enumWireType.turn;
+ rotation -= 90;
+ break;
+
+ case 0x1101:
+ // Top | Right | Left
+ targetType = enumWireType.split;
+ rotation += 180;
+ break;
+
+ case 0x1110:
+ // Top | Right | Bottom
+ targetType = enumWireType.split;
+ rotation -= 90;
+ break;
+
+ case 0x1111:
+ // Top | Right | Bottom | Left
+ targetType = enumWireType.cross;
+ break;
+ }
+
+ return {
+ // Clamp rotation
+ rotation: (rotation + 360 * 10) % 360,
+ rotationVariant: arrayWireRotationVariantToType.indexOf(targetType),
+ };
+ }
+}
diff --git a/src/js/game/buildings/wire_tunnel.js b/src/js/game/buildings/wire_tunnel.js
index 80faa9df..36197622 100644
--- a/src/js/game/buildings/wire_tunnel.js
+++ b/src/js/game/buildings/wire_tunnel.js
@@ -1,67 +1,67 @@
-import { generateMatrixRotations } from "../../core/utils";
-import { Vector } from "../../core/vector";
-import { WireTunnelComponent } from "../components/wire_tunnel";
-import { Entity } from "../entity";
-import { defaultBuildingVariant, MetaBuilding } from "../meta_building";
-import { GameRoot } from "../root";
-import { enumHubGoalRewards } from "../tutorial_goals";
-
-const wireTunnelOverlayMatrix = generateMatrixRotations([0, 1, 0, 1, 1, 1, 0, 1, 0]);
-
-export class MetaWireTunnelBuilding extends MetaBuilding {
- constructor() {
- super("wire_tunnel");
- }
-
- static getAllVariantCombinations() {
- return [
- {
- internalId: 39,
- variant: defaultBuildingVariant,
- },
- ];
- }
-
- getSilhouetteColor() {
- return "#777a86";
- }
-
- /**
- * @param {GameRoot} root
- */
- getIsUnlocked(root) {
- return root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_wires_painter_and_levers);
- }
-
- /**
- *
- * @param {number} rotation
- * @param {number} rotationVariant
- * @param {string} variant
- * @param {Entity} entity
- */
- getSpecialOverlayRenderMatrix(rotation, rotationVariant, variant, entity) {
- return wireTunnelOverlayMatrix[rotation];
- }
-
- getIsRotateable() {
- return false;
- }
-
- getDimensions() {
- return new Vector(1, 1);
- }
-
- /** @returns {"wires"} **/
- getLayer() {
- return "wires";
- }
-
- /**
- * Creates the entity at the given location
- * @param {Entity} entity
- */
- setupEntityComponents(entity) {
- entity.addComponent(new WireTunnelComponent());
- }
-}
+import { generateMatrixRotations } from "../../core/utils";
+import { Vector } from "../../core/vector";
+import { WireTunnelComponent } from "../components/wire_tunnel";
+import { Entity } from "../entity";
+import { defaultBuildingVariant, MetaBuilding } from "../meta_building";
+import { GameRoot } from "../root";
+import { enumHubGoalRewards } from "../tutorial_goals";
+
+const wireTunnelOverlayMatrix = generateMatrixRotations([0, 1, 0, 1, 1, 1, 0, 1, 0]);
+
+export class MetaWireTunnelBuilding extends MetaBuilding {
+ constructor() {
+ super("wire_tunnel");
+ }
+
+ static getAllVariantCombinations() {
+ return [
+ {
+ internalId: 39,
+ variant: defaultBuildingVariant,
+ },
+ ];
+ }
+
+ getSilhouetteColor() {
+ return "#777a86";
+ }
+
+ /**
+ * @param {GameRoot} root
+ */
+ getIsUnlocked(root) {
+ return root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_wires_painter_and_levers);
+ }
+
+ /**
+ *
+ * @param {number} rotation
+ * @param {number} rotationVariant
+ * @param {string} variant
+ * @param {Entity} entity
+ */
+ getSpecialOverlayRenderMatrix(rotation, rotationVariant, variant, entity) {
+ return wireTunnelOverlayMatrix[rotation];
+ }
+
+ getIsRotateable() {
+ return false;
+ }
+
+ getDimensions() {
+ return new Vector(1, 1);
+ }
+
+ /** @returns {"wires"} **/
+ getLayer() {
+ return "wires";
+ }
+
+ /**
+ * Creates the entity at the given location
+ * @param {Entity} entity
+ */
+ setupEntityComponents(entity) {
+ entity.addComponent(new WireTunnelComponent());
+ }
+}
diff --git a/src/js/game/camera.js b/src/js/game/camera.js
index fc08d73f..b5001f45 100644
--- a/src/js/game/camera.js
+++ b/src/js/game/camera.js
@@ -1,1039 +1,1041 @@
-import { clickDetectorGlobals } from "../core/click_detector";
-import { globalConfig, SUPPORT_TOUCH } from "../core/config";
-import { createLogger } from "../core/logging";
-import { Rectangle } from "../core/rectangle";
-import { Signal, STOP_PROPAGATION } from "../core/signal";
-import { clamp } from "../core/utils";
-import { mixVector, Vector } from "../core/vector";
-import { BasicSerializableObject, types } from "../savegame/serialization";
-import { KEYMAPPINGS } from "./key_action_mapper";
-import { GameRoot } from "./root";
-
-const logger = createLogger("camera");
-
-export const USER_INTERACT_MOVE = "move";
-export const USER_INTERACT_ZOOM = "zoom";
-export const USER_INTERACT_TOUCHEND = "touchend";
-
-const velocitySmoothing = 0.5;
-const velocityFade = 0.98;
-const velocityStrength = 0.4;
-const velocityMax = 20;
-const ticksBeforeErasingVelocity = 10;
-
-/**
- * @enum {string}
- */
-export const enumMouseButton = {
- left: "left",
- middle: "middle",
- right: "right",
-};
-
-export class Camera extends BasicSerializableObject {
- constructor(root) {
- super();
-
- /** @type {GameRoot} */
- this.root = root;
-
- // Zoom level, 2 means double size
-
- // Find optimal initial zoom
-
- this.zoomLevel = this.findInitialZoom();
- this.clampZoomLevel();
-
- /** @type {Vector} */
- this.center = new Vector(0, 0);
-
- // Input handling
- this.currentlyMoving = false;
- this.lastMovingPosition = null;
- this.lastMovingPositionLastTick = null;
- this.numTicksStandingStill = null;
- this.cameraUpdateTimeBucket = 0.0;
- this.didMoveSinceTouchStart = false;
- this.currentlyPinching = false;
- this.lastPinchPositions = null;
-
- this.keyboardForce = new Vector();
-
- // Signal which gets emitted once the user changed something
- this.userInteraction = new Signal();
-
- /** @type {Vector} */
- this.currentShake = new Vector(0, 0);
-
- /** @type {Vector} */
- this.currentPan = new Vector(0, 0);
-
- // Set desired pan (camera movement)
- /** @type {Vector} */
- this.desiredPan = new Vector(0, 0);
-
- // Set desired camera center
- /** @type {Vector} */
- this.desiredCenter = null;
-
- // Set desired camera zoom
- /** @type {number} */
- this.desiredZoom = null;
-
- /** @type {Vector} */
- this.touchPostMoveVelocity = new Vector(0, 0);
-
- // Handlers
- this.downPreHandler = /** @type {TypedSignal<[Vector, enumMouseButton]>} */ (new Signal());
- this.movePreHandler = /** @type {TypedSignal<[Vector]>} */ (new Signal());
- // this.pinchPreHandler = /** @type {TypedSignal<[Vector]>} */ (new Signal());
- this.upPostHandler = /** @type {TypedSignal<[Vector]>} */ (new Signal());
-
- this.internalInitEvents();
- this.clampZoomLevel();
- this.bindKeys();
- if (G_IS_DEV) {
- window.addEventListener("keydown", ev => {
- if (ev.key === "i") {
- this.zoomLevel = 3;
- }
- });
- }
- }
-
- // Serialization
- static getId() {
- return "Camera";
- }
-
- static getSchema() {
- return {
- zoomLevel: types.float,
- center: types.vector,
- };
- }
-
- deserialize(data) {
- const errorCode = super.deserialize(data);
- if (errorCode) {
- return errorCode;
- }
-
- // Safety
- this.clampZoomLevel();
- }
-
- // Simple getters & setters
-
- addScreenShake(amount) {
- const currentShakeAmount = this.currentShake.length();
- const scale = 1 / (1 + 3 * currentShakeAmount);
- this.currentShake.x = this.currentShake.x + 2 * (Math.random() - 0.5) * scale * amount;
- this.currentShake.y = this.currentShake.y + 2 * (Math.random() - 0.5) * scale * amount;
- }
-
- /**
- * Sets a point in world space to focus on
- * @param {Vector} center
- */
- setDesiredCenter(center) {
- this.desiredCenter = center.copy();
- this.currentlyMoving = false;
- }
-
- /**
- * Sets a desired zoom level
- * @param {number} zoom
- */
- setDesiredZoom(zoom) {
- this.desiredZoom = zoom;
- }
-
- /**
- * Returns if this camera is currently moving by a non-user interaction
- */
- isCurrentlyMovingToDesiredCenter() {
- return this.desiredCenter !== null;
- }
-
- /**
- * Sets the camera pan, every frame the camera will move by this amount
- * @param {Vector} pan
- */
- setPan(pan) {
- this.desiredPan = pan.copy();
- }
-
- /**
- * Finds a good initial zoom level
- */
- findInitialZoom() {
- let desiredWorldSpaceWidth = 18 * globalConfig.tileSize;
- if (window.innerWidth < 1000) {
- desiredWorldSpaceWidth = 12 * globalConfig.tileSize;
- }
-
- const zoomLevelX = this.root.gameWidth / desiredWorldSpaceWidth;
- const zoomLevelY = this.root.gameHeight / desiredWorldSpaceWidth;
-
- const finalLevel = Math.min(zoomLevelX, zoomLevelY);
- assert(
- Number.isFinite(finalLevel) && finalLevel > 0,
- "Invalid zoom level computed for initial zoom: " + finalLevel
- );
- return finalLevel;
- }
-
- /**
- * Clears all animations
- */
- clearAnimations() {
- this.touchPostMoveVelocity.x = 0;
- this.touchPostMoveVelocity.y = 0;
- this.desiredCenter = null;
- this.desiredPan.x = 0;
- this.desiredPan.y = 0;
- this.currentPan.x = 0;
- this.currentPan.y = 0;
- this.currentlyPinching = false;
- this.currentlyMoving = false;
- this.lastMovingPosition = null;
- this.didMoveSinceTouchStart = false;
- this.desiredZoom = null;
- }
-
- /**
- * Returns if the user is currently interacting with the camera
- * @returns {boolean} true if the user interacts
- */
- isCurrentlyInteracting() {
- if (this.currentlyPinching) {
- return true;
- }
- if (this.currentlyMoving) {
- // Only interacting if moved at least once
- return this.didMoveSinceTouchStart;
- }
- if (this.touchPostMoveVelocity.lengthSquare() > 1) {
- return true;
- }
- return false;
- }
-
- /**
- * Returns if in the next frame the viewport will change
- * @returns {boolean} true if it willchange
- */
- viewportWillChange() {
- return this.desiredCenter !== null || this.desiredZoom !== null || this.isCurrentlyInteracting();
- }
-
- /**
- * Cancels all interactions, that is user interaction and non user interaction
- */
- cancelAllInteractions() {
- this.touchPostMoveVelocity = new Vector(0, 0);
- this.desiredCenter = null;
- this.currentlyMoving = false;
- this.currentlyPinching = false;
- this.desiredZoom = null;
- }
-
- /**
- * Returns effective viewport width
- */
- getViewportWidth() {
- return this.root.gameWidth / this.zoomLevel;
- }
-
- /**
- * Returns effective viewport height
- */
- getViewportHeight() {
- return this.root.gameHeight / this.zoomLevel;
- }
-
- /**
- * Returns effective world space viewport left
- */
- getViewportLeft() {
- return this.center.x - this.getViewportWidth() / 2 + (this.currentShake.x * 10) / this.zoomLevel;
- }
-
- /**
- * Returns effective world space viewport right
- */
- getViewportRight() {
- return this.center.x + this.getViewportWidth() / 2 + (this.currentShake.x * 10) / this.zoomLevel;
- }
-
- /**
- * Returns effective world space viewport top
- */
- getViewportTop() {
- return this.center.y - this.getViewportHeight() / 2 + (this.currentShake.x * 10) / this.zoomLevel;
- }
-
- /**
- * Returns effective world space viewport bottom
- */
- getViewportBottom() {
- return this.center.y + this.getViewportHeight() / 2 + (this.currentShake.x * 10) / this.zoomLevel;
- }
-
- /**
- * Returns the visible world space rect
- * @returns {Rectangle}
- */
- getVisibleRect() {
- return Rectangle.fromTRBL(
- Math.floor(this.getViewportTop()),
- Math.ceil(this.getViewportRight()),
- Math.ceil(this.getViewportBottom()),
- Math.floor(this.getViewportLeft())
- );
- }
-
- getIsMapOverlayActive() {
- return this.zoomLevel < globalConfig.mapChunkOverviewMinZoom;
- }
-
- /**
- * Attaches all event listeners
- */
- internalInitEvents() {
- this.eventListenerTouchStart = this.onTouchStart.bind(this);
- this.eventListenerTouchEnd = this.onTouchEnd.bind(this);
- this.eventListenerTouchMove = this.onTouchMove.bind(this);
- this.eventListenerMousewheel = this.onMouseWheel.bind(this);
- this.eventListenerMouseDown = this.onMouseDown.bind(this);
- this.eventListenerMouseMove = this.onMouseMove.bind(this);
- this.eventListenerMouseUp = this.onMouseUp.bind(this);
-
- if (SUPPORT_TOUCH) {
- this.root.canvas.addEventListener("touchstart", this.eventListenerTouchStart);
- this.root.canvas.addEventListener("touchend", this.eventListenerTouchEnd);
- this.root.canvas.addEventListener("touchcancel", this.eventListenerTouchEnd);
- this.root.canvas.addEventListener("touchmove", this.eventListenerTouchMove);
- }
-
- this.root.canvas.addEventListener("wheel", this.eventListenerMousewheel);
- this.root.canvas.addEventListener("mousedown", this.eventListenerMouseDown);
- this.root.canvas.addEventListener("mousemove", this.eventListenerMouseMove);
- window.addEventListener("mouseup", this.eventListenerMouseUp);
- // this.root.canvas.addEventListener("mouseout", this.eventListenerMouseUp);
- }
-
- /**
- * Cleans up all event listeners
- */
- cleanup() {
- if (SUPPORT_TOUCH) {
- this.root.canvas.removeEventListener("touchstart", this.eventListenerTouchStart);
- this.root.canvas.removeEventListener("touchend", this.eventListenerTouchEnd);
- this.root.canvas.removeEventListener("touchcancel", this.eventListenerTouchEnd);
- this.root.canvas.removeEventListener("touchmove", this.eventListenerTouchMove);
- }
-
- this.root.canvas.removeEventListener("wheel", this.eventListenerMousewheel);
- this.root.canvas.removeEventListener("mousedown", this.eventListenerMouseDown);
- this.root.canvas.removeEventListener("mousemove", this.eventListenerMouseMove);
- window.removeEventListener("mouseup", this.eventListenerMouseUp);
- // this.root.canvas.removeEventListener("mouseout", this.eventListenerMouseUp);
- }
-
- /**
- * Binds the arrow keys
- */
- bindKeys() {
- const mapper = this.root.keyMapper;
- mapper.getBinding(KEYMAPPINGS.navigation.mapMoveUp).add(() => (this.keyboardForce.y = -1));
- mapper.getBinding(KEYMAPPINGS.navigation.mapMoveDown).add(() => (this.keyboardForce.y = 1));
- mapper.getBinding(KEYMAPPINGS.navigation.mapMoveRight).add(() => (this.keyboardForce.x = 1));
- mapper.getBinding(KEYMAPPINGS.navigation.mapMoveLeft).add(() => (this.keyboardForce.x = -1));
-
- mapper
- .getBinding(KEYMAPPINGS.navigation.mapZoomIn)
- .add(() => (this.desiredZoom = this.zoomLevel * 1.2));
- mapper
- .getBinding(KEYMAPPINGS.navigation.mapZoomOut)
- .add(() => (this.desiredZoom = this.zoomLevel / 1.2));
-
- mapper.getBinding(KEYMAPPINGS.navigation.centerMap).add(() => this.centerOnMap());
- }
-
- centerOnMap() {
- this.desiredCenter = new Vector(0, 0);
- }
-
- /**
- * Converts from screen to world space
- * @param {Vector} screen
- * @returns {Vector} world space
- */
- screenToWorld(screen) {
- const centerSpace = screen.subScalars(this.root.gameWidth / 2, this.root.gameHeight / 2);
- return centerSpace.divideScalar(this.zoomLevel).add(this.center);
- }
-
- /**
- * Converts from world to screen space
- * @param {Vector} world
- * @returns {Vector} screen space
- */
- worldToScreen(world) {
- const screenSpace = world.sub(this.center).multiplyScalar(this.zoomLevel);
- return screenSpace.addScalars(this.root.gameWidth / 2, this.root.gameHeight / 2);
- }
-
- /**
- * Returns if a point is on screen
- * @param {Vector} point
- * @returns {boolean} true if its on screen
- */
- isWorldPointOnScreen(point) {
- const rect = this.getVisibleRect();
- return rect.containsPoint(point.x, point.y);
- }
-
- getMaximumZoom() {
- return this.root.gameMode.getMaximumZoom();
- }
-
- getMinimumZoom() {
- return this.root.gameMode.getMinimumZoom();
- }
-
- /**
- * Returns if we can further zoom in
- * @returns {boolean}
- */
- canZoomIn() {
- return this.zoomLevel <= this.getMaximumZoom() - 0.01;
- }
-
- /**
- * Returns if we can further zoom out
- * @returns {boolean}
- */
- canZoomOut() {
- return this.zoomLevel >= this.getMinimumZoom() + 0.01;
- }
-
- // EVENTS
-
- /**
- * Checks if the mouse event is too close after a touch event and thus
- * should get ignored
- */
- checkPreventDoubleMouse() {
- if (performance.now() - clickDetectorGlobals.lastTouchTime < 1000.0) {
- return false;
- }
- return true;
- }
-
- /**
- * Mousedown handler
- * @param {MouseEvent} event
- */
- onMouseDown(event) {
- if (event.cancelable) {
- event.preventDefault();
- // event.stopPropagation();
- }
-
- if (!this.checkPreventDoubleMouse()) {
- return;
- }
-
- this.touchPostMoveVelocity = new Vector(0, 0);
- if (event.button === 0) {
- this.combinedSingleTouchStartHandler(event.clientX, event.clientY);
- } else if (event.button === 1) {
- this.downPreHandler.dispatch(new Vector(event.clientX, event.clientY), enumMouseButton.middle);
- } else if (event.button === 2) {
- this.downPreHandler.dispatch(new Vector(event.clientX, event.clientY), enumMouseButton.right);
- }
- return false;
- }
-
- /**
- * Mousemove handler
- * @param {MouseEvent} event
- */
- onMouseMove(event) {
- if (event.cancelable) {
- event.preventDefault();
- // event.stopPropagation();
- }
-
- if (!this.checkPreventDoubleMouse()) {
- return;
- }
-
- if (event.button === 0) {
- this.combinedSingleTouchMoveHandler(event.clientX, event.clientY);
- }
-
- // Clamp everything afterwards
- this.clampZoomLevel();
- this.clampToBounds();
- return false;
- }
-
- /**
- * Mouseup handler
- * @param {MouseEvent=} event
- */
- onMouseUp(event) {
- if (event) {
- if (event.cancelable) {
- event.preventDefault();
- // event.stopPropagation();
- }
- }
-
- if (!this.checkPreventDoubleMouse()) {
- return;
- }
-
- this.combinedSingleTouchStopHandler(event.clientX, event.clientY);
- return false;
- }
-
- /**
- * Mousewheel event
- * @param {WheelEvent} event
- */
- onMouseWheel(event) {
- if (event.cancelable) {
- event.preventDefault();
- // event.stopPropagation();
- }
- const prevZoom = this.zoomLevel;
-
- const scale = 1 + 0.15 * this.root.app.settings.getScrollWheelSensitivity();
- assert(Number.isFinite(scale), "Got invalid scale in mouse wheel event: " + event.deltaY);
- assert(Number.isFinite(this.zoomLevel), "Got invalid zoom level *before* wheel: " + this.zoomLevel);
- this.zoomLevel *= event.deltaY < 0 ? scale : 1 / scale;
- assert(Number.isFinite(this.zoomLevel), "Got invalid zoom level *after* wheel: " + this.zoomLevel);
-
- this.clampZoomLevel();
- this.desiredZoom = null;
-
- let mousePosition = this.root.app.mousePosition;
- if (!this.root.app.settings.getAllSettings().zoomToCursor) {
- mousePosition = new Vector(this.root.gameWidth / 2, this.root.gameHeight / 2);
- }
-
- if (mousePosition) {
- const worldPos = this.root.camera.screenToWorld(mousePosition);
- const worldDelta = worldPos.sub(this.center);
- const actualDelta = this.zoomLevel / prevZoom - 1;
- this.center = this.center.add(worldDelta.multiplyScalar(actualDelta));
- this.desiredCenter = null;
- }
-
- return false;
- }
-
- /**
- * Touch start handler
- * @param {TouchEvent} event
- */
- onTouchStart(event) {
- if (event.cancelable) {
- event.preventDefault();
- // event.stopPropagation();
- }
-
- clickDetectorGlobals.lastTouchTime = performance.now();
- this.touchPostMoveVelocity = new Vector(0, 0);
-
- if (event.touches.length === 1) {
- const touch = event.touches[0];
- this.combinedSingleTouchStartHandler(touch.clientX, touch.clientY);
- } else if (event.touches.length === 2) {
- // if (this.pinchPreHandler.dispatch() === STOP_PROPAGATION) {
- // // Something prevented pinching
- // return false;
- // }
-
- const touch1 = event.touches[0];
- const touch2 = event.touches[1];
- this.currentlyMoving = false;
- this.currentlyPinching = true;
- this.lastPinchPositions = [
- new Vector(touch1.clientX, touch1.clientY),
- new Vector(touch2.clientX, touch2.clientY),
- ];
- }
- return false;
- }
-
- /**
- * Touch move handler
- * @param {TouchEvent} event
- */
- onTouchMove(event) {
- if (event.cancelable) {
- event.preventDefault();
- // event.stopPropagation();
- }
-
- clickDetectorGlobals.lastTouchTime = performance.now();
-
- if (event.touches.length === 1) {
- const touch = event.touches[0];
- this.combinedSingleTouchMoveHandler(touch.clientX, touch.clientY);
- } else if (event.touches.length === 2) {
- if (this.currentlyPinching) {
- const touch1 = event.touches[0];
- const touch2 = event.touches[1];
-
- const newPinchPositions = [
- new Vector(touch1.clientX, touch1.clientY),
- new Vector(touch2.clientX, touch2.clientY),
- ];
-
- // Get distance of taps last time and now
- const lastDistance = this.lastPinchPositions[0].distance(this.lastPinchPositions[1]);
- const thisDistance = newPinchPositions[0].distance(newPinchPositions[1]);
-
- // IMPORTANT to do math max here to avoid NaN and causing an invalid zoom level
- const difference = thisDistance / Math.max(0.001, lastDistance);
-
- // Find old center of zoom
- let oldCenter = this.lastPinchPositions[0].centerPoint(this.lastPinchPositions[1]);
-
- // Find new center of zoom
- let center = newPinchPositions[0].centerPoint(newPinchPositions[1]);
-
- // Compute movement
- let movement = oldCenter.sub(center);
- this.center.x += movement.x / this.zoomLevel;
- this.center.y += movement.y / this.zoomLevel;
-
- // Compute zoom
- center = center.sub(new Vector(this.root.gameWidth / 2, this.root.gameHeight / 2));
-
- // Apply zoom
- assert(
- Number.isFinite(difference),
- "Invalid pinch difference: " +
- difference +
- "(last=" +
- lastDistance +
- ", new = " +
- thisDistance +
- ")"
- );
- this.zoomLevel *= difference;
-
- // Stick to pivot point
- const correcture = center.multiplyScalar(difference - 1).divideScalar(this.zoomLevel);
-
- this.center = this.center.add(correcture);
- this.lastPinchPositions = newPinchPositions;
- this.userInteraction.dispatch(USER_INTERACT_MOVE);
-
- // Since we zoomed, abort any programmed zooming
- if (this.desiredZoom) {
- this.desiredZoom = null;
- }
- }
- }
-
- // Clamp everything afterwards
- this.clampZoomLevel();
- return false;
- }
-
- /**
- * Touch end and cancel handler
- * @param {TouchEvent=} event
- */
- onTouchEnd(event) {
- if (event) {
- if (event.cancelable) {
- event.preventDefault();
- // event.stopPropagation();
- }
- }
-
- clickDetectorGlobals.lastTouchTime = performance.now();
- if (event.changedTouches.length === 0) {
- logger.warn("Touch end without changed touches");
- }
-
- const touch = event.changedTouches[0];
- this.combinedSingleTouchStopHandler(touch.clientX, touch.clientY);
- return false;
- }
-
- /**
- * Internal touch start handler
- * @param {number} x
- * @param {number} y
- */
- combinedSingleTouchStartHandler(x, y) {
- const pos = new Vector(x, y);
- if (this.downPreHandler.dispatch(pos, enumMouseButton.left) === STOP_PROPAGATION) {
- // Somebody else captured it
- return;
- }
-
- this.touchPostMoveVelocity = new Vector(0, 0);
- this.currentlyMoving = true;
- this.lastMovingPosition = pos;
- this.lastMovingPositionLastTick = null;
- this.numTicksStandingStill = 0;
- this.didMoveSinceTouchStart = false;
- }
-
- /**
- * Internal touch move handler
- * @param {number} x
- * @param {number} y
- */
- combinedSingleTouchMoveHandler(x, y) {
- const pos = new Vector(x, y);
- if (this.movePreHandler.dispatch(pos) === STOP_PROPAGATION) {
- // Somebody else captured it
- return;
- }
-
- if (!this.currentlyMoving) {
- return false;
- }
-
- let delta = this.lastMovingPosition.sub(pos).divideScalar(this.zoomLevel);
- if (G_IS_DEV && globalConfig.debug.testCulling) {
- // When testing culling, we see everything from the same distance
- delta = delta.multiplyScalar(this.zoomLevel * -2);
- }
-
- this.didMoveSinceTouchStart = this.didMoveSinceTouchStart || delta.length() > 0;
- this.center = this.center.add(delta);
-
- this.touchPostMoveVelocity = this.touchPostMoveVelocity
- .multiplyScalar(velocitySmoothing)
- .add(delta.multiplyScalar(1 - velocitySmoothing));
-
- this.lastMovingPosition = pos;
- this.userInteraction.dispatch(USER_INTERACT_MOVE);
-
- // Since we moved, abort any programmed moving
- if (this.desiredCenter) {
- this.desiredCenter = null;
- }
- }
-
- /**
- * Internal touch stop handler
- */
- combinedSingleTouchStopHandler(x, y) {
- if (this.currentlyMoving || this.currentlyPinching) {
- this.currentlyMoving = false;
- this.currentlyPinching = false;
- this.lastMovingPosition = null;
- this.lastMovingPositionLastTick = null;
- this.numTicksStandingStill = 0;
- this.lastPinchPositions = null;
- this.userInteraction.dispatch(USER_INTERACT_TOUCHEND);
- this.didMoveSinceTouchStart = false;
- }
- this.upPostHandler.dispatch(new Vector(x, y));
- }
-
- /**
- * Clamps the camera zoom level within the allowed range
- */
- clampZoomLevel() {
- if (G_IS_DEV && globalConfig.debug.disableZoomLimits) {
- return;
- }
- assert(Number.isFinite(this.zoomLevel), "Invalid zoom level *before* clamp: " + this.zoomLevel);
- this.zoomLevel = clamp(this.zoomLevel, this.getMinimumZoom(), this.getMaximumZoom());
- assert(Number.isFinite(this.zoomLevel), "Invalid zoom level *after* clamp: " + this.zoomLevel);
-
- if (this.desiredZoom) {
- this.desiredZoom = clamp(this.desiredZoom, this.getMinimumZoom(), this.getMaximumZoom());
- }
- }
-
- /**
- * Clamps the center within set boundaries
- */
- clampToBounds() {
- const bounds = this.root.gameMode.getCameraBounds();
- if (!bounds) {
- return;
- }
-
- const tileScaleBounds = this.root.gameMode.getCameraBounds().allScaled(globalConfig.tileSize);
- this.center.x = clamp(this.center.x, tileScaleBounds.x, tileScaleBounds.x + tileScaleBounds.w);
- this.center.y = clamp(this.center.y, tileScaleBounds.y, tileScaleBounds.y + tileScaleBounds.h);
- }
-
- /**
- * Updates the camera
- * @param {number} dt Delta time in milliseconds
- */
- update(dt) {
- dt = Math.min(dt, 33);
- this.cameraUpdateTimeBucket += dt;
-
- // Simulate movement of N FPS
- const updatesPerFrame = 4;
- const physicsStepSizeMs = 1000.0 / (60.0 * updatesPerFrame);
-
- let now = this.root.time.systemNow() - 3 * physicsStepSizeMs;
-
- while (this.cameraUpdateTimeBucket > physicsStepSizeMs) {
- now += physicsStepSizeMs;
- this.cameraUpdateTimeBucket -= physicsStepSizeMs;
-
- this.internalUpdatePanning(now, physicsStepSizeMs);
- this.internalUpdateMousePanning(now, physicsStepSizeMs);
- this.internalUpdateZooming(now, physicsStepSizeMs);
- this.internalUpdateCentering(now, physicsStepSizeMs);
- this.internalUpdateShake(now, physicsStepSizeMs);
- this.internalUpdateKeyboardForce(now, physicsStepSizeMs);
- }
- this.clampZoomLevel();
- }
-
- /**
- * Prepares a context to transform it
- * @param {CanvasRenderingContext2D} context
- */
- transform(context) {
- if (G_IS_DEV && globalConfig.debug.testCulling) {
- context.transform(1, 0, 0, 1, 100, 100);
- return;
- }
-
- this.clampZoomLevel();
- const zoom = this.zoomLevel;
-
- context.transform(
- // Scale, skew, rotate
- zoom,
- 0,
- 0,
- zoom,
-
- // Translate
- -zoom * this.getViewportLeft(),
- -zoom * this.getViewportTop()
- );
- }
-
- /**
- * Internal shake handler
- * @param {number} now Time now in seconds
- * @param {number} dt Delta time
- */
- internalUpdateShake(now, dt) {
- this.currentShake = this.currentShake.multiplyScalar(0.92);
- }
-
- /**
- * Internal pan handler
- * @param {number} now Time now in seconds
- * @param {number} dt Delta time
- */
- internalUpdatePanning(now, dt) {
- const baseStrength = velocityStrength * this.root.app.platformWrapper.getTouchPanStrength();
-
- this.touchPostMoveVelocity = this.touchPostMoveVelocity.multiplyScalar(velocityFade);
-
- // Check if the camera is being dragged but standing still: if not, zero out `touchPostMoveVelocity`.
- if (this.currentlyMoving && this.desiredCenter === null) {
- if (
- this.lastMovingPositionLastTick !== null &&
- this.lastMovingPositionLastTick.equalsEpsilon(this.lastMovingPosition)
- ) {
- this.numTicksStandingStill++;
- } else {
- this.numTicksStandingStill = 0;
- }
- this.lastMovingPositionLastTick = this.lastMovingPosition.copy();
-
- if (this.numTicksStandingStill >= ticksBeforeErasingVelocity) {
- this.touchPostMoveVelocity.x = 0;
- this.touchPostMoveVelocity.y = 0;
- }
- }
- // Check influence of past points
- if (!this.currentlyMoving && !this.currentlyPinching) {
- const len = this.touchPostMoveVelocity.length();
- if (len >= velocityMax) {
- this.touchPostMoveVelocity.x = (this.touchPostMoveVelocity.x * velocityMax) / len;
- this.touchPostMoveVelocity.y = (this.touchPostMoveVelocity.y * velocityMax) / len;
- }
-
- this.center = this.center.add(this.touchPostMoveVelocity.multiplyScalar(baseStrength));
-
- // Panning
- this.currentPan = mixVector(this.currentPan, this.desiredPan, 0.06);
- this.center = this.center.add(this.currentPan.multiplyScalar((0.5 * dt) / this.zoomLevel));
- this.clampToBounds();
- }
- }
-
- /**
- * Internal screen panning handler
- * @param {number} now
- * @param {number} dt
- */
- internalUpdateMousePanning(now, dt) {
- if (!this.root.app.focused) {
- return;
- }
-
- if (!this.root.app.settings.getAllSettings().enableMousePan) {
- // Not enabled
- return;
- }
-
- const mousePos = this.root.app.mousePosition;
- if (!mousePos) {
- return;
- }
-
- if (this.root.hud.shouldPauseGame() || this.root.hud.hasBlockingOverlayOpen()) {
- return;
- }
-
- if (this.desiredCenter || this.desiredZoom || this.currentlyMoving || this.currentlyPinching) {
- // Performing another method of movement right now
- return;
- }
-
- if (
- mousePos.x < 0 ||
- mousePos.y < 0 ||
- mousePos.x > this.root.gameWidth ||
- mousePos.y > this.root.gameHeight
- ) {
- // Out of screen
- return;
- }
-
- const panAreaPixels = 2;
-
- const panVelocity = new Vector();
- if (mousePos.x < panAreaPixels) {
- panVelocity.x -= 1;
- }
- if (mousePos.x > this.root.gameWidth - panAreaPixels) {
- panVelocity.x += 1;
- }
-
- if (mousePos.y < panAreaPixels) {
- panVelocity.y -= 1;
- }
- if (mousePos.y > this.root.gameHeight - panAreaPixels) {
- panVelocity.y += 1;
- }
-
- this.center = this.center.add(
- panVelocity.multiplyScalar(
- ((0.5 * dt) / this.zoomLevel) * this.root.app.settings.getMovementSpeed()
- )
- );
-
- this.clampToBounds();
- }
-
- /**
- * Updates the non user interaction zooming
- * @param {number} now Time now in seconds
- * @param {number} dt Delta time
- */
- internalUpdateZooming(now, dt) {
- if (!this.currentlyPinching && this.desiredZoom !== null) {
- const diff = this.zoomLevel - this.desiredZoom;
- if (Math.abs(diff) > 0.0001) {
- let fade = 0.94;
- if (diff > 0) {
- // Zoom out faster than in
- fade = 0.9;
- }
-
- assert(Number.isFinite(this.desiredZoom), "Desired zoom is NaN: " + this.desiredZoom);
- assert(Number.isFinite(fade), "Zoom fade is NaN: " + fade);
- this.zoomLevel = this.zoomLevel * fade + this.desiredZoom * (1 - fade);
- assert(Number.isFinite(this.zoomLevel), "Zoom level is NaN after fade: " + this.zoomLevel);
- } else {
- this.zoomLevel = this.desiredZoom;
- this.desiredZoom = null;
- }
- }
- }
-
- /**
- * Updates the non user interaction centering
- * @param {number} now Time now in seconds
- * @param {number} dt Delta time
- */
- internalUpdateCentering(now, dt) {
- if (!this.currentlyMoving && this.desiredCenter !== null) {
- const diff = this.center.direction(this.desiredCenter);
- const length = diff.length();
- const tolerance = 1 / this.zoomLevel;
- if (length > tolerance) {
- const movement = diff.multiplyScalar(Math.min(1, dt * 0.008));
- this.center.x += movement.x;
- this.center.y += movement.y;
- } else {
- this.desiredCenter = null;
- }
- }
- }
-
- /**
- * Updates the keyboard forces
- * @param {number} now
- * @param {number} dt Delta time
- */
- internalUpdateKeyboardForce(now, dt) {
- if (!this.currentlyMoving && this.desiredCenter == null) {
- const limitingDimension = Math.min(this.root.gameWidth, this.root.gameHeight);
-
- const moveAmount = ((limitingDimension / 2048) * dt) / this.zoomLevel;
-
- let forceX = 0;
- let forceY = 0;
-
- const actionMapper = this.root.keyMapper;
- if (actionMapper.getBinding(KEYMAPPINGS.navigation.mapMoveUp).pressed) {
- forceY -= 1;
- }
-
- if (actionMapper.getBinding(KEYMAPPINGS.navigation.mapMoveDown).pressed) {
- forceY += 1;
- }
-
- if (actionMapper.getBinding(KEYMAPPINGS.navigation.mapMoveLeft).pressed) {
- forceX -= 1;
- }
-
- if (actionMapper.getBinding(KEYMAPPINGS.navigation.mapMoveRight).pressed) {
- forceX += 1;
- }
-
- let movementSpeed =
- this.root.app.settings.getMovementSpeed() *
- (actionMapper.getBinding(KEYMAPPINGS.navigation.mapMoveFaster).pressed ? 4 : 1);
-
- this.center.x += moveAmount * forceX * movementSpeed;
- this.center.y += moveAmount * forceY * movementSpeed;
-
- this.clampToBounds();
- }
- }
-}
+import { clickDetectorGlobals } from "../core/click_detector";
+import { globalConfig, SUPPORT_TOUCH } from "../core/config";
+import { createLogger } from "../core/logging";
+import { Rectangle } from "../core/rectangle";
+import { Signal, STOP_PROPAGATION } from "../core/signal";
+import { clamp } from "../core/utils";
+import { mixVector, Vector } from "../core/vector";
+import { BasicSerializableObject, types } from "../savegame/serialization";
+import { KEYMAPPINGS } from "./key_action_mapper";
+import { GameRoot } from "./root";
+
+const logger = createLogger("camera");
+
+// @TODO: unused signal
+export const USER_INTERACT_MOVE = "move";
+export const USER_INTERACT_ZOOM = "zoom";
+export const USER_INTERACT_TOUCHEND = "touchend";
+
+const velocitySmoothing = 0.5;
+const velocityFade = 0.98;
+const velocityStrength = 0.4;
+const velocityMax = 20;
+const ticksBeforeErasingVelocity = 10;
+
+/**
+ * @enum {string}
+ */
+export const enumMouseButton = {
+ left: "left",
+ middle: "middle",
+ right: "right",
+};
+
+export class Camera extends BasicSerializableObject {
+ constructor(root) {
+ super();
+
+ /** @type {GameRoot} */
+ this.root = root;
+
+ // Zoom level, 2 means double size
+
+ // Find optimal initial zoom
+
+ this.zoomLevel = this.findInitialZoom();
+ this.clampZoomLevel();
+
+ /** @type {Vector} */
+ this.center = new Vector(0, 0);
+
+ // Input handling
+ this.currentlyMoving = false;
+ this.lastMovingPosition = null;
+ this.lastMovingPositionLastTick = null;
+ this.numTicksStandingStill = null;
+ this.cameraUpdateTimeBucket = 0.0;
+ this.didMoveSinceTouchStart = false;
+ this.currentlyPinching = false;
+ this.lastPinchPositions = null;
+
+ this.keyboardForce = new Vector();
+
+ // Signal which gets emitted once the user changed something
+ /** @type {Signal<[string]>} */
+ this.userInteraction = new Signal();
+
+ /** @type {Vector} */
+ this.currentShake = new Vector(0, 0);
+
+ /** @type {Vector} */
+ this.currentPan = new Vector(0, 0);
+
+ // Set desired pan (camera movement)
+ /** @type {Vector} */
+ this.desiredPan = new Vector(0, 0);
+
+ // Set desired camera center
+ /** @type {Vector} */
+ this.desiredCenter = null;
+
+ // Set desired camera zoom
+ /** @type {number} */
+ this.desiredZoom = null;
+
+ /** @type {Vector} */
+ this.touchPostMoveVelocity = new Vector(0, 0);
+
+ // Handlers
+ this.downPreHandler = /** @type {Signal<[Vector, enumMouseButton]>} */ (new Signal());
+ this.movePreHandler = /** @type {Signal<[Vector]>} */ (new Signal());
+ // this.pinchPreHandler = /** @type {Signal<[Vector]>} */ (new Signal());
+ this.upPostHandler = /** @type {Signal<[Vector]>} */ (new Signal());
+
+ this.internalInitEvents();
+ this.clampZoomLevel();
+ this.bindKeys();
+ if (G_IS_DEV) {
+ window.addEventListener("keydown", ev => {
+ if (ev.key === "i") {
+ this.zoomLevel = 3;
+ }
+ });
+ }
+ }
+
+ // Serialization
+ static getId() {
+ return "Camera";
+ }
+
+ static getSchema() {
+ return {
+ zoomLevel: types.float,
+ center: types.vector,
+ };
+ }
+
+ deserialize(data) {
+ const errorCode = super.deserialize(data);
+ if (errorCode) {
+ return errorCode;
+ }
+
+ // Safety
+ this.clampZoomLevel();
+ }
+
+ // Simple getters & setters
+
+ addScreenShake(amount) {
+ const currentShakeAmount = this.currentShake.length();
+ const scale = 1 / (1 + 3 * currentShakeAmount);
+ this.currentShake.x = this.currentShake.x + 2 * (Math.random() - 0.5) * scale * amount;
+ this.currentShake.y = this.currentShake.y + 2 * (Math.random() - 0.5) * scale * amount;
+ }
+
+ /**
+ * Sets a point in world space to focus on
+ * @param {Vector} center
+ */
+ setDesiredCenter(center) {
+ this.desiredCenter = center.copy();
+ this.currentlyMoving = false;
+ }
+
+ /**
+ * Sets a desired zoom level
+ * @param {number} zoom
+ */
+ setDesiredZoom(zoom) {
+ this.desiredZoom = zoom;
+ }
+
+ /**
+ * Returns if this camera is currently moving by a non-user interaction
+ */
+ isCurrentlyMovingToDesiredCenter() {
+ return this.desiredCenter !== null;
+ }
+
+ /**
+ * Sets the camera pan, every frame the camera will move by this amount
+ * @param {Vector} pan
+ */
+ setPan(pan) {
+ this.desiredPan = pan.copy();
+ }
+
+ /**
+ * Finds a good initial zoom level
+ */
+ findInitialZoom() {
+ let desiredWorldSpaceWidth = 18 * globalConfig.tileSize;
+ if (window.innerWidth < 1000) {
+ desiredWorldSpaceWidth = 12 * globalConfig.tileSize;
+ }
+
+ const zoomLevelX = this.root.gameWidth / desiredWorldSpaceWidth;
+ const zoomLevelY = this.root.gameHeight / desiredWorldSpaceWidth;
+
+ const finalLevel = Math.min(zoomLevelX, zoomLevelY);
+ assert(
+ Number.isFinite(finalLevel) && finalLevel > 0,
+ "Invalid zoom level computed for initial zoom: " + finalLevel
+ );
+ return finalLevel;
+ }
+
+ /**
+ * Clears all animations
+ */
+ clearAnimations() {
+ this.touchPostMoveVelocity.x = 0;
+ this.touchPostMoveVelocity.y = 0;
+ this.desiredCenter = null;
+ this.desiredPan.x = 0;
+ this.desiredPan.y = 0;
+ this.currentPan.x = 0;
+ this.currentPan.y = 0;
+ this.currentlyPinching = false;
+ this.currentlyMoving = false;
+ this.lastMovingPosition = null;
+ this.didMoveSinceTouchStart = false;
+ this.desiredZoom = null;
+ }
+
+ /**
+ * Returns if the user is currently interacting with the camera
+ * @returns {boolean} true if the user interacts
+ */
+ isCurrentlyInteracting() {
+ if (this.currentlyPinching) {
+ return true;
+ }
+ if (this.currentlyMoving) {
+ // Only interacting if moved at least once
+ return this.didMoveSinceTouchStart;
+ }
+ if (this.touchPostMoveVelocity.lengthSquare() > 1) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Returns if in the next frame the viewport will change
+ * @returns {boolean} true if it willchange
+ */
+ viewportWillChange() {
+ return this.desiredCenter !== null || this.desiredZoom !== null || this.isCurrentlyInteracting();
+ }
+
+ /**
+ * Cancels all interactions, that is user interaction and non user interaction
+ */
+ cancelAllInteractions() {
+ this.touchPostMoveVelocity = new Vector(0, 0);
+ this.desiredCenter = null;
+ this.currentlyMoving = false;
+ this.currentlyPinching = false;
+ this.desiredZoom = null;
+ }
+
+ /**
+ * Returns effective viewport width
+ */
+ getViewportWidth() {
+ return this.root.gameWidth / this.zoomLevel;
+ }
+
+ /**
+ * Returns effective viewport height
+ */
+ getViewportHeight() {
+ return this.root.gameHeight / this.zoomLevel;
+ }
+
+ /**
+ * Returns effective world space viewport left
+ */
+ getViewportLeft() {
+ return this.center.x - this.getViewportWidth() / 2 + (this.currentShake.x * 10) / this.zoomLevel;
+ }
+
+ /**
+ * Returns effective world space viewport right
+ */
+ getViewportRight() {
+ return this.center.x + this.getViewportWidth() / 2 + (this.currentShake.x * 10) / this.zoomLevel;
+ }
+
+ /**
+ * Returns effective world space viewport top
+ */
+ getViewportTop() {
+ return this.center.y - this.getViewportHeight() / 2 + (this.currentShake.x * 10) / this.zoomLevel;
+ }
+
+ /**
+ * Returns effective world space viewport bottom
+ */
+ getViewportBottom() {
+ return this.center.y + this.getViewportHeight() / 2 + (this.currentShake.x * 10) / this.zoomLevel;
+ }
+
+ /**
+ * Returns the visible world space rect
+ * @returns {Rectangle}
+ */
+ getVisibleRect() {
+ return Rectangle.fromTRBL(
+ Math.floor(this.getViewportTop()),
+ Math.ceil(this.getViewportRight()),
+ Math.ceil(this.getViewportBottom()),
+ Math.floor(this.getViewportLeft())
+ );
+ }
+
+ getIsMapOverlayActive() {
+ return this.zoomLevel < globalConfig.mapChunkOverviewMinZoom;
+ }
+
+ /**
+ * Attaches all event listeners
+ */
+ internalInitEvents() {
+ this.eventListenerTouchStart = this.onTouchStart.bind(this);
+ this.eventListenerTouchEnd = this.onTouchEnd.bind(this);
+ this.eventListenerTouchMove = this.onTouchMove.bind(this);
+ this.eventListenerMousewheel = this.onMouseWheel.bind(this);
+ this.eventListenerMouseDown = this.onMouseDown.bind(this);
+ this.eventListenerMouseMove = this.onMouseMove.bind(this);
+ this.eventListenerMouseUp = this.onMouseUp.bind(this);
+
+ if (SUPPORT_TOUCH) {
+ this.root.canvas.addEventListener("touchstart", this.eventListenerTouchStart);
+ this.root.canvas.addEventListener("touchend", this.eventListenerTouchEnd);
+ this.root.canvas.addEventListener("touchcancel", this.eventListenerTouchEnd);
+ this.root.canvas.addEventListener("touchmove", this.eventListenerTouchMove);
+ }
+
+ this.root.canvas.addEventListener("wheel", this.eventListenerMousewheel);
+ this.root.canvas.addEventListener("mousedown", this.eventListenerMouseDown);
+ this.root.canvas.addEventListener("mousemove", this.eventListenerMouseMove);
+ window.addEventListener("mouseup", this.eventListenerMouseUp);
+ // this.root.canvas.addEventListener("mouseout", this.eventListenerMouseUp);
+ }
+
+ /**
+ * Cleans up all event listeners
+ */
+ cleanup() {
+ if (SUPPORT_TOUCH) {
+ this.root.canvas.removeEventListener("touchstart", this.eventListenerTouchStart);
+ this.root.canvas.removeEventListener("touchend", this.eventListenerTouchEnd);
+ this.root.canvas.removeEventListener("touchcancel", this.eventListenerTouchEnd);
+ this.root.canvas.removeEventListener("touchmove", this.eventListenerTouchMove);
+ }
+
+ this.root.canvas.removeEventListener("wheel", this.eventListenerMousewheel);
+ this.root.canvas.removeEventListener("mousedown", this.eventListenerMouseDown);
+ this.root.canvas.removeEventListener("mousemove", this.eventListenerMouseMove);
+ window.removeEventListener("mouseup", this.eventListenerMouseUp);
+ // this.root.canvas.removeEventListener("mouseout", this.eventListenerMouseUp);
+ }
+
+ /**
+ * Binds the arrow keys
+ */
+ bindKeys() {
+ const mapper = this.root.keyMapper;
+ mapper.getBinding(KEYMAPPINGS.navigation.mapMoveUp).add(() => (this.keyboardForce.y = -1));
+ mapper.getBinding(KEYMAPPINGS.navigation.mapMoveDown).add(() => (this.keyboardForce.y = 1));
+ mapper.getBinding(KEYMAPPINGS.navigation.mapMoveRight).add(() => (this.keyboardForce.x = 1));
+ mapper.getBinding(KEYMAPPINGS.navigation.mapMoveLeft).add(() => (this.keyboardForce.x = -1));
+
+ mapper
+ .getBinding(KEYMAPPINGS.navigation.mapZoomIn)
+ .add(() => (this.desiredZoom = this.zoomLevel * 1.2));
+ mapper
+ .getBinding(KEYMAPPINGS.navigation.mapZoomOut)
+ .add(() => (this.desiredZoom = this.zoomLevel / 1.2));
+
+ mapper.getBinding(KEYMAPPINGS.navigation.centerMap).add(() => this.centerOnMap());
+ }
+
+ centerOnMap() {
+ this.desiredCenter = new Vector(0, 0);
+ }
+
+ /**
+ * Converts from screen to world space
+ * @param {Vector} screen
+ * @returns {Vector} world space
+ */
+ screenToWorld(screen) {
+ const centerSpace = screen.subScalars(this.root.gameWidth / 2, this.root.gameHeight / 2);
+ return centerSpace.divideScalar(this.zoomLevel).add(this.center);
+ }
+
+ /**
+ * Converts from world to screen space
+ * @param {Vector} world
+ * @returns {Vector} screen space
+ */
+ worldToScreen(world) {
+ const screenSpace = world.sub(this.center).multiplyScalar(this.zoomLevel);
+ return screenSpace.addScalars(this.root.gameWidth / 2, this.root.gameHeight / 2);
+ }
+
+ /**
+ * Returns if a point is on screen
+ * @param {Vector} point
+ * @returns {boolean} true if its on screen
+ */
+ isWorldPointOnScreen(point) {
+ const rect = this.getVisibleRect();
+ return rect.containsPoint(point.x, point.y);
+ }
+
+ getMaximumZoom() {
+ return this.root.gameMode.getMaximumZoom();
+ }
+
+ getMinimumZoom() {
+ return this.root.gameMode.getMinimumZoom();
+ }
+
+ /**
+ * Returns if we can further zoom in
+ * @returns {boolean}
+ */
+ canZoomIn() {
+ return this.zoomLevel <= this.getMaximumZoom() - 0.01;
+ }
+
+ /**
+ * Returns if we can further zoom out
+ * @returns {boolean}
+ */
+ canZoomOut() {
+ return this.zoomLevel >= this.getMinimumZoom() + 0.01;
+ }
+
+ // EVENTS
+
+ /**
+ * Checks if the mouse event is too close after a touch event and thus
+ * should get ignored
+ */
+ checkPreventDoubleMouse() {
+ if (performance.now() - clickDetectorGlobals.lastTouchTime < 1000.0) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Mousedown handler
+ * @param {MouseEvent} event
+ */
+ onMouseDown(event) {
+ if (event.cancelable) {
+ event.preventDefault();
+ // event.stopPropagation();
+ }
+
+ if (!this.checkPreventDoubleMouse()) {
+ return;
+ }
+
+ this.touchPostMoveVelocity = new Vector(0, 0);
+ if (event.button === 0) {
+ this.combinedSingleTouchStartHandler(event.clientX, event.clientY);
+ } else if (event.button === 1) {
+ this.downPreHandler.dispatch(new Vector(event.clientX, event.clientY), enumMouseButton.middle);
+ } else if (event.button === 2) {
+ this.downPreHandler.dispatch(new Vector(event.clientX, event.clientY), enumMouseButton.right);
+ }
+ return false;
+ }
+
+ /**
+ * Mousemove handler
+ * @param {MouseEvent} event
+ */
+ onMouseMove(event) {
+ if (event.cancelable) {
+ event.preventDefault();
+ // event.stopPropagation();
+ }
+
+ if (!this.checkPreventDoubleMouse()) {
+ return;
+ }
+
+ if (event.button === 0) {
+ this.combinedSingleTouchMoveHandler(event.clientX, event.clientY);
+ }
+
+ // Clamp everything afterwards
+ this.clampZoomLevel();
+ this.clampToBounds();
+ return false;
+ }
+
+ /**
+ * Mouseup handler
+ * @param {MouseEvent=} event
+ */
+ onMouseUp(event) {
+ if (event) {
+ if (event.cancelable) {
+ event.preventDefault();
+ // event.stopPropagation();
+ }
+ }
+
+ if (!this.checkPreventDoubleMouse()) {
+ return;
+ }
+
+ this.combinedSingleTouchStopHandler(event.clientX, event.clientY);
+ return false;
+ }
+
+ /**
+ * Mousewheel event
+ * @param {WheelEvent} event
+ */
+ onMouseWheel(event) {
+ if (event.cancelable) {
+ event.preventDefault();
+ // event.stopPropagation();
+ }
+ const prevZoom = this.zoomLevel;
+
+ const scale = 1 + 0.15 * this.root.app.settings.getScrollWheelSensitivity();
+ assert(Number.isFinite(scale), "Got invalid scale in mouse wheel event: " + event.deltaY);
+ assert(Number.isFinite(this.zoomLevel), "Got invalid zoom level *before* wheel: " + this.zoomLevel);
+ this.zoomLevel *= event.deltaY < 0 ? scale : 1 / scale;
+ assert(Number.isFinite(this.zoomLevel), "Got invalid zoom level *after* wheel: " + this.zoomLevel);
+
+ this.clampZoomLevel();
+ this.desiredZoom = null;
+
+ let mousePosition = this.root.app.mousePosition;
+ if (!this.root.app.settings.getAllSettings().zoomToCursor) {
+ mousePosition = new Vector(this.root.gameWidth / 2, this.root.gameHeight / 2);
+ }
+
+ if (mousePosition) {
+ const worldPos = this.root.camera.screenToWorld(mousePosition);
+ const worldDelta = worldPos.sub(this.center);
+ const actualDelta = this.zoomLevel / prevZoom - 1;
+ this.center = this.center.add(worldDelta.multiplyScalar(actualDelta));
+ this.desiredCenter = null;
+ }
+
+ return false;
+ }
+
+ /**
+ * Touch start handler
+ * @param {TouchEvent} event
+ */
+ onTouchStart(event) {
+ if (event.cancelable) {
+ event.preventDefault();
+ // event.stopPropagation();
+ }
+
+ clickDetectorGlobals.lastTouchTime = performance.now();
+ this.touchPostMoveVelocity = new Vector(0, 0);
+
+ if (event.touches.length === 1) {
+ const touch = event.touches[0];
+ this.combinedSingleTouchStartHandler(touch.clientX, touch.clientY);
+ } else if (event.touches.length === 2) {
+ // if (this.pinchPreHandler.dispatch() === STOP_PROPAGATION) {
+ // // Something prevented pinching
+ // return false;
+ // }
+
+ const touch1 = event.touches[0];
+ const touch2 = event.touches[1];
+ this.currentlyMoving = false;
+ this.currentlyPinching = true;
+ this.lastPinchPositions = [
+ new Vector(touch1.clientX, touch1.clientY),
+ new Vector(touch2.clientX, touch2.clientY),
+ ];
+ }
+ return false;
+ }
+
+ /**
+ * Touch move handler
+ * @param {TouchEvent} event
+ */
+ onTouchMove(event) {
+ if (event.cancelable) {
+ event.preventDefault();
+ // event.stopPropagation();
+ }
+
+ clickDetectorGlobals.lastTouchTime = performance.now();
+
+ if (event.touches.length === 1) {
+ const touch = event.touches[0];
+ this.combinedSingleTouchMoveHandler(touch.clientX, touch.clientY);
+ } else if (event.touches.length === 2) {
+ if (this.currentlyPinching) {
+ const touch1 = event.touches[0];
+ const touch2 = event.touches[1];
+
+ const newPinchPositions = [
+ new Vector(touch1.clientX, touch1.clientY),
+ new Vector(touch2.clientX, touch2.clientY),
+ ];
+
+ // Get distance of taps last time and now
+ const lastDistance = this.lastPinchPositions[0].distance(this.lastPinchPositions[1]);
+ const thisDistance = newPinchPositions[0].distance(newPinchPositions[1]);
+
+ // IMPORTANT to do math max here to avoid NaN and causing an invalid zoom level
+ const difference = thisDistance / Math.max(0.001, lastDistance);
+
+ // Find old center of zoom
+ let oldCenter = this.lastPinchPositions[0].centerPoint(this.lastPinchPositions[1]);
+
+ // Find new center of zoom
+ let center = newPinchPositions[0].centerPoint(newPinchPositions[1]);
+
+ // Compute movement
+ let movement = oldCenter.sub(center);
+ this.center.x += movement.x / this.zoomLevel;
+ this.center.y += movement.y / this.zoomLevel;
+
+ // Compute zoom
+ center = center.sub(new Vector(this.root.gameWidth / 2, this.root.gameHeight / 2));
+
+ // Apply zoom
+ assert(
+ Number.isFinite(difference),
+ "Invalid pinch difference: " +
+ difference +
+ "(last=" +
+ lastDistance +
+ ", new = " +
+ thisDistance +
+ ")"
+ );
+ this.zoomLevel *= difference;
+
+ // Stick to pivot point
+ const correcture = center.multiplyScalar(difference - 1).divideScalar(this.zoomLevel);
+
+ this.center = this.center.add(correcture);
+ this.lastPinchPositions = newPinchPositions;
+ this.userInteraction.dispatch(USER_INTERACT_MOVE);
+
+ // Since we zoomed, abort any programmed zooming
+ if (this.desiredZoom) {
+ this.desiredZoom = null;
+ }
+ }
+ }
+
+ // Clamp everything afterwards
+ this.clampZoomLevel();
+ return false;
+ }
+
+ /**
+ * Touch end and cancel handler
+ * @param {TouchEvent=} event
+ */
+ onTouchEnd(event) {
+ if (event) {
+ if (event.cancelable) {
+ event.preventDefault();
+ // event.stopPropagation();
+ }
+ }
+
+ clickDetectorGlobals.lastTouchTime = performance.now();
+ if (event.changedTouches.length === 0) {
+ logger.warn("Touch end without changed touches");
+ }
+
+ const touch = event.changedTouches[0];
+ this.combinedSingleTouchStopHandler(touch.clientX, touch.clientY);
+ return false;
+ }
+
+ /**
+ * Internal touch start handler
+ * @param {number} x
+ * @param {number} y
+ */
+ combinedSingleTouchStartHandler(x, y) {
+ const pos = new Vector(x, y);
+ if (this.downPreHandler.dispatch(pos, enumMouseButton.left) === STOP_PROPAGATION) {
+ // Somebody else captured it
+ return;
+ }
+
+ this.touchPostMoveVelocity = new Vector(0, 0);
+ this.currentlyMoving = true;
+ this.lastMovingPosition = pos;
+ this.lastMovingPositionLastTick = null;
+ this.numTicksStandingStill = 0;
+ this.didMoveSinceTouchStart = false;
+ }
+
+ /**
+ * Internal touch move handler
+ * @param {number} x
+ * @param {number} y
+ */
+ combinedSingleTouchMoveHandler(x, y) {
+ const pos = new Vector(x, y);
+ if (this.movePreHandler.dispatch(pos) === STOP_PROPAGATION) {
+ // Somebody else captured it
+ return;
+ }
+
+ if (!this.currentlyMoving) {
+ return false;
+ }
+
+ let delta = this.lastMovingPosition.sub(pos).divideScalar(this.zoomLevel);
+ if (G_IS_DEV && globalConfig.debug.testCulling) {
+ // When testing culling, we see everything from the same distance
+ delta = delta.multiplyScalar(this.zoomLevel * -2);
+ }
+
+ this.didMoveSinceTouchStart = this.didMoveSinceTouchStart || delta.length() > 0;
+ this.center = this.center.add(delta);
+
+ this.touchPostMoveVelocity = this.touchPostMoveVelocity
+ .multiplyScalar(velocitySmoothing)
+ .add(delta.multiplyScalar(1 - velocitySmoothing));
+
+ this.lastMovingPosition = pos;
+ this.userInteraction.dispatch(USER_INTERACT_MOVE);
+
+ // Since we moved, abort any programmed moving
+ if (this.desiredCenter) {
+ this.desiredCenter = null;
+ }
+ }
+
+ /**
+ * Internal touch stop handler
+ */
+ combinedSingleTouchStopHandler(x, y) {
+ if (this.currentlyMoving || this.currentlyPinching) {
+ this.currentlyMoving = false;
+ this.currentlyPinching = false;
+ this.lastMovingPosition = null;
+ this.lastMovingPositionLastTick = null;
+ this.numTicksStandingStill = 0;
+ this.lastPinchPositions = null;
+ this.userInteraction.dispatch(USER_INTERACT_TOUCHEND);
+ this.didMoveSinceTouchStart = false;
+ }
+ this.upPostHandler.dispatch(new Vector(x, y));
+ }
+
+ /**
+ * Clamps the camera zoom level within the allowed range
+ */
+ clampZoomLevel() {
+ if (G_IS_DEV && globalConfig.debug.disableZoomLimits) {
+ return;
+ }
+ assert(Number.isFinite(this.zoomLevel), "Invalid zoom level *before* clamp: " + this.zoomLevel);
+ this.zoomLevel = clamp(this.zoomLevel, this.getMinimumZoom(), this.getMaximumZoom());
+ assert(Number.isFinite(this.zoomLevel), "Invalid zoom level *after* clamp: " + this.zoomLevel);
+
+ if (this.desiredZoom) {
+ this.desiredZoom = clamp(this.desiredZoom, this.getMinimumZoom(), this.getMaximumZoom());
+ }
+ }
+
+ /**
+ * Clamps the center within set boundaries
+ */
+ clampToBounds() {
+ const bounds = this.root.gameMode.getCameraBounds();
+ if (!bounds) {
+ return;
+ }
+
+ const tileScaleBounds = this.root.gameMode.getCameraBounds().allScaled(globalConfig.tileSize);
+ this.center.x = clamp(this.center.x, tileScaleBounds.x, tileScaleBounds.x + tileScaleBounds.w);
+ this.center.y = clamp(this.center.y, tileScaleBounds.y, tileScaleBounds.y + tileScaleBounds.h);
+ }
+
+ /**
+ * Updates the camera
+ * @param {number} dt Delta time in milliseconds
+ */
+ update(dt) {
+ dt = Math.min(dt, 33);
+ this.cameraUpdateTimeBucket += dt;
+
+ // Simulate movement of N FPS
+ const updatesPerFrame = 4;
+ const physicsStepSizeMs = 1000.0 / (60.0 * updatesPerFrame);
+
+ let now = this.root.time.systemNow() - 3 * physicsStepSizeMs;
+
+ while (this.cameraUpdateTimeBucket > physicsStepSizeMs) {
+ now += physicsStepSizeMs;
+ this.cameraUpdateTimeBucket -= physicsStepSizeMs;
+
+ this.internalUpdatePanning(now, physicsStepSizeMs);
+ this.internalUpdateMousePanning(now, physicsStepSizeMs);
+ this.internalUpdateZooming(now, physicsStepSizeMs);
+ this.internalUpdateCentering(now, physicsStepSizeMs);
+ this.internalUpdateShake(now, physicsStepSizeMs);
+ this.internalUpdateKeyboardForce(now, physicsStepSizeMs);
+ }
+ this.clampZoomLevel();
+ }
+
+ /**
+ * Prepares a context to transform it
+ * @param {CanvasRenderingContext2D} context
+ */
+ transform(context) {
+ if (G_IS_DEV && globalConfig.debug.testCulling) {
+ context.transform(1, 0, 0, 1, 100, 100);
+ return;
+ }
+
+ this.clampZoomLevel();
+ const zoom = this.zoomLevel;
+
+ context.transform(
+ // Scale, skew, rotate
+ zoom,
+ 0,
+ 0,
+ zoom,
+
+ // Translate
+ -zoom * this.getViewportLeft(),
+ -zoom * this.getViewportTop()
+ );
+ }
+
+ /**
+ * Internal shake handler
+ * @param {number} now Time now in seconds
+ * @param {number} dt Delta time
+ */
+ internalUpdateShake(now, dt) {
+ this.currentShake = this.currentShake.multiplyScalar(0.92);
+ }
+
+ /**
+ * Internal pan handler
+ * @param {number} now Time now in seconds
+ * @param {number} dt Delta time
+ */
+ internalUpdatePanning(now, dt) {
+ const baseStrength = velocityStrength * this.root.app.platformWrapper.getTouchPanStrength();
+
+ this.touchPostMoveVelocity = this.touchPostMoveVelocity.multiplyScalar(velocityFade);
+
+ // Check if the camera is being dragged but standing still: if not, zero out `touchPostMoveVelocity`.
+ if (this.currentlyMoving && this.desiredCenter === null) {
+ if (
+ this.lastMovingPositionLastTick !== null &&
+ this.lastMovingPositionLastTick.equalsEpsilon(this.lastMovingPosition)
+ ) {
+ this.numTicksStandingStill++;
+ } else {
+ this.numTicksStandingStill = 0;
+ }
+ this.lastMovingPositionLastTick = this.lastMovingPosition.copy();
+
+ if (this.numTicksStandingStill >= ticksBeforeErasingVelocity) {
+ this.touchPostMoveVelocity.x = 0;
+ this.touchPostMoveVelocity.y = 0;
+ }
+ }
+ // Check influence of past points
+ if (!this.currentlyMoving && !this.currentlyPinching) {
+ const len = this.touchPostMoveVelocity.length();
+ if (len >= velocityMax) {
+ this.touchPostMoveVelocity.x = (this.touchPostMoveVelocity.x * velocityMax) / len;
+ this.touchPostMoveVelocity.y = (this.touchPostMoveVelocity.y * velocityMax) / len;
+ }
+
+ this.center = this.center.add(this.touchPostMoveVelocity.multiplyScalar(baseStrength));
+
+ // Panning
+ this.currentPan = mixVector(this.currentPan, this.desiredPan, 0.06);
+ this.center = this.center.add(this.currentPan.multiplyScalar((0.5 * dt) / this.zoomLevel));
+ this.clampToBounds();
+ }
+ }
+
+ /**
+ * Internal screen panning handler
+ * @param {number} now
+ * @param {number} dt
+ */
+ internalUpdateMousePanning(now, dt) {
+ if (!this.root.app.focused) {
+ return;
+ }
+
+ if (!this.root.app.settings.getAllSettings().enableMousePan) {
+ // Not enabled
+ return;
+ }
+
+ const mousePos = this.root.app.mousePosition;
+ if (!mousePos) {
+ return;
+ }
+
+ if (this.root.hud.shouldPauseGame() || this.root.hud.hasBlockingOverlayOpen()) {
+ return;
+ }
+
+ if (this.desiredCenter || this.desiredZoom || this.currentlyMoving || this.currentlyPinching) {
+ // Performing another method of movement right now
+ return;
+ }
+
+ if (
+ mousePos.x < 0 ||
+ mousePos.y < 0 ||
+ mousePos.x > this.root.gameWidth ||
+ mousePos.y > this.root.gameHeight
+ ) {
+ // Out of screen
+ return;
+ }
+
+ const panAreaPixels = 2;
+
+ const panVelocity = new Vector();
+ if (mousePos.x < panAreaPixels) {
+ panVelocity.x -= 1;
+ }
+ if (mousePos.x > this.root.gameWidth - panAreaPixels) {
+ panVelocity.x += 1;
+ }
+
+ if (mousePos.y < panAreaPixels) {
+ panVelocity.y -= 1;
+ }
+ if (mousePos.y > this.root.gameHeight - panAreaPixels) {
+ panVelocity.y += 1;
+ }
+
+ this.center = this.center.add(
+ panVelocity.multiplyScalar(
+ ((0.5 * dt) / this.zoomLevel) * this.root.app.settings.getMovementSpeed()
+ )
+ );
+
+ this.clampToBounds();
+ }
+
+ /**
+ * Updates the non user interaction zooming
+ * @param {number} now Time now in seconds
+ * @param {number} dt Delta time
+ */
+ internalUpdateZooming(now, dt) {
+ if (!this.currentlyPinching && this.desiredZoom !== null) {
+ const diff = this.zoomLevel - this.desiredZoom;
+ if (Math.abs(diff) > 0.0001) {
+ let fade = 0.94;
+ if (diff > 0) {
+ // Zoom out faster than in
+ fade = 0.9;
+ }
+
+ assert(Number.isFinite(this.desiredZoom), "Desired zoom is NaN: " + this.desiredZoom);
+ assert(Number.isFinite(fade), "Zoom fade is NaN: " + fade);
+ this.zoomLevel = this.zoomLevel * fade + this.desiredZoom * (1 - fade);
+ assert(Number.isFinite(this.zoomLevel), "Zoom level is NaN after fade: " + this.zoomLevel);
+ } else {
+ this.zoomLevel = this.desiredZoom;
+ this.desiredZoom = null;
+ }
+ }
+ }
+
+ /**
+ * Updates the non user interaction centering
+ * @param {number} now Time now in seconds
+ * @param {number} dt Delta time
+ */
+ internalUpdateCentering(now, dt) {
+ if (!this.currentlyMoving && this.desiredCenter !== null) {
+ const diff = this.center.direction(this.desiredCenter);
+ const length = diff.length();
+ const tolerance = 1 / this.zoomLevel;
+ if (length > tolerance) {
+ const movement = diff.multiplyScalar(Math.min(1, dt * 0.008));
+ this.center.x += movement.x;
+ this.center.y += movement.y;
+ } else {
+ this.desiredCenter = null;
+ }
+ }
+ }
+
+ /**
+ * Updates the keyboard forces
+ * @param {number} now
+ * @param {number} dt Delta time
+ */
+ internalUpdateKeyboardForce(now, dt) {
+ if (!this.currentlyMoving && this.desiredCenter == null) {
+ const limitingDimension = Math.min(this.root.gameWidth, this.root.gameHeight);
+
+ const moveAmount = ((limitingDimension / 2048) * dt) / this.zoomLevel;
+
+ let forceX = 0;
+ let forceY = 0;
+
+ const actionMapper = this.root.keyMapper;
+ if (actionMapper.getBinding(KEYMAPPINGS.navigation.mapMoveUp).pressed) {
+ forceY -= 1;
+ }
+
+ if (actionMapper.getBinding(KEYMAPPINGS.navigation.mapMoveDown).pressed) {
+ forceY += 1;
+ }
+
+ if (actionMapper.getBinding(KEYMAPPINGS.navigation.mapMoveLeft).pressed) {
+ forceX -= 1;
+ }
+
+ if (actionMapper.getBinding(KEYMAPPINGS.navigation.mapMoveRight).pressed) {
+ forceX += 1;
+ }
+
+ let movementSpeed =
+ this.root.app.settings.getMovementSpeed() *
+ (actionMapper.getBinding(KEYMAPPINGS.navigation.mapMoveFaster).pressed ? 4 : 1);
+
+ this.center.x += moveAmount * forceX * movementSpeed;
+ this.center.y += moveAmount * forceY * movementSpeed;
+
+ this.clampToBounds();
+ }
+ }
+}
diff --git a/src/js/game/component_registry.js b/src/js/game/component_registry.js
index 1add879e..4146ea45 100644
--- a/src/js/game/component_registry.js
+++ b/src/js/game/component_registry.js
@@ -53,7 +53,7 @@ export function initComponentRegistry() {
assert(
// @ts-ignore
- require.context("./components", false, /.*\.js/i).keys().length ===
+ import.meta.webpackContext("./components", { recursive: false, regExp: /.*\.js/i }).keys().length ===
gComponentRegistry.getNumEntries(),
"Not all components are registered"
);
diff --git a/src/js/game/components/belt_reader.js b/src/js/game/components/belt_reader.js
index 187e53cd..0026f2b8 100644
--- a/src/js/game/components/belt_reader.js
+++ b/src/js/game/components/belt_reader.js
@@ -1,53 +1,53 @@
-import { Component } from "../component";
-import { BaseItem } from "../base_item";
-import { typeItemSingleton } from "../item_resolver";
-import { types } from "../../savegame/serialization";
-
-/** @enum {string} */
-export const enumBeltReaderType = {
- wired: "wired",
- wireless: "wireless",
-};
-
-export class BeltReaderComponent extends Component {
- static getId() {
- return "BeltReader";
- }
-
- static getSchema() {
- return {
- lastItem: types.nullable(typeItemSingleton),
- };
- }
-
- constructor() {
- super();
- this.clear();
- }
-
- clear() {
- /**
- * Which items went through the reader, we only store the time
- * @type {Array}
- */
- this.lastItemTimes = [];
-
- /**
- * Which item passed the reader last
- * @type {BaseItem}
- */
- this.lastItem = null;
-
- /**
- * Stores the last throughput we computed
- * @type {number}
- */
- this.lastThroughput = 0;
-
- /**
- * Stores when we last computed the throughput
- * @type {number}
- */
- this.lastThroughputComputation = 0;
- }
-}
+import { Component } from "../component";
+import { BaseItem } from "../base_item";
+import { typeItemSingleton } from "../item_resolver";
+import { types } from "../../savegame/serialization";
+
+/** @enum {string} */
+export const enumBeltReaderType = {
+ wired: "wired",
+ wireless: "wireless",
+};
+
+export class BeltReaderComponent extends Component {
+ static getId() {
+ return "BeltReader";
+ }
+
+ static getSchema() {
+ return {
+ lastItem: types.nullable(typeItemSingleton),
+ };
+ }
+
+ constructor() {
+ super();
+ this.clear();
+ }
+
+ clear() {
+ /**
+ * Which items went through the reader, we only store the time
+ * @type {Array}
+ */
+ this.lastItemTimes = [];
+
+ /**
+ * Which item passed the reader last
+ * @type {BaseItem}
+ */
+ this.lastItem = null;
+
+ /**
+ * Stores the last throughput we computed
+ * @type {number}
+ */
+ this.lastThroughput = 0;
+
+ /**
+ * Stores when we last computed the throughput
+ * @type {number}
+ */
+ this.lastThroughputComputation = 0;
+ }
+}
diff --git a/src/js/game/components/belt_underlays.js b/src/js/game/components/belt_underlays.js
index 63b265d0..ccce4dd4 100644
--- a/src/js/game/components/belt_underlays.js
+++ b/src/js/game/components/belt_underlays.js
@@ -1,41 +1,41 @@
-import { enumDirection, Vector } from "../../core/vector";
-import { Component } from "../component";
-
-/**
- * Store which type an underlay is, this is cached so we can easily
- * render it.
- *
- * Full: Render underlay at top and bottom of tile
- * Bottom Only: Only render underlay at the bottom half
- * Top Only:
- * @enum {string}
- */
-export const enumClippedBeltUnderlayType = {
- full: "full",
- bottomOnly: "bottomOnly",
- topOnly: "topOnly",
- none: "none",
-};
-
-/**
- * @typedef {{
- * pos: Vector,
- * direction: enumDirection,
- * cachedType?: enumClippedBeltUnderlayType
- * }} BeltUnderlayTile
- */
-
-export class BeltUnderlaysComponent extends Component {
- static getId() {
- return "BeltUnderlays";
- }
-
- /**
- * @param {object} param0
- * @param {Array=} param0.underlays Where to render belt underlays
- */
- constructor({ underlays = [] }) {
- super();
- this.underlays = underlays;
- }
-}
+import { enumDirection, Vector } from "../../core/vector";
+import { Component } from "../component";
+
+/**
+ * Store which type an underlay is, this is cached so we can easily
+ * render it.
+ *
+ * Full: Render underlay at top and bottom of tile
+ * Bottom Only: Only render underlay at the bottom half
+ * Top Only:
+ * @enum {string}
+ */
+export const enumClippedBeltUnderlayType = {
+ full: "full",
+ bottomOnly: "bottomOnly",
+ topOnly: "topOnly",
+ none: "none",
+};
+
+/**
+ * @typedef {{
+ * pos: Vector,
+ * direction: enumDirection,
+ * cachedType?: enumClippedBeltUnderlayType
+ * }} BeltUnderlayTile
+ */
+
+export class BeltUnderlaysComponent extends Component {
+ static getId() {
+ return "BeltUnderlays";
+ }
+
+ /**
+ * @param {object} param0
+ * @param {Array=} param0.underlays Where to render belt underlays
+ */
+ constructor({ underlays = [] }) {
+ super();
+ this.underlays = underlays;
+ }
+}
diff --git a/src/js/game/components/filter.js b/src/js/game/components/filter.js
index 8a22a076..d90e05e9 100644
--- a/src/js/game/components/filter.js
+++ b/src/js/game/components/filter.js
@@ -1,59 +1,59 @@
-import { types } from "../../savegame/serialization";
-import { BaseItem } from "../base_item";
-import { Component } from "../component";
-import { typeItemSingleton } from "../item_resolver";
-
-/**
- * @typedef {{
- * item: BaseItem,
- * progress: number
- * }} PendingFilterItem
- */
-
-export class FilterComponent extends Component {
- static getId() {
- return "Filter";
- }
-
- duplicateWithoutContents() {
- return new FilterComponent();
- }
-
- static getSchema() {
- return {
- pendingItemsToLeaveThrough: types.array(
- types.structured({
- item: typeItemSingleton,
- progress: types.ufloat,
- })
- ),
-
- pendingItemsToReject: types.array(
- types.structured({
- item: typeItemSingleton,
- progress: types.ufloat,
- })
- ),
- };
- }
-
- constructor() {
- super();
-
- this.clear();
- }
-
- clear() {
- /**
- * Items in queue to leave through
- * @type {Array}
- */
- this.pendingItemsToLeaveThrough = [];
-
- /**
- * Items in queue to reject
- * @type {Array}
- */
- this.pendingItemsToReject = [];
- }
-}
+import { types } from "../../savegame/serialization";
+import { BaseItem } from "../base_item";
+import { Component } from "../component";
+import { typeItemSingleton } from "../item_resolver";
+
+/**
+ * @typedef {{
+ * item: BaseItem,
+ * progress: number
+ * }} PendingFilterItem
+ */
+
+export class FilterComponent extends Component {
+ static getId() {
+ return "Filter";
+ }
+
+ duplicateWithoutContents() {
+ return new FilterComponent();
+ }
+
+ static getSchema() {
+ return {
+ pendingItemsToLeaveThrough: types.array(
+ types.structured({
+ item: typeItemSingleton,
+ progress: types.ufloat,
+ })
+ ),
+
+ pendingItemsToReject: types.array(
+ types.structured({
+ item: typeItemSingleton,
+ progress: types.ufloat,
+ })
+ ),
+ };
+ }
+
+ constructor() {
+ super();
+
+ this.clear();
+ }
+
+ clear() {
+ /**
+ * Items in queue to leave through
+ * @type {Array}
+ */
+ this.pendingItemsToLeaveThrough = [];
+
+ /**
+ * Items in queue to reject
+ * @type {Array}
+ */
+ this.pendingItemsToReject = [];
+ }
+}
diff --git a/src/js/game/components/goal_acceptor.js b/src/js/game/components/goal_acceptor.js
index fa5f5908..c5aeb974 100644
--- a/src/js/game/components/goal_acceptor.js
+++ b/src/js/game/components/goal_acceptor.js
@@ -1,67 +1,67 @@
-import { globalConfig } from "../../core/config";
-import { BaseItem } from "../base_item";
-import { Component } from "../component";
-import { typeItemSingleton } from "../item_resolver";
-
-export class GoalAcceptorComponent extends Component {
- static getId() {
- return "GoalAcceptor";
- }
-
- static getSchema() {
- return {
- item: typeItemSingleton,
- };
- }
-
- /**
- * @param {object} param0
- * @param {BaseItem=} param0.item
- * @param {number=} param0.rate
- */
- constructor({ item = null, rate = null }) {
- super();
-
- // ths item to produce
- /** @type {BaseItem | undefined} */
- this.item = item;
-
- this.clear();
- }
-
- clear() {
- /**
- * The last item we delivered
- * @type {{ item: BaseItem; time: number; } | null} */
- this.lastDelivery = null;
-
- // The amount of items we delivered so far
- this.currentDeliveredItems = 0;
-
- // Used for animations
- this.displayPercentage = 0;
- }
-
- /**
- * Clears items but doesn't instantly reset the progress bar
- */
- clearItems() {
- this.lastDelivery = null;
- this.currentDeliveredItems = 0;
- }
-
- getRequiredSecondsPerItem() {
- return (
- globalConfig.goalAcceptorsPerProducer /
- (globalConfig.puzzleModeSpeed * globalConfig.beltSpeedItemsPerSecond)
- );
- }
-
- /**
- * Copy the current state to another component
- * @param {GoalAcceptorComponent} otherComponent
- */
- copyAdditionalStateTo(otherComponent) {
- otherComponent.item = this.item;
- }
-}
+import { globalConfig } from "../../core/config";
+import { BaseItem } from "../base_item";
+import { Component } from "../component";
+import { typeItemSingleton } from "../item_resolver";
+
+export class GoalAcceptorComponent extends Component {
+ static getId() {
+ return "GoalAcceptor";
+ }
+
+ static getSchema() {
+ return {
+ item: typeItemSingleton,
+ };
+ }
+
+ /**
+ * @param {object} param0
+ * @param {BaseItem=} param0.item
+ * @param {number=} param0.rate
+ */
+ constructor({ item = null, rate = null }) {
+ super();
+
+ // ths item to produce
+ /** @type {BaseItem | undefined} */
+ this.item = item;
+
+ this.clear();
+ }
+
+ clear() {
+ /**
+ * The last item we delivered
+ * @type {{ item: BaseItem; time: number; } | null} */
+ this.lastDelivery = null;
+
+ // The amount of items we delivered so far
+ this.currentDeliveredItems = 0;
+
+ // Used for animations
+ this.displayPercentage = 0;
+ }
+
+ /**
+ * Clears items but doesn't instantly reset the progress bar
+ */
+ clearItems() {
+ this.lastDelivery = null;
+ this.currentDeliveredItems = 0;
+ }
+
+ getRequiredSecondsPerItem() {
+ return (
+ globalConfig.goalAcceptorsPerProducer /
+ (globalConfig.puzzleModeSpeed * globalConfig.beltSpeedItemsPerSecond)
+ );
+ }
+
+ /**
+ * Copy the current state to another component
+ * @param {GoalAcceptorComponent} otherComponent
+ */
+ copyAdditionalStateTo(otherComponent) {
+ otherComponent.item = this.item;
+ }
+}
diff --git a/src/js/game/components/item_acceptor.js b/src/js/game/components/item_acceptor.js
index d3df3763..e984fefb 100644
--- a/src/js/game/components/item_acceptor.js
+++ b/src/js/game/components/item_acceptor.js
@@ -1,136 +1,136 @@
-import { enumDirection, enumInvertedDirections, Vector } from "../../core/vector";
-import { types } from "../../savegame/serialization";
-import { BaseItem } from "../base_item";
-import { Component } from "../component";
-
-/**
- * @typedef {{
- * pos: Vector,
- * direction: enumDirection,
- * filter?: ItemType
- * }} ItemAcceptorSlot */
-
-/**
- * Contains information about a slot plus its location
- * @typedef {{
- * slot: ItemAcceptorSlot,
- * index: number,
- * }} ItemAcceptorLocatedSlot */
-
-/**
- * @typedef {{
- * pos: Vector,
- * direction: enumDirection,
- * filter?: ItemType
- * }} ItemAcceptorSlotConfig */
-
-export class ItemAcceptorComponent extends Component {
- static getId() {
- return "ItemAcceptor";
- }
-
- /**
- *
- * @param {object} param0
- * @param {Array} param0.slots The slots from which we accept items
- */
- constructor({ slots = [] }) {
- super();
-
- this.setSlots(slots);
- this.clear();
- }
-
- clear() {
- /**
- * Fixes belt animations
- * @type {Array<{
- * item: BaseItem,
- * slotIndex: number,
- * animProgress: number,
- * direction: enumDirection
- * }>}
- */
- this.itemConsumptionAnimations = [];
- }
-
- /**
- *
- * @param {Array} slots
- */
- setSlots(slots) {
- /** @type {Array} */
- this.slots = [];
- for (let i = 0; i < slots.length; ++i) {
- const slot = slots[i];
- this.slots.push({
- pos: slot.pos,
- direction: slot.direction,
-
- // Which type of item to accept (shape | color | all) @see ItemType
- filter: slot.filter,
- });
- }
- }
-
- /**
- * Returns if this acceptor can accept a new item at slot N
- *
- * NOTICE: The belt path ignores this for performance reasons and does his own check
- * @param {number} slotIndex
- * @param {BaseItem=} item
- */
- canAcceptItem(slotIndex, item) {
- const slot = this.slots[slotIndex];
- return !slot.filter || slot.filter === item.getItemType();
- }
-
- /**
- * Called when an item has been accepted so that
- * @param {number} slotIndex
- * @param {enumDirection} direction
- * @param {BaseItem} item
- * @param {number} remainingProgress World space remaining progress, can be set to set the start position of the item
- */
- onItemAccepted(slotIndex, direction, item, remainingProgress = 0.0) {
- this.itemConsumptionAnimations.push({
- item,
- slotIndex,
- direction,
- animProgress: Math.min(1, remainingProgress * 2),
- });
- }
-
- /**
- * Tries to find a slot which accepts the current item
- * @param {Vector} targetLocalTile
- * @param {enumDirection} fromLocalDirection
- * @returns {ItemAcceptorLocatedSlot|null}
- */
- findMatchingSlot(targetLocalTile, fromLocalDirection) {
- // We need to invert our direction since the acceptor specifies *from* which direction
- // it accepts items, but the ejector specifies *into* which direction it ejects items.
- // E.g.: Ejector ejects into "right" direction but acceptor accepts from "left" direction.
- const desiredDirection = enumInvertedDirections[fromLocalDirection];
-
- // Go over all slots and try to find a target slot
- for (let slotIndex = 0; slotIndex < this.slots.length; ++slotIndex) {
- const slot = this.slots[slotIndex];
-
- // Make sure the acceptor slot is on the right position
- if (!slot.pos.equals(targetLocalTile)) {
- continue;
- }
-
- // Check if the acceptor slot accepts items from our direction
- if (desiredDirection === slot.direction) {
- return {
- slot,
- index: slotIndex,
- };
- }
- }
-
- return null;
- }
-}
+import { enumDirection, enumInvertedDirections, Vector } from "../../core/vector";
+import { types } from "../../savegame/serialization";
+import { BaseItem } from "../base_item";
+import { Component } from "../component";
+
+/**
+ * @typedef {{
+ * pos: Vector,
+ * direction: enumDirection,
+ * filter?: ItemType
+ * }} ItemAcceptorSlot */
+
+/**
+ * Contains information about a slot plus its location
+ * @typedef {{
+ * slot: ItemAcceptorSlot,
+ * index: number,
+ * }} ItemAcceptorLocatedSlot */
+
+/**
+ * @typedef {{
+ * pos: Vector,
+ * direction: enumDirection,
+ * filter?: ItemType
+ * }} ItemAcceptorSlotConfig */
+
+export class ItemAcceptorComponent extends Component {
+ static getId() {
+ return "ItemAcceptor";
+ }
+
+ /**
+ *
+ * @param {object} param0
+ * @param {Array} param0.slots The slots from which we accept items
+ */
+ constructor({ slots = [] }) {
+ super();
+
+ this.setSlots(slots);
+ this.clear();
+ }
+
+ clear() {
+ /**
+ * Fixes belt animations
+ * @type {Array<{
+ * item: BaseItem,
+ * slotIndex: number,
+ * animProgress: number,
+ * direction: enumDirection
+ * }>}
+ */
+ this.itemConsumptionAnimations = [];
+ }
+
+ /**
+ *
+ * @param {Array} slots
+ */
+ setSlots(slots) {
+ /** @type {Array} */
+ this.slots = [];
+ for (let i = 0; i < slots.length; ++i) {
+ const slot = slots[i];
+ this.slots.push({
+ pos: slot.pos,
+ direction: slot.direction,
+
+ // Which type of item to accept (shape | color | all) @see ItemType
+ filter: slot.filter,
+ });
+ }
+ }
+
+ /**
+ * Returns if this acceptor can accept a new item at slot N
+ *
+ * NOTICE: The belt path ignores this for performance reasons and does his own check
+ * @param {number} slotIndex
+ * @param {BaseItem=} item
+ */
+ canAcceptItem(slotIndex, item) {
+ const slot = this.slots[slotIndex];
+ return !slot.filter || slot.filter === item.getItemType();
+ }
+
+ /**
+ * Called when an item has been accepted so that
+ * @param {number} slotIndex
+ * @param {enumDirection} direction
+ * @param {BaseItem} item
+ * @param {number} remainingProgress World space remaining progress, can be set to set the start position of the item
+ */
+ onItemAccepted(slotIndex, direction, item, remainingProgress = 0.0) {
+ this.itemConsumptionAnimations.push({
+ item,
+ slotIndex,
+ direction,
+ animProgress: Math.min(1, remainingProgress * 2),
+ });
+ }
+
+ /**
+ * Tries to find a slot which accepts the current item
+ * @param {Vector} targetLocalTile
+ * @param {enumDirection} fromLocalDirection
+ * @returns {ItemAcceptorLocatedSlot|null}
+ */
+ findMatchingSlot(targetLocalTile, fromLocalDirection) {
+ // We need to invert our direction since the acceptor specifies *from* which direction
+ // it accepts items, but the ejector specifies *into* which direction it ejects items.
+ // E.g.: Ejector ejects into "right" direction but acceptor accepts from "left" direction.
+ const desiredDirection = enumInvertedDirections[fromLocalDirection];
+
+ // Go over all slots and try to find a target slot
+ for (let slotIndex = 0; slotIndex < this.slots.length; ++slotIndex) {
+ const slot = this.slots[slotIndex];
+
+ // Make sure the acceptor slot is on the right position
+ if (!slot.pos.equals(targetLocalTile)) {
+ continue;
+ }
+
+ // Check if the acceptor slot accepts items from our direction
+ if (desiredDirection === slot.direction) {
+ return {
+ slot,
+ index: slotIndex,
+ };
+ }
+ }
+
+ return null;
+ }
+}
diff --git a/src/js/game/components/item_ejector.js b/src/js/game/components/item_ejector.js
index bfc54cd8..c8c4ec94 100644
--- a/src/js/game/components/item_ejector.js
+++ b/src/js/game/components/item_ejector.js
@@ -1,154 +1,154 @@
-import { enumDirection, enumDirectionToVector, Vector } from "../../core/vector";
-import { types } from "../../savegame/serialization";
-import { BaseItem } from "../base_item";
-import { BeltPath } from "../belt_path";
-import { Component } from "../component";
-import { Entity } from "../entity";
-import { typeItemSingleton } from "../item_resolver";
-
-/**
- * @typedef {{
- * pos: Vector,
- * direction: enumDirection,
- * item: BaseItem,
- * lastItem: BaseItem,
- * progress: number?,
- * cachedDestSlot?: import("./item_acceptor").ItemAcceptorLocatedSlot,
- * cachedBeltPath?: BeltPath,
- * cachedTargetEntity?: Entity
- * }} ItemEjectorSlot
- */
-
-export class ItemEjectorComponent extends Component {
- static getId() {
- return "ItemEjector";
- }
-
- static getSchema() {
- // The cachedDestSlot, cachedTargetEntity fields are not serialized.
- return {
- slots: types.fixedSizeArray(
- types.structured({
- item: types.nullable(typeItemSingleton),
- progress: types.float,
- })
- ),
- };
- }
-
- /**
- *
- * @param {object} param0
- * @param {Array<{pos: Vector, direction: enumDirection }>=} param0.slots The slots to eject on
- * @param {boolean=} param0.renderFloatingItems Whether to render items even if they are not connected
- */
- constructor({ slots = [], renderFloatingItems = true }) {
- super();
-
- this.setSlots(slots);
- this.renderFloatingItems = renderFloatingItems;
- }
-
- clear() {
- for (const slot of this.slots) {
- slot.item = null;
- slot.lastItem = null;
- slot.progress = 0;
- }
- }
-
- /**
- * @param {Array<{pos: Vector, direction: enumDirection }>} slots The slots to eject on
- */
- setSlots(slots) {
- /** @type {Array} */
- this.slots = [];
- for (let i = 0; i < slots.length; ++i) {
- const slot = slots[i];
- this.slots.push({
- pos: slot.pos,
- direction: slot.direction,
- item: null,
- lastItem: null,
- progress: 0,
- cachedDestSlot: null,
- cachedTargetEntity: null,
- });
- }
- }
-
- /**
- * Returns where this slot ejects to
- * @param {ItemEjectorSlot} slot
- * @returns {Vector}
- */
- getSlotTargetLocalTile(slot) {
- const directionVector = enumDirectionToVector[slot.direction];
- return slot.pos.add(directionVector);
- }
-
- /**
- * Returns whether any slot ejects to the given local tile
- * @param {Vector} tile
- */
- anySlotEjectsToLocalTile(tile) {
- for (let i = 0; i < this.slots.length; ++i) {
- if (this.getSlotTargetLocalTile(this.slots[i]).equals(tile)) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Returns if we can eject on a given slot
- * @param {number} slotIndex
- * @returns {boolean}
- */
- canEjectOnSlot(slotIndex) {
- assert(slotIndex >= 0 && slotIndex < this.slots.length, "Invalid ejector slot: " + slotIndex);
- return !this.slots[slotIndex].item;
- }
-
- /**
- * Returns the first free slot on this ejector or null if there is none
- * @returns {number?}
- */
- getFirstFreeSlot() {
- for (let i = 0; i < this.slots.length; ++i) {
- if (this.canEjectOnSlot(i)) {
- return i;
- }
- }
- return null;
- }
-
- /**
- * Tries to eject a given item
- * @param {number} slotIndex
- * @param {BaseItem} item
- * @returns {boolean}
- */
- tryEject(slotIndex, item) {
- if (!this.canEjectOnSlot(slotIndex)) {
- return false;
- }
- this.slots[slotIndex].item = item;
- this.slots[slotIndex].lastItem = item;
- this.slots[slotIndex].progress = 0;
- return true;
- }
-
- /**
- * Clears the given slot and returns the item it had
- * @param {number} slotIndex
- * @returns {BaseItem|null}
- */
- takeSlotItem(slotIndex) {
- const slot = this.slots[slotIndex];
- const item = slot.item;
- slot.item = null;
- slot.progress = 0.0;
- return item;
- }
-}
+import { enumDirection, enumDirectionToVector, Vector } from "../../core/vector";
+import { types } from "../../savegame/serialization";
+import { BaseItem } from "../base_item";
+import { BeltPath } from "../belt_path";
+import { Component } from "../component";
+import { Entity } from "../entity";
+import { typeItemSingleton } from "../item_resolver";
+
+/**
+ * @typedef {{
+ * pos: Vector,
+ * direction: enumDirection,
+ * item: BaseItem,
+ * lastItem: BaseItem,
+ * progress: number?,
+ * cachedDestSlot?: import("./item_acceptor").ItemAcceptorLocatedSlot,
+ * cachedBeltPath?: BeltPath,
+ * cachedTargetEntity?: Entity
+ * }} ItemEjectorSlot
+ */
+
+export class ItemEjectorComponent extends Component {
+ static getId() {
+ return "ItemEjector";
+ }
+
+ static getSchema() {
+ // The cachedDestSlot, cachedTargetEntity fields are not serialized.
+ return {
+ slots: types.fixedSizeArray(
+ types.structured({
+ item: types.nullable(typeItemSingleton),
+ progress: types.float,
+ })
+ ),
+ };
+ }
+
+ /**
+ *
+ * @param {object} param0
+ * @param {Array<{pos: Vector, direction: enumDirection }>=} param0.slots The slots to eject on
+ * @param {boolean=} param0.renderFloatingItems Whether to render items even if they are not connected
+ */
+ constructor({ slots = [], renderFloatingItems = true }) {
+ super();
+
+ this.setSlots(slots);
+ this.renderFloatingItems = renderFloatingItems;
+ }
+
+ clear() {
+ for (const slot of this.slots) {
+ slot.item = null;
+ slot.lastItem = null;
+ slot.progress = 0;
+ }
+ }
+
+ /**
+ * @param {Array<{pos: Vector, direction: enumDirection }>} slots The slots to eject on
+ */
+ setSlots(slots) {
+ /** @type {Array} */
+ this.slots = [];
+ for (let i = 0; i < slots.length; ++i) {
+ const slot = slots[i];
+ this.slots.push({
+ pos: slot.pos,
+ direction: slot.direction,
+ item: null,
+ lastItem: null,
+ progress: 0,
+ cachedDestSlot: null,
+ cachedTargetEntity: null,
+ });
+ }
+ }
+
+ /**
+ * Returns where this slot ejects to
+ * @param {ItemEjectorSlot} slot
+ * @returns {Vector}
+ */
+ getSlotTargetLocalTile(slot) {
+ const directionVector = enumDirectionToVector[slot.direction];
+ return slot.pos.add(directionVector);
+ }
+
+ /**
+ * Returns whether any slot ejects to the given local tile
+ * @param {Vector} tile
+ */
+ anySlotEjectsToLocalTile(tile) {
+ for (let i = 0; i < this.slots.length; ++i) {
+ if (this.getSlotTargetLocalTile(this.slots[i]).equals(tile)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Returns if we can eject on a given slot
+ * @param {number} slotIndex
+ * @returns {boolean}
+ */
+ canEjectOnSlot(slotIndex) {
+ assert(slotIndex >= 0 && slotIndex < this.slots.length, "Invalid ejector slot: " + slotIndex);
+ return !this.slots[slotIndex].item;
+ }
+
+ /**
+ * Returns the first free slot on this ejector or null if there is none
+ * @returns {number?}
+ */
+ getFirstFreeSlot() {
+ for (let i = 0; i < this.slots.length; ++i) {
+ if (this.canEjectOnSlot(i)) {
+ return i;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Tries to eject a given item
+ * @param {number} slotIndex
+ * @param {BaseItem} item
+ * @returns {boolean}
+ */
+ tryEject(slotIndex, item) {
+ if (!this.canEjectOnSlot(slotIndex)) {
+ return false;
+ }
+ this.slots[slotIndex].item = item;
+ this.slots[slotIndex].lastItem = item;
+ this.slots[slotIndex].progress = 0;
+ return true;
+ }
+
+ /**
+ * Clears the given slot and returns the item it had
+ * @param {number} slotIndex
+ * @returns {BaseItem|null}
+ */
+ takeSlotItem(slotIndex) {
+ const slot = this.slots[slotIndex];
+ const item = slot.item;
+ slot.item = null;
+ slot.progress = 0.0;
+ return item;
+ }
+}
diff --git a/src/js/game/components/item_processor.js b/src/js/game/components/item_processor.js
index be7d1ce4..e512d666 100644
--- a/src/js/game/components/item_processor.js
+++ b/src/js/game/components/item_processor.js
@@ -7,9 +7,9 @@ export const enumItemProcessorTypes = {
balancer: "balancer",
cutter: "cutter",
cutterQuad: "cutterQuad",
- rotater: "rotater",
- rotaterCCW: "rotaterCCW",
- rotater180: "rotater180",
+ rotator: "rotator",
+ rotatorCCW: "rotatorCCW",
+ rotator180: "rotator180",
stacker: "stacker",
trash: "trash",
mixer: "mixer",
diff --git a/src/js/game/components/item_producer.js b/src/js/game/components/item_producer.js
index ef3571e2..3c1ccf0c 100644
--- a/src/js/game/components/item_producer.js
+++ b/src/js/game/components/item_producer.js
@@ -1,7 +1,7 @@
-import { Component } from "../component";
-
-export class ItemProducerComponent extends Component {
- static getId() {
- return "ItemProducer";
- }
-}
+import { Component } from "../component";
+
+export class ItemProducerComponent extends Component {
+ static getId() {
+ return "ItemProducer";
+ }
+}
diff --git a/src/js/game/components/lever.js b/src/js/game/components/lever.js
index 106cbbdd..cdef5a58 100644
--- a/src/js/game/components/lever.js
+++ b/src/js/game/components/lever.js
@@ -1,31 +1,31 @@
-import { Component } from "../component";
-import { types } from "../../savegame/serialization";
-
-export class LeverComponent extends Component {
- static getId() {
- return "Lever";
- }
-
- static getSchema() {
- return {
- toggled: types.bool,
- };
- }
-
- /**
- * Copy the current state to another component
- * @param {LeverComponent} otherComponent
- */
- copyAdditionalStateTo(otherComponent) {
- otherComponent.toggled = this.toggled;
- }
-
- /**
- * @param {object} param0
- * @param {boolean=} param0.toggled
- */
- constructor({ toggled = false }) {
- super();
- this.toggled = toggled;
- }
-}
+import { Component } from "../component";
+import { types } from "../../savegame/serialization";
+
+export class LeverComponent extends Component {
+ static getId() {
+ return "Lever";
+ }
+
+ static getSchema() {
+ return {
+ toggled: types.bool,
+ };
+ }
+
+ /**
+ * Copy the current state to another component
+ * @param {LeverComponent} otherComponent
+ */
+ copyAdditionalStateTo(otherComponent) {
+ otherComponent.toggled = this.toggled;
+ }
+
+ /**
+ * @param {object} param0
+ * @param {boolean=} param0.toggled
+ */
+ constructor({ toggled = false }) {
+ super();
+ this.toggled = toggled;
+ }
+}
diff --git a/src/js/game/components/logic_gate.js b/src/js/game/components/logic_gate.js
index 62cd3365..83611706 100644
--- a/src/js/game/components/logic_gate.js
+++ b/src/js/game/components/logic_gate.js
@@ -1,34 +1,34 @@
-import { Component } from "../component";
-
-/** @enum {string} */
-export const enumLogicGateType = {
- and: "and",
- not: "not",
- xor: "xor",
- or: "or",
- transistor: "transistor",
-
- analyzer: "analyzer",
- rotater: "rotater",
- unstacker: "unstacker",
- cutter: "cutter",
- compare: "compare",
- stacker: "stacker",
- painter: "painter",
-};
-
-export class LogicGateComponent extends Component {
- static getId() {
- return "LogicGate";
- }
-
- /**
- *
- * @param {object} param0
- * @param {enumLogicGateType=} param0.type
- */
- constructor({ type = enumLogicGateType.and }) {
- super();
- this.type = type;
- }
-}
+import { Component } from "../component";
+
+/** @enum {string} */
+export const enumLogicGateType = {
+ and: "and",
+ not: "not",
+ xor: "xor",
+ or: "or",
+ transistor: "transistor",
+
+ analyzer: "analyzer",
+ rotator: "rotator",
+ unstacker: "unstacker",
+ cutter: "cutter",
+ compare: "compare",
+ stacker: "stacker",
+ painter: "painter",
+};
+
+export class LogicGateComponent extends Component {
+ static getId() {
+ return "LogicGate";
+ }
+
+ /**
+ *
+ * @param {object} param0
+ * @param {enumLogicGateType=} param0.type
+ */
+ constructor({ type = enumLogicGateType.and }) {
+ super();
+ this.type = type;
+ }
+}
diff --git a/src/js/game/components/miner.js b/src/js/game/components/miner.js
index 5321ae11..cc2edb2c 100644
--- a/src/js/game/components/miner.js
+++ b/src/js/game/components/miner.js
@@ -1,64 +1,64 @@
-import { types } from "../../savegame/serialization";
-import { BaseItem } from "../base_item";
-import { Component } from "../component";
-import { Entity } from "../entity";
-import { typeItemSingleton } from "../item_resolver";
-
-const chainBufferSize = 6;
-
-export class MinerComponent extends Component {
- static getId() {
- return "Miner";
- }
-
- static getSchema() {
- // cachedMinedItem is not serialized.
- return {
- lastMiningTime: types.ufloat,
- itemChainBuffer: types.array(typeItemSingleton),
- };
- }
-
- constructor({ chainable = false }) {
- super();
- this.lastMiningTime = 0;
- this.chainable = chainable;
-
- /**
- * @type {BaseItem}
- */
- this.cachedMinedItem = null;
-
- /**
- * Which miner this miner ejects to, in case its a chainable one.
- * If the value is false, it means there is no entity, and we don't have to re-check
- * @type {Entity|null|false}
- */
- this.cachedChainedMiner = null;
-
- this.clear();
- }
-
- clear() {
- /**
- * Stores items from other miners which were chained to this
- * miner.
- * @type {Array}
- */
- this.itemChainBuffer = [];
- }
-
- /**
- *
- * @param {BaseItem} item
- */
- tryAcceptChainedItem(item) {
- if (this.itemChainBuffer.length > chainBufferSize) {
- // Well, this one is full
- return false;
- }
-
- this.itemChainBuffer.push(item);
- return true;
- }
-}
+import { types } from "../../savegame/serialization";
+import { BaseItem } from "../base_item";
+import { Component } from "../component";
+import { Entity } from "../entity";
+import { typeItemSingleton } from "../item_resolver";
+
+const chainBufferSize = 6;
+
+export class MinerComponent extends Component {
+ static getId() {
+ return "Miner";
+ }
+
+ static getSchema() {
+ // cachedMinedItem is not serialized.
+ return {
+ lastMiningTime: types.ufloat,
+ itemChainBuffer: types.array(typeItemSingleton),
+ };
+ }
+
+ constructor({ chainable = false }) {
+ super();
+ this.lastMiningTime = 0;
+ this.chainable = chainable;
+
+ /**
+ * @type {BaseItem}
+ */
+ this.cachedMinedItem = null;
+
+ /**
+ * Which miner this miner ejects to, in case its a chainable one.
+ * If the value is false, it means there is no entity, and we don't have to re-check
+ * @type {Entity|null|false}
+ */
+ this.cachedChainedMiner = null;
+
+ this.clear();
+ }
+
+ clear() {
+ /**
+ * Stores items from other miners which were chained to this
+ * miner.
+ * @type {Array}
+ */
+ this.itemChainBuffer = [];
+ }
+
+ /**
+ *
+ * @param {BaseItem} item
+ */
+ tryAcceptChainedItem(item) {
+ if (this.itemChainBuffer.length > chainBufferSize) {
+ // Well, this one is full
+ return false;
+ }
+
+ this.itemChainBuffer.push(item);
+ return true;
+ }
+}
diff --git a/src/js/game/components/static_map_entity.js b/src/js/game/components/static_map_entity.js
index a3d6a8ca..f92fcc48 100644
--- a/src/js/game/components/static_map_entity.js
+++ b/src/js/game/components/static_map_entity.js
@@ -255,8 +255,16 @@ export class StaticMapEntityComponent extends Component {
* @param {AtlasSprite} sprite
* @param {number=} extrudePixels How many pixels to extrude the sprite
* @param {Vector=} overridePosition Whether to drwa the entity at a different location
+ * @param {boolean=} pixelAligned
+ * Whether to round the canvas coordinates, to avoid issues with transparency between tiling images
*/
- drawSpriteOnBoundsClipped(parameters, sprite, extrudePixels = 0, overridePosition = null) {
+ drawSpriteOnBoundsClipped(
+ parameters,
+ sprite,
+ extrudePixels = 0,
+ overridePosition = null,
+ pixelAligned = false
+ ) {
if (!this.shouldBeDrawn(parameters) && !overridePosition) {
return;
}
@@ -269,31 +277,74 @@ export class StaticMapEntityComponent extends Component {
worldY = overridePosition.y * globalConfig.tileSize;
}
- if (this.rotation === 0) {
- // Early out, is faster
- sprite.drawCached(
- parameters,
- worldX - extrudePixels * size.x,
- worldY - extrudePixels * size.y,
- globalConfig.tileSize * size.x + 2 * extrudePixels * size.x,
- globalConfig.tileSize * size.y + 2 * extrudePixels * size.y
- );
- } else {
- const rotationCenterX = worldX + globalConfig.halfTileSize;
- const rotationCenterY = worldY + globalConfig.halfTileSize;
+ if (!pixelAligned) {
+ if (this.rotation === 0) {
+ // Early out, is faster
+ sprite.drawCached(
+ parameters,
+ worldX - extrudePixels * size.x,
+ worldY - extrudePixels * size.y,
+ globalConfig.tileSize * size.x + 2 * extrudePixels * size.x,
+ globalConfig.tileSize * size.y + 2 * extrudePixels * size.y
+ );
+ } else {
+ const rotationCenterX = worldX + globalConfig.halfTileSize;
+ const rotationCenterY = worldY + globalConfig.halfTileSize;
- parameters.context.translate(rotationCenterX, rotationCenterY);
- parameters.context.rotate(Math.radians(this.rotation));
- sprite.drawCached(
- parameters,
- -globalConfig.halfTileSize - extrudePixels * size.x,
- -globalConfig.halfTileSize - extrudePixels * size.y,
- globalConfig.tileSize * size.x + 2 * extrudePixels * size.x,
- globalConfig.tileSize * size.y + 2 * extrudePixels * size.y,
- false // no clipping possible here
- );
- parameters.context.rotate(-Math.radians(this.rotation));
- parameters.context.translate(-rotationCenterX, -rotationCenterY);
+ parameters.context.translate(rotationCenterX, rotationCenterY);
+ parameters.context.rotate(Math.radians(this.rotation));
+ sprite.drawCached(
+ parameters,
+ -globalConfig.halfTileSize - extrudePixels * size.x,
+ -globalConfig.halfTileSize - extrudePixels * size.y,
+ globalConfig.tileSize * size.x + 2 * extrudePixels * size.x,
+ globalConfig.tileSize * size.y + 2 * extrudePixels * size.y,
+ false // no clipping possible here
+ );
+ parameters.context.rotate(-Math.radians(this.rotation));
+ parameters.context.translate(-rotationCenterX, -rotationCenterY);
+ }
+ return;
}
+
+ const tileCenter = new Vector(globalConfig.halfTileSize, globalConfig.halfTileSize);
+ const rotatedTileCenter = tileCenter.rotateFastMultipleOf90(this.rotation);
+ const cornerX = worldX + tileCenter.x - rotatedTileCenter.x;
+ const cornerY = worldY + tileCenter.y - rotatedTileCenter.y;
+ const offset = size.rotateFastMultipleOf90(this.rotation);
+
+ const transform = parameters.context.getTransform();
+ const matrix = new DOMMatrix().rotate(0, 0, -this.rotation).multiplySelf(transform);
+ let { x: x1, y: y1 } = matrix.transformPoint(
+ new DOMPoint(cornerX - extrudePixels * offset.x, cornerY - extrudePixels * offset.y)
+ );
+ let { x: x2, y: y2 } = matrix.transformPoint(
+ new DOMPoint(
+ cornerX + globalConfig.tileSize * offset.x + extrudePixels * offset.x,
+ cornerY + globalConfig.tileSize * offset.y + extrudePixels * offset.y
+ )
+ );
+ if (x1 > x2) {
+ [x1, x2] = [x2, x1];
+ }
+ if (y1 > y2) {
+ [y1, y2] = [y2, y1];
+ }
+ // Even though drawCached may scale the coordinates,
+ // that scaling is for sprites that don't take up their full tile space,
+ // so they should be interpolated exactly between the rounded tile coordinates.
+ // E.g. rounding in drawCached causes curved belts to look misaligned.
+ x1 = Math.round(x1);
+ y1 = Math.round(y1);
+ x2 = Math.round(x2);
+ y2 = Math.round(y2);
+ if (x2 - x1 == 0 || y2 - y1 == 0) {
+ return;
+ }
+
+ parameters.context.resetTransform();
+ parameters.context.rotate(Math.radians(this.rotation));
+ sprite.drawCached(parameters, x1, y1, x2 - x1, y2 - y1, false);
+ parameters.context.setTransform(transform);
}
}
diff --git a/src/js/game/components/underground_belt.js b/src/js/game/components/underground_belt.js
index 2b744edd..fe465350 100644
--- a/src/js/game/components/underground_belt.js
+++ b/src/js/game/components/underground_belt.js
@@ -57,7 +57,7 @@ export class UndergroundBeltComponent extends Component {
/**
* Used on both receiver and sender.
- * Reciever: Used to store the next item to transfer, and to block input while doing this
+ * Receiver: Used to store the next item to transfer, and to block input while doing this
* Sender: Used to store which items are currently "travelling"
* @type {Array<[BaseItem, number]>} Format is [Item, ingame time to eject the item]
*/
diff --git a/src/js/game/core.js b/src/js/game/core.js
index 7283710e..e349f5b2 100644
--- a/src/js/game/core.js
+++ b/src/js/game/core.js
@@ -1,576 +1,523 @@
-/* typehints:start */
-import { Application } from "../application";
-/* typehints:end */
-import { BufferMaintainer } from "../core/buffer_maintainer";
-import {
- disableImageSmoothing,
- enableImageSmoothing,
- getBufferStats,
- registerCanvas,
-} from "../core/buffer_utils";
-import { globalConfig } from "../core/config";
-import { getDeviceDPI, resizeHighDPICanvas } from "../core/dpi_manager";
-import { DrawParameters } from "../core/draw_parameters";
-import { gMetaBuildingRegistry } from "../core/global_registries";
-import { createLogger } from "../core/logging";
-import { Rectangle } from "../core/rectangle";
-import { ORIGINAL_SPRITE_SCALE } from "../core/sprites";
-import { lerp, randomInt, round2Digits } from "../core/utils";
-import { Vector } from "../core/vector";
-import { Savegame } from "../savegame/savegame";
-import { SavegameSerializer } from "../savegame/savegame_serializer";
-import { AutomaticSave } from "./automatic_save";
-import { MetaHubBuilding } from "./buildings/hub";
-import { Camera } from "./camera";
-import { DynamicTickrate } from "./dynamic_tickrate";
-import { EntityManager } from "./entity_manager";
-import { GameSystemManager } from "./game_system_manager";
-import { HubGoals } from "./hub_goals";
-import { GameHUD } from "./hud/hud";
-import { KeyActionMapper } from "./key_action_mapper";
-import { GameLogic } from "./logic";
-import { MapView } from "./map_view";
-import { defaultBuildingVariant } from "./meta_building";
-import { GameMode } from "./game_mode";
-import { ProductionAnalytics } from "./production_analytics";
-import { GameRoot } from "./root";
-import { ShapeDefinitionManager } from "./shape_definition_manager";
-import { AchievementProxy } from "./achievement_proxy";
-import { SoundProxy } from "./sound_proxy";
-import { GameTime } from "./time/game_time";
-import { MOD_SIGNALS } from "../mods/mod_signals";
-
-const logger = createLogger("ingame/core");
-
-// Store the canvas so we can reuse it later
-/** @type {HTMLCanvasElement} */
-let lastCanvas = null;
-/** @type {CanvasRenderingContext2D} */
-let lastContext = null;
-
-/**
- * The core manages the root and represents the whole game. It wraps the root, since
- * the root class is just a data holder.
- */
-export class GameCore {
- /** @param {Application} app */
- constructor(app) {
- this.app = app;
-
- /** @type {GameRoot} */
- this.root = null;
-
- /**
- * Set to true at the beginning of a logic update and cleared when its finished.
- * This is to prevent doing a recursive logic update which can lead to unexpected
- * behaviour.
- */
- this.duringLogicUpdate = false;
-
- // Cached
- this.boundInternalTick = this.updateLogic.bind(this);
-
- /**
- * Opacity of the overview alpha
- * @TODO Doesn't belong here
- */
- this.overlayAlpha = 0;
- }
-
- /**
- * Initializes the root object which stores all game related data. The state
- * is required as a back reference (used sometimes)
- * @param {import("../states/ingame").InGameState} parentState
- * @param {Savegame} savegame
- */
- initializeRoot(parentState, savegame, gameModeId) {
- logger.log("initializing root");
-
- // Construct the root element, this is the data representation of the game
- this.root = new GameRoot(this.app);
- this.root.gameState = parentState;
- this.root.keyMapper = parentState.keyActionMapper;
- this.root.savegame = savegame;
- this.root.gameWidth = this.app.screenWidth;
- this.root.gameHeight = this.app.screenHeight;
-
- // Initialize canvas element & context
- this.internalInitCanvas();
-
- // Members
- const root = this.root;
-
- // This isn't nice, but we need it right here
- root.keyMapper = new KeyActionMapper(root, this.root.gameState.inputReciever);
-
- // Init game mode
- root.gameMode = GameMode.create(root, gameModeId, parentState.creationPayload.gameModeParameters);
-
- // Needs to come first
- root.dynamicTickrate = new DynamicTickrate(root);
-
- // Init classes
- root.camera = new Camera(root);
- root.map = new MapView(root);
- root.logic = new GameLogic(root);
- root.hud = new GameHUD(root);
- root.time = new GameTime(root);
- root.achievementProxy = new AchievementProxy(root);
- root.automaticSave = new AutomaticSave(root);
- root.soundProxy = new SoundProxy(root);
-
- // Init managers
- root.entityMgr = new EntityManager(root);
- root.systemMgr = new GameSystemManager(root);
- root.shapeDefinitionMgr = new ShapeDefinitionManager(root);
- root.hubGoals = new HubGoals(root);
- root.productionAnalytics = new ProductionAnalytics(root);
- root.buffers = new BufferMaintainer(root);
-
- // Initialize the hud once everything is loaded
- this.root.hud.initialize();
-
- // Initial resize event, it might be possible that the screen
- // resized later during init tho, which is why will emit it later
- // again anyways
- this.resize(this.app.screenWidth, this.app.screenHeight);
-
- if (G_IS_DEV) {
- // @ts-ignore
- window.globalRoot = root;
- }
-
- // @todo Find better place
- if (G_IS_DEV && globalConfig.debug.manualTickOnly) {
- this.root.gameState.inputReciever.keydown.add(key => {
- if (key.keyCode === 84) {
- // 'T'
-
- // Extract current real time
- this.root.time.updateRealtimeNow();
-
- // Perform logic ticks
- this.root.time.performTicks(this.root.dynamicTickrate.deltaMs, this.boundInternalTick);
-
- // Update analytics
- root.productionAnalytics.update();
-
- // Check achievements
- root.achievementProxy.update();
- }
- });
- }
-
- logger.log("root initialized");
- MOD_SIGNALS.gameInitialized.dispatch(root);
- }
-
- /**
- * Initializes a new game, this means creating a new map and centering on the
- * playerbase
- * */
- initNewGame() {
- logger.log("Initializing new game");
- this.root.gameIsFresh = true;
- this.root.map.seed = randomInt(0, 100000);
-
- if (!this.root.gameMode.hasHub()) {
- return;
- }
-
- // Place the hub
- const hub = gMetaBuildingRegistry.findByClass(MetaHubBuilding).createEntity({
- root: this.root,
- origin: new Vector(-2, -2),
- rotation: 0,
- originalRotation: 0,
- rotationVariant: 0,
- variant: defaultBuildingVariant,
- });
- this.root.map.placeStaticEntity(hub);
- this.root.entityMgr.registerEntity(hub);
- this.root.camera.center = new Vector(-5, 2).multiplyScalar(globalConfig.tileSize);
- }
-
- /**
- * Inits an existing game by loading the raw savegame data and deserializing it.
- * Also runs basic validity checks.
- */
- initExistingGame() {
- logger.log("Initializing existing game");
- const serializer = new SavegameSerializer();
-
- try {
- const status = serializer.deserialize(this.root.savegame.getCurrentDump(), this.root);
- if (!status.isGood()) {
- logger.error("savegame-deserialize-failed:" + status.reason);
- return false;
- }
- } catch (ex) {
- logger.error("Exception during deserialization:", ex);
- return false;
- }
- this.root.gameIsFresh = false;
- return true;
- }
-
- /**
- * Initializes the render canvas
- */
- internalInitCanvas() {
- let canvas, context;
- if (!lastCanvas) {
- logger.log("Creating new canvas");
- canvas = document.createElement("canvas");
- canvas.id = "ingame_Canvas";
- canvas.setAttribute("opaque", "true");
- canvas.setAttribute("webkitOpaque", "true");
- canvas.setAttribute("mozOpaque", "true");
- this.root.gameState.getDivElement().appendChild(canvas);
- context = canvas.getContext("2d", { alpha: false });
-
- lastCanvas = canvas;
- lastContext = context;
- } else {
- logger.log("Reusing canvas");
- if (lastCanvas.parentElement) {
- lastCanvas.parentElement.removeChild(lastCanvas);
- }
- this.root.gameState.getDivElement().appendChild(lastCanvas);
-
- canvas = lastCanvas;
- context = lastContext;
-
- lastContext.clearRect(0, 0, lastCanvas.width, lastCanvas.height);
- }
-
- canvas.classList.toggle("smoothed", globalConfig.smoothing.smoothMainCanvas);
-
- // Oof, use :not() instead
- canvas.classList.toggle("unsmoothed", !globalConfig.smoothing.smoothMainCanvas);
-
- if (globalConfig.smoothing.smoothMainCanvas) {
- enableImageSmoothing(context);
- } else {
- disableImageSmoothing(context);
- }
-
- this.root.canvas = canvas;
- this.root.context = context;
-
- registerCanvas(canvas, context);
- }
-
- /**
- * Destructs the root, freeing all resources
- */
- destruct() {
- if (lastCanvas && lastCanvas.parentElement) {
- lastCanvas.parentElement.removeChild(lastCanvas);
- }
-
- this.root.destruct();
- delete this.root;
- this.root = null;
- this.app = null;
- }
-
- tick(deltaMs) {
- const root = this.root;
-
- // Extract current real time
- root.time.updateRealtimeNow();
-
- // Camera is always updated, no matter what
- root.camera.update(deltaMs);
-
- if (!(G_IS_DEV && globalConfig.debug.manualTickOnly)) {
- // Perform logic ticks
- this.root.time.performTicks(deltaMs, this.boundInternalTick);
-
- // Update analytics
- root.productionAnalytics.update();
-
- // Check achievements
- root.achievementProxy.update();
- }
-
- // Update automatic save after everything finished
- root.automaticSave.update();
-
- return true;
- }
-
- shouldRender() {
- if (this.root.queue.requireRedraw) {
- return true;
- }
- if (this.root.hud.shouldPauseRendering()) {
- return false;
- }
-
- // Do not render
- if (!this.app.isRenderable()) {
- return false;
- }
-
- return true;
- }
-
- updateLogic() {
- const root = this.root;
-
- root.dynamicTickrate.beginTick();
-
- if (G_IS_DEV && globalConfig.debug.disableLogicTicks) {
- root.dynamicTickrate.endTick();
- return true;
- }
-
- this.duringLogicUpdate = true;
-
- // Update entities, this removes destroyed entities
- root.entityMgr.update();
-
- // IMPORTANT: At this point, the game might be game over. Stop if this is the case
- if (!this.root) {
- logger.log("Root destructed, returning false");
- root.dynamicTickrate.endTick();
-
- return false;
- }
-
- root.systemMgr.update();
- // root.particleMgr.update();
-
- this.duringLogicUpdate = false;
- root.dynamicTickrate.endTick();
- return true;
- }
-
- resize(w, h) {
- this.root.gameWidth = w;
- this.root.gameHeight = h;
- resizeHighDPICanvas(this.root.canvas, w, h, globalConfig.smoothing.smoothMainCanvas);
- this.root.signals.resized.dispatch(w, h);
- this.root.queue.requireRedraw = true;
- }
-
- postLoadHook() {
- logger.log("Dispatching post load hook");
- this.root.signals.postLoadHook.dispatch();
-
- if (!this.root.gameIsFresh) {
- // Also dispatch game restored hook on restored savegames
- this.root.signals.gameRestored.dispatch();
- }
-
- this.root.gameInitialized = true;
- }
-
- draw() {
- const root = this.root;
- const systems = root.systemMgr.systems;
-
- this.root.dynamicTickrate.onFrameRendered();
-
- if (!this.shouldRender()) {
- // Always update hud tho
- root.hud.update();
- return;
- }
-
- this.root.signals.gameFrameStarted.dispatch();
-
- root.queue.requireRedraw = false;
-
- // Gather context and save all state
- const context = root.context;
- context.save();
- if (G_IS_DEV) {
- context.fillStyle = "#a10000";
- context.fillRect(0, 0, window.innerWidth * 3, window.innerHeight * 3);
- }
-
- // Compute optimal zoom level and atlas scale
- const zoomLevel = root.camera.zoomLevel;
- const lowQuality = root.app.settings.getAllSettings().lowQualityTextures;
- const effectiveZoomLevel =
- (zoomLevel / globalConfig.assetsDpi) * getDeviceDPI() * globalConfig.assetsSharpness;
-
- let desiredAtlasScale = "0.25";
- if (effectiveZoomLevel > 0.5 && !lowQuality) {
- desiredAtlasScale = ORIGINAL_SPRITE_SCALE;
- } else if (effectiveZoomLevel > 0.35 && !lowQuality) {
- desiredAtlasScale = "0.5";
- }
-
- // Construct parameters required for drawing
- const params = new DrawParameters({
- context: context,
- visibleRect: root.camera.getVisibleRect(),
- desiredAtlasScale,
- zoomLevel,
- root: root,
- });
-
- if (G_IS_DEV && globalConfig.debug.testCulling) {
- context.clearRect(0, 0, root.gameWidth, root.gameHeight);
- }
-
- // Transform to world space
-
- if (G_IS_DEV && globalConfig.debug.testClipping) {
- params.visibleRect = params.visibleRect.expandedInAllDirections(
- -200 / this.root.camera.zoomLevel
- );
- }
-
- root.camera.transform(context);
-
- assert(context.globalAlpha === 1.0, "Global alpha not 1 on frame start");
-
- // Update hud
- root.hud.update();
-
- // Main rendering order
- // -----
-
- const desiredOverlayAlpha = this.root.camera.getIsMapOverlayActive() ? 1 : 0;
- this.overlayAlpha = lerp(this.overlayAlpha, desiredOverlayAlpha, 0.25);
-
- // On low performance, skip the fade
- if (this.root.entityMgr.entities.length > 5000 || this.root.dynamicTickrate.averageFps < 50) {
- this.overlayAlpha = desiredOverlayAlpha;
- }
-
- if (this.overlayAlpha < 0.99) {
- // Background (grid, resources, etc)
- root.map.drawBackground(params);
-
- // Belt items
- systems.belt.drawBeltItems(params);
-
- // Miner & Static map entities etc.
- root.map.drawForeground(params);
-
- // HUB Overlay
- systems.hub.draw(params);
-
- // Green wires overlay
- if (root.hud.parts.wiresOverlay) {
- root.hud.parts.wiresOverlay.draw(params);
- }
-
- if (this.root.currentLayer === "wires") {
- // Static map entities
- root.map.drawWiresForegroundLayer(params);
- }
- }
-
- if (this.overlayAlpha > 0.01) {
- // Map overview
- context.globalAlpha = this.overlayAlpha;
- root.map.drawOverlay(params);
- context.globalAlpha = 1;
- }
-
- if (G_IS_DEV) {
- root.map.drawStaticEntityDebugOverlays(params);
- }
-
- if (G_IS_DEV && globalConfig.debug.renderBeltPaths) {
- systems.belt.drawBeltPathDebug(params);
- }
-
- // END OF GAME CONTENT
- // -----
-
- // Finally, draw the hud. Nothing should come after that
- root.hud.draw(params);
-
- assert(context.globalAlpha === 1.0, "Global alpha not 1 on frame end before restore");
-
- // Restore to screen space
- context.restore();
-
- // Restore parameters
- params.zoomLevel = 1;
- params.desiredAtlasScale = ORIGINAL_SPRITE_SCALE;
- params.visibleRect = new Rectangle(0, 0, this.root.gameWidth, this.root.gameHeight);
- if (G_IS_DEV && globalConfig.debug.testClipping) {
- params.visibleRect = params.visibleRect.expandedInAllDirections(-200);
- }
-
- // Draw overlays, those are screen space
- root.hud.drawOverlays(params);
-
- assert(context.globalAlpha === 1.0, "context.globalAlpha not 1 on frame end");
-
- if (G_IS_DEV && globalConfig.debug.simulateSlowRendering) {
- let sum = 0;
- for (let i = 0; i < 1e8; ++i) {
- sum += i;
- }
- if (Math.random() > 0.95) {
- console.log(sum);
- }
- }
-
- if (G_IS_DEV && globalConfig.debug.showAtlasInfo) {
- context.font = "13px GameFont";
- context.fillStyle = "blue";
- context.fillText(
- "Atlas: " +
- desiredAtlasScale +
- " / Zoom: " +
- round2Digits(zoomLevel) +
- " / Effective Zoom: " +
- round2Digits(effectiveZoomLevel),
- 20,
- 600
- );
-
- const stats = this.root.buffers.getStats();
-
- context.fillText(
- "Maintained Buffers: " +
- stats.rootKeys +
- " root keys / " +
- stats.subKeys +
- " buffers / VRAM: " +
- round2Digits(stats.vramBytes / (1024 * 1024)) +
- " MB",
- 20,
- 620
- );
- const internalStats = getBufferStats();
- context.fillText(
- "Total Buffers: " +
- internalStats.bufferCount +
- " buffers / " +
- internalStats.backlogSize +
- " backlog / " +
- internalStats.backlogKeys +
- " keys in backlog / VRAM " +
- round2Digits(internalStats.vramUsage / (1024 * 1024)) +
- " MB / Backlog " +
- round2Digits(internalStats.backlogVramUsage / (1024 * 1024)) +
- " MB / Created " +
- internalStats.numCreated +
- " / Reused " +
- internalStats.numReused,
- 20,
- 640
- );
- }
-
- if (G_IS_DEV && globalConfig.debug.testClipping) {
- context.strokeStyle = "red";
- context.lineWidth = 1;
- context.beginPath();
- context.rect(200, 200, this.root.gameWidth - 400, this.root.gameHeight - 400);
- context.stroke();
- }
- }
-}
+/* typehints:start */
+import { Application } from "../application";
+/* typehints:end */
+import { BufferMaintainer } from "../core/buffer_maintainer";
+import { getBufferStats } from "../core/buffer_utils";
+import { globalConfig } from "../core/config";
+import { getDeviceDPI, resizeHighDPICanvas } from "../core/dpi_manager";
+import { DrawParameters } from "../core/draw_parameters";
+import { gMetaBuildingRegistry } from "../core/global_registries";
+import { createLogger } from "../core/logging";
+import { Rectangle } from "../core/rectangle";
+import { ORIGINAL_SPRITE_SCALE } from "../core/sprites";
+import { lerp, randomInt, round2Digits } from "../core/utils";
+import { Vector } from "../core/vector";
+import { MOD_SIGNALS } from "../mods/mod_signals";
+import { Savegame } from "../savegame/savegame";
+import { SavegameSerializer } from "../savegame/savegame_serializer";
+import { AutomaticSave } from "./automatic_save";
+import { MetaHubBuilding } from "./buildings/hub";
+import { Camera } from "./camera";
+import { DynamicTickrate } from "./dynamic_tickrate";
+import { EntityManager } from "./entity_manager";
+import { GameMode } from "./game_mode";
+import { GameSystemManager } from "./game_system_manager";
+import { HubGoals } from "./hub_goals";
+import { GameHUD } from "./hud/hud";
+import { KeyActionMapper } from "./key_action_mapper";
+import { GameLogic } from "./logic";
+import { MapView } from "./map_view";
+import { defaultBuildingVariant } from "./meta_building";
+import { ProductionAnalytics } from "./production_analytics";
+import { GameRoot } from "./root";
+import { ShapeDefinitionManager } from "./shape_definition_manager";
+import { SoundProxy } from "./sound_proxy";
+import { GameTime } from "./time/game_time";
+
+const logger = createLogger("ingame/core");
+
+/**
+ * The core manages the root and represents the whole game. It wraps the root, since
+ * the root class is just a data holder.
+ */
+export class GameCore {
+ /** @param {Application} app */
+ constructor(app) {
+ this.app = app;
+
+ /** @type {GameRoot} */
+ this.root = null;
+
+ /**
+ * Set to true at the beginning of a logic update and cleared when its finished.
+ * This is to prevent doing a recursive logic update which can lead to unexpected
+ * behaviour.
+ */
+ this.duringLogicUpdate = false;
+
+ // Cached
+ this.boundInternalTick = this.updateLogic.bind(this);
+
+ /**
+ * Opacity of the overview alpha
+ * @TODO Doesn't belong here
+ */
+ this.overlayAlpha = 0;
+ }
+
+ /**
+ * Initializes the root object which stores all game related data. The state
+ * is required as a back reference (used sometimes)
+ * @param {import("../states/ingame").InGameState} parentState
+ * @param {Savegame} savegame
+ */
+ initializeRoot(parentState, savegame, gameModeId) {
+ logger.log("initializing root");
+
+ // Construct the root element, this is the data representation of the game
+ this.root = new GameRoot(this.app);
+ this.root.gameState = parentState;
+ this.root.keyMapper = parentState.keyActionMapper;
+ this.root.savegame = savegame;
+ this.root.gameWidth = this.app.screenWidth;
+ this.root.gameHeight = this.app.screenHeight;
+
+ // Initialize canvas element & context
+ this.internalInitCanvas();
+
+ // Members
+ const root = this.root;
+
+ // This isn't nice, but we need it right here
+ root.keyMapper = new KeyActionMapper(root, this.root.gameState.inputReceiver);
+
+ // Init game mode
+ root.gameMode = GameMode.create(root, gameModeId, parentState.creationPayload.gameModeParameters);
+
+ // Needs to come first
+ root.dynamicTickrate = new DynamicTickrate(root);
+
+ // Init classes
+ root.camera = new Camera(root);
+ root.map = new MapView(root);
+ root.logic = new GameLogic(root);
+ root.hud = new GameHUD(root);
+ root.time = new GameTime(root);
+ root.automaticSave = new AutomaticSave(root);
+ root.soundProxy = new SoundProxy(root);
+
+ // Init managers
+ root.entityMgr = new EntityManager(root);
+ root.systemMgr = new GameSystemManager(root);
+ root.shapeDefinitionMgr = new ShapeDefinitionManager(root);
+ root.hubGoals = new HubGoals(root);
+ root.productionAnalytics = new ProductionAnalytics(root);
+ root.buffers = new BufferMaintainer(root);
+
+ // Initialize the hud once everything is loaded
+ this.root.hud.initialize();
+
+ // Initial resize event, it might be possible that the screen
+ // resized later during init tho, which is why will emit it later
+ // again anyways
+ this.resize(this.app.screenWidth, this.app.screenHeight);
+
+ if (G_IS_DEV) {
+ // @ts-ignore
+ window.globalRoot = root;
+ }
+
+ // @todo Find better place
+ if (G_IS_DEV && globalConfig.debug.manualTickOnly) {
+ this.root.gameState.inputReceiver.keydown.add(key => {
+ if (key.keyCode === 84) {
+ // 'T'
+
+ // Extract current real time
+ this.root.time.updateRealtimeNow();
+
+ // Perform logic ticks
+ this.root.time.performTicks(this.root.dynamicTickrate.deltaMs, this.boundInternalTick);
+
+ // Update analytics
+ root.productionAnalytics.update();
+ }
+ });
+ }
+
+ logger.log("root initialized");
+ MOD_SIGNALS.gameInitialized.dispatch(root);
+ }
+
+ /**
+ * Initializes a new game, this means creating a new map and centering on the
+ * playerbase
+ * */
+ initNewGame() {
+ logger.log("Initializing new game");
+ this.root.gameIsFresh = true;
+ this.root.map.seed = randomInt(0, 100000);
+
+ if (!this.root.gameMode.hasHub()) {
+ return;
+ }
+
+ // Place the hub
+ const hub = gMetaBuildingRegistry.findByClass(MetaHubBuilding).createEntity({
+ root: this.root,
+ origin: new Vector(-2, -2),
+ rotation: 0,
+ originalRotation: 0,
+ rotationVariant: 0,
+ variant: defaultBuildingVariant,
+ });
+ this.root.map.placeStaticEntity(hub);
+ this.root.entityMgr.registerEntity(hub);
+ this.root.camera.center = new Vector(-5, 2).multiplyScalar(globalConfig.tileSize);
+ }
+
+ /**
+ * Inits an existing game by loading the raw savegame data and deserializing it.
+ * Also runs basic validity checks.
+ */
+ initExistingGame() {
+ logger.log("Initializing existing game");
+ const serializer = new SavegameSerializer();
+
+ try {
+ const status = serializer.deserialize(this.root.savegame.getCurrentDump(), this.root);
+ if (!status.isGood()) {
+ logger.error("savegame-deserialize-failed:" + status.reason);
+ return false;
+ }
+ } catch (ex) {
+ logger.error("Exception during deserialization:", ex);
+ return false;
+ }
+ this.root.gameIsFresh = false;
+ return true;
+ }
+
+ /**
+ * Initializes the render canvas
+ */
+ internalInitCanvas() {
+ logger.log("Creating new canvas");
+ const canvas = document.createElement("canvas");
+ canvas.id = "ingame_Canvas";
+ this.root.gameState.getDivElement().appendChild(canvas);
+ const context = canvas.getContext("2d", { alpha: false });
+
+ context.imageSmoothingEnabled = globalConfig.smoothing.smoothMainCanvas;
+ context.imageSmoothingQuality = globalConfig.smoothing.quality;
+
+ this.root.canvas = canvas;
+ this.root.context = context;
+ }
+
+ /**
+ * Destructs the root, freeing all resources
+ */
+ destruct() {
+ this.root.destruct();
+ delete this.root;
+ this.root = null;
+ this.app = null;
+ }
+
+ tick(deltaMs) {
+ const root = this.root;
+
+ // Extract current real time
+ root.time.updateRealtimeNow();
+
+ // Camera is always updated, no matter what
+ root.camera.update(deltaMs);
+
+ if (!(G_IS_DEV && globalConfig.debug.manualTickOnly)) {
+ // Perform logic ticks
+ this.root.time.performTicks(deltaMs, this.boundInternalTick);
+
+ // Update analytics
+ root.productionAnalytics.update();
+ }
+
+ // Update automatic save after everything finished
+ root.automaticSave.update();
+
+ return true;
+ }
+
+ shouldRender() {
+ if (this.root.queue.requireRedraw) {
+ return true;
+ }
+ if (this.root.hud.shouldPauseRendering()) {
+ return false;
+ }
+
+ // Do not render
+ if (!this.app.isRenderable()) {
+ return false;
+ }
+
+ return true;
+ }
+
+ updateLogic() {
+ const root = this.root;
+
+ root.dynamicTickrate.beginTick();
+
+ if (G_IS_DEV && globalConfig.debug.disableLogicTicks) {
+ root.dynamicTickrate.endTick();
+ return true;
+ }
+
+ this.duringLogicUpdate = true;
+
+ // Update entities, this removes destroyed entities
+ root.entityMgr.update();
+
+ // IMPORTANT: At this point, the game might be game over. Stop if this is the case
+ if (!this.root) {
+ logger.log("Root destructed, returning false");
+ root.dynamicTickrate.endTick();
+
+ return false;
+ }
+
+ root.systemMgr.update();
+ // root.particleMgr.update();
+
+ this.duringLogicUpdate = false;
+ root.dynamicTickrate.endTick();
+ return true;
+ }
+
+ resize(w, h) {
+ this.root.gameWidth = w;
+ this.root.gameHeight = h;
+ resizeHighDPICanvas(this.root.canvas, w, h, globalConfig.smoothing.smoothMainCanvas);
+ this.root.signals.resized.dispatch(w, h);
+ this.root.queue.requireRedraw = true;
+ }
+
+ postLoadHook() {
+ logger.log("Dispatching post load hook");
+ this.root.signals.postLoadHook.dispatch();
+
+ if (!this.root.gameIsFresh) {
+ // Also dispatch game restored hook on restored savegames
+ this.root.signals.gameRestored.dispatch();
+ }
+
+ this.root.gameInitialized = true;
+ }
+
+ draw() {
+ const root = this.root;
+ const systems = root.systemMgr.systems;
+
+ this.root.dynamicTickrate.onFrameRendered();
+
+ if (!this.shouldRender()) {
+ // Always update hud tho
+ root.hud.update();
+ return;
+ }
+
+ this.root.signals.gameFrameStarted.dispatch();
+
+ root.queue.requireRedraw = false;
+
+ // Gather context and save all state
+ const context = root.context;
+ context.save();
+ if (G_IS_DEV) {
+ context.fillStyle = "#a10000";
+ context.fillRect(0, 0, window.innerWidth * 3, window.innerHeight * 3);
+ }
+
+ // Compute optimal zoom level and atlas scale
+ const zoomLevel = root.camera.zoomLevel;
+ const lowQuality = root.app.settings.getAllSettings().lowQualityTextures;
+ const effectiveZoomLevel =
+ (zoomLevel / globalConfig.assetsDpi) * getDeviceDPI() * globalConfig.assetsSharpness;
+
+ let desiredAtlasScale = "0.25";
+ if (effectiveZoomLevel > 0.5 && !lowQuality) {
+ desiredAtlasScale = ORIGINAL_SPRITE_SCALE;
+ } else if (effectiveZoomLevel > 0.35 && !lowQuality) {
+ desiredAtlasScale = "0.5";
+ }
+
+ // Construct parameters required for drawing
+ const params = new DrawParameters({
+ context: context,
+ visibleRect: root.camera.getVisibleRect(),
+ desiredAtlasScale,
+ zoomLevel,
+ root: root,
+ });
+
+ if (G_IS_DEV && globalConfig.debug.testCulling) {
+ context.clearRect(0, 0, root.gameWidth, root.gameHeight);
+ }
+
+ // Transform to world space
+
+ if (G_IS_DEV && globalConfig.debug.testClipping) {
+ params.visibleRect = params.visibleRect.expandedInAllDirections(
+ -200 / this.root.camera.zoomLevel
+ );
+ }
+
+ root.camera.transform(context);
+
+ assert(context.globalAlpha === 1.0, "Global alpha not 1 on frame start");
+
+ // Update hud
+ root.hud.update();
+
+ // Main rendering order
+ // -----
+
+ const desiredOverlayAlpha = this.root.camera.getIsMapOverlayActive() ? 1 : 0;
+ this.overlayAlpha = lerp(this.overlayAlpha, desiredOverlayAlpha, 0.25);
+
+ // On low performance, skip the fade
+ if (this.root.entityMgr.entities.size > 5000 || this.root.dynamicTickrate.averageFps < 50) {
+ this.overlayAlpha = desiredOverlayAlpha;
+ }
+
+ if (this.overlayAlpha < 0.99) {
+ // Background (grid, resources, etc)
+ root.map.drawBackground(params);
+
+ // Belt items
+ systems.belt.drawBeltItems(params);
+
+ // Miner & Static map entities etc.
+ root.map.drawForeground(params);
+
+ // HUB Overlay
+ systems.hub.draw(params);
+
+ // Green wires overlay
+ if (root.hud.parts.wiresOverlay) {
+ root.hud.parts.wiresOverlay.draw(params);
+ }
+
+ if (this.root.currentLayer === "wires") {
+ // Static map entities
+ root.map.drawWiresForegroundLayer(params);
+ }
+ }
+
+ if (this.overlayAlpha > 0.01) {
+ // Map overview
+ context.globalAlpha = this.overlayAlpha;
+ root.map.drawOverlay(params);
+ context.globalAlpha = 1;
+ }
+
+ if (G_IS_DEV) {
+ root.map.drawStaticEntityDebugOverlays(params);
+ }
+
+ if (G_IS_DEV && globalConfig.debug.renderBeltPaths) {
+ systems.belt.drawBeltPathDebug(params);
+ }
+
+ // END OF GAME CONTENT
+ // -----
+
+ // Finally, draw the hud. Nothing should come after that
+ root.hud.draw(params);
+
+ assert(context.globalAlpha === 1.0, "Global alpha not 1 on frame end before restore");
+
+ // Restore to screen space
+ context.restore();
+
+ // Restore parameters
+ params.zoomLevel = 1;
+ params.desiredAtlasScale = ORIGINAL_SPRITE_SCALE;
+ params.visibleRect = new Rectangle(0, 0, this.root.gameWidth, this.root.gameHeight);
+ if (G_IS_DEV && globalConfig.debug.testClipping) {
+ params.visibleRect = params.visibleRect.expandedInAllDirections(-200);
+ }
+
+ // Draw overlays, those are screen space
+ root.hud.drawOverlays(params);
+
+ assert(context.globalAlpha === 1.0, "context.globalAlpha not 1 on frame end");
+
+ if (G_IS_DEV && globalConfig.debug.simulateSlowRendering) {
+ let sum = 0;
+ for (let i = 0; i < 1e8; ++i) {
+ sum += i;
+ }
+ if (Math.random() > 0.95) {
+ console.log(sum);
+ }
+ }
+
+ if (G_IS_DEV && globalConfig.debug.showAtlasInfo) {
+ context.font = "13px GameFont";
+ context.fillStyle = "blue";
+ context.fillText(
+ "Atlas: " +
+ desiredAtlasScale +
+ " / Zoom: " +
+ round2Digits(zoomLevel) +
+ " / Effective Zoom: " +
+ round2Digits(effectiveZoomLevel),
+ 20,
+ 600
+ );
+
+ const stats = this.root.buffers.getStats();
+
+ context.fillText(
+ "Maintained Buffers: " +
+ stats.rootKeys +
+ " root keys / " +
+ stats.subKeys +
+ " buffers / VRAM: " +
+ round2Digits(stats.vramBytes / (1024 * 1024)) +
+ " MB",
+ 20,
+ 620
+ );
+ const internalStats = getBufferStats();
+ context.fillText(
+ "Total Buffers: " +
+ internalStats.bufferCount +
+ " buffers / " +
+ internalStats.backlogSize +
+ " backlog / " +
+ internalStats.backlogKeys +
+ " keys in backlog / VRAM " +
+ round2Digits(internalStats.vramUsage / (1024 * 1024)) +
+ " MB / Backlog " +
+ round2Digits(internalStats.backlogVramUsage / (1024 * 1024)) +
+ " MB / Created " +
+ internalStats.numCreated +
+ " / Reused " +
+ internalStats.numReused,
+ 20,
+ 640
+ );
+ }
+
+ if (G_IS_DEV && globalConfig.debug.testClipping) {
+ context.strokeStyle = "red";
+ context.lineWidth = 1;
+ context.beginPath();
+ context.rect(200, 200, this.root.gameWidth - 400, this.root.gameHeight - 400);
+ context.stroke();
+ }
+ }
+}
diff --git a/src/js/game/dynamic_tickrate.js b/src/js/game/dynamic_tickrate.js
index c76fa2e1..c68a3ec9 100644
--- a/src/js/game/dynamic_tickrate.js
+++ b/src/js/game/dynamic_tickrate.js
@@ -1,129 +1,116 @@
-import { GameRoot } from "./root";
-import { createLogger } from "../core/logging";
-import { globalConfig } from "../core/config";
-
-const logger = createLogger("dynamic_tickrate");
-
-const fpsAccumulationTime = 1000;
-
-export class DynamicTickrate {
- /**
- *
- * @param {GameRoot} root
- */
- constructor(root) {
- this.root = root;
-
- this.currentTickStart = null;
- this.capturedTicks = [];
- this.averageTickDuration = 0;
-
- this.accumulatedFps = 0;
- this.accumulatedFpsLastUpdate = 0;
-
- this.averageFps = 60;
-
- const fixedRate = this.root.gameMode.getFixedTickrate();
- if (fixedRate) {
- logger.log("Setting fixed tickrate of", fixedRate);
- this.setTickRate(fixedRate);
- } else {
- this.setTickRate(this.root.app.settings.getDesiredFps());
-
- if (G_IS_DEV && globalConfig.debug.renderForTrailer) {
- this.setTickRate(300);
- }
- }
- }
-
- onFrameRendered() {
- ++this.accumulatedFps;
-
- const now = performance.now();
- const timeDuration = now - this.accumulatedFpsLastUpdate;
- if (timeDuration > fpsAccumulationTime) {
- const avgFps = (this.accumulatedFps / fpsAccumulationTime) * 1000;
- this.averageFps = avgFps;
- this.accumulatedFps = 0;
- this.accumulatedFpsLastUpdate = now;
- }
- }
-
- /**
- * Sets the tick rate to N updates per second
- * @param {number} rate
- */
- setTickRate(rate) {
- logger.log("Applying tick-rate of", rate);
- this.currentTickRate = rate;
- this.deltaMs = 1000.0 / this.currentTickRate;
- this.deltaSeconds = 1.0 / this.currentTickRate;
- }
-
- /**
- * Increases the tick rate marginally
- */
- increaseTickRate() {
- if (G_IS_DEV && globalConfig.debug.renderForTrailer) {
- return;
- }
-
- const desiredFps = this.root.app.settings.getDesiredFps();
- this.setTickRate(Math.round(Math.min(desiredFps, this.currentTickRate * 1.2)));
- }
-
- /**
- * Decreases the tick rate marginally
- */
- decreaseTickRate() {
- if (G_IS_DEV && globalConfig.debug.renderForTrailer) {
- return;
- }
-
- const desiredFps = this.root.app.settings.getDesiredFps();
- this.setTickRate(Math.round(Math.max(desiredFps / 2, this.currentTickRate * 0.8)));
- }
-
- /**
- * Call whenever a tick began
- */
- beginTick() {
- assert(this.currentTickStart === null, "BeginTick called twice");
- this.currentTickStart = performance.now();
-
- if (this.capturedTicks.length > this.currentTickRate * 2) {
- // Take only a portion of the ticks
- this.capturedTicks.sort();
- this.capturedTicks.splice(0, 10);
- this.capturedTicks.splice(this.capturedTicks.length - 11, 10);
-
- let average = 0;
- for (let i = 0; i < this.capturedTicks.length; ++i) {
- average += this.capturedTicks[i];
- }
- average /= this.capturedTicks.length;
-
- this.averageTickDuration = average;
-
- // Disabled for now: Dynamically adjusting tick rate
- // if (this.averageFps > desiredFps * 0.9) {
- // // if (average < maxTickDuration) {
- // this.increaseTickRate();
- // } else if (this.averageFps < desiredFps * 0.7) {
- // this.decreaseTickRate();
- // }
-
- this.capturedTicks = [];
- }
- }
-
- /**
- * Call whenever a tick ended
- */
- endTick() {
- assert(this.currentTickStart !== null, "EndTick called without BeginTick");
- const duration = performance.now() - this.currentTickStart;
- this.capturedTicks.push(duration);
- this.currentTickStart = null;
- }
-}
+import { createLogger } from "../core/logging";
+import { GameRoot } from "./root";
+
+const logger = createLogger("dynamic_tickrate");
+
+const fpsAccumulationTime = 1000;
+
+export class DynamicTickrate {
+ /**
+ *
+ * @param {GameRoot} root
+ */
+ constructor(root) {
+ this.root = root;
+
+ this.currentTickStart = null;
+ this.capturedTicks = [];
+ this.averageTickDuration = 0;
+
+ this.accumulatedFps = 0;
+ this.accumulatedFpsLastUpdate = 0;
+
+ this.averageFps = 60;
+
+ const fixedRate = this.root.gameMode.getFixedTickrate();
+ if (fixedRate) {
+ logger.log("Setting fixed tickrate of", fixedRate);
+ this.setTickRate(fixedRate);
+ } else {
+ this.setTickRate(this.root.app.settings.getDesiredFps());
+ }
+ }
+
+ onFrameRendered() {
+ ++this.accumulatedFps;
+
+ const now = performance.now();
+ const timeDuration = now - this.accumulatedFpsLastUpdate;
+ if (timeDuration > fpsAccumulationTime) {
+ const avgFps = (this.accumulatedFps / fpsAccumulationTime) * 1000;
+ this.averageFps = avgFps;
+ this.accumulatedFps = 0;
+ this.accumulatedFpsLastUpdate = now;
+ }
+ }
+
+ /**
+ * Sets the tick rate to N updates per second
+ * @param {number} rate
+ */
+ setTickRate(rate) {
+ logger.log("Applying tick-rate of", rate);
+ this.currentTickRate = rate;
+ this.deltaMs = 1000.0 / this.currentTickRate;
+ this.deltaSeconds = 1.0 / this.currentTickRate;
+ }
+
+ /**
+ * Increases the tick rate marginally
+ */
+ increaseTickRate() {
+ const desiredFps = this.root.app.settings.getDesiredFps();
+ this.setTickRate(Math.round(Math.min(desiredFps, this.currentTickRate * 1.2)));
+ }
+
+ /**
+ * Decreases the tick rate marginally
+ */
+ decreaseTickRate() {
+ const desiredFps = this.root.app.settings.getDesiredFps();
+ this.setTickRate(Math.round(Math.max(desiredFps / 2, this.currentTickRate * 0.8)));
+ }
+
+ /**
+ * Call whenever a tick began
+ */
+ beginTick() {
+ assert(this.currentTickStart === null, "BeginTick called twice");
+ this.currentTickStart = performance.now();
+
+ if (this.capturedTicks.length > this.currentTickRate * 2) {
+ // Take only a portion of the ticks
+ this.capturedTicks.sort();
+ this.capturedTicks.splice(0, 10);
+ this.capturedTicks.splice(this.capturedTicks.length - 11, 10);
+
+ let average = 0;
+ for (let i = 0; i < this.capturedTicks.length; ++i) {
+ average += this.capturedTicks[i];
+ }
+ average /= this.capturedTicks.length;
+
+ this.averageTickDuration = average;
+
+ // Disabled for now: Dynamically adjusting tick rate
+ // if (this.averageFps > desiredFps * 0.9) {
+ // // if (average < maxTickDuration) {
+ // this.increaseTickRate();
+ // } else if (this.averageFps < desiredFps * 0.7) {
+ // this.decreaseTickRate();
+ // }
+
+ this.capturedTicks = [];
+ }
+ }
+
+ /**
+ * Call whenever a tick ended
+ */
+ endTick() {
+ assert(this.currentTickStart !== null, "EndTick called without BeginTick");
+ const duration = performance.now() - this.currentTickStart;
+ this.capturedTicks.push(duration);
+ this.currentTickStart = null;
+ }
+}
diff --git a/src/js/game/entity.js b/src/js/game/entity.js
index 9acaf26b..e9373918 100644
--- a/src/js/game/entity.js
+++ b/src/js/game/entity.js
@@ -1,232 +1,232 @@
-/* typehints:start */
-import { DrawParameters } from "../core/draw_parameters";
-import { Component } from "./component";
-/* typehints:end */
-
-import { GameRoot } from "./root";
-import { globalConfig } from "../core/config";
-import { enumDirectionToVector, enumDirectionToAngle } from "../core/vector";
-import { BasicSerializableObject, types } from "../savegame/serialization";
-import { EntityComponentStorage } from "./entity_components";
-import { Loader } from "../core/loader";
-import { drawRotatedSprite } from "../core/draw_utils";
-import { gComponentRegistry } from "../core/global_registries";
-import { getBuildingDataFromCode } from "./building_codes";
-
-export class Entity extends BasicSerializableObject {
- /**
- * @param {GameRoot} root
- */
- constructor(root) {
- super();
-
- /**
- * Handle to the global game root
- */
- this.root = root;
-
- /**
- * The components of the entity
- */
- this.components = new EntityComponentStorage();
-
- /**
- * Whether this entity was registered on the @see EntityManager so far
- */
- this.registered = false;
-
- /**
- * On which layer this entity is
- * @type {Layer}
- */
- this.layer = "regular";
-
- /**
- * Internal entity unique id, set by the @see EntityManager
- */
- this.uid = 0;
-
- /* typehints:start */
-
- /**
- * Stores if this entity is destroyed, set by the @see EntityManager
- * @type {boolean} */
- this.destroyed;
-
- /**
- * Stores if this entity is queued to get destroyed in the next tick
- * of the @see EntityManager
- * @type {boolean} */
- this.queuedForDestroy;
-
- /**
- * Stores the reason why this entity was destroyed
- * @type {string} */
- this.destroyReason;
-
- /* typehints:end */
- }
-
- static getId() {
- return "Entity";
- }
-
- /**
- * @see BasicSerializableObject.getSchema
- * @returns {import("../savegame/serialization").Schema}
- */
- static getSchema() {
- return {
- uid: types.uint,
- components: types.keyValueMap(types.objData(gComponentRegistry), false),
- };
- }
-
- /**
- * Returns a clone of this entity
- */
- clone() {
- const staticComp = this.components.StaticMapEntity;
- const buildingData = getBuildingDataFromCode(staticComp.code);
-
- const clone = buildingData.metaInstance.createEntity({
- root: this.root,
- origin: staticComp.origin,
- originalRotation: staticComp.originalRotation,
- rotation: staticComp.rotation,
- rotationVariant: buildingData.rotationVariant,
- variant: buildingData.variant,
- });
-
- for (const key in this.components) {
- /** @type {Component} */ (this.components[key]).copyAdditionalStateTo(clone.components[key]);
- }
-
- return clone;
- }
-
- /**
- * Adds a new component, only possible until the entity is registered on the entity manager,
- * after that use @see EntityManager.addDynamicComponent
- * @param {Component} componentInstance
- * @param {boolean} force Used by the entity manager. Internal parameter, do not change
- */
- addComponent(componentInstance, force = false) {
- if (!force && this.registered) {
- this.root.entityMgr.attachDynamicComponent(this, componentInstance);
- return;
- }
- assert(force || !this.registered, "Entity already registered, use EntityManager.addDynamicComponent");
- const id = /** @type {typeof Component} */ (componentInstance.constructor).getId();
- assert(!this.components[id], "Component already present");
- this.components[id] = componentInstance;
- }
-
- /**
- * Removes a given component, only possible until the entity is registered on the entity manager,
- * after that use @see EntityManager.removeDynamicComponent
- * @param {typeof Component} componentClass
- * @param {boolean} force
- */
- removeComponent(componentClass, force = false) {
- if (!force && this.registered) {
- this.root.entityMgr.removeDynamicComponent(this, componentClass);
- return;
- }
- assert(
- force || !this.registered,
- "Entity already registered, use EntityManager.removeDynamicComponent"
- );
- const id = componentClass.getId();
- assert(this.components[id], "Component does not exist on entity");
- delete this.components[id];
- }
-
- /**
- * Draws the entity, to override use @see Entity.drawImpl
- * @param {DrawParameters} parameters
- */
- drawDebugOverlays(parameters) {
- const context = parameters.context;
- const staticComp = this.components.StaticMapEntity;
-
- if (G_IS_DEV && staticComp && globalConfig.debug.showEntityBounds) {
- if (staticComp) {
- const transformed = staticComp.getTileSpaceBounds();
- context.strokeStyle = "rgba(255, 0, 0, 0.5)";
- context.lineWidth = 2;
- // const boundsSize = 20;
- context.beginPath();
- context.rect(
- transformed.x * globalConfig.tileSize,
- transformed.y * globalConfig.tileSize,
- transformed.w * globalConfig.tileSize,
- transformed.h * globalConfig.tileSize
- );
- context.stroke();
- }
- }
-
- if (G_IS_DEV && staticComp && globalConfig.debug.showAcceptorEjectors) {
- const ejectorComp = this.components.ItemEjector;
-
- if (ejectorComp) {
- const ejectorSprite = Loader.getSprite("sprites/debug/ejector_slot.png");
- for (let i = 0; i < ejectorComp.slots.length; ++i) {
- const slot = ejectorComp.slots[i];
- const slotTile = staticComp.localTileToWorld(slot.pos);
- const direction = staticComp.localDirectionToWorld(slot.direction);
- const directionVector = enumDirectionToVector[direction];
- const angle = Math.radians(enumDirectionToAngle[direction]);
-
- context.globalAlpha = slot.item ? 1 : 0.2;
- drawRotatedSprite({
- parameters,
- sprite: ejectorSprite,
- x: (slotTile.x + 0.5 + directionVector.x * 0.37) * globalConfig.tileSize,
- y: (slotTile.y + 0.5 + directionVector.y * 0.37) * globalConfig.tileSize,
- angle,
- size: globalConfig.tileSize * 0.25,
- });
- }
- }
- const acceptorComp = this.components.ItemAcceptor;
-
- if (acceptorComp) {
- const acceptorSprite = Loader.getSprite("sprites/misc/acceptor_slot.png");
- for (let i = 0; i < acceptorComp.slots.length; ++i) {
- const slot = acceptorComp.slots[i];
- const slotTile = staticComp.localTileToWorld(slot.pos);
- const direction = staticComp.localDirectionToWorld(slot.direction);
- const directionVector = enumDirectionToVector[direction];
- const angle = Math.radians(enumDirectionToAngle[direction] + 180);
- context.globalAlpha = 0.4;
- drawRotatedSprite({
- parameters,
- sprite: acceptorSprite,
- x: (slotTile.x + 0.5 + directionVector.x * 0.37) * globalConfig.tileSize,
- y: (slotTile.y + 0.5 + directionVector.y * 0.37) * globalConfig.tileSize,
- angle,
- size: globalConfig.tileSize * 0.25,
- });
- }
- }
-
- context.globalAlpha = 1;
- }
- // this.drawImpl(parameters);
- }
-
- ///// Helper interfaces
-
- ///// Interface to override by subclasses
-
- /**
- * override, should draw the entity
- * @param {DrawParameters} parameters
- * @abstract
- */
- drawImpl(parameters) {
- abstract;
- }
-}
+/* typehints:start */
+import { DrawParameters } from "../core/draw_parameters";
+import { Component } from "./component";
+/* typehints:end */
+
+import { GameRoot } from "./root";
+import { globalConfig } from "../core/config";
+import { enumDirectionToVector, enumDirectionToAngle } from "../core/vector";
+import { BasicSerializableObject, types } from "../savegame/serialization";
+import { Loader } from "../core/loader";
+import { drawRotatedSprite } from "../core/draw_utils";
+import { gComponentRegistry } from "../core/global_registries";
+import { getBuildingDataFromCode } from "./building_codes";
+
+export class Entity extends BasicSerializableObject {
+ /**
+ * @param {GameRoot} root
+ */
+ constructor(root) {
+ super();
+
+ /**
+ * Handle to the global game root
+ */
+ this.root = root;
+
+ /**
+ * The components of the entity
+ * @type {import("./entity_components").EntityComponentStorage}
+ */
+ this.components = {};
+
+ /**
+ * Whether this entity was registered on the @see EntityManager so far
+ */
+ this.registered = false;
+
+ /**
+ * On which layer this entity is
+ * @type {Layer}
+ */
+ this.layer = "regular";
+
+ /**
+ * Internal entity unique id, set by the @see EntityManager
+ */
+ this.uid = 0;
+
+ /* typehints:start */
+
+ /**
+ * Stores if this entity is destroyed, set by the @see EntityManager
+ * @type {boolean} */
+ this.destroyed;
+
+ /**
+ * Stores if this entity is queued to get destroyed in the next tick
+ * of the @see EntityManager
+ * @type {boolean} */
+ this.queuedForDestroy;
+
+ /**
+ * Stores the reason why this entity was destroyed
+ * @type {string} */
+ this.destroyReason;
+
+ /* typehints:end */
+ }
+
+ static getId() {
+ return "Entity";
+ }
+
+ /**
+ * @see BasicSerializableObject.getSchema
+ * @returns {import("../savegame/serialization").Schema}
+ */
+ static getSchema() {
+ return {
+ uid: types.uint,
+ components: types.keyValueMap(types.objData(gComponentRegistry), false),
+ };
+ }
+
+ /**
+ * Returns a clone of this entity
+ */
+ clone() {
+ const staticComp = this.components.StaticMapEntity;
+ const buildingData = getBuildingDataFromCode(staticComp.code);
+
+ const clone = buildingData.metaInstance.createEntity({
+ root: this.root,
+ origin: staticComp.origin,
+ originalRotation: staticComp.originalRotation,
+ rotation: staticComp.rotation,
+ rotationVariant: buildingData.rotationVariant,
+ variant: buildingData.variant,
+ });
+
+ for (const key in this.components) {
+ this.components[key].copyAdditionalStateTo(clone.components[key]);
+ }
+
+ return clone;
+ }
+
+ /**
+ * Adds a new component, only possible until the entity is registered on the entity manager,
+ * after that use @see EntityManager.addDynamicComponent
+ * @param {Component} componentInstance
+ * @param {boolean} force Used by the entity manager. Internal parameter, do not change
+ */
+ addComponent(componentInstance, force = false) {
+ if (!force && this.registered) {
+ this.root.entityMgr.attachDynamicComponent(this, componentInstance);
+ return;
+ }
+ assert(force || !this.registered, "Entity already registered, use EntityManager.addDynamicComponent");
+ const id = /** @type {typeof Component} */ (componentInstance.constructor).getId();
+ assert(!this.components[id], "Component already present");
+ this.components[id] = componentInstance;
+ }
+
+ /**
+ * Removes a given component, only possible until the entity is registered on the entity manager,
+ * after that use @see EntityManager.removeDynamicComponent
+ * @param {typeof Component} componentClass
+ * @param {boolean} force
+ */
+ removeComponent(componentClass, force = false) {
+ if (!force && this.registered) {
+ this.root.entityMgr.removeDynamicComponent(this, componentClass);
+ return;
+ }
+ assert(
+ force || !this.registered,
+ "Entity already registered, use EntityManager.removeDynamicComponent"
+ );
+ const id = componentClass.getId();
+ assert(this.components[id], "Component does not exist on entity");
+ delete this.components[id];
+ }
+
+ /**
+ * Draws the entity, to override use @see Entity.drawImpl
+ * @param {DrawParameters} parameters
+ */
+ drawDebugOverlays(parameters) {
+ const context = parameters.context;
+ const staticComp = this.components.StaticMapEntity;
+
+ if (G_IS_DEV && staticComp && globalConfig.debug.showEntityBounds) {
+ if (staticComp) {
+ const transformed = staticComp.getTileSpaceBounds();
+ context.strokeStyle = "rgba(255, 0, 0, 0.5)";
+ context.lineWidth = 2;
+ // const boundsSize = 20;
+ context.beginPath();
+ context.rect(
+ transformed.x * globalConfig.tileSize,
+ transformed.y * globalConfig.tileSize,
+ transformed.w * globalConfig.tileSize,
+ transformed.h * globalConfig.tileSize
+ );
+ context.stroke();
+ }
+ }
+
+ if (G_IS_DEV && staticComp && globalConfig.debug.showAcceptorEjectors) {
+ const ejectorComp = this.components.ItemEjector;
+
+ if (ejectorComp) {
+ const ejectorSprite = Loader.getSprite("sprites/debug/ejector_slot.png");
+ for (let i = 0; i < ejectorComp.slots.length; ++i) {
+ const slot = ejectorComp.slots[i];
+ const slotTile = staticComp.localTileToWorld(slot.pos);
+ const direction = staticComp.localDirectionToWorld(slot.direction);
+ const directionVector = enumDirectionToVector[direction];
+ const angle = Math.radians(enumDirectionToAngle[direction]);
+
+ context.globalAlpha = slot.item ? 1 : 0.2;
+ drawRotatedSprite({
+ parameters,
+ sprite: ejectorSprite,
+ x: (slotTile.x + 0.5 + directionVector.x * 0.37) * globalConfig.tileSize,
+ y: (slotTile.y + 0.5 + directionVector.y * 0.37) * globalConfig.tileSize,
+ angle,
+ size: globalConfig.tileSize * 0.25,
+ });
+ }
+ }
+ const acceptorComp = this.components.ItemAcceptor;
+
+ if (acceptorComp) {
+ const acceptorSprite = Loader.getSprite("sprites/misc/acceptor_slot.png");
+ for (let i = 0; i < acceptorComp.slots.length; ++i) {
+ const slot = acceptorComp.slots[i];
+ const slotTile = staticComp.localTileToWorld(slot.pos);
+ const direction = staticComp.localDirectionToWorld(slot.direction);
+ const directionVector = enumDirectionToVector[direction];
+ const angle = Math.radians(enumDirectionToAngle[direction] + 180);
+ context.globalAlpha = 0.4;
+ drawRotatedSprite({
+ parameters,
+ sprite: acceptorSprite,
+ x: (slotTile.x + 0.5 + directionVector.x * 0.37) * globalConfig.tileSize,
+ y: (slotTile.y + 0.5 + directionVector.y * 0.37) * globalConfig.tileSize,
+ angle,
+ size: globalConfig.tileSize * 0.25,
+ });
+ }
+ }
+
+ context.globalAlpha = 1;
+ }
+ // this.drawImpl(parameters);
+ }
+
+ ///// Helper interfaces
+
+ ///// Interface to override by subclasses
+
+ /**
+ * override, should draw the entity
+ * @param {DrawParameters} parameters
+ * @abstract
+ */
+ drawImpl(parameters) {
+ abstract;
+ }
+}
diff --git a/src/js/game/entity_components.js b/src/js/game/entity_components.js
deleted file mode 100644
index 163be9f9..00000000
--- a/src/js/game/entity_components.js
+++ /dev/null
@@ -1,98 +0,0 @@
-/* typehints:start */
-import { BeltComponent } from "./components/belt";
-import { BeltUnderlaysComponent } from "./components/belt_underlays";
-import { HubComponent } from "./components/hub";
-import { ItemAcceptorComponent } from "./components/item_acceptor";
-import { ItemEjectorComponent } from "./components/item_ejector";
-import { ItemProcessorComponent } from "./components/item_processor";
-import { MinerComponent } from "./components/miner";
-import { StaticMapEntityComponent } from "./components/static_map_entity";
-import { StorageComponent } from "./components/storage";
-import { UndergroundBeltComponent } from "./components/underground_belt";
-import { WiredPinsComponent } from "./components/wired_pins";
-import { WireComponent } from "./components/wire";
-import { ConstantSignalComponent } from "./components/constant_signal";
-import { LogicGateComponent } from "./components/logic_gate";
-import { LeverComponent } from "./components/lever";
-import { WireTunnelComponent } from "./components/wire_tunnel";
-import { DisplayComponent } from "./components/display";
-import { BeltReaderComponent } from "./components/belt_reader";
-import { FilterComponent } from "./components/filter";
-import { ItemProducerComponent } from "./components/item_producer";
-import { GoalAcceptorComponent } from "./components/goal_acceptor";
-/* typehints:end */
-
-/**
- * Typedefs for all entity components. These are not actually present on the entity,
- * thus they are undefined by default
- */
-export class EntityComponentStorage {
- constructor() {
- /* typehints:start */
-
- /** @type {StaticMapEntityComponent} */
- this.StaticMapEntity;
-
- /** @type {BeltComponent} */
- this.Belt;
-
- /** @type {ItemEjectorComponent} */
- this.ItemEjector;
-
- /** @type {ItemAcceptorComponent} */
- this.ItemAcceptor;
-
- /** @type {MinerComponent} */
- this.Miner;
-
- /** @type {ItemProcessorComponent} */
- this.ItemProcessor;
-
- /** @type {UndergroundBeltComponent} */
- this.UndergroundBelt;
-
- /** @type {HubComponent} */
- this.Hub;
-
- /** @type {StorageComponent} */
- this.Storage;
-
- /** @type {WiredPinsComponent} */
- this.WiredPins;
-
- /** @type {BeltUnderlaysComponent} */
- this.BeltUnderlays;
-
- /** @type {WireComponent} */
- this.Wire;
-
- /** @type {ConstantSignalComponent} */
- this.ConstantSignal;
-
- /** @type {LogicGateComponent} */
- this.LogicGate;
-
- /** @type {LeverComponent} */
- this.Lever;
-
- /** @type {WireTunnelComponent} */
- this.WireTunnel;
-
- /** @type {DisplayComponent} */
- this.Display;
-
- /** @type {BeltReaderComponent} */
- this.BeltReader;
-
- /** @type {FilterComponent} */
- this.Filter;
-
- /** @type {ItemProducerComponent} */
- this.ItemProducer;
-
- /** @type {GoalAcceptorComponent} */
- this.GoalAcceptor;
-
- /* typehints:end */
- }
-}
diff --git a/src/js/game/entity_components.ts b/src/js/game/entity_components.ts
new file mode 100644
index 00000000..e057dcf4
--- /dev/null
+++ b/src/js/game/entity_components.ts
@@ -0,0 +1,51 @@
+import type { BeltComponent } from "./components/belt";
+import type { BeltUnderlaysComponent } from "./components/belt_underlays";
+import type { HubComponent } from "./components/hub";
+import type { ItemAcceptorComponent } from "./components/item_acceptor";
+import type { ItemEjectorComponent } from "./components/item_ejector";
+import type { ItemProcessorComponent } from "./components/item_processor";
+import type { MinerComponent } from "./components/miner";
+import type { StaticMapEntityComponent } from "./components/static_map_entity";
+import type { StorageComponent } from "./components/storage";
+import type { UndergroundBeltComponent } from "./components/underground_belt";
+import type { WiredPinsComponent } from "./components/wired_pins";
+import type { WireComponent } from "./components/wire";
+import type { ConstantSignalComponent } from "./components/constant_signal";
+import type { LogicGateComponent } from "./components/logic_gate";
+import type { LeverComponent } from "./components/lever";
+import type { WireTunnelComponent } from "./components/wire_tunnel";
+import type { DisplayComponent } from "./components/display";
+import type { BeltReaderComponent } from "./components/belt_reader";
+import type { FilterComponent } from "./components/filter";
+import type { ItemProducerComponent } from "./components/item_producer";
+import type { GoalAcceptorComponent } from "./components/goal_acceptor";
+import type { Component } from "./component";
+
+/**
+ * Typedefs for all entity components.
+ */
+export interface EntityComponentStorage {
+ StaticMapEntity?: StaticMapEntityComponent;
+ Belt?: BeltComponent;
+ ItemEjector?: ItemEjectorComponent;
+ ItemAcceptor?: ItemAcceptorComponent;
+ Miner?: MinerComponent;
+ ItemProcessor?: ItemProcessorComponent;
+ UndergroundBelt?: UndergroundBeltComponent;
+ Hub?: HubComponent;
+ Storage?: StorageComponent;
+ WiredPins?: WiredPinsComponent;
+ BeltUnderlays?: BeltUnderlaysComponent;
+ Wire?: WireComponent;
+ ConstantSignal?: ConstantSignalComponent;
+ LogicGate?: LogicGateComponent;
+ Lever?: LeverComponent;
+ WireTunnel?: WireTunnelComponent;
+ Display?: DisplayComponent;
+ BeltReader?: BeltReaderComponent;
+ Filter?: FilterComponent;
+ ItemProducer?: ItemProducerComponent;
+ GoalAcceptor?: GoalAcceptorComponent;
+
+ [k: string]: Component;
+}
diff --git a/src/js/game/entity_manager.js b/src/js/game/entity_manager.ts
similarity index 50%
rename from src/js/game/entity_manager.js
rename to src/js/game/entity_manager.ts
index b4101fc8..756f5bce 100644
--- a/src/js/game/entity_manager.js
+++ b/src/js/game/entity_manager.ts
@@ -1,241 +1,218 @@
-import { arrayDeleteValue, newEmptyMap, fastArrayDeleteValue } from "../core/utils";
-import { Component } from "./component";
-import { GameRoot } from "./root";
-import { Entity } from "./entity";
-import { BasicSerializableObject, types } from "../savegame/serialization";
-import { createLogger } from "../core/logging";
-import { globalConfig } from "../core/config";
-
-const logger = createLogger("entity_manager");
-
-// Manages all entities
-
-// NOTICE: We use arrayDeleteValue instead of fastArrayDeleteValue since that does not preserve the order
-// This is slower but we need it for the street path generation
-
-export class EntityManager extends BasicSerializableObject {
- constructor(root) {
- super();
-
- /** @type {GameRoot} */
- this.root = root;
-
- /** @type {Array} */
- this.entities = [];
-
- // We store a separate list with entities to destroy, since we don't destroy
- // them instantly
- /** @type {Array} */
- this.destroyList = [];
-
- // Store a map from componentid to entities - This is used by the game system
- // for faster processing
- /** @type {Object.>} */
- this.componentToEntity = newEmptyMap();
-
- // Store the next uid to use
- this.nextUid = 10000;
- }
-
- static getId() {
- return "EntityManager";
- }
-
- static getSchema() {
- return {
- nextUid: types.uint,
- };
- }
-
- getStatsText() {
- return this.entities.length + " entities [" + this.destroyList.length + " to kill]";
- }
-
- // Main update
- update() {
- this.processDestroyList();
- }
-
- /**
- * Registers a new entity
- * @param {Entity} entity
- * @param {number=} uid Optional predefined uid
- */
- registerEntity(entity, uid = null) {
- if (G_IS_DEV && !globalConfig.debug.disableSlowAsserts) {
- assert(this.entities.indexOf(entity) < 0, `RegisterEntity() called twice for entity ${entity}`);
- }
- assert(!entity.destroyed, `Attempting to register destroyed entity ${entity}`);
-
- if (G_IS_DEV && !globalConfig.debug.disableSlowAsserts && uid !== null) {
- assert(!this.findByUid(uid, false), "Entity uid already taken: " + uid);
- assert(uid >= 0 && uid < Number.MAX_SAFE_INTEGER, "Invalid uid passed: " + uid);
- }
-
- this.entities.push(entity);
-
- // Register into the componentToEntity map
- for (const componentId in entity.components) {
- if (entity.components[componentId]) {
- if (this.componentToEntity[componentId]) {
- this.componentToEntity[componentId].push(entity);
- } else {
- this.componentToEntity[componentId] = [entity];
- }
- }
- }
-
- // Give each entity a unique id
- entity.uid = uid ? uid : this.generateUid();
- entity.registered = true;
-
- this.root.signals.entityAdded.dispatch(entity);
- }
-
- /**
- * Generates a new uid
- * @returns {number}
- */
- generateUid() {
- return this.nextUid++;
- }
-
- /**
- * Call to attach a new component after the creation of the entity
- * @param {Entity} entity
- * @param {Component} component
- */
- attachDynamicComponent(entity, component) {
- entity.addComponent(component, true);
- const componentId = /** @type {typeof Component} */ (component.constructor).getId();
- if (this.componentToEntity[componentId]) {
- this.componentToEntity[componentId].push(entity);
- } else {
- this.componentToEntity[componentId] = [entity];
- }
- this.root.signals.entityGotNewComponent.dispatch(entity);
- }
-
- /**
- * Call to remove a component after the creation of the entity
- * @param {Entity} entity
- * @param {typeof Component} component
- */
- removeDynamicComponent(entity, component) {
- entity.removeComponent(component, true);
- const componentId = /** @type {typeof Component} */ (component.constructor).getId();
-
- fastArrayDeleteValue(this.componentToEntity[componentId], entity);
- this.root.signals.entityComponentRemoved.dispatch(entity);
- }
-
- /**
- * Finds an entity buy its uid, kinda slow since it loops over all entities
- * @param {number} uid
- * @param {boolean=} errorWhenNotFound
- * @returns {Entity}
- */
- findByUid(uid, errorWhenNotFound = true) {
- const arr = this.entities;
- for (let i = 0, len = arr.length; i < len; ++i) {
- const entity = arr[i];
- if (entity.uid === uid) {
- if (entity.queuedForDestroy || entity.destroyed) {
- if (errorWhenNotFound) {
- logger.warn("Entity with UID", uid, "not found (destroyed)");
- }
- return null;
- }
- return entity;
- }
- }
- if (errorWhenNotFound) {
- logger.warn("Entity with UID", uid, "not found");
- }
- return null;
- }
-
- /**
- * Returns a map which gives a mapping from UID to Entity.
- * This map is not updated.
- *
- * @returns {Map}
- */
- getFrozenUidSearchMap() {
- const result = new Map();
- const array = this.entities;
- for (let i = 0, len = array.length; i < len; ++i) {
- const entity = array[i];
- if (!entity.queuedForDestroy && !entity.destroyed) {
- result.set(entity.uid, entity);
- }
- }
- return result;
- }
-
- /**
- * Returns all entities having the given component
- * @param {typeof Component} componentHandle
- * @returns {Array} entities
- */
- getAllWithComponent(componentHandle) {
- return this.componentToEntity[componentHandle.getId()] || [];
- }
-
- /**
- * Unregisters all components of an entity from the component to entity mapping
- * @param {Entity} entity
- */
- unregisterEntityComponents(entity) {
- for (const componentId in entity.components) {
- if (entity.components[componentId]) {
- arrayDeleteValue(this.componentToEntity[componentId], entity);
- }
- }
- }
-
- // Processes the entities to destroy and actually destroys them
- /* eslint-disable max-statements */
- processDestroyList() {
- for (let i = 0; i < this.destroyList.length; ++i) {
- const entity = this.destroyList[i];
-
- // Remove from entities list
- arrayDeleteValue(this.entities, entity);
-
- // Remove from componentToEntity list
- this.unregisterEntityComponents(entity);
-
- entity.registered = false;
- entity.destroyed = true;
-
- this.root.signals.entityDestroyed.dispatch(entity);
- }
-
- this.destroyList = [];
- }
-
- /**
- * Queues an entity for destruction
- * @param {Entity} entity
- */
- destroyEntity(entity) {
- if (entity.destroyed) {
- logger.error("Tried to destroy already destroyed entity:", entity.uid);
- return;
- }
-
- if (entity.queuedForDestroy) {
- logger.error("Trying to destroy entity which is already queued for destroy!", entity.uid);
- return;
- }
-
- if (this.destroyList.indexOf(entity) < 0) {
- this.destroyList.push(entity);
- entity.queuedForDestroy = true;
- this.root.signals.entityQueuedForDestroy.dispatch(entity);
- } else {
- assert(false, "Trying to destroy entity twice");
- }
- }
-}
+import { globalConfig } from "../core/config";
+import { createLogger } from "../core/logging";
+import { newEmptyMap } from "../core/utils";
+import { BasicSerializableObject, types } from "../savegame/serialization";
+import { Component } from "./component";
+import { Entity } from "./entity";
+import { GameRoot } from "./root";
+
+const logger = createLogger("entity_manager");
+
+// Manages all entities
+
+// NOTICE: We use arrayDeleteValue instead of fastArrayDeleteValue since that does not preserve the order
+// This is slower but we need it for the street path generation
+
+export class EntityManager extends BasicSerializableObject {
+ readonly root: GameRoot;
+ readonly entities = new Map();
+
+ // We store a separate list with entities to destroy, since we don't destroy
+ // them instantly
+ private destroyList: Entity[] = [];
+
+ // Store a map from componentid to entities - This is used by the game system
+ // for faster processing
+ private readonly componentToEntity: Record> = newEmptyMap();
+
+ // Store the next uid to use
+ private nextUid = 10000;
+
+ constructor(root: GameRoot) {
+ super();
+ this.root = root;
+ }
+
+ static getId() {
+ return "EntityManager";
+ }
+
+ static getSchema() {
+ return {
+ nextUid: types.uint,
+ };
+ }
+
+ getStatsText() {
+ return this.entities.size + " entities [" + this.destroyList.length + " to kill]";
+ }
+
+ // Main update
+ update() {
+ this.processDestroyList();
+ }
+
+ /**
+ * Registers a new entity
+ * @param uid Optional predefined uid
+ */
+ registerEntity(entity: Entity, uid = this.generateUid()) {
+ if (G_IS_DEV && !globalConfig.debug.disableSlowAsserts) {
+ assert(
+ this.entities.get(entity.uid) !== entity,
+ `RegisterEntity() called twice for entity ${entity}`
+ );
+ }
+ assert(!entity.destroyed, `Attempting to register destroyed entity ${entity}`);
+
+ if (G_IS_DEV && !globalConfig.debug.disableSlowAsserts) {
+ assert(!this.findByUid(uid, false), "Entity uid already taken: " + uid);
+ assert(uid >= 0 && uid < Number.MAX_SAFE_INTEGER, "Invalid uid passed: " + uid);
+ }
+
+ // Give each entity a unique id
+ entity.uid = uid;
+ entity.registered = true;
+
+ this.entities.set(entity.uid, entity);
+
+ // Register into the componentToEntity map
+ for (const componentId in entity.components) {
+ if (entity.components[componentId]) {
+ const set = (this.componentToEntity[componentId] ??= new Set());
+ set.add(entity);
+ }
+ }
+
+ this.root.signals.entityAdded.dispatch(entity);
+ }
+
+ /**
+ * Generates a new uid
+ */
+ generateUid(): number {
+ return this.nextUid++;
+ }
+
+ /**
+ * Call to attach a new component after the creation of the entity
+ */
+ attachDynamicComponent(entity: Entity, component: Component) {
+ entity.addComponent(component, true);
+ const componentId = /** @type {typeof Component} */ component.constructor.getId();
+ const set = (this.componentToEntity[componentId] ??= new Set());
+ set.add(entity);
+ this.root.signals.entityGotNewComponent.dispatch(entity);
+ }
+
+ /**
+ * Call to remove a component after the creation of the entity
+ */
+ removeDynamicComponent(entity: Entity, component: typeof Component) {
+ entity.removeComponent(component, true);
+ const componentId = /** @type {typeof Component} */ component.constructor.getId();
+
+ this.componentToEntity[componentId].delete(entity);
+ this.root.signals.entityComponentRemoved.dispatch(entity);
+ }
+
+ /**
+ * Finds an entity by its uid
+ */
+ findByUid(uid: number, errorWhenNotFound = true): Entity {
+ const entity = this.entities.get(uid);
+
+ if (entity === undefined || entity.queuedForDestroy || entity.destroyed) {
+ if (errorWhenNotFound) {
+ logger.warn("Entity with UID", uid, "not found (destroyed)");
+ }
+
+ return null;
+ }
+
+ return entity;
+ }
+
+ /**
+ * Returns a map which gives a mapping from UID to Entity.
+ * This map is not updated.
+ */
+ getFrozenUidSearchMap(): Map {
+ const result = new Map();
+ for (const [uid, entity] of this.entities) {
+ if (!entity.queuedForDestroy && !entity.destroyed) {
+ result.set(uid, entity);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Returns all entities having the given component
+ * @deprecated use {@link getEntitiesWithComponent} instead
+ */
+ getAllWithComponent(componentHandle: typeof Component): Entity[] {
+ return [...(this.componentToEntity[componentHandle.getId()] ?? new Set())];
+ }
+
+ /**
+ * A version of {@link getAllWithComponent} that returns a Set
+ */
+ getEntitiesWithComponent(componentHandle: typeof Component): Set {
+ return new Set(this.componentToEntity[componentHandle.getId()] ?? []);
+ }
+
+ /**
+ * Unregisters all components of an entity from the component to entity mapping
+ */
+ unregisterEntityComponents(entity: Entity) {
+ for (const componentId in entity.components) {
+ if (entity.components[componentId]) {
+ this.componentToEntity[componentId].delete(entity);
+ }
+ }
+ }
+
+ // Processes the entities to destroy and actually destroys them
+ processDestroyList() {
+ for (let i = 0; i < this.destroyList.length; ++i) {
+ const entity = this.destroyList[i];
+
+ // Remove from entities list
+ this.entities.delete(entity.uid);
+
+ // Remove from componentToEntity list
+ this.unregisterEntityComponents(entity);
+
+ entity.registered = false;
+ entity.destroyed = true;
+
+ this.root.signals.entityDestroyed.dispatch(entity);
+ }
+
+ this.destroyList = [];
+ }
+
+ /**
+ * Queues an entity for destruction
+ */
+ destroyEntity(entity: Entity) {
+ if (entity.destroyed) {
+ logger.error("Tried to destroy already destroyed entity:", entity.uid);
+ return;
+ }
+
+ if (entity.queuedForDestroy) {
+ logger.error("Trying to destroy entity which is already queued for destroy!", entity.uid);
+ return;
+ }
+
+ if (this.destroyList.indexOf(entity) < 0) {
+ this.destroyList.push(entity);
+ entity.queuedForDestroy = true;
+ this.root.signals.entityQueuedForDestroy.dispatch(entity);
+ } else {
+ assert(false, "Trying to destroy entity twice");
+ }
+ }
+}
diff --git a/src/js/game/game_mode.js b/src/js/game/game_mode.js
index 2c4527e3..a49d94f3 100644
--- a/src/js/game/game_mode.js
+++ b/src/js/game/game_mode.js
@@ -1,198 +1,193 @@
-/* typehints:start */
-import { GameRoot } from "./root";
-/* typehints:end */
-
-import { Rectangle } from "../core/rectangle";
-import { gGameModeRegistry } from "../core/global_registries";
-import { types, BasicSerializableObject } from "../savegame/serialization";
-import { MetaBuilding } from "./meta_building";
-import { MetaItemProducerBuilding } from "./buildings/item_producer";
-import { BaseHUDPart } from "./hud/base_hud_part";
-
-/** @enum {string} */
-export const enumGameModeIds = {
- puzzleEdit: "puzzleEditMode",
- puzzlePlay: "puzzlePlayMode",
- regular: "regularMode",
-};
-
-/** @enum {string} */
-export const enumGameModeTypes = {
- default: "defaultModeType",
- puzzle: "puzzleModeType",
-};
-
-export class GameMode extends BasicSerializableObject {
- /** @returns {string} */
- static getId() {
- abstract;
- return "unknownMode";
- }
-
- /** @returns {string} */
- static getType() {
- abstract;
- return "unknownType";
- }
- /**
- * @param {GameRoot} root
- * @param {string} [id=Regular]
- * @param {object|undefined} payload
- */
- static create(root, id = enumGameModeIds.regular, payload = undefined) {
- return new (gGameModeRegistry.findById(id))(root, payload);
- }
-
- /**
- * @param {GameRoot} root
- */
- constructor(root) {
- super();
- this.root = root;
-
- /**
- * @type {Record}
- */
- this.additionalHudParts = {};
-
- /** @type {typeof MetaBuilding[]} */
- this.hiddenBuildings = [MetaItemProducerBuilding];
- }
-
- /** @returns {object} */
- serialize() {
- return {
- $: this.getId(),
- data: super.serialize(),
- };
- }
-
- /** @param {object} savedata */
- deserialize({ data }) {
- super.deserialize(data, this.root);
- }
-
- /** @returns {string} */
- getId() {
- // @ts-ignore
- return this.constructor.getId();
- }
-
- /** @returns {string} */
- getType() {
- // @ts-ignore
- return this.constructor.getType();
- }
-
- /**
- * @param {typeof MetaBuilding} building - Class name of building
- * @returns {boolean}
- */
- isBuildingExcluded(building) {
- return this.hiddenBuildings.indexOf(building) >= 0;
- }
-
- /** @returns {undefined|Rectangle[]} */
- getBuildableZones() {
- return;
- }
-
- /** @returns {Rectangle|undefined} */
- getCameraBounds() {
- return;
- }
-
- /** @returns {boolean} */
- hasHub() {
- return true;
- }
-
- /** @returns {boolean} */
- hasResources() {
- return true;
- }
-
- /** @returns {boolean} */
- hasAchievements() {
- return false;
- }
-
- /** @returns {number} */
- getMinimumZoom() {
- return 0.06;
- }
-
- /** @returns {number} */
- getMaximumZoom() {
- return 3.5;
- }
-
- /** @returns {Object} */
- getUpgrades() {
- return {
- belt: [],
- miner: [],
- processors: [],
- painting: [],
- };
- }
-
- throughputDoesNotMatter() {
- return false;
- }
-
- /**
- * @param {number} w
- * @param {number} h
- * @abstract
- */
- adjustZone(w = 0, h = 0) {
- abstract;
- return;
- }
-
- /** @returns {array} */
- getLevelDefinitions() {
- return [];
- }
-
- /** @returns {boolean} */
- getIsFreeplayAvailable() {
- return false;
- }
-
- /** @returns {boolean} */
- getIsSaveable() {
- return true;
- }
-
- /** @returns {boolean} */
- getHasFreeCopyPaste() {
- return false;
- }
-
- /** @returns {boolean} */
- getSupportsWires() {
- return true;
- }
-
- /** @returns {boolean} */
- getIsEditor() {
- return false;
- }
-
- /** @returns {boolean} */
- getIsDeterministic() {
- return false;
- }
-
- /** @returns {number | undefined} */
- getFixedTickrate() {
- return;
- }
-
- /** @returns {string} */
- getBlueprintShapeKey() {
- return "CbCbCbRb:CwCwCwCw";
- }
-}
+/* typehints:start */
+import { GameRoot } from "./root";
+/* typehints:end */
+
+import { gGameModeRegistry } from "../core/global_registries";
+import { Rectangle } from "../core/rectangle";
+import { BasicSerializableObject } from "../savegame/serialization";
+import { MetaItemProducerBuilding } from "./buildings/item_producer";
+import { BaseHUDPart } from "./hud/base_hud_part";
+import { MetaBuilding } from "./meta_building";
+
+/** @enum {string} */
+export const enumGameModeIds = {
+ puzzleEdit: "puzzleEditMode",
+ puzzlePlay: "puzzlePlayMode",
+ regular: "regularMode",
+};
+
+/** @enum {string} */
+export const enumGameModeTypes = {
+ default: "defaultModeType",
+ puzzle: "puzzleModeType",
+};
+
+export class GameMode extends BasicSerializableObject {
+ /** @returns {string} */
+ static getId() {
+ abstract;
+ return "unknownMode";
+ }
+
+ /** @returns {string} */
+ static getType() {
+ abstract;
+ return "unknownType";
+ }
+ /**
+ * @param {GameRoot} root
+ * @param {string} [id=Regular]
+ * @param {object|undefined} payload
+ */
+ static create(root, id = enumGameModeIds.regular, payload = undefined) {
+ return new (gGameModeRegistry.findById(id))(root, payload);
+ }
+
+ /**
+ * @param {GameRoot} root
+ */
+ constructor(root) {
+ super();
+ this.root = root;
+
+ /**
+ * @type {Record