From 0bc36b69b9c70495ea6aac2407231cf63a4ba67e Mon Sep 17 00:00:00 2001 From: Hecht Date: Tue, 11 Jun 2024 20:31:50 +0200 Subject: [PATCH] Added support for login and providing the godot client webapp --- .gitignore | 4 + composer.json | 1 + composer.lock | 40 +- config/api_platform/resources.xml | 9 +- config/packages/nelmio_cors.yaml | 1 + migrations/Version20240508185559.php | 151 + public/.htaccess | 75 + public/godot/index.apple-touch-icon.png | Bin 0 -> 12305 bytes public/godot/index.audio.worklet.js | 213 + public/godot/index.icon.png | Bin 0 -> 5676 bytes public/godot/index.js | 14477 ++++++++++++++++ public/godot/index.png | Bin 0 -> 323863 bytes public/godot/index.worker.js | 161 + server.Dockerfile | 12 + src/Command/LoginUrlCommand.php | 39 + src/Controller/ClientLoaderController.php | 31 + src/Entity/Character.php | 3 +- src/Entity/User.php | 5 +- src/Security/AccessTokenHandler.php | 61 +- .../TournamentRegistrationStateProcessor.php | 6 +- start_apache.sh | 7 + symfony.lock | 12 + templates/client_loader/index.html.foo.twig | 248 + templates/client_loader/index.html.old.twig | 22 + templates/client_loader/index.html.twig | 248 + tests/AbstractTest.php | 8 +- tests/UserTest.php | 62 + 27 files changed, 15864 insertions(+), 32 deletions(-) create mode 100644 migrations/Version20240508185559.php create mode 100644 public/.htaccess create mode 100644 public/godot/index.apple-touch-icon.png create mode 100644 public/godot/index.audio.worklet.js create mode 100644 public/godot/index.icon.png create mode 100644 public/godot/index.js create mode 100644 public/godot/index.png create mode 100644 public/godot/index.worker.js create mode 100644 server.Dockerfile create mode 100644 src/Command/LoginUrlCommand.php create mode 100644 src/Controller/ClientLoaderController.php create mode 100755 start_apache.sh create mode 100644 templates/client_loader/index.html.foo.twig create mode 100644 templates/client_loader/index.html.old.twig create mode 100644 templates/client_loader/index.html.twig create mode 100644 tests/UserTest.php diff --git a/.gitignore b/.gitignore index 4a741e4..1a274b0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,8 @@ /.* +public/godot/index.pck +public/godot/index.wasm +public/godot/index.pck.br +public/godot/index.wasm.br ###> symfony/framework-bundle ### /.env.local diff --git a/composer.json b/composer.json index fec56a9..351793f 100644 --- a/composer.json +++ b/composer.json @@ -14,6 +14,7 @@ "nelmio/cors-bundle": "^2.4", "phpdocumentor/reflection-docblock": "^5.3", "phpstan/phpdoc-parser": "^1.25", + "symfony/apache-pack": "^1.0", "symfony/asset": "6.4.*", "symfony/console": "6.4.*", "symfony/dotenv": "6.4.*", diff --git a/composer.lock b/composer.lock index d6d5a9b..c6db81c 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "cb35f34a2e8fe45ee2ca7ec7965bfaed", + "content-hash": "2cfe24bccdeb45c935548631fee3ec64", "packages": [ { "name": "api-platform/core", @@ -2078,18 +2078,44 @@ }, "time": "2021-07-14T16:46:02+00:00" }, + { + "name": "symfony/apache-pack", + "version": "v1.0.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/apache-pack.git", + "reference": "3aa5818d73ad2551281fc58a75afd9ca82622e6c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/apache-pack/zipball/3aa5818d73ad2551281fc58a75afd9ca82622e6c", + "reference": "3aa5818d73ad2551281fc58a75afd9ca82622e6c", + "shasum": "" + }, + "type": "symfony-pack", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A pack for Apache support in Symfony", + "support": { + "issues": "https://github.com/symfony/apache-pack/issues", + "source": "https://github.com/symfony/apache-pack/tree/master" + }, + "time": "2017-12-12T01:46:35+00:00" + }, { "name": "symfony/asset", - "version": "v6.4.3", + "version": "v6.4.7", "source": { "type": "git", "url": "https://github.com/symfony/asset.git", - "reference": "14b1c0fddb64af6ea626af51bb3c47af9fa19cb7" + "reference": "743757ab1dfa7114a8a3c63aeb376dfcf4b0a191" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/asset/zipball/14b1c0fddb64af6ea626af51bb3c47af9fa19cb7", - "reference": "14b1c0fddb64af6ea626af51bb3c47af9fa19cb7", + "url": "https://api.github.com/repos/symfony/asset/zipball/743757ab1dfa7114a8a3c63aeb376dfcf4b0a191", + "reference": "743757ab1dfa7114a8a3c63aeb376dfcf4b0a191", "shasum": "" }, "require": { @@ -2129,7 +2155,7 @@ "description": "Manages URL generation and versioning of web assets such as CSS stylesheets, JavaScript files and image files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/asset/tree/v6.4.3" + "source": "https://github.com/symfony/asset/tree/v6.4.7" }, "funding": [ { @@ -2145,7 +2171,7 @@ "type": "tidelift" } ], - "time": "2024-01-23T14:51:35+00:00" + "time": "2024-04-18T09:22:46+00:00" }, { "name": "symfony/cache", diff --git a/config/api_platform/resources.xml b/config/api_platform/resources.xml index 9f3de08..8fcc585 100644 --- a/config/api_platform/resources.xml +++ b/config/api_platform/resources.xml @@ -12,7 +12,9 @@ - + + public + @@ -129,8 +131,7 @@ - - + @@ -143,7 +144,7 @@ - + diff --git a/config/packages/nelmio_cors.yaml b/config/packages/nelmio_cors.yaml index c766508..ef44a4d 100644 --- a/config/packages/nelmio_cors.yaml +++ b/config/packages/nelmio_cors.yaml @@ -8,3 +8,4 @@ nelmio_cors: max_age: 3600 paths: '^/': null + diff --git a/migrations/Version20240508185559.php b/migrations/Version20240508185559.php new file mode 100644 index 0000000..b7eb396 --- /dev/null +++ b/migrations/Version20240508185559.php @@ -0,0 +1,151 @@ +addSql('CREATE TABLE "character" (id UUID NOT NULL, dojo_id UUID DEFAULT NULL, name VARCHAR(64) NOT NULL, strength INT NOT NULL, constitution INT NOT NULL, agility INT NOT NULL, chi INT NOT NULL, PRIMARY KEY(id))'); + $this->addSql('CREATE INDEX IDX_937AB03432F09E9C ON "character" (dojo_id)'); + $this->addSql('COMMENT ON COLUMN "character".id IS \'(DC2Type:ulid)\''); + $this->addSql('COMMENT ON COLUMN "character".dojo_id IS \'(DC2Type:ulid)\''); + $this->addSql('CREATE TABLE character_technique (character_id UUID NOT NULL, technique_id UUID NOT NULL, PRIMARY KEY(character_id, technique_id))'); + $this->addSql('CREATE INDEX IDX_506B3A7A1136BE75 ON character_technique (character_id)'); + $this->addSql('CREATE INDEX IDX_506B3A7A1F8ACB26 ON character_technique (technique_id)'); + $this->addSql('COMMENT ON COLUMN character_technique.character_id IS \'(DC2Type:ulid)\''); + $this->addSql('COMMENT ON COLUMN character_technique.technique_id IS \'(DC2Type:ulid)\''); + $this->addSql('CREATE TABLE city (id UUID NOT NULL, dungeon_id UUID NOT NULL, PRIMARY KEY(id))'); + $this->addSql('CREATE UNIQUE INDEX UNIQ_2D5B0234B606863 ON city (dungeon_id)'); + $this->addSql('COMMENT ON COLUMN city.id IS \'(DC2Type:ulid)\''); + $this->addSql('COMMENT ON COLUMN city.dungeon_id IS \'(DC2Type:ulid)\''); + $this->addSql('CREATE TABLE country (id UUID NOT NULL, capital_id UUID NOT NULL, PRIMARY KEY(id))'); + $this->addSql('CREATE UNIQUE INDEX UNIQ_5373C966FC2D9FF7 ON country (capital_id)'); + $this->addSql('COMMENT ON COLUMN country.id IS \'(DC2Type:ulid)\''); + $this->addSql('COMMENT ON COLUMN country.capital_id IS \'(DC2Type:ulid)\''); + $this->addSql('CREATE TABLE dojo (id UUID NOT NULL, village_id UUID DEFAULT NULL, owner_id UUID NOT NULL, name VARCHAR(255) NOT NULL, PRIMARY KEY(id))'); + $this->addSql('CREATE UNIQUE INDEX UNIQ_9494CCB15E237E06 ON dojo (name)'); + $this->addSql('CREATE INDEX IDX_9494CCB15E0D5582 ON dojo (village_id)'); + $this->addSql('CREATE UNIQUE INDEX UNIQ_9494CCB17E3C61F9 ON dojo (owner_id)'); + $this->addSql('COMMENT ON COLUMN dojo.id IS \'(DC2Type:ulid)\''); + $this->addSql('COMMENT ON COLUMN dojo.village_id IS \'(DC2Type:ulid)\''); + $this->addSql('COMMENT ON COLUMN dojo.owner_id IS \'(DC2Type:ulid)\''); + $this->addSql('CREATE TABLE dungeon (id UUID NOT NULL, city_id UUID NOT NULL, PRIMARY KEY(id))'); + $this->addSql('CREATE UNIQUE INDEX UNIQ_3FFA1F908BAC62AF ON dungeon (city_id)'); + $this->addSql('COMMENT ON COLUMN dungeon.id IS \'(DC2Type:ulid)\''); + $this->addSql('COMMENT ON COLUMN dungeon.city_id IS \'(DC2Type:ulid)\''); + $this->addSql('CREATE TABLE fight (id UUID NOT NULL, winner_id UUID DEFAULT NULL, tournament_id UUID NOT NULL, start_date TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, events JSON NOT NULL, PRIMARY KEY(id))'); + $this->addSql('CREATE INDEX IDX_21AA44565DFCD4B8 ON fight (winner_id)'); + $this->addSql('CREATE INDEX IDX_21AA445633D1A3E7 ON fight (tournament_id)'); + $this->addSql('COMMENT ON COLUMN fight.id IS \'(DC2Type:ulid)\''); + $this->addSql('COMMENT ON COLUMN fight.winner_id IS \'(DC2Type:ulid)\''); + $this->addSql('COMMENT ON COLUMN fight.tournament_id IS \'(DC2Type:ulid)\''); + $this->addSql('CREATE TABLE fight_character (fight_id UUID NOT NULL, character_id UUID NOT NULL, PRIMARY KEY(fight_id, character_id))'); + $this->addSql('CREATE INDEX IDX_BBD57C41AC6657E4 ON fight_character (fight_id)'); + $this->addSql('CREATE INDEX IDX_BBD57C411136BE75 ON fight_character (character_id)'); + $this->addSql('COMMENT ON COLUMN fight_character.fight_id IS \'(DC2Type:ulid)\''); + $this->addSql('COMMENT ON COLUMN fight_character.character_id IS \'(DC2Type:ulid)\''); + $this->addSql('CREATE TABLE prefecture (id UUID NOT NULL, capital_id UUID NOT NULL, country_id UUID NOT NULL, PRIMARY KEY(id))'); + $this->addSql('CREATE UNIQUE INDEX UNIQ_ABE6511AFC2D9FF7 ON prefecture (capital_id)'); + $this->addSql('CREATE INDEX IDX_ABE6511AF92F3E70 ON prefecture (country_id)'); + $this->addSql('COMMENT ON COLUMN prefecture.id IS \'(DC2Type:ulid)\''); + $this->addSql('COMMENT ON COLUMN prefecture.capital_id IS \'(DC2Type:ulid)\''); + $this->addSql('COMMENT ON COLUMN prefecture.country_id IS \'(DC2Type:ulid)\''); + $this->addSql('CREATE TABLE technique (id UUID NOT NULL, prerequisite_id UUID DEFAULT NULL, name VARCHAR(255) NOT NULL, costs INT NOT NULL, damage VARCHAR(255) NOT NULL, energy VARCHAR(255) NOT NULL, accuracy VARCHAR(255) NOT NULL, PRIMARY KEY(id))'); + $this->addSql('CREATE UNIQUE INDEX UNIQ_D73B98415E237E06 ON technique (name)'); + $this->addSql('CREATE INDEX IDX_D73B9841276AF86B ON technique (prerequisite_id)'); + $this->addSql('COMMENT ON COLUMN technique.id IS \'(DC2Type:ulid)\''); + $this->addSql('COMMENT ON COLUMN technique.prerequisite_id IS \'(DC2Type:ulid)\''); + $this->addSql('CREATE TABLE tournament (id UUID NOT NULL, winner_id UUID DEFAULT NULL, name VARCHAR(255) NOT NULL, start_date TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, PRIMARY KEY(id))'); + $this->addSql('CREATE INDEX IDX_BD5FB8D95DFCD4B8 ON tournament (winner_id)'); + $this->addSql('COMMENT ON COLUMN tournament.id IS \'(DC2Type:ulid)\''); + $this->addSql('COMMENT ON COLUMN tournament.winner_id IS \'(DC2Type:ulid)\''); + $this->addSql('CREATE TABLE tournament_character (tournament_id UUID NOT NULL, character_id UUID NOT NULL, PRIMARY KEY(tournament_id, character_id))'); + $this->addSql('CREATE INDEX IDX_43FA182533D1A3E7 ON tournament_character (tournament_id)'); + $this->addSql('CREATE INDEX IDX_43FA18251136BE75 ON tournament_character (character_id)'); + $this->addSql('COMMENT ON COLUMN tournament_character.tournament_id IS \'(DC2Type:ulid)\''); + $this->addSql('COMMENT ON COLUMN tournament_character.character_id IS \'(DC2Type:ulid)\''); + $this->addSql('CREATE TABLE "user" (id UUID NOT NULL, dojo_id UUID DEFAULT NULL, auth_name VARCHAR(32) NOT NULL, properties JSON NOT NULL, PRIMARY KEY(id))'); + $this->addSql('CREATE UNIQUE INDEX UNIQ_8D93D64932F09E9C ON "user" (dojo_id)'); + $this->addSql('COMMENT ON COLUMN "user".id IS \'(DC2Type:ulid)\''); + $this->addSql('COMMENT ON COLUMN "user".dojo_id IS \'(DC2Type:ulid)\''); + $this->addSql('CREATE TABLE village (id UUID NOT NULL, prefecture_id UUID NOT NULL, PRIMARY KEY(id))'); + $this->addSql('CREATE INDEX IDX_4E6C7FAA9D39C865 ON village (prefecture_id)'); + $this->addSql('COMMENT ON COLUMN village.id IS \'(DC2Type:ulid)\''); + $this->addSql('COMMENT ON COLUMN village.prefecture_id IS \'(DC2Type:ulid)\''); + $this->addSql('ALTER TABLE "character" ADD CONSTRAINT FK_937AB03432F09E9C FOREIGN KEY (dojo_id) REFERENCES dojo (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('ALTER TABLE character_technique ADD CONSTRAINT FK_506B3A7A1136BE75 FOREIGN KEY (character_id) REFERENCES "character" (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('ALTER TABLE character_technique ADD CONSTRAINT FK_506B3A7A1F8ACB26 FOREIGN KEY (technique_id) REFERENCES technique (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('ALTER TABLE city ADD CONSTRAINT FK_2D5B0234B606863 FOREIGN KEY (dungeon_id) REFERENCES dungeon (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('ALTER TABLE country ADD CONSTRAINT FK_5373C966FC2D9FF7 FOREIGN KEY (capital_id) REFERENCES city (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('ALTER TABLE dojo ADD CONSTRAINT FK_9494CCB15E0D5582 FOREIGN KEY (village_id) REFERENCES village (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('ALTER TABLE dojo ADD CONSTRAINT FK_9494CCB17E3C61F9 FOREIGN KEY (owner_id) REFERENCES "user" (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('ALTER TABLE dungeon ADD CONSTRAINT FK_3FFA1F908BAC62AF FOREIGN KEY (city_id) REFERENCES city (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('ALTER TABLE fight ADD CONSTRAINT FK_21AA44565DFCD4B8 FOREIGN KEY (winner_id) REFERENCES "character" (id) NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('ALTER TABLE fight ADD CONSTRAINT FK_21AA445633D1A3E7 FOREIGN KEY (tournament_id) REFERENCES tournament (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('ALTER TABLE fight_character ADD CONSTRAINT FK_BBD57C41AC6657E4 FOREIGN KEY (fight_id) REFERENCES fight (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('ALTER TABLE fight_character ADD CONSTRAINT FK_BBD57C411136BE75 FOREIGN KEY (character_id) REFERENCES "character" (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('ALTER TABLE prefecture ADD CONSTRAINT FK_ABE6511AFC2D9FF7 FOREIGN KEY (capital_id) REFERENCES city (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('ALTER TABLE prefecture ADD CONSTRAINT FK_ABE6511AF92F3E70 FOREIGN KEY (country_id) REFERENCES country (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('ALTER TABLE technique ADD CONSTRAINT FK_D73B9841276AF86B FOREIGN KEY (prerequisite_id) REFERENCES technique (id) ON DELETE SET NULL NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('ALTER TABLE tournament ADD CONSTRAINT FK_BD5FB8D95DFCD4B8 FOREIGN KEY (winner_id) REFERENCES "character" (id) NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('ALTER TABLE tournament_character ADD CONSTRAINT FK_43FA182533D1A3E7 FOREIGN KEY (tournament_id) REFERENCES tournament (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('ALTER TABLE tournament_character ADD CONSTRAINT FK_43FA18251136BE75 FOREIGN KEY (character_id) REFERENCES "character" (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('ALTER TABLE "user" ADD CONSTRAINT FK_8D93D64932F09E9C FOREIGN KEY (dojo_id) REFERENCES dojo (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('ALTER TABLE village ADD CONSTRAINT FK_4E6C7FAA9D39C865 FOREIGN KEY (prefecture_id) REFERENCES prefecture (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('CREATE SCHEMA public'); + $this->addSql('ALTER TABLE "character" DROP CONSTRAINT FK_937AB03432F09E9C'); + $this->addSql('ALTER TABLE character_technique DROP CONSTRAINT FK_506B3A7A1136BE75'); + $this->addSql('ALTER TABLE character_technique DROP CONSTRAINT FK_506B3A7A1F8ACB26'); + $this->addSql('ALTER TABLE city DROP CONSTRAINT FK_2D5B0234B606863'); + $this->addSql('ALTER TABLE country DROP CONSTRAINT FK_5373C966FC2D9FF7'); + $this->addSql('ALTER TABLE dojo DROP CONSTRAINT FK_9494CCB15E0D5582'); + $this->addSql('ALTER TABLE dojo DROP CONSTRAINT FK_9494CCB17E3C61F9'); + $this->addSql('ALTER TABLE dungeon DROP CONSTRAINT FK_3FFA1F908BAC62AF'); + $this->addSql('ALTER TABLE fight DROP CONSTRAINT FK_21AA44565DFCD4B8'); + $this->addSql('ALTER TABLE fight DROP CONSTRAINT FK_21AA445633D1A3E7'); + $this->addSql('ALTER TABLE fight_character DROP CONSTRAINT FK_BBD57C41AC6657E4'); + $this->addSql('ALTER TABLE fight_character DROP CONSTRAINT FK_BBD57C411136BE75'); + $this->addSql('ALTER TABLE prefecture DROP CONSTRAINT FK_ABE6511AFC2D9FF7'); + $this->addSql('ALTER TABLE prefecture DROP CONSTRAINT FK_ABE6511AF92F3E70'); + $this->addSql('ALTER TABLE technique DROP CONSTRAINT FK_D73B9841276AF86B'); + $this->addSql('ALTER TABLE tournament DROP CONSTRAINT FK_BD5FB8D95DFCD4B8'); + $this->addSql('ALTER TABLE tournament_character DROP CONSTRAINT FK_43FA182533D1A3E7'); + $this->addSql('ALTER TABLE tournament_character DROP CONSTRAINT FK_43FA18251136BE75'); + $this->addSql('ALTER TABLE "user" DROP CONSTRAINT FK_8D93D64932F09E9C'); + $this->addSql('ALTER TABLE village DROP CONSTRAINT FK_4E6C7FAA9D39C865'); + $this->addSql('DROP TABLE "character"'); + $this->addSql('DROP TABLE character_technique'); + $this->addSql('DROP TABLE city'); + $this->addSql('DROP TABLE country'); + $this->addSql('DROP TABLE dojo'); + $this->addSql('DROP TABLE dungeon'); + $this->addSql('DROP TABLE fight'); + $this->addSql('DROP TABLE fight_character'); + $this->addSql('DROP TABLE prefecture'); + $this->addSql('DROP TABLE technique'); + $this->addSql('DROP TABLE tournament'); + $this->addSql('DROP TABLE tournament_character'); + $this->addSql('DROP TABLE "user"'); + $this->addSql('DROP TABLE village'); + } +} diff --git a/public/.htaccess b/public/.htaccess new file mode 100644 index 0000000..3646650 --- /dev/null +++ b/public/.htaccess @@ -0,0 +1,75 @@ +# Use the front controller as index file. It serves as a fallback solution when +# every other rewrite/redirect fails (e.g. in an aliased environment without +# mod_rewrite). Additionally, this reduces the matching process for the +# start page (path "/") because otherwise Apache will apply the rewriting rules +# to each configured DirectoryIndex file (e.g. index.php, index.html, index.pl). +DirectoryIndex index.php + +# By default, Apache does not evaluate symbolic links if you did not enable this +# feature in your server configuration. Uncomment the following line if you +# install assets as symlinks or if you experience problems related to symlinks +# when compiling LESS/Sass/CoffeScript assets. +# Options +SymLinksIfOwnerMatch + +# Disabling MultiViews prevents unwanted negotiation, e.g. "/index" should not resolve +# to the front controller "/index.php" but be rewritten to "/index.php/index". + + Options -MultiViews + + + + # This Option needs to be enabled for RewriteRule, otherwise it will show an error like + # 'Options FollowSymLinks or SymLinksIfOwnerMatch is off which implies that RewriteRule directive is forbidden' + Options +SymLinksIfOwnerMatch + + RewriteEngine On + + # Determine the RewriteBase automatically and set it as environment variable. + # If you are using Apache aliases to do mass virtual hosting or installed the + # project in a subdirectory, the base path will be prepended to allow proper + # resolution of the index.php file and to redirect to the correct URI. It will + # work in environments without path prefix as well, providing a safe, one-size + # fits all solution. But as you do not need it in this case, you can comment + # the following 2 lines to eliminate the overhead. + RewriteCond %{REQUEST_URI}::$0 ^(/.+)/(.*)::\2$ + RewriteRule .* - [E=BASE:%1] + + # Sets the HTTP_AUTHORIZATION header removed by Apache + RewriteCond %{HTTP:Authorization} .+ + RewriteRule ^ - [E=HTTP_AUTHORIZATION:%0] + + # Redirect to URI without front controller to prevent duplicate content + # (with and without `/index.php`). Only do this redirect on the initial + # rewrite by Apache and not on subsequent cycles. Otherwise we would get an + # endless redirect loop (request -> rewrite to front controller -> + # redirect -> request -> ...). + # So in case you get a "too many redirects" error or you always get redirected + # to the start page because your Apache does not expose the REDIRECT_STATUS + # environment variable, you have 2 choices: + # - disable this feature by commenting the following 2 lines or + # - use Apache >= 2.3.9 and replace all L flags by END flags and remove the + # following RewriteCond (best solution) + RewriteCond %{ENV:REDIRECT_STATUS} ="" + RewriteRule ^index\.php(?:/(.*)|$) %{ENV:BASE}/$1 [R=301,L] + + # If the requested filename exists, simply serve it. + # We only want to let Apache serve files and not directories. + # Rewrite all other queries to the front controller. + RewriteCond %{REQUEST_FILENAME} !-f + RewriteRule ^ %{ENV:BASE}/index.php [L] + + + + + # When mod_rewrite is not available, we instruct a temporary redirect of + # the start page to the front controller explicitly so that the website + # and the generated links can still be used. + RedirectMatch 307 ^/$ /index.php/ + # RedirectTemp cannot be used instead + + + +Header set Cross-Origin-Embedder-Policy "require-corp" +Header set Cross-Origin-Opener-Policy "same-origin" + + diff --git a/public/godot/index.apple-touch-icon.png b/public/godot/index.apple-touch-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ea3bf8daaa08c859b976bbef3c8324fa6c67c761 GIT binary patch literal 12305 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 literal 0 HcmV?d00001 diff --git a/public/godot/index.audio.worklet.js b/public/godot/index.audio.worklet.js new file mode 100644 index 0000000..89b581b --- /dev/null +++ b/public/godot/index.audio.worklet.js @@ -0,0 +1,213 @@ +/**************************************************************************/ +/* audio.worklet.js */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ + +class RingBuffer { + constructor(p_buffer, p_state, p_threads) { + this.buffer = p_buffer; + this.avail = p_state; + this.threads = p_threads; + this.rpos = 0; + this.wpos = 0; + } + + data_left() { + return this.threads ? Atomics.load(this.avail, 0) : this.avail; + } + + space_left() { + return this.buffer.length - this.data_left(); + } + + read(output) { + const size = this.buffer.length; + let from = 0; + let to_write = output.length; + if (this.rpos + to_write > size) { + const high = size - this.rpos; + output.set(this.buffer.subarray(this.rpos, size)); + from = high; + to_write -= high; + this.rpos = 0; + } + if (to_write) { + output.set(this.buffer.subarray(this.rpos, this.rpos + to_write), from); + } + this.rpos += to_write; + if (this.threads) { + Atomics.add(this.avail, 0, -output.length); + Atomics.notify(this.avail, 0); + } else { + this.avail -= output.length; + } + } + + write(p_buffer) { + const to_write = p_buffer.length; + const mw = this.buffer.length - this.wpos; + if (mw >= to_write) { + this.buffer.set(p_buffer, this.wpos); + this.wpos += to_write; + if (mw === to_write) { + this.wpos = 0; + } + } else { + const high = p_buffer.subarray(0, mw); + const low = p_buffer.subarray(mw); + this.buffer.set(high, this.wpos); + this.buffer.set(low); + this.wpos = low.length; + } + if (this.threads) { + Atomics.add(this.avail, 0, to_write); + Atomics.notify(this.avail, 0); + } else { + this.avail += to_write; + } + } +} + +class GodotProcessor extends AudioWorkletProcessor { + constructor() { + super(); + this.threads = false; + this.running = true; + this.lock = null; + this.notifier = null; + this.output = null; + this.output_buffer = new Float32Array(); + this.input = null; + this.input_buffer = new Float32Array(); + this.port.onmessage = (event) => { + const cmd = event.data['cmd']; + const data = event.data['data']; + this.parse_message(cmd, data); + }; + } + + process_notify() { + if (this.notifier) { + Atomics.add(this.notifier, 0, 1); + Atomics.notify(this.notifier, 0); + } + } + + parse_message(p_cmd, p_data) { + if (p_cmd === 'start' && p_data) { + const state = p_data[0]; + let idx = 0; + this.threads = true; + this.lock = state.subarray(idx, ++idx); + this.notifier = state.subarray(idx, ++idx); + const avail_in = state.subarray(idx, ++idx); + const avail_out = state.subarray(idx, ++idx); + this.input = new RingBuffer(p_data[1], avail_in, true); + this.output = new RingBuffer(p_data[2], avail_out, true); + } else if (p_cmd === 'stop') { + this.running = false; + this.output = null; + this.input = null; + this.lock = null; + this.notifier = null; + } else if (p_cmd === 'start_nothreads') { + this.output = new RingBuffer(p_data[0], p_data[0].length, false); + } else if (p_cmd === 'chunk') { + this.output.write(p_data); + } + } + + static array_has_data(arr) { + return arr.length && arr[0].length && arr[0][0].length; + } + + process(inputs, outputs, parameters) { + if (!this.running) { + return false; // Stop processing. + } + if (this.output === null) { + return true; // Not ready yet, keep processing. + } + const process_input = GodotProcessor.array_has_data(inputs); + if (process_input) { + const input = inputs[0]; + const chunk = input[0].length * input.length; + if (this.input_buffer.length !== chunk) { + this.input_buffer = new Float32Array(chunk); + } + if (!this.threads) { + GodotProcessor.write_input(this.input_buffer, input); + this.port.postMessage({ 'cmd': 'input', 'data': this.input_buffer }); + } else if (this.input.space_left() >= chunk) { + GodotProcessor.write_input(this.input_buffer, input); + this.input.write(this.input_buffer); + } else { + this.port.postMessage('Input buffer is full! Skipping input frame.'); + } + } + const process_output = GodotProcessor.array_has_data(outputs); + if (process_output) { + const output = outputs[0]; + const chunk = output[0].length * output.length; + if (this.output_buffer.length !== chunk) { + this.output_buffer = new Float32Array(chunk); + } + if (this.output.data_left() >= chunk) { + this.output.read(this.output_buffer); + GodotProcessor.write_output(output, this.output_buffer); + if (!this.threads) { + this.port.postMessage({ 'cmd': 'read', 'data': chunk }); + } + } else { + this.port.postMessage('Output buffer has not enough frames! Skipping output frame.'); + } + } + this.process_notify(); + return true; + } + + static write_output(dest, source) { + const channels = dest.length; + for (let ch = 0; ch < channels; ch++) { + for (let sample = 0; sample < dest[ch].length; sample++) { + dest[ch][sample] = source[sample * channels + ch]; + } + } + } + + static write_input(dest, source) { + const channels = source.length; + for (let ch = 0; ch < channels; ch++) { + for (let sample = 0; sample < source[ch].length; sample++) { + dest[sample * channels + ch] = source[ch][sample]; + } + } + } +} + +registerProcessor('godot-processor', GodotProcessor); diff --git a/public/godot/index.icon.png b/public/godot/index.icon.png new file mode 100644 index 0000000000000000000000000000000000000000..287892f8e2ecaf1d9b7bc4e602c64fe9040c23cd GIT binary patch literal 5676 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 Sxb!Cg0000 { + var _scriptDir = typeof document !== 'undefined' && document.currentScript ? document.currentScript.src : undefined; + + return ( +function(Godot = {}) { + +// Support for growable heap + pthreads, where the buffer may change, so JS views +// must be updated. +function GROWABLE_HEAP_I8() { + if (wasmMemory.buffer != HEAP8.buffer) { + updateMemoryViews(); + } + return HEAP8; +} +function GROWABLE_HEAP_U8() { + if (wasmMemory.buffer != HEAP8.buffer) { + updateMemoryViews(); + } + return HEAPU8; +} +function GROWABLE_HEAP_I16() { + if (wasmMemory.buffer != HEAP8.buffer) { + updateMemoryViews(); + } + return HEAP16; +} +function GROWABLE_HEAP_U16() { + if (wasmMemory.buffer != HEAP8.buffer) { + updateMemoryViews(); + } + return HEAPU16; +} +function GROWABLE_HEAP_I32() { + if (wasmMemory.buffer != HEAP8.buffer) { + updateMemoryViews(); + } + return HEAP32; +} +function GROWABLE_HEAP_U32() { + if (wasmMemory.buffer != HEAP8.buffer) { + updateMemoryViews(); + } + return HEAPU32; +} +function GROWABLE_HEAP_F32() { + if (wasmMemory.buffer != HEAP8.buffer) { + updateMemoryViews(); + } + return HEAPF32; +} +function GROWABLE_HEAP_F64() { + if (wasmMemory.buffer != HEAP8.buffer) { + updateMemoryViews(); + } + return HEAPF64; +} + +var Module = typeof Godot != "undefined" ? Godot : {}; + +var readyPromiseResolve, readyPromiseReject; + +Module["ready"] = new Promise((resolve, reject) => { + readyPromiseResolve = resolve; + readyPromiseReject = reject; +}); + +[ "_main", "__emscripten_thread_init", "__emscripten_thread_exit", "__emscripten_thread_crashed", "__emscripten_thread_mailbox_await", "__emscripten_tls_init", "_pthread_self", "checkMailbox", "establishStackSpace", "invokeEntryPoint", "PThread", "__Z14godot_web_mainiPPc", "_fflush", "__emwebxr_on_input_event", "__emwebxr_on_simple_event", "__emscripten_check_mailbox", "onRuntimeInitialized" ].forEach(prop => { + if (!Object.getOwnPropertyDescriptor(Module["ready"], prop)) { + Object.defineProperty(Module["ready"], prop, { + get: () => abort("You are getting " + prop + " on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js"), + set: () => abort("You are setting " + prop + " on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js") + }); + } +}); + +var moduleOverrides = Object.assign({}, Module); + +var arguments_ = []; + +var thisProgram = "./this.program"; + +var quit_ = (status, toThrow) => { + throw toThrow; +}; + +var ENVIRONMENT_IS_WEB = typeof window == "object"; + +var ENVIRONMENT_IS_WORKER = typeof importScripts == "function"; + +var ENVIRONMENT_IS_NODE = typeof process == "object" && typeof process.versions == "object" && typeof process.versions.node == "string"; + +var ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIRONMENT_IS_WORKER; + +if (Module["ENVIRONMENT"]) { + throw new Error("Module.ENVIRONMENT has been deprecated. To force the environment, use the ENVIRONMENT compile-time option (for example, -sENVIRONMENT=web or -sENVIRONMENT=node)"); +} + +var ENVIRONMENT_IS_PTHREAD = Module["ENVIRONMENT_IS_PTHREAD"] || false; + +var scriptDirectory = ""; + +function locateFile(path) { + if (Module["locateFile"]) { + return Module["locateFile"](path, scriptDirectory); + } + return scriptDirectory + path; +} + +var read_, readAsync, readBinary, setWindowTitle; + +if (ENVIRONMENT_IS_SHELL) { + if (typeof process == "object" && typeof require === "function" || typeof window == "object" || typeof importScripts == "function") throw new Error("not compiled for this environment (did you build to HTML and try to run it not on the web, or set ENVIRONMENT to something - like node - and run it someplace else - like on the web?)"); + if (typeof read != "undefined") { + read_ = f => { + return read(f); + }; + } + readBinary = f => { + let data; + if (typeof readbuffer == "function") { + return new Uint8Array(readbuffer(f)); + } + data = read(f, "binary"); + assert(typeof data == "object"); + return data; + }; + readAsync = (f, onload, onerror) => { + setTimeout(() => onload(readBinary(f)), 0); + }; + if (typeof clearTimeout == "undefined") { + globalThis.clearTimeout = id => {}; + } + if (typeof scriptArgs != "undefined") { + arguments_ = scriptArgs; + } else if (typeof arguments != "undefined") { + arguments_ = arguments; + } + if (typeof quit == "function") { + quit_ = (status, toThrow) => { + setTimeout(() => { + if (!(toThrow instanceof ExitStatus)) { + let toLog = toThrow; + if (toThrow && typeof toThrow == "object" && toThrow.stack) { + toLog = [ toThrow, toThrow.stack ]; + } + err(`exiting due to exception: ${toLog}`); + } + quit(status); + }); + throw toThrow; + }; + } + if (typeof print != "undefined") { + if (typeof console == "undefined") console = {}; + console.log = print; + console.warn = console.error = typeof printErr != "undefined" ? printErr : print; + } +} else if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) { + if (ENVIRONMENT_IS_WORKER) { + scriptDirectory = self.location.href; + } else if (typeof document != "undefined" && document.currentScript) { + scriptDirectory = document.currentScript.src; + } + if (_scriptDir) { + scriptDirectory = _scriptDir; + } + if (scriptDirectory.indexOf("blob:") !== 0) { + scriptDirectory = scriptDirectory.substr(0, scriptDirectory.replace(/[?#].*/, "").lastIndexOf("/") + 1); + } else { + scriptDirectory = ""; + } + if (!(typeof window == "object" || typeof importScripts == "function")) throw new Error("not compiled for this environment (did you build to HTML and try to run it not on the web, or set ENVIRONMENT to something - like node - and run it someplace else - like on the web?)"); + { + read_ = url => { + var xhr = new XMLHttpRequest(); + xhr.open("GET", url, false); + xhr.send(null); + return xhr.responseText; + }; + if (ENVIRONMENT_IS_WORKER) { + readBinary = url => { + var xhr = new XMLHttpRequest(); + xhr.open("GET", url, false); + xhr.responseType = "arraybuffer"; + xhr.send(null); + return new Uint8Array(xhr.response); + }; + } + readAsync = (url, onload, onerror) => { + var xhr = new XMLHttpRequest(); + xhr.open("GET", url, true); + xhr.responseType = "arraybuffer"; + xhr.onload = () => { + if (xhr.status == 200 || xhr.status == 0 && xhr.response) { + onload(xhr.response); + return; + } + onerror(); + }; + xhr.onerror = onerror; + xhr.send(null); + }; + } + setWindowTitle = title => document.title = title; +} else { + throw new Error("environment detection error"); +} + +var out = Module["print"] || console.log.bind(console); + +var err = Module["printErr"] || console.error.bind(console); + +Object.assign(Module, moduleOverrides); + +moduleOverrides = null; + +checkIncomingModuleAPI(); + +if (Module["arguments"]) arguments_ = Module["arguments"]; + +legacyModuleProp("arguments", "arguments_"); + +if (Module["thisProgram"]) thisProgram = Module["thisProgram"]; + +legacyModuleProp("thisProgram", "thisProgram"); + +if (Module["quit"]) quit_ = Module["quit"]; + +legacyModuleProp("quit", "quit_"); + +assert(typeof Module["memoryInitializerPrefixURL"] == "undefined", "Module.memoryInitializerPrefixURL option was removed, use Module.locateFile instead"); + +assert(typeof Module["pthreadMainPrefixURL"] == "undefined", "Module.pthreadMainPrefixURL option was removed, use Module.locateFile instead"); + +assert(typeof Module["cdInitializerPrefixURL"] == "undefined", "Module.cdInitializerPrefixURL option was removed, use Module.locateFile instead"); + +assert(typeof Module["filePackagePrefixURL"] == "undefined", "Module.filePackagePrefixURL option was removed, use Module.locateFile instead"); + +assert(typeof Module["read"] == "undefined", "Module.read option was removed (modify read_ in JS)"); + +assert(typeof Module["readAsync"] == "undefined", "Module.readAsync option was removed (modify readAsync in JS)"); + +assert(typeof Module["readBinary"] == "undefined", "Module.readBinary option was removed (modify readBinary in JS)"); + +assert(typeof Module["setWindowTitle"] == "undefined", "Module.setWindowTitle option was removed (modify setWindowTitle in JS)"); + +assert(typeof Module["TOTAL_MEMORY"] == "undefined", "Module.TOTAL_MEMORY has been renamed Module.INITIAL_MEMORY"); + +legacyModuleProp("read", "read_"); + +legacyModuleProp("readAsync", "readAsync"); + +legacyModuleProp("readBinary", "readBinary"); + +legacyModuleProp("setWindowTitle", "setWindowTitle"); + +var PROXYFS = "PROXYFS is no longer included by default; build with -lproxyfs.js"; + +var WORKERFS = "WORKERFS is no longer included by default; build with -lworkerfs.js"; + +var NODEFS = "NODEFS is no longer included by default; build with -lnodefs.js"; + +assert(ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER || ENVIRONMENT_IS_NODE, "Pthreads do not work in this environment yet (need Web Workers, or an alternative to them)"); + +assert(!ENVIRONMENT_IS_NODE, "node environment detected but not enabled at build time. Add 'node' to `-sENVIRONMENT` to enable."); + +assert(!ENVIRONMENT_IS_SHELL, "shell environment detected but not enabled at build time. Add 'shell' to `-sENVIRONMENT` to enable."); + +var wasmBinary; + +if (Module["wasmBinary"]) wasmBinary = Module["wasmBinary"]; + +legacyModuleProp("wasmBinary", "wasmBinary"); + +var noExitRuntime = Module["noExitRuntime"] || false; + +legacyModuleProp("noExitRuntime", "noExitRuntime"); + +if (typeof WebAssembly != "object") { + abort("no native wasm support detected"); +} + +var wasmMemory; + +var wasmModule; + +var ABORT = false; + +var EXITSTATUS; + +function assert(condition, text) { + if (!condition) { + abort("Assertion failed" + (text ? ": " + text : "")); + } +} + +var HEAP, HEAP8, HEAPU8, HEAP16, HEAPU16, HEAP32, HEAPU32, HEAPF32, HEAPF64; + +function updateMemoryViews() { + var b = wasmMemory.buffer; + Module["HEAP8"] = HEAP8 = new Int8Array(b); + Module["HEAP16"] = HEAP16 = new Int16Array(b); + Module["HEAP32"] = HEAP32 = new Int32Array(b); + Module["HEAPU8"] = HEAPU8 = new Uint8Array(b); + Module["HEAPU16"] = HEAPU16 = new Uint16Array(b); + Module["HEAPU32"] = HEAPU32 = new Uint32Array(b); + Module["HEAPF32"] = HEAPF32 = new Float32Array(b); + Module["HEAPF64"] = HEAPF64 = new Float64Array(b); +} + +assert(!Module["STACK_SIZE"], "STACK_SIZE can no longer be set at runtime. Use -sSTACK_SIZE at link time"); + +assert(typeof Int32Array != "undefined" && typeof Float64Array !== "undefined" && Int32Array.prototype.subarray != undefined && Int32Array.prototype.set != undefined, "JS engine does not provide full typed array support"); + +var INITIAL_MEMORY = Module["INITIAL_MEMORY"] || 33554432; + +legacyModuleProp("INITIAL_MEMORY", "INITIAL_MEMORY"); + +assert(INITIAL_MEMORY >= 5242880, "INITIAL_MEMORY should be larger than STACK_SIZE, was " + INITIAL_MEMORY + "! (STACK_SIZE=" + 5242880 + ")"); + +if (ENVIRONMENT_IS_PTHREAD) { + wasmMemory = Module["wasmMemory"]; +} else { + if (Module["wasmMemory"]) { + wasmMemory = Module["wasmMemory"]; + } else { + wasmMemory = new WebAssembly.Memory({ + "initial": INITIAL_MEMORY / 65536, + "maximum": 2147483648 / 65536, + "shared": true + }); + if (!(wasmMemory.buffer instanceof SharedArrayBuffer)) { + err("requested a shared WebAssembly.Memory but the returned buffer is not a SharedArrayBuffer, indicating that while the browser has SharedArrayBuffer it does not have WebAssembly threads support - you may need to set a flag"); + if (ENVIRONMENT_IS_NODE) { + err("(on node you may need: --experimental-wasm-threads --experimental-wasm-bulk-memory and/or recent version)"); + } + throw Error("bad memory"); + } + } +} + +updateMemoryViews(); + +INITIAL_MEMORY = wasmMemory.buffer.byteLength; + +assert(INITIAL_MEMORY % 65536 === 0); + +var wasmTable; + +function writeStackCookie() { + var max = _emscripten_stack_get_end(); + assert((max & 3) == 0); + if (max == 0) { + max += 4; + } + GROWABLE_HEAP_U32()[max >> 2] = 34821223; + GROWABLE_HEAP_U32()[max + 4 >> 2] = 2310721022; + GROWABLE_HEAP_U32()[0] = 1668509029; +} + +function checkStackCookie() { + if (ABORT) return; + var max = _emscripten_stack_get_end(); + if (max == 0) { + max += 4; + } + var cookie1 = GROWABLE_HEAP_U32()[max >> 2]; + var cookie2 = GROWABLE_HEAP_U32()[max + 4 >> 2]; + if (cookie1 != 34821223 || cookie2 != 2310721022) { + abort("Stack overflow! Stack cookie has been overwritten at " + ptrToString(max) + ", expected hex dwords 0x89BACDFE and 0x2135467, but received " + ptrToString(cookie2) + " " + ptrToString(cookie1)); + } + if (GROWABLE_HEAP_U32()[0] !== 1668509029) { + abort("Runtime error: The application has corrupted its heap memory area (address zero)!"); + } +} + +(function() { + var h16 = new Int16Array(1); + var h8 = new Int8Array(h16.buffer); + h16[0] = 25459; + if (h8[0] !== 115 || h8[1] !== 99) throw "Runtime error: expected the system to be little-endian! (Run with -sSUPPORT_BIG_ENDIAN to bypass)"; +})(); + +var __ATPRERUN__ = []; + +var __ATINIT__ = []; + +var __ATMAIN__ = []; + +var __ATEXIT__ = []; + +var __ATPOSTRUN__ = []; + +var runtimeInitialized = false; + +var runtimeExited = false; + +var runtimeKeepaliveCounter = 0; + +function keepRuntimeAlive() { + return noExitRuntime || runtimeKeepaliveCounter > 0; +} + +function preRun() { + assert(!ENVIRONMENT_IS_PTHREAD); + if (Module["preRun"]) { + if (typeof Module["preRun"] == "function") Module["preRun"] = [ Module["preRun"] ]; + while (Module["preRun"].length) { + addOnPreRun(Module["preRun"].shift()); + } + } + callRuntimeCallbacks(__ATPRERUN__); +} + +function initRuntime() { + assert(!runtimeInitialized); + runtimeInitialized = true; + if (ENVIRONMENT_IS_PTHREAD) return; + checkStackCookie(); + if (!Module["noFSInit"] && !FS.init.initialized) FS.init(); + FS.ignorePermissions = false; + TTY.init(); + SOCKFS.root = FS.mount(SOCKFS, {}, null); + callRuntimeCallbacks(__ATINIT__); +} + +function preMain() { + checkStackCookie(); + if (ENVIRONMENT_IS_PTHREAD) return; + callRuntimeCallbacks(__ATMAIN__); +} + +function exitRuntime() { + assert(!runtimeExited); + checkStackCookie(); + if (ENVIRONMENT_IS_PTHREAD) return; + ___funcs_on_exit(); + callRuntimeCallbacks(__ATEXIT__); + FS.quit(); + TTY.shutdown(); + IDBFS.quit(); + PThread.terminateAllThreads(); + runtimeExited = true; +} + +function postRun() { + checkStackCookie(); + if (ENVIRONMENT_IS_PTHREAD) return; + if (Module["postRun"]) { + if (typeof Module["postRun"] == "function") Module["postRun"] = [ Module["postRun"] ]; + while (Module["postRun"].length) { + addOnPostRun(Module["postRun"].shift()); + } + } + callRuntimeCallbacks(__ATPOSTRUN__); +} + +function addOnPreRun(cb) { + __ATPRERUN__.unshift(cb); +} + +function addOnInit(cb) { + __ATINIT__.unshift(cb); +} + +function addOnPreMain(cb) { + __ATMAIN__.unshift(cb); +} + +function addOnExit(cb) { + __ATEXIT__.unshift(cb); +} + +function addOnPostRun(cb) { + __ATPOSTRUN__.unshift(cb); +} + +assert(Math.imul, "This browser does not support Math.imul(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill"); + +assert(Math.fround, "This browser does not support Math.fround(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill"); + +assert(Math.clz32, "This browser does not support Math.clz32(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill"); + +assert(Math.trunc, "This browser does not support Math.trunc(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill"); + +var runDependencies = 0; + +var runDependencyWatcher = null; + +var dependenciesFulfilled = null; + +var runDependencyTracking = {}; + +function getUniqueRunDependency(id) { + var orig = id; + while (1) { + if (!runDependencyTracking[id]) return id; + id = orig + Math.random(); + } +} + +function addRunDependency(id) { + runDependencies++; + if (Module["monitorRunDependencies"]) { + Module["monitorRunDependencies"](runDependencies); + } + if (id) { + assert(!runDependencyTracking[id]); + runDependencyTracking[id] = 1; + if (runDependencyWatcher === null && typeof setInterval != "undefined") { + runDependencyWatcher = setInterval(() => { + if (ABORT) { + clearInterval(runDependencyWatcher); + runDependencyWatcher = null; + return; + } + var shown = false; + for (var dep in runDependencyTracking) { + if (!shown) { + shown = true; + err("still waiting on run dependencies:"); + } + err("dependency: " + dep); + } + if (shown) { + err("(end of list)"); + } + }, 1e4); + } + } else { + err("warning: run dependency added without ID"); + } +} + +function removeRunDependency(id) { + runDependencies--; + if (Module["monitorRunDependencies"]) { + Module["monitorRunDependencies"](runDependencies); + } + if (id) { + assert(runDependencyTracking[id]); + delete runDependencyTracking[id]; + } else { + err("warning: run dependency removed without ID"); + } + if (runDependencies == 0) { + if (runDependencyWatcher !== null) { + clearInterval(runDependencyWatcher); + runDependencyWatcher = null; + } + if (dependenciesFulfilled) { + var callback = dependenciesFulfilled; + dependenciesFulfilled = null; + callback(); + } + } +} + +function abort(what) { + if (Module["onAbort"]) { + Module["onAbort"](what); + } + what = "Aborted(" + what + ")"; + err(what); + ABORT = true; + EXITSTATUS = 1; + var e = new WebAssembly.RuntimeError(what); + readyPromiseReject(e); + throw e; +} + +var dataURIPrefix = "data:application/octet-stream;base64,"; + +function isDataURI(filename) { + return filename.startsWith(dataURIPrefix); +} + +function isFileURI(filename) { + return filename.startsWith("file://"); +} + +function createExportWrapper(name, fixedasm) { + return function() { + var displayName = name; + var asm = fixedasm; + if (!fixedasm) { + asm = Module["asm"]; + } + assert(runtimeInitialized, "native function `" + displayName + "` called before runtime initialization"); + assert(!runtimeExited, "native function `" + displayName + "` called after runtime exit (use NO_EXIT_RUNTIME to keep it alive after main() exits)"); + if (!asm[name]) { + assert(asm[name], "exported native function `" + displayName + "` not found"); + } + return asm[name].apply(null, arguments); + }; +} + +var wasmBinaryFile; + +wasmBinaryFile = "godot.web.template_release.wasm32.wasm"; + +if (!isDataURI(wasmBinaryFile)) { + wasmBinaryFile = locateFile(wasmBinaryFile); +} + +function getBinary(file) { + try { + if (file == wasmBinaryFile && wasmBinary) { + return new Uint8Array(wasmBinary); + } + if (readBinary) { + return readBinary(file); + } + throw "both async and sync fetching of the wasm failed"; + } catch (err) { + abort(err); + } +} + +function getBinaryPromise(binaryFile) { + if (!wasmBinary && (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER)) { + if (typeof fetch == "function") { + return fetch(binaryFile, { + credentials: "same-origin" + }).then(response => { + if (!response["ok"]) { + throw "failed to load wasm binary file at '" + binaryFile + "'"; + } + return response["arrayBuffer"](); + }).catch(() => getBinary(binaryFile)); + } + } + return Promise.resolve().then(() => getBinary(binaryFile)); +} + +function instantiateArrayBuffer(binaryFile, imports, receiver) { + return getBinaryPromise(binaryFile).then(binary => { + return WebAssembly.instantiate(binary, imports); + }).then(instance => { + return instance; + }).then(receiver, reason => { + err("failed to asynchronously prepare wasm: " + reason); + if (isFileURI(wasmBinaryFile)) { + err("warning: Loading from a file URI (" + wasmBinaryFile + ") is not supported in most browsers. See https://emscripten.org/docs/getting_started/FAQ.html#how-do-i-run-a-local-webserver-for-testing-why-does-my-program-stall-in-downloading-or-preparing"); + } + abort(reason); + }); +} + +function instantiateAsync(binary, binaryFile, imports, callback) { + if (!binary && typeof WebAssembly.instantiateStreaming == "function" && !isDataURI(binaryFile) && typeof fetch == "function") { + return fetch(binaryFile, { + credentials: "same-origin" + }).then(response => { + var result = WebAssembly.instantiateStreaming(response, imports); + return result.then(callback, function(reason) { + err("wasm streaming compile failed: " + reason); + err("falling back to ArrayBuffer instantiation"); + return instantiateArrayBuffer(binaryFile, imports, callback); + }); + }); + } else { + return instantiateArrayBuffer(binaryFile, imports, callback); + } +} + +function createWasm() { + var info = { + "env": wasmImports, + "wasi_snapshot_preview1": wasmImports + }; + function receiveInstance(instance, module) { + var exports = instance.exports; + Module["asm"] = exports; + registerTLSInit(Module["asm"]["_emscripten_tls_init"]); + wasmTable = Module["asm"]["__indirect_function_table"]; + assert(wasmTable, "table not found in wasm exports"); + addOnInit(Module["asm"]["__wasm_call_ctors"]); + wasmModule = module; + PThread.loadWasmModuleToAllWorkers(() => removeRunDependency("wasm-instantiate")); + return exports; + } + addRunDependency("wasm-instantiate"); + var trueModule = Module; + function receiveInstantiationResult(result) { + assert(Module === trueModule, "the Module object should not be replaced during async compilation - perhaps the order of HTML elements is wrong?"); + trueModule = null; + receiveInstance(result["instance"], result["module"]); + } + if (Module["instantiateWasm"]) { + try { + return Module["instantiateWasm"](info, receiveInstance); + } catch (e) { + err("Module.instantiateWasm callback failed with error: " + e); + readyPromiseReject(e); + } + } + instantiateAsync(wasmBinary, wasmBinaryFile, info, receiveInstantiationResult).catch(readyPromiseReject); + return {}; +} + +var tempDouble; + +var tempI64; + +function legacyModuleProp(prop, newName) { + if (!Object.getOwnPropertyDescriptor(Module, prop)) { + Object.defineProperty(Module, prop, { + configurable: true, + get: function() { + abort("Module." + prop + " has been replaced with plain " + newName + " (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)"); + } + }); + } +} + +function ignoredModuleProp(prop) { + if (Object.getOwnPropertyDescriptor(Module, prop)) { + abort("`Module." + prop + "` was supplied but `" + prop + "` not included in INCOMING_MODULE_JS_API"); + } +} + +function isExportedByForceFilesystem(name) { + return name === "FS_createPath" || name === "FS_createDataFile" || name === "FS_createPreloadedFile" || name === "FS_unlink" || name === "addRunDependency" || name === "FS_createLazyFile" || name === "FS_createDevice" || name === "removeRunDependency"; +} + +function missingGlobal(sym, msg) { + if (typeof globalThis !== "undefined") { + Object.defineProperty(globalThis, sym, { + configurable: true, + get: function() { + warnOnce("`" + sym + "` is not longer defined by emscripten. " + msg); + return undefined; + } + }); + } +} + +missingGlobal("buffer", "Please use HEAP8.buffer or wasmMemory.buffer"); + +function missingLibrarySymbol(sym) { + if (typeof globalThis !== "undefined" && !Object.getOwnPropertyDescriptor(globalThis, sym)) { + Object.defineProperty(globalThis, sym, { + configurable: true, + get: function() { + var msg = "`" + sym + "` is a library symbol and not included by default; add it to your library.js __deps or to DEFAULT_LIBRARY_FUNCS_TO_INCLUDE on the command line"; + var librarySymbol = sym; + if (!librarySymbol.startsWith("_")) { + librarySymbol = "$" + sym; + } + msg += " (e.g. -sDEFAULT_LIBRARY_FUNCS_TO_INCLUDE=" + librarySymbol + ")"; + if (isExportedByForceFilesystem(sym)) { + msg += ". Alternatively, forcing filesystem support (-sFORCE_FILESYSTEM) can export this for you"; + } + warnOnce(msg); + return undefined; + } + }); + } + unexportedRuntimeSymbol(sym); +} + +function unexportedRuntimeSymbol(sym) { + if (!Object.getOwnPropertyDescriptor(Module, sym)) { + Object.defineProperty(Module, sym, { + configurable: true, + get: function() { + var msg = "'" + sym + "' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)"; + if (isExportedByForceFilesystem(sym)) { + msg += ". Alternatively, forcing filesystem support (-sFORCE_FILESYSTEM) can export this for you"; + } + abort(msg); + } + }); + } +} + +function dbg(text) { + console.warn.apply(console, arguments); +} + +function ExitStatus(status) { + this.name = "ExitStatus"; + this.message = "Program terminated with exit(" + status + ")"; + this.status = status; +} + +function terminateWorker(worker) { + worker.terminate(); + worker.onmessage = e => { + var cmd = e["data"]["cmd"]; + err('received "' + cmd + '" command from terminated worker: ' + worker.workerID); + }; +} + +function killThread(pthread_ptr) { + assert(!ENVIRONMENT_IS_PTHREAD, "Internal Error! killThread() can only ever be called from main application thread!"); + assert(pthread_ptr, "Internal Error! Null pthread_ptr in killThread!"); + var worker = PThread.pthreads[pthread_ptr]; + delete PThread.pthreads[pthread_ptr]; + terminateWorker(worker); + __emscripten_thread_free_data(pthread_ptr); + PThread.runningWorkers.splice(PThread.runningWorkers.indexOf(worker), 1); + worker.pthread_ptr = 0; +} + +function cancelThread(pthread_ptr) { + assert(!ENVIRONMENT_IS_PTHREAD, "Internal Error! cancelThread() can only ever be called from main application thread!"); + assert(pthread_ptr, "Internal Error! Null pthread_ptr in cancelThread!"); + var worker = PThread.pthreads[pthread_ptr]; + worker.postMessage({ + "cmd": "cancel" + }); +} + +function cleanupThread(pthread_ptr) { + assert(!ENVIRONMENT_IS_PTHREAD, "Internal Error! cleanupThread() can only ever be called from main application thread!"); + assert(pthread_ptr, "Internal Error! Null pthread_ptr in cleanupThread!"); + var worker = PThread.pthreads[pthread_ptr]; + assert(worker); + PThread.returnWorkerToPool(worker); +} + +function zeroMemory(address, size) { + GROWABLE_HEAP_U8().fill(0, address, address + size); + return address; +} + +function spawnThread(threadParams) { + assert(!ENVIRONMENT_IS_PTHREAD, "Internal Error! spawnThread() can only ever be called from main application thread!"); + assert(threadParams.pthread_ptr, "Internal error, no pthread ptr!"); + var worker = PThread.getNewWorker(); + if (!worker) { + return 6; + } + assert(!worker.pthread_ptr, "Internal error!"); + PThread.runningWorkers.push(worker); + PThread.pthreads[threadParams.pthread_ptr] = worker; + worker.pthread_ptr = threadParams.pthread_ptr; + var msg = { + "cmd": "run", + "start_routine": threadParams.startRoutine, + "arg": threadParams.arg, + "pthread_ptr": threadParams.pthread_ptr + }; + worker.postMessage(msg, threadParams.transferList); + return 0; +} + +var PATH = { + isAbs: path => path.charAt(0) === "/", + splitPath: filename => { + var splitPathRe = /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/; + return splitPathRe.exec(filename).slice(1); + }, + normalizeArray: (parts, allowAboveRoot) => { + var up = 0; + for (var i = parts.length - 1; i >= 0; i--) { + var last = parts[i]; + if (last === ".") { + parts.splice(i, 1); + } else if (last === "..") { + parts.splice(i, 1); + up++; + } else if (up) { + parts.splice(i, 1); + up--; + } + } + if (allowAboveRoot) { + for (;up; up--) { + parts.unshift(".."); + } + } + return parts; + }, + normalize: path => { + var isAbsolute = PATH.isAbs(path), trailingSlash = path.substr(-1) === "/"; + path = PATH.normalizeArray(path.split("/").filter(p => !!p), !isAbsolute).join("/"); + if (!path && !isAbsolute) { + path = "."; + } + if (path && trailingSlash) { + path += "/"; + } + return (isAbsolute ? "/" : "") + path; + }, + dirname: path => { + var result = PATH.splitPath(path), root = result[0], dir = result[1]; + if (!root && !dir) { + return "."; + } + if (dir) { + dir = dir.substr(0, dir.length - 1); + } + return root + dir; + }, + basename: path => { + if (path === "/") return "/"; + path = PATH.normalize(path); + path = path.replace(/\/$/, ""); + var lastSlash = path.lastIndexOf("/"); + if (lastSlash === -1) return path; + return path.substr(lastSlash + 1); + }, + join: function() { + var paths = Array.prototype.slice.call(arguments); + return PATH.normalize(paths.join("/")); + }, + join2: (l, r) => { + return PATH.normalize(l + "/" + r); + } +}; + +function initRandomFill() { + if (typeof crypto == "object" && typeof crypto["getRandomValues"] == "function") { + return view => (view.set(crypto.getRandomValues(new Uint8Array(view.byteLength))), + view); + } else abort("no cryptographic support found for randomDevice. consider polyfilling it if you want to use something insecure like Math.random(), e.g. put this in a --pre-js: var crypto = { getRandomValues: function(array) { for (var i = 0; i < array.length; i++) array[i] = (Math.random()*256)|0 } };"); +} + +function randomFill(view) { + return (randomFill = initRandomFill())(view); +} + +var PATH_FS = { + resolve: function() { + var resolvedPath = "", resolvedAbsolute = false; + for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) { + var path = i >= 0 ? arguments[i] : FS.cwd(); + if (typeof path != "string") { + throw new TypeError("Arguments to path.resolve must be strings"); + } else if (!path) { + return ""; + } + resolvedPath = path + "/" + resolvedPath; + resolvedAbsolute = PATH.isAbs(path); + } + resolvedPath = PATH.normalizeArray(resolvedPath.split("/").filter(p => !!p), !resolvedAbsolute).join("/"); + return (resolvedAbsolute ? "/" : "") + resolvedPath || "."; + }, + relative: (from, to) => { + from = PATH_FS.resolve(from).substr(1); + to = PATH_FS.resolve(to).substr(1); + function trim(arr) { + var start = 0; + for (;start < arr.length; start++) { + if (arr[start] !== "") break; + } + var end = arr.length - 1; + for (;end >= 0; end--) { + if (arr[end] !== "") break; + } + if (start > end) return []; + return arr.slice(start, end - start + 1); + } + var fromParts = trim(from.split("/")); + var toParts = trim(to.split("/")); + var length = Math.min(fromParts.length, toParts.length); + var samePartsLength = length; + for (var i = 0; i < length; i++) { + if (fromParts[i] !== toParts[i]) { + samePartsLength = i; + break; + } + } + var outputParts = []; + for (var i = samePartsLength; i < fromParts.length; i++) { + outputParts.push(".."); + } + outputParts = outputParts.concat(toParts.slice(samePartsLength)); + return outputParts.join("/"); + } +}; + +function lengthBytesUTF8(str) { + var len = 0; + for (var i = 0; i < str.length; ++i) { + var c = str.charCodeAt(i); + if (c <= 127) { + len++; + } else if (c <= 2047) { + len += 2; + } else if (c >= 55296 && c <= 57343) { + len += 4; + ++i; + } else { + len += 3; + } + } + return len; +} + +function stringToUTF8Array(str, heap, outIdx, maxBytesToWrite) { + assert(typeof str === "string"); + if (!(maxBytesToWrite > 0)) return 0; + var startIdx = outIdx; + var endIdx = outIdx + maxBytesToWrite - 1; + for (var i = 0; i < str.length; ++i) { + var u = str.charCodeAt(i); + if (u >= 55296 && u <= 57343) { + var u1 = str.charCodeAt(++i); + u = 65536 + ((u & 1023) << 10) | u1 & 1023; + } + if (u <= 127) { + if (outIdx >= endIdx) break; + heap[outIdx++] = u; + } else if (u <= 2047) { + if (outIdx + 1 >= endIdx) break; + heap[outIdx++] = 192 | u >> 6; + heap[outIdx++] = 128 | u & 63; + } else if (u <= 65535) { + if (outIdx + 2 >= endIdx) break; + heap[outIdx++] = 224 | u >> 12; + heap[outIdx++] = 128 | u >> 6 & 63; + heap[outIdx++] = 128 | u & 63; + } else { + if (outIdx + 3 >= endIdx) break; + if (u > 1114111) warnOnce("Invalid Unicode code point " + ptrToString(u) + " encountered when serializing a JS string to a UTF-8 string in wasm memory! (Valid unicode code points should be in range 0-0x10FFFF)."); + heap[outIdx++] = 240 | u >> 18; + heap[outIdx++] = 128 | u >> 12 & 63; + heap[outIdx++] = 128 | u >> 6 & 63; + heap[outIdx++] = 128 | u & 63; + } + } + heap[outIdx] = 0; + return outIdx - startIdx; +} + +function intArrayFromString(stringy, dontAddNull, length) { + var len = length > 0 ? length : lengthBytesUTF8(stringy) + 1; + var u8array = new Array(len); + var numBytesWritten = stringToUTF8Array(stringy, u8array, 0, u8array.length); + if (dontAddNull) u8array.length = numBytesWritten; + return u8array; +} + +var UTF8Decoder = typeof TextDecoder != "undefined" ? new TextDecoder("utf8") : undefined; + +function UTF8ArrayToString(heapOrArray, idx, maxBytesToRead) { + var endIdx = idx + maxBytesToRead; + var endPtr = idx; + while (heapOrArray[endPtr] && !(endPtr >= endIdx)) ++endPtr; + if (endPtr - idx > 16 && heapOrArray.buffer && UTF8Decoder) { + return UTF8Decoder.decode(heapOrArray.buffer instanceof SharedArrayBuffer ? heapOrArray.slice(idx, endPtr) : heapOrArray.subarray(idx, endPtr)); + } + var str = ""; + while (idx < endPtr) { + var u0 = heapOrArray[idx++]; + if (!(u0 & 128)) { + str += String.fromCharCode(u0); + continue; + } + var u1 = heapOrArray[idx++] & 63; + if ((u0 & 224) == 192) { + str += String.fromCharCode((u0 & 31) << 6 | u1); + continue; + } + var u2 = heapOrArray[idx++] & 63; + if ((u0 & 240) == 224) { + u0 = (u0 & 15) << 12 | u1 << 6 | u2; + } else { + if ((u0 & 248) != 240) warnOnce("Invalid UTF-8 leading byte " + ptrToString(u0) + " encountered when deserializing a UTF-8 string in wasm memory to a JS string!"); + u0 = (u0 & 7) << 18 | u1 << 12 | u2 << 6 | heapOrArray[idx++] & 63; + } + if (u0 < 65536) { + str += String.fromCharCode(u0); + } else { + var ch = u0 - 65536; + str += String.fromCharCode(55296 | ch >> 10, 56320 | ch & 1023); + } + } + return str; +} + +var TTY = { + ttys: [], + init: function() {}, + shutdown: function() {}, + register: function(dev, ops) { + TTY.ttys[dev] = { + input: [], + output: [], + ops: ops + }; + FS.registerDevice(dev, TTY.stream_ops); + }, + stream_ops: { + open: function(stream) { + var tty = TTY.ttys[stream.node.rdev]; + if (!tty) { + throw new FS.ErrnoError(43); + } + stream.tty = tty; + stream.seekable = false; + }, + close: function(stream) { + stream.tty.ops.fsync(stream.tty); + }, + fsync: function(stream) { + stream.tty.ops.fsync(stream.tty); + }, + read: function(stream, buffer, offset, length, pos) { + if (!stream.tty || !stream.tty.ops.get_char) { + throw new FS.ErrnoError(60); + } + var bytesRead = 0; + for (var i = 0; i < length; i++) { + var result; + try { + result = stream.tty.ops.get_char(stream.tty); + } catch (e) { + throw new FS.ErrnoError(29); + } + if (result === undefined && bytesRead === 0) { + throw new FS.ErrnoError(6); + } + if (result === null || result === undefined) break; + bytesRead++; + buffer[offset + i] = result; + } + if (bytesRead) { + stream.node.timestamp = Date.now(); + } + return bytesRead; + }, + write: function(stream, buffer, offset, length, pos) { + if (!stream.tty || !stream.tty.ops.put_char) { + throw new FS.ErrnoError(60); + } + try { + for (var i = 0; i < length; i++) { + stream.tty.ops.put_char(stream.tty, buffer[offset + i]); + } + } catch (e) { + throw new FS.ErrnoError(29); + } + if (length) { + stream.node.timestamp = Date.now(); + } + return i; + } + }, + default_tty_ops: { + get_char: function(tty) { + if (!tty.input.length) { + var result = null; + if (typeof window != "undefined" && typeof window.prompt == "function") { + result = window.prompt("Input: "); + if (result !== null) { + result += "\n"; + } + } else if (typeof readline == "function") { + result = readline(); + if (result !== null) { + result += "\n"; + } + } + if (!result) { + return null; + } + tty.input = intArrayFromString(result, true); + } + return tty.input.shift(); + }, + put_char: function(tty, val) { + if (val === null || val === 10) { + out(UTF8ArrayToString(tty.output, 0)); + tty.output = []; + } else { + if (val != 0) tty.output.push(val); + } + }, + fsync: function(tty) { + if (tty.output && tty.output.length > 0) { + out(UTF8ArrayToString(tty.output, 0)); + tty.output = []; + } + } + }, + default_tty1_ops: { + put_char: function(tty, val) { + if (val === null || val === 10) { + err(UTF8ArrayToString(tty.output, 0)); + tty.output = []; + } else { + if (val != 0) tty.output.push(val); + } + }, + fsync: function(tty) { + if (tty.output && tty.output.length > 0) { + err(UTF8ArrayToString(tty.output, 0)); + tty.output = []; + } + } + } +}; + +function alignMemory(size, alignment) { + assert(alignment, "alignment argument is required"); + return Math.ceil(size / alignment) * alignment; +} + +function mmapAlloc(size) { + abort("internal error: mmapAlloc called but `emscripten_builtin_memalign` native symbol not exported"); +} + +var MEMFS = { + ops_table: null, + mount: function(mount) { + return MEMFS.createNode(null, "/", 16384 | 511, 0); + }, + createNode: function(parent, name, mode, dev) { + if (FS.isBlkdev(mode) || FS.isFIFO(mode)) { + throw new FS.ErrnoError(63); + } + if (!MEMFS.ops_table) { + MEMFS.ops_table = { + dir: { + node: { + getattr: MEMFS.node_ops.getattr, + setattr: MEMFS.node_ops.setattr, + lookup: MEMFS.node_ops.lookup, + mknod: MEMFS.node_ops.mknod, + rename: MEMFS.node_ops.rename, + unlink: MEMFS.node_ops.unlink, + rmdir: MEMFS.node_ops.rmdir, + readdir: MEMFS.node_ops.readdir, + symlink: MEMFS.node_ops.symlink + }, + stream: { + llseek: MEMFS.stream_ops.llseek + } + }, + file: { + node: { + getattr: MEMFS.node_ops.getattr, + setattr: MEMFS.node_ops.setattr + }, + stream: { + llseek: MEMFS.stream_ops.llseek, + read: MEMFS.stream_ops.read, + write: MEMFS.stream_ops.write, + allocate: MEMFS.stream_ops.allocate, + mmap: MEMFS.stream_ops.mmap, + msync: MEMFS.stream_ops.msync + } + }, + link: { + node: { + getattr: MEMFS.node_ops.getattr, + setattr: MEMFS.node_ops.setattr, + readlink: MEMFS.node_ops.readlink + }, + stream: {} + }, + chrdev: { + node: { + getattr: MEMFS.node_ops.getattr, + setattr: MEMFS.node_ops.setattr + }, + stream: FS.chrdev_stream_ops + } + }; + } + var node = FS.createNode(parent, name, mode, dev); + if (FS.isDir(node.mode)) { + node.node_ops = MEMFS.ops_table.dir.node; + node.stream_ops = MEMFS.ops_table.dir.stream; + node.contents = {}; + } else if (FS.isFile(node.mode)) { + node.node_ops = MEMFS.ops_table.file.node; + node.stream_ops = MEMFS.ops_table.file.stream; + node.usedBytes = 0; + node.contents = null; + } else if (FS.isLink(node.mode)) { + node.node_ops = MEMFS.ops_table.link.node; + node.stream_ops = MEMFS.ops_table.link.stream; + } else if (FS.isChrdev(node.mode)) { + node.node_ops = MEMFS.ops_table.chrdev.node; + node.stream_ops = MEMFS.ops_table.chrdev.stream; + } + node.timestamp = Date.now(); + if (parent) { + parent.contents[name] = node; + parent.timestamp = node.timestamp; + } + return node; + }, + getFileDataAsTypedArray: function(node) { + if (!node.contents) return new Uint8Array(0); + if (node.contents.subarray) return node.contents.subarray(0, node.usedBytes); + return new Uint8Array(node.contents); + }, + expandFileStorage: function(node, newCapacity) { + var prevCapacity = node.contents ? node.contents.length : 0; + if (prevCapacity >= newCapacity) return; + var CAPACITY_DOUBLING_MAX = 1024 * 1024; + newCapacity = Math.max(newCapacity, prevCapacity * (prevCapacity < CAPACITY_DOUBLING_MAX ? 2 : 1.125) >>> 0); + if (prevCapacity != 0) newCapacity = Math.max(newCapacity, 256); + var oldContents = node.contents; + node.contents = new Uint8Array(newCapacity); + if (node.usedBytes > 0) node.contents.set(oldContents.subarray(0, node.usedBytes), 0); + }, + resizeFileStorage: function(node, newSize) { + if (node.usedBytes == newSize) return; + if (newSize == 0) { + node.contents = null; + node.usedBytes = 0; + } else { + var oldContents = node.contents; + node.contents = new Uint8Array(newSize); + if (oldContents) { + node.contents.set(oldContents.subarray(0, Math.min(newSize, node.usedBytes))); + } + node.usedBytes = newSize; + } + }, + node_ops: { + getattr: function(node) { + var attr = {}; + attr.dev = FS.isChrdev(node.mode) ? node.id : 1; + attr.ino = node.id; + attr.mode = node.mode; + attr.nlink = 1; + attr.uid = 0; + attr.gid = 0; + attr.rdev = node.rdev; + if (FS.isDir(node.mode)) { + attr.size = 4096; + } else if (FS.isFile(node.mode)) { + attr.size = node.usedBytes; + } else if (FS.isLink(node.mode)) { + attr.size = node.link.length; + } else { + attr.size = 0; + } + attr.atime = new Date(node.timestamp); + attr.mtime = new Date(node.timestamp); + attr.ctime = new Date(node.timestamp); + attr.blksize = 4096; + attr.blocks = Math.ceil(attr.size / attr.blksize); + return attr; + }, + setattr: function(node, attr) { + if (attr.mode !== undefined) { + node.mode = attr.mode; + } + if (attr.timestamp !== undefined) { + node.timestamp = attr.timestamp; + } + if (attr.size !== undefined) { + MEMFS.resizeFileStorage(node, attr.size); + } + }, + lookup: function(parent, name) { + throw FS.genericErrors[44]; + }, + mknod: function(parent, name, mode, dev) { + return MEMFS.createNode(parent, name, mode, dev); + }, + rename: function(old_node, new_dir, new_name) { + if (FS.isDir(old_node.mode)) { + var new_node; + try { + new_node = FS.lookupNode(new_dir, new_name); + } catch (e) {} + if (new_node) { + for (var i in new_node.contents) { + throw new FS.ErrnoError(55); + } + } + } + delete old_node.parent.contents[old_node.name]; + old_node.parent.timestamp = Date.now(); + old_node.name = new_name; + new_dir.contents[new_name] = old_node; + new_dir.timestamp = old_node.parent.timestamp; + old_node.parent = new_dir; + }, + unlink: function(parent, name) { + delete parent.contents[name]; + parent.timestamp = Date.now(); + }, + rmdir: function(parent, name) { + var node = FS.lookupNode(parent, name); + for (var i in node.contents) { + throw new FS.ErrnoError(55); + } + delete parent.contents[name]; + parent.timestamp = Date.now(); + }, + readdir: function(node) { + var entries = [ ".", ".." ]; + for (var key in node.contents) { + if (!node.contents.hasOwnProperty(key)) { + continue; + } + entries.push(key); + } + return entries; + }, + symlink: function(parent, newname, oldpath) { + var node = MEMFS.createNode(parent, newname, 511 | 40960, 0); + node.link = oldpath; + return node; + }, + readlink: function(node) { + if (!FS.isLink(node.mode)) { + throw new FS.ErrnoError(28); + } + return node.link; + } + }, + stream_ops: { + read: function(stream, buffer, offset, length, position) { + var contents = stream.node.contents; + if (position >= stream.node.usedBytes) return 0; + var size = Math.min(stream.node.usedBytes - position, length); + assert(size >= 0); + if (size > 8 && contents.subarray) { + buffer.set(contents.subarray(position, position + size), offset); + } else { + for (var i = 0; i < size; i++) buffer[offset + i] = contents[position + i]; + } + return size; + }, + write: function(stream, buffer, offset, length, position, canOwn) { + assert(!(buffer instanceof ArrayBuffer)); + if (buffer.buffer === GROWABLE_HEAP_I8().buffer) { + canOwn = false; + } + if (!length) return 0; + var node = stream.node; + node.timestamp = Date.now(); + if (buffer.subarray && (!node.contents || node.contents.subarray)) { + if (canOwn) { + assert(position === 0, "canOwn must imply no weird position inside the file"); + node.contents = buffer.subarray(offset, offset + length); + node.usedBytes = length; + return length; + } else if (node.usedBytes === 0 && position === 0) { + node.contents = buffer.slice(offset, offset + length); + node.usedBytes = length; + return length; + } else if (position + length <= node.usedBytes) { + node.contents.set(buffer.subarray(offset, offset + length), position); + return length; + } + } + MEMFS.expandFileStorage(node, position + length); + if (node.contents.subarray && buffer.subarray) { + node.contents.set(buffer.subarray(offset, offset + length), position); + } else { + for (var i = 0; i < length; i++) { + node.contents[position + i] = buffer[offset + i]; + } + } + node.usedBytes = Math.max(node.usedBytes, position + length); + return length; + }, + llseek: function(stream, offset, whence) { + var position = offset; + if (whence === 1) { + position += stream.position; + } else if (whence === 2) { + if (FS.isFile(stream.node.mode)) { + position += stream.node.usedBytes; + } + } + if (position < 0) { + throw new FS.ErrnoError(28); + } + return position; + }, + allocate: function(stream, offset, length) { + MEMFS.expandFileStorage(stream.node, offset + length); + stream.node.usedBytes = Math.max(stream.node.usedBytes, offset + length); + }, + mmap: function(stream, length, position, prot, flags) { + if (!FS.isFile(stream.node.mode)) { + throw new FS.ErrnoError(43); + } + var ptr; + var allocated; + var contents = stream.node.contents; + if (!(flags & 2) && contents.buffer === GROWABLE_HEAP_I8().buffer) { + allocated = false; + ptr = contents.byteOffset; + } else { + if (position > 0 || position + length < contents.length) { + if (contents.subarray) { + contents = contents.subarray(position, position + length); + } else { + contents = Array.prototype.slice.call(contents, position, position + length); + } + } + allocated = true; + ptr = mmapAlloc(length); + if (!ptr) { + throw new FS.ErrnoError(48); + } + GROWABLE_HEAP_I8().set(contents, ptr); + } + return { + ptr: ptr, + allocated: allocated + }; + }, + msync: function(stream, buffer, offset, length, mmapFlags) { + MEMFS.stream_ops.write(stream, buffer, 0, length, offset, false); + return 0; + } + } +}; + +function asyncLoad(url, onload, onerror, noRunDep) { + var dep = !noRunDep ? getUniqueRunDependency(`al ${url}`) : ""; + readAsync(url, arrayBuffer => { + assert(arrayBuffer, `Loading data file "${url}" failed (no arrayBuffer).`); + onload(new Uint8Array(arrayBuffer)); + if (dep) removeRunDependency(dep); + }, event => { + if (onerror) { + onerror(); + } else { + throw `Loading data file "${url}" failed.`; + } + }); + if (dep) addRunDependency(dep); +} + +var preloadPlugins = Module["preloadPlugins"] || []; + +function FS_handledByPreloadPlugin(byteArray, fullname, finish, onerror) { + if (typeof Browser != "undefined") Browser.init(); + var handled = false; + preloadPlugins.forEach(function(plugin) { + if (handled) return; + if (plugin["canHandle"](fullname)) { + plugin["handle"](byteArray, fullname, finish, onerror); + handled = true; + } + }); + return handled; +} + +function FS_createPreloadedFile(parent, name, url, canRead, canWrite, onload, onerror, dontCreateFile, canOwn, preFinish) { + var fullname = name ? PATH_FS.resolve(PATH.join2(parent, name)) : parent; + var dep = getUniqueRunDependency(`cp ${fullname}`); + function processData(byteArray) { + function finish(byteArray) { + if (preFinish) preFinish(); + if (!dontCreateFile) { + FS.createDataFile(parent, name, byteArray, canRead, canWrite, canOwn); + } + if (onload) onload(); + removeRunDependency(dep); + } + if (FS_handledByPreloadPlugin(byteArray, fullname, finish, () => { + if (onerror) onerror(); + removeRunDependency(dep); + })) { + return; + } + finish(byteArray); + } + addRunDependency(dep); + if (typeof url == "string") { + asyncLoad(url, byteArray => processData(byteArray), onerror); + } else { + processData(url); + } +} + +function FS_modeStringToFlags(str) { + var flagModes = { + "r": 0, + "r+": 2, + "w": 512 | 64 | 1, + "w+": 512 | 64 | 2, + "a": 1024 | 64 | 1, + "a+": 1024 | 64 | 2 + }; + var flags = flagModes[str]; + if (typeof flags == "undefined") { + throw new Error(`Unknown file open mode: ${str}`); + } + return flags; +} + +function FS_getMode(canRead, canWrite) { + var mode = 0; + if (canRead) mode |= 292 | 73; + if (canWrite) mode |= 146; + return mode; +} + +var IDBFS = { + dbs: {}, + indexedDB: () => { + if (typeof indexedDB != "undefined") return indexedDB; + var ret = null; + if (typeof window == "object") ret = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB; + assert(ret, "IDBFS used, but indexedDB not supported"); + return ret; + }, + DB_VERSION: 21, + DB_STORE_NAME: "FILE_DATA", + mount: function(mount) { + return MEMFS.mount.apply(null, arguments); + }, + syncfs: (mount, populate, callback) => { + IDBFS.getLocalSet(mount, (err, local) => { + if (err) return callback(err); + IDBFS.getRemoteSet(mount, (err, remote) => { + if (err) return callback(err); + var src = populate ? remote : local; + var dst = populate ? local : remote; + IDBFS.reconcile(src, dst, callback); + }); + }); + }, + quit: () => { + Object.values(IDBFS.dbs).forEach(value => value.close()); + IDBFS.dbs = {}; + }, + getDB: (name, callback) => { + var db = IDBFS.dbs[name]; + if (db) { + return callback(null, db); + } + var req; + try { + req = IDBFS.indexedDB().open(name, IDBFS.DB_VERSION); + } catch (e) { + return callback(e); + } + if (!req) { + return callback("Unable to connect to IndexedDB"); + } + req.onupgradeneeded = e => { + var db = e.target.result; + var transaction = e.target.transaction; + var fileStore; + if (db.objectStoreNames.contains(IDBFS.DB_STORE_NAME)) { + fileStore = transaction.objectStore(IDBFS.DB_STORE_NAME); + } else { + fileStore = db.createObjectStore(IDBFS.DB_STORE_NAME); + } + if (!fileStore.indexNames.contains("timestamp")) { + fileStore.createIndex("timestamp", "timestamp", { + unique: false + }); + } + }; + req.onsuccess = () => { + db = req.result; + IDBFS.dbs[name] = db; + callback(null, db); + }; + req.onerror = e => { + callback(this.error); + e.preventDefault(); + }; + }, + getLocalSet: (mount, callback) => { + var entries = {}; + function isRealDir(p) { + return p !== "." && p !== ".."; + } + function toAbsolute(root) { + return p => { + return PATH.join2(root, p); + }; + } + var check = FS.readdir(mount.mountpoint).filter(isRealDir).map(toAbsolute(mount.mountpoint)); + while (check.length) { + var path = check.pop(); + var stat; + try { + stat = FS.stat(path); + } catch (e) { + return callback(e); + } + if (FS.isDir(stat.mode)) { + check.push.apply(check, FS.readdir(path).filter(isRealDir).map(toAbsolute(path))); + } + entries[path] = { + "timestamp": stat.mtime + }; + } + return callback(null, { + type: "local", + entries: entries + }); + }, + getRemoteSet: (mount, callback) => { + var entries = {}; + IDBFS.getDB(mount.mountpoint, (err, db) => { + if (err) return callback(err); + try { + var transaction = db.transaction([ IDBFS.DB_STORE_NAME ], "readonly"); + transaction.onerror = e => { + callback(this.error); + e.preventDefault(); + }; + var store = transaction.objectStore(IDBFS.DB_STORE_NAME); + var index = store.index("timestamp"); + index.openKeyCursor().onsuccess = event => { + var cursor = event.target.result; + if (!cursor) { + return callback(null, { + type: "remote", + db: db, + entries: entries + }); + } + entries[cursor.primaryKey] = { + "timestamp": cursor.key + }; + cursor.continue(); + }; + } catch (e) { + return callback(e); + } + }); + }, + loadLocalEntry: (path, callback) => { + var stat, node; + try { + var lookup = FS.lookupPath(path); + node = lookup.node; + stat = FS.stat(path); + } catch (e) { + return callback(e); + } + if (FS.isDir(stat.mode)) { + return callback(null, { + "timestamp": stat.mtime, + "mode": stat.mode + }); + } else if (FS.isFile(stat.mode)) { + node.contents = MEMFS.getFileDataAsTypedArray(node); + return callback(null, { + "timestamp": stat.mtime, + "mode": stat.mode, + "contents": node.contents + }); + } else { + return callback(new Error("node type not supported")); + } + }, + storeLocalEntry: (path, entry, callback) => { + try { + if (FS.isDir(entry["mode"])) { + FS.mkdirTree(path, entry["mode"]); + } else if (FS.isFile(entry["mode"])) { + FS.writeFile(path, entry["contents"], { + canOwn: true + }); + } else { + return callback(new Error("node type not supported")); + } + FS.chmod(path, entry["mode"]); + FS.utime(path, entry["timestamp"], entry["timestamp"]); + } catch (e) { + return callback(e); + } + callback(null); + }, + removeLocalEntry: (path, callback) => { + try { + var stat = FS.stat(path); + if (FS.isDir(stat.mode)) { + FS.rmdir(path); + } else if (FS.isFile(stat.mode)) { + FS.unlink(path); + } + } catch (e) { + return callback(e); + } + callback(null); + }, + loadRemoteEntry: (store, path, callback) => { + var req = store.get(path); + req.onsuccess = event => { + callback(null, event.target.result); + }; + req.onerror = e => { + callback(this.error); + e.preventDefault(); + }; + }, + storeRemoteEntry: (store, path, entry, callback) => { + try { + var req = store.put(entry, path); + } catch (e) { + callback(e); + return; + } + req.onsuccess = () => { + callback(null); + }; + req.onerror = e => { + callback(this.error); + e.preventDefault(); + }; + }, + removeRemoteEntry: (store, path, callback) => { + var req = store.delete(path); + req.onsuccess = () => { + callback(null); + }; + req.onerror = e => { + callback(this.error); + e.preventDefault(); + }; + }, + reconcile: (src, dst, callback) => { + var total = 0; + var create = []; + Object.keys(src.entries).forEach(function(key) { + var e = src.entries[key]; + var e2 = dst.entries[key]; + if (!e2 || e["timestamp"].getTime() != e2["timestamp"].getTime()) { + create.push(key); + total++; + } + }); + var remove = []; + Object.keys(dst.entries).forEach(function(key) { + if (!src.entries[key]) { + remove.push(key); + total++; + } + }); + if (!total) { + return callback(null); + } + var errored = false; + var db = src.type === "remote" ? src.db : dst.db; + var transaction = db.transaction([ IDBFS.DB_STORE_NAME ], "readwrite"); + var store = transaction.objectStore(IDBFS.DB_STORE_NAME); + function done(err) { + if (err && !errored) { + errored = true; + return callback(err); + } + } + transaction.onerror = e => { + done(this.error); + e.preventDefault(); + }; + transaction.oncomplete = e => { + if (!errored) { + callback(null); + } + }; + create.sort().forEach(path => { + if (dst.type === "local") { + IDBFS.loadRemoteEntry(store, path, (err, entry) => { + if (err) return done(err); + IDBFS.storeLocalEntry(path, entry, done); + }); + } else { + IDBFS.loadLocalEntry(path, (err, entry) => { + if (err) return done(err); + IDBFS.storeRemoteEntry(store, path, entry, done); + }); + } + }); + remove.sort().reverse().forEach(path => { + if (dst.type === "local") { + IDBFS.removeLocalEntry(path, done); + } else { + IDBFS.removeRemoteEntry(store, path, done); + } + }); + } +}; + +var ERRNO_MESSAGES = { + 0: "Success", + 1: "Arg list too long", + 2: "Permission denied", + 3: "Address already in use", + 4: "Address not available", + 5: "Address family not supported by protocol family", + 6: "No more processes", + 7: "Socket already connected", + 8: "Bad file number", + 9: "Trying to read unreadable message", + 10: "Mount device busy", + 11: "Operation canceled", + 12: "No children", + 13: "Connection aborted", + 14: "Connection refused", + 15: "Connection reset by peer", + 16: "File locking deadlock error", + 17: "Destination address required", + 18: "Math arg out of domain of func", + 19: "Quota exceeded", + 20: "File exists", + 21: "Bad address", + 22: "File too large", + 23: "Host is unreachable", + 24: "Identifier removed", + 25: "Illegal byte sequence", + 26: "Connection already in progress", + 27: "Interrupted system call", + 28: "Invalid argument", + 29: "I/O error", + 30: "Socket is already connected", + 31: "Is a directory", + 32: "Too many symbolic links", + 33: "Too many open files", + 34: "Too many links", + 35: "Message too long", + 36: "Multihop attempted", + 37: "File or path name too long", + 38: "Network interface is not configured", + 39: "Connection reset by network", + 40: "Network is unreachable", + 41: "Too many open files in system", + 42: "No buffer space available", + 43: "No such device", + 44: "No such file or directory", + 45: "Exec format error", + 46: "No record locks available", + 47: "The link has been severed", + 48: "Not enough core", + 49: "No message of desired type", + 50: "Protocol not available", + 51: "No space left on device", + 52: "Function not implemented", + 53: "Socket is not connected", + 54: "Not a directory", + 55: "Directory not empty", + 56: "State not recoverable", + 57: "Socket operation on non-socket", + 59: "Not a typewriter", + 60: "No such device or address", + 61: "Value too large for defined data type", + 62: "Previous owner died", + 63: "Not super-user", + 64: "Broken pipe", + 65: "Protocol error", + 66: "Unknown protocol", + 67: "Protocol wrong type for socket", + 68: "Math result not representable", + 69: "Read only file system", + 70: "Illegal seek", + 71: "No such process", + 72: "Stale file handle", + 73: "Connection timed out", + 74: "Text file busy", + 75: "Cross-device link", + 100: "Device not a stream", + 101: "Bad font file fmt", + 102: "Invalid slot", + 103: "Invalid request code", + 104: "No anode", + 105: "Block device required", + 106: "Channel number out of range", + 107: "Level 3 halted", + 108: "Level 3 reset", + 109: "Link number out of range", + 110: "Protocol driver not attached", + 111: "No CSI structure available", + 112: "Level 2 halted", + 113: "Invalid exchange", + 114: "Invalid request descriptor", + 115: "Exchange full", + 116: "No data (for no delay io)", + 117: "Timer expired", + 118: "Out of streams resources", + 119: "Machine is not on the network", + 120: "Package not installed", + 121: "The object is remote", + 122: "Advertise error", + 123: "Srmount error", + 124: "Communication error on send", + 125: "Cross mount point (not really error)", + 126: "Given log. name not unique", + 127: "f.d. invalid for this operation", + 128: "Remote address changed", + 129: "Can access a needed shared lib", + 130: "Accessing a corrupted shared lib", + 131: ".lib section in a.out corrupted", + 132: "Attempting to link in too many libs", + 133: "Attempting to exec a shared library", + 135: "Streams pipe error", + 136: "Too many users", + 137: "Socket type not supported", + 138: "Not supported", + 139: "Protocol family not supported", + 140: "Can't send after socket shutdown", + 141: "Too many references", + 142: "Host is down", + 148: "No medium (in tape drive)", + 156: "Level 2 not synchronized" +}; + +var ERRNO_CODES = {}; + +function demangle(func) { + warnOnce("warning: build with -sDEMANGLE_SUPPORT to link in libcxxabi demangling"); + return func; +} + +function demangleAll(text) { + var regex = /\b_Z[\w\d_]+/g; + return text.replace(regex, function(x) { + var y = demangle(x); + return x === y ? x : y + " [" + x + "]"; + }); +} + +var FS = { + root: null, + mounts: [], + devices: {}, + streams: [], + nextInode: 1, + nameTable: null, + currentPath: "/", + initialized: false, + ignorePermissions: true, + ErrnoError: null, + genericErrors: {}, + filesystems: null, + syncFSRequests: 0, + lookupPath: (path, opts = {}) => { + path = PATH_FS.resolve(path); + if (!path) return { + path: "", + node: null + }; + var defaults = { + follow_mount: true, + recurse_count: 0 + }; + opts = Object.assign(defaults, opts); + if (opts.recurse_count > 8) { + throw new FS.ErrnoError(32); + } + var parts = path.split("/").filter(p => !!p); + var current = FS.root; + var current_path = "/"; + for (var i = 0; i < parts.length; i++) { + var islast = i === parts.length - 1; + if (islast && opts.parent) { + break; + } + current = FS.lookupNode(current, parts[i]); + current_path = PATH.join2(current_path, parts[i]); + if (FS.isMountpoint(current)) { + if (!islast || islast && opts.follow_mount) { + current = current.mounted.root; + } + } + if (!islast || opts.follow) { + var count = 0; + while (FS.isLink(current.mode)) { + var link = FS.readlink(current_path); + current_path = PATH_FS.resolve(PATH.dirname(current_path), link); + var lookup = FS.lookupPath(current_path, { + recurse_count: opts.recurse_count + 1 + }); + current = lookup.node; + if (count++ > 40) { + throw new FS.ErrnoError(32); + } + } + } + } + return { + path: current_path, + node: current + }; + }, + getPath: node => { + var path; + while (true) { + if (FS.isRoot(node)) { + var mount = node.mount.mountpoint; + if (!path) return mount; + return mount[mount.length - 1] !== "/" ? `${mount}/${path}` : mount + path; + } + path = path ? `${node.name}/${path}` : node.name; + node = node.parent; + } + }, + hashName: (parentid, name) => { + var hash = 0; + for (var i = 0; i < name.length; i++) { + hash = (hash << 5) - hash + name.charCodeAt(i) | 0; + } + return (parentid + hash >>> 0) % FS.nameTable.length; + }, + hashAddNode: node => { + var hash = FS.hashName(node.parent.id, node.name); + node.name_next = FS.nameTable[hash]; + FS.nameTable[hash] = node; + }, + hashRemoveNode: node => { + var hash = FS.hashName(node.parent.id, node.name); + if (FS.nameTable[hash] === node) { + FS.nameTable[hash] = node.name_next; + } else { + var current = FS.nameTable[hash]; + while (current) { + if (current.name_next === node) { + current.name_next = node.name_next; + break; + } + current = current.name_next; + } + } + }, + lookupNode: (parent, name) => { + var errCode = FS.mayLookup(parent); + if (errCode) { + throw new FS.ErrnoError(errCode, parent); + } + var hash = FS.hashName(parent.id, name); + for (var node = FS.nameTable[hash]; node; node = node.name_next) { + var nodeName = node.name; + if (node.parent.id === parent.id && nodeName === name) { + return node; + } + } + return FS.lookup(parent, name); + }, + createNode: (parent, name, mode, rdev) => { + assert(typeof parent == "object"); + var node = new FS.FSNode(parent, name, mode, rdev); + FS.hashAddNode(node); + return node; + }, + destroyNode: node => { + FS.hashRemoveNode(node); + }, + isRoot: node => { + return node === node.parent; + }, + isMountpoint: node => { + return !!node.mounted; + }, + isFile: mode => { + return (mode & 61440) === 32768; + }, + isDir: mode => { + return (mode & 61440) === 16384; + }, + isLink: mode => { + return (mode & 61440) === 40960; + }, + isChrdev: mode => { + return (mode & 61440) === 8192; + }, + isBlkdev: mode => { + return (mode & 61440) === 24576; + }, + isFIFO: mode => { + return (mode & 61440) === 4096; + }, + isSocket: mode => { + return (mode & 49152) === 49152; + }, + flagsToPermissionString: flag => { + var perms = [ "r", "w", "rw" ][flag & 3]; + if (flag & 512) { + perms += "w"; + } + return perms; + }, + nodePermissions: (node, perms) => { + if (FS.ignorePermissions) { + return 0; + } + if (perms.includes("r") && !(node.mode & 292)) { + return 2; + } else if (perms.includes("w") && !(node.mode & 146)) { + return 2; + } else if (perms.includes("x") && !(node.mode & 73)) { + return 2; + } + return 0; + }, + mayLookup: dir => { + var errCode = FS.nodePermissions(dir, "x"); + if (errCode) return errCode; + if (!dir.node_ops.lookup) return 2; + return 0; + }, + mayCreate: (dir, name) => { + try { + var node = FS.lookupNode(dir, name); + return 20; + } catch (e) {} + return FS.nodePermissions(dir, "wx"); + }, + mayDelete: (dir, name, isdir) => { + var node; + try { + node = FS.lookupNode(dir, name); + } catch (e) { + return e.errno; + } + var errCode = FS.nodePermissions(dir, "wx"); + if (errCode) { + return errCode; + } + if (isdir) { + if (!FS.isDir(node.mode)) { + return 54; + } + if (FS.isRoot(node) || FS.getPath(node) === FS.cwd()) { + return 10; + } + } else { + if (FS.isDir(node.mode)) { + return 31; + } + } + return 0; + }, + mayOpen: (node, flags) => { + if (!node) { + return 44; + } + if (FS.isLink(node.mode)) { + return 32; + } else if (FS.isDir(node.mode)) { + if (FS.flagsToPermissionString(flags) !== "r" || flags & 512) { + return 31; + } + } + return FS.nodePermissions(node, FS.flagsToPermissionString(flags)); + }, + MAX_OPEN_FDS: 4096, + nextfd: (fd_start = 0, fd_end = FS.MAX_OPEN_FDS) => { + for (var fd = fd_start; fd <= fd_end; fd++) { + if (!FS.streams[fd]) { + return fd; + } + } + throw new FS.ErrnoError(33); + }, + getStream: fd => FS.streams[fd], + createStream: (stream, fd_start, fd_end) => { + if (!FS.FSStream) { + FS.FSStream = function() { + this.shared = {}; + }; + FS.FSStream.prototype = {}; + Object.defineProperties(FS.FSStream.prototype, { + object: { + get: function() { + return this.node; + }, + set: function(val) { + this.node = val; + } + }, + isRead: { + get: function() { + return (this.flags & 2097155) !== 1; + } + }, + isWrite: { + get: function() { + return (this.flags & 2097155) !== 0; + } + }, + isAppend: { + get: function() { + return this.flags & 1024; + } + }, + flags: { + get: function() { + return this.shared.flags; + }, + set: function(val) { + this.shared.flags = val; + } + }, + position: { + get: function() { + return this.shared.position; + }, + set: function(val) { + this.shared.position = val; + } + } + }); + } + stream = Object.assign(new FS.FSStream(), stream); + var fd = FS.nextfd(fd_start, fd_end); + stream.fd = fd; + FS.streams[fd] = stream; + return stream; + }, + closeStream: fd => { + FS.streams[fd] = null; + }, + chrdev_stream_ops: { + open: stream => { + var device = FS.getDevice(stream.node.rdev); + stream.stream_ops = device.stream_ops; + if (stream.stream_ops.open) { + stream.stream_ops.open(stream); + } + }, + llseek: () => { + throw new FS.ErrnoError(70); + } + }, + major: dev => dev >> 8, + minor: dev => dev & 255, + makedev: (ma, mi) => ma << 8 | mi, + registerDevice: (dev, ops) => { + FS.devices[dev] = { + stream_ops: ops + }; + }, + getDevice: dev => FS.devices[dev], + getMounts: mount => { + var mounts = []; + var check = [ mount ]; + while (check.length) { + var m = check.pop(); + mounts.push(m); + check.push.apply(check, m.mounts); + } + return mounts; + }, + syncfs: (populate, callback) => { + if (typeof populate == "function") { + callback = populate; + populate = false; + } + FS.syncFSRequests++; + if (FS.syncFSRequests > 1) { + err(`warning: ${FS.syncFSRequests} FS.syncfs operations in flight at once, probably just doing extra work`); + } + var mounts = FS.getMounts(FS.root.mount); + var completed = 0; + function doCallback(errCode) { + assert(FS.syncFSRequests > 0); + FS.syncFSRequests--; + return callback(errCode); + } + function done(errCode) { + if (errCode) { + if (!done.errored) { + done.errored = true; + return doCallback(errCode); + } + return; + } + if (++completed >= mounts.length) { + doCallback(null); + } + } + mounts.forEach(mount => { + if (!mount.type.syncfs) { + return done(null); + } + mount.type.syncfs(mount, populate, done); + }); + }, + mount: (type, opts, mountpoint) => { + if (typeof type == "string") { + throw type; + } + var root = mountpoint === "/"; + var pseudo = !mountpoint; + var node; + if (root && FS.root) { + throw new FS.ErrnoError(10); + } else if (!root && !pseudo) { + var lookup = FS.lookupPath(mountpoint, { + follow_mount: false + }); + mountpoint = lookup.path; + node = lookup.node; + if (FS.isMountpoint(node)) { + throw new FS.ErrnoError(10); + } + if (!FS.isDir(node.mode)) { + throw new FS.ErrnoError(54); + } + } + var mount = { + type: type, + opts: opts, + mountpoint: mountpoint, + mounts: [] + }; + var mountRoot = type.mount(mount); + mountRoot.mount = mount; + mount.root = mountRoot; + if (root) { + FS.root = mountRoot; + } else if (node) { + node.mounted = mount; + if (node.mount) { + node.mount.mounts.push(mount); + } + } + return mountRoot; + }, + unmount: mountpoint => { + var lookup = FS.lookupPath(mountpoint, { + follow_mount: false + }); + if (!FS.isMountpoint(lookup.node)) { + throw new FS.ErrnoError(28); + } + var node = lookup.node; + var mount = node.mounted; + var mounts = FS.getMounts(mount); + Object.keys(FS.nameTable).forEach(hash => { + var current = FS.nameTable[hash]; + while (current) { + var next = current.name_next; + if (mounts.includes(current.mount)) { + FS.destroyNode(current); + } + current = next; + } + }); + node.mounted = null; + var idx = node.mount.mounts.indexOf(mount); + assert(idx !== -1); + node.mount.mounts.splice(idx, 1); + }, + lookup: (parent, name) => { + return parent.node_ops.lookup(parent, name); + }, + mknod: (path, mode, dev) => { + var lookup = FS.lookupPath(path, { + parent: true + }); + var parent = lookup.node; + var name = PATH.basename(path); + if (!name || name === "." || name === "..") { + throw new FS.ErrnoError(28); + } + var errCode = FS.mayCreate(parent, name); + if (errCode) { + throw new FS.ErrnoError(errCode); + } + if (!parent.node_ops.mknod) { + throw new FS.ErrnoError(63); + } + return parent.node_ops.mknod(parent, name, mode, dev); + }, + create: (path, mode) => { + mode = mode !== undefined ? mode : 438; + mode &= 4095; + mode |= 32768; + return FS.mknod(path, mode, 0); + }, + mkdir: (path, mode) => { + mode = mode !== undefined ? mode : 511; + mode &= 511 | 512; + mode |= 16384; + return FS.mknod(path, mode, 0); + }, + mkdirTree: (path, mode) => { + var dirs = path.split("/"); + var d = ""; + for (var i = 0; i < dirs.length; ++i) { + if (!dirs[i]) continue; + d += "/" + dirs[i]; + try { + FS.mkdir(d, mode); + } catch (e) { + if (e.errno != 20) throw e; + } + } + }, + mkdev: (path, mode, dev) => { + if (typeof dev == "undefined") { + dev = mode; + mode = 438; + } + mode |= 8192; + return FS.mknod(path, mode, dev); + }, + symlink: (oldpath, newpath) => { + if (!PATH_FS.resolve(oldpath)) { + throw new FS.ErrnoError(44); + } + var lookup = FS.lookupPath(newpath, { + parent: true + }); + var parent = lookup.node; + if (!parent) { + throw new FS.ErrnoError(44); + } + var newname = PATH.basename(newpath); + var errCode = FS.mayCreate(parent, newname); + if (errCode) { + throw new FS.ErrnoError(errCode); + } + if (!parent.node_ops.symlink) { + throw new FS.ErrnoError(63); + } + return parent.node_ops.symlink(parent, newname, oldpath); + }, + rename: (old_path, new_path) => { + var old_dirname = PATH.dirname(old_path); + var new_dirname = PATH.dirname(new_path); + var old_name = PATH.basename(old_path); + var new_name = PATH.basename(new_path); + var lookup, old_dir, new_dir; + lookup = FS.lookupPath(old_path, { + parent: true + }); + old_dir = lookup.node; + lookup = FS.lookupPath(new_path, { + parent: true + }); + new_dir = lookup.node; + if (!old_dir || !new_dir) throw new FS.ErrnoError(44); + if (old_dir.mount !== new_dir.mount) { + throw new FS.ErrnoError(75); + } + var old_node = FS.lookupNode(old_dir, old_name); + var relative = PATH_FS.relative(old_path, new_dirname); + if (relative.charAt(0) !== ".") { + throw new FS.ErrnoError(28); + } + relative = PATH_FS.relative(new_path, old_dirname); + if (relative.charAt(0) !== ".") { + throw new FS.ErrnoError(55); + } + var new_node; + try { + new_node = FS.lookupNode(new_dir, new_name); + } catch (e) {} + if (old_node === new_node) { + return; + } + var isdir = FS.isDir(old_node.mode); + var errCode = FS.mayDelete(old_dir, old_name, isdir); + if (errCode) { + throw new FS.ErrnoError(errCode); + } + errCode = new_node ? FS.mayDelete(new_dir, new_name, isdir) : FS.mayCreate(new_dir, new_name); + if (errCode) { + throw new FS.ErrnoError(errCode); + } + if (!old_dir.node_ops.rename) { + throw new FS.ErrnoError(63); + } + if (FS.isMountpoint(old_node) || new_node && FS.isMountpoint(new_node)) { + throw new FS.ErrnoError(10); + } + if (new_dir !== old_dir) { + errCode = FS.nodePermissions(old_dir, "w"); + if (errCode) { + throw new FS.ErrnoError(errCode); + } + } + FS.hashRemoveNode(old_node); + try { + old_dir.node_ops.rename(old_node, new_dir, new_name); + } catch (e) { + throw e; + } finally { + FS.hashAddNode(old_node); + } + }, + rmdir: path => { + var lookup = FS.lookupPath(path, { + parent: true + }); + var parent = lookup.node; + var name = PATH.basename(path); + var node = FS.lookupNode(parent, name); + var errCode = FS.mayDelete(parent, name, true); + if (errCode) { + throw new FS.ErrnoError(errCode); + } + if (!parent.node_ops.rmdir) { + throw new FS.ErrnoError(63); + } + if (FS.isMountpoint(node)) { + throw new FS.ErrnoError(10); + } + parent.node_ops.rmdir(parent, name); + FS.destroyNode(node); + }, + readdir: path => { + var lookup = FS.lookupPath(path, { + follow: true + }); + var node = lookup.node; + if (!node.node_ops.readdir) { + throw new FS.ErrnoError(54); + } + return node.node_ops.readdir(node); + }, + unlink: path => { + var lookup = FS.lookupPath(path, { + parent: true + }); + var parent = lookup.node; + if (!parent) { + throw new FS.ErrnoError(44); + } + var name = PATH.basename(path); + var node = FS.lookupNode(parent, name); + var errCode = FS.mayDelete(parent, name, false); + if (errCode) { + throw new FS.ErrnoError(errCode); + } + if (!parent.node_ops.unlink) { + throw new FS.ErrnoError(63); + } + if (FS.isMountpoint(node)) { + throw new FS.ErrnoError(10); + } + parent.node_ops.unlink(parent, name); + FS.destroyNode(node); + }, + readlink: path => { + var lookup = FS.lookupPath(path); + var link = lookup.node; + if (!link) { + throw new FS.ErrnoError(44); + } + if (!link.node_ops.readlink) { + throw new FS.ErrnoError(28); + } + return PATH_FS.resolve(FS.getPath(link.parent), link.node_ops.readlink(link)); + }, + stat: (path, dontFollow) => { + var lookup = FS.lookupPath(path, { + follow: !dontFollow + }); + var node = lookup.node; + if (!node) { + throw new FS.ErrnoError(44); + } + if (!node.node_ops.getattr) { + throw new FS.ErrnoError(63); + } + return node.node_ops.getattr(node); + }, + lstat: path => { + return FS.stat(path, true); + }, + chmod: (path, mode, dontFollow) => { + var node; + if (typeof path == "string") { + var lookup = FS.lookupPath(path, { + follow: !dontFollow + }); + node = lookup.node; + } else { + node = path; + } + if (!node.node_ops.setattr) { + throw new FS.ErrnoError(63); + } + node.node_ops.setattr(node, { + mode: mode & 4095 | node.mode & ~4095, + timestamp: Date.now() + }); + }, + lchmod: (path, mode) => { + FS.chmod(path, mode, true); + }, + fchmod: (fd, mode) => { + var stream = FS.getStream(fd); + if (!stream) { + throw new FS.ErrnoError(8); + } + FS.chmod(stream.node, mode); + }, + chown: (path, uid, gid, dontFollow) => { + var node; + if (typeof path == "string") { + var lookup = FS.lookupPath(path, { + follow: !dontFollow + }); + node = lookup.node; + } else { + node = path; + } + if (!node.node_ops.setattr) { + throw new FS.ErrnoError(63); + } + node.node_ops.setattr(node, { + timestamp: Date.now() + }); + }, + lchown: (path, uid, gid) => { + FS.chown(path, uid, gid, true); + }, + fchown: (fd, uid, gid) => { + var stream = FS.getStream(fd); + if (!stream) { + throw new FS.ErrnoError(8); + } + FS.chown(stream.node, uid, gid); + }, + truncate: (path, len) => { + if (len < 0) { + throw new FS.ErrnoError(28); + } + var node; + if (typeof path == "string") { + var lookup = FS.lookupPath(path, { + follow: true + }); + node = lookup.node; + } else { + node = path; + } + if (!node.node_ops.setattr) { + throw new FS.ErrnoError(63); + } + if (FS.isDir(node.mode)) { + throw new FS.ErrnoError(31); + } + if (!FS.isFile(node.mode)) { + throw new FS.ErrnoError(28); + } + var errCode = FS.nodePermissions(node, "w"); + if (errCode) { + throw new FS.ErrnoError(errCode); + } + node.node_ops.setattr(node, { + size: len, + timestamp: Date.now() + }); + }, + ftruncate: (fd, len) => { + var stream = FS.getStream(fd); + if (!stream) { + throw new FS.ErrnoError(8); + } + if ((stream.flags & 2097155) === 0) { + throw new FS.ErrnoError(28); + } + FS.truncate(stream.node, len); + }, + utime: (path, atime, mtime) => { + var lookup = FS.lookupPath(path, { + follow: true + }); + var node = lookup.node; + node.node_ops.setattr(node, { + timestamp: Math.max(atime, mtime) + }); + }, + open: (path, flags, mode) => { + if (path === "") { + throw new FS.ErrnoError(44); + } + flags = typeof flags == "string" ? FS_modeStringToFlags(flags) : flags; + mode = typeof mode == "undefined" ? 438 : mode; + if (flags & 64) { + mode = mode & 4095 | 32768; + } else { + mode = 0; + } + var node; + if (typeof path == "object") { + node = path; + } else { + path = PATH.normalize(path); + try { + var lookup = FS.lookupPath(path, { + follow: !(flags & 131072) + }); + node = lookup.node; + } catch (e) {} + } + var created = false; + if (flags & 64) { + if (node) { + if (flags & 128) { + throw new FS.ErrnoError(20); + } + } else { + node = FS.mknod(path, mode, 0); + created = true; + } + } + if (!node) { + throw new FS.ErrnoError(44); + } + if (FS.isChrdev(node.mode)) { + flags &= ~512; + } + if (flags & 65536 && !FS.isDir(node.mode)) { + throw new FS.ErrnoError(54); + } + if (!created) { + var errCode = FS.mayOpen(node, flags); + if (errCode) { + throw new FS.ErrnoError(errCode); + } + } + if (flags & 512 && !created) { + FS.truncate(node, 0); + } + flags &= ~(128 | 512 | 131072); + var stream = FS.createStream({ + node: node, + path: FS.getPath(node), + flags: flags, + seekable: true, + position: 0, + stream_ops: node.stream_ops, + ungotten: [], + error: false + }); + if (stream.stream_ops.open) { + stream.stream_ops.open(stream); + } + if (Module["logReadFiles"] && !(flags & 1)) { + if (!FS.readFiles) FS.readFiles = {}; + if (!(path in FS.readFiles)) { + FS.readFiles[path] = 1; + } + } + return stream; + }, + close: stream => { + if (FS.isClosed(stream)) { + throw new FS.ErrnoError(8); + } + if (stream.getdents) stream.getdents = null; + try { + if (stream.stream_ops.close) { + stream.stream_ops.close(stream); + } + } catch (e) { + throw e; + } finally { + FS.closeStream(stream.fd); + } + stream.fd = null; + }, + isClosed: stream => { + return stream.fd === null; + }, + llseek: (stream, offset, whence) => { + if (FS.isClosed(stream)) { + throw new FS.ErrnoError(8); + } + if (!stream.seekable || !stream.stream_ops.llseek) { + throw new FS.ErrnoError(70); + } + if (whence != 0 && whence != 1 && whence != 2) { + throw new FS.ErrnoError(28); + } + stream.position = stream.stream_ops.llseek(stream, offset, whence); + stream.ungotten = []; + return stream.position; + }, + read: (stream, buffer, offset, length, position) => { + if (length < 0 || position < 0) { + throw new FS.ErrnoError(28); + } + if (FS.isClosed(stream)) { + throw new FS.ErrnoError(8); + } + if ((stream.flags & 2097155) === 1) { + throw new FS.ErrnoError(8); + } + if (FS.isDir(stream.node.mode)) { + throw new FS.ErrnoError(31); + } + if (!stream.stream_ops.read) { + throw new FS.ErrnoError(28); + } + var seeking = typeof position != "undefined"; + if (!seeking) { + position = stream.position; + } else if (!stream.seekable) { + throw new FS.ErrnoError(70); + } + var bytesRead = stream.stream_ops.read(stream, buffer, offset, length, position); + if (!seeking) stream.position += bytesRead; + return bytesRead; + }, + write: (stream, buffer, offset, length, position, canOwn) => { + if (length < 0 || position < 0) { + throw new FS.ErrnoError(28); + } + if (FS.isClosed(stream)) { + throw new FS.ErrnoError(8); + } + if ((stream.flags & 2097155) === 0) { + throw new FS.ErrnoError(8); + } + if (FS.isDir(stream.node.mode)) { + throw new FS.ErrnoError(31); + } + if (!stream.stream_ops.write) { + throw new FS.ErrnoError(28); + } + if (stream.seekable && stream.flags & 1024) { + FS.llseek(stream, 0, 2); + } + var seeking = typeof position != "undefined"; + if (!seeking) { + position = stream.position; + } else if (!stream.seekable) { + throw new FS.ErrnoError(70); + } + var bytesWritten = stream.stream_ops.write(stream, buffer, offset, length, position, canOwn); + if (!seeking) stream.position += bytesWritten; + return bytesWritten; + }, + allocate: (stream, offset, length) => { + if (FS.isClosed(stream)) { + throw new FS.ErrnoError(8); + } + if (offset < 0 || length <= 0) { + throw new FS.ErrnoError(28); + } + if ((stream.flags & 2097155) === 0) { + throw new FS.ErrnoError(8); + } + if (!FS.isFile(stream.node.mode) && !FS.isDir(stream.node.mode)) { + throw new FS.ErrnoError(43); + } + if (!stream.stream_ops.allocate) { + throw new FS.ErrnoError(138); + } + stream.stream_ops.allocate(stream, offset, length); + }, + mmap: (stream, length, position, prot, flags) => { + if ((prot & 2) !== 0 && (flags & 2) === 0 && (stream.flags & 2097155) !== 2) { + throw new FS.ErrnoError(2); + } + if ((stream.flags & 2097155) === 1) { + throw new FS.ErrnoError(2); + } + if (!stream.stream_ops.mmap) { + throw new FS.ErrnoError(43); + } + return stream.stream_ops.mmap(stream, length, position, prot, flags); + }, + msync: (stream, buffer, offset, length, mmapFlags) => { + if (!stream.stream_ops.msync) { + return 0; + } + return stream.stream_ops.msync(stream, buffer, offset, length, mmapFlags); + }, + munmap: stream => 0, + ioctl: (stream, cmd, arg) => { + if (!stream.stream_ops.ioctl) { + throw new FS.ErrnoError(59); + } + return stream.stream_ops.ioctl(stream, cmd, arg); + }, + readFile: (path, opts = {}) => { + opts.flags = opts.flags || 0; + opts.encoding = opts.encoding || "binary"; + if (opts.encoding !== "utf8" && opts.encoding !== "binary") { + throw new Error(`Invalid encoding type "${opts.encoding}"`); + } + var ret; + var stream = FS.open(path, opts.flags); + var stat = FS.stat(path); + var length = stat.size; + var buf = new Uint8Array(length); + FS.read(stream, buf, 0, length, 0); + if (opts.encoding === "utf8") { + ret = UTF8ArrayToString(buf, 0); + } else if (opts.encoding === "binary") { + ret = buf; + } + FS.close(stream); + return ret; + }, + writeFile: (path, data, opts = {}) => { + opts.flags = opts.flags || 577; + var stream = FS.open(path, opts.flags, opts.mode); + if (typeof data == "string") { + var buf = new Uint8Array(lengthBytesUTF8(data) + 1); + var actualNumBytes = stringToUTF8Array(data, buf, 0, buf.length); + FS.write(stream, buf, 0, actualNumBytes, undefined, opts.canOwn); + } else if (ArrayBuffer.isView(data)) { + FS.write(stream, data, 0, data.byteLength, undefined, opts.canOwn); + } else { + throw new Error("Unsupported data type"); + } + FS.close(stream); + }, + cwd: () => FS.currentPath, + chdir: path => { + var lookup = FS.lookupPath(path, { + follow: true + }); + if (lookup.node === null) { + throw new FS.ErrnoError(44); + } + if (!FS.isDir(lookup.node.mode)) { + throw new FS.ErrnoError(54); + } + var errCode = FS.nodePermissions(lookup.node, "x"); + if (errCode) { + throw new FS.ErrnoError(errCode); + } + FS.currentPath = lookup.path; + }, + createDefaultDirectories: () => { + FS.mkdir("/tmp"); + FS.mkdir("/home"); + FS.mkdir("/home/web_user"); + }, + createDefaultDevices: () => { + FS.mkdir("/dev"); + FS.registerDevice(FS.makedev(1, 3), { + read: () => 0, + write: (stream, buffer, offset, length, pos) => length + }); + FS.mkdev("/dev/null", FS.makedev(1, 3)); + TTY.register(FS.makedev(5, 0), TTY.default_tty_ops); + TTY.register(FS.makedev(6, 0), TTY.default_tty1_ops); + FS.mkdev("/dev/tty", FS.makedev(5, 0)); + FS.mkdev("/dev/tty1", FS.makedev(6, 0)); + var randomBuffer = new Uint8Array(1024), randomLeft = 0; + var randomByte = () => { + if (randomLeft === 0) { + randomLeft = randomFill(randomBuffer).byteLength; + } + return randomBuffer[--randomLeft]; + }; + FS.createDevice("/dev", "random", randomByte); + FS.createDevice("/dev", "urandom", randomByte); + FS.mkdir("/dev/shm"); + FS.mkdir("/dev/shm/tmp"); + }, + createSpecialDirectories: () => { + FS.mkdir("/proc"); + var proc_self = FS.mkdir("/proc/self"); + FS.mkdir("/proc/self/fd"); + FS.mount({ + mount: () => { + var node = FS.createNode(proc_self, "fd", 16384 | 511, 73); + node.node_ops = { + lookup: (parent, name) => { + var fd = +name; + var stream = FS.getStream(fd); + if (!stream) throw new FS.ErrnoError(8); + var ret = { + parent: null, + mount: { + mountpoint: "fake" + }, + node_ops: { + readlink: () => stream.path + } + }; + ret.parent = ret; + return ret; + } + }; + return node; + } + }, {}, "/proc/self/fd"); + }, + createStandardStreams: () => { + if (Module["stdin"]) { + FS.createDevice("/dev", "stdin", Module["stdin"]); + } else { + FS.symlink("/dev/tty", "/dev/stdin"); + } + if (Module["stdout"]) { + FS.createDevice("/dev", "stdout", null, Module["stdout"]); + } else { + FS.symlink("/dev/tty", "/dev/stdout"); + } + if (Module["stderr"]) { + FS.createDevice("/dev", "stderr", null, Module["stderr"]); + } else { + FS.symlink("/dev/tty1", "/dev/stderr"); + } + var stdin = FS.open("/dev/stdin", 0); + var stdout = FS.open("/dev/stdout", 1); + var stderr = FS.open("/dev/stderr", 1); + assert(stdin.fd === 0, `invalid handle for stdin (${stdin.fd})`); + assert(stdout.fd === 1, `invalid handle for stdout (${stdout.fd})`); + assert(stderr.fd === 2, `invalid handle for stderr (${stderr.fd})`); + }, + ensureErrnoError: () => { + if (FS.ErrnoError) return; + FS.ErrnoError = function ErrnoError(errno, node) { + this.name = "ErrnoError"; + this.node = node; + this.setErrno = function(errno) { + this.errno = errno; + for (var key in ERRNO_CODES) { + if (ERRNO_CODES[key] === errno) { + this.code = key; + break; + } + } + }; + this.setErrno(errno); + this.message = ERRNO_MESSAGES[errno]; + if (this.stack) { + Object.defineProperty(this, "stack", { + value: new Error().stack, + writable: true + }); + this.stack = demangleAll(this.stack); + } + }; + FS.ErrnoError.prototype = new Error(); + FS.ErrnoError.prototype.constructor = FS.ErrnoError; + [ 44 ].forEach(code => { + FS.genericErrors[code] = new FS.ErrnoError(code); + FS.genericErrors[code].stack = ""; + }); + }, + staticInit: () => { + FS.ensureErrnoError(); + FS.nameTable = new Array(4096); + FS.mount(MEMFS, {}, "/"); + FS.createDefaultDirectories(); + FS.createDefaultDevices(); + FS.createSpecialDirectories(); + FS.filesystems = { + "MEMFS": MEMFS, + "IDBFS": IDBFS + }; + }, + init: (input, output, error) => { + assert(!FS.init.initialized, "FS.init was previously called. If you want to initialize later with custom parameters, remove any earlier calls (note that one is automatically added to the generated code)"); + FS.init.initialized = true; + FS.ensureErrnoError(); + Module["stdin"] = input || Module["stdin"]; + Module["stdout"] = output || Module["stdout"]; + Module["stderr"] = error || Module["stderr"]; + FS.createStandardStreams(); + }, + quit: () => { + FS.init.initialized = false; + _fflush(0); + for (var i = 0; i < FS.streams.length; i++) { + var stream = FS.streams[i]; + if (!stream) { + continue; + } + FS.close(stream); + } + }, + findObject: (path, dontResolveLastLink) => { + var ret = FS.analyzePath(path, dontResolveLastLink); + if (!ret.exists) { + return null; + } + return ret.object; + }, + analyzePath: (path, dontResolveLastLink) => { + try { + var lookup = FS.lookupPath(path, { + follow: !dontResolveLastLink + }); + path = lookup.path; + } catch (e) {} + var ret = { + isRoot: false, + exists: false, + error: 0, + name: null, + path: null, + object: null, + parentExists: false, + parentPath: null, + parentObject: null + }; + try { + var lookup = FS.lookupPath(path, { + parent: true + }); + ret.parentExists = true; + ret.parentPath = lookup.path; + ret.parentObject = lookup.node; + ret.name = PATH.basename(path); + lookup = FS.lookupPath(path, { + follow: !dontResolveLastLink + }); + ret.exists = true; + ret.path = lookup.path; + ret.object = lookup.node; + ret.name = lookup.node.name; + ret.isRoot = lookup.path === "/"; + } catch (e) { + ret.error = e.errno; + } + return ret; + }, + createPath: (parent, path, canRead, canWrite) => { + parent = typeof parent == "string" ? parent : FS.getPath(parent); + var parts = path.split("/").reverse(); + while (parts.length) { + var part = parts.pop(); + if (!part) continue; + var current = PATH.join2(parent, part); + try { + FS.mkdir(current); + } catch (e) {} + parent = current; + } + return current; + }, + createFile: (parent, name, properties, canRead, canWrite) => { + var path = PATH.join2(typeof parent == "string" ? parent : FS.getPath(parent), name); + var mode = FS_getMode(canRead, canWrite); + return FS.create(path, mode); + }, + createDataFile: (parent, name, data, canRead, canWrite, canOwn) => { + var path = name; + if (parent) { + parent = typeof parent == "string" ? parent : FS.getPath(parent); + path = name ? PATH.join2(parent, name) : parent; + } + var mode = FS_getMode(canRead, canWrite); + var node = FS.create(path, mode); + if (data) { + if (typeof data == "string") { + var arr = new Array(data.length); + for (var i = 0, len = data.length; i < len; ++i) arr[i] = data.charCodeAt(i); + data = arr; + } + FS.chmod(node, mode | 146); + var stream = FS.open(node, 577); + FS.write(stream, data, 0, data.length, 0, canOwn); + FS.close(stream); + FS.chmod(node, mode); + } + return node; + }, + createDevice: (parent, name, input, output) => { + var path = PATH.join2(typeof parent == "string" ? parent : FS.getPath(parent), name); + var mode = FS_getMode(!!input, !!output); + if (!FS.createDevice.major) FS.createDevice.major = 64; + var dev = FS.makedev(FS.createDevice.major++, 0); + FS.registerDevice(dev, { + open: stream => { + stream.seekable = false; + }, + close: stream => { + if (output && output.buffer && output.buffer.length) { + output(10); + } + }, + read: (stream, buffer, offset, length, pos) => { + var bytesRead = 0; + for (var i = 0; i < length; i++) { + var result; + try { + result = input(); + } catch (e) { + throw new FS.ErrnoError(29); + } + if (result === undefined && bytesRead === 0) { + throw new FS.ErrnoError(6); + } + if (result === null || result === undefined) break; + bytesRead++; + buffer[offset + i] = result; + } + if (bytesRead) { + stream.node.timestamp = Date.now(); + } + return bytesRead; + }, + write: (stream, buffer, offset, length, pos) => { + for (var i = 0; i < length; i++) { + try { + output(buffer[offset + i]); + } catch (e) { + throw new FS.ErrnoError(29); + } + } + if (length) { + stream.node.timestamp = Date.now(); + } + return i; + } + }); + return FS.mkdev(path, mode, dev); + }, + forceLoadFile: obj => { + if (obj.isDevice || obj.isFolder || obj.link || obj.contents) return true; + if (typeof XMLHttpRequest != "undefined") { + throw new Error("Lazy loading should have been performed (contents set) in createLazyFile, but it was not. Lazy loading only works in web workers. Use --embed-file or --preload-file in emcc on the main thread."); + } else if (read_) { + try { + obj.contents = intArrayFromString(read_(obj.url), true); + obj.usedBytes = obj.contents.length; + } catch (e) { + throw new FS.ErrnoError(29); + } + } else { + throw new Error("Cannot load without read() or XMLHttpRequest."); + } + }, + createLazyFile: (parent, name, url, canRead, canWrite) => { + function LazyUint8Array() { + this.lengthKnown = false; + this.chunks = []; + } + LazyUint8Array.prototype.get = function LazyUint8Array_get(idx) { + if (idx > this.length - 1 || idx < 0) { + return undefined; + } + var chunkOffset = idx % this.chunkSize; + var chunkNum = idx / this.chunkSize | 0; + return this.getter(chunkNum)[chunkOffset]; + }; + LazyUint8Array.prototype.setDataGetter = function LazyUint8Array_setDataGetter(getter) { + this.getter = getter; + }; + LazyUint8Array.prototype.cacheLength = function LazyUint8Array_cacheLength() { + var xhr = new XMLHttpRequest(); + xhr.open("HEAD", url, false); + xhr.send(null); + if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) throw new Error("Couldn't load " + url + ". Status: " + xhr.status); + var datalength = Number(xhr.getResponseHeader("Content-length")); + var header; + var hasByteServing = (header = xhr.getResponseHeader("Accept-Ranges")) && header === "bytes"; + var usesGzip = (header = xhr.getResponseHeader("Content-Encoding")) && header === "gzip"; + var chunkSize = 1024 * 1024; + if (!hasByteServing) chunkSize = datalength; + var doXHR = (from, to) => { + if (from > to) throw new Error("invalid range (" + from + ", " + to + ") or no bytes requested!"); + if (to > datalength - 1) throw new Error("only " + datalength + " bytes available! programmer error!"); + var xhr = new XMLHttpRequest(); + xhr.open("GET", url, false); + if (datalength !== chunkSize) xhr.setRequestHeader("Range", "bytes=" + from + "-" + to); + xhr.responseType = "arraybuffer"; + if (xhr.overrideMimeType) { + xhr.overrideMimeType("text/plain; charset=x-user-defined"); + } + xhr.send(null); + if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) throw new Error("Couldn't load " + url + ". Status: " + xhr.status); + if (xhr.response !== undefined) { + return new Uint8Array(xhr.response || []); + } + return intArrayFromString(xhr.responseText || "", true); + }; + var lazyArray = this; + lazyArray.setDataGetter(chunkNum => { + var start = chunkNum * chunkSize; + var end = (chunkNum + 1) * chunkSize - 1; + end = Math.min(end, datalength - 1); + if (typeof lazyArray.chunks[chunkNum] == "undefined") { + lazyArray.chunks[chunkNum] = doXHR(start, end); + } + if (typeof lazyArray.chunks[chunkNum] == "undefined") throw new Error("doXHR failed!"); + return lazyArray.chunks[chunkNum]; + }); + if (usesGzip || !datalength) { + chunkSize = datalength = 1; + datalength = this.getter(0).length; + chunkSize = datalength; + out("LazyFiles on gzip forces download of the whole file when length is accessed"); + } + this._length = datalength; + this._chunkSize = chunkSize; + this.lengthKnown = true; + }; + if (typeof XMLHttpRequest != "undefined") { + if (!ENVIRONMENT_IS_WORKER) throw "Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc"; + var lazyArray = new LazyUint8Array(); + Object.defineProperties(lazyArray, { + length: { + get: function() { + if (!this.lengthKnown) { + this.cacheLength(); + } + return this._length; + } + }, + chunkSize: { + get: function() { + if (!this.lengthKnown) { + this.cacheLength(); + } + return this._chunkSize; + } + } + }); + var properties = { + isDevice: false, + contents: lazyArray + }; + } else { + var properties = { + isDevice: false, + url: url + }; + } + var node = FS.createFile(parent, name, properties, canRead, canWrite); + if (properties.contents) { + node.contents = properties.contents; + } else if (properties.url) { + node.contents = null; + node.url = properties.url; + } + Object.defineProperties(node, { + usedBytes: { + get: function() { + return this.contents.length; + } + } + }); + var stream_ops = {}; + var keys = Object.keys(node.stream_ops); + keys.forEach(key => { + var fn = node.stream_ops[key]; + stream_ops[key] = function forceLoadLazyFile() { + FS.forceLoadFile(node); + return fn.apply(null, arguments); + }; + }); + function writeChunks(stream, buffer, offset, length, position) { + var contents = stream.node.contents; + if (position >= contents.length) return 0; + var size = Math.min(contents.length - position, length); + assert(size >= 0); + if (contents.slice) { + for (var i = 0; i < size; i++) { + buffer[offset + i] = contents[position + i]; + } + } else { + for (var i = 0; i < size; i++) { + buffer[offset + i] = contents.get(position + i); + } + } + return size; + } + stream_ops.read = (stream, buffer, offset, length, position) => { + FS.forceLoadFile(node); + return writeChunks(stream, buffer, offset, length, position); + }; + stream_ops.mmap = (stream, length, position, prot, flags) => { + FS.forceLoadFile(node); + var ptr = mmapAlloc(length); + if (!ptr) { + throw new FS.ErrnoError(48); + } + writeChunks(stream, GROWABLE_HEAP_I8(), ptr, length, position); + return { + ptr: ptr, + allocated: true + }; + }; + node.stream_ops = stream_ops; + return node; + }, + absolutePath: () => { + abort("FS.absolutePath has been removed; use PATH_FS.resolve instead"); + }, + createFolder: () => { + abort("FS.createFolder has been removed; use FS.mkdir instead"); + }, + createLink: () => { + abort("FS.createLink has been removed; use FS.symlink instead"); + }, + joinPath: () => { + abort("FS.joinPath has been removed; use PATH.join instead"); + }, + mmapAlloc: () => { + abort("FS.mmapAlloc has been replaced by the top level function mmapAlloc"); + }, + standardizePath: () => { + abort("FS.standardizePath has been removed; use PATH.normalize instead"); + } +}; + +function UTF8ToString(ptr, maxBytesToRead) { + assert(typeof ptr == "number"); + return ptr ? UTF8ArrayToString(GROWABLE_HEAP_U8(), ptr, maxBytesToRead) : ""; +} + +var SYSCALLS = { + DEFAULT_POLLMASK: 5, + calculateAt: function(dirfd, path, allowEmpty) { + if (PATH.isAbs(path)) { + return path; + } + var dir; + if (dirfd === -100) { + dir = FS.cwd(); + } else { + var dirstream = SYSCALLS.getStreamFromFD(dirfd); + dir = dirstream.path; + } + if (path.length == 0) { + if (!allowEmpty) { + throw new FS.ErrnoError(44); + } + return dir; + } + return PATH.join2(dir, path); + }, + doStat: function(func, path, buf) { + try { + var stat = func(path); + } catch (e) { + if (e && e.node && PATH.normalize(path) !== PATH.normalize(FS.getPath(e.node))) { + return -54; + } + throw e; + } + GROWABLE_HEAP_I32()[buf >> 2] = stat.dev; + GROWABLE_HEAP_I32()[buf + 8 >> 2] = stat.ino; + GROWABLE_HEAP_I32()[buf + 12 >> 2] = stat.mode; + GROWABLE_HEAP_U32()[buf + 16 >> 2] = stat.nlink; + GROWABLE_HEAP_I32()[buf + 20 >> 2] = stat.uid; + GROWABLE_HEAP_I32()[buf + 24 >> 2] = stat.gid; + GROWABLE_HEAP_I32()[buf + 28 >> 2] = stat.rdev; + tempI64 = [ stat.size >>> 0, (tempDouble = stat.size, +Math.abs(tempDouble) >= 1 ? tempDouble > 0 ? +Math.floor(tempDouble / 4294967296) >>> 0 : ~~+Math.ceil((tempDouble - +(~~tempDouble >>> 0)) / 4294967296) >>> 0 : 0) ], + GROWABLE_HEAP_I32()[buf + 40 >> 2] = tempI64[0], GROWABLE_HEAP_I32()[buf + 44 >> 2] = tempI64[1]; + GROWABLE_HEAP_I32()[buf + 48 >> 2] = 4096; + GROWABLE_HEAP_I32()[buf + 52 >> 2] = stat.blocks; + var atime = stat.atime.getTime(); + var mtime = stat.mtime.getTime(); + var ctime = stat.ctime.getTime(); + tempI64 = [ Math.floor(atime / 1e3) >>> 0, (tempDouble = Math.floor(atime / 1e3), + +Math.abs(tempDouble) >= 1 ? tempDouble > 0 ? +Math.floor(tempDouble / 4294967296) >>> 0 : ~~+Math.ceil((tempDouble - +(~~tempDouble >>> 0)) / 4294967296) >>> 0 : 0) ], + GROWABLE_HEAP_I32()[buf + 56 >> 2] = tempI64[0], GROWABLE_HEAP_I32()[buf + 60 >> 2] = tempI64[1]; + GROWABLE_HEAP_U32()[buf + 64 >> 2] = atime % 1e3 * 1e3; + tempI64 = [ Math.floor(mtime / 1e3) >>> 0, (tempDouble = Math.floor(mtime / 1e3), + +Math.abs(tempDouble) >= 1 ? tempDouble > 0 ? +Math.floor(tempDouble / 4294967296) >>> 0 : ~~+Math.ceil((tempDouble - +(~~tempDouble >>> 0)) / 4294967296) >>> 0 : 0) ], + GROWABLE_HEAP_I32()[buf + 72 >> 2] = tempI64[0], GROWABLE_HEAP_I32()[buf + 76 >> 2] = tempI64[1]; + GROWABLE_HEAP_U32()[buf + 80 >> 2] = mtime % 1e3 * 1e3; + tempI64 = [ Math.floor(ctime / 1e3) >>> 0, (tempDouble = Math.floor(ctime / 1e3), + +Math.abs(tempDouble) >= 1 ? tempDouble > 0 ? +Math.floor(tempDouble / 4294967296) >>> 0 : ~~+Math.ceil((tempDouble - +(~~tempDouble >>> 0)) / 4294967296) >>> 0 : 0) ], + GROWABLE_HEAP_I32()[buf + 88 >> 2] = tempI64[0], GROWABLE_HEAP_I32()[buf + 92 >> 2] = tempI64[1]; + GROWABLE_HEAP_U32()[buf + 96 >> 2] = ctime % 1e3 * 1e3; + tempI64 = [ stat.ino >>> 0, (tempDouble = stat.ino, +Math.abs(tempDouble) >= 1 ? tempDouble > 0 ? +Math.floor(tempDouble / 4294967296) >>> 0 : ~~+Math.ceil((tempDouble - +(~~tempDouble >>> 0)) / 4294967296) >>> 0 : 0) ], + GROWABLE_HEAP_I32()[buf + 104 >> 2] = tempI64[0], GROWABLE_HEAP_I32()[buf + 108 >> 2] = tempI64[1]; + return 0; + }, + doMsync: function(addr, stream, len, flags, offset) { + if (!FS.isFile(stream.node.mode)) { + throw new FS.ErrnoError(43); + } + if (flags & 2) { + return 0; + } + var buffer = GROWABLE_HEAP_U8().slice(addr, addr + len); + FS.msync(stream, buffer, offset, len, flags); + }, + varargs: undefined, + get: function() { + assert(SYSCALLS.varargs != undefined); + SYSCALLS.varargs += 4; + var ret = GROWABLE_HEAP_I32()[SYSCALLS.varargs - 4 >> 2]; + return ret; + }, + getStr: function(ptr) { + var ret = UTF8ToString(ptr); + return ret; + }, + getStreamFromFD: function(fd) { + var stream = FS.getStream(fd); + if (!stream) throw new FS.ErrnoError(8); + return stream; + } +}; + +function _proc_exit(code) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(1, 1, code); + EXITSTATUS = code; + if (!keepRuntimeAlive()) { + PThread.terminateAllThreads(); + if (Module["onExit"]) Module["onExit"](code); + ABORT = true; + } + quit_(code, new ExitStatus(code)); +} + +function exitJS(status, implicit) { + EXITSTATUS = status; + if (ENVIRONMENT_IS_PTHREAD) { + assert(!implicit); + exitOnMainThread(status); + throw "unwind"; + } + if (!keepRuntimeAlive()) { + exitRuntime(); + } + if (keepRuntimeAlive() && !implicit) { + var msg = `program exited (with status: ${status}), but keepRuntimeAlive() is set (counter=${runtimeKeepaliveCounter}) due to an async operation, so halting execution but not exiting the runtime or preventing further async execution (you can use emscripten_force_exit, if you want to force a true shutdown)`; + readyPromiseReject(msg); + err(msg); + } + _proc_exit(status); +} + +var _exit = exitJS; + +function ptrToString(ptr) { + assert(typeof ptr === "number"); + return "0x" + ptr.toString(16).padStart(8, "0"); +} + +function handleException(e) { + if (e instanceof ExitStatus || e == "unwind") { + return EXITSTATUS; + } + checkStackCookie(); + if (e instanceof WebAssembly.RuntimeError) { + if (_emscripten_stack_get_current() <= 0) { + err("Stack overflow detected. You can try increasing -sSTACK_SIZE (currently set to 5242880)"); + } + } + quit_(1, e); +} + +var PThread = { + unusedWorkers: [], + runningWorkers: [], + tlsInitFunctions: [], + pthreads: {}, + nextWorkerID: 1, + debugInit: function() { + function pthreadLogPrefix() { + var t = 0; + if (runtimeInitialized && typeof _pthread_self != "undefined" && !runtimeExited) { + t = _pthread_self(); + } + return "w:" + (Module["workerID"] || 0) + ",t:" + ptrToString(t) + ": "; + } + var origDbg = dbg; + dbg = message => origDbg(pthreadLogPrefix() + message); + }, + init: function() { + PThread.debugInit(); + if (ENVIRONMENT_IS_PTHREAD) { + PThread.initWorker(); + } else { + PThread.initMainThread(); + } + }, + initMainThread: function() { + var pthreadPoolSize = 8; + while (pthreadPoolSize--) { + PThread.allocateUnusedWorker(); + } + }, + initWorker: function() { + noExitRuntime = false; + }, + setExitStatus: function(status) { + EXITSTATUS = status; + }, + terminateAllThreads__deps: [ "$terminateWorker" ], + terminateAllThreads: function() { + assert(!ENVIRONMENT_IS_PTHREAD, "Internal Error! terminateAllThreads() can only ever be called from main application thread!"); + for (var worker of PThread.runningWorkers) { + terminateWorker(worker); + } + for (var worker of PThread.unusedWorkers) { + terminateWorker(worker); + } + PThread.unusedWorkers = []; + PThread.runningWorkers = []; + PThread.pthreads = []; + }, + returnWorkerToPool: function(worker) { + var pthread_ptr = worker.pthread_ptr; + delete PThread.pthreads[pthread_ptr]; + PThread.unusedWorkers.push(worker); + PThread.runningWorkers.splice(PThread.runningWorkers.indexOf(worker), 1); + worker.pthread_ptr = 0; + __emscripten_thread_free_data(pthread_ptr); + }, + receiveObjectTransfer: function(data) {}, + threadInitTLS: function() { + PThread.tlsInitFunctions.forEach(f => f()); + }, + loadWasmModuleToWorker: worker => new Promise(onFinishedLoading => { + worker.onmessage = e => { + var d = e["data"]; + var cmd = d["cmd"]; + if (worker.pthread_ptr) PThread.currentProxiedOperationCallerThread = worker.pthread_ptr; + if (d["targetThread"] && d["targetThread"] != _pthread_self()) { + var targetWorker = PThread.pthreads[d.targetThread]; + if (targetWorker) { + targetWorker.postMessage(d, d["transferList"]); + } else { + err('Internal error! Worker sent a message "' + cmd + '" to target pthread ' + d["targetThread"] + ", but that thread no longer exists!"); + } + PThread.currentProxiedOperationCallerThread = undefined; + return; + } + if (cmd === "checkMailbox") { + checkMailbox(); + } else if (cmd === "spawnThread") { + spawnThread(d); + } else if (cmd === "cleanupThread") { + cleanupThread(d["thread"]); + } else if (cmd === "killThread") { + killThread(d["thread"]); + } else if (cmd === "cancelThread") { + cancelThread(d["thread"]); + } else if (cmd === "loaded") { + worker.loaded = true; + onFinishedLoading(worker); + } else if (cmd === "print") { + out("Thread " + d["threadId"] + ": " + d["text"]); + } else if (cmd === "printErr") { + err("Thread " + d["threadId"] + ": " + d["text"]); + } else if (cmd === "alert") { + alert("Thread " + d["threadId"] + ": " + d["text"]); + } else if (d.target === "setimmediate") { + worker.postMessage(d); + } else if (cmd === "callHandler") { + Module[d["handler"]](...d["args"]); + } else if (cmd) { + err("worker sent an unknown command " + cmd); + } + PThread.currentProxiedOperationCallerThread = undefined; + }; + worker.onerror = e => { + var message = "worker sent an error!"; + if (worker.pthread_ptr) { + message = "Pthread " + ptrToString(worker.pthread_ptr) + " sent an error!"; + } + err(message + " " + e.filename + ":" + e.lineno + ": " + e.message); + throw e; + }; + assert(wasmMemory instanceof WebAssembly.Memory, "WebAssembly memory should have been loaded by now!"); + assert(wasmModule instanceof WebAssembly.Module, "WebAssembly Module should have been loaded by now!"); + var handlers = []; + var knownHandlers = [ "onExit", "onAbort", "print", "printErr" ]; + for (var handler of knownHandlers) { + if (Module.hasOwnProperty(handler)) { + handlers.push(handler); + } + } + worker.workerID = PThread.nextWorkerID++; + worker.postMessage({ + "cmd": "load", + "handlers": handlers, + "urlOrBlob": Module["mainScriptUrlOrBlob"] || _scriptDir, + "wasmMemory": wasmMemory, + "wasmModule": wasmModule, + "workerID": worker.workerID + }); + }), + loadWasmModuleToAllWorkers: function(onMaybeReady) { + if (ENVIRONMENT_IS_PTHREAD) { + return onMaybeReady(); + } + let pthreadPoolReady = Promise.all(PThread.unusedWorkers.map(PThread.loadWasmModuleToWorker)); + pthreadPoolReady.then(onMaybeReady); + }, + allocateUnusedWorker: function() { + var worker; + var pthreadMainJs = locateFile("godot.web.template_release.wasm32.worker.js"); + worker = new Worker(pthreadMainJs); + PThread.unusedWorkers.push(worker); + }, + getNewWorker: function() { + if (PThread.unusedWorkers.length == 0) { + err("Tried to spawn a new thread, but the thread pool is exhausted.\n" + "This might result in a deadlock unless some threads eventually exit or the code explicitly breaks out to the event loop.\n" + "If you want to increase the pool size, use setting `-sPTHREAD_POOL_SIZE=...`." + "\nIf you want to throw an explicit error instead of the risk of deadlocking in those cases, use setting `-sPTHREAD_POOL_SIZE_STRICT=2`."); + PThread.allocateUnusedWorker(); + PThread.loadWasmModuleToWorker(PThread.unusedWorkers[0]); + } + return PThread.unusedWorkers.pop(); + } +}; + +Module["PThread"] = PThread; + +function callRuntimeCallbacks(callbacks) { + while (callbacks.length > 0) { + callbacks.shift()(Module); + } +} + +function establishStackSpace() { + var pthread_ptr = _pthread_self(); + var stackTop = GROWABLE_HEAP_I32()[pthread_ptr + 52 >> 2]; + var stackSize = GROWABLE_HEAP_I32()[pthread_ptr + 56 >> 2]; + var stackMax = stackTop - stackSize; + assert(stackTop != 0); + assert(stackMax != 0); + assert(stackTop > stackMax, "stackTop must be higher then stackMax"); + _emscripten_stack_set_limits(stackTop, stackMax); + stackRestore(stackTop); + writeStackCookie(); +} + +Module["establishStackSpace"] = establishStackSpace; + +function exitOnMainThread(returnCode) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(2, 0, returnCode); + _exit(returnCode); +} + +function getValue(ptr, type = "i8") { + if (type.endsWith("*")) type = "*"; + switch (type) { + case "i1": + return GROWABLE_HEAP_I8()[ptr >> 0]; + + case "i8": + return GROWABLE_HEAP_I8()[ptr >> 0]; + + case "i16": + return GROWABLE_HEAP_I16()[ptr >> 1]; + + case "i32": + return GROWABLE_HEAP_I32()[ptr >> 2]; + + case "i64": + return GROWABLE_HEAP_I32()[ptr >> 2]; + + case "float": + return GROWABLE_HEAP_F32()[ptr >> 2]; + + case "double": + return GROWABLE_HEAP_F64()[ptr >> 3]; + + case "*": + return GROWABLE_HEAP_U32()[ptr >> 2]; + + default: + abort(`invalid type for getValue: ${type}`); + } +} + +var wasmTableMirror = []; + +function getWasmTableEntry(funcPtr) { + var func = wasmTableMirror[funcPtr]; + if (!func) { + if (funcPtr >= wasmTableMirror.length) wasmTableMirror.length = funcPtr + 1; + wasmTableMirror[funcPtr] = func = wasmTable.get(funcPtr); + } + assert(wasmTable.get(funcPtr) == func, "JavaScript-side Wasm function table mirror is out of date!"); + return func; +} + +function invokeEntryPoint(ptr, arg) { + runtimeKeepaliveCounter = 0; + var result = getWasmTableEntry(ptr)(arg); + checkStackCookie(); + if (keepRuntimeAlive()) { + PThread.setExitStatus(result); + } else { + __emscripten_thread_exit(result); + } +} + +Module["invokeEntryPoint"] = invokeEntryPoint; + +function registerTLSInit(tlsInitFunc) { + PThread.tlsInitFunctions.push(tlsInitFunc); +} + +function setValue(ptr, value, type = "i8") { + if (type.endsWith("*")) type = "*"; + switch (type) { + case "i1": + GROWABLE_HEAP_I8()[ptr >> 0] = value; + break; + + case "i8": + GROWABLE_HEAP_I8()[ptr >> 0] = value; + break; + + case "i16": + GROWABLE_HEAP_I16()[ptr >> 1] = value; + break; + + case "i32": + GROWABLE_HEAP_I32()[ptr >> 2] = value; + break; + + case "i64": + tempI64 = [ value >>> 0, (tempDouble = value, +Math.abs(tempDouble) >= 1 ? tempDouble > 0 ? +Math.floor(tempDouble / 4294967296) >>> 0 : ~~+Math.ceil((tempDouble - +(~~tempDouble >>> 0)) / 4294967296) >>> 0 : 0) ], + GROWABLE_HEAP_I32()[ptr >> 2] = tempI64[0], GROWABLE_HEAP_I32()[ptr + 4 >> 2] = tempI64[1]; + break; + + case "float": + GROWABLE_HEAP_F32()[ptr >> 2] = value; + break; + + case "double": + GROWABLE_HEAP_F64()[ptr >> 3] = value; + break; + + case "*": + GROWABLE_HEAP_U32()[ptr >> 2] = value; + break; + + default: + abort(`invalid type for setValue: ${type}`); + } +} + +function warnOnce(text) { + if (!warnOnce.shown) warnOnce.shown = {}; + if (!warnOnce.shown[text]) { + warnOnce.shown[text] = 1; + err(text); + } +} + +function ___assert_fail(condition, filename, line, func) { + abort(`Assertion failed: ${UTF8ToString(condition)}, at: ` + [ filename ? UTF8ToString(filename) : "unknown filename", line, func ? UTF8ToString(func) : "unknown function" ]); +} + +function ___call_sighandler(fp, sig) { + getWasmTableEntry(fp)(sig); +} + +var dlopenMissingError = "To use dlopen, you need enable dynamic linking, see https://emscripten.org/docs/compiling/Dynamic-Linking.html"; + +function ___dlsym(handle, symbol) { + abort(dlopenMissingError); +} + +function ___emscripten_init_main_thread_js(tb) { + __emscripten_thread_init(tb, !ENVIRONMENT_IS_WORKER, 1, !ENVIRONMENT_IS_WEB, 2097152); + PThread.threadInitTLS(); +} + +function ___emscripten_thread_cleanup(thread) { + if (!ENVIRONMENT_IS_PTHREAD) cleanupThread(thread); else postMessage({ + "cmd": "cleanupThread", + "thread": thread + }); +} + +function pthreadCreateProxied(pthread_ptr, attr, startRoutine, arg) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(3, 1, pthread_ptr, attr, startRoutine, arg); + return ___pthread_create_js(pthread_ptr, attr, startRoutine, arg); +} + +function ___pthread_create_js(pthread_ptr, attr, startRoutine, arg) { + if (typeof SharedArrayBuffer == "undefined") { + err("Current environment does not support SharedArrayBuffer, pthreads are not available!"); + return 6; + } + var transferList = []; + var error = 0; + if (ENVIRONMENT_IS_PTHREAD && (transferList.length === 0 || error)) { + return pthreadCreateProxied(pthread_ptr, attr, startRoutine, arg); + } + if (error) return error; + var threadParams = { + startRoutine: startRoutine, + pthread_ptr: pthread_ptr, + arg: arg, + transferList: transferList + }; + if (ENVIRONMENT_IS_PTHREAD) { + threadParams.cmd = "spawnThread"; + postMessage(threadParams, transferList); + return 0; + } + return spawnThread(threadParams); +} + +function ___syscall__newselect(nfds, readfds, writefds, exceptfds, timeout) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(4, 1, nfds, readfds, writefds, exceptfds, timeout); + try { + assert(nfds <= 64, "nfds must be less than or equal to 64"); + assert(!exceptfds, "exceptfds not supported"); + var total = 0; + var srcReadLow = readfds ? GROWABLE_HEAP_I32()[readfds >> 2] : 0, srcReadHigh = readfds ? GROWABLE_HEAP_I32()[readfds + 4 >> 2] : 0; + var srcWriteLow = writefds ? GROWABLE_HEAP_I32()[writefds >> 2] : 0, srcWriteHigh = writefds ? GROWABLE_HEAP_I32()[writefds + 4 >> 2] : 0; + var srcExceptLow = exceptfds ? GROWABLE_HEAP_I32()[exceptfds >> 2] : 0, srcExceptHigh = exceptfds ? GROWABLE_HEAP_I32()[exceptfds + 4 >> 2] : 0; + var dstReadLow = 0, dstReadHigh = 0; + var dstWriteLow = 0, dstWriteHigh = 0; + var dstExceptLow = 0, dstExceptHigh = 0; + var allLow = (readfds ? GROWABLE_HEAP_I32()[readfds >> 2] : 0) | (writefds ? GROWABLE_HEAP_I32()[writefds >> 2] : 0) | (exceptfds ? GROWABLE_HEAP_I32()[exceptfds >> 2] : 0); + var allHigh = (readfds ? GROWABLE_HEAP_I32()[readfds + 4 >> 2] : 0) | (writefds ? GROWABLE_HEAP_I32()[writefds + 4 >> 2] : 0) | (exceptfds ? GROWABLE_HEAP_I32()[exceptfds + 4 >> 2] : 0); + var check = function(fd, low, high, val) { + return fd < 32 ? low & val : high & val; + }; + for (var fd = 0; fd < nfds; fd++) { + var mask = 1 << fd % 32; + if (!check(fd, allLow, allHigh, mask)) { + continue; + } + var stream = SYSCALLS.getStreamFromFD(fd); + var flags = SYSCALLS.DEFAULT_POLLMASK; + if (stream.stream_ops.poll) { + flags = stream.stream_ops.poll(stream); + } + if (flags & 1 && check(fd, srcReadLow, srcReadHigh, mask)) { + fd < 32 ? dstReadLow = dstReadLow | mask : dstReadHigh = dstReadHigh | mask; + total++; + } + if (flags & 4 && check(fd, srcWriteLow, srcWriteHigh, mask)) { + fd < 32 ? dstWriteLow = dstWriteLow | mask : dstWriteHigh = dstWriteHigh | mask; + total++; + } + if (flags & 2 && check(fd, srcExceptLow, srcExceptHigh, mask)) { + fd < 32 ? dstExceptLow = dstExceptLow | mask : dstExceptHigh = dstExceptHigh | mask; + total++; + } + } + if (readfds) { + GROWABLE_HEAP_I32()[readfds >> 2] = dstReadLow; + GROWABLE_HEAP_I32()[readfds + 4 >> 2] = dstReadHigh; + } + if (writefds) { + GROWABLE_HEAP_I32()[writefds >> 2] = dstWriteLow; + GROWABLE_HEAP_I32()[writefds + 4 >> 2] = dstWriteHigh; + } + if (exceptfds) { + GROWABLE_HEAP_I32()[exceptfds >> 2] = dstExceptLow; + GROWABLE_HEAP_I32()[exceptfds + 4 >> 2] = dstExceptHigh; + } + return total; + } catch (e) { + if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e; + return -e.errno; + } +} + +var SOCKFS = { + mount: function(mount) { + Module["websocket"] = Module["websocket"] && "object" === typeof Module["websocket"] ? Module["websocket"] : {}; + Module["websocket"]._callbacks = {}; + Module["websocket"]["on"] = function(event, callback) { + if ("function" === typeof callback) { + this._callbacks[event] = callback; + } + return this; + }; + Module["websocket"].emit = function(event, param) { + if ("function" === typeof this._callbacks[event]) { + this._callbacks[event].call(this, param); + } + }; + return FS.createNode(null, "/", 16384 | 511, 0); + }, + createSocket: function(family, type, protocol) { + type &= ~526336; + var streaming = type == 1; + if (streaming && protocol && protocol != 6) { + throw new FS.ErrnoError(66); + } + var sock = { + family: family, + type: type, + protocol: protocol, + server: null, + error: null, + peers: {}, + pending: [], + recv_queue: [], + sock_ops: SOCKFS.websocket_sock_ops + }; + var name = SOCKFS.nextname(); + var node = FS.createNode(SOCKFS.root, name, 49152, 0); + node.sock = sock; + var stream = FS.createStream({ + path: name, + node: node, + flags: 2, + seekable: false, + stream_ops: SOCKFS.stream_ops + }); + sock.stream = stream; + return sock; + }, + getSocket: function(fd) { + var stream = FS.getStream(fd); + if (!stream || !FS.isSocket(stream.node.mode)) { + return null; + } + return stream.node.sock; + }, + stream_ops: { + poll: function(stream) { + var sock = stream.node.sock; + return sock.sock_ops.poll(sock); + }, + ioctl: function(stream, request, varargs) { + var sock = stream.node.sock; + return sock.sock_ops.ioctl(sock, request, varargs); + }, + read: function(stream, buffer, offset, length, position) { + var sock = stream.node.sock; + var msg = sock.sock_ops.recvmsg(sock, length); + if (!msg) { + return 0; + } + buffer.set(msg.buffer, offset); + return msg.buffer.length; + }, + write: function(stream, buffer, offset, length, position) { + var sock = stream.node.sock; + return sock.sock_ops.sendmsg(sock, buffer, offset, length); + }, + close: function(stream) { + var sock = stream.node.sock; + sock.sock_ops.close(sock); + } + }, + nextname: function() { + if (!SOCKFS.nextname.current) { + SOCKFS.nextname.current = 0; + } + return "socket[" + SOCKFS.nextname.current++ + "]"; + }, + websocket_sock_ops: { + createPeer: function(sock, addr, port) { + var ws; + if (typeof addr == "object") { + ws = addr; + addr = null; + port = null; + } + if (ws) { + if (ws._socket) { + addr = ws._socket.remoteAddress; + port = ws._socket.remotePort; + } else { + var result = /ws[s]?:\/\/([^:]+):(\d+)/.exec(ws.url); + if (!result) { + throw new Error("WebSocket URL must be in the format ws(s)://address:port"); + } + addr = result[1]; + port = parseInt(result[2], 10); + } + } else { + try { + var runtimeConfig = Module["websocket"] && "object" === typeof Module["websocket"]; + var url = "ws:#".replace("#", "//"); + if (runtimeConfig) { + if ("string" === typeof Module["websocket"]["url"]) { + url = Module["websocket"]["url"]; + } + } + if (url === "ws://" || url === "wss://") { + var parts = addr.split("/"); + url = url + parts[0] + ":" + port + "/" + parts.slice(1).join("/"); + } + var subProtocols = "binary"; + if (runtimeConfig) { + if ("string" === typeof Module["websocket"]["subprotocol"]) { + subProtocols = Module["websocket"]["subprotocol"]; + } + } + var opts = undefined; + if (subProtocols !== "null") { + subProtocols = subProtocols.replace(/^ +| +$/g, "").split(/ *, */); + opts = subProtocols; + } + if (runtimeConfig && null === Module["websocket"]["subprotocol"]) { + subProtocols = "null"; + opts = undefined; + } + var WebSocketConstructor; + { + WebSocketConstructor = WebSocket; + } + ws = new WebSocketConstructor(url, opts); + ws.binaryType = "arraybuffer"; + } catch (e) { + throw new FS.ErrnoError(23); + } + } + var peer = { + addr: addr, + port: port, + socket: ws, + dgram_send_queue: [] + }; + SOCKFS.websocket_sock_ops.addPeer(sock, peer); + SOCKFS.websocket_sock_ops.handlePeerEvents(sock, peer); + if (sock.type === 2 && typeof sock.sport != "undefined") { + peer.dgram_send_queue.push(new Uint8Array([ 255, 255, 255, 255, "p".charCodeAt(0), "o".charCodeAt(0), "r".charCodeAt(0), "t".charCodeAt(0), (sock.sport & 65280) >> 8, sock.sport & 255 ])); + } + return peer; + }, + getPeer: function(sock, addr, port) { + return sock.peers[addr + ":" + port]; + }, + addPeer: function(sock, peer) { + sock.peers[peer.addr + ":" + peer.port] = peer; + }, + removePeer: function(sock, peer) { + delete sock.peers[peer.addr + ":" + peer.port]; + }, + handlePeerEvents: function(sock, peer) { + var first = true; + var handleOpen = function() { + Module["websocket"].emit("open", sock.stream.fd); + try { + var queued = peer.dgram_send_queue.shift(); + while (queued) { + peer.socket.send(queued); + queued = peer.dgram_send_queue.shift(); + } + } catch (e) { + peer.socket.close(); + } + }; + function handleMessage(data) { + if (typeof data == "string") { + var encoder = new TextEncoder(); + data = encoder.encode(data); + } else { + assert(data.byteLength !== undefined); + if (data.byteLength == 0) { + return; + } + data = new Uint8Array(data); + } + var wasfirst = first; + first = false; + if (wasfirst && data.length === 10 && data[0] === 255 && data[1] === 255 && data[2] === 255 && data[3] === 255 && data[4] === "p".charCodeAt(0) && data[5] === "o".charCodeAt(0) && data[6] === "r".charCodeAt(0) && data[7] === "t".charCodeAt(0)) { + var newport = data[8] << 8 | data[9]; + SOCKFS.websocket_sock_ops.removePeer(sock, peer); + peer.port = newport; + SOCKFS.websocket_sock_ops.addPeer(sock, peer); + return; + } + sock.recv_queue.push({ + addr: peer.addr, + port: peer.port, + data: data + }); + Module["websocket"].emit("message", sock.stream.fd); + } + if (ENVIRONMENT_IS_NODE) { + peer.socket.on("open", handleOpen); + peer.socket.on("message", function(data, isBinary) { + if (!isBinary) { + return; + } + handleMessage(new Uint8Array(data).buffer); + }); + peer.socket.on("close", function() { + Module["websocket"].emit("close", sock.stream.fd); + }); + peer.socket.on("error", function(error) { + sock.error = 14; + Module["websocket"].emit("error", [ sock.stream.fd, sock.error, "ECONNREFUSED: Connection refused" ]); + }); + } else { + peer.socket.onopen = handleOpen; + peer.socket.onclose = function() { + Module["websocket"].emit("close", sock.stream.fd); + }; + peer.socket.onmessage = function peer_socket_onmessage(event) { + handleMessage(event.data); + }; + peer.socket.onerror = function(error) { + sock.error = 14; + Module["websocket"].emit("error", [ sock.stream.fd, sock.error, "ECONNREFUSED: Connection refused" ]); + }; + } + }, + poll: function(sock) { + if (sock.type === 1 && sock.server) { + return sock.pending.length ? 64 | 1 : 0; + } + var mask = 0; + var dest = sock.type === 1 ? SOCKFS.websocket_sock_ops.getPeer(sock, sock.daddr, sock.dport) : null; + if (sock.recv_queue.length || !dest || dest && dest.socket.readyState === dest.socket.CLOSING || dest && dest.socket.readyState === dest.socket.CLOSED) { + mask |= 64 | 1; + } + if (!dest || dest && dest.socket.readyState === dest.socket.OPEN) { + mask |= 4; + } + if (dest && dest.socket.readyState === dest.socket.CLOSING || dest && dest.socket.readyState === dest.socket.CLOSED) { + mask |= 16; + } + return mask; + }, + ioctl: function(sock, request, arg) { + switch (request) { + case 21531: + var bytes = 0; + if (sock.recv_queue.length) { + bytes = sock.recv_queue[0].data.length; + } + GROWABLE_HEAP_I32()[arg >> 2] = bytes; + return 0; + + default: + return 28; + } + }, + close: function(sock) { + if (sock.server) { + try { + sock.server.close(); + } catch (e) {} + sock.server = null; + } + var peers = Object.keys(sock.peers); + for (var i = 0; i < peers.length; i++) { + var peer = sock.peers[peers[i]]; + try { + peer.socket.close(); + } catch (e) {} + SOCKFS.websocket_sock_ops.removePeer(sock, peer); + } + return 0; + }, + bind: function(sock, addr, port) { + if (typeof sock.saddr != "undefined" || typeof sock.sport != "undefined") { + throw new FS.ErrnoError(28); + } + sock.saddr = addr; + sock.sport = port; + if (sock.type === 2) { + if (sock.server) { + sock.server.close(); + sock.server = null; + } + try { + sock.sock_ops.listen(sock, 0); + } catch (e) { + if (!(e.name === "ErrnoError")) throw e; + if (e.errno !== 138) throw e; + } + } + }, + connect: function(sock, addr, port) { + if (sock.server) { + throw new FS.ErrnoError(138); + } + if (typeof sock.daddr != "undefined" && typeof sock.dport != "undefined") { + var dest = SOCKFS.websocket_sock_ops.getPeer(sock, sock.daddr, sock.dport); + if (dest) { + if (dest.socket.readyState === dest.socket.CONNECTING) { + throw new FS.ErrnoError(7); + } else { + throw new FS.ErrnoError(30); + } + } + } + var peer = SOCKFS.websocket_sock_ops.createPeer(sock, addr, port); + sock.daddr = peer.addr; + sock.dport = peer.port; + throw new FS.ErrnoError(26); + }, + listen: function(sock, backlog) { + if (!ENVIRONMENT_IS_NODE) { + throw new FS.ErrnoError(138); + } + }, + accept: function(listensock) { + if (!listensock.server || !listensock.pending.length) { + throw new FS.ErrnoError(28); + } + var newsock = listensock.pending.shift(); + newsock.stream.flags = listensock.stream.flags; + return newsock; + }, + getname: function(sock, peer) { + var addr, port; + if (peer) { + if (sock.daddr === undefined || sock.dport === undefined) { + throw new FS.ErrnoError(53); + } + addr = sock.daddr; + port = sock.dport; + } else { + addr = sock.saddr || 0; + port = sock.sport || 0; + } + return { + addr: addr, + port: port + }; + }, + sendmsg: function(sock, buffer, offset, length, addr, port) { + if (sock.type === 2) { + if (addr === undefined || port === undefined) { + addr = sock.daddr; + port = sock.dport; + } + if (addr === undefined || port === undefined) { + throw new FS.ErrnoError(17); + } + } else { + addr = sock.daddr; + port = sock.dport; + } + var dest = SOCKFS.websocket_sock_ops.getPeer(sock, addr, port); + if (sock.type === 1) { + if (!dest || dest.socket.readyState === dest.socket.CLOSING || dest.socket.readyState === dest.socket.CLOSED) { + throw new FS.ErrnoError(53); + } else if (dest.socket.readyState === dest.socket.CONNECTING) { + throw new FS.ErrnoError(6); + } + } + if (ArrayBuffer.isView(buffer)) { + offset += buffer.byteOffset; + buffer = buffer.buffer; + } + var data; + if (buffer instanceof SharedArrayBuffer) { + data = new Uint8Array(new Uint8Array(buffer.slice(offset, offset + length))).buffer; + } else { + data = buffer.slice(offset, offset + length); + } + if (sock.type === 2) { + if (!dest || dest.socket.readyState !== dest.socket.OPEN) { + if (!dest || dest.socket.readyState === dest.socket.CLOSING || dest.socket.readyState === dest.socket.CLOSED) { + dest = SOCKFS.websocket_sock_ops.createPeer(sock, addr, port); + } + dest.dgram_send_queue.push(data); + return length; + } + } + try { + dest.socket.send(data); + return length; + } catch (e) { + throw new FS.ErrnoError(28); + } + }, + recvmsg: function(sock, length) { + if (sock.type === 1 && sock.server) { + throw new FS.ErrnoError(53); + } + var queued = sock.recv_queue.shift(); + if (!queued) { + if (sock.type === 1) { + var dest = SOCKFS.websocket_sock_ops.getPeer(sock, sock.daddr, sock.dport); + if (!dest) { + throw new FS.ErrnoError(53); + } + if (dest.socket.readyState === dest.socket.CLOSING || dest.socket.readyState === dest.socket.CLOSED) { + return null; + } + throw new FS.ErrnoError(6); + } + throw new FS.ErrnoError(6); + } + var queuedLength = queued.data.byteLength || queued.data.length; + var queuedOffset = queued.data.byteOffset || 0; + var queuedBuffer = queued.data.buffer || queued.data; + var bytesRead = Math.min(length, queuedLength); + var res = { + buffer: new Uint8Array(queuedBuffer, queuedOffset, bytesRead), + addr: queued.addr, + port: queued.port + }; + if (sock.type === 1 && bytesRead < queuedLength) { + var bytesRemaining = queuedLength - bytesRead; + queued.data = new Uint8Array(queuedBuffer, queuedOffset + bytesRead, bytesRemaining); + sock.recv_queue.unshift(queued); + } + return res; + } + } +}; + +function getSocketFromFD(fd) { + var socket = SOCKFS.getSocket(fd); + if (!socket) throw new FS.ErrnoError(8); + return socket; +} + +function setErrNo(value) { + GROWABLE_HEAP_I32()[___errno_location() >> 2] = value; + return value; +} + +var Sockets = { + BUFFER_SIZE: 10240, + MAX_BUFFER_SIZE: 10485760, + nextFd: 1, + fds: {}, + nextport: 1, + maxport: 65535, + peer: null, + connections: {}, + portmap: {}, + localAddr: 4261412874, + addrPool: [ 33554442, 50331658, 67108874, 83886090, 100663306, 117440522, 134217738, 150994954, 167772170, 184549386, 201326602, 218103818, 234881034 ] +}; + +function inetPton4(str) { + var b = str.split("."); + for (var i = 0; i < 4; i++) { + var tmp = Number(b[i]); + if (isNaN(tmp)) return null; + b[i] = tmp; + } + return (b[0] | b[1] << 8 | b[2] << 16 | b[3] << 24) >>> 0; +} + +function jstoi_q(str) { + return parseInt(str); +} + +function inetPton6(str) { + var words; + var w, offset, z, i; + var valid6regx = /^((?=.*::)(?!.*::.+::)(::)?([\dA-F]{1,4}:(:|\b)|){5}|([\dA-F]{1,4}:){6})((([\dA-F]{1,4}((?!\3)::|:\b|$))|(?!\2\3)){2}|(((2[0-4]|1\d|[1-9])?\d|25[0-5])\.?\b){4})$/i; + var parts = []; + if (!valid6regx.test(str)) { + return null; + } + if (str === "::") { + return [ 0, 0, 0, 0, 0, 0, 0, 0 ]; + } + if (str.startsWith("::")) { + str = str.replace("::", "Z:"); + } else { + str = str.replace("::", ":Z:"); + } + if (str.indexOf(".") > 0) { + str = str.replace(new RegExp("[.]", "g"), ":"); + words = str.split(":"); + words[words.length - 4] = jstoi_q(words[words.length - 4]) + jstoi_q(words[words.length - 3]) * 256; + words[words.length - 3] = jstoi_q(words[words.length - 2]) + jstoi_q(words[words.length - 1]) * 256; + words = words.slice(0, words.length - 2); + } else { + words = str.split(":"); + } + offset = 0; + z = 0; + for (w = 0; w < words.length; w++) { + if (typeof words[w] == "string") { + if (words[w] === "Z") { + for (z = 0; z < 8 - words.length + 1; z++) { + parts[w + z] = 0; + } + offset = z - 1; + } else { + parts[w + offset] = _htons(parseInt(words[w], 16)); + } + } else { + parts[w + offset] = words[w]; + } + } + return [ parts[1] << 16 | parts[0], parts[3] << 16 | parts[2], parts[5] << 16 | parts[4], parts[7] << 16 | parts[6] ]; +} + +function writeSockaddr(sa, family, addr, port, addrlen) { + switch (family) { + case 2: + addr = inetPton4(addr); + zeroMemory(sa, 16); + if (addrlen) { + GROWABLE_HEAP_I32()[addrlen >> 2] = 16; + } + GROWABLE_HEAP_I16()[sa >> 1] = family; + GROWABLE_HEAP_I32()[sa + 4 >> 2] = addr; + GROWABLE_HEAP_I16()[sa + 2 >> 1] = _htons(port); + break; + + case 10: + addr = inetPton6(addr); + zeroMemory(sa, 28); + if (addrlen) { + GROWABLE_HEAP_I32()[addrlen >> 2] = 28; + } + GROWABLE_HEAP_I32()[sa >> 2] = family; + GROWABLE_HEAP_I32()[sa + 8 >> 2] = addr[0]; + GROWABLE_HEAP_I32()[sa + 12 >> 2] = addr[1]; + GROWABLE_HEAP_I32()[sa + 16 >> 2] = addr[2]; + GROWABLE_HEAP_I32()[sa + 20 >> 2] = addr[3]; + GROWABLE_HEAP_I16()[sa + 2 >> 1] = _htons(port); + break; + + default: + return 5; + } + return 0; +} + +var DNS = { + address_map: { + id: 1, + addrs: {}, + names: {} + }, + lookup_name: function(name) { + var res = inetPton4(name); + if (res !== null) { + return name; + } + res = inetPton6(name); + if (res !== null) { + return name; + } + var addr; + if (DNS.address_map.addrs[name]) { + addr = DNS.address_map.addrs[name]; + } else { + var id = DNS.address_map.id++; + assert(id < 65535, "exceeded max address mappings of 65535"); + addr = "172.29." + (id & 255) + "." + (id & 65280); + DNS.address_map.names[addr] = name; + DNS.address_map.addrs[name] = addr; + } + return addr; + }, + lookup_addr: function(addr) { + if (DNS.address_map.names[addr]) { + return DNS.address_map.names[addr]; + } + return null; + } +}; + +function ___syscall_accept4(fd, addr, addrlen, flags, d1, d2) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(5, 1, fd, addr, addrlen, flags, d1, d2); + try { + var sock = getSocketFromFD(fd); + var newsock = sock.sock_ops.accept(sock); + if (addr) { + var errno = writeSockaddr(addr, newsock.family, DNS.lookup_name(newsock.daddr), newsock.dport, addrlen); + assert(!errno); + } + return newsock.stream.fd; + } catch (e) { + if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e; + return -e.errno; + } +} + +function inetNtop4(addr) { + return (addr & 255) + "." + (addr >> 8 & 255) + "." + (addr >> 16 & 255) + "." + (addr >> 24 & 255); +} + +function inetNtop6(ints) { + var str = ""; + var word = 0; + var longest = 0; + var lastzero = 0; + var zstart = 0; + var len = 0; + var i = 0; + var parts = [ ints[0] & 65535, ints[0] >> 16, ints[1] & 65535, ints[1] >> 16, ints[2] & 65535, ints[2] >> 16, ints[3] & 65535, ints[3] >> 16 ]; + var hasipv4 = true; + var v4part = ""; + for (i = 0; i < 5; i++) { + if (parts[i] !== 0) { + hasipv4 = false; + break; + } + } + if (hasipv4) { + v4part = inetNtop4(parts[6] | parts[7] << 16); + if (parts[5] === -1) { + str = "::ffff:"; + str += v4part; + return str; + } + if (parts[5] === 0) { + str = "::"; + if (v4part === "0.0.0.0") v4part = ""; + if (v4part === "0.0.0.1") v4part = "1"; + str += v4part; + return str; + } + } + for (word = 0; word < 8; word++) { + if (parts[word] === 0) { + if (word - lastzero > 1) { + len = 0; + } + lastzero = word; + len++; + } + if (len > longest) { + longest = len; + zstart = word - longest + 1; + } + } + for (word = 0; word < 8; word++) { + if (longest > 1) { + if (parts[word] === 0 && word >= zstart && word < zstart + longest) { + if (word === zstart) { + str += ":"; + if (zstart === 0) str += ":"; + } + continue; + } + } + str += Number(_ntohs(parts[word] & 65535)).toString(16); + str += word < 7 ? ":" : ""; + } + return str; +} + +function readSockaddr(sa, salen) { + var family = GROWABLE_HEAP_I16()[sa >> 1]; + var port = _ntohs(GROWABLE_HEAP_U16()[sa + 2 >> 1]); + var addr; + switch (family) { + case 2: + if (salen !== 16) { + return { + errno: 28 + }; + } + addr = GROWABLE_HEAP_I32()[sa + 4 >> 2]; + addr = inetNtop4(addr); + break; + + case 10: + if (salen !== 28) { + return { + errno: 28 + }; + } + addr = [ GROWABLE_HEAP_I32()[sa + 8 >> 2], GROWABLE_HEAP_I32()[sa + 12 >> 2], GROWABLE_HEAP_I32()[sa + 16 >> 2], GROWABLE_HEAP_I32()[sa + 20 >> 2] ]; + addr = inetNtop6(addr); + break; + + default: + return { + errno: 5 + }; + } + return { + family: family, + addr: addr, + port: port + }; +} + +function getSocketAddress(addrp, addrlen, allowNull) { + if (allowNull && addrp === 0) return null; + var info = readSockaddr(addrp, addrlen); + if (info.errno) throw new FS.ErrnoError(info.errno); + info.addr = DNS.lookup_addr(info.addr) || info.addr; + return info; +} + +function ___syscall_bind(fd, addr, addrlen, d1, d2, d3) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(6, 1, fd, addr, addrlen, d1, d2, d3); + try { + var sock = getSocketFromFD(fd); + var info = getSocketAddress(addr, addrlen); + sock.sock_ops.bind(sock, info.addr, info.port); + return 0; + } catch (e) { + if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e; + return -e.errno; + } +} + +function ___syscall_chdir(path) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(7, 1, path); + try { + path = SYSCALLS.getStr(path); + FS.chdir(path); + return 0; + } catch (e) { + if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e; + return -e.errno; + } +} + +function ___syscall_chmod(path, mode) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(8, 1, path, mode); + try { + path = SYSCALLS.getStr(path); + FS.chmod(path, mode); + return 0; + } catch (e) { + if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e; + return -e.errno; + } +} + +function ___syscall_connect(fd, addr, addrlen, d1, d2, d3) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(9, 1, fd, addr, addrlen, d1, d2, d3); + try { + var sock = getSocketFromFD(fd); + var info = getSocketAddress(addr, addrlen); + sock.sock_ops.connect(sock, info.addr, info.port); + return 0; + } catch (e) { + if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e; + return -e.errno; + } +} + +function ___syscall_faccessat(dirfd, path, amode, flags) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(10, 1, dirfd, path, amode, flags); + try { + path = SYSCALLS.getStr(path); + assert(flags === 0); + path = SYSCALLS.calculateAt(dirfd, path); + if (amode & ~7) { + return -28; + } + var lookup = FS.lookupPath(path, { + follow: true + }); + var node = lookup.node; + if (!node) { + return -44; + } + var perms = ""; + if (amode & 4) perms += "r"; + if (amode & 2) perms += "w"; + if (amode & 1) perms += "x"; + if (perms && FS.nodePermissions(node, perms)) { + return -2; + } + return 0; + } catch (e) { + if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e; + return -e.errno; + } +} + +function ___syscall_fchmod(fd, mode) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(11, 1, fd, mode); + try { + FS.fchmod(fd, mode); + return 0; + } catch (e) { + if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e; + return -e.errno; + } +} + +function ___syscall_fcntl64(fd, cmd, varargs) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(12, 1, fd, cmd, varargs); + SYSCALLS.varargs = varargs; + try { + var stream = SYSCALLS.getStreamFromFD(fd); + switch (cmd) { + case 0: + { + var arg = SYSCALLS.get(); + if (arg < 0) { + return -28; + } + var newStream; + newStream = FS.createStream(stream, arg); + return newStream.fd; + } + + case 1: + case 2: + return 0; + + case 3: + return stream.flags; + + case 4: + { + var arg = SYSCALLS.get(); + stream.flags |= arg; + return 0; + } + + case 5: + { + var arg = SYSCALLS.get(); + var offset = 0; + GROWABLE_HEAP_I16()[arg + offset >> 1] = 2; + return 0; + } + + case 6: + case 7: + return 0; + + case 16: + case 8: + return -28; + + case 9: + setErrNo(28); + return -1; + + default: + { + return -28; + } + } + } catch (e) { + if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e; + return -e.errno; + } +} + +function stringToUTF8(str, outPtr, maxBytesToWrite) { + assert(typeof maxBytesToWrite == "number", "stringToUTF8(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!"); + return stringToUTF8Array(str, GROWABLE_HEAP_U8(), outPtr, maxBytesToWrite); +} + +function ___syscall_getcwd(buf, size) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(13, 1, buf, size); + try { + if (size === 0) return -28; + var cwd = FS.cwd(); + var cwdLengthInBytes = lengthBytesUTF8(cwd) + 1; + if (size < cwdLengthInBytes) return -68; + stringToUTF8(cwd, buf, size); + return cwdLengthInBytes; + } catch (e) { + if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e; + return -e.errno; + } +} + +function ___syscall_getdents64(fd, dirp, count) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(14, 1, fd, dirp, count); + try { + var stream = SYSCALLS.getStreamFromFD(fd); + if (!stream.getdents) { + stream.getdents = FS.readdir(stream.path); + } + var struct_size = 280; + var pos = 0; + var off = FS.llseek(stream, 0, 1); + var idx = Math.floor(off / struct_size); + while (idx < stream.getdents.length && pos + struct_size <= count) { + var id; + var type; + var name = stream.getdents[idx]; + if (name === ".") { + id = stream.node.id; + type = 4; + } else if (name === "..") { + var lookup = FS.lookupPath(stream.path, { + parent: true + }); + id = lookup.node.id; + type = 4; + } else { + var child = FS.lookupNode(stream.node, name); + id = child.id; + type = FS.isChrdev(child.mode) ? 2 : FS.isDir(child.mode) ? 4 : FS.isLink(child.mode) ? 10 : 8; + } + assert(id); + tempI64 = [ id >>> 0, (tempDouble = id, +Math.abs(tempDouble) >= 1 ? tempDouble > 0 ? +Math.floor(tempDouble / 4294967296) >>> 0 : ~~+Math.ceil((tempDouble - +(~~tempDouble >>> 0)) / 4294967296) >>> 0 : 0) ], + GROWABLE_HEAP_I32()[dirp + pos >> 2] = tempI64[0], GROWABLE_HEAP_I32()[dirp + pos + 4 >> 2] = tempI64[1]; + tempI64 = [ (idx + 1) * struct_size >>> 0, (tempDouble = (idx + 1) * struct_size, + +Math.abs(tempDouble) >= 1 ? tempDouble > 0 ? +Math.floor(tempDouble / 4294967296) >>> 0 : ~~+Math.ceil((tempDouble - +(~~tempDouble >>> 0)) / 4294967296) >>> 0 : 0) ], + GROWABLE_HEAP_I32()[dirp + pos + 8 >> 2] = tempI64[0], GROWABLE_HEAP_I32()[dirp + pos + 12 >> 2] = tempI64[1]; + GROWABLE_HEAP_I16()[dirp + pos + 16 >> 1] = 280; + GROWABLE_HEAP_I8()[dirp + pos + 18 >> 0] = type; + stringToUTF8(name, dirp + pos + 19, 256); + pos += struct_size; + idx += 1; + } + FS.llseek(stream, idx * struct_size, 0); + return pos; + } catch (e) { + if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e; + return -e.errno; + } +} + +function ___syscall_getsockname(fd, addr, addrlen, d1, d2, d3) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(15, 1, fd, addr, addrlen, d1, d2, d3); + try { + var sock = getSocketFromFD(fd); + var errno = writeSockaddr(addr, sock.family, DNS.lookup_name(sock.saddr || "0.0.0.0"), sock.sport, addrlen); + assert(!errno); + return 0; + } catch (e) { + if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e; + return -e.errno; + } +} + +function ___syscall_getsockopt(fd, level, optname, optval, optlen, d1) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(16, 1, fd, level, optname, optval, optlen, d1); + try { + var sock = getSocketFromFD(fd); + if (level === 1) { + if (optname === 4) { + GROWABLE_HEAP_I32()[optval >> 2] = sock.error; + GROWABLE_HEAP_I32()[optlen >> 2] = 4; + sock.error = null; + return 0; + } + } + return -50; + } catch (e) { + if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e; + return -e.errno; + } +} + +function ___syscall_ioctl(fd, op, varargs) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(17, 1, fd, op, varargs); + SYSCALLS.varargs = varargs; + try { + var stream = SYSCALLS.getStreamFromFD(fd); + switch (op) { + case 21509: + case 21505: + { + if (!stream.tty) return -59; + return 0; + } + + case 21510: + case 21511: + case 21512: + case 21506: + case 21507: + case 21508: + { + if (!stream.tty) return -59; + return 0; + } + + case 21519: + { + if (!stream.tty) return -59; + var argp = SYSCALLS.get(); + GROWABLE_HEAP_I32()[argp >> 2] = 0; + return 0; + } + + case 21520: + { + if (!stream.tty) return -59; + return -28; + } + + case 21531: + { + var argp = SYSCALLS.get(); + return FS.ioctl(stream, op, argp); + } + + case 21523: + { + if (!stream.tty) return -59; + return 0; + } + + case 21524: + { + if (!stream.tty) return -59; + return 0; + } + + default: + return -28; + } + } catch (e) { + if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e; + return -e.errno; + } +} + +function ___syscall_listen(fd, backlog) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(18, 1, fd, backlog); + try { + var sock = getSocketFromFD(fd); + sock.sock_ops.listen(sock, backlog); + return 0; + } catch (e) { + if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e; + return -e.errno; + } +} + +function ___syscall_lstat64(path, buf) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(19, 1, path, buf); + try { + path = SYSCALLS.getStr(path); + return SYSCALLS.doStat(FS.lstat, path, buf); + } catch (e) { + if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e; + return -e.errno; + } +} + +function ___syscall_mkdirat(dirfd, path, mode) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(20, 1, dirfd, path, mode); + try { + path = SYSCALLS.getStr(path); + path = SYSCALLS.calculateAt(dirfd, path); + path = PATH.normalize(path); + if (path[path.length - 1] === "/") path = path.substr(0, path.length - 1); + FS.mkdir(path, mode, 0); + return 0; + } catch (e) { + if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e; + return -e.errno; + } +} + +function ___syscall_newfstatat(dirfd, path, buf, flags) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(21, 1, dirfd, path, buf, flags); + try { + path = SYSCALLS.getStr(path); + var nofollow = flags & 256; + var allowEmpty = flags & 4096; + flags = flags & ~6400; + assert(!flags, "unknown flags in __syscall_newfstatat: " + flags); + path = SYSCALLS.calculateAt(dirfd, path, allowEmpty); + return SYSCALLS.doStat(nofollow ? FS.lstat : FS.stat, path, buf); + } catch (e) { + if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e; + return -e.errno; + } +} + +function ___syscall_openat(dirfd, path, flags, varargs) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(22, 1, dirfd, path, flags, varargs); + SYSCALLS.varargs = varargs; + try { + path = SYSCALLS.getStr(path); + path = SYSCALLS.calculateAt(dirfd, path); + var mode = varargs ? SYSCALLS.get() : 0; + return FS.open(path, flags, mode).fd; + } catch (e) { + if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e; + return -e.errno; + } +} + +function ___syscall_poll(fds, nfds, timeout) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(23, 1, fds, nfds, timeout); + try { + var nonzero = 0; + for (var i = 0; i < nfds; i++) { + var pollfd = fds + 8 * i; + var fd = GROWABLE_HEAP_I32()[pollfd >> 2]; + var events = GROWABLE_HEAP_I16()[pollfd + 4 >> 1]; + var mask = 32; + var stream = FS.getStream(fd); + if (stream) { + mask = SYSCALLS.DEFAULT_POLLMASK; + if (stream.stream_ops.poll) { + mask = stream.stream_ops.poll(stream); + } + } + mask &= events | 8 | 16; + if (mask) nonzero++; + GROWABLE_HEAP_I16()[pollfd + 6 >> 1] = mask; + } + return nonzero; + } catch (e) { + if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e; + return -e.errno; + } +} + +function ___syscall_readlinkat(dirfd, path, buf, bufsize) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(24, 1, dirfd, path, buf, bufsize); + try { + path = SYSCALLS.getStr(path); + path = SYSCALLS.calculateAt(dirfd, path); + if (bufsize <= 0) return -28; + var ret = FS.readlink(path); + var len = Math.min(bufsize, lengthBytesUTF8(ret)); + var endChar = GROWABLE_HEAP_I8()[buf + len]; + stringToUTF8(ret, buf, bufsize + 1); + GROWABLE_HEAP_I8()[buf + len] = endChar; + return len; + } catch (e) { + if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e; + return -e.errno; + } +} + +function ___syscall_recvfrom(fd, buf, len, flags, addr, addrlen) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(25, 1, fd, buf, len, flags, addr, addrlen); + try { + var sock = getSocketFromFD(fd); + var msg = sock.sock_ops.recvmsg(sock, len); + if (!msg) return 0; + if (addr) { + var errno = writeSockaddr(addr, sock.family, DNS.lookup_name(msg.addr), msg.port, addrlen); + assert(!errno); + } + GROWABLE_HEAP_U8().set(msg.buffer, buf); + return msg.buffer.byteLength; + } catch (e) { + if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e; + return -e.errno; + } +} + +function ___syscall_renameat(olddirfd, oldpath, newdirfd, newpath) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(26, 1, olddirfd, oldpath, newdirfd, newpath); + try { + oldpath = SYSCALLS.getStr(oldpath); + newpath = SYSCALLS.getStr(newpath); + oldpath = SYSCALLS.calculateAt(olddirfd, oldpath); + newpath = SYSCALLS.calculateAt(newdirfd, newpath); + FS.rename(oldpath, newpath); + return 0; + } catch (e) { + if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e; + return -e.errno; + } +} + +function ___syscall_rmdir(path) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(27, 1, path); + try { + path = SYSCALLS.getStr(path); + FS.rmdir(path); + return 0; + } catch (e) { + if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e; + return -e.errno; + } +} + +function ___syscall_sendto(fd, message, length, flags, addr, addr_len) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(28, 1, fd, message, length, flags, addr, addr_len); + try { + var sock = getSocketFromFD(fd); + var dest = getSocketAddress(addr, addr_len, true); + if (!dest) { + return FS.write(sock.stream, GROWABLE_HEAP_I8(), message, length); + } + return sock.sock_ops.sendmsg(sock, GROWABLE_HEAP_I8(), message, length, dest.addr, dest.port); + } catch (e) { + if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e; + return -e.errno; + } +} + +function ___syscall_socket(domain, type, protocol) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(29, 1, domain, type, protocol); + try { + var sock = SOCKFS.createSocket(domain, type, protocol); + assert(sock.stream.fd < 64); + return sock.stream.fd; + } catch (e) { + if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e; + return -e.errno; + } +} + +function ___syscall_stat64(path, buf) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(30, 1, path, buf); + try { + path = SYSCALLS.getStr(path); + return SYSCALLS.doStat(FS.stat, path, buf); + } catch (e) { + if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e; + return -e.errno; + } +} + +function ___syscall_statfs64(path, size, buf) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(31, 1, path, size, buf); + try { + path = SYSCALLS.getStr(path); + assert(size === 64); + GROWABLE_HEAP_I32()[buf + 4 >> 2] = 4096; + GROWABLE_HEAP_I32()[buf + 40 >> 2] = 4096; + GROWABLE_HEAP_I32()[buf + 8 >> 2] = 1e6; + GROWABLE_HEAP_I32()[buf + 12 >> 2] = 5e5; + GROWABLE_HEAP_I32()[buf + 16 >> 2] = 5e5; + GROWABLE_HEAP_I32()[buf + 20 >> 2] = FS.nextInode; + GROWABLE_HEAP_I32()[buf + 24 >> 2] = 1e6; + GROWABLE_HEAP_I32()[buf + 28 >> 2] = 42; + GROWABLE_HEAP_I32()[buf + 44 >> 2] = 2; + GROWABLE_HEAP_I32()[buf + 36 >> 2] = 255; + return 0; + } catch (e) { + if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e; + return -e.errno; + } +} + +function ___syscall_symlink(target, linkpath) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(32, 1, target, linkpath); + try { + target = SYSCALLS.getStr(target); + linkpath = SYSCALLS.getStr(linkpath); + FS.symlink(target, linkpath); + return 0; + } catch (e) { + if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e; + return -e.errno; + } +} + +function ___syscall_unlinkat(dirfd, path, flags) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(33, 1, dirfd, path, flags); + try { + path = SYSCALLS.getStr(path); + path = SYSCALLS.calculateAt(dirfd, path); + if (flags === 0) { + FS.unlink(path); + } else if (flags === 512) { + FS.rmdir(path); + } else { + abort("Invalid flags passed to unlinkat"); + } + return 0; + } catch (e) { + if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e; + return -e.errno; + } +} + +var nowIsMonotonic = true; + +function __emscripten_get_now_is_monotonic() { + return nowIsMonotonic; +} + +function maybeExit() { + if (runtimeExited) { + return; + } + if (!keepRuntimeAlive()) { + try { + if (ENVIRONMENT_IS_PTHREAD) __emscripten_thread_exit(EXITSTATUS); else _exit(EXITSTATUS); + } catch (e) { + handleException(e); + } + } +} + +function callUserCallback(func) { + if (runtimeExited || ABORT) { + err("user callback triggered after runtime exited or application aborted. Ignoring."); + return; + } + try { + func(); + maybeExit(); + } catch (e) { + handleException(e); + } +} + +function __emscripten_thread_mailbox_await(pthread_ptr) { + if (typeof Atomics.waitAsync === "function") { + var wait = Atomics.waitAsync(GROWABLE_HEAP_I32(), pthread_ptr >> 2, pthread_ptr); + assert(wait.async); + wait.value.then(checkMailbox); + var waitingAsync = pthread_ptr + 128; + Atomics.store(GROWABLE_HEAP_I32(), waitingAsync >> 2, 1); + } +} + +Module["__emscripten_thread_mailbox_await"] = __emscripten_thread_mailbox_await; + +function checkMailbox() { + var pthread_ptr = _pthread_self(); + if (pthread_ptr) { + __emscripten_thread_mailbox_await(pthread_ptr); + callUserCallback(() => __emscripten_check_mailbox()); + } +} + +Module["checkMailbox"] = checkMailbox; + +function __emscripten_notify_mailbox_postmessage(targetThreadId, currThreadId, mainThreadId) { + if (targetThreadId == currThreadId) { + setTimeout(() => checkMailbox()); + } else if (ENVIRONMENT_IS_PTHREAD) { + postMessage({ + "targetThread": targetThreadId, + "cmd": "checkMailbox" + }); + } else { + var worker = PThread.pthreads[targetThreadId]; + if (!worker) { + err("Cannot send message to thread with ID " + targetThreadId + ", unknown thread ID!"); + return; + } + worker.postMessage({ + "cmd": "checkMailbox" + }); + } +} + +function webgl_enable_ANGLE_instanced_arrays(ctx) { + var ext = ctx.getExtension("ANGLE_instanced_arrays"); + if (ext) { + ctx["vertexAttribDivisor"] = function(index, divisor) { + ext["vertexAttribDivisorANGLE"](index, divisor); + }; + ctx["drawArraysInstanced"] = function(mode, first, count, primcount) { + ext["drawArraysInstancedANGLE"](mode, first, count, primcount); + }; + ctx["drawElementsInstanced"] = function(mode, count, type, indices, primcount) { + ext["drawElementsInstancedANGLE"](mode, count, type, indices, primcount); + }; + return 1; + } +} + +function webgl_enable_OES_vertex_array_object(ctx) { + var ext = ctx.getExtension("OES_vertex_array_object"); + if (ext) { + ctx["createVertexArray"] = function() { + return ext["createVertexArrayOES"](); + }; + ctx["deleteVertexArray"] = function(vao) { + ext["deleteVertexArrayOES"](vao); + }; + ctx["bindVertexArray"] = function(vao) { + ext["bindVertexArrayOES"](vao); + }; + ctx["isVertexArray"] = function(vao) { + return ext["isVertexArrayOES"](vao); + }; + return 1; + } +} + +function webgl_enable_WEBGL_draw_buffers(ctx) { + var ext = ctx.getExtension("WEBGL_draw_buffers"); + if (ext) { + ctx["drawBuffers"] = function(n, bufs) { + ext["drawBuffersWEBGL"](n, bufs); + }; + return 1; + } +} + +function webgl_enable_WEBGL_draw_instanced_base_vertex_base_instance(ctx) { + return !!(ctx.dibvbi = ctx.getExtension("WEBGL_draw_instanced_base_vertex_base_instance")); +} + +function webgl_enable_WEBGL_multi_draw_instanced_base_vertex_base_instance(ctx) { + return !!(ctx.mdibvbi = ctx.getExtension("WEBGL_multi_draw_instanced_base_vertex_base_instance")); +} + +function webgl_enable_WEBGL_multi_draw(ctx) { + return !!(ctx.multiDrawWebgl = ctx.getExtension("WEBGL_multi_draw")); +} + +var GL = { + counter: 1, + buffers: [], + programs: [], + framebuffers: [], + renderbuffers: [], + textures: [], + shaders: [], + vaos: [], + contexts: {}, + offscreenCanvases: {}, + queries: [], + samplers: [], + transformFeedbacks: [], + syncs: [], + stringCache: {}, + stringiCache: {}, + unpackAlignment: 4, + recordError: function recordError(errorCode) { + if (!GL.lastError) { + GL.lastError = errorCode; + } + }, + getNewId: function(table) { + var ret = GL.counter++; + for (var i = table.length; i < ret; i++) { + table[i] = null; + } + return ret; + }, + getSource: function(shader, count, string, length) { + var source = ""; + for (var i = 0; i < count; ++i) { + var len = length ? GROWABLE_HEAP_I32()[length + i * 4 >> 2] : -1; + source += UTF8ToString(GROWABLE_HEAP_I32()[string + i * 4 >> 2], len < 0 ? undefined : len); + } + return source; + }, + createContext: function(canvas, webGLContextAttributes) { + if (webGLContextAttributes.renderViaOffscreenBackBuffer) webGLContextAttributes["preserveDrawingBuffer"] = true; + var ctx = webGLContextAttributes.majorVersion > 1 ? canvas.getContext("webgl2", webGLContextAttributes) : canvas.getContext("webgl", webGLContextAttributes); + if (!ctx) return 0; + var handle = GL.registerContext(ctx, webGLContextAttributes); + return handle; + }, + enableOffscreenFramebufferAttributes: function(webGLContextAttributes) { + webGLContextAttributes.renderViaOffscreenBackBuffer = true; + webGLContextAttributes.preserveDrawingBuffer = true; + }, + createOffscreenFramebuffer: function(context) { + var gl = context.GLctx; + var fbo = gl.createFramebuffer(); + gl.bindFramebuffer(36160, fbo); + context.defaultFbo = fbo; + context.defaultFboForbidBlitFramebuffer = false; + if (gl.getContextAttributes().antialias) { + context.defaultFboForbidBlitFramebuffer = true; + } + context.defaultColorTarget = gl.createTexture(); + context.defaultDepthTarget = gl.createRenderbuffer(); + GL.resizeOffscreenFramebuffer(context); + gl.bindTexture(3553, context.defaultColorTarget); + gl.texParameteri(3553, 10241, 9728); + gl.texParameteri(3553, 10240, 9728); + gl.texParameteri(3553, 10242, 33071); + gl.texParameteri(3553, 10243, 33071); + gl.texImage2D(3553, 0, 6408, gl.canvas.width, gl.canvas.height, 0, 6408, 5121, null); + gl.framebufferTexture2D(36160, 36064, 3553, context.defaultColorTarget, 0); + gl.bindTexture(3553, null); + var depthTarget = gl.createRenderbuffer(); + gl.bindRenderbuffer(36161, context.defaultDepthTarget); + gl.renderbufferStorage(36161, 33189, gl.canvas.width, gl.canvas.height); + gl.framebufferRenderbuffer(36160, 36096, 36161, context.defaultDepthTarget); + gl.bindRenderbuffer(36161, null); + var vertices = [ -1, -1, -1, 1, 1, -1, 1, 1 ]; + var vb = gl.createBuffer(); + gl.bindBuffer(34962, vb); + gl.bufferData(34962, new Float32Array(vertices), 35044); + gl.bindBuffer(34962, null); + context.blitVB = vb; + var vsCode = "attribute vec2 pos;" + "varying lowp vec2 tex;" + "void main() { tex = pos * 0.5 + vec2(0.5,0.5); gl_Position = vec4(pos, 0.0, 1.0); }"; + var vs = gl.createShader(35633); + gl.shaderSource(vs, vsCode); + gl.compileShader(vs); + var fsCode = "varying lowp vec2 tex;" + "uniform sampler2D sampler;" + "void main() { gl_FragColor = texture2D(sampler, tex); }"; + var fs = gl.createShader(35632); + gl.shaderSource(fs, fsCode); + gl.compileShader(fs); + var blitProgram = gl.createProgram(); + gl.attachShader(blitProgram, vs); + gl.attachShader(blitProgram, fs); + gl.linkProgram(blitProgram); + context.blitProgram = blitProgram; + context.blitPosLoc = gl.getAttribLocation(blitProgram, "pos"); + gl.useProgram(blitProgram); + gl.uniform1i(gl.getUniformLocation(blitProgram, "sampler"), 0); + gl.useProgram(null); + context.defaultVao = undefined; + if (gl.createVertexArray) { + context.defaultVao = gl.createVertexArray(); + gl.bindVertexArray(context.defaultVao); + gl.enableVertexAttribArray(context.blitPosLoc); + gl.bindVertexArray(null); + } + }, + resizeOffscreenFramebuffer: function(context) { + var gl = context.GLctx; + if (context.defaultColorTarget) { + var prevTextureBinding = gl.getParameter(32873); + gl.bindTexture(3553, context.defaultColorTarget); + gl.texImage2D(3553, 0, 6408, gl.drawingBufferWidth, gl.drawingBufferHeight, 0, 6408, 5121, null); + gl.bindTexture(3553, prevTextureBinding); + } + if (context.defaultDepthTarget) { + var prevRenderBufferBinding = gl.getParameter(36007); + gl.bindRenderbuffer(36161, context.defaultDepthTarget); + gl.renderbufferStorage(36161, 33189, gl.drawingBufferWidth, gl.drawingBufferHeight); + gl.bindRenderbuffer(36161, prevRenderBufferBinding); + } + }, + blitOffscreenFramebuffer: function(context) { + var gl = context.GLctx; + var prevScissorTest = gl.getParameter(3089); + if (prevScissorTest) gl.disable(3089); + var prevFbo = gl.getParameter(36006); + if (gl.blitFramebuffer && !context.defaultFboForbidBlitFramebuffer) { + gl.bindFramebuffer(36008, context.defaultFbo); + gl.bindFramebuffer(36009, null); + gl.blitFramebuffer(0, 0, gl.canvas.width, gl.canvas.height, 0, 0, gl.canvas.width, gl.canvas.height, 16384, 9728); + } else { + gl.bindFramebuffer(36160, null); + var prevProgram = gl.getParameter(35725); + gl.useProgram(context.blitProgram); + var prevVB = gl.getParameter(34964); + gl.bindBuffer(34962, context.blitVB); + var prevActiveTexture = gl.getParameter(34016); + gl.activeTexture(33984); + var prevTextureBinding = gl.getParameter(32873); + gl.bindTexture(3553, context.defaultColorTarget); + var prevBlend = gl.getParameter(3042); + if (prevBlend) gl.disable(3042); + var prevCullFace = gl.getParameter(2884); + if (prevCullFace) gl.disable(2884); + var prevDepthTest = gl.getParameter(2929); + if (prevDepthTest) gl.disable(2929); + var prevStencilTest = gl.getParameter(2960); + if (prevStencilTest) gl.disable(2960); + function draw() { + gl.vertexAttribPointer(context.blitPosLoc, 2, 5126, false, 0, 0); + gl.drawArrays(5, 0, 4); + } + if (context.defaultVao) { + var prevVAO = gl.getParameter(34229); + gl.bindVertexArray(context.defaultVao); + draw(); + gl.bindVertexArray(prevVAO); + } else { + var prevVertexAttribPointer = { + buffer: gl.getVertexAttrib(context.blitPosLoc, 34975), + size: gl.getVertexAttrib(context.blitPosLoc, 34339), + stride: gl.getVertexAttrib(context.blitPosLoc, 34340), + type: gl.getVertexAttrib(context.blitPosLoc, 34341), + normalized: gl.getVertexAttrib(context.blitPosLoc, 34922), + pointer: gl.getVertexAttribOffset(context.blitPosLoc, 34373) + }; + var maxVertexAttribs = gl.getParameter(34921); + var prevVertexAttribEnables = []; + for (var i = 0; i < maxVertexAttribs; ++i) { + var prevEnabled = gl.getVertexAttrib(i, 34338); + var wantEnabled = i == context.blitPosLoc; + if (prevEnabled && !wantEnabled) { + gl.disableVertexAttribArray(i); + } + if (!prevEnabled && wantEnabled) { + gl.enableVertexAttribArray(i); + } + prevVertexAttribEnables[i] = prevEnabled; + } + draw(); + for (var i = 0; i < maxVertexAttribs; ++i) { + var prevEnabled = prevVertexAttribEnables[i]; + var nowEnabled = i == context.blitPosLoc; + if (prevEnabled && !nowEnabled) { + gl.enableVertexAttribArray(i); + } + if (!prevEnabled && nowEnabled) { + gl.disableVertexAttribArray(i); + } + } + gl.bindBuffer(34962, prevVertexAttribPointer.buffer); + gl.vertexAttribPointer(context.blitPosLoc, prevVertexAttribPointer.size, prevVertexAttribPointer.type, prevVertexAttribPointer.normalized, prevVertexAttribPointer.stride, prevVertexAttribPointer.offset); + } + if (prevStencilTest) gl.enable(2960); + if (prevDepthTest) gl.enable(2929); + if (prevCullFace) gl.enable(2884); + if (prevBlend) gl.enable(3042); + gl.bindTexture(3553, prevTextureBinding); + gl.activeTexture(prevActiveTexture); + gl.bindBuffer(34962, prevVB); + gl.useProgram(prevProgram); + } + gl.bindFramebuffer(36160, prevFbo); + if (prevScissorTest) gl.enable(3089); + }, + registerContext: function(ctx, webGLContextAttributes) { + var handle = _malloc(8); + GROWABLE_HEAP_I32()[handle + 4 >> 2] = _pthread_self(); + var context = { + handle: handle, + attributes: webGLContextAttributes, + version: webGLContextAttributes.majorVersion, + GLctx: ctx + }; + if (ctx.canvas) ctx.canvas.GLctxObject = context; + GL.contexts[handle] = context; + if (typeof webGLContextAttributes.enableExtensionsByDefault == "undefined" || webGLContextAttributes.enableExtensionsByDefault) { + GL.initExtensions(context); + } + if (webGLContextAttributes.renderViaOffscreenBackBuffer) GL.createOffscreenFramebuffer(context); + return handle; + }, + makeContextCurrent: function(contextHandle) { + GL.currentContext = GL.contexts[contextHandle]; + Module.ctx = GLctx = GL.currentContext && GL.currentContext.GLctx; + return !(contextHandle && !GLctx); + }, + getContext: function(contextHandle) { + return GL.contexts[contextHandle]; + }, + deleteContext: function(contextHandle) { + if (GL.currentContext === GL.contexts[contextHandle]) GL.currentContext = null; + if (typeof JSEvents == "object") JSEvents.removeAllHandlersOnTarget(GL.contexts[contextHandle].GLctx.canvas); + if (GL.contexts[contextHandle] && GL.contexts[contextHandle].GLctx.canvas) GL.contexts[contextHandle].GLctx.canvas.GLctxObject = undefined; + _free(GL.contexts[contextHandle].handle); + GL.contexts[contextHandle] = null; + }, + initExtensions: function(context) { + if (!context) context = GL.currentContext; + if (context.initExtensionsDone) return; + context.initExtensionsDone = true; + var GLctx = context.GLctx; + webgl_enable_ANGLE_instanced_arrays(GLctx); + webgl_enable_OES_vertex_array_object(GLctx); + webgl_enable_WEBGL_draw_buffers(GLctx); + webgl_enable_WEBGL_draw_instanced_base_vertex_base_instance(GLctx); + webgl_enable_WEBGL_multi_draw_instanced_base_vertex_base_instance(GLctx); + if (context.version >= 2) { + GLctx.disjointTimerQueryExt = GLctx.getExtension("EXT_disjoint_timer_query_webgl2"); + } + if (context.version < 2 || !GLctx.disjointTimerQueryExt) { + GLctx.disjointTimerQueryExt = GLctx.getExtension("EXT_disjoint_timer_query"); + } + webgl_enable_WEBGL_multi_draw(GLctx); + var exts = GLctx.getSupportedExtensions() || []; + exts.forEach(function(ext) { + if (!ext.includes("lose_context") && !ext.includes("debug")) { + GLctx.getExtension(ext); + } + }); + } +}; + +function __emscripten_proxied_gl_context_activated_from_main_browser_thread(contextHandle) { + GLctx = Module.ctx = GL.currentContext = contextHandle; + GL.currentContextIsProxied = true; +} + +function __emscripten_set_offscreencanvas_size(target, width, height) { + err("emscripten_set_offscreencanvas_size: Build with -sOFFSCREENCANVAS_SUPPORT=1 to enable transferring canvases to pthreads."); + return -1; +} + +function __emscripten_thread_set_strongref(thread) {} + +function __emscripten_throw_longjmp() { + throw Infinity; +} + +function readI53FromI64(ptr) { + return GROWABLE_HEAP_U32()[ptr >> 2] + GROWABLE_HEAP_I32()[ptr + 4 >> 2] * 4294967296; +} + +function __gmtime_js(time, tmPtr) { + var date = new Date(readI53FromI64(time) * 1e3); + GROWABLE_HEAP_I32()[tmPtr >> 2] = date.getUTCSeconds(); + GROWABLE_HEAP_I32()[tmPtr + 4 >> 2] = date.getUTCMinutes(); + GROWABLE_HEAP_I32()[tmPtr + 8 >> 2] = date.getUTCHours(); + GROWABLE_HEAP_I32()[tmPtr + 12 >> 2] = date.getUTCDate(); + GROWABLE_HEAP_I32()[tmPtr + 16 >> 2] = date.getUTCMonth(); + GROWABLE_HEAP_I32()[tmPtr + 20 >> 2] = date.getUTCFullYear() - 1900; + GROWABLE_HEAP_I32()[tmPtr + 24 >> 2] = date.getUTCDay(); + var start = Date.UTC(date.getUTCFullYear(), 0, 1, 0, 0, 0, 0); + var yday = (date.getTime() - start) / (1e3 * 60 * 60 * 24) | 0; + GROWABLE_HEAP_I32()[tmPtr + 28 >> 2] = yday; +} + +function isLeapYear(year) { + return year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0); +} + +var MONTH_DAYS_LEAP_CUMULATIVE = [ 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 ]; + +var MONTH_DAYS_REGULAR_CUMULATIVE = [ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 ]; + +function ydayFromDate(date) { + var leap = isLeapYear(date.getFullYear()); + var monthDaysCumulative = leap ? MONTH_DAYS_LEAP_CUMULATIVE : MONTH_DAYS_REGULAR_CUMULATIVE; + var yday = monthDaysCumulative[date.getMonth()] + date.getDate() - 1; + return yday; +} + +function __localtime_js(time, tmPtr) { + var date = new Date(readI53FromI64(time) * 1e3); + GROWABLE_HEAP_I32()[tmPtr >> 2] = date.getSeconds(); + GROWABLE_HEAP_I32()[tmPtr + 4 >> 2] = date.getMinutes(); + GROWABLE_HEAP_I32()[tmPtr + 8 >> 2] = date.getHours(); + GROWABLE_HEAP_I32()[tmPtr + 12 >> 2] = date.getDate(); + GROWABLE_HEAP_I32()[tmPtr + 16 >> 2] = date.getMonth(); + GROWABLE_HEAP_I32()[tmPtr + 20 >> 2] = date.getFullYear() - 1900; + GROWABLE_HEAP_I32()[tmPtr + 24 >> 2] = date.getDay(); + var yday = ydayFromDate(date) | 0; + GROWABLE_HEAP_I32()[tmPtr + 28 >> 2] = yday; + GROWABLE_HEAP_I32()[tmPtr + 36 >> 2] = -(date.getTimezoneOffset() * 60); + var start = new Date(date.getFullYear(), 0, 1); + var summerOffset = new Date(date.getFullYear(), 6, 1).getTimezoneOffset(); + var winterOffset = start.getTimezoneOffset(); + var dst = (summerOffset != winterOffset && date.getTimezoneOffset() == Math.min(winterOffset, summerOffset)) | 0; + GROWABLE_HEAP_I32()[tmPtr + 32 >> 2] = dst; +} + +var timers = {}; + +var _emscripten_get_now; + +_emscripten_get_now = () => performance.timeOrigin + performance.now(); + +function __setitimer_js(which, timeout_ms) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(34, 1, which, timeout_ms); + if (timers[which]) { + clearTimeout(timers[which].id); + delete timers[which]; + } + if (!timeout_ms) return 0; + var id = setTimeout(() => { + assert(which in timers); + delete timers[which]; + callUserCallback(() => __emscripten_timeout(which, _emscripten_get_now())); + }, timeout_ms); + timers[which] = { + id: id, + timeout_ms: timeout_ms + }; + return 0; +} + +function stringToNewUTF8(str) { + var size = lengthBytesUTF8(str) + 1; + var ret = _malloc(size); + if (ret) stringToUTF8(str, ret, size); + return ret; +} + +function __tzset_js(timezone, daylight, tzname) { + var currentYear = new Date().getFullYear(); + var winter = new Date(currentYear, 0, 1); + var summer = new Date(currentYear, 6, 1); + var winterOffset = winter.getTimezoneOffset(); + var summerOffset = summer.getTimezoneOffset(); + var stdTimezoneOffset = Math.max(winterOffset, summerOffset); + GROWABLE_HEAP_U32()[timezone >> 2] = stdTimezoneOffset * 60; + GROWABLE_HEAP_I32()[daylight >> 2] = Number(winterOffset != summerOffset); + function extractZone(date) { + var match = date.toTimeString().match(/\(([A-Za-z ]+)\)$/); + return match ? match[1] : "GMT"; + } + var winterName = extractZone(winter); + var summerName = extractZone(summer); + var winterNamePtr = stringToNewUTF8(winterName); + var summerNamePtr = stringToNewUTF8(summerName); + if (summerOffset < winterOffset) { + GROWABLE_HEAP_U32()[tzname >> 2] = winterNamePtr; + GROWABLE_HEAP_U32()[tzname + 4 >> 2] = summerNamePtr; + } else { + GROWABLE_HEAP_U32()[tzname >> 2] = summerNamePtr; + GROWABLE_HEAP_U32()[tzname + 4 >> 2] = winterNamePtr; + } +} + +function _abort() { + abort("native code called abort()"); +} + +function _dlopen(handle) { + abort(dlopenMissingError); +} + +function runtimeKeepalivePush() { + runtimeKeepaliveCounter += 1; +} + +function _emscripten_set_main_loop_timing(mode, value) { + Browser.mainLoop.timingMode = mode; + Browser.mainLoop.timingValue = value; + if (!Browser.mainLoop.func) { + err("emscripten_set_main_loop_timing: Cannot set timing mode for main loop since a main loop does not exist! Call emscripten_set_main_loop first to set one up."); + return 1; + } + if (!Browser.mainLoop.running) { + runtimeKeepalivePush(); + Browser.mainLoop.running = true; + } + if (mode == 0) { + Browser.mainLoop.scheduler = function Browser_mainLoop_scheduler_setTimeout() { + var timeUntilNextTick = Math.max(0, Browser.mainLoop.tickStartTime + value - _emscripten_get_now()) | 0; + setTimeout(Browser.mainLoop.runner, timeUntilNextTick); + }; + Browser.mainLoop.method = "timeout"; + } else if (mode == 1) { + Browser.mainLoop.scheduler = function Browser_mainLoop_scheduler_rAF() { + Browser.requestAnimationFrame(Browser.mainLoop.runner); + }; + Browser.mainLoop.method = "rAF"; + } else if (mode == 2) { + if (typeof setImmediate == "undefined") { + var setImmediates = []; + var emscriptenMainLoopMessageId = "setimmediate"; + var Browser_setImmediate_messageHandler = event => { + if (event.data === emscriptenMainLoopMessageId || event.data.target === emscriptenMainLoopMessageId) { + event.stopPropagation(); + setImmediates.shift()(); + } + }; + addEventListener("message", Browser_setImmediate_messageHandler, true); + setImmediate = function Browser_emulated_setImmediate(func) { + setImmediates.push(func); + if (ENVIRONMENT_IS_WORKER) { + if (Module["setImmediates"] === undefined) Module["setImmediates"] = []; + Module["setImmediates"].push(func); + postMessage({ + target: emscriptenMainLoopMessageId + }); + } else postMessage(emscriptenMainLoopMessageId, "*"); + }; + } + Browser.mainLoop.scheduler = function Browser_mainLoop_scheduler_setImmediate() { + setImmediate(Browser.mainLoop.runner); + }; + Browser.mainLoop.method = "immediate"; + } + return 0; +} + +function runtimeKeepalivePop() { + assert(runtimeKeepaliveCounter > 0); + runtimeKeepaliveCounter -= 1; +} + +function setMainLoop(browserIterationFunc, fps, simulateInfiniteLoop, arg, noSetTiming) { + assert(!Browser.mainLoop.func, "emscripten_set_main_loop: there can only be one main loop function at once: call emscripten_cancel_main_loop to cancel the previous one before setting a new one with different parameters."); + Browser.mainLoop.func = browserIterationFunc; + Browser.mainLoop.arg = arg; + var thisMainLoopId = Browser.mainLoop.currentlyRunningMainloop; + function checkIsRunning() { + if (thisMainLoopId < Browser.mainLoop.currentlyRunningMainloop) { + runtimeKeepalivePop(); + maybeExit(); + return false; + } + return true; + } + Browser.mainLoop.running = false; + Browser.mainLoop.runner = function Browser_mainLoop_runner() { + if (ABORT) return; + if (Browser.mainLoop.queue.length > 0) { + var start = Date.now(); + var blocker = Browser.mainLoop.queue.shift(); + blocker.func(blocker.arg); + if (Browser.mainLoop.remainingBlockers) { + var remaining = Browser.mainLoop.remainingBlockers; + var next = remaining % 1 == 0 ? remaining - 1 : Math.floor(remaining); + if (blocker.counted) { + Browser.mainLoop.remainingBlockers = next; + } else { + next = next + .5; + Browser.mainLoop.remainingBlockers = (8 * remaining + next) / 9; + } + } + out('main loop blocker "' + blocker.name + '" took ' + (Date.now() - start) + " ms"); + Browser.mainLoop.updateStatus(); + if (!checkIsRunning()) return; + setTimeout(Browser.mainLoop.runner, 0); + return; + } + if (!checkIsRunning()) return; + Browser.mainLoop.currentFrameNumber = Browser.mainLoop.currentFrameNumber + 1 | 0; + if (Browser.mainLoop.timingMode == 1 && Browser.mainLoop.timingValue > 1 && Browser.mainLoop.currentFrameNumber % Browser.mainLoop.timingValue != 0) { + Browser.mainLoop.scheduler(); + return; + } else if (Browser.mainLoop.timingMode == 0) { + Browser.mainLoop.tickStartTime = _emscripten_get_now(); + } + if (Browser.mainLoop.method === "timeout" && Module.ctx) { + warnOnce("Looks like you are rendering without using requestAnimationFrame for the main loop. You should use 0 for the frame rate in emscripten_set_main_loop in order to use requestAnimationFrame, as that can greatly improve your frame rates!"); + Browser.mainLoop.method = ""; + } + Browser.mainLoop.runIter(browserIterationFunc); + checkStackCookie(); + if (!checkIsRunning()) return; + if (typeof SDL == "object" && SDL.audio && SDL.audio.queueNewAudioData) SDL.audio.queueNewAudioData(); + Browser.mainLoop.scheduler(); + }; + if (!noSetTiming) { + if (fps && fps > 0) { + _emscripten_set_main_loop_timing(0, 1e3 / fps); + } else { + _emscripten_set_main_loop_timing(1, 1); + } + Browser.mainLoop.scheduler(); + } + if (simulateInfiniteLoop) { + throw "unwind"; + } +} + +function safeSetTimeout(func, timeout) { + runtimeKeepalivePush(); + return setTimeout(() => { + runtimeKeepalivePop(); + callUserCallback(func); + }, timeout); +} + +var Browser = { + mainLoop: { + running: false, + scheduler: null, + method: "", + currentlyRunningMainloop: 0, + func: null, + arg: 0, + timingMode: 0, + timingValue: 0, + currentFrameNumber: 0, + queue: [], + pause: function() { + Browser.mainLoop.scheduler = null; + Browser.mainLoop.currentlyRunningMainloop++; + }, + resume: function() { + Browser.mainLoop.currentlyRunningMainloop++; + var timingMode = Browser.mainLoop.timingMode; + var timingValue = Browser.mainLoop.timingValue; + var func = Browser.mainLoop.func; + Browser.mainLoop.func = null; + setMainLoop(func, 0, false, Browser.mainLoop.arg, true); + _emscripten_set_main_loop_timing(timingMode, timingValue); + Browser.mainLoop.scheduler(); + }, + updateStatus: function() { + if (Module["setStatus"]) { + var message = Module["statusMessage"] || "Please wait..."; + var remaining = Browser.mainLoop.remainingBlockers; + var expected = Browser.mainLoop.expectedBlockers; + if (remaining) { + if (remaining < expected) { + Module["setStatus"](message + " (" + (expected - remaining) + "/" + expected + ")"); + } else { + Module["setStatus"](message); + } + } else { + Module["setStatus"](""); + } + } + }, + runIter: function(func) { + if (ABORT) return; + if (Module["preMainLoop"]) { + var preRet = Module["preMainLoop"](); + if (preRet === false) { + return; + } + } + callUserCallback(func); + if (Module["postMainLoop"]) Module["postMainLoop"](); + } + }, + isFullscreen: false, + pointerLock: false, + moduleContextCreatedCallbacks: [], + workers: [], + init: function() { + if (Browser.initted) return; + Browser.initted = true; + var imagePlugin = {}; + imagePlugin["canHandle"] = function imagePlugin_canHandle(name) { + return !Module.noImageDecoding && /\.(jpg|jpeg|png|bmp)$/i.test(name); + }; + imagePlugin["handle"] = function imagePlugin_handle(byteArray, name, onload, onerror) { + var b = new Blob([ byteArray ], { + type: Browser.getMimetype(name) + }); + if (b.size !== byteArray.length) { + b = new Blob([ new Uint8Array(byteArray).buffer ], { + type: Browser.getMimetype(name) + }); + } + var url = URL.createObjectURL(b); + assert(typeof url == "string", "createObjectURL must return a url as a string"); + var img = new Image(); + img.onload = () => { + assert(img.complete, "Image " + name + " could not be decoded"); + var canvas = document.createElement("canvas"); + canvas.width = img.width; + canvas.height = img.height; + var ctx = canvas.getContext("2d"); + ctx.drawImage(img, 0, 0); + preloadedImages[name] = canvas; + URL.revokeObjectURL(url); + if (onload) onload(byteArray); + }; + img.onerror = event => { + out("Image " + url + " could not be decoded"); + if (onerror) onerror(); + }; + img.src = url; + }; + preloadPlugins.push(imagePlugin); + var audioPlugin = {}; + audioPlugin["canHandle"] = function audioPlugin_canHandle(name) { + return !Module.noAudioDecoding && name.substr(-4) in { + ".ogg": 1, + ".wav": 1, + ".mp3": 1 + }; + }; + audioPlugin["handle"] = function audioPlugin_handle(byteArray, name, onload, onerror) { + var done = false; + function finish(audio) { + if (done) return; + done = true; + preloadedAudios[name] = audio; + if (onload) onload(byteArray); + } + function fail() { + if (done) return; + done = true; + preloadedAudios[name] = new Audio(); + if (onerror) onerror(); + } + var b = new Blob([ byteArray ], { + type: Browser.getMimetype(name) + }); + var url = URL.createObjectURL(b); + assert(typeof url == "string", "createObjectURL must return a url as a string"); + var audio = new Audio(); + audio.addEventListener("canplaythrough", () => finish(audio), false); + audio.onerror = function audio_onerror(event) { + if (done) return; + err("warning: browser could not fully decode audio " + name + ", trying slower base64 approach"); + function encode64(data) { + var BASE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + var PAD = "="; + var ret = ""; + var leftchar = 0; + var leftbits = 0; + for (var i = 0; i < data.length; i++) { + leftchar = leftchar << 8 | data[i]; + leftbits += 8; + while (leftbits >= 6) { + var curr = leftchar >> leftbits - 6 & 63; + leftbits -= 6; + ret += BASE[curr]; + } + } + if (leftbits == 2) { + ret += BASE[(leftchar & 3) << 4]; + ret += PAD + PAD; + } else if (leftbits == 4) { + ret += BASE[(leftchar & 15) << 2]; + ret += PAD; + } + return ret; + } + audio.src = "data:audio/x-" + name.substr(-3) + ";base64," + encode64(byteArray); + finish(audio); + }; + audio.src = url; + safeSetTimeout(() => { + finish(audio); + }, 1e4); + }; + preloadPlugins.push(audioPlugin); + function pointerLockChange() { + Browser.pointerLock = document["pointerLockElement"] === Module["canvas"] || document["mozPointerLockElement"] === Module["canvas"] || document["webkitPointerLockElement"] === Module["canvas"] || document["msPointerLockElement"] === Module["canvas"]; + } + var canvas = Module["canvas"]; + if (canvas) { + canvas.requestPointerLock = canvas["requestPointerLock"] || canvas["mozRequestPointerLock"] || canvas["webkitRequestPointerLock"] || canvas["msRequestPointerLock"] || (() => {}); + canvas.exitPointerLock = document["exitPointerLock"] || document["mozExitPointerLock"] || document["webkitExitPointerLock"] || document["msExitPointerLock"] || (() => {}); + canvas.exitPointerLock = canvas.exitPointerLock.bind(document); + document.addEventListener("pointerlockchange", pointerLockChange, false); + document.addEventListener("mozpointerlockchange", pointerLockChange, false); + document.addEventListener("webkitpointerlockchange", pointerLockChange, false); + document.addEventListener("mspointerlockchange", pointerLockChange, false); + if (Module["elementPointerLock"]) { + canvas.addEventListener("click", ev => { + if (!Browser.pointerLock && Module["canvas"].requestPointerLock) { + Module["canvas"].requestPointerLock(); + ev.preventDefault(); + } + }, false); + } + } + }, + createContext: function(canvas, useWebGL, setInModule, webGLContextAttributes) { + if (useWebGL && Module.ctx && canvas == Module.canvas) return Module.ctx; + var ctx; + var contextHandle; + if (useWebGL) { + var contextAttributes = { + antialias: false, + alpha: false, + majorVersion: typeof WebGL2RenderingContext != "undefined" ? 2 : 1 + }; + if (webGLContextAttributes) { + for (var attribute in webGLContextAttributes) { + contextAttributes[attribute] = webGLContextAttributes[attribute]; + } + } + if (typeof GL != "undefined") { + contextHandle = GL.createContext(canvas, contextAttributes); + if (contextHandle) { + ctx = GL.getContext(contextHandle).GLctx; + } + } + } else { + ctx = canvas.getContext("2d"); + } + if (!ctx) return null; + if (setInModule) { + if (!useWebGL) assert(typeof GLctx == "undefined", "cannot set in module if GLctx is used, but we are a non-GL context that would replace it"); + Module.ctx = ctx; + if (useWebGL) GL.makeContextCurrent(contextHandle); + Module.useWebGL = useWebGL; + Browser.moduleContextCreatedCallbacks.forEach(callback => callback()); + Browser.init(); + } + return ctx; + }, + destroyContext: function(canvas, useWebGL, setInModule) {}, + fullscreenHandlersInstalled: false, + lockPointer: undefined, + resizeCanvas: undefined, + requestFullscreen: function(lockPointer, resizeCanvas) { + Browser.lockPointer = lockPointer; + Browser.resizeCanvas = resizeCanvas; + if (typeof Browser.lockPointer == "undefined") Browser.lockPointer = true; + if (typeof Browser.resizeCanvas == "undefined") Browser.resizeCanvas = false; + var canvas = Module["canvas"]; + function fullscreenChange() { + Browser.isFullscreen = false; + var canvasContainer = canvas.parentNode; + if ((document["fullscreenElement"] || document["mozFullScreenElement"] || document["msFullscreenElement"] || document["webkitFullscreenElement"] || document["webkitCurrentFullScreenElement"]) === canvasContainer) { + canvas.exitFullscreen = Browser.exitFullscreen; + if (Browser.lockPointer) canvas.requestPointerLock(); + Browser.isFullscreen = true; + if (Browser.resizeCanvas) { + Browser.setFullscreenCanvasSize(); + } else { + Browser.updateCanvasDimensions(canvas); + } + } else { + canvasContainer.parentNode.insertBefore(canvas, canvasContainer); + canvasContainer.parentNode.removeChild(canvasContainer); + if (Browser.resizeCanvas) { + Browser.setWindowedCanvasSize(); + } else { + Browser.updateCanvasDimensions(canvas); + } + } + if (Module["onFullScreen"]) Module["onFullScreen"](Browser.isFullscreen); + if (Module["onFullscreen"]) Module["onFullscreen"](Browser.isFullscreen); + } + if (!Browser.fullscreenHandlersInstalled) { + Browser.fullscreenHandlersInstalled = true; + document.addEventListener("fullscreenchange", fullscreenChange, false); + document.addEventListener("mozfullscreenchange", fullscreenChange, false); + document.addEventListener("webkitfullscreenchange", fullscreenChange, false); + document.addEventListener("MSFullscreenChange", fullscreenChange, false); + } + var canvasContainer = document.createElement("div"); + canvas.parentNode.insertBefore(canvasContainer, canvas); + canvasContainer.appendChild(canvas); + canvasContainer.requestFullscreen = canvasContainer["requestFullscreen"] || canvasContainer["mozRequestFullScreen"] || canvasContainer["msRequestFullscreen"] || (canvasContainer["webkitRequestFullscreen"] ? () => canvasContainer["webkitRequestFullscreen"](Element["ALLOW_KEYBOARD_INPUT"]) : null) || (canvasContainer["webkitRequestFullScreen"] ? () => canvasContainer["webkitRequestFullScreen"](Element["ALLOW_KEYBOARD_INPUT"]) : null); + canvasContainer.requestFullscreen(); + }, + requestFullScreen: function() { + abort("Module.requestFullScreen has been replaced by Module.requestFullscreen (without a capital S)"); + }, + exitFullscreen: function() { + if (!Browser.isFullscreen) { + return false; + } + var CFS = document["exitFullscreen"] || document["cancelFullScreen"] || document["mozCancelFullScreen"] || document["msExitFullscreen"] || document["webkitCancelFullScreen"] || (() => {}); + CFS.apply(document, []); + return true; + }, + nextRAF: 0, + fakeRequestAnimationFrame: function(func) { + var now = Date.now(); + if (Browser.nextRAF === 0) { + Browser.nextRAF = now + 1e3 / 60; + } else { + while (now + 2 >= Browser.nextRAF) { + Browser.nextRAF += 1e3 / 60; + } + } + var delay = Math.max(Browser.nextRAF - now, 0); + setTimeout(func, delay); + }, + requestAnimationFrame: function(func) { + if (typeof requestAnimationFrame == "function") { + requestAnimationFrame(func); + return; + } + var RAF = Browser.fakeRequestAnimationFrame; + RAF(func); + }, + safeSetTimeout: function(func, timeout) { + return safeSetTimeout(func, timeout); + }, + safeRequestAnimationFrame: function(func) { + runtimeKeepalivePush(); + return Browser.requestAnimationFrame(() => { + runtimeKeepalivePop(); + callUserCallback(func); + }); + }, + getMimetype: function(name) { + return { + "jpg": "image/jpeg", + "jpeg": "image/jpeg", + "png": "image/png", + "bmp": "image/bmp", + "ogg": "audio/ogg", + "wav": "audio/wav", + "mp3": "audio/mpeg" + }[name.substr(name.lastIndexOf(".") + 1)]; + }, + getUserMedia: function(func) { + if (!window.getUserMedia) { + window.getUserMedia = navigator["getUserMedia"] || navigator["mozGetUserMedia"]; + } + window.getUserMedia(func); + }, + getMovementX: function(event) { + return event["movementX"] || event["mozMovementX"] || event["webkitMovementX"] || 0; + }, + getMovementY: function(event) { + return event["movementY"] || event["mozMovementY"] || event["webkitMovementY"] || 0; + }, + getMouseWheelDelta: function(event) { + var delta = 0; + switch (event.type) { + case "DOMMouseScroll": + delta = event.detail / 3; + break; + + case "mousewheel": + delta = event.wheelDelta / 120; + break; + + case "wheel": + delta = event.deltaY; + switch (event.deltaMode) { + case 0: + delta /= 100; + break; + + case 1: + delta /= 3; + break; + + case 2: + delta *= 80; + break; + + default: + throw "unrecognized mouse wheel delta mode: " + event.deltaMode; + } + break; + + default: + throw "unrecognized mouse wheel event: " + event.type; + } + return delta; + }, + mouseX: 0, + mouseY: 0, + mouseMovementX: 0, + mouseMovementY: 0, + touches: {}, + lastTouches: {}, + calculateMouseEvent: function(event) { + if (Browser.pointerLock) { + if (event.type != "mousemove" && "mozMovementX" in event) { + Browser.mouseMovementX = Browser.mouseMovementY = 0; + } else { + Browser.mouseMovementX = Browser.getMovementX(event); + Browser.mouseMovementY = Browser.getMovementY(event); + } + if (typeof SDL != "undefined") { + Browser.mouseX = SDL.mouseX + Browser.mouseMovementX; + Browser.mouseY = SDL.mouseY + Browser.mouseMovementY; + } else { + Browser.mouseX += Browser.mouseMovementX; + Browser.mouseY += Browser.mouseMovementY; + } + } else { + var rect = Module["canvas"].getBoundingClientRect(); + var cw = Module["canvas"].width; + var ch = Module["canvas"].height; + var scrollX = typeof window.scrollX != "undefined" ? window.scrollX : window.pageXOffset; + var scrollY = typeof window.scrollY != "undefined" ? window.scrollY : window.pageYOffset; + assert(typeof scrollX != "undefined" && typeof scrollY != "undefined", "Unable to retrieve scroll position, mouse positions likely broken."); + if (event.type === "touchstart" || event.type === "touchend" || event.type === "touchmove") { + var touch = event.touch; + if (touch === undefined) { + return; + } + var adjustedX = touch.pageX - (scrollX + rect.left); + var adjustedY = touch.pageY - (scrollY + rect.top); + adjustedX = adjustedX * (cw / rect.width); + adjustedY = adjustedY * (ch / rect.height); + var coords = { + x: adjustedX, + y: adjustedY + }; + if (event.type === "touchstart") { + Browser.lastTouches[touch.identifier] = coords; + Browser.touches[touch.identifier] = coords; + } else if (event.type === "touchend" || event.type === "touchmove") { + var last = Browser.touches[touch.identifier]; + if (!last) last = coords; + Browser.lastTouches[touch.identifier] = last; + Browser.touches[touch.identifier] = coords; + } + return; + } + var x = event.pageX - (scrollX + rect.left); + var y = event.pageY - (scrollY + rect.top); + x = x * (cw / rect.width); + y = y * (ch / rect.height); + Browser.mouseMovementX = x - Browser.mouseX; + Browser.mouseMovementY = y - Browser.mouseY; + Browser.mouseX = x; + Browser.mouseY = y; + } + }, + resizeListeners: [], + updateResizeListeners: function() { + var canvas = Module["canvas"]; + Browser.resizeListeners.forEach(listener => listener(canvas.width, canvas.height)); + }, + setCanvasSize: function(width, height, noUpdates) { + var canvas = Module["canvas"]; + Browser.updateCanvasDimensions(canvas, width, height); + if (!noUpdates) Browser.updateResizeListeners(); + }, + windowedWidth: 0, + windowedHeight: 0, + setFullscreenCanvasSize: function() { + if (typeof SDL != "undefined") { + var flags = GROWABLE_HEAP_U32()[SDL.screen >> 2]; + flags = flags | 8388608; + GROWABLE_HEAP_I32()[SDL.screen >> 2] = flags; + } + Browser.updateCanvasDimensions(Module["canvas"]); + Browser.updateResizeListeners(); + }, + setWindowedCanvasSize: function() { + if (typeof SDL != "undefined") { + var flags = GROWABLE_HEAP_U32()[SDL.screen >> 2]; + flags = flags & ~8388608; + GROWABLE_HEAP_I32()[SDL.screen >> 2] = flags; + } + Browser.updateCanvasDimensions(Module["canvas"]); + Browser.updateResizeListeners(); + }, + updateCanvasDimensions: function(canvas, wNative, hNative) { + if (wNative && hNative) { + canvas.widthNative = wNative; + canvas.heightNative = hNative; + } else { + wNative = canvas.widthNative; + hNative = canvas.heightNative; + } + var w = wNative; + var h = hNative; + if (Module["forcedAspectRatio"] && Module["forcedAspectRatio"] > 0) { + if (w / h < Module["forcedAspectRatio"]) { + w = Math.round(h * Module["forcedAspectRatio"]); + } else { + h = Math.round(w / Module["forcedAspectRatio"]); + } + } + if ((document["fullscreenElement"] || document["mozFullScreenElement"] || document["msFullscreenElement"] || document["webkitFullscreenElement"] || document["webkitCurrentFullScreenElement"]) === canvas.parentNode && typeof screen != "undefined") { + var factor = Math.min(screen.width / w, screen.height / h); + w = Math.round(w * factor); + h = Math.round(h * factor); + } + if (Browser.resizeCanvas) { + if (canvas.width != w) canvas.width = w; + if (canvas.height != h) canvas.height = h; + if (typeof canvas.style != "undefined") { + canvas.style.removeProperty("width"); + canvas.style.removeProperty("height"); + } + } else { + if (canvas.width != wNative) canvas.width = wNative; + if (canvas.height != hNative) canvas.height = hNative; + if (typeof canvas.style != "undefined") { + if (w != wNative || h != hNative) { + canvas.style.setProperty("width", w + "px", "important"); + canvas.style.setProperty("height", h + "px", "important"); + } else { + canvas.style.removeProperty("width"); + canvas.style.removeProperty("height"); + } + } + } + } +}; + +function _emscripten_cancel_main_loop() { + Browser.mainLoop.pause(); + Browser.mainLoop.func = null; +} + +function _emscripten_check_blocking_allowed() { + if (ENVIRONMENT_IS_WORKER) return; + warnOnce("Blocking on the main thread is very dangerous, see https://emscripten.org/docs/porting/pthreads.html#blocking-on-the-main-browser-thread"); +} + +function _emscripten_console_error(str) { + assert(typeof str == "number"); + console.error(UTF8ToString(str)); +} + +function _emscripten_date_now() { + return Date.now(); +} + +function _emscripten_exit_with_live_runtime() { + runtimeKeepalivePush(); + throw "unwind"; +} + +function _emscripten_force_exit(status) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(35, 1, status); + noExitRuntime = false; + runtimeKeepaliveCounter = 0; + _exit(status); +} + +function _glActiveTexture(x0) { + GLctx.activeTexture(x0); +} + +var _emscripten_glActiveTexture = _glActiveTexture; + +function _glAttachShader(program, shader) { + GLctx.attachShader(GL.programs[program], GL.shaders[shader]); +} + +var _emscripten_glAttachShader = _glAttachShader; + +function _glBeginTransformFeedback(x0) { + GLctx.beginTransformFeedback(x0); +} + +var _emscripten_glBeginTransformFeedback = _glBeginTransformFeedback; + +function _glBindBuffer(target, buffer) { + if (target == 35051) { + GLctx.currentPixelPackBufferBinding = buffer; + } else if (target == 35052) { + GLctx.currentPixelUnpackBufferBinding = buffer; + } + GLctx.bindBuffer(target, GL.buffers[buffer]); +} + +var _emscripten_glBindBuffer = _glBindBuffer; + +function _glBindBufferBase(target, index, buffer) { + GLctx.bindBufferBase(target, index, GL.buffers[buffer]); +} + +var _emscripten_glBindBufferBase = _glBindBufferBase; + +function _glBindBufferRange(target, index, buffer, offset, ptrsize) { + GLctx.bindBufferRange(target, index, GL.buffers[buffer], offset, ptrsize); +} + +var _emscripten_glBindBufferRange = _glBindBufferRange; + +function _glBindFramebuffer(target, framebuffer) { + GLctx.bindFramebuffer(target, framebuffer ? GL.framebuffers[framebuffer] : GL.currentContext.defaultFbo); +} + +var _emscripten_glBindFramebuffer = _glBindFramebuffer; + +function _glBindRenderbuffer(target, renderbuffer) { + GLctx.bindRenderbuffer(target, GL.renderbuffers[renderbuffer]); +} + +var _emscripten_glBindRenderbuffer = _glBindRenderbuffer; + +function _glBindTexture(target, texture) { + GLctx.bindTexture(target, GL.textures[texture]); +} + +var _emscripten_glBindTexture = _glBindTexture; + +function _glBindVertexArray(vao) { + GLctx.bindVertexArray(GL.vaos[vao]); +} + +var _emscripten_glBindVertexArray = _glBindVertexArray; + +function _glBlendColor(x0, x1, x2, x3) { + GLctx.blendColor(x0, x1, x2, x3); +} + +var _emscripten_glBlendColor = _glBlendColor; + +function _glBlendEquation(x0) { + GLctx.blendEquation(x0); +} + +var _emscripten_glBlendEquation = _glBlendEquation; + +function _glBlendFunc(x0, x1) { + GLctx.blendFunc(x0, x1); +} + +var _emscripten_glBlendFunc = _glBlendFunc; + +function _glBlendFuncSeparate(x0, x1, x2, x3) { + GLctx.blendFuncSeparate(x0, x1, x2, x3); +} + +var _emscripten_glBlendFuncSeparate = _glBlendFuncSeparate; + +function _glBlitFramebuffer(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9) { + GLctx.blitFramebuffer(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9); +} + +var _emscripten_glBlitFramebuffer = _glBlitFramebuffer; + +function _glBufferData(target, size, data, usage) { + if (GL.currentContext.version >= 2) { + if (data && size) { + GLctx.bufferData(target, GROWABLE_HEAP_U8(), usage, data, size); + } else { + GLctx.bufferData(target, size, usage); + } + } else { + GLctx.bufferData(target, data ? GROWABLE_HEAP_U8().subarray(data, data + size) : size, usage); + } +} + +var _emscripten_glBufferData = _glBufferData; + +function _glBufferSubData(target, offset, size, data) { + if (GL.currentContext.version >= 2) { + size && GLctx.bufferSubData(target, offset, GROWABLE_HEAP_U8(), data, size); + return; + } + GLctx.bufferSubData(target, offset, GROWABLE_HEAP_U8().subarray(data, data + size)); +} + +var _emscripten_glBufferSubData = _glBufferSubData; + +function _glCheckFramebufferStatus(x0) { + return GLctx.checkFramebufferStatus(x0); +} + +var _emscripten_glCheckFramebufferStatus = _glCheckFramebufferStatus; + +function _glClear(x0) { + GLctx.clear(x0); +} + +var _emscripten_glClear = _glClear; + +function _glClearBufferfv(buffer, drawbuffer, value) { + GLctx.clearBufferfv(buffer, drawbuffer, GROWABLE_HEAP_F32(), value >> 2); +} + +var _emscripten_glClearBufferfv = _glClearBufferfv; + +function _glClearColor(x0, x1, x2, x3) { + GLctx.clearColor(x0, x1, x2, x3); +} + +var _emscripten_glClearColor = _glClearColor; + +function _glClearDepthf(x0) { + GLctx.clearDepth(x0); +} + +var _emscripten_glClearDepthf = _glClearDepthf; + +function _glColorMask(red, green, blue, alpha) { + GLctx.colorMask(!!red, !!green, !!blue, !!alpha); +} + +var _emscripten_glColorMask = _glColorMask; + +function _glCompileShader(shader) { + GLctx.compileShader(GL.shaders[shader]); +} + +var _emscripten_glCompileShader = _glCompileShader; + +function _glCompressedTexImage2D(target, level, internalFormat, width, height, border, imageSize, data) { + if (GL.currentContext.version >= 2) { + if (GLctx.currentPixelUnpackBufferBinding || !imageSize) { + GLctx.compressedTexImage2D(target, level, internalFormat, width, height, border, imageSize, data); + } else { + GLctx.compressedTexImage2D(target, level, internalFormat, width, height, border, GROWABLE_HEAP_U8(), data, imageSize); + } + return; + } + GLctx.compressedTexImage2D(target, level, internalFormat, width, height, border, data ? GROWABLE_HEAP_U8().subarray(data, data + imageSize) : null); +} + +var _emscripten_glCompressedTexImage2D = _glCompressedTexImage2D; + +function _glCopyBufferSubData(x0, x1, x2, x3, x4) { + GLctx.copyBufferSubData(x0, x1, x2, x3, x4); +} + +var _emscripten_glCopyBufferSubData = _glCopyBufferSubData; + +function _glCreateProgram() { + var id = GL.getNewId(GL.programs); + var program = GLctx.createProgram(); + program.name = id; + program.maxUniformLength = program.maxAttributeLength = program.maxUniformBlockNameLength = 0; + program.uniformIdCounter = 1; + GL.programs[id] = program; + return id; +} + +var _emscripten_glCreateProgram = _glCreateProgram; + +function _glCreateShader(shaderType) { + var id = GL.getNewId(GL.shaders); + GL.shaders[id] = GLctx.createShader(shaderType); + return id; +} + +var _emscripten_glCreateShader = _glCreateShader; + +function _glCullFace(x0) { + GLctx.cullFace(x0); +} + +var _emscripten_glCullFace = _glCullFace; + +function _glDeleteBuffers(n, buffers) { + for (var i = 0; i < n; i++) { + var id = GROWABLE_HEAP_I32()[buffers + i * 4 >> 2]; + var buffer = GL.buffers[id]; + if (!buffer) continue; + GLctx.deleteBuffer(buffer); + buffer.name = 0; + GL.buffers[id] = null; + if (id == GLctx.currentPixelPackBufferBinding) GLctx.currentPixelPackBufferBinding = 0; + if (id == GLctx.currentPixelUnpackBufferBinding) GLctx.currentPixelUnpackBufferBinding = 0; + } +} + +var _emscripten_glDeleteBuffers = _glDeleteBuffers; + +function _glDeleteFramebuffers(n, framebuffers) { + for (var i = 0; i < n; ++i) { + var id = GROWABLE_HEAP_I32()[framebuffers + i * 4 >> 2]; + var framebuffer = GL.framebuffers[id]; + if (!framebuffer) continue; + GLctx.deleteFramebuffer(framebuffer); + framebuffer.name = 0; + GL.framebuffers[id] = null; + } +} + +var _emscripten_glDeleteFramebuffers = _glDeleteFramebuffers; + +function _glDeleteProgram(id) { + if (!id) return; + var program = GL.programs[id]; + if (!program) { + GL.recordError(1281); + return; + } + GLctx.deleteProgram(program); + program.name = 0; + GL.programs[id] = null; +} + +var _emscripten_glDeleteProgram = _glDeleteProgram; + +function _glDeleteQueries(n, ids) { + for (var i = 0; i < n; i++) { + var id = GROWABLE_HEAP_I32()[ids + i * 4 >> 2]; + var query = GL.queries[id]; + if (!query) continue; + GLctx.deleteQuery(query); + GL.queries[id] = null; + } +} + +var _emscripten_glDeleteQueries = _glDeleteQueries; + +function _glDeleteRenderbuffers(n, renderbuffers) { + for (var i = 0; i < n; i++) { + var id = GROWABLE_HEAP_I32()[renderbuffers + i * 4 >> 2]; + var renderbuffer = GL.renderbuffers[id]; + if (!renderbuffer) continue; + GLctx.deleteRenderbuffer(renderbuffer); + renderbuffer.name = 0; + GL.renderbuffers[id] = null; + } +} + +var _emscripten_glDeleteRenderbuffers = _glDeleteRenderbuffers; + +function _glDeleteShader(id) { + if (!id) return; + var shader = GL.shaders[id]; + if (!shader) { + GL.recordError(1281); + return; + } + GLctx.deleteShader(shader); + GL.shaders[id] = null; +} + +var _emscripten_glDeleteShader = _glDeleteShader; + +function _glDeleteSync(id) { + if (!id) return; + var sync = GL.syncs[id]; + if (!sync) { + GL.recordError(1281); + return; + } + GLctx.deleteSync(sync); + sync.name = 0; + GL.syncs[id] = null; +} + +var _emscripten_glDeleteSync = _glDeleteSync; + +function _glDeleteTextures(n, textures) { + for (var i = 0; i < n; i++) { + var id = GROWABLE_HEAP_I32()[textures + i * 4 >> 2]; + var texture = GL.textures[id]; + if (!texture) continue; + GLctx.deleteTexture(texture); + texture.name = 0; + GL.textures[id] = null; + } +} + +var _emscripten_glDeleteTextures = _glDeleteTextures; + +function _glDeleteVertexArrays(n, vaos) { + for (var i = 0; i < n; i++) { + var id = GROWABLE_HEAP_I32()[vaos + i * 4 >> 2]; + GLctx.deleteVertexArray(GL.vaos[id]); + GL.vaos[id] = null; + } +} + +var _emscripten_glDeleteVertexArrays = _glDeleteVertexArrays; + +function _glDepthFunc(x0) { + GLctx.depthFunc(x0); +} + +var _emscripten_glDepthFunc = _glDepthFunc; + +function _glDepthMask(flag) { + GLctx.depthMask(!!flag); +} + +var _emscripten_glDepthMask = _glDepthMask; + +function _glDisable(x0) { + GLctx.disable(x0); +} + +var _emscripten_glDisable = _glDisable; + +function _glDisableVertexAttribArray(index) { + GLctx.disableVertexAttribArray(index); +} + +var _emscripten_glDisableVertexAttribArray = _glDisableVertexAttribArray; + +function _glDrawArrays(mode, first, count) { + GLctx.drawArrays(mode, first, count); +} + +var _emscripten_glDrawArrays = _glDrawArrays; + +function _glDrawArraysInstanced(mode, first, count, primcount) { + GLctx.drawArraysInstanced(mode, first, count, primcount); +} + +var _emscripten_glDrawArraysInstanced = _glDrawArraysInstanced; + +function _glDrawElements(mode, count, type, indices) { + GLctx.drawElements(mode, count, type, indices); +} + +var _emscripten_glDrawElements = _glDrawElements; + +function _glDrawElementsInstanced(mode, count, type, indices, primcount) { + GLctx.drawElementsInstanced(mode, count, type, indices, primcount); +} + +var _emscripten_glDrawElementsInstanced = _glDrawElementsInstanced; + +function _glEnable(x0) { + GLctx.enable(x0); +} + +var _emscripten_glEnable = _glEnable; + +function _glEnableVertexAttribArray(index) { + GLctx.enableVertexAttribArray(index); +} + +var _emscripten_glEnableVertexAttribArray = _glEnableVertexAttribArray; + +function _glEndTransformFeedback() { + GLctx.endTransformFeedback(); +} + +var _emscripten_glEndTransformFeedback = _glEndTransformFeedback; + +function _glFenceSync(condition, flags) { + var sync = GLctx.fenceSync(condition, flags); + if (sync) { + var id = GL.getNewId(GL.syncs); + sync.name = id; + GL.syncs[id] = sync; + return id; + } + return 0; +} + +var _emscripten_glFenceSync = _glFenceSync; + +function _glFinish() { + GLctx.finish(); +} + +var _emscripten_glFinish = _glFinish; + +function _glFramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer) { + GLctx.framebufferRenderbuffer(target, attachment, renderbuffertarget, GL.renderbuffers[renderbuffer]); +} + +var _emscripten_glFramebufferRenderbuffer = _glFramebufferRenderbuffer; + +function _glFramebufferTexture2D(target, attachment, textarget, texture, level) { + GLctx.framebufferTexture2D(target, attachment, textarget, GL.textures[texture], level); +} + +var _emscripten_glFramebufferTexture2D = _glFramebufferTexture2D; + +function _glFramebufferTextureLayer(target, attachment, texture, level, layer) { + GLctx.framebufferTextureLayer(target, attachment, GL.textures[texture], level, layer); +} + +var _emscripten_glFramebufferTextureLayer = _glFramebufferTextureLayer; + +function _glFrontFace(x0) { + GLctx.frontFace(x0); +} + +var _emscripten_glFrontFace = _glFrontFace; + +function __glGenObject(n, buffers, createFunction, objectTable) { + for (var i = 0; i < n; i++) { + var buffer = GLctx[createFunction](); + var id = buffer && GL.getNewId(objectTable); + if (buffer) { + buffer.name = id; + objectTable[id] = buffer; + } else { + GL.recordError(1282); + } + GROWABLE_HEAP_I32()[buffers + i * 4 >> 2] = id; + } +} + +function _glGenBuffers(n, buffers) { + __glGenObject(n, buffers, "createBuffer", GL.buffers); +} + +var _emscripten_glGenBuffers = _glGenBuffers; + +function _glGenFramebuffers(n, ids) { + __glGenObject(n, ids, "createFramebuffer", GL.framebuffers); +} + +var _emscripten_glGenFramebuffers = _glGenFramebuffers; + +function _glGenQueries(n, ids) { + __glGenObject(n, ids, "createQuery", GL.queries); +} + +var _emscripten_glGenQueries = _glGenQueries; + +function _glGenRenderbuffers(n, renderbuffers) { + __glGenObject(n, renderbuffers, "createRenderbuffer", GL.renderbuffers); +} + +var _emscripten_glGenRenderbuffers = _glGenRenderbuffers; + +function _glGenTextures(n, textures) { + __glGenObject(n, textures, "createTexture", GL.textures); +} + +var _emscripten_glGenTextures = _glGenTextures; + +function _glGenVertexArrays(n, arrays) { + __glGenObject(n, arrays, "createVertexArray", GL.vaos); +} + +var _emscripten_glGenVertexArrays = _glGenVertexArrays; + +function _glGenerateMipmap(x0) { + GLctx.generateMipmap(x0); +} + +var _emscripten_glGenerateMipmap = _glGenerateMipmap; + +function readI53FromU64(ptr) { + return GROWABLE_HEAP_U32()[ptr >> 2] + GROWABLE_HEAP_U32()[ptr + 4 >> 2] * 4294967296; +} + +function writeI53ToI64(ptr, num) { + GROWABLE_HEAP_U32()[ptr >> 2] = num; + GROWABLE_HEAP_U32()[ptr + 4 >> 2] = (num - GROWABLE_HEAP_U32()[ptr >> 2]) / 4294967296; + var deserialized = num >= 0 ? readI53FromU64(ptr) : readI53FromI64(ptr); + if (deserialized != num) warnOnce("writeI53ToI64() out of range: serialized JS Number " + num + " to Wasm heap as bytes lo=" + ptrToString(GROWABLE_HEAP_U32()[ptr >> 2]) + ", hi=" + ptrToString(GROWABLE_HEAP_U32()[ptr + 4 >> 2]) + ", which deserializes back to " + deserialized + " instead!"); +} + +function emscriptenWebGLGet(name_, p, type) { + if (!p) { + GL.recordError(1281); + return; + } + var ret = undefined; + switch (name_) { + case 36346: + ret = 1; + break; + + case 36344: + if (type != 0 && type != 1) { + GL.recordError(1280); + } + return; + + case 34814: + case 36345: + ret = 0; + break; + + case 34466: + var formats = GLctx.getParameter(34467); + ret = formats ? formats.length : 0; + break; + + case 33309: + if (GL.currentContext.version < 2) { + GL.recordError(1282); + return; + } + var exts = GLctx.getSupportedExtensions() || []; + ret = 2 * exts.length; + break; + + case 33307: + case 33308: + if (GL.currentContext.version < 2) { + GL.recordError(1280); + return; + } + ret = name_ == 33307 ? 3 : 0; + break; + } + if (ret === undefined) { + var result = GLctx.getParameter(name_); + switch (typeof result) { + case "number": + ret = result; + break; + + case "boolean": + ret = result ? 1 : 0; + break; + + case "string": + GL.recordError(1280); + return; + + case "object": + if (result === null) { + switch (name_) { + case 34964: + case 35725: + case 34965: + case 36006: + case 36007: + case 32873: + case 34229: + case 36662: + case 36663: + case 35053: + case 35055: + case 36010: + case 35097: + case 35869: + case 32874: + case 36389: + case 35983: + case 35368: + case 34068: + { + ret = 0; + break; + } + + default: + { + GL.recordError(1280); + return; + } + } + } else if (result instanceof Float32Array || result instanceof Uint32Array || result instanceof Int32Array || result instanceof Array) { + for (var i = 0; i < result.length; ++i) { + switch (type) { + case 0: + GROWABLE_HEAP_I32()[p + i * 4 >> 2] = result[i]; + break; + + case 2: + GROWABLE_HEAP_F32()[p + i * 4 >> 2] = result[i]; + break; + + case 4: + GROWABLE_HEAP_I8()[p + i >> 0] = result[i] ? 1 : 0; + break; + } + } + return; + } else { + try { + ret = result.name | 0; + } catch (e) { + GL.recordError(1280); + err("GL_INVALID_ENUM in glGet" + type + "v: Unknown object returned from WebGL getParameter(" + name_ + ")! (error: " + e + ")"); + return; + } + } + break; + + default: + GL.recordError(1280); + err("GL_INVALID_ENUM in glGet" + type + "v: Native code calling glGet" + type + "v(" + name_ + ") and it returns " + result + " of type " + typeof result + "!"); + return; + } + } + switch (type) { + case 1: + writeI53ToI64(p, ret); + break; + + case 0: + GROWABLE_HEAP_I32()[p >> 2] = ret; + break; + + case 2: + GROWABLE_HEAP_F32()[p >> 2] = ret; + break; + + case 4: + GROWABLE_HEAP_I8()[p >> 0] = ret ? 1 : 0; + break; + } +} + +function _glGetFloatv(name_, p) { + emscriptenWebGLGet(name_, p, 2); +} + +var _emscripten_glGetFloatv = _glGetFloatv; + +function _glGetInteger64v(name_, p) { + emscriptenWebGLGet(name_, p, 1); +} + +var _emscripten_glGetInteger64v = _glGetInteger64v; + +function _glGetProgramInfoLog(program, maxLength, length, infoLog) { + var log = GLctx.getProgramInfoLog(GL.programs[program]); + if (log === null) log = "(unknown error)"; + var numBytesWrittenExclNull = maxLength > 0 && infoLog ? stringToUTF8(log, infoLog, maxLength) : 0; + if (length) GROWABLE_HEAP_I32()[length >> 2] = numBytesWrittenExclNull; +} + +var _emscripten_glGetProgramInfoLog = _glGetProgramInfoLog; + +function _glGetProgramiv(program, pname, p) { + if (!p) { + GL.recordError(1281); + return; + } + if (program >= GL.counter) { + GL.recordError(1281); + return; + } + program = GL.programs[program]; + if (pname == 35716) { + var log = GLctx.getProgramInfoLog(program); + if (log === null) log = "(unknown error)"; + GROWABLE_HEAP_I32()[p >> 2] = log.length + 1; + } else if (pname == 35719) { + if (!program.maxUniformLength) { + for (var i = 0; i < GLctx.getProgramParameter(program, 35718); ++i) { + program.maxUniformLength = Math.max(program.maxUniformLength, GLctx.getActiveUniform(program, i).name.length + 1); + } + } + GROWABLE_HEAP_I32()[p >> 2] = program.maxUniformLength; + } else if (pname == 35722) { + if (!program.maxAttributeLength) { + for (var i = 0; i < GLctx.getProgramParameter(program, 35721); ++i) { + program.maxAttributeLength = Math.max(program.maxAttributeLength, GLctx.getActiveAttrib(program, i).name.length + 1); + } + } + GROWABLE_HEAP_I32()[p >> 2] = program.maxAttributeLength; + } else if (pname == 35381) { + if (!program.maxUniformBlockNameLength) { + for (var i = 0; i < GLctx.getProgramParameter(program, 35382); ++i) { + program.maxUniformBlockNameLength = Math.max(program.maxUniformBlockNameLength, GLctx.getActiveUniformBlockName(program, i).length + 1); + } + } + GROWABLE_HEAP_I32()[p >> 2] = program.maxUniformBlockNameLength; + } else { + GROWABLE_HEAP_I32()[p >> 2] = GLctx.getProgramParameter(program, pname); + } +} + +var _emscripten_glGetProgramiv = _glGetProgramiv; + +function _glGetShaderInfoLog(shader, maxLength, length, infoLog) { + var log = GLctx.getShaderInfoLog(GL.shaders[shader]); + if (log === null) log = "(unknown error)"; + var numBytesWrittenExclNull = maxLength > 0 && infoLog ? stringToUTF8(log, infoLog, maxLength) : 0; + if (length) GROWABLE_HEAP_I32()[length >> 2] = numBytesWrittenExclNull; +} + +var _emscripten_glGetShaderInfoLog = _glGetShaderInfoLog; + +function _glGetShaderiv(shader, pname, p) { + if (!p) { + GL.recordError(1281); + return; + } + if (pname == 35716) { + var log = GLctx.getShaderInfoLog(GL.shaders[shader]); + if (log === null) log = "(unknown error)"; + var logLength = log ? log.length + 1 : 0; + GROWABLE_HEAP_I32()[p >> 2] = logLength; + } else if (pname == 35720) { + var source = GLctx.getShaderSource(GL.shaders[shader]); + var sourceLength = source ? source.length + 1 : 0; + GROWABLE_HEAP_I32()[p >> 2] = sourceLength; + } else { + GROWABLE_HEAP_I32()[p >> 2] = GLctx.getShaderParameter(GL.shaders[shader], pname); + } +} + +var _emscripten_glGetShaderiv = _glGetShaderiv; + +function _glGetString(name_) { + var ret = GL.stringCache[name_]; + if (!ret) { + switch (name_) { + case 7939: + var exts = GLctx.getSupportedExtensions() || []; + exts = exts.concat(exts.map(function(e) { + return "GL_" + e; + })); + ret = stringToNewUTF8(exts.join(" ")); + break; + + case 7936: + case 7937: + case 37445: + case 37446: + var s = GLctx.getParameter(name_); + if (!s) { + GL.recordError(1280); + } + ret = s && stringToNewUTF8(s); + break; + + case 7938: + var glVersion = GLctx.getParameter(7938); + if (GL.currentContext.version >= 2) glVersion = "OpenGL ES 3.0 (" + glVersion + ")"; else { + glVersion = "OpenGL ES 2.0 (" + glVersion + ")"; + } + ret = stringToNewUTF8(glVersion); + break; + + case 35724: + var glslVersion = GLctx.getParameter(35724); + var ver_re = /^WebGL GLSL ES ([0-9]\.[0-9][0-9]?)(?:$| .*)/; + var ver_num = glslVersion.match(ver_re); + if (ver_num !== null) { + if (ver_num[1].length == 3) ver_num[1] = ver_num[1] + "0"; + glslVersion = "OpenGL ES GLSL ES " + ver_num[1] + " (" + glslVersion + ")"; + } + ret = stringToNewUTF8(glslVersion); + break; + + default: + GL.recordError(1280); + } + GL.stringCache[name_] = ret; + } + return ret; +} + +var _emscripten_glGetString = _glGetString; + +function _glGetStringi(name, index) { + if (GL.currentContext.version < 2) { + GL.recordError(1282); + return 0; + } + var stringiCache = GL.stringiCache[name]; + if (stringiCache) { + if (index < 0 || index >= stringiCache.length) { + GL.recordError(1281); + return 0; + } + return stringiCache[index]; + } + switch (name) { + case 7939: + var exts = GLctx.getSupportedExtensions() || []; + exts = exts.concat(exts.map(function(e) { + return "GL_" + e; + })); + exts = exts.map(function(e) { + return stringToNewUTF8(e); + }); + stringiCache = GL.stringiCache[name] = exts; + if (index < 0 || index >= stringiCache.length) { + GL.recordError(1281); + return 0; + } + return stringiCache[index]; + + default: + GL.recordError(1280); + return 0; + } +} + +var _emscripten_glGetStringi = _glGetStringi; + +function _glGetSynciv(sync, pname, bufSize, length, values) { + if (bufSize < 0) { + GL.recordError(1281); + return; + } + if (!values) { + GL.recordError(1281); + return; + } + var ret = GLctx.getSyncParameter(GL.syncs[sync], pname); + if (ret !== null) { + GROWABLE_HEAP_I32()[values >> 2] = ret; + if (length) GROWABLE_HEAP_I32()[length >> 2] = 1; + } +} + +var _emscripten_glGetSynciv = _glGetSynciv; + +function _glGetUniformBlockIndex(program, uniformBlockName) { + return GLctx.getUniformBlockIndex(GL.programs[program], UTF8ToString(uniformBlockName)); +} + +var _emscripten_glGetUniformBlockIndex = _glGetUniformBlockIndex; + +function webglGetLeftBracePos(name) { + return name.slice(-1) == "]" && name.lastIndexOf("["); +} + +function webglPrepareUniformLocationsBeforeFirstUse(program) { + var uniformLocsById = program.uniformLocsById, uniformSizeAndIdsByName = program.uniformSizeAndIdsByName, i, j; + if (!uniformLocsById) { + program.uniformLocsById = uniformLocsById = {}; + program.uniformArrayNamesById = {}; + for (i = 0; i < GLctx.getProgramParameter(program, 35718); ++i) { + var u = GLctx.getActiveUniform(program, i); + var nm = u.name; + var sz = u.size; + var lb = webglGetLeftBracePos(nm); + var arrayName = lb > 0 ? nm.slice(0, lb) : nm; + var id = program.uniformIdCounter; + program.uniformIdCounter += sz; + uniformSizeAndIdsByName[arrayName] = [ sz, id ]; + for (j = 0; j < sz; ++j) { + uniformLocsById[id] = j; + program.uniformArrayNamesById[id++] = arrayName; + } + } + } +} + +function _glGetUniformLocation(program, name) { + name = UTF8ToString(name); + if (program = GL.programs[program]) { + webglPrepareUniformLocationsBeforeFirstUse(program); + var uniformLocsById = program.uniformLocsById; + var arrayIndex = 0; + var uniformBaseName = name; + var leftBrace = webglGetLeftBracePos(name); + if (leftBrace > 0) { + arrayIndex = jstoi_q(name.slice(leftBrace + 1)) >>> 0; + uniformBaseName = name.slice(0, leftBrace); + } + var sizeAndId = program.uniformSizeAndIdsByName[uniformBaseName]; + if (sizeAndId && arrayIndex < sizeAndId[0]) { + arrayIndex += sizeAndId[1]; + if (uniformLocsById[arrayIndex] = uniformLocsById[arrayIndex] || GLctx.getUniformLocation(program, name)) { + return arrayIndex; + } + } + } else { + GL.recordError(1281); + } + return -1; +} + +var _emscripten_glGetUniformLocation = _glGetUniformLocation; + +function _glLinkProgram(program) { + program = GL.programs[program]; + GLctx.linkProgram(program); + program.uniformLocsById = 0; + program.uniformSizeAndIdsByName = {}; +} + +var _emscripten_glLinkProgram = _glLinkProgram; + +function _glPixelStorei(pname, param) { + if (pname == 3317) { + GL.unpackAlignment = param; + } + GLctx.pixelStorei(pname, param); +} + +var _emscripten_glPixelStorei = _glPixelStorei; + +function _glReadBuffer(x0) { + GLctx.readBuffer(x0); +} + +var _emscripten_glReadBuffer = _glReadBuffer; + +function computeUnpackAlignedImageSize(width, height, sizePerPixel, alignment) { + function roundedToNextMultipleOf(x, y) { + return x + y - 1 & -y; + } + var plainRowSize = width * sizePerPixel; + var alignedRowSize = roundedToNextMultipleOf(plainRowSize, alignment); + return height * alignedRowSize; +} + +function colorChannelsInGlTextureFormat(format) { + var colorChannels = { + 5: 3, + 6: 4, + 8: 2, + 29502: 3, + 29504: 4, + 26917: 2, + 26918: 2, + 29846: 3, + 29847: 4 + }; + return colorChannels[format - 6402] || 1; +} + +function heapObjectForWebGLType(type) { + type -= 5120; + if (type == 0) return GROWABLE_HEAP_I8(); + if (type == 1) return GROWABLE_HEAP_U8(); + if (type == 2) return GROWABLE_HEAP_I16(); + if (type == 4) return GROWABLE_HEAP_I32(); + if (type == 6) return GROWABLE_HEAP_F32(); + if (type == 5 || type == 28922 || type == 28520 || type == 30779 || type == 30782) return GROWABLE_HEAP_U32(); + return GROWABLE_HEAP_U16(); +} + +function heapAccessShiftForWebGLHeap(heap) { + return 31 - Math.clz32(heap.BYTES_PER_ELEMENT); +} + +function emscriptenWebGLGetTexPixelData(type, format, width, height, pixels, internalFormat) { + var heap = heapObjectForWebGLType(type); + var shift = heapAccessShiftForWebGLHeap(heap); + var byteSize = 1 << shift; + var sizePerPixel = colorChannelsInGlTextureFormat(format) * byteSize; + var bytes = computeUnpackAlignedImageSize(width, height, sizePerPixel, GL.unpackAlignment); + return heap.subarray(pixels >> shift, pixels + bytes >> shift); +} + +function _glReadPixels(x, y, width, height, format, type, pixels) { + if (GL.currentContext.version >= 2) { + if (GLctx.currentPixelPackBufferBinding) { + GLctx.readPixels(x, y, width, height, format, type, pixels); + } else { + var heap = heapObjectForWebGLType(type); + GLctx.readPixels(x, y, width, height, format, type, heap, pixels >> heapAccessShiftForWebGLHeap(heap)); + } + return; + } + var pixelData = emscriptenWebGLGetTexPixelData(type, format, width, height, pixels, format); + if (!pixelData) { + GL.recordError(1280); + return; + } + GLctx.readPixels(x, y, width, height, format, type, pixelData); +} + +var _emscripten_glReadPixels = _glReadPixels; + +function _glRenderbufferStorage(x0, x1, x2, x3) { + GLctx.renderbufferStorage(x0, x1, x2, x3); +} + +var _emscripten_glRenderbufferStorage = _glRenderbufferStorage; + +function _glScissor(x0, x1, x2, x3) { + GLctx.scissor(x0, x1, x2, x3); +} + +var _emscripten_glScissor = _glScissor; + +function _glShaderSource(shader, count, string, length) { + var source = GL.getSource(shader, count, string, length); + GLctx.shaderSource(GL.shaders[shader], source); +} + +var _emscripten_glShaderSource = _glShaderSource; + +function _glTexImage2D(target, level, internalFormat, width, height, border, format, type, pixels) { + if (GL.currentContext.version >= 2) { + if (GLctx.currentPixelUnpackBufferBinding) { + GLctx.texImage2D(target, level, internalFormat, width, height, border, format, type, pixels); + } else if (pixels) { + var heap = heapObjectForWebGLType(type); + GLctx.texImage2D(target, level, internalFormat, width, height, border, format, type, heap, pixels >> heapAccessShiftForWebGLHeap(heap)); + } else { + GLctx.texImage2D(target, level, internalFormat, width, height, border, format, type, null); + } + return; + } + GLctx.texImage2D(target, level, internalFormat, width, height, border, format, type, pixels ? emscriptenWebGLGetTexPixelData(type, format, width, height, pixels, internalFormat) : null); +} + +var _emscripten_glTexImage2D = _glTexImage2D; + +function _glTexImage3D(target, level, internalFormat, width, height, depth, border, format, type, pixels) { + if (GLctx.currentPixelUnpackBufferBinding) { + GLctx.texImage3D(target, level, internalFormat, width, height, depth, border, format, type, pixels); + } else if (pixels) { + var heap = heapObjectForWebGLType(type); + GLctx.texImage3D(target, level, internalFormat, width, height, depth, border, format, type, heap, pixels >> heapAccessShiftForWebGLHeap(heap)); + } else { + GLctx.texImage3D(target, level, internalFormat, width, height, depth, border, format, type, null); + } +} + +var _emscripten_glTexImage3D = _glTexImage3D; + +function _glTexParameterf(x0, x1, x2) { + GLctx.texParameterf(x0, x1, x2); +} + +var _emscripten_glTexParameterf = _glTexParameterf; + +function _glTexParameteri(x0, x1, x2) { + GLctx.texParameteri(x0, x1, x2); +} + +var _emscripten_glTexParameteri = _glTexParameteri; + +function _glTexStorage2D(x0, x1, x2, x3, x4) { + GLctx.texStorage2D(x0, x1, x2, x3, x4); +} + +var _emscripten_glTexStorage2D = _glTexStorage2D; + +function _glTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels) { + if (GLctx.currentPixelUnpackBufferBinding) { + GLctx.texSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels); + } else if (pixels) { + var heap = heapObjectForWebGLType(type); + GLctx.texSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, heap, pixels >> heapAccessShiftForWebGLHeap(heap)); + } else { + GLctx.texSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, null); + } +} + +var _emscripten_glTexSubImage3D = _glTexSubImage3D; + +function _glTransformFeedbackVaryings(program, count, varyings, bufferMode) { + program = GL.programs[program]; + var vars = []; + for (var i = 0; i < count; i++) vars.push(UTF8ToString(GROWABLE_HEAP_I32()[varyings + i * 4 >> 2])); + GLctx.transformFeedbackVaryings(program, vars, bufferMode); +} + +var _emscripten_glTransformFeedbackVaryings = _glTransformFeedbackVaryings; + +function webglGetUniformLocation(location) { + var p = GLctx.currentProgram; + if (p) { + var webglLoc = p.uniformLocsById[location]; + if (typeof webglLoc == "number") { + p.uniformLocsById[location] = webglLoc = GLctx.getUniformLocation(p, p.uniformArrayNamesById[location] + (webglLoc > 0 ? "[" + webglLoc + "]" : "")); + } + return webglLoc; + } else { + GL.recordError(1282); + } +} + +function _glUniform1f(location, v0) { + GLctx.uniform1f(webglGetUniformLocation(location), v0); +} + +var _emscripten_glUniform1f = _glUniform1f; + +function _glUniform1i(location, v0) { + GLctx.uniform1i(webglGetUniformLocation(location), v0); +} + +var _emscripten_glUniform1i = _glUniform1i; + +var miniTempWebGLIntBuffers = []; + +function _glUniform1iv(location, count, value) { + if (GL.currentContext.version >= 2) { + count && GLctx.uniform1iv(webglGetUniformLocation(location), GROWABLE_HEAP_I32(), value >> 2, count); + return; + } + if (count <= 288) { + var view = miniTempWebGLIntBuffers[count - 1]; + for (var i = 0; i < count; ++i) { + view[i] = GROWABLE_HEAP_I32()[value + 4 * i >> 2]; + } + } else { + var view = GROWABLE_HEAP_I32().subarray(value >> 2, value + count * 4 >> 2); + } + GLctx.uniform1iv(webglGetUniformLocation(location), view); +} + +var _emscripten_glUniform1iv = _glUniform1iv; + +function _glUniform1ui(location, v0) { + GLctx.uniform1ui(webglGetUniformLocation(location), v0); +} + +var _emscripten_glUniform1ui = _glUniform1ui; + +function _glUniform1uiv(location, count, value) { + count && GLctx.uniform1uiv(webglGetUniformLocation(location), GROWABLE_HEAP_U32(), value >> 2, count); +} + +var _emscripten_glUniform1uiv = _glUniform1uiv; + +function _glUniform2f(location, v0, v1) { + GLctx.uniform2f(webglGetUniformLocation(location), v0, v1); +} + +var _emscripten_glUniform2f = _glUniform2f; + +var miniTempWebGLFloatBuffers = []; + +function _glUniform2fv(location, count, value) { + if (GL.currentContext.version >= 2) { + count && GLctx.uniform2fv(webglGetUniformLocation(location), GROWABLE_HEAP_F32(), value >> 2, count * 2); + return; + } + if (count <= 144) { + var view = miniTempWebGLFloatBuffers[2 * count - 1]; + for (var i = 0; i < 2 * count; i += 2) { + view[i] = GROWABLE_HEAP_F32()[value + 4 * i >> 2]; + view[i + 1] = GROWABLE_HEAP_F32()[value + (4 * i + 4) >> 2]; + } + } else { + var view = GROWABLE_HEAP_F32().subarray(value >> 2, value + count * 8 >> 2); + } + GLctx.uniform2fv(webglGetUniformLocation(location), view); +} + +var _emscripten_glUniform2fv = _glUniform2fv; + +function _glUniform2iv(location, count, value) { + if (GL.currentContext.version >= 2) { + count && GLctx.uniform2iv(webglGetUniformLocation(location), GROWABLE_HEAP_I32(), value >> 2, count * 2); + return; + } + if (count <= 144) { + var view = miniTempWebGLIntBuffers[2 * count - 1]; + for (var i = 0; i < 2 * count; i += 2) { + view[i] = GROWABLE_HEAP_I32()[value + 4 * i >> 2]; + view[i + 1] = GROWABLE_HEAP_I32()[value + (4 * i + 4) >> 2]; + } + } else { + var view = GROWABLE_HEAP_I32().subarray(value >> 2, value + count * 8 >> 2); + } + GLctx.uniform2iv(webglGetUniformLocation(location), view); +} + +var _emscripten_glUniform2iv = _glUniform2iv; + +function _glUniform3fv(location, count, value) { + if (GL.currentContext.version >= 2) { + count && GLctx.uniform3fv(webglGetUniformLocation(location), GROWABLE_HEAP_F32(), value >> 2, count * 3); + return; + } + if (count <= 96) { + var view = miniTempWebGLFloatBuffers[3 * count - 1]; + for (var i = 0; i < 3 * count; i += 3) { + view[i] = GROWABLE_HEAP_F32()[value + 4 * i >> 2]; + view[i + 1] = GROWABLE_HEAP_F32()[value + (4 * i + 4) >> 2]; + view[i + 2] = GROWABLE_HEAP_F32()[value + (4 * i + 8) >> 2]; + } + } else { + var view = GROWABLE_HEAP_F32().subarray(value >> 2, value + count * 12 >> 2); + } + GLctx.uniform3fv(webglGetUniformLocation(location), view); +} + +var _emscripten_glUniform3fv = _glUniform3fv; + +function _glUniform4f(location, v0, v1, v2, v3) { + GLctx.uniform4f(webglGetUniformLocation(location), v0, v1, v2, v3); +} + +var _emscripten_glUniform4f = _glUniform4f; + +function _glUniform4fv(location, count, value) { + if (GL.currentContext.version >= 2) { + count && GLctx.uniform4fv(webglGetUniformLocation(location), GROWABLE_HEAP_F32(), value >> 2, count * 4); + return; + } + if (count <= 72) { + var view = miniTempWebGLFloatBuffers[4 * count - 1]; + var heap = GROWABLE_HEAP_F32(); + value >>= 2; + for (var i = 0; i < 4 * count; i += 4) { + var dst = value + i; + view[i] = heap[dst]; + view[i + 1] = heap[dst + 1]; + view[i + 2] = heap[dst + 2]; + view[i + 3] = heap[dst + 3]; + } + } else { + var view = GROWABLE_HEAP_F32().subarray(value >> 2, value + count * 16 >> 2); + } + GLctx.uniform4fv(webglGetUniformLocation(location), view); +} + +var _emscripten_glUniform4fv = _glUniform4fv; + +function _glUniformBlockBinding(program, uniformBlockIndex, uniformBlockBinding) { + program = GL.programs[program]; + GLctx.uniformBlockBinding(program, uniformBlockIndex, uniformBlockBinding); +} + +var _emscripten_glUniformBlockBinding = _glUniformBlockBinding; + +function _glUniformMatrix4fv(location, count, transpose, value) { + if (GL.currentContext.version >= 2) { + count && GLctx.uniformMatrix4fv(webglGetUniformLocation(location), !!transpose, GROWABLE_HEAP_F32(), value >> 2, count * 16); + return; + } + if (count <= 18) { + var view = miniTempWebGLFloatBuffers[16 * count - 1]; + var heap = GROWABLE_HEAP_F32(); + value >>= 2; + for (var i = 0; i < 16 * count; i += 16) { + var dst = value + i; + view[i] = heap[dst]; + view[i + 1] = heap[dst + 1]; + view[i + 2] = heap[dst + 2]; + view[i + 3] = heap[dst + 3]; + view[i + 4] = heap[dst + 4]; + view[i + 5] = heap[dst + 5]; + view[i + 6] = heap[dst + 6]; + view[i + 7] = heap[dst + 7]; + view[i + 8] = heap[dst + 8]; + view[i + 9] = heap[dst + 9]; + view[i + 10] = heap[dst + 10]; + view[i + 11] = heap[dst + 11]; + view[i + 12] = heap[dst + 12]; + view[i + 13] = heap[dst + 13]; + view[i + 14] = heap[dst + 14]; + view[i + 15] = heap[dst + 15]; + } + } else { + var view = GROWABLE_HEAP_F32().subarray(value >> 2, value + count * 64 >> 2); + } + GLctx.uniformMatrix4fv(webglGetUniformLocation(location), !!transpose, view); +} + +var _emscripten_glUniformMatrix4fv = _glUniformMatrix4fv; + +function _glUseProgram(program) { + program = GL.programs[program]; + GLctx.useProgram(program); + GLctx.currentProgram = program; +} + +var _emscripten_glUseProgram = _glUseProgram; + +function _glVertexAttrib4f(x0, x1, x2, x3, x4) { + GLctx.vertexAttrib4f(x0, x1, x2, x3, x4); +} + +var _emscripten_glVertexAttrib4f = _glVertexAttrib4f; + +function _glVertexAttribDivisor(index, divisor) { + GLctx.vertexAttribDivisor(index, divisor); +} + +var _emscripten_glVertexAttribDivisor = _glVertexAttribDivisor; + +function _glVertexAttribI4ui(x0, x1, x2, x3, x4) { + GLctx.vertexAttribI4ui(x0, x1, x2, x3, x4); +} + +var _emscripten_glVertexAttribI4ui = _glVertexAttribI4ui; + +function _glVertexAttribIPointer(index, size, type, stride, ptr) { + GLctx.vertexAttribIPointer(index, size, type, stride, ptr); +} + +var _emscripten_glVertexAttribIPointer = _glVertexAttribIPointer; + +function _glVertexAttribPointer(index, size, type, normalized, stride, ptr) { + GLctx.vertexAttribPointer(index, size, type, !!normalized, stride, ptr); +} + +var _emscripten_glVertexAttribPointer = _glVertexAttribPointer; + +function _glViewport(x0, x1, x2, x3) { + GLctx.viewport(x0, x1, x2, x3); +} + +var _emscripten_glViewport = _glViewport; + +function _emscripten_num_logical_cores() { + return navigator["hardwareConcurrency"]; +} + +function withStackSave(f) { + var stack = stackSave(); + var ret = f(); + stackRestore(stack); + return ret; +} + +function proxyToMainThread(index, sync) { + var numCallArgs = arguments.length - 2; + var outerArgs = arguments; + var maxArgs = 19; + if (numCallArgs > maxArgs) { + throw "proxyToMainThread: Too many arguments " + numCallArgs + " to proxied function idx=" + index + ", maximum supported is " + maxArgs; + } + return withStackSave(() => { + var serializedNumCallArgs = numCallArgs; + var args = stackAlloc(serializedNumCallArgs * 8); + var b = args >> 3; + for (var i = 0; i < numCallArgs; i++) { + var arg = outerArgs[2 + i]; + GROWABLE_HEAP_F64()[b + i] = arg; + } + return __emscripten_run_in_main_runtime_thread_js(index, serializedNumCallArgs, args, sync); + }); +} + +var emscripten_receive_on_main_thread_js_callArgs = []; + +function _emscripten_receive_on_main_thread_js(index, numCallArgs, args) { + emscripten_receive_on_main_thread_js_callArgs.length = numCallArgs; + var b = args >> 3; + for (var i = 0; i < numCallArgs; i++) { + emscripten_receive_on_main_thread_js_callArgs[i] = GROWABLE_HEAP_F64()[b + i]; + } + var func = proxiedFunctionTable[index]; + assert(func.length == numCallArgs, "Call args mismatch in emscripten_receive_on_main_thread_js"); + return func.apply(null, emscripten_receive_on_main_thread_js_callArgs); +} + +function getHeapMax() { + return 2147483648; +} + +function emscripten_realloc_buffer(size) { + var b = wasmMemory.buffer; + try { + wasmMemory.grow(size - b.byteLength + 65535 >>> 16); + updateMemoryViews(); + return 1; + } catch (e) { + err(`emscripten_realloc_buffer: Attempted to grow heap from ${b.byteLength} bytes to ${size} bytes, but got error: ${e}`); + } +} + +function _emscripten_resize_heap(requestedSize) { + var oldSize = GROWABLE_HEAP_U8().length; + requestedSize = requestedSize >>> 0; + if (requestedSize <= oldSize) { + return false; + } + var maxHeapSize = getHeapMax(); + if (requestedSize > maxHeapSize) { + err(`Cannot enlarge memory, asked to go up to ${requestedSize} bytes, but the limit is ${maxHeapSize} bytes!`); + return false; + } + var alignUp = (x, multiple) => x + (multiple - x % multiple) % multiple; + for (var cutDown = 1; cutDown <= 4; cutDown *= 2) { + var overGrownHeapSize = oldSize * (1 + .2 / cutDown); + overGrownHeapSize = Math.min(overGrownHeapSize, requestedSize + 100663296); + var newSize = Math.min(maxHeapSize, alignUp(Math.max(requestedSize, overGrownHeapSize), 65536)); + var replacement = emscripten_realloc_buffer(newSize); + if (replacement) { + return true; + } + } + err(`Failed to grow the heap from ${oldSize} bytes to ${newSize} bytes, not enough memory!`); + return false; +} + +var JSEvents = { + inEventHandler: 0, + removeAllEventListeners: function() { + for (var i = JSEvents.eventHandlers.length - 1; i >= 0; --i) { + JSEvents._removeHandler(i); + } + JSEvents.eventHandlers = []; + JSEvents.deferredCalls = []; + }, + registerRemoveEventListeners: function() { + if (!JSEvents.removeEventListenersRegistered) { + __ATEXIT__.push(JSEvents.removeAllEventListeners); + JSEvents.removeEventListenersRegistered = true; + } + }, + deferredCalls: [], + deferCall: function(targetFunction, precedence, argsList) { + function arraysHaveEqualContent(arrA, arrB) { + if (arrA.length != arrB.length) return false; + for (var i in arrA) { + if (arrA[i] != arrB[i]) return false; + } + return true; + } + for (var i in JSEvents.deferredCalls) { + var call = JSEvents.deferredCalls[i]; + if (call.targetFunction == targetFunction && arraysHaveEqualContent(call.argsList, argsList)) { + return; + } + } + JSEvents.deferredCalls.push({ + targetFunction: targetFunction, + precedence: precedence, + argsList: argsList + }); + JSEvents.deferredCalls.sort(function(x, y) { + return x.precedence < y.precedence; + }); + }, + removeDeferredCalls: function(targetFunction) { + for (var i = 0; i < JSEvents.deferredCalls.length; ++i) { + if (JSEvents.deferredCalls[i].targetFunction == targetFunction) { + JSEvents.deferredCalls.splice(i, 1); + --i; + } + } + }, + canPerformEventHandlerRequests: function() { + return JSEvents.inEventHandler && JSEvents.currentEventHandler.allowsDeferredCalls; + }, + runDeferredCalls: function() { + if (!JSEvents.canPerformEventHandlerRequests()) { + return; + } + for (var i = 0; i < JSEvents.deferredCalls.length; ++i) { + var call = JSEvents.deferredCalls[i]; + JSEvents.deferredCalls.splice(i, 1); + --i; + call.targetFunction.apply(null, call.argsList); + } + }, + eventHandlers: [], + removeAllHandlersOnTarget: function(target, eventTypeString) { + for (var i = 0; i < JSEvents.eventHandlers.length; ++i) { + if (JSEvents.eventHandlers[i].target == target && (!eventTypeString || eventTypeString == JSEvents.eventHandlers[i].eventTypeString)) { + JSEvents._removeHandler(i--); + } + } + }, + _removeHandler: function(i) { + var h = JSEvents.eventHandlers[i]; + h.target.removeEventListener(h.eventTypeString, h.eventListenerFunc, h.useCapture); + JSEvents.eventHandlers.splice(i, 1); + }, + registerOrRemoveHandler: function(eventHandler) { + if (!eventHandler.target) { + err("registerOrRemoveHandler: the target element for event handler registration does not exist, when processing the following event handler registration:"); + console.dir(eventHandler); + return -4; + } + var jsEventHandler = function jsEventHandler(event) { + ++JSEvents.inEventHandler; + JSEvents.currentEventHandler = eventHandler; + JSEvents.runDeferredCalls(); + eventHandler.handlerFunc(event); + JSEvents.runDeferredCalls(); + --JSEvents.inEventHandler; + }; + if (eventHandler.callbackfunc) { + eventHandler.eventListenerFunc = jsEventHandler; + eventHandler.target.addEventListener(eventHandler.eventTypeString, jsEventHandler, eventHandler.useCapture); + JSEvents.eventHandlers.push(eventHandler); + JSEvents.registerRemoveEventListeners(); + } else { + for (var i = 0; i < JSEvents.eventHandlers.length; ++i) { + if (JSEvents.eventHandlers[i].target == eventHandler.target && JSEvents.eventHandlers[i].eventTypeString == eventHandler.eventTypeString) { + JSEvents._removeHandler(i--); + } + } + } + return 0; + }, + queueEventHandlerOnThread_iiii: function(targetThread, eventHandlerFunc, eventTypeId, eventData, userData) { + withStackSave(function() { + var varargs = stackAlloc(12); + GROWABLE_HEAP_I32()[varargs >> 2] = eventTypeId; + GROWABLE_HEAP_I32()[varargs + 4 >> 2] = eventData; + GROWABLE_HEAP_I32()[varargs + 8 >> 2] = userData; + _emscripten_dispatch_to_thread_(targetThread, 637534208, eventHandlerFunc, eventData, varargs); + }); + }, + getTargetThreadForEventCallback: function(targetThread) { + switch (targetThread) { + case 1: + return 0; + + case 2: + return PThread.currentProxiedOperationCallerThread; + + default: + return targetThread; + } + }, + getNodeNameForTarget: function(target) { + if (!target) return ""; + if (target == window) return "#window"; + if (target == screen) return "#screen"; + return target && target.nodeName ? target.nodeName : ""; + }, + fullscreenEnabled: function() { + return document.fullscreenEnabled || document.webkitFullscreenEnabled; + } +}; + +function maybeCStringToJsString(cString) { + return cString > 2 ? UTF8ToString(cString) : cString; +} + +var specialHTMLTargets = [ 0, typeof document != "undefined" ? document : 0, typeof window != "undefined" ? window : 0 ]; + +function findEventTarget(target) { + target = maybeCStringToJsString(target); + var domElement = specialHTMLTargets[target] || (typeof document != "undefined" ? document.querySelector(target) : undefined); + return domElement; +} + +function findCanvasEventTarget(target) { + return findEventTarget(target); +} + +function setCanvasElementSizeCallingThread(target, width, height) { + var canvas = findCanvasEventTarget(target); + if (!canvas) return -4; + if (!canvas.controlTransferredOffscreen) { + var autoResizeViewport = false; + if (canvas.GLctxObject && canvas.GLctxObject.GLctx) { + var prevViewport = canvas.GLctxObject.GLctx.getParameter(2978); + autoResizeViewport = prevViewport[0] === 0 && prevViewport[1] === 0 && prevViewport[2] === canvas.width && prevViewport[3] === canvas.height; + } + canvas.width = width; + canvas.height = height; + if (autoResizeViewport) { + canvas.GLctxObject.GLctx.viewport(0, 0, width, height); + } + } else { + return -4; + } + if (canvas.GLctxObject) GL.resizeOffscreenFramebuffer(canvas.GLctxObject); + return 0; +} + +function setCanvasElementSizeMainThread(target, width, height) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(36, 1, target, width, height); + return setCanvasElementSizeCallingThread(target, width, height); +} + +function _emscripten_set_canvas_element_size(target, width, height) { + var canvas = findCanvasEventTarget(target); + if (canvas) { + return setCanvasElementSizeCallingThread(target, width, height); + } + return setCanvasElementSizeMainThread(target, width, height); +} + +function _emscripten_set_main_loop(func, fps, simulateInfiniteLoop) { + var browserIterationFunc = getWasmTableEntry(func); + setMainLoop(browserIterationFunc, fps, simulateInfiniteLoop); +} + +function _emscripten_supports_offscreencanvas() { + return 0; +} + +function _emscripten_webgl_destroy_context(contextHandle) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(37, 1, contextHandle); + if (GL.currentContext == contextHandle) GL.currentContext = 0; + GL.deleteContext(contextHandle); +} + +function _emscripten_webgl_do_commit_frame() { + if (!GL.currentContext || !GL.currentContext.GLctx) { + return -3; + } + if (GL.currentContext.defaultFbo) { + GL.blitOffscreenFramebuffer(GL.currentContext); + return 0; + } + if (!GL.currentContext.attributes.explicitSwapControl) { + return -3; + } + return 0; +} + +function _emscripten_webgl_create_context_proxied(target, attributes) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(38, 1, target, attributes); + return _emscripten_webgl_do_create_context(target, attributes); +} + +var emscripten_webgl_power_preferences = [ "default", "low-power", "high-performance" ]; + +function _emscripten_webgl_do_create_context(target, attributes) { + assert(attributes); + var a = attributes >> 2; + var powerPreference = GROWABLE_HEAP_I32()[a + (24 >> 2)]; + var contextAttributes = { + "alpha": !!GROWABLE_HEAP_I32()[a + (0 >> 2)], + "depth": !!GROWABLE_HEAP_I32()[a + (4 >> 2)], + "stencil": !!GROWABLE_HEAP_I32()[a + (8 >> 2)], + "antialias": !!GROWABLE_HEAP_I32()[a + (12 >> 2)], + "premultipliedAlpha": !!GROWABLE_HEAP_I32()[a + (16 >> 2)], + "preserveDrawingBuffer": !!GROWABLE_HEAP_I32()[a + (20 >> 2)], + "powerPreference": emscripten_webgl_power_preferences[powerPreference], + "failIfMajorPerformanceCaveat": !!GROWABLE_HEAP_I32()[a + (28 >> 2)], + majorVersion: GROWABLE_HEAP_I32()[a + (32 >> 2)], + minorVersion: GROWABLE_HEAP_I32()[a + (36 >> 2)], + enableExtensionsByDefault: GROWABLE_HEAP_I32()[a + (40 >> 2)], + explicitSwapControl: GROWABLE_HEAP_I32()[a + (44 >> 2)], + proxyContextToMainThread: GROWABLE_HEAP_I32()[a + (48 >> 2)], + renderViaOffscreenBackBuffer: GROWABLE_HEAP_I32()[a + (52 >> 2)] + }; + var canvas = findCanvasEventTarget(target); + if (ENVIRONMENT_IS_PTHREAD) { + if (contextAttributes.proxyContextToMainThread === 2 || !canvas && contextAttributes.proxyContextToMainThread === 1) { + if (typeof OffscreenCanvas == "undefined") { + GROWABLE_HEAP_I32()[attributes + 52 >> 2] = 1; + GROWABLE_HEAP_I32()[attributes + 20 >> 2] = 1; + } + return _emscripten_webgl_create_context_proxied(target, attributes); + } + } + if (!canvas) { + return 0; + } + if (contextAttributes.explicitSwapControl && !contextAttributes.renderViaOffscreenBackBuffer) { + contextAttributes.renderViaOffscreenBackBuffer = true; + } + var contextHandle = GL.createContext(canvas, contextAttributes); + return contextHandle; +} + +function _emscripten_webgl_enable_extension(contextHandle, extension) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(39, 1, contextHandle, extension); + var context = GL.getContext(contextHandle); + var extString = UTF8ToString(extension); + if (extString.startsWith("GL_")) extString = extString.substr(3); + if (extString == "ANGLE_instanced_arrays") webgl_enable_ANGLE_instanced_arrays(GLctx); + if (extString == "OES_vertex_array_object") webgl_enable_OES_vertex_array_object(GLctx); + if (extString == "WEBGL_draw_buffers") webgl_enable_WEBGL_draw_buffers(GLctx); + if (extString == "WEBGL_draw_instanced_base_vertex_base_instance") webgl_enable_WEBGL_draw_instanced_base_vertex_base_instance(GLctx); + if (extString == "WEBGL_multi_draw_instanced_base_vertex_base_instance") webgl_enable_WEBGL_multi_draw_instanced_base_vertex_base_instance(GLctx); + if (extString == "WEBGL_multi_draw") webgl_enable_WEBGL_multi_draw(GLctx); + var ext = context.GLctx.getExtension(extString); + return !!ext; +} + +function _emscripten_webgl_init_context_attributes(attributes) { + assert(attributes); + var a = attributes >> 2; + for (var i = 0; i < 56 >> 2; ++i) { + GROWABLE_HEAP_I32()[a + i] = 0; + } + GROWABLE_HEAP_I32()[a + (0 >> 2)] = GROWABLE_HEAP_I32()[a + (4 >> 2)] = GROWABLE_HEAP_I32()[a + (12 >> 2)] = GROWABLE_HEAP_I32()[a + (16 >> 2)] = GROWABLE_HEAP_I32()[a + (32 >> 2)] = GROWABLE_HEAP_I32()[a + (40 >> 2)] = 1; + if (ENVIRONMENT_IS_WORKER) GROWABLE_HEAP_I32()[attributes + 48 >> 2] = 1; +} + +function _emscripten_webgl_make_context_current_calling_thread(contextHandle) { + var success = GL.makeContextCurrent(contextHandle); + if (success) GL.currentContextIsProxied = false; + return success ? 0 : -5; +} + +var ENV = {}; + +function getExecutableName() { + return thisProgram || "./this.program"; +} + +function getEnvStrings() { + if (!getEnvStrings.strings) { + var lang = (typeof navigator == "object" && navigator.languages && navigator.languages[0] || "C").replace("-", "_") + ".UTF-8"; + var env = { + "USER": "web_user", + "LOGNAME": "web_user", + "PATH": "/", + "PWD": "/", + "HOME": "/home/web_user", + "LANG": lang, + "_": getExecutableName() + }; + for (var x in ENV) { + if (ENV[x] === undefined) delete env[x]; else env[x] = ENV[x]; + } + var strings = []; + for (var x in env) { + strings.push(x + "=" + env[x]); + } + getEnvStrings.strings = strings; + } + return getEnvStrings.strings; +} + +function stringToAscii(str, buffer) { + for (var i = 0; i < str.length; ++i) { + assert(str.charCodeAt(i) === (str.charCodeAt(i) & 255)); + GROWABLE_HEAP_I8()[buffer++ >> 0] = str.charCodeAt(i); + } + GROWABLE_HEAP_I8()[buffer >> 0] = 0; +} + +function _environ_get(__environ, environ_buf) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(40, 1, __environ, environ_buf); + var bufSize = 0; + getEnvStrings().forEach(function(string, i) { + var ptr = environ_buf + bufSize; + GROWABLE_HEAP_U32()[__environ + i * 4 >> 2] = ptr; + stringToAscii(string, ptr); + bufSize += string.length + 1; + }); + return 0; +} + +function _environ_sizes_get(penviron_count, penviron_buf_size) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(41, 1, penviron_count, penviron_buf_size); + var strings = getEnvStrings(); + GROWABLE_HEAP_U32()[penviron_count >> 2] = strings.length; + var bufSize = 0; + strings.forEach(function(string) { + bufSize += string.length + 1; + }); + GROWABLE_HEAP_U32()[penviron_buf_size >> 2] = bufSize; + return 0; +} + +function _fd_close(fd) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(42, 1, fd); + try { + var stream = SYSCALLS.getStreamFromFD(fd); + FS.close(stream); + return 0; + } catch (e) { + if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e; + return e.errno; + } +} + +function _fd_fdstat_get(fd, pbuf) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(43, 1, fd, pbuf); + try { + var rightsBase = 0; + var rightsInheriting = 0; + var flags = 0; + { + var stream = SYSCALLS.getStreamFromFD(fd); + var type = stream.tty ? 2 : FS.isDir(stream.mode) ? 3 : FS.isLink(stream.mode) ? 7 : 4; + } + GROWABLE_HEAP_I8()[pbuf >> 0] = type; + GROWABLE_HEAP_I16()[pbuf + 2 >> 1] = flags; + tempI64 = [ rightsBase >>> 0, (tempDouble = rightsBase, +Math.abs(tempDouble) >= 1 ? tempDouble > 0 ? +Math.floor(tempDouble / 4294967296) >>> 0 : ~~+Math.ceil((tempDouble - +(~~tempDouble >>> 0)) / 4294967296) >>> 0 : 0) ], + GROWABLE_HEAP_I32()[pbuf + 8 >> 2] = tempI64[0], GROWABLE_HEAP_I32()[pbuf + 12 >> 2] = tempI64[1]; + tempI64 = [ rightsInheriting >>> 0, (tempDouble = rightsInheriting, +Math.abs(tempDouble) >= 1 ? tempDouble > 0 ? +Math.floor(tempDouble / 4294967296) >>> 0 : ~~+Math.ceil((tempDouble - +(~~tempDouble >>> 0)) / 4294967296) >>> 0 : 0) ], + GROWABLE_HEAP_I32()[pbuf + 16 >> 2] = tempI64[0], GROWABLE_HEAP_I32()[pbuf + 20 >> 2] = tempI64[1]; + return 0; + } catch (e) { + if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e; + return e.errno; + } +} + +function doReadv(stream, iov, iovcnt, offset) { + var ret = 0; + for (var i = 0; i < iovcnt; i++) { + var ptr = GROWABLE_HEAP_U32()[iov >> 2]; + var len = GROWABLE_HEAP_U32()[iov + 4 >> 2]; + iov += 8; + var curr = FS.read(stream, GROWABLE_HEAP_I8(), ptr, len, offset); + if (curr < 0) return -1; + ret += curr; + if (curr < len) break; + if (typeof offset !== "undefined") { + offset += curr; + } + } + return ret; +} + +function _fd_read(fd, iov, iovcnt, pnum) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(44, 1, fd, iov, iovcnt, pnum); + try { + var stream = SYSCALLS.getStreamFromFD(fd); + var num = doReadv(stream, iov, iovcnt); + GROWABLE_HEAP_U32()[pnum >> 2] = num; + return 0; + } catch (e) { + if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e; + return e.errno; + } +} + +function convertI32PairToI53Checked(lo, hi) { + assert(lo == lo >>> 0 || lo == (lo | 0)); + assert(hi === (hi | 0)); + return hi + 2097152 >>> 0 < 4194305 - !!lo ? (lo >>> 0) + hi * 4294967296 : NaN; +} + +function _fd_seek(fd, offset_low, offset_high, whence, newOffset) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(45, 1, fd, offset_low, offset_high, whence, newOffset); + try { + var offset = convertI32PairToI53Checked(offset_low, offset_high); + if (isNaN(offset)) return 61; + var stream = SYSCALLS.getStreamFromFD(fd); + FS.llseek(stream, offset, whence); + tempI64 = [ stream.position >>> 0, (tempDouble = stream.position, +Math.abs(tempDouble) >= 1 ? tempDouble > 0 ? +Math.floor(tempDouble / 4294967296) >>> 0 : ~~+Math.ceil((tempDouble - +(~~tempDouble >>> 0)) / 4294967296) >>> 0 : 0) ], + GROWABLE_HEAP_I32()[newOffset >> 2] = tempI64[0], GROWABLE_HEAP_I32()[newOffset + 4 >> 2] = tempI64[1]; + if (stream.getdents && offset === 0 && whence === 0) stream.getdents = null; + return 0; + } catch (e) { + if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e; + return e.errno; + } +} + +function doWritev(stream, iov, iovcnt, offset) { + var ret = 0; + for (var i = 0; i < iovcnt; i++) { + var ptr = GROWABLE_HEAP_U32()[iov >> 2]; + var len = GROWABLE_HEAP_U32()[iov + 4 >> 2]; + iov += 8; + var curr = FS.write(stream, GROWABLE_HEAP_I8(), ptr, len, offset); + if (curr < 0) return -1; + ret += curr; + if (typeof offset !== "undefined") { + offset += curr; + } + } + return ret; +} + +function _fd_write(fd, iov, iovcnt, pnum) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(46, 1, fd, iov, iovcnt, pnum); + try { + var stream = SYSCALLS.getStreamFromFD(fd); + var num = doWritev(stream, iov, iovcnt); + GROWABLE_HEAP_U32()[pnum >> 2] = num; + return 0; + } catch (e) { + if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e; + return e.errno; + } +} + +function _getaddrinfo(node, service, hint, out) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(47, 1, node, service, hint, out); + var addrs = []; + var canon = null; + var addr = 0; + var port = 0; + var flags = 0; + var family = 0; + var type = 0; + var proto = 0; + var ai, last; + function allocaddrinfo(family, type, proto, canon, addr, port) { + var sa, salen, ai; + var errno; + salen = family === 10 ? 28 : 16; + addr = family === 10 ? inetNtop6(addr) : inetNtop4(addr); + sa = _malloc(salen); + errno = writeSockaddr(sa, family, addr, port); + assert(!errno); + ai = _malloc(32); + GROWABLE_HEAP_I32()[ai + 4 >> 2] = family; + GROWABLE_HEAP_I32()[ai + 8 >> 2] = type; + GROWABLE_HEAP_I32()[ai + 12 >> 2] = proto; + GROWABLE_HEAP_U32()[ai + 24 >> 2] = canon; + GROWABLE_HEAP_U32()[ai + 20 >> 2] = sa; + if (family === 10) { + GROWABLE_HEAP_I32()[ai + 16 >> 2] = 28; + } else { + GROWABLE_HEAP_I32()[ai + 16 >> 2] = 16; + } + GROWABLE_HEAP_I32()[ai + 28 >> 2] = 0; + return ai; + } + if (hint) { + flags = GROWABLE_HEAP_I32()[hint >> 2]; + family = GROWABLE_HEAP_I32()[hint + 4 >> 2]; + type = GROWABLE_HEAP_I32()[hint + 8 >> 2]; + proto = GROWABLE_HEAP_I32()[hint + 12 >> 2]; + } + if (type && !proto) { + proto = type === 2 ? 17 : 6; + } + if (!type && proto) { + type = proto === 17 ? 2 : 1; + } + if (proto === 0) { + proto = 6; + } + if (type === 0) { + type = 1; + } + if (!node && !service) { + return -2; + } + if (flags & ~(1 | 2 | 4 | 1024 | 8 | 16 | 32)) { + return -1; + } + if (hint !== 0 && GROWABLE_HEAP_I32()[hint >> 2] & 2 && !node) { + return -1; + } + if (flags & 32) { + return -2; + } + if (type !== 0 && type !== 1 && type !== 2) { + return -7; + } + if (family !== 0 && family !== 2 && family !== 10) { + return -6; + } + if (service) { + service = UTF8ToString(service); + port = parseInt(service, 10); + if (isNaN(port)) { + if (flags & 1024) { + return -2; + } + return -8; + } + } + if (!node) { + if (family === 0) { + family = 2; + } + if ((flags & 1) === 0) { + if (family === 2) { + addr = _htonl(2130706433); + } else { + addr = [ 0, 0, 0, 1 ]; + } + } + ai = allocaddrinfo(family, type, proto, null, addr, port); + GROWABLE_HEAP_U32()[out >> 2] = ai; + return 0; + } + node = UTF8ToString(node); + addr = inetPton4(node); + if (addr !== null) { + if (family === 0 || family === 2) { + family = 2; + } else if (family === 10 && flags & 8) { + addr = [ 0, 0, _htonl(65535), addr ]; + family = 10; + } else { + return -2; + } + } else { + addr = inetPton6(node); + if (addr !== null) { + if (family === 0 || family === 10) { + family = 10; + } else { + return -2; + } + } + } + if (addr != null) { + ai = allocaddrinfo(family, type, proto, node, addr, port); + GROWABLE_HEAP_U32()[out >> 2] = ai; + return 0; + } + if (flags & 4) { + return -2; + } + node = DNS.lookup_name(node); + addr = inetPton4(node); + if (family === 0) { + family = 2; + } else if (family === 10) { + addr = [ 0, 0, _htonl(65535), addr ]; + } + ai = allocaddrinfo(family, type, proto, null, addr, port); + GROWABLE_HEAP_U32()[out >> 2] = ai; + return 0; +} + +function _getnameinfo(sa, salen, node, nodelen, serv, servlen, flags) { + var info = readSockaddr(sa, salen); + if (info.errno) { + return -6; + } + var port = info.port; + var addr = info.addr; + var overflowed = false; + if (node && nodelen) { + var lookup; + if (flags & 1 || !(lookup = DNS.lookup_addr(addr))) { + if (flags & 8) { + return -2; + } + } else { + addr = lookup; + } + var numBytesWrittenExclNull = stringToUTF8(addr, node, nodelen); + if (numBytesWrittenExclNull + 1 >= nodelen) { + overflowed = true; + } + } + if (serv && servlen) { + port = "" + port; + var numBytesWrittenExclNull = stringToUTF8(port, serv, servlen); + if (numBytesWrittenExclNull + 1 >= servlen) { + overflowed = true; + } + } + if (overflowed) { + return -12; + } + return 0; +} + +var GodotRuntime = { + get_func: function(ptr) { + return wasmTable.get(ptr); + }, + error: function() { + err.apply(null, Array.from(arguments)); + }, + print: function() { + out.apply(null, Array.from(arguments)); + }, + malloc: function(p_size) { + return _malloc(p_size); + }, + free: function(p_ptr) { + _free(p_ptr); + }, + getHeapValue: function(p_ptr, p_type) { + return getValue(p_ptr, p_type); + }, + setHeapValue: function(p_ptr, p_value, p_type) { + setValue(p_ptr, p_value, p_type); + }, + heapSub: function(p_heap, p_ptr, p_len) { + const bytes = p_heap.BYTES_PER_ELEMENT; + return p_heap.subarray(p_ptr / bytes, p_ptr / bytes + p_len); + }, + heapSlice: function(p_heap, p_ptr, p_len) { + const bytes = p_heap.BYTES_PER_ELEMENT; + return p_heap.slice(p_ptr / bytes, p_ptr / bytes + p_len); + }, + heapCopy: function(p_dst, p_src, p_ptr) { + const bytes = p_src.BYTES_PER_ELEMENT; + return p_dst.set(p_src, p_ptr / bytes); + }, + parseString: function(p_ptr) { + return UTF8ToString(p_ptr); + }, + parseStringArray: function(p_ptr, p_size) { + const strings = []; + const ptrs = GodotRuntime.heapSub(GROWABLE_HEAP_I32(), p_ptr, p_size); + ptrs.forEach(function(ptr) { + strings.push(GodotRuntime.parseString(ptr)); + }); + return strings; + }, + strlen: function(p_str) { + return lengthBytesUTF8(p_str); + }, + allocString: function(p_str) { + const length = GodotRuntime.strlen(p_str) + 1; + const c_str = GodotRuntime.malloc(length); + stringToUTF8(p_str, c_str, length); + return c_str; + }, + allocStringArray: function(p_strings) { + const size = p_strings.length; + const c_ptr = GodotRuntime.malloc(size * 4); + for (let i = 0; i < size; i++) { + GROWABLE_HEAP_I32()[(c_ptr >> 2) + i] = GodotRuntime.allocString(p_strings[i]); + } + return c_ptr; + }, + freeStringArray: function(p_ptr, p_len) { + for (let i = 0; i < p_len; i++) { + GodotRuntime.free(GROWABLE_HEAP_I32()[(p_ptr >> 2) + i]); + } + GodotRuntime.free(p_ptr); + }, + stringToHeap: function(p_str, p_ptr, p_len) { + return stringToUTF8Array(p_str, GROWABLE_HEAP_I8(), p_ptr, p_len); + } +}; + +var GodotConfig = { + canvas: null, + locale: "en", + canvas_resize_policy: 2, + virtual_keyboard: false, + persistent_drops: false, + on_execute: null, + on_exit: null, + init_config: function(p_opts) { + GodotConfig.canvas_resize_policy = p_opts["canvasResizePolicy"]; + GodotConfig.canvas = p_opts["canvas"]; + GodotConfig.locale = p_opts["locale"] || GodotConfig.locale; + GodotConfig.virtual_keyboard = p_opts["virtualKeyboard"]; + GodotConfig.persistent_drops = !!p_opts["persistentDrops"]; + GodotConfig.on_execute = p_opts["onExecute"]; + GodotConfig.on_exit = p_opts["onExit"]; + if (p_opts["focusCanvas"]) { + GodotConfig.canvas.focus(); + } + }, + locate_file: function(file) { + return Module["locateFile"](file); + }, + clear: function() { + GodotConfig.canvas = null; + GodotConfig.locale = "en"; + GodotConfig.canvas_resize_policy = 2; + GodotConfig.virtual_keyboard = false; + GodotConfig.persistent_drops = false; + GodotConfig.on_execute = null; + GodotConfig.on_exit = null; + } +}; + +var GodotFS = { + ENOENT: 44, + _idbfs: false, + _syncing: false, + _mount_points: [], + is_persistent: function() { + return GodotFS._idbfs ? 1 : 0; + }, + init: function(persistentPaths) { + GodotFS._idbfs = false; + if (!Array.isArray(persistentPaths)) { + return Promise.reject(new Error("Persistent paths must be an array")); + } + if (!persistentPaths.length) { + return Promise.resolve(); + } + GodotFS._mount_points = persistentPaths.slice(); + function createRecursive(dir) { + try { + FS.stat(dir); + } catch (e) { + if (e.errno !== GodotFS.ENOENT) { + GodotRuntime.error(e); + } + FS.mkdirTree(dir); + } + } + GodotFS._mount_points.forEach(function(path) { + createRecursive(path); + FS.mount(IDBFS, {}, path); + }); + return new Promise(function(resolve, reject) { + FS.syncfs(true, function(err) { + if (err) { + GodotFS._mount_points = []; + GodotFS._idbfs = false; + GodotRuntime.print(`IndexedDB not available: ${err.message}`); + } else { + GodotFS._idbfs = true; + } + resolve(err); + }); + }); + }, + deinit: function() { + GodotFS._mount_points.forEach(function(path) { + try { + FS.unmount(path); + } catch (e) { + GodotRuntime.print("Already unmounted", e); + } + if (GodotFS._idbfs && IDBFS.dbs[path]) { + IDBFS.dbs[path].close(); + delete IDBFS.dbs[path]; + } + }); + GodotFS._mount_points = []; + GodotFS._idbfs = false; + GodotFS._syncing = false; + }, + sync: function() { + if (GodotFS._syncing) { + GodotRuntime.error("Already syncing!"); + return Promise.resolve(); + } + GodotFS._syncing = true; + return new Promise(function(resolve, reject) { + FS.syncfs(false, function(error) { + if (error) { + GodotRuntime.error(`Failed to save IDB file system: ${error.message}`); + } + GodotFS._syncing = false; + resolve(error); + }); + }); + }, + copy_to_fs: function(path, buffer) { + const idx = path.lastIndexOf("/"); + let dir = "/"; + if (idx > 0) { + dir = path.slice(0, idx); + } + try { + FS.stat(dir); + } catch (e) { + if (e.errno !== GodotFS.ENOENT) { + GodotRuntime.error(e); + } + FS.mkdirTree(dir); + } + FS.writeFile(path, new Uint8Array(buffer)); + } +}; + +var GodotOS = { + request_quit: function() {}, + _async_cbs: [], + _fs_sync_promise: null, + atexit: function(p_promise_cb) { + GodotOS._async_cbs.push(p_promise_cb); + }, + cleanup: function(exit_code) { + const cb = GodotConfig.on_exit; + GodotFS.deinit(); + GodotConfig.clear(); + if (cb) { + cb(exit_code); + } + }, + finish_async: function(callback) { + GodotOS._fs_sync_promise.then(function(err) { + const promises = []; + GodotOS._async_cbs.forEach(function(cb) { + promises.push(new Promise(cb)); + }); + return Promise.all(promises); + }).then(function() { + return GodotFS.sync(); + }).then(function(err) { + setTimeout(function() { + callback(); + }, 0); + }); + } +}; + +var GodotAudio = { + ctx: null, + input: null, + driver: null, + interval: 0, + init: function(mix_rate, latency, onstatechange, onlatencyupdate) { + const opts = {}; + if (mix_rate) { + opts["sampleRate"] = mix_rate; + } + const ctx = new (window.AudioContext || window.webkitAudioContext)(opts); + GodotAudio.ctx = ctx; + ctx.onstatechange = function() { + let state = 0; + switch (ctx.state) { + case "suspended": + state = 0; + break; + + case "running": + state = 1; + break; + + case "closed": + state = 2; + break; + } + onstatechange(state); + }; + ctx.onstatechange(); + GodotAudio.interval = setInterval(function() { + let computed_latency = 0; + if (ctx.baseLatency) { + computed_latency += GodotAudio.ctx.baseLatency; + } + if (ctx.outputLatency) { + computed_latency += GodotAudio.ctx.outputLatency; + } + onlatencyupdate(computed_latency); + }, 1e3); + GodotOS.atexit(GodotAudio.close_async); + return ctx.destination.channelCount; + }, + create_input: function(callback) { + if (GodotAudio.input) { + return 0; + } + function gotMediaInput(stream) { + try { + GodotAudio.input = GodotAudio.ctx.createMediaStreamSource(stream); + callback(GodotAudio.input); + } catch (e) { + GodotRuntime.error("Failed creating input.", e); + } + } + if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) { + navigator.mediaDevices.getUserMedia({ + "audio": true + }).then(gotMediaInput, function(e) { + GodotRuntime.error("Error getting user media.", e); + }); + } else { + if (!navigator.getUserMedia) { + navigator.getUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia; + } + if (!navigator.getUserMedia) { + GodotRuntime.error("getUserMedia not available."); + return 1; + } + navigator.getUserMedia({ + "audio": true + }, gotMediaInput, function(e) { + GodotRuntime.print(e); + }); + } + return 0; + }, + close_async: function(resolve, reject) { + const ctx = GodotAudio.ctx; + GodotAudio.ctx = null; + if (!ctx) { + resolve(); + return; + } + if (GodotAudio.interval) { + clearInterval(GodotAudio.interval); + GodotAudio.interval = 0; + } + if (GodotAudio.input) { + GodotAudio.input.disconnect(); + GodotAudio.input = null; + } + let closed = Promise.resolve(); + if (GodotAudio.driver) { + closed = GodotAudio.driver.close(); + } + closed.then(function() { + return ctx.close(); + }).then(function() { + ctx.onstatechange = null; + resolve(); + }).catch(function(e) { + ctx.onstatechange = null; + GodotRuntime.error("Error closing AudioContext", e); + resolve(); + }); + } +}; + +function _godot_audio_has_worklet() { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(48, 1); + return GodotAudio.ctx && GodotAudio.ctx.audioWorklet ? 1 : 0; +} + +function _godot_audio_init(p_mix_rate, p_latency, p_state_change, p_latency_update) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(49, 1, p_mix_rate, p_latency, p_state_change, p_latency_update); + const statechange = GodotRuntime.get_func(p_state_change); + const latencyupdate = GodotRuntime.get_func(p_latency_update); + const mix_rate = GodotRuntime.getHeapValue(p_mix_rate, "i32"); + const channels = GodotAudio.init(mix_rate, p_latency, statechange, latencyupdate); + GodotRuntime.setHeapValue(p_mix_rate, GodotAudio.ctx.sampleRate, "i32"); + return channels; +} + +function _godot_audio_input_start() { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(50, 1); + return GodotAudio.create_input(function(input) { + input.connect(GodotAudio.driver.get_node()); + }); +} + +function _godot_audio_input_stop() { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(51, 1); + if (GodotAudio.input) { + const tracks = GodotAudio.input["mediaStream"]["getTracks"](); + for (let i = 0; i < tracks.length; i++) { + tracks[i]["stop"](); + } + GodotAudio.input.disconnect(); + GodotAudio.input = null; + } +} + +function _godot_audio_is_available() { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(52, 1); + if (!(window.AudioContext || window.webkitAudioContext)) { + return 0; + } + return 1; +} + +function _godot_audio_resume() { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(53, 1); + if (GodotAudio.ctx && GodotAudio.ctx.state !== "running") { + GodotAudio.ctx.resume(); + } +} + +var GodotAudioWorklet = { + promise: null, + worklet: null, + ring_buffer: null, + create: function(channels) { + const path = GodotConfig.locate_file("godot.audio.worklet.js"); + GodotAudioWorklet.promise = GodotAudio.ctx.audioWorklet.addModule(path).then(function() { + GodotAudioWorklet.worklet = new AudioWorkletNode(GodotAudio.ctx, "godot-processor", { + "outputChannelCount": [ channels ] + }); + return Promise.resolve(); + }); + GodotAudio.driver = GodotAudioWorklet; + }, + start: function(in_buf, out_buf, state) { + GodotAudioWorklet.promise.then(function() { + const node = GodotAudioWorklet.worklet; + node.connect(GodotAudio.ctx.destination); + node.port.postMessage({ + "cmd": "start", + "data": [ state, in_buf, out_buf ] + }); + node.port.onmessage = function(event) { + GodotRuntime.error(event.data); + }; + }); + }, + start_no_threads: function(p_out_buf, p_out_size, out_callback, p_in_buf, p_in_size, in_callback) { + function RingBuffer() { + let wpos = 0; + let rpos = 0; + let pending_samples = 0; + const wbuf = new Float32Array(p_out_size); + function send(port) { + if (pending_samples === 0) { + return; + } + const buffer = GodotRuntime.heapSub(GROWABLE_HEAP_F32(), p_out_buf, p_out_size); + const size = buffer.length; + const tot_sent = pending_samples; + out_callback(wpos, pending_samples); + if (wpos + pending_samples >= size) { + const high = size - wpos; + wbuf.set(buffer.subarray(wpos, size)); + pending_samples -= high; + wpos = 0; + } + if (pending_samples > 0) { + wbuf.set(buffer.subarray(wpos, wpos + pending_samples), tot_sent - pending_samples); + } + port.postMessage({ + "cmd": "chunk", + "data": wbuf.subarray(0, tot_sent) + }); + wpos += pending_samples; + pending_samples = 0; + } + this.receive = function(recv_buf) { + const buffer = GodotRuntime.heapSub(GROWABLE_HEAP_F32(), p_in_buf, p_in_size); + const from = rpos; + let to_write = recv_buf.length; + let high = 0; + if (rpos + to_write >= p_in_size) { + high = p_in_size - rpos; + buffer.set(recv_buf.subarray(0, high), rpos); + to_write -= high; + rpos = 0; + } + if (to_write) { + buffer.set(recv_buf.subarray(high, to_write), rpos); + } + in_callback(from, recv_buf.length); + rpos += to_write; + }; + this.consumed = function(size, port) { + pending_samples += size; + send(port); + }; + } + GodotAudioWorklet.ring_buffer = new RingBuffer(); + GodotAudioWorklet.promise.then(function() { + const node = GodotAudioWorklet.worklet; + const buffer = GodotRuntime.heapSlice(GROWABLE_HEAP_F32(), p_out_buf, p_out_size); + node.connect(GodotAudio.ctx.destination); + node.port.postMessage({ + "cmd": "start_nothreads", + "data": [ buffer, p_in_size ] + }); + node.port.onmessage = function(event) { + if (!GodotAudioWorklet.worklet) { + return; + } + if (event.data["cmd"] === "read") { + const read = event.data["data"]; + GodotAudioWorklet.ring_buffer.consumed(read, GodotAudioWorklet.worklet.port); + } else if (event.data["cmd"] === "input") { + const buf = event.data["data"]; + if (buf.length > p_in_size) { + GodotRuntime.error("Input chunk is too big"); + return; + } + GodotAudioWorklet.ring_buffer.receive(buf); + } else { + GodotRuntime.error(event.data); + } + }; + }); + }, + get_node: function() { + return GodotAudioWorklet.worklet; + }, + close: function() { + return new Promise(function(resolve, reject) { + if (GodotAudioWorklet.promise === null) { + return; + } + const p = GodotAudioWorklet.promise; + p.then(function() { + GodotAudioWorklet.worklet.port.postMessage({ + "cmd": "stop", + "data": null + }); + GodotAudioWorklet.worklet.disconnect(); + GodotAudioWorklet.worklet.port.onmessage = null; + GodotAudioWorklet.worklet = null; + GodotAudioWorklet.promise = null; + resolve(); + }).catch(function(err) { + GodotRuntime.error(err); + }); + }); + } +}; + +function _godot_audio_worklet_create(channels) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(54, 1, channels); + try { + GodotAudioWorklet.create(channels); + } catch (e) { + GodotRuntime.error("Error starting AudioDriverWorklet", e); + return 1; + } + return 0; +} + +function _godot_audio_worklet_start(p_in_buf, p_in_size, p_out_buf, p_out_size, p_state) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(55, 1, p_in_buf, p_in_size, p_out_buf, p_out_size, p_state); + const out_buffer = GodotRuntime.heapSub(GROWABLE_HEAP_F32(), p_out_buf, p_out_size); + const in_buffer = GodotRuntime.heapSub(GROWABLE_HEAP_F32(), p_in_buf, p_in_size); + const state = GodotRuntime.heapSub(GROWABLE_HEAP_I32(), p_state, 4); + GodotAudioWorklet.start(in_buffer, out_buffer, state); +} + +function _godot_audio_worklet_state_add(p_state, p_idx, p_value) { + return Atomics.add(GROWABLE_HEAP_I32(), (p_state >> 2) + p_idx, p_value); +} + +function _godot_audio_worklet_state_get(p_state, p_idx) { + return Atomics.load(GROWABLE_HEAP_I32(), (p_state >> 2) + p_idx); +} + +function _godot_audio_worklet_state_wait(p_state, p_idx, p_expected, p_timeout) { + Atomics.wait(GROWABLE_HEAP_I32(), (p_state >> 2) + p_idx, p_expected, p_timeout); + return Atomics.load(GROWABLE_HEAP_I32(), (p_state >> 2) + p_idx); +} + +function _godot_js_config_canvas_id_get(p_ptr, p_ptr_max) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(56, 1, p_ptr, p_ptr_max); + GodotRuntime.stringToHeap(`#${GodotConfig.canvas.id}`, p_ptr, p_ptr_max); +} + +function _godot_js_config_locale_get(p_ptr, p_ptr_max) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(57, 1, p_ptr, p_ptr_max); + GodotRuntime.stringToHeap(GodotConfig.locale, p_ptr, p_ptr_max); +} + +var GodotDisplayCursor = { + shape: "default", + visible: true, + cursors: {}, + set_style: function(style) { + GodotConfig.canvas.style.cursor = style; + }, + set_shape: function(shape) { + GodotDisplayCursor.shape = shape; + let css = shape; + if (shape in GodotDisplayCursor.cursors) { + const c = GodotDisplayCursor.cursors[shape]; + css = `url("${c.url}") ${c.x} ${c.y}, default`; + } + if (GodotDisplayCursor.visible) { + GodotDisplayCursor.set_style(css); + } + }, + clear: function() { + GodotDisplayCursor.set_style(""); + GodotDisplayCursor.shape = "default"; + GodotDisplayCursor.visible = true; + Object.keys(GodotDisplayCursor.cursors).forEach(function(key) { + URL.revokeObjectURL(GodotDisplayCursor.cursors[key]); + delete GodotDisplayCursor.cursors[key]; + }); + }, + lockPointer: function() { + const canvas = GodotConfig.canvas; + if (canvas.requestPointerLock) { + canvas.requestPointerLock(); + } + }, + releasePointer: function() { + if (document.exitPointerLock) { + document.exitPointerLock(); + } + }, + isPointerLocked: function() { + return document.pointerLockElement === GodotConfig.canvas; + } +}; + +var GodotEventListeners = { + handlers: [], + has: function(target, event, method, capture) { + return GodotEventListeners.handlers.findIndex(function(e) { + return e.target === target && e.event === event && e.method === method && e.capture === capture; + }) !== -1; + }, + add: function(target, event, method, capture) { + if (GodotEventListeners.has(target, event, method, capture)) { + return; + } + function Handler(p_target, p_event, p_method, p_capture) { + this.target = p_target; + this.event = p_event; + this.method = p_method; + this.capture = p_capture; + } + GodotEventListeners.handlers.push(new Handler(target, event, method, capture)); + target.addEventListener(event, method, capture); + }, + clear: function() { + GodotEventListeners.handlers.forEach(function(h) { + h.target.removeEventListener(h.event, h.method, h.capture); + }); + GodotEventListeners.handlers.length = 0; + } +}; + +var GodotDisplayScreen = { + desired_size: [ 0, 0 ], + hidpi: true, + getPixelRatio: function() { + return GodotDisplayScreen.hidpi ? window.devicePixelRatio || 1 : 1; + }, + isFullscreen: function() { + const elem = document.fullscreenElement || document.mozFullscreenElement || document.webkitFullscreenElement || document.msFullscreenElement; + if (elem) { + return elem === GodotConfig.canvas; + } + return document.fullscreen || document.mozFullScreen || document.webkitIsFullscreen; + }, + hasFullscreen: function() { + return document.fullscreenEnabled || document.mozFullScreenEnabled || document.webkitFullscreenEnabled; + }, + requestFullscreen: function() { + if (!GodotDisplayScreen.hasFullscreen()) { + return 1; + } + const canvas = GodotConfig.canvas; + try { + const promise = (canvas.requestFullscreen || canvas.msRequestFullscreen || canvas.mozRequestFullScreen || canvas.mozRequestFullscreen || canvas.webkitRequestFullscreen).call(canvas); + if (promise) { + promise.catch(function() {}); + } + } catch (e) { + return 1; + } + return 0; + }, + exitFullscreen: function() { + if (!GodotDisplayScreen.isFullscreen()) { + return 0; + } + try { + const promise = document.exitFullscreen(); + if (promise) { + promise.catch(function() {}); + } + } catch (e) { + return 1; + } + return 0; + }, + _updateGL: function() { + const gl_context_handle = _emscripten_webgl_get_current_context(); + const gl = GL.getContext(gl_context_handle); + if (gl) { + GL.resizeOffscreenFramebuffer(gl); + } + }, + updateSize: function() { + const isFullscreen = GodotDisplayScreen.isFullscreen(); + const wantsFullWindow = GodotConfig.canvas_resize_policy === 2; + const noResize = GodotConfig.canvas_resize_policy === 0; + const dWidth = GodotDisplayScreen.desired_size[0]; + const dHeight = GodotDisplayScreen.desired_size[1]; + const canvas = GodotConfig.canvas; + let width = dWidth; + let height = dHeight; + if (noResize) { + if (canvas.width !== width || canvas.height !== height) { + GodotDisplayScreen.desired_size = [ canvas.width, canvas.height ]; + GodotDisplayScreen._updateGL(); + return 1; + } + return 0; + } + const scale = GodotDisplayScreen.getPixelRatio(); + if (isFullscreen || wantsFullWindow) { + width = window.innerWidth * scale; + height = window.innerHeight * scale; + } + const csw = `${width / scale}px`; + const csh = `${height / scale}px`; + if (canvas.style.width !== csw || canvas.style.height !== csh || canvas.width !== width || canvas.height !== height) { + canvas.width = width; + canvas.height = height; + canvas.style.width = csw; + canvas.style.height = csh; + GodotDisplayScreen._updateGL(); + return 1; + } + return 0; + } +}; + +var GodotDisplayVK = { + textinput: null, + textarea: null, + available: function() { + return GodotConfig.virtual_keyboard && "ontouchstart" in window; + }, + init: function(input_cb) { + function create(what) { + const elem = document.createElement(what); + elem.style.display = "none"; + elem.style.position = "absolute"; + elem.style.zIndex = "-1"; + elem.style.background = "transparent"; + elem.style.padding = "0px"; + elem.style.margin = "0px"; + elem.style.overflow = "hidden"; + elem.style.width = "0px"; + elem.style.height = "0px"; + elem.style.border = "0px"; + elem.style.outline = "none"; + elem.readonly = true; + elem.disabled = true; + GodotEventListeners.add(elem, "input", function(evt) { + const c_str = GodotRuntime.allocString(elem.value); + input_cb(c_str, elem.selectionEnd); + GodotRuntime.free(c_str); + }, false); + GodotEventListeners.add(elem, "blur", function(evt) { + elem.style.display = "none"; + elem.readonly = true; + elem.disabled = true; + }, false); + GodotConfig.canvas.insertAdjacentElement("beforebegin", elem); + return elem; + } + GodotDisplayVK.textinput = create("input"); + GodotDisplayVK.textarea = create("textarea"); + GodotDisplayVK.updateSize(); + }, + show: function(text, type, start, end) { + if (!GodotDisplayVK.textinput || !GodotDisplayVK.textarea) { + return; + } + if (GodotDisplayVK.textinput.style.display !== "" || GodotDisplayVK.textarea.style.display !== "") { + GodotDisplayVK.hide(); + } + GodotDisplayVK.updateSize(); + let elem = GodotDisplayVK.textinput; + switch (type) { + case 0: + elem.type = "text"; + elem.inputmode = ""; + break; + + case 1: + elem = GodotDisplayVK.textarea; + break; + + case 2: + elem.type = "text"; + elem.inputmode = "numeric"; + break; + + case 3: + elem.type = "text"; + elem.inputmode = "decimal"; + break; + + case 4: + elem.type = "tel"; + elem.inputmode = ""; + break; + + case 5: + elem.type = "email"; + elem.inputmode = ""; + break; + + case 6: + elem.type = "password"; + elem.inputmode = ""; + break; + + case 7: + elem.type = "url"; + elem.inputmode = ""; + break; + + default: + elem.type = "text"; + elem.inputmode = ""; + break; + } + elem.readonly = false; + elem.disabled = false; + elem.value = text; + elem.style.display = "block"; + elem.focus(); + elem.setSelectionRange(start, end); + }, + hide: function() { + if (!GodotDisplayVK.textinput || !GodotDisplayVK.textarea) { + return; + } + [ GodotDisplayVK.textinput, GodotDisplayVK.textarea ].forEach(function(elem) { + elem.blur(); + elem.style.display = "none"; + elem.value = ""; + }); + }, + updateSize: function() { + if (!GodotDisplayVK.textinput || !GodotDisplayVK.textarea) { + return; + } + const rect = GodotConfig.canvas.getBoundingClientRect(); + function update(elem) { + elem.style.left = `${rect.left}px`; + elem.style.top = `${rect.top}px`; + elem.style.width = `${rect.width}px`; + elem.style.height = `${rect.height}px`; + } + update(GodotDisplayVK.textinput); + update(GodotDisplayVK.textarea); + }, + clear: function() { + if (GodotDisplayVK.textinput) { + GodotDisplayVK.textinput.remove(); + GodotDisplayVK.textinput = null; + } + if (GodotDisplayVK.textarea) { + GodotDisplayVK.textarea.remove(); + GodotDisplayVK.textarea = null; + } + } +}; + +var GodotDisplay = { + window_icon: "", + getDPI: function() { + const dpi = Math.round(window.devicePixelRatio * 96); + return dpi >= 96 ? dpi : 96; + } +}; + +function _godot_js_display_alert(p_text) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(58, 1, p_text); + window.alert(GodotRuntime.parseString(p_text)); +} + +function _godot_js_display_canvas_focus() { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(59, 1); + GodotConfig.canvas.focus(); +} + +function _godot_js_display_canvas_is_focused() { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(60, 1); + return document.activeElement === GodotConfig.canvas; +} + +function _godot_js_display_clipboard_get(callback) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(61, 1, callback); + const func = GodotRuntime.get_func(callback); + try { + navigator.clipboard.readText().then(function(result) { + const ptr = GodotRuntime.allocString(result); + func(ptr); + GodotRuntime.free(ptr); + }).catch(function(e) {}); + } catch (e) {} +} + +function _godot_js_display_clipboard_set(p_text) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(62, 1, p_text); + const text = GodotRuntime.parseString(p_text); + if (!navigator.clipboard || !navigator.clipboard.writeText) { + return 1; + } + navigator.clipboard.writeText(text).catch(function(e) { + GodotRuntime.error("Setting OS clipboard is only possible from an input callback for the Web platform. Exception:", e); + }); + return 0; +} + +function _godot_js_display_cursor_is_hidden() { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(63, 1); + return !GodotDisplayCursor.visible; +} + +function _godot_js_display_cursor_is_locked() { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(64, 1); + return GodotDisplayCursor.isPointerLocked() ? 1 : 0; +} + +function _godot_js_display_cursor_lock_set(p_lock) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(65, 1, p_lock); + if (p_lock) { + GodotDisplayCursor.lockPointer(); + } else { + GodotDisplayCursor.releasePointer(); + } +} + +function _godot_js_display_cursor_set_custom_shape(p_shape, p_ptr, p_len, p_hotspot_x, p_hotspot_y) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(66, 1, p_shape, p_ptr, p_len, p_hotspot_x, p_hotspot_y); + const shape = GodotRuntime.parseString(p_shape); + const old_shape = GodotDisplayCursor.cursors[shape]; + if (p_len > 0) { + const png = new Blob([ GodotRuntime.heapSlice(GROWABLE_HEAP_U8(), p_ptr, p_len) ], { + type: "image/png" + }); + const url = URL.createObjectURL(png); + GodotDisplayCursor.cursors[shape] = { + url: url, + x: p_hotspot_x, + y: p_hotspot_y + }; + } else { + delete GodotDisplayCursor.cursors[shape]; + } + if (shape === GodotDisplayCursor.shape) { + GodotDisplayCursor.set_shape(GodotDisplayCursor.shape); + } + if (old_shape) { + URL.revokeObjectURL(old_shape.url); + } +} + +function _godot_js_display_cursor_set_shape(p_string) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(67, 1, p_string); + GodotDisplayCursor.set_shape(GodotRuntime.parseString(p_string)); +} + +function _godot_js_display_cursor_set_visible(p_visible) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(68, 1, p_visible); + const visible = p_visible !== 0; + if (visible === GodotDisplayCursor.visible) { + return; + } + GodotDisplayCursor.visible = visible; + if (visible) { + GodotDisplayCursor.set_shape(GodotDisplayCursor.shape); + } else { + GodotDisplayCursor.set_style("none"); + } +} + +function _godot_js_display_desired_size_set(width, height) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(69, 1, width, height); + GodotDisplayScreen.desired_size = [ width, height ]; + GodotDisplayScreen.updateSize(); +} + +function _godot_js_display_fullscreen_cb(callback) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(70, 1, callback); + const canvas = GodotConfig.canvas; + const func = GodotRuntime.get_func(callback); + function change_cb(evt) { + if (evt.target === canvas) { + func(GodotDisplayScreen.isFullscreen()); + } + } + GodotEventListeners.add(document, "fullscreenchange", change_cb, false); + GodotEventListeners.add(document, "mozfullscreenchange", change_cb, false); + GodotEventListeners.add(document, "webkitfullscreenchange", change_cb, false); +} + +function _godot_js_display_fullscreen_exit() { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(71, 1); + return GodotDisplayScreen.exitFullscreen(); +} + +function _godot_js_display_fullscreen_request() { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(72, 1); + return GodotDisplayScreen.requestFullscreen(); +} + +function _godot_js_display_has_webgl(p_version) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(73, 1, p_version); + if (p_version !== 1 && p_version !== 2) { + return false; + } + try { + return !!document.createElement("canvas").getContext(p_version === 2 ? "webgl2" : "webgl"); + } catch (e) {} + return false; +} + +function _godot_js_display_is_swap_ok_cancel() { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(74, 1); + const win = [ "Windows", "Win64", "Win32", "WinCE" ]; + const plat = navigator.platform || ""; + if (win.indexOf(plat) !== -1) { + return 1; + } + return 0; +} + +function _godot_js_display_notification_cb(callback, p_enter, p_exit, p_in, p_out) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(75, 1, callback, p_enter, p_exit, p_in, p_out); + const canvas = GodotConfig.canvas; + const func = GodotRuntime.get_func(callback); + const notif = [ p_enter, p_exit, p_in, p_out ]; + [ "mouseover", "mouseleave", "focus", "blur" ].forEach(function(evt_name, idx) { + GodotEventListeners.add(canvas, evt_name, function() { + func(notif[idx]); + }, true); + }); +} + +function _godot_js_display_pixel_ratio_get() { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(76, 1); + return GodotDisplayScreen.getPixelRatio(); +} + +function _godot_js_display_screen_dpi_get() { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(77, 1); + return GodotDisplay.getDPI(); +} + +function _godot_js_display_screen_size_get(width, height) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(78, 1, width, height); + const scale = GodotDisplayScreen.getPixelRatio(); + GodotRuntime.setHeapValue(width, window.screen.width * scale, "i32"); + GodotRuntime.setHeapValue(height, window.screen.height * scale, "i32"); +} + +function _godot_js_display_setup_canvas(p_width, p_height, p_fullscreen, p_hidpi) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(79, 1, p_width, p_height, p_fullscreen, p_hidpi); + const canvas = GodotConfig.canvas; + GodotEventListeners.add(canvas, "contextmenu", function(ev) { + ev.preventDefault(); + }, false); + GodotEventListeners.add(canvas, "webglcontextlost", function(ev) { + alert("WebGL context lost, please reload the page"); + ev.preventDefault(); + }, false); + GodotDisplayScreen.hidpi = !!p_hidpi; + switch (GodotConfig.canvas_resize_policy) { + case 0: + GodotDisplayScreen.desired_size = [ canvas.width, canvas.height ]; + break; + + case 1: + GodotDisplayScreen.desired_size = [ p_width, p_height ]; + break; + + default: + canvas.style.position = "absolute"; + canvas.style.top = 0; + canvas.style.left = 0; + break; + } + GodotDisplayScreen.updateSize(); + if (p_fullscreen) { + GodotDisplayScreen.requestFullscreen(); + } +} + +function _godot_js_display_size_update() { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(80, 1); + const updated = GodotDisplayScreen.updateSize(); + if (updated) { + GodotDisplayVK.updateSize(); + } + return updated; +} + +function _godot_js_display_touchscreen_is_available() { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(81, 1); + return "ontouchstart" in window; +} + +function _godot_js_display_tts_available() { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(82, 1); + return "speechSynthesis" in window; +} + +function _godot_js_display_vk_available() { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(83, 1); + return GodotDisplayVK.available(); +} + +function _godot_js_display_vk_cb(p_input_cb) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(84, 1, p_input_cb); + const input_cb = GodotRuntime.get_func(p_input_cb); + if (GodotDisplayVK.available()) { + GodotDisplayVK.init(input_cb); + } +} + +function _godot_js_display_vk_hide() { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(85, 1); + GodotDisplayVK.hide(); +} + +function _godot_js_display_vk_show(p_text, p_type, p_start, p_end) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(86, 1, p_text, p_type, p_start, p_end); + const text = GodotRuntime.parseString(p_text); + const start = p_start > 0 ? p_start : 0; + const end = p_end > 0 ? p_end : start; + GodotDisplayVK.show(text, p_type, start, end); +} + +function _godot_js_display_window_blur_cb(callback) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(87, 1, callback); + const func = GodotRuntime.get_func(callback); + GodotEventListeners.add(window, "blur", function() { + func(); + }, false); +} + +function _godot_js_display_window_icon_set(p_ptr, p_len) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(88, 1, p_ptr, p_len); + let link = document.getElementById("-gd-engine-icon"); + const old_icon = GodotDisplay.window_icon; + if (p_ptr) { + if (link === null) { + link = document.createElement("link"); + link.rel = "icon"; + link.id = "-gd-engine-icon"; + document.head.appendChild(link); + } + const png = new Blob([ GodotRuntime.heapSlice(GROWABLE_HEAP_U8(), p_ptr, p_len) ], { + type: "image/png" + }); + GodotDisplay.window_icon = URL.createObjectURL(png); + link.href = GodotDisplay.window_icon; + } else { + if (link) { + link.remove(); + } + GodotDisplay.window_icon = null; + } + if (old_icon) { + URL.revokeObjectURL(old_icon); + } +} + +function _godot_js_display_window_size_get(p_width, p_height) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(89, 1, p_width, p_height); + GodotRuntime.setHeapValue(p_width, GodotConfig.canvas.width, "i32"); + GodotRuntime.setHeapValue(p_height, GodotConfig.canvas.height, "i32"); +} + +function _godot_js_display_window_title_set(p_data) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(90, 1, p_data); + document.title = GodotRuntime.parseString(p_data); +} + +function _godot_js_eval(p_js, p_use_global_ctx, p_union_ptr, p_byte_arr, p_byte_arr_write, p_callback) { + const js_code = GodotRuntime.parseString(p_js); + let eval_ret = null; + try { + if (p_use_global_ctx) { + const global_eval = eval; + eval_ret = global_eval(js_code); + } else { + eval_ret = eval(js_code); + } + } catch (e) { + GodotRuntime.error(e); + } + switch (typeof eval_ret) { + case "boolean": + GodotRuntime.setHeapValue(p_union_ptr, eval_ret, "i32"); + return 1; + + case "number": + GodotRuntime.setHeapValue(p_union_ptr, eval_ret, "double"); + return 3; + + case "string": + GodotRuntime.setHeapValue(p_union_ptr, GodotRuntime.allocString(eval_ret), "*"); + return 4; + + case "object": + if (eval_ret === null) { + break; + } + if (ArrayBuffer.isView(eval_ret) && !(eval_ret instanceof Uint8Array)) { + eval_ret = new Uint8Array(eval_ret.buffer); + } else if (eval_ret instanceof ArrayBuffer) { + eval_ret = new Uint8Array(eval_ret); + } + if (eval_ret instanceof Uint8Array) { + const func = GodotRuntime.get_func(p_callback); + const bytes_ptr = func(p_byte_arr, p_byte_arr_write, eval_ret.length); + GROWABLE_HEAP_U8().set(eval_ret, bytes_ptr); + return 29; + } + break; + } + return 0; +} + +var IDHandler = { + _last_id: 0, + _references: {}, + get: function(p_id) { + return IDHandler._references[p_id]; + }, + add: function(p_data) { + const id = ++IDHandler._last_id; + IDHandler._references[id] = p_data; + return id; + }, + remove: function(p_id) { + delete IDHandler._references[p_id]; + } +}; + +var GodotFetch = { + onread: function(id, result) { + const obj = IDHandler.get(id); + if (!obj) { + return; + } + if (result.value) { + obj.chunks.push(result.value); + } + obj.reading = false; + obj.done = result.done; + }, + onresponse: function(id, response) { + const obj = IDHandler.get(id); + if (!obj) { + return; + } + let chunked = false; + response.headers.forEach(function(value, header) { + const v = value.toLowerCase().trim(); + const h = header.toLowerCase().trim(); + if (h === "transfer-encoding" && v === "chunked") { + chunked = true; + } + }); + obj.status = response.status; + obj.response = response; + obj.reader = response.body.getReader(); + obj.chunked = chunked; + }, + onerror: function(id, err) { + GodotRuntime.error(err); + const obj = IDHandler.get(id); + if (!obj) { + return; + } + obj.error = err; + }, + create: function(method, url, headers, body) { + const obj = { + request: null, + response: null, + reader: null, + error: null, + done: false, + reading: false, + status: 0, + chunks: [] + }; + const id = IDHandler.add(obj); + const init = { + method: method, + headers: headers, + body: body + }; + obj.request = fetch(url, init); + obj.request.then(GodotFetch.onresponse.bind(null, id)).catch(GodotFetch.onerror.bind(null, id)); + return id; + }, + free: function(id) { + const obj = IDHandler.get(id); + if (!obj) { + return; + } + IDHandler.remove(id); + if (!obj.request) { + return; + } + obj.request.then(function(response) { + response.abort(); + }).catch(function(e) {}); + }, + read: function(id) { + const obj = IDHandler.get(id); + if (!obj) { + return; + } + if (obj.reader && !obj.reading) { + if (obj.done) { + obj.reader = null; + return; + } + obj.reading = true; + obj.reader.read().then(GodotFetch.onread.bind(null, id)).catch(GodotFetch.onerror.bind(null, id)); + } + } +}; + +function _godot_js_fetch_create(p_method, p_url, p_headers, p_headers_size, p_body, p_body_size) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(91, 1, p_method, p_url, p_headers, p_headers_size, p_body, p_body_size); + const method = GodotRuntime.parseString(p_method); + const url = GodotRuntime.parseString(p_url); + const headers = GodotRuntime.parseStringArray(p_headers, p_headers_size); + const body = p_body_size ? GodotRuntime.heapSlice(GROWABLE_HEAP_I8(), p_body, p_body_size) : null; + return GodotFetch.create(method, url, headers.map(function(hv) { + const idx = hv.indexOf(":"); + if (idx <= 0) { + return []; + } + return [ hv.slice(0, idx).trim(), hv.slice(idx + 1).trim() ]; + }).filter(function(v) { + return v.length === 2; + }), body); +} + +function _godot_js_fetch_free(id) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(92, 1, id); + GodotFetch.free(id); +} + +function _godot_js_fetch_http_status_get(p_id) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(93, 1, p_id); + const obj = IDHandler.get(p_id); + if (!obj || !obj.response) { + return 0; + } + return obj.status; +} + +function _godot_js_fetch_is_chunked(p_id) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(94, 1, p_id); + const obj = IDHandler.get(p_id); + if (!obj || !obj.response) { + return -1; + } + return obj.chunked ? 1 : 0; +} + +function _godot_js_fetch_read_chunk(p_id, p_buf, p_buf_size) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(95, 1, p_id, p_buf, p_buf_size); + const obj = IDHandler.get(p_id); + if (!obj || !obj.response) { + return 0; + } + let to_read = p_buf_size; + const chunks = obj.chunks; + while (to_read && chunks.length) { + const chunk = obj.chunks[0]; + if (chunk.length > to_read) { + GodotRuntime.heapCopy(GROWABLE_HEAP_I8(), chunk.slice(0, to_read), p_buf); + chunks[0] = chunk.slice(to_read); + to_read = 0; + } else { + GodotRuntime.heapCopy(GROWABLE_HEAP_I8(), chunk, p_buf); + to_read -= chunk.length; + chunks.pop(); + } + } + if (!chunks.length) { + GodotFetch.read(p_id); + } + return p_buf_size - to_read; +} + +function _godot_js_fetch_read_headers(p_id, p_parse_cb, p_ref) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(96, 1, p_id, p_parse_cb, p_ref); + const obj = IDHandler.get(p_id); + if (!obj || !obj.response) { + return 1; + } + const cb = GodotRuntime.get_func(p_parse_cb); + const arr = []; + obj.response.headers.forEach(function(v, h) { + arr.push(`${h}:${v}`); + }); + const c_ptr = GodotRuntime.allocStringArray(arr); + cb(arr.length, c_ptr, p_ref); + GodotRuntime.freeStringArray(c_ptr, arr.length); + return 0; +} + +function _godot_js_fetch_state_get(p_id) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(97, 1, p_id); + const obj = IDHandler.get(p_id); + if (!obj) { + return -1; + } + if (obj.error) { + return -1; + } + if (!obj.response) { + return 0; + } + if (obj.reader) { + return 1; + } + if (obj.done) { + return 2; + } + return -1; +} + +var GodotInputGamepads = { + samples: [], + get_pads: function() { + try { + const pads = navigator.getGamepads(); + if (pads) { + return pads; + } + return []; + } catch (e) { + return []; + } + }, + get_samples: function() { + return GodotInputGamepads.samples; + }, + get_sample: function(index) { + const samples = GodotInputGamepads.samples; + return index < samples.length ? samples[index] : null; + }, + sample: function() { + const pads = GodotInputGamepads.get_pads(); + const samples = []; + for (let i = 0; i < pads.length; i++) { + const pad = pads[i]; + if (!pad) { + samples.push(null); + continue; + } + const s = { + standard: pad.mapping === "standard", + buttons: [], + axes: [], + connected: pad.connected + }; + for (let b = 0; b < pad.buttons.length; b++) { + s.buttons.push(pad.buttons[b].value); + } + for (let a = 0; a < pad.axes.length; a++) { + s.axes.push(pad.axes[a]); + } + samples.push(s); + } + GodotInputGamepads.samples = samples; + }, + init: function(onchange) { + GodotInputGamepads.samples = []; + function add(pad) { + const guid = GodotInputGamepads.get_guid(pad); + const c_id = GodotRuntime.allocString(pad.id); + const c_guid = GodotRuntime.allocString(guid); + onchange(pad.index, 1, c_id, c_guid); + GodotRuntime.free(c_id); + GodotRuntime.free(c_guid); + } + const pads = GodotInputGamepads.get_pads(); + for (let i = 0; i < pads.length; i++) { + if (pads[i]) { + add(pads[i]); + } + } + GodotEventListeners.add(window, "gamepadconnected", function(evt) { + if (evt.gamepad) { + add(evt.gamepad); + } + }, false); + GodotEventListeners.add(window, "gamepaddisconnected", function(evt) { + if (evt.gamepad) { + onchange(evt.gamepad.index, 0); + } + }, false); + }, + get_guid: function(pad) { + if (pad.mapping) { + return pad.mapping; + } + const ua = navigator.userAgent; + let os = "Unknown"; + if (ua.indexOf("Android") >= 0) { + os = "Android"; + } else if (ua.indexOf("Linux") >= 0) { + os = "Linux"; + } else if (ua.indexOf("iPhone") >= 0) { + os = "iOS"; + } else if (ua.indexOf("Macintosh") >= 0) { + os = "MacOSX"; + } else if (ua.indexOf("Windows") >= 0) { + os = "Windows"; + } + const id = pad.id; + const exp1 = /vendor: ([0-9a-f]{4}) product: ([0-9a-f]{4})/i; + const exp2 = /^([0-9a-f]+)-([0-9a-f]+)-/i; + let vendor = ""; + let product = ""; + if (exp1.test(id)) { + const match = exp1.exec(id); + vendor = match[1].padStart(4, "0"); + product = match[2].padStart(4, "0"); + } else if (exp2.test(id)) { + const match = exp2.exec(id); + vendor = match[1].padStart(4, "0"); + product = match[2].padStart(4, "0"); + } + if (!vendor || !product) { + return `${os}Unknown`; + } + return os + vendor + product; + } +}; + +var GodotInputDragDrop = { + promises: [], + pending_files: [], + add_entry: function(entry) { + if (entry.isDirectory) { + GodotInputDragDrop.add_dir(entry); + } else if (entry.isFile) { + GodotInputDragDrop.add_file(entry); + } else { + GodotRuntime.error("Unrecognized entry...", entry); + } + }, + add_dir: function(entry) { + GodotInputDragDrop.promises.push(new Promise(function(resolve, reject) { + const reader = entry.createReader(); + reader.readEntries(function(entries) { + for (let i = 0; i < entries.length; i++) { + GodotInputDragDrop.add_entry(entries[i]); + } + resolve(); + }); + })); + }, + add_file: function(entry) { + GodotInputDragDrop.promises.push(new Promise(function(resolve, reject) { + entry.file(function(file) { + const reader = new FileReader(); + reader.onload = function() { + const f = { + "path": file.relativePath || file.webkitRelativePath, + "name": file.name, + "type": file.type, + "size": file.size, + "data": reader.result + }; + if (!f["path"]) { + f["path"] = f["name"]; + } + GodotInputDragDrop.pending_files.push(f); + resolve(); + }; + reader.onerror = function() { + GodotRuntime.print("Error reading file"); + reject(); + }; + reader.readAsArrayBuffer(file); + }, function(err) { + GodotRuntime.print("Error!"); + reject(); + }); + })); + }, + process: function(resolve, reject) { + if (GodotInputDragDrop.promises.length === 0) { + resolve(); + return; + } + GodotInputDragDrop.promises.pop().then(function() { + setTimeout(function() { + GodotInputDragDrop.process(resolve, reject); + }, 0); + }); + }, + _process_event: function(ev, callback) { + ev.preventDefault(); + if (ev.dataTransfer.items) { + for (let i = 0; i < ev.dataTransfer.items.length; i++) { + const item = ev.dataTransfer.items[i]; + let entry = null; + if ("getAsEntry" in item) { + entry = item.getAsEntry(); + } else if ("webkitGetAsEntry" in item) { + entry = item.webkitGetAsEntry(); + } + if (entry) { + GodotInputDragDrop.add_entry(entry); + } + } + } else { + GodotRuntime.error("File upload not supported"); + } + new Promise(GodotInputDragDrop.process).then(function() { + const DROP = `/tmp/drop-${parseInt(Math.random() * (1 << 30), 10)}/`; + const drops = []; + const files = []; + FS.mkdir(DROP.slice(0, -1)); + GodotInputDragDrop.pending_files.forEach(elem => { + const path = elem["path"]; + GodotFS.copy_to_fs(DROP + path, elem["data"]); + let idx = path.indexOf("/"); + if (idx === -1) { + drops.push(DROP + path); + } else { + const sub = path.substr(0, idx); + idx = sub.indexOf("/"); + if (idx < 0 && drops.indexOf(DROP + sub) === -1) { + drops.push(DROP + sub); + } + } + files.push(DROP + path); + }); + GodotInputDragDrop.promises = []; + GodotInputDragDrop.pending_files = []; + callback(drops); + if (GodotConfig.persistent_drops) { + GodotOS.atexit(function(resolve, reject) { + GodotInputDragDrop.remove_drop(files, DROP); + resolve(); + }); + } else { + GodotInputDragDrop.remove_drop(files, DROP); + } + }); + }, + remove_drop: function(files, drop_path) { + const dirs = [ drop_path.substr(0, drop_path.length - 1) ]; + files.forEach(function(file) { + FS.unlink(file); + let dir = file.replace(drop_path, ""); + let idx = dir.lastIndexOf("/"); + while (idx > 0) { + dir = dir.substr(0, idx); + if (dirs.indexOf(drop_path + dir) === -1) { + dirs.push(drop_path + dir); + } + idx = dir.lastIndexOf("/"); + } + }); + dirs.sort(function(a, b) { + const al = (a.match(/\//g) || []).length; + const bl = (b.match(/\//g) || []).length; + if (al > bl) { + return -1; + } else if (al < bl) { + return 1; + } + return 0; + }).forEach(function(dir) { + FS.rmdir(dir); + }); + }, + handler: function(callback) { + return function(ev) { + GodotInputDragDrop._process_event(ev, callback); + }; + } +}; + +var GodotInput = { + getModifiers: function(evt) { + return evt.shiftKey + 0 + (evt.altKey + 0 << 1) + (evt.ctrlKey + 0 << 2) + (evt.metaKey + 0 << 3); + }, + computePosition: function(evt, rect) { + const canvas = GodotConfig.canvas; + const rw = canvas.width / rect.width; + const rh = canvas.height / rect.height; + const x = (evt.clientX - rect.x) * rw; + const y = (evt.clientY - rect.y) * rh; + return [ x, y ]; + } +}; + +function _godot_js_input_drop_files_cb(callback) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(98, 1, callback); + const func = GodotRuntime.get_func(callback); + const dropFiles = function(files) { + const args = files || []; + if (!args.length) { + return; + } + const argc = args.length; + const argv = GodotRuntime.allocStringArray(args); + func(argv, argc); + GodotRuntime.freeStringArray(argv, argc); + }; + const canvas = GodotConfig.canvas; + GodotEventListeners.add(canvas, "dragover", function(ev) { + ev.preventDefault(); + }, false); + GodotEventListeners.add(canvas, "drop", GodotInputDragDrop.handler(dropFiles)); +} + +function _godot_js_input_gamepad_cb(change_cb) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(99, 1, change_cb); + const onchange = GodotRuntime.get_func(change_cb); + GodotInputGamepads.init(onchange); +} + +function _godot_js_input_gamepad_sample() { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(100, 1); + GodotInputGamepads.sample(); + return 0; +} + +function _godot_js_input_gamepad_sample_count() { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(101, 1); + return GodotInputGamepads.get_samples().length; +} + +function _godot_js_input_gamepad_sample_get(p_index, r_btns, r_btns_num, r_axes, r_axes_num, r_standard) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(102, 1, p_index, r_btns, r_btns_num, r_axes, r_axes_num, r_standard); + const sample = GodotInputGamepads.get_sample(p_index); + if (!sample || !sample.connected) { + return 1; + } + const btns = sample.buttons; + const btns_len = btns.length < 16 ? btns.length : 16; + for (let i = 0; i < btns_len; i++) { + GodotRuntime.setHeapValue(r_btns + (i << 2), btns[i], "float"); + } + GodotRuntime.setHeapValue(r_btns_num, btns_len, "i32"); + const axes = sample.axes; + const axes_len = axes.length < 10 ? axes.length : 10; + for (let i = 0; i < axes_len; i++) { + GodotRuntime.setHeapValue(r_axes + (i << 2), axes[i], "float"); + } + GodotRuntime.setHeapValue(r_axes_num, axes_len, "i32"); + const is_standard = sample.standard ? 1 : 0; + GodotRuntime.setHeapValue(r_standard, is_standard, "i32"); + return 0; +} + +function _godot_js_input_key_cb(callback, code, key) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(103, 1, callback, code, key); + const func = GodotRuntime.get_func(callback); + function key_cb(pressed, evt) { + const modifiers = GodotInput.getModifiers(evt); + GodotRuntime.stringToHeap(evt.code, code, 32); + GodotRuntime.stringToHeap(evt.key, key, 32); + func(pressed, evt.repeat, modifiers); + evt.preventDefault(); + } + GodotEventListeners.add(GodotConfig.canvas, "keydown", key_cb.bind(null, 1), false); + GodotEventListeners.add(GodotConfig.canvas, "keyup", key_cb.bind(null, 0), false); +} + +function _godot_js_input_mouse_button_cb(callback) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(104, 1, callback); + const func = GodotRuntime.get_func(callback); + const canvas = GodotConfig.canvas; + function button_cb(p_pressed, evt) { + const rect = canvas.getBoundingClientRect(); + const pos = GodotInput.computePosition(evt, rect); + const modifiers = GodotInput.getModifiers(evt); + if (p_pressed) { + GodotConfig.canvas.focus(); + } + if (func(p_pressed, evt.button, pos[0], pos[1], modifiers)) { + evt.preventDefault(); + } + } + GodotEventListeners.add(canvas, "mousedown", button_cb.bind(null, 1), false); + GodotEventListeners.add(window, "mouseup", button_cb.bind(null, 0), false); +} + +function _godot_js_input_mouse_move_cb(callback) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(105, 1, callback); + const func = GodotRuntime.get_func(callback); + const canvas = GodotConfig.canvas; + function move_cb(evt) { + const rect = canvas.getBoundingClientRect(); + const pos = GodotInput.computePosition(evt, rect); + const rw = canvas.width / rect.width; + const rh = canvas.height / rect.height; + const rel_pos_x = evt.movementX * rw; + const rel_pos_y = evt.movementY * rh; + const modifiers = GodotInput.getModifiers(evt); + func(pos[0], pos[1], rel_pos_x, rel_pos_y, modifiers); + } + GodotEventListeners.add(window, "mousemove", move_cb, false); +} + +function _godot_js_input_mouse_wheel_cb(callback) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(106, 1, callback); + const func = GodotRuntime.get_func(callback); + function wheel_cb(evt) { + if (func(evt["deltaX"] || 0, evt["deltaY"] || 0)) { + evt.preventDefault(); + } + } + GodotEventListeners.add(GodotConfig.canvas, "wheel", wheel_cb, false); +} + +function _godot_js_input_paste_cb(callback) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(107, 1, callback); + const func = GodotRuntime.get_func(callback); + GodotEventListeners.add(window, "paste", function(evt) { + const text = evt.clipboardData.getData("text"); + const ptr = GodotRuntime.allocString(text); + func(ptr); + GodotRuntime.free(ptr); + }, false); +} + +function _godot_js_input_touch_cb(callback, ids, coords) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(108, 1, callback, ids, coords); + const func = GodotRuntime.get_func(callback); + const canvas = GodotConfig.canvas; + function touch_cb(type, evt) { + if (type === 0) { + GodotConfig.canvas.focus(); + } + const rect = canvas.getBoundingClientRect(); + const touches = evt.changedTouches; + for (let i = 0; i < touches.length; i++) { + const touch = touches[i]; + const pos = GodotInput.computePosition(touch, rect); + GodotRuntime.setHeapValue(coords + i * 2 * 8, pos[0], "double"); + GodotRuntime.setHeapValue(coords + (i * 2 + 1) * 8, pos[1], "double"); + GodotRuntime.setHeapValue(ids + i * 4, touch.identifier, "i32"); + } + func(type, touches.length); + if (evt.cancelable) { + evt.preventDefault(); + } + } + GodotEventListeners.add(canvas, "touchstart", touch_cb.bind(null, 0), false); + GodotEventListeners.add(canvas, "touchend", touch_cb.bind(null, 1), false); + GodotEventListeners.add(canvas, "touchcancel", touch_cb.bind(null, 1), false); + GodotEventListeners.add(canvas, "touchmove", touch_cb.bind(null, 2), false); +} + +function _godot_js_input_vibrate_handheld(p_duration_ms) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(109, 1, p_duration_ms); + if (typeof navigator.vibrate !== "function") { + GodotRuntime.print("This browser does not support vibration."); + } else { + navigator.vibrate(p_duration_ms); + } +} + +function _godot_js_os_download_buffer(p_ptr, p_size, p_name, p_mime) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(110, 1, p_ptr, p_size, p_name, p_mime); + const buf = GodotRuntime.heapSlice(GROWABLE_HEAP_I8(), p_ptr, p_size); + const name = GodotRuntime.parseString(p_name); + const mime = GodotRuntime.parseString(p_mime); + const blob = new Blob([ buf ], { + type: mime + }); + const url = window.URL.createObjectURL(blob); + const a = document.createElement("a"); + a.href = url; + a.download = name; + a.style.display = "none"; + document.body.appendChild(a); + a.click(); + a.remove(); + window.URL.revokeObjectURL(url); +} + +function _godot_js_os_execute(p_json) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(111, 1, p_json); + const json_args = GodotRuntime.parseString(p_json); + const args = JSON.parse(json_args); + if (GodotConfig.on_execute) { + GodotConfig.on_execute(args); + return 0; + } + return 1; +} + +function _godot_js_os_finish_async(p_callback) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(112, 1, p_callback); + const func = GodotRuntime.get_func(p_callback); + GodotOS.finish_async(func); +} + +function _godot_js_os_fs_is_persistent() { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(113, 1); + return GodotFS.is_persistent(); +} + +function _godot_js_os_fs_sync(callback) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(114, 1, callback); + const func = GodotRuntime.get_func(callback); + GodotOS._fs_sync_promise = GodotFS.sync(); + GodotOS._fs_sync_promise.then(function(err) { + func(); + }); +} + +function _godot_js_os_has_feature(p_ftr) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(115, 1, p_ftr); + const ftr = GodotRuntime.parseString(p_ftr); + const ua = navigator.userAgent; + if (ftr === "web_macos") { + return ua.indexOf("Mac") !== -1 ? 1 : 0; + } + if (ftr === "web_windows") { + return ua.indexOf("Windows") !== -1 ? 1 : 0; + } + if (ftr === "web_android") { + return ua.indexOf("Android") !== -1 ? 1 : 0; + } + if (ftr === "web_ios") { + return ua.indexOf("iPhone") !== -1 || ua.indexOf("iPad") !== -1 || ua.indexOf("iPod") !== -1 ? 1 : 0; + } + if (ftr === "web_linuxbsd") { + return ua.indexOf("CrOS") !== -1 || ua.indexOf("BSD") !== -1 || ua.indexOf("Linux") !== -1 || ua.indexOf("X11") !== -1 ? 1 : 0; + } + return 0; +} + +function _godot_js_os_hw_concurrency_get() { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(116, 1); + const concurrency = navigator.hardwareConcurrency || 1; + return concurrency < 2 ? concurrency : 2; +} + +function _godot_js_os_request_quit_cb(p_callback) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(117, 1, p_callback); + GodotOS.request_quit = GodotRuntime.get_func(p_callback); +} + +function _godot_js_os_shell_open(p_uri) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(118, 1, p_uri); + window.open(GodotRuntime.parseString(p_uri), "_blank"); +} + +var GodotPWA = { + hasUpdate: false, + updateState: function(cb, reg) { + if (!reg) { + return; + } + if (!reg.active) { + return; + } + if (reg.waiting) { + GodotPWA.hasUpdate = true; + cb(); + } + GodotEventListeners.add(reg, "updatefound", function() { + const installing = reg.installing; + GodotEventListeners.add(installing, "statechange", function() { + if (installing.state === "installed") { + GodotPWA.hasUpdate = true; + cb(); + } + }); + }); + } +}; + +function _godot_js_pwa_cb(p_update_cb) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(119, 1, p_update_cb); + if ("serviceWorker" in navigator) { + const cb = GodotRuntime.get_func(p_update_cb); + navigator.serviceWorker.getRegistration().then(GodotPWA.updateState.bind(null, cb)); + } +} + +function _godot_js_pwa_update() { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(120, 1); + if ("serviceWorker" in navigator && GodotPWA.hasUpdate) { + navigator.serviceWorker.getRegistration().then(function(reg) { + if (!reg || !reg.waiting) { + return; + } + reg.waiting.postMessage("update"); + }); + return 0; + } + return 1; +} + +var GodotRTCDataChannel = { + connect: function(p_id, p_on_open, p_on_message, p_on_error, p_on_close) { + const ref = IDHandler.get(p_id); + if (!ref) { + return; + } + ref.binaryType = "arraybuffer"; + ref.onopen = function(event) { + p_on_open(); + }; + ref.onclose = function(event) { + p_on_close(); + }; + ref.onerror = function(event) { + p_on_error(); + }; + ref.onmessage = function(event) { + let buffer; + let is_string = 0; + if (event.data instanceof ArrayBuffer) { + buffer = new Uint8Array(event.data); + } else if (event.data instanceof Blob) { + GodotRuntime.error("Blob type not supported"); + return; + } else if (typeof event.data === "string") { + is_string = 1; + const enc = new TextEncoder("utf-8"); + buffer = new Uint8Array(enc.encode(event.data)); + } else { + GodotRuntime.error("Unknown message type"); + return; + } + const len = buffer.length * buffer.BYTES_PER_ELEMENT; + const out = GodotRuntime.malloc(len); + GROWABLE_HEAP_U8().set(buffer, out); + p_on_message(out, len, is_string); + GodotRuntime.free(out); + }; + }, + close: function(p_id) { + const ref = IDHandler.get(p_id); + if (!ref) { + return; + } + ref.onopen = null; + ref.onmessage = null; + ref.onerror = null; + ref.onclose = null; + ref.close(); + }, + get_prop: function(p_id, p_prop, p_def) { + const ref = IDHandler.get(p_id); + return ref && ref[p_prop] !== undefined ? ref[p_prop] : p_def; + } +}; + +function _godot_js_rtc_datachannel_close(p_id) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(121, 1, p_id); + const ref = IDHandler.get(p_id); + if (!ref) { + return; + } + GodotRTCDataChannel.close(p_id); +} + +function _godot_js_rtc_datachannel_connect(p_id, p_ref, p_on_open, p_on_message, p_on_error, p_on_close) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(122, 1, p_id, p_ref, p_on_open, p_on_message, p_on_error, p_on_close); + const onopen = GodotRuntime.get_func(p_on_open).bind(null, p_ref); + const onmessage = GodotRuntime.get_func(p_on_message).bind(null, p_ref); + const onerror = GodotRuntime.get_func(p_on_error).bind(null, p_ref); + const onclose = GodotRuntime.get_func(p_on_close).bind(null, p_ref); + GodotRTCDataChannel.connect(p_id, onopen, onmessage, onerror, onclose); +} + +function _godot_js_rtc_datachannel_destroy(p_id) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(123, 1, p_id); + GodotRTCDataChannel.close(p_id); + IDHandler.remove(p_id); +} + +function _godot_js_rtc_datachannel_get_buffered_amount(p_id) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(124, 1, p_id); + return GodotRTCDataChannel.get_prop(p_id, "bufferedAmount", 0); +} + +function _godot_js_rtc_datachannel_id_get(p_id) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(125, 1, p_id); + return GodotRTCDataChannel.get_prop(p_id, "id", 65535); +} + +function _godot_js_rtc_datachannel_is_negotiated(p_id) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(126, 1, p_id); + return GodotRTCDataChannel.get_prop(p_id, "negotiated", 65535); +} + +function _godot_js_rtc_datachannel_is_ordered(p_id) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(127, 1, p_id); + return GodotRTCDataChannel.get_prop(p_id, "ordered", true); +} + +function _godot_js_rtc_datachannel_label_get(p_id) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(128, 1, p_id); + const ref = IDHandler.get(p_id); + if (!ref || !ref.label) { + return 0; + } + return GodotRuntime.allocString(ref.label); +} + +function _godot_js_rtc_datachannel_max_packet_lifetime_get(p_id) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(129, 1, p_id); + const ref = IDHandler.get(p_id); + if (!ref) { + return 65535; + } + if (ref["maxPacketLifeTime"] !== undefined) { + return ref["maxPacketLifeTime"]; + } else if (ref["maxRetransmitTime"] !== undefined) { + return ref["maxRetransmitTime"]; + } + return 65535; +} + +function _godot_js_rtc_datachannel_max_retransmits_get(p_id) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(130, 1, p_id); + return GodotRTCDataChannel.get_prop(p_id, "maxRetransmits", 65535); +} + +function _godot_js_rtc_datachannel_protocol_get(p_id) { + const ref = IDHandler.get(p_id); + if (!ref || !ref.protocol) { + return 0; + } + return GodotRuntime.allocString(ref.protocol); +} + +function _godot_js_rtc_datachannel_ready_state_get(p_id) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(131, 1, p_id); + const ref = IDHandler.get(p_id); + if (!ref) { + return 3; + } + switch (ref.readyState) { + case "connecting": + return 0; + + case "open": + return 1; + + case "closing": + return 2; + + case "closed": + default: + return 3; + } +} + +function _godot_js_rtc_datachannel_send(p_id, p_buffer, p_length, p_raw) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(132, 1, p_id, p_buffer, p_length, p_raw); + const ref = IDHandler.get(p_id); + if (!ref) { + return 1; + } + const bytes_array = new Uint8Array(p_length); + for (let i = 0; i < p_length; i++) { + bytes_array[i] = GodotRuntime.getHeapValue(p_buffer + i, "i8"); + } + if (p_raw) { + ref.send(bytes_array.buffer); + } else { + const string = new TextDecoder("utf-8").decode(bytes_array); + ref.send(string); + } + return 0; +} + +var GodotRTCPeerConnection = { + ConnectionState: { + new: 0, + connecting: 1, + connected: 2, + disconnected: 3, + failed: 4, + closed: 5 + }, + ConnectionStateCompat: { + new: 0, + checking: 1, + connected: 2, + completed: 2, + disconnected: 3, + failed: 4, + closed: 5 + }, + IceGatheringState: { + new: 0, + gathering: 1, + complete: 2 + }, + SignalingState: { + stable: 0, + "have-local-offer": 1, + "have-remote-offer": 2, + "have-local-pranswer": 3, + "have-remote-pranswer": 4, + closed: 5 + }, + create: function(config, onConnectionChange, onSignalingChange, onIceGatheringChange, onIceCandidate, onDataChannel) { + let conn = null; + try { + conn = new RTCPeerConnection(config); + } catch (e) { + GodotRuntime.error(e); + return 0; + } + const id = IDHandler.add(conn); + if ("connectionState" in conn && conn["connectionState"] !== undefined) { + conn.onconnectionstatechange = function(event) { + if (!IDHandler.get(id)) { + return; + } + onConnectionChange(GodotRTCPeerConnection.ConnectionState[conn.connectionState] || 0); + }; + } else { + conn.oniceconnectionstatechange = function(event) { + if (!IDHandler.get(id)) { + return; + } + onConnectionChange(GodotRTCPeerConnection.ConnectionStateCompat[conn.iceConnectionState] || 0); + }; + } + conn.onicegatheringstatechange = function(event) { + if (!IDHandler.get(id)) { + return; + } + onIceGatheringChange(GodotRTCPeerConnection.IceGatheringState[conn.iceGatheringState] || 0); + }; + conn.onsignalingstatechange = function(event) { + if (!IDHandler.get(id)) { + return; + } + onSignalingChange(GodotRTCPeerConnection.SignalingState[conn.signalingState] || 0); + }; + conn.onicecandidate = function(event) { + if (!IDHandler.get(id)) { + return; + } + const c = event.candidate; + if (!c || !c.candidate) { + return; + } + const candidate_str = GodotRuntime.allocString(c.candidate); + const mid_str = GodotRuntime.allocString(c.sdpMid); + onIceCandidate(mid_str, c.sdpMLineIndex, candidate_str); + GodotRuntime.free(candidate_str); + GodotRuntime.free(mid_str); + }; + conn.ondatachannel = function(event) { + if (!IDHandler.get(id)) { + return; + } + const cid = IDHandler.add(event.channel); + onDataChannel(cid); + }; + return id; + }, + destroy: function(p_id) { + const conn = IDHandler.get(p_id); + if (!conn) { + return; + } + conn.onconnectionstatechange = null; + conn.oniceconnectionstatechange = null; + conn.onicegatheringstatechange = null; + conn.onsignalingstatechange = null; + conn.onicecandidate = null; + conn.ondatachannel = null; + IDHandler.remove(p_id); + }, + onsession: function(p_id, callback, session) { + if (!IDHandler.get(p_id)) { + return; + } + const type_str = GodotRuntime.allocString(session.type); + const sdp_str = GodotRuntime.allocString(session.sdp); + callback(type_str, sdp_str); + GodotRuntime.free(type_str); + GodotRuntime.free(sdp_str); + }, + onerror: function(p_id, callback, error) { + const ref = IDHandler.get(p_id); + if (!ref) { + return; + } + GodotRuntime.error(error); + callback(); + } +}; + +function _godot_js_rtc_pc_close(p_id) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(133, 1, p_id); + const ref = IDHandler.get(p_id); + if (!ref) { + return; + } + ref.close(); +} + +function _godot_js_rtc_pc_create(p_config, p_ref, p_on_connection_state_change, p_on_ice_gathering_state_change, p_on_signaling_state_change, p_on_ice_candidate, p_on_datachannel) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(134, 1, p_config, p_ref, p_on_connection_state_change, p_on_ice_gathering_state_change, p_on_signaling_state_change, p_on_ice_candidate, p_on_datachannel); + const wrap = function(p_func) { + return GodotRuntime.get_func(p_func).bind(null, p_ref); + }; + return GodotRTCPeerConnection.create(JSON.parse(GodotRuntime.parseString(p_config)), wrap(p_on_connection_state_change), wrap(p_on_signaling_state_change), wrap(p_on_ice_gathering_state_change), wrap(p_on_ice_candidate), wrap(p_on_datachannel)); +} + +function _godot_js_rtc_pc_datachannel_create(p_id, p_label, p_config) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(135, 1, p_id, p_label, p_config); + try { + const ref = IDHandler.get(p_id); + if (!ref) { + return 0; + } + const label = GodotRuntime.parseString(p_label); + const config = JSON.parse(GodotRuntime.parseString(p_config)); + const channel = ref.createDataChannel(label, config); + return IDHandler.add(channel); + } catch (e) { + GodotRuntime.error(e); + return 0; + } +} + +function _godot_js_rtc_pc_destroy(p_id) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(136, 1, p_id); + GodotRTCPeerConnection.destroy(p_id); +} + +function _godot_js_rtc_pc_ice_candidate_add(p_id, p_mid_name, p_mline_idx, p_sdp) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(137, 1, p_id, p_mid_name, p_mline_idx, p_sdp); + const ref = IDHandler.get(p_id); + if (!ref) { + return; + } + const sdpMidName = GodotRuntime.parseString(p_mid_name); + const sdpName = GodotRuntime.parseString(p_sdp); + ref.addIceCandidate(new RTCIceCandidate({ + "candidate": sdpName, + "sdpMid": sdpMidName, + "sdpMlineIndex": p_mline_idx + })); +} + +function _godot_js_rtc_pc_local_description_set(p_id, p_type, p_sdp, p_obj, p_on_error) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(138, 1, p_id, p_type, p_sdp, p_obj, p_on_error); + const ref = IDHandler.get(p_id); + if (!ref) { + return; + } + const type = GodotRuntime.parseString(p_type); + const sdp = GodotRuntime.parseString(p_sdp); + const onerror = GodotRuntime.get_func(p_on_error).bind(null, p_obj); + ref.setLocalDescription({ + "sdp": sdp, + "type": type + }).catch(function(error) { + GodotRTCPeerConnection.onerror(p_id, onerror, error); + }); +} + +function _godot_js_rtc_pc_offer_create(p_id, p_obj, p_on_session, p_on_error) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(139, 1, p_id, p_obj, p_on_session, p_on_error); + const ref = IDHandler.get(p_id); + if (!ref) { + return; + } + const onsession = GodotRuntime.get_func(p_on_session).bind(null, p_obj); + const onerror = GodotRuntime.get_func(p_on_error).bind(null, p_obj); + ref.createOffer().then(function(session) { + GodotRTCPeerConnection.onsession(p_id, onsession, session); + }).catch(function(error) { + GodotRTCPeerConnection.onerror(p_id, onerror, error); + }); +} + +function _godot_js_rtc_pc_remote_description_set(p_id, p_type, p_sdp, p_obj, p_session_created, p_on_error) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(140, 1, p_id, p_type, p_sdp, p_obj, p_session_created, p_on_error); + const ref = IDHandler.get(p_id); + if (!ref) { + return; + } + const type = GodotRuntime.parseString(p_type); + const sdp = GodotRuntime.parseString(p_sdp); + const onerror = GodotRuntime.get_func(p_on_error).bind(null, p_obj); + const onsession = GodotRuntime.get_func(p_session_created).bind(null, p_obj); + ref.setRemoteDescription({ + "sdp": sdp, + "type": type + }).then(function() { + if (type !== "offer") { + return Promise.resolve(); + } + return ref.createAnswer().then(function(session) { + GodotRTCPeerConnection.onsession(p_id, onsession, session); + }); + }).catch(function(error) { + GodotRTCPeerConnection.onerror(p_id, onerror, error); + }); +} + +function _godot_js_tts_get_voices(p_callback) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(141, 1, p_callback); + const func = GodotRuntime.get_func(p_callback); + try { + const arr = []; + const voices = window.speechSynthesis.getVoices(); + for (let i = 0; i < voices.length; i++) { + arr.push(`${voices[i].lang};${voices[i].name}`); + } + const c_ptr = GodotRuntime.allocStringArray(arr); + func(arr.length, c_ptr); + GodotRuntime.freeStringArray(c_ptr, arr.length); + } catch (e) {} +} + +function _godot_js_tts_is_paused() { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(142, 1); + return window.speechSynthesis.paused; +} + +function _godot_js_tts_is_speaking() { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(143, 1); + return window.speechSynthesis.speaking; +} + +function _godot_js_tts_pause() { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(144, 1); + window.speechSynthesis.pause(); +} + +function _godot_js_tts_resume() { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(145, 1); + window.speechSynthesis.resume(); +} + +function _godot_js_tts_speak(p_text, p_voice, p_volume, p_pitch, p_rate, p_utterance_id, p_callback) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(146, 1, p_text, p_voice, p_volume, p_pitch, p_rate, p_utterance_id, p_callback); + const func = GodotRuntime.get_func(p_callback); + function listener_end(evt) { + evt.currentTarget.cb(1, evt.currentTarget.id, 0); + } + function listener_start(evt) { + evt.currentTarget.cb(0, evt.currentTarget.id, 0); + } + function listener_error(evt) { + evt.currentTarget.cb(2, evt.currentTarget.id, 0); + } + function listener_bound(evt) { + evt.currentTarget.cb(3, evt.currentTarget.id, evt.charIndex); + } + const utterance = new SpeechSynthesisUtterance(GodotRuntime.parseString(p_text)); + utterance.rate = p_rate; + utterance.pitch = p_pitch; + utterance.volume = p_volume / 100; + utterance.addEventListener("end", listener_end); + utterance.addEventListener("start", listener_start); + utterance.addEventListener("error", listener_error); + utterance.addEventListener("boundary", listener_bound); + utterance.id = p_utterance_id; + utterance.cb = func; + const voice = GodotRuntime.parseString(p_voice); + const voices = window.speechSynthesis.getVoices(); + for (let i = 0; i < voices.length; i++) { + if (voices[i].name === voice) { + utterance.voice = voices[i]; + break; + } + } + window.speechSynthesis.resume(); + window.speechSynthesis.speak(utterance); +} + +function _godot_js_tts_stop() { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(147, 1); + window.speechSynthesis.cancel(); + window.speechSynthesis.resume(); +} + +var GodotWebSocket = { + _onopen: function(p_id, callback, event) { + const ref = IDHandler.get(p_id); + if (!ref) { + return; + } + const c_str = GodotRuntime.allocString(ref.protocol); + callback(c_str); + GodotRuntime.free(c_str); + }, + _onmessage: function(p_id, callback, event) { + const ref = IDHandler.get(p_id); + if (!ref) { + return; + } + let buffer; + let is_string = 0; + if (event.data instanceof ArrayBuffer) { + buffer = new Uint8Array(event.data); + } else if (event.data instanceof Blob) { + GodotRuntime.error("Blob type not supported"); + return; + } else if (typeof event.data === "string") { + is_string = 1; + const enc = new TextEncoder("utf-8"); + buffer = new Uint8Array(enc.encode(event.data)); + } else { + GodotRuntime.error("Unknown message type"); + return; + } + const len = buffer.length * buffer.BYTES_PER_ELEMENT; + const out = GodotRuntime.malloc(len); + GROWABLE_HEAP_U8().set(buffer, out); + callback(out, len, is_string); + GodotRuntime.free(out); + }, + _onerror: function(p_id, callback, event) { + const ref = IDHandler.get(p_id); + if (!ref) { + return; + } + callback(); + }, + _onclose: function(p_id, callback, event) { + const ref = IDHandler.get(p_id); + if (!ref) { + return; + } + const c_str = GodotRuntime.allocString(event.reason); + callback(event.code, c_str, event.wasClean ? 1 : 0); + GodotRuntime.free(c_str); + }, + send: function(p_id, p_data) { + const ref = IDHandler.get(p_id); + if (!ref || ref.readyState !== ref.OPEN) { + return 1; + } + ref.send(p_data); + return 0; + }, + bufferedAmount: function(p_id) { + const ref = IDHandler.get(p_id); + if (!ref) { + return 0; + } + return ref.bufferedAmount; + }, + create: function(socket, p_on_open, p_on_message, p_on_error, p_on_close) { + const id = IDHandler.add(socket); + socket.onopen = GodotWebSocket._onopen.bind(null, id, p_on_open); + socket.onmessage = GodotWebSocket._onmessage.bind(null, id, p_on_message); + socket.onerror = GodotWebSocket._onerror.bind(null, id, p_on_error); + socket.onclose = GodotWebSocket._onclose.bind(null, id, p_on_close); + return id; + }, + close: function(p_id, p_code, p_reason) { + const ref = IDHandler.get(p_id); + if (ref && ref.readyState < ref.CLOSING) { + const code = p_code; + const reason = p_reason; + ref.close(code, reason); + } + }, + destroy: function(p_id) { + const ref = IDHandler.get(p_id); + if (!ref) { + return; + } + GodotWebSocket.close(p_id, 3001, "destroyed"); + IDHandler.remove(p_id); + ref.onopen = null; + ref.onmessage = null; + ref.onerror = null; + ref.onclose = null; + } +}; + +function _godot_js_websocket_buffered_amount(p_id) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(148, 1, p_id); + return GodotWebSocket.bufferedAmount(p_id); +} + +function _godot_js_websocket_close(p_id, p_code, p_reason) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(149, 1, p_id, p_code, p_reason); + const code = p_code; + const reason = GodotRuntime.parseString(p_reason); + GodotWebSocket.close(p_id, code, reason); +} + +function _godot_js_websocket_create(p_ref, p_url, p_proto, p_on_open, p_on_message, p_on_error, p_on_close) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(150, 1, p_ref, p_url, p_proto, p_on_open, p_on_message, p_on_error, p_on_close); + const on_open = GodotRuntime.get_func(p_on_open).bind(null, p_ref); + const on_message = GodotRuntime.get_func(p_on_message).bind(null, p_ref); + const on_error = GodotRuntime.get_func(p_on_error).bind(null, p_ref); + const on_close = GodotRuntime.get_func(p_on_close).bind(null, p_ref); + const url = GodotRuntime.parseString(p_url); + const protos = GodotRuntime.parseString(p_proto); + let socket = null; + try { + if (protos) { + socket = new WebSocket(url, protos.split(",")); + } else { + socket = new WebSocket(url); + } + } catch (e) { + return 0; + } + socket.binaryType = "arraybuffer"; + return GodotWebSocket.create(socket, on_open, on_message, on_error, on_close); +} + +function _godot_js_websocket_destroy(p_id) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(151, 1, p_id); + GodotWebSocket.destroy(p_id); +} + +function _godot_js_websocket_send(p_id, p_buf, p_buf_len, p_raw) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(152, 1, p_id, p_buf, p_buf_len, p_raw); + const bytes_array = new Uint8Array(p_buf_len); + let i = 0; + for (i = 0; i < p_buf_len; i++) { + bytes_array[i] = GodotRuntime.getHeapValue(p_buf + i, "i8"); + } + let out = bytes_array.buffer; + if (!p_raw) { + out = new TextDecoder("utf-8").decode(bytes_array); + } + return GodotWebSocket.send(p_id, out); +} + +var GodotJSWrapper = { + proxies: null, + cb_ret: null, + MyProxy: function(val) { + const id = IDHandler.add(this); + GodotJSWrapper.proxies.set(val, id); + let refs = 1; + this.ref = function() { + refs++; + }; + this.unref = function() { + refs--; + if (refs === 0) { + IDHandler.remove(id); + GodotJSWrapper.proxies.delete(val); + } + }; + this.get_val = function() { + return val; + }; + this.get_id = function() { + return id; + }; + }, + get_proxied: function(val) { + const id = GodotJSWrapper.proxies.get(val); + if (id === undefined) { + const proxy = new GodotJSWrapper.MyProxy(val); + return proxy.get_id(); + } + IDHandler.get(id).ref(); + return id; + }, + get_proxied_value: function(id) { + const proxy = IDHandler.get(id); + if (proxy === undefined) { + return undefined; + } + return proxy.get_val(); + }, + variant2js: function(type, val) { + switch (type) { + case 0: + return null; + + case 1: + return !!GodotRuntime.getHeapValue(val, "i64"); + + case 2: + return GodotRuntime.getHeapValue(val, "i64"); + + case 3: + return GodotRuntime.getHeapValue(val, "double"); + + case 4: + return GodotRuntime.parseString(GodotRuntime.getHeapValue(val, "*")); + + case 24: + return GodotJSWrapper.get_proxied_value(GodotRuntime.getHeapValue(val, "i64")); + + default: + return undefined; + } + }, + js2variant: function(p_val, p_exchange) { + if (p_val === undefined || p_val === null) { + return 0; + } + const type = typeof p_val; + if (type === "boolean") { + GodotRuntime.setHeapValue(p_exchange, p_val, "i64"); + return 1; + } else if (type === "number") { + if (Number.isInteger(p_val)) { + GodotRuntime.setHeapValue(p_exchange, p_val, "i64"); + return 2; + } + GodotRuntime.setHeapValue(p_exchange, p_val, "double"); + return 3; + } else if (type === "string") { + const c_str = GodotRuntime.allocString(p_val); + GodotRuntime.setHeapValue(p_exchange, c_str, "*"); + return 4; + } + const id = GodotJSWrapper.get_proxied(p_val); + GodotRuntime.setHeapValue(p_exchange, id, "i64"); + return 24; + } +}; + +function _godot_js_wrapper_create_cb(p_ref, p_func) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(153, 1, p_ref, p_func); + const func = GodotRuntime.get_func(p_func); + let id = 0; + const cb = function() { + if (!GodotJSWrapper.get_proxied_value(id)) { + return undefined; + } + GodotJSWrapper.cb_ret = null; + const args = Array.from(arguments); + const argsProxy = new GodotJSWrapper.MyProxy(args); + func(p_ref, argsProxy.get_id(), args.length); + argsProxy.unref(); + const ret = GodotJSWrapper.cb_ret; + GodotJSWrapper.cb_ret = null; + return ret; + }; + id = GodotJSWrapper.get_proxied(cb); + return id; +} + +function _godot_js_wrapper_create_object(p_object, p_args, p_argc, p_convert_callback, p_exchange, p_lock, p_free_lock_callback) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(154, 1, p_object, p_args, p_argc, p_convert_callback, p_exchange, p_lock, p_free_lock_callback); + const name = GodotRuntime.parseString(p_object); + if (typeof window[name] === "undefined") { + return -1; + } + const convert = GodotRuntime.get_func(p_convert_callback); + const freeLock = GodotRuntime.get_func(p_free_lock_callback); + const args = new Array(p_argc); + for (let i = 0; i < p_argc; i++) { + const type = convert(p_args, i, p_exchange, p_lock); + const lock = GodotRuntime.getHeapValue(p_lock, "*"); + args[i] = GodotJSWrapper.variant2js(type, p_exchange); + if (lock) { + freeLock(p_lock, type); + } + } + try { + const res = new window[name](...args); + return GodotJSWrapper.js2variant(res, p_exchange); + } catch (e) { + GodotRuntime.error(`Error calling constructor ${name} with args:`, args, "error:", e); + return -1; + } +} + +function _godot_js_wrapper_interface_get(p_name) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(155, 1, p_name); + const name = GodotRuntime.parseString(p_name); + if (typeof window[name] !== "undefined") { + return GodotJSWrapper.get_proxied(window[name]); + } + return 0; +} + +function _godot_js_wrapper_object_call(p_id, p_method, p_args, p_argc, p_convert_callback, p_exchange, p_lock, p_free_lock_callback) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(156, 1, p_id, p_method, p_args, p_argc, p_convert_callback, p_exchange, p_lock, p_free_lock_callback); + const obj = GodotJSWrapper.get_proxied_value(p_id); + if (obj === undefined) { + return -1; + } + const method = GodotRuntime.parseString(p_method); + const convert = GodotRuntime.get_func(p_convert_callback); + const freeLock = GodotRuntime.get_func(p_free_lock_callback); + const args = new Array(p_argc); + for (let i = 0; i < p_argc; i++) { + const type = convert(p_args, i, p_exchange, p_lock); + const lock = GodotRuntime.getHeapValue(p_lock, "*"); + args[i] = GodotJSWrapper.variant2js(type, p_exchange); + if (lock) { + freeLock(p_lock, type); + } + } + try { + const res = obj[method](...args); + return GodotJSWrapper.js2variant(res, p_exchange); + } catch (e) { + GodotRuntime.error(`Error calling method ${method} on:`, obj, "error:", e); + return -1; + } +} + +function _godot_js_wrapper_object_get(p_id, p_exchange, p_prop) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(157, 1, p_id, p_exchange, p_prop); + const obj = GodotJSWrapper.get_proxied_value(p_id); + if (obj === undefined) { + return 0; + } + if (p_prop) { + const prop = GodotRuntime.parseString(p_prop); + try { + return GodotJSWrapper.js2variant(obj[prop], p_exchange); + } catch (e) { + GodotRuntime.error(`Error getting variable ${prop} on object`, obj); + return 0; + } + } + return GodotJSWrapper.js2variant(obj, p_exchange); +} + +function _godot_js_wrapper_object_getvar(p_id, p_type, p_exchange) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(158, 1, p_id, p_type, p_exchange); + const obj = GodotJSWrapper.get_proxied_value(p_id); + if (obj === undefined) { + return -1; + } + const prop = GodotJSWrapper.variant2js(p_type, p_exchange); + if (prop === undefined || prop === null) { + return -1; + } + try { + return GodotJSWrapper.js2variant(obj[prop], p_exchange); + } catch (e) { + GodotRuntime.error(`Error getting variable ${prop} on object`, obj, e); + return -1; + } +} + +function _godot_js_wrapper_object_set(p_id, p_name, p_type, p_exchange) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(159, 1, p_id, p_name, p_type, p_exchange); + const obj = GodotJSWrapper.get_proxied_value(p_id); + if (obj === undefined) { + return; + } + const name = GodotRuntime.parseString(p_name); + try { + obj[name] = GodotJSWrapper.variant2js(p_type, p_exchange); + } catch (e) { + GodotRuntime.error(`Error setting variable ${name} on object`, obj); + } +} + +function _godot_js_wrapper_object_set_cb_ret(p_val_type, p_val_ex) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(160, 1, p_val_type, p_val_ex); + GodotJSWrapper.cb_ret = GodotJSWrapper.variant2js(p_val_type, p_val_ex); +} + +function _godot_js_wrapper_object_setvar(p_id, p_key_type, p_key_ex, p_val_type, p_val_ex) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(161, 1, p_id, p_key_type, p_key_ex, p_val_type, p_val_ex); + const obj = GodotJSWrapper.get_proxied_value(p_id); + if (obj === undefined) { + return -1; + } + const key = GodotJSWrapper.variant2js(p_key_type, p_key_ex); + try { + obj[key] = GodotJSWrapper.variant2js(p_val_type, p_val_ex); + return 0; + } catch (e) { + GodotRuntime.error(`Error setting variable ${key} on object`, obj); + return -1; + } +} + +function _godot_js_wrapper_object_unref(p_id) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(162, 1, p_id); + const proxy = IDHandler.get(p_id); + if (proxy !== undefined) { + proxy.unref(); + } +} + +var GodotWebGL2 = {}; + +function _godot_webgl2_glFramebufferTextureMultiviewOVR(target, attachment, texture, level, base_view_index, num_views) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(163, 1, target, attachment, texture, level, base_view_index, num_views); + const context = GL.currentContext; + if (typeof context.multiviewExt === "undefined") { + const ext = context.GLctx.getExtension("OVR_multiview2"); + if (!ext) { + GodotRuntime.error("Trying to call glFramebufferTextureMultiviewOVR() without the OVR_multiview2 extension"); + return; + } + context.multiviewExt = ext; + } + const ext = context.multiviewExt; + ext.framebufferTextureMultiviewOVR(target, attachment, GL.textures[texture], level, base_view_index, num_views); +} + +function _godot_webgl2_glGetBufferSubData(target, offset, size, data) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(164, 1, target, offset, size, data); + const gl_context_handle = _emscripten_webgl_get_current_context(); + const gl = GL.getContext(gl_context_handle); + if (gl) { + gl.GLctx["getBufferSubData"](target, offset, GROWABLE_HEAP_U8(), data, size); + } +} + +var GodotWebXR = { + gl: null, + session: null, + gl_binding: null, + layer: null, + space: null, + frame: null, + pose: null, + view_count: 1, + input_sources: [ , , , , , , , , , , , , , , , ], + touches: [ , , , , ], + onsimpleevent: null, + orig_requestAnimationFrame: null, + requestAnimationFrame: callback => { + if (GodotWebXR.session && GodotWebXR.space) { + const onFrame = function(time, frame) { + GodotWebXR.frame = frame; + GodotWebXR.pose = frame.getViewerPose(GodotWebXR.space); + callback(time); + GodotWebXR.frame = null; + GodotWebXR.pose = null; + }; + GodotWebXR.session.requestAnimationFrame(onFrame); + } else { + GodotWebXR.orig_requestAnimationFrame(callback); + } + }, + monkeyPatchRequestAnimationFrame: enable => { + if (GodotWebXR.orig_requestAnimationFrame === null) { + GodotWebXR.orig_requestAnimationFrame = Browser.requestAnimationFrame; + } + Browser.requestAnimationFrame = enable ? GodotWebXR.requestAnimationFrame : GodotWebXR.orig_requestAnimationFrame; + }, + pauseResumeMainLoop: () => { + Browser.mainLoop.pause(); + runtimeKeepalivePush(); + window.setTimeout(function() { + runtimeKeepalivePop(); + Browser.mainLoop.resume(); + }, 0); + }, + getLayer: () => { + const new_view_count = GodotWebXR.pose ? GodotWebXR.pose.views.length : 1; + let layer = GodotWebXR.layer; + if (layer && GodotWebXR.view_count === new_view_count) { + return layer; + } + if (!GodotWebXR.session || !GodotWebXR.gl_binding) { + return null; + } + const gl = GodotWebXR.gl; + layer = GodotWebXR.gl_binding.createProjectionLayer({ + textureType: new_view_count > 1 ? "texture-array" : "texture", + colorFormat: gl.RGBA8, + depthFormat: gl.DEPTH_COMPONENT24 + }); + GodotWebXR.session.updateRenderState({ + layers: [ layer ] + }); + GodotWebXR.layer = layer; + GodotWebXR.view_count = new_view_count; + return layer; + }, + getSubImage: () => { + if (!GodotWebXR.pose) { + return null; + } + const layer = GodotWebXR.getLayer(); + if (layer === null) { + return null; + } + return GodotWebXR.gl_binding.getViewSubImage(layer, GodotWebXR.pose.views[0]); + }, + getTextureId: texture => { + if (texture.name !== undefined) { + return texture.name; + } + const id = GL.getNewId(GL.textures); + texture.name = id; + GL.textures[id] = texture; + return id; + }, + addInputSource: input_source => { + let name = -1; + if (input_source.targetRayMode === "tracked-pointer" && input_source.handedness === "left") { + name = 0; + } else if (input_source.targetRayMode === "tracked-pointer" && input_source.handedness === "right") { + name = 1; + } else { + for (let i = 2; i < 16; i++) { + if (!GodotWebXR.input_sources[i]) { + name = i; + break; + } + } + } + if (name >= 0) { + GodotWebXR.input_sources[name] = input_source; + input_source.name = name; + if (input_source.targetRayMode === "screen") { + let touch_index = -1; + for (let i = 0; i < 5; i++) { + if (!GodotWebXR.touches[i]) { + touch_index = i; + break; + } + } + if (touch_index >= 0) { + GodotWebXR.touches[touch_index] = input_source; + input_source.touch_index = touch_index; + } + } + } + return name; + }, + removeInputSource: input_source => { + if (input_source.name !== undefined) { + const name = input_source.name; + if (name >= 0 && name < 16) { + GodotWebXR.input_sources[name] = null; + } + if (input_source.touch_index !== undefined) { + const touch_index = input_source.touch_index; + if (touch_index >= 0 && touch_index < 5) { + GodotWebXR.touches[touch_index] = null; + } + } + return name; + } + return -1; + }, + getInputSourceId: input_source => { + if (input_source !== undefined) { + return input_source.name; + } + return -1; + }, + getTouchIndex: input_source => { + if (input_source.touch_index !== undefined) { + return input_source.touch_index; + } + return -1; + } +}; + +function _godot_webxr_get_bounds_geometry(r_points) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(165, 1, r_points); + if (!GodotWebXR.space || !GodotWebXR.space.boundsGeometry) { + return 0; + } + const point_count = GodotWebXR.space.boundsGeometry.length; + if (point_count === 0) { + return 0; + } + const buf = GodotRuntime.malloc(point_count * 3 * 4); + for (let i = 0; i < point_count; i++) { + const point = GodotWebXR.space.boundsGeometry[i]; + GodotRuntime.setHeapValue(buf + (i * 3 + 0) * 4, point.x, "float"); + GodotRuntime.setHeapValue(buf + (i * 3 + 1) * 4, point.y, "float"); + GodotRuntime.setHeapValue(buf + (i * 3 + 2) * 4, point.z, "float"); + } + GodotRuntime.setHeapValue(r_points, buf, "i32"); + return point_count; +} + +function _godot_webxr_get_color_texture() { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(166, 1); + const subimage = GodotWebXR.getSubImage(); + if (subimage === null) { + return 0; + } + return GodotWebXR.getTextureId(subimage.colorTexture); +} + +function _godot_webxr_get_depth_texture() { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(167, 1); + const subimage = GodotWebXR.getSubImage(); + if (subimage === null) { + return 0; + } + if (!subimage.depthStencilTexture) { + return 0; + } + return GodotWebXR.getTextureId(subimage.depthStencilTexture); +} + +function _godot_webxr_get_frame_rate() { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(168, 1); + if (!GodotWebXR.session || GodotWebXR.session.frameRate === undefined) { + return 0; + } + return GodotWebXR.session.frameRate; +} + +function _godot_webxr_get_projection_for_view(p_view, r_transform) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(169, 1, p_view, r_transform); + if (!GodotWebXR.session || !GodotWebXR.pose) { + return false; + } + const matrix = GodotWebXR.pose.views[p_view].projectionMatrix; + for (let i = 0; i < 16; i++) { + GodotRuntime.setHeapValue(r_transform + i * 4, matrix[i], "float"); + } + return true; +} + +function _godot_webxr_get_render_target_size(r_size) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(170, 1, r_size); + const subimage = GodotWebXR.getSubImage(); + if (subimage === null) { + return false; + } + GodotRuntime.setHeapValue(r_size + 0, subimage.viewport.width, "i32"); + GodotRuntime.setHeapValue(r_size + 4, subimage.viewport.height, "i32"); + return true; +} + +function _godot_webxr_get_supported_frame_rates(r_frame_rates) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(171, 1, r_frame_rates); + if (!GodotWebXR.session || GodotWebXR.session.supportedFrameRates === undefined) { + return 0; + } + const frame_rate_count = GodotWebXR.session.supportedFrameRates.length; + if (frame_rate_count === 0) { + return 0; + } + const buf = GodotRuntime.malloc(frame_rate_count * 4); + for (let i = 0; i < frame_rate_count; i++) { + GodotRuntime.setHeapValue(buf + i * 4, GodotWebXR.session.supportedFrameRates[i], "float"); + } + GodotRuntime.setHeapValue(r_frame_rates, buf, "i32"); + return frame_rate_count; +} + +function _godot_webxr_get_transform_for_view(p_view, r_transform) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(172, 1, p_view, r_transform); + if (!GodotWebXR.session || !GodotWebXR.pose) { + return false; + } + const views = GodotWebXR.pose.views; + let matrix; + if (p_view >= 0) { + matrix = views[p_view].transform.matrix; + } else { + matrix = GodotWebXR.pose.transform.matrix; + } + for (let i = 0; i < 16; i++) { + GodotRuntime.setHeapValue(r_transform + i * 4, matrix[i], "float"); + } + return true; +} + +function _godot_webxr_get_velocity_texture() { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(173, 1); + const subimage = GodotWebXR.getSubImage(); + if (subimage === null) { + return 0; + } + if (!subimage.motionVectorTexture) { + return 0; + } + return GodotWebXR.getTextureId(subimage.motionVectorTexture); +} + +function _godot_webxr_get_view_count() { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(174, 1); + if (!GodotWebXR.session || !GodotWebXR.pose) { + return 1; + } + const view_count = GodotWebXR.pose.views.length; + return view_count > 0 ? view_count : 1; +} + +function _godot_webxr_get_visibility_state() { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(175, 1); + if (!GodotWebXR.session || !GodotWebXR.session.visibilityState) { + return 0; + } + return GodotRuntime.allocString(GodotWebXR.session.visibilityState); +} + +function _godot_webxr_initialize(p_session_mode, p_required_features, p_optional_features, p_requested_reference_spaces, p_on_session_started, p_on_session_ended, p_on_session_failed, p_on_input_event, p_on_simple_event) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(176, 1, p_session_mode, p_required_features, p_optional_features, p_requested_reference_spaces, p_on_session_started, p_on_session_ended, p_on_session_failed, p_on_input_event, p_on_simple_event); + GodotWebXR.monkeyPatchRequestAnimationFrame(true); + const session_mode = GodotRuntime.parseString(p_session_mode); + const required_features = GodotRuntime.parseString(p_required_features).split(",").map(s => s.trim()).filter(s => s !== ""); + const optional_features = GodotRuntime.parseString(p_optional_features).split(",").map(s => s.trim()).filter(s => s !== ""); + const requested_reference_space_types = GodotRuntime.parseString(p_requested_reference_spaces).split(",").map(s => s.trim()); + const onstarted = GodotRuntime.get_func(p_on_session_started); + const onended = GodotRuntime.get_func(p_on_session_ended); + const onfailed = GodotRuntime.get_func(p_on_session_failed); + const oninputevent = GodotRuntime.get_func(p_on_input_event); + const onsimpleevent = GodotRuntime.get_func(p_on_simple_event); + const session_init = {}; + if (required_features.length > 0) { + session_init["requiredFeatures"] = required_features; + } + if (optional_features.length > 0) { + session_init["optionalFeatures"] = optional_features; + } + navigator.xr.requestSession(session_mode, session_init).then(function(session) { + GodotWebXR.session = session; + session.addEventListener("end", function(evt) { + onended(); + }); + session.addEventListener("inputsourceschange", function(evt) { + evt.added.forEach(GodotWebXR.addInputSource); + evt.removed.forEach(GodotWebXR.removeInputSource); + }); + [ "selectstart", "selectend", "squeezestart", "squeezeend" ].forEach((input_event, index) => { + session.addEventListener(input_event, function(evt) { + GodotWebXR.frame = evt.frame; + oninputevent(index, GodotWebXR.getInputSourceId(evt.inputSource)); + GodotWebXR.frame = null; + }); + }); + session.addEventListener("visibilitychange", function(evt) { + const c_str = GodotRuntime.allocString("visibility_state_changed"); + onsimpleevent(c_str); + GodotRuntime.free(c_str); + }); + GodotWebXR.onsimpleevent = onsimpleevent; + const gl_context_handle = _emscripten_webgl_get_current_context(); + const gl = GL.getContext(gl_context_handle).GLctx; + GodotWebXR.gl = gl; + gl.makeXRCompatible().then(function() { + GodotWebXR.gl_binding = new XRWebGLBinding(session, gl); + GodotWebXR.getLayer(); + function onReferenceSpaceSuccess(reference_space, reference_space_type) { + GodotWebXR.space = reference_space; + reference_space.onreset = function(evt) { + const c_str = GodotRuntime.allocString("reference_space_reset"); + onsimpleevent(c_str); + GodotRuntime.free(c_str); + }; + GodotWebXR.pauseResumeMainLoop(); + window.setTimeout(function() { + const c_str = GodotRuntime.allocString(reference_space_type); + onstarted(c_str); + GodotRuntime.free(c_str); + }, 0); + } + function requestReferenceSpace() { + const reference_space_type = requested_reference_space_types.shift(); + session.requestReferenceSpace(reference_space_type).then(refSpace => { + onReferenceSpaceSuccess(refSpace, reference_space_type); + }).catch(() => { + if (requested_reference_space_types.length === 0) { + const c_str = GodotRuntime.allocString("Unable to get any of the requested reference space types"); + onfailed(c_str); + GodotRuntime.free(c_str); + } else { + requestReferenceSpace(); + } + }); + } + requestReferenceSpace(); + }).catch(function(error) { + const c_str = GodotRuntime.allocString(`Unable to make WebGL context compatible with WebXR: ${error}`); + onfailed(c_str); + GodotRuntime.free(c_str); + }); + }).catch(function(error) { + const c_str = GodotRuntime.allocString(`Unable to start session: ${error}`); + onfailed(c_str); + GodotRuntime.free(c_str); + }); +} + +function _godot_webxr_is_session_supported(p_session_mode, p_callback) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(177, 1, p_session_mode, p_callback); + const session_mode = GodotRuntime.parseString(p_session_mode); + const cb = GodotRuntime.get_func(p_callback); + if (navigator.xr) { + navigator.xr.isSessionSupported(session_mode).then(function(supported) { + const c_str = GodotRuntime.allocString(session_mode); + cb(c_str, supported ? 1 : 0); + GodotRuntime.free(c_str); + }); + } else { + const c_str = GodotRuntime.allocString(session_mode); + cb(c_str, 0); + GodotRuntime.free(c_str); + } +} + +function _godot_webxr_is_supported() { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(178, 1); + return !!navigator.xr; +} + +function _godot_webxr_uninitialize() { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(179, 1); + if (GodotWebXR.session) { + GodotWebXR.session.end().catch(e => {}); + } + GodotWebXR.session = null; + GodotWebXR.gl_binding = null; + GodotWebXR.layer = null; + GodotWebXR.space = null; + GodotWebXR.frame = null; + GodotWebXR.pose = null; + GodotWebXR.view_count = 1; + GodotWebXR.input_sources = new Array(16); + GodotWebXR.touches = new Array(5); + GodotWebXR.onsimpleevent = null; + GodotWebXR.monkeyPatchRequestAnimationFrame(false); + GodotWebXR.pauseResumeMainLoop(); +} + +function _godot_webxr_update_input_source(p_input_source_id, r_target_pose, r_target_ray_mode, r_touch_index, r_has_grip_pose, r_grip_pose, r_has_standard_mapping, r_button_count, r_buttons, r_axes_count, r_axes) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(180, 1, p_input_source_id, r_target_pose, r_target_ray_mode, r_touch_index, r_has_grip_pose, r_grip_pose, r_has_standard_mapping, r_button_count, r_buttons, r_axes_count, r_axes); + if (!GodotWebXR.session || !GodotWebXR.frame) { + return 0; + } + if (p_input_source_id < 0 || p_input_source_id >= GodotWebXR.input_sources.length || !GodotWebXR.input_sources[p_input_source_id]) { + return false; + } + const input_source = GodotWebXR.input_sources[p_input_source_id]; + const frame = GodotWebXR.frame; + const space = GodotWebXR.space; + const target_pose = frame.getPose(input_source.targetRaySpace, space); + if (!target_pose) { + return false; + } + const target_pose_matrix = target_pose.transform.matrix; + for (let i = 0; i < 16; i++) { + GodotRuntime.setHeapValue(r_target_pose + i * 4, target_pose_matrix[i], "float"); + } + let target_ray_mode = 0; + switch (input_source.targetRayMode) { + case "gaze": + target_ray_mode = 1; + break; + + case "tracked-pointer": + target_ray_mode = 2; + break; + + case "screen": + target_ray_mode = 3; + break; + + default: + } + GodotRuntime.setHeapValue(r_target_ray_mode, target_ray_mode, "i32"); + GodotRuntime.setHeapValue(r_touch_index, GodotWebXR.getTouchIndex(input_source), "i32"); + let has_grip_pose = false; + if (input_source.gripSpace) { + const grip_pose = frame.getPose(input_source.gripSpace, space); + if (grip_pose) { + const grip_pose_matrix = grip_pose.transform.matrix; + for (let i = 0; i < 16; i++) { + GodotRuntime.setHeapValue(r_grip_pose + i * 4, grip_pose_matrix[i], "float"); + } + has_grip_pose = true; + } + } + GodotRuntime.setHeapValue(r_has_grip_pose, has_grip_pose ? 1 : 0, "i32"); + let has_standard_mapping = false; + let button_count = 0; + let axes_count = 0; + if (input_source.gamepad) { + if (input_source.gamepad.mapping === "xr-standard") { + has_standard_mapping = true; + } + button_count = Math.min(input_source.gamepad.buttons.length, 10); + for (let i = 0; i < button_count; i++) { + GodotRuntime.setHeapValue(r_buttons + i * 4, input_source.gamepad.buttons[i].value, "float"); + } + axes_count = Math.min(input_source.gamepad.axes.length, 10); + for (let i = 0; i < axes_count; i++) { + GodotRuntime.setHeapValue(r_axes + i * 4, input_source.gamepad.axes[i], "float"); + } + } + GodotRuntime.setHeapValue(r_has_standard_mapping, has_standard_mapping ? 1 : 0, "i32"); + GodotRuntime.setHeapValue(r_button_count, button_count, "i32"); + GodotRuntime.setHeapValue(r_axes_count, axes_count, "i32"); + return true; +} + +function _godot_webxr_update_target_frame_rate(p_frame_rate) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(181, 1, p_frame_rate); + if (!GodotWebXR.session || GodotWebXR.session.updateTargetFrameRate === undefined) { + return; + } + GodotWebXR.session.updateTargetFrameRate(p_frame_rate).then(() => { + const c_str = GodotRuntime.allocString("display_refresh_rate_changed"); + GodotWebXR.onsimpleevent(c_str); + GodotRuntime.free(c_str); + }); +} + +function arraySum(array, index) { + var sum = 0; + for (var i = 0; i <= index; sum += array[i++]) {} + return sum; +} + +var MONTH_DAYS_LEAP = [ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ]; + +var MONTH_DAYS_REGULAR = [ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ]; + +function addDays(date, days) { + var newDate = new Date(date.getTime()); + while (days > 0) { + var leap = isLeapYear(newDate.getFullYear()); + var currentMonth = newDate.getMonth(); + var daysInCurrentMonth = (leap ? MONTH_DAYS_LEAP : MONTH_DAYS_REGULAR)[currentMonth]; + if (days > daysInCurrentMonth - newDate.getDate()) { + days -= daysInCurrentMonth - newDate.getDate() + 1; + newDate.setDate(1); + if (currentMonth < 11) { + newDate.setMonth(currentMonth + 1); + } else { + newDate.setMonth(0); + newDate.setFullYear(newDate.getFullYear() + 1); + } + } else { + newDate.setDate(newDate.getDate() + days); + return newDate; + } + } + return newDate; +} + +function writeArrayToMemory(array, buffer) { + assert(array.length >= 0, "writeArrayToMemory array must have a length (should be an array or typed array)"); + GROWABLE_HEAP_I8().set(array, buffer); +} + +function _strftime(s, maxsize, format, tm) { + var tm_zone = GROWABLE_HEAP_I32()[tm + 40 >> 2]; + var date = { + tm_sec: GROWABLE_HEAP_I32()[tm >> 2], + tm_min: GROWABLE_HEAP_I32()[tm + 4 >> 2], + tm_hour: GROWABLE_HEAP_I32()[tm + 8 >> 2], + tm_mday: GROWABLE_HEAP_I32()[tm + 12 >> 2], + tm_mon: GROWABLE_HEAP_I32()[tm + 16 >> 2], + tm_year: GROWABLE_HEAP_I32()[tm + 20 >> 2], + tm_wday: GROWABLE_HEAP_I32()[tm + 24 >> 2], + tm_yday: GROWABLE_HEAP_I32()[tm + 28 >> 2], + tm_isdst: GROWABLE_HEAP_I32()[tm + 32 >> 2], + tm_gmtoff: GROWABLE_HEAP_I32()[tm + 36 >> 2], + tm_zone: tm_zone ? UTF8ToString(tm_zone) : "" + }; + var pattern = UTF8ToString(format); + var EXPANSION_RULES_1 = { + "%c": "%a %b %d %H:%M:%S %Y", + "%D": "%m/%d/%y", + "%F": "%Y-%m-%d", + "%h": "%b", + "%r": "%I:%M:%S %p", + "%R": "%H:%M", + "%T": "%H:%M:%S", + "%x": "%m/%d/%y", + "%X": "%H:%M:%S", + "%Ec": "%c", + "%EC": "%C", + "%Ex": "%m/%d/%y", + "%EX": "%H:%M:%S", + "%Ey": "%y", + "%EY": "%Y", + "%Od": "%d", + "%Oe": "%e", + "%OH": "%H", + "%OI": "%I", + "%Om": "%m", + "%OM": "%M", + "%OS": "%S", + "%Ou": "%u", + "%OU": "%U", + "%OV": "%V", + "%Ow": "%w", + "%OW": "%W", + "%Oy": "%y" + }; + for (var rule in EXPANSION_RULES_1) { + pattern = pattern.replace(new RegExp(rule, "g"), EXPANSION_RULES_1[rule]); + } + var WEEKDAYS = [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ]; + var MONTHS = [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ]; + function leadingSomething(value, digits, character) { + var str = typeof value == "number" ? value.toString() : value || ""; + while (str.length < digits) { + str = character[0] + str; + } + return str; + } + function leadingNulls(value, digits) { + return leadingSomething(value, digits, "0"); + } + function compareByDay(date1, date2) { + function sgn(value) { + return value < 0 ? -1 : value > 0 ? 1 : 0; + } + var compare; + if ((compare = sgn(date1.getFullYear() - date2.getFullYear())) === 0) { + if ((compare = sgn(date1.getMonth() - date2.getMonth())) === 0) { + compare = sgn(date1.getDate() - date2.getDate()); + } + } + return compare; + } + function getFirstWeekStartDate(janFourth) { + switch (janFourth.getDay()) { + case 0: + return new Date(janFourth.getFullYear() - 1, 11, 29); + + case 1: + return janFourth; + + case 2: + return new Date(janFourth.getFullYear(), 0, 3); + + case 3: + return new Date(janFourth.getFullYear(), 0, 2); + + case 4: + return new Date(janFourth.getFullYear(), 0, 1); + + case 5: + return new Date(janFourth.getFullYear() - 1, 11, 31); + + case 6: + return new Date(janFourth.getFullYear() - 1, 11, 30); + } + } + function getWeekBasedYear(date) { + var thisDate = addDays(new Date(date.tm_year + 1900, 0, 1), date.tm_yday); + var janFourthThisYear = new Date(thisDate.getFullYear(), 0, 4); + var janFourthNextYear = new Date(thisDate.getFullYear() + 1, 0, 4); + var firstWeekStartThisYear = getFirstWeekStartDate(janFourthThisYear); + var firstWeekStartNextYear = getFirstWeekStartDate(janFourthNextYear); + if (compareByDay(firstWeekStartThisYear, thisDate) <= 0) { + if (compareByDay(firstWeekStartNextYear, thisDate) <= 0) { + return thisDate.getFullYear() + 1; + } + return thisDate.getFullYear(); + } + return thisDate.getFullYear() - 1; + } + var EXPANSION_RULES_2 = { + "%a": function(date) { + return WEEKDAYS[date.tm_wday].substring(0, 3); + }, + "%A": function(date) { + return WEEKDAYS[date.tm_wday]; + }, + "%b": function(date) { + return MONTHS[date.tm_mon].substring(0, 3); + }, + "%B": function(date) { + return MONTHS[date.tm_mon]; + }, + "%C": function(date) { + var year = date.tm_year + 1900; + return leadingNulls(year / 100 | 0, 2); + }, + "%d": function(date) { + return leadingNulls(date.tm_mday, 2); + }, + "%e": function(date) { + return leadingSomething(date.tm_mday, 2, " "); + }, + "%g": function(date) { + return getWeekBasedYear(date).toString().substring(2); + }, + "%G": function(date) { + return getWeekBasedYear(date); + }, + "%H": function(date) { + return leadingNulls(date.tm_hour, 2); + }, + "%I": function(date) { + var twelveHour = date.tm_hour; + if (twelveHour == 0) twelveHour = 12; else if (twelveHour > 12) twelveHour -= 12; + return leadingNulls(twelveHour, 2); + }, + "%j": function(date) { + return leadingNulls(date.tm_mday + arraySum(isLeapYear(date.tm_year + 1900) ? MONTH_DAYS_LEAP : MONTH_DAYS_REGULAR, date.tm_mon - 1), 3); + }, + "%m": function(date) { + return leadingNulls(date.tm_mon + 1, 2); + }, + "%M": function(date) { + return leadingNulls(date.tm_min, 2); + }, + "%n": function() { + return "\n"; + }, + "%p": function(date) { + if (date.tm_hour >= 0 && date.tm_hour < 12) { + return "AM"; + } + return "PM"; + }, + "%S": function(date) { + return leadingNulls(date.tm_sec, 2); + }, + "%t": function() { + return "\t"; + }, + "%u": function(date) { + return date.tm_wday || 7; + }, + "%U": function(date) { + var days = date.tm_yday + 7 - date.tm_wday; + return leadingNulls(Math.floor(days / 7), 2); + }, + "%V": function(date) { + var val = Math.floor((date.tm_yday + 7 - (date.tm_wday + 6) % 7) / 7); + if ((date.tm_wday + 371 - date.tm_yday - 2) % 7 <= 2) { + val++; + } + if (!val) { + val = 52; + var dec31 = (date.tm_wday + 7 - date.tm_yday - 1) % 7; + if (dec31 == 4 || dec31 == 5 && isLeapYear(date.tm_year % 400 - 1)) { + val++; + } + } else if (val == 53) { + var jan1 = (date.tm_wday + 371 - date.tm_yday) % 7; + if (jan1 != 4 && (jan1 != 3 || !isLeapYear(date.tm_year))) val = 1; + } + return leadingNulls(val, 2); + }, + "%w": function(date) { + return date.tm_wday; + }, + "%W": function(date) { + var days = date.tm_yday + 7 - (date.tm_wday + 6) % 7; + return leadingNulls(Math.floor(days / 7), 2); + }, + "%y": function(date) { + return (date.tm_year + 1900).toString().substring(2); + }, + "%Y": function(date) { + return date.tm_year + 1900; + }, + "%z": function(date) { + var off = date.tm_gmtoff; + var ahead = off >= 0; + off = Math.abs(off) / 60; + off = off / 60 * 100 + off % 60; + return (ahead ? "+" : "-") + String("0000" + off).slice(-4); + }, + "%Z": function(date) { + return date.tm_zone; + }, + "%%": function() { + return "%"; + } + }; + pattern = pattern.replace(/%%/g, "\0\0"); + for (var rule in EXPANSION_RULES_2) { + if (pattern.includes(rule)) { + pattern = pattern.replace(new RegExp(rule, "g"), EXPANSION_RULES_2[rule](date)); + } + } + pattern = pattern.replace(/\0\0/g, "%"); + var bytes = intArrayFromString(pattern, false); + if (bytes.length > maxsize) { + return 0; + } + writeArrayToMemory(bytes, s); + return bytes.length - 1; +} + +function _strftime_l(s, maxsize, format, tm, loc) { + return _strftime(s, maxsize, format, tm); +} + +function stringToUTF8OnStack(str) { + var size = lengthBytesUTF8(str) + 1; + var ret = stackAlloc(size); + stringToUTF8(str, ret, size); + return ret; +} + +function getCFunc(ident) { + var func = Module["_" + ident]; + assert(func, "Cannot call unknown function " + ident + ", make sure it is exported"); + return func; +} + +function ccall(ident, returnType, argTypes, args, opts) { + var toC = { + "string": str => { + var ret = 0; + if (str !== null && str !== undefined && str !== 0) { + ret = stringToUTF8OnStack(str); + } + return ret; + }, + "array": arr => { + var ret = stackAlloc(arr.length); + writeArrayToMemory(arr, ret); + return ret; + } + }; + function convertReturnValue(ret) { + if (returnType === "string") { + return UTF8ToString(ret); + } + if (returnType === "boolean") return Boolean(ret); + return ret; + } + var func = getCFunc(ident); + var cArgs = []; + var stack = 0; + assert(returnType !== "array", 'Return type should not be "array".'); + if (args) { + for (var i = 0; i < args.length; i++) { + var converter = toC[argTypes[i]]; + if (converter) { + if (stack === 0) stack = stackSave(); + cArgs[i] = converter(args[i]); + } else { + cArgs[i] = args[i]; + } + } + } + var ret = func.apply(null, cArgs); + function onDone(ret) { + if (stack !== 0) stackRestore(stack); + return convertReturnValue(ret); + } + ret = onDone(ret); + return ret; +} + +function cwrap(ident, returnType, argTypes, opts) { + return function() { + return ccall(ident, returnType, argTypes, arguments, opts); + }; +} + +PThread.init(); + +var FSNode = function(parent, name, mode, rdev) { + if (!parent) { + parent = this; + } + this.parent = parent; + this.mount = parent.mount; + this.mounted = null; + this.id = FS.nextInode++; + this.name = name; + this.mode = mode; + this.node_ops = {}; + this.stream_ops = {}; + this.rdev = rdev; +}; + +var readMode = 292 | 73; + +var writeMode = 146; + +Object.defineProperties(FSNode.prototype, { + read: { + get: function() { + return (this.mode & readMode) === readMode; + }, + set: function(val) { + val ? this.mode |= readMode : this.mode &= ~readMode; + } + }, + write: { + get: function() { + return (this.mode & writeMode) === writeMode; + }, + set: function(val) { + val ? this.mode |= writeMode : this.mode &= ~writeMode; + } + }, + isFolder: { + get: function() { + return FS.isDir(this.mode); + } + }, + isDevice: { + get: function() { + return FS.isChrdev(this.mode); + } + } +}); + +FS.FSNode = FSNode; + +FS.createPreloadedFile = FS_createPreloadedFile; + +FS.staticInit(); + +ERRNO_CODES = { + "EPERM": 63, + "ENOENT": 44, + "ESRCH": 71, + "EINTR": 27, + "EIO": 29, + "ENXIO": 60, + "E2BIG": 1, + "ENOEXEC": 45, + "EBADF": 8, + "ECHILD": 12, + "EAGAIN": 6, + "EWOULDBLOCK": 6, + "ENOMEM": 48, + "EACCES": 2, + "EFAULT": 21, + "ENOTBLK": 105, + "EBUSY": 10, + "EEXIST": 20, + "EXDEV": 75, + "ENODEV": 43, + "ENOTDIR": 54, + "EISDIR": 31, + "EINVAL": 28, + "ENFILE": 41, + "EMFILE": 33, + "ENOTTY": 59, + "ETXTBSY": 74, + "EFBIG": 22, + "ENOSPC": 51, + "ESPIPE": 70, + "EROFS": 69, + "EMLINK": 34, + "EPIPE": 64, + "EDOM": 18, + "ERANGE": 68, + "ENOMSG": 49, + "EIDRM": 24, + "ECHRNG": 106, + "EL2NSYNC": 156, + "EL3HLT": 107, + "EL3RST": 108, + "ELNRNG": 109, + "EUNATCH": 110, + "ENOCSI": 111, + "EL2HLT": 112, + "EDEADLK": 16, + "ENOLCK": 46, + "EBADE": 113, + "EBADR": 114, + "EXFULL": 115, + "ENOANO": 104, + "EBADRQC": 103, + "EBADSLT": 102, + "EDEADLOCK": 16, + "EBFONT": 101, + "ENOSTR": 100, + "ENODATA": 116, + "ETIME": 117, + "ENOSR": 118, + "ENONET": 119, + "ENOPKG": 120, + "EREMOTE": 121, + "ENOLINK": 47, + "EADV": 122, + "ESRMNT": 123, + "ECOMM": 124, + "EPROTO": 65, + "EMULTIHOP": 36, + "EDOTDOT": 125, + "EBADMSG": 9, + "ENOTUNIQ": 126, + "EBADFD": 127, + "EREMCHG": 128, + "ELIBACC": 129, + "ELIBBAD": 130, + "ELIBSCN": 131, + "ELIBMAX": 132, + "ELIBEXEC": 133, + "ENOSYS": 52, + "ENOTEMPTY": 55, + "ENAMETOOLONG": 37, + "ELOOP": 32, + "EOPNOTSUPP": 138, + "EPFNOSUPPORT": 139, + "ECONNRESET": 15, + "ENOBUFS": 42, + "EAFNOSUPPORT": 5, + "EPROTOTYPE": 67, + "ENOTSOCK": 57, + "ENOPROTOOPT": 50, + "ESHUTDOWN": 140, + "ECONNREFUSED": 14, + "EADDRINUSE": 3, + "ECONNABORTED": 13, + "ENETUNREACH": 40, + "ENETDOWN": 38, + "ETIMEDOUT": 73, + "EHOSTDOWN": 142, + "EHOSTUNREACH": 23, + "EINPROGRESS": 26, + "EALREADY": 7, + "EDESTADDRREQ": 17, + "EMSGSIZE": 35, + "EPROTONOSUPPORT": 66, + "ESOCKTNOSUPPORT": 137, + "EADDRNOTAVAIL": 4, + "ENETRESET": 39, + "EISCONN": 30, + "ENOTCONN": 53, + "ETOOMANYREFS": 141, + "EUSERS": 136, + "EDQUOT": 19, + "ESTALE": 72, + "ENOTSUP": 138, + "ENOMEDIUM": 148, + "EILSEQ": 25, + "EOVERFLOW": 61, + "ECANCELED": 11, + "ENOTRECOVERABLE": 56, + "EOWNERDEAD": 62, + "ESTRPIPE": 135 +}; + +var GLctx; + +Module["requestFullscreen"] = function Module_requestFullscreen(lockPointer, resizeCanvas) { + Browser.requestFullscreen(lockPointer, resizeCanvas); +}; + +Module["requestFullScreen"] = function Module_requestFullScreen() { + Browser.requestFullScreen(); +}; + +Module["requestAnimationFrame"] = function Module_requestAnimationFrame(func) { + Browser.requestAnimationFrame(func); +}; + +Module["setCanvasSize"] = function Module_setCanvasSize(width, height, noUpdates) { + Browser.setCanvasSize(width, height, noUpdates); +}; + +Module["pauseMainLoop"] = function Module_pauseMainLoop() { + Browser.mainLoop.pause(); +}; + +Module["resumeMainLoop"] = function Module_resumeMainLoop() { + Browser.mainLoop.resume(); +}; + +Module["getUserMedia"] = function Module_getUserMedia() { + Browser.getUserMedia(); +}; + +Module["createContext"] = function Module_createContext(canvas, useWebGL, setInModule, webGLContextAttributes) { + return Browser.createContext(canvas, useWebGL, setInModule, webGLContextAttributes); +}; + +var preloadedImages = {}; + +var preloadedAudios = {}; + +var miniTempWebGLIntBuffersStorage = new Int32Array(288); + +for (var i = 0; i < 288; ++i) { + miniTempWebGLIntBuffers[i] = miniTempWebGLIntBuffersStorage.subarray(0, i + 1); +} + +var miniTempWebGLFloatBuffersStorage = new Float32Array(288); + +for (var i = 0; i < 288; ++i) { + miniTempWebGLFloatBuffers[i] = miniTempWebGLFloatBuffersStorage.subarray(0, i + 1); +} + +Module["request_quit"] = function() { + GodotOS.request_quit(); +}; + +Module["onExit"] = GodotOS.cleanup; + +GodotOS._fs_sync_promise = Promise.resolve(); + +Module["initConfig"] = GodotConfig.init_config; + +Module["initFS"] = GodotFS.init; + +Module["copyToFS"] = GodotFS.copy_to_fs; + +GodotOS.atexit(function(resolve, reject) { + GodotDisplayCursor.clear(); + resolve(); +}); + +GodotOS.atexit(function(resolve, reject) { + GodotEventListeners.clear(); + resolve(); +}); + +GodotOS.atexit(function(resolve, reject) { + GodotDisplayVK.clear(); + resolve(); +}); + +GodotJSWrapper.proxies = new Map(); + +var proxiedFunctionTable = [ null, _proc_exit, exitOnMainThread, pthreadCreateProxied, ___syscall__newselect, ___syscall_accept4, ___syscall_bind, ___syscall_chdir, ___syscall_chmod, ___syscall_connect, ___syscall_faccessat, ___syscall_fchmod, ___syscall_fcntl64, ___syscall_getcwd, ___syscall_getdents64, ___syscall_getsockname, ___syscall_getsockopt, ___syscall_ioctl, ___syscall_listen, ___syscall_lstat64, ___syscall_mkdirat, ___syscall_newfstatat, ___syscall_openat, ___syscall_poll, ___syscall_readlinkat, ___syscall_recvfrom, ___syscall_renameat, ___syscall_rmdir, ___syscall_sendto, ___syscall_socket, ___syscall_stat64, ___syscall_statfs64, ___syscall_symlink, ___syscall_unlinkat, __setitimer_js, _emscripten_force_exit, setCanvasElementSizeMainThread, _emscripten_webgl_destroy_context, _emscripten_webgl_create_context_proxied, _emscripten_webgl_enable_extension, _environ_get, _environ_sizes_get, _fd_close, _fd_fdstat_get, _fd_read, _fd_seek, _fd_write, _getaddrinfo, _godot_audio_has_worklet, _godot_audio_init, _godot_audio_input_start, _godot_audio_input_stop, _godot_audio_is_available, _godot_audio_resume, _godot_audio_worklet_create, _godot_audio_worklet_start, _godot_js_config_canvas_id_get, _godot_js_config_locale_get, _godot_js_display_alert, _godot_js_display_canvas_focus, _godot_js_display_canvas_is_focused, _godot_js_display_clipboard_get, _godot_js_display_clipboard_set, _godot_js_display_cursor_is_hidden, _godot_js_display_cursor_is_locked, _godot_js_display_cursor_lock_set, _godot_js_display_cursor_set_custom_shape, _godot_js_display_cursor_set_shape, _godot_js_display_cursor_set_visible, _godot_js_display_desired_size_set, _godot_js_display_fullscreen_cb, _godot_js_display_fullscreen_exit, _godot_js_display_fullscreen_request, _godot_js_display_has_webgl, _godot_js_display_is_swap_ok_cancel, _godot_js_display_notification_cb, _godot_js_display_pixel_ratio_get, _godot_js_display_screen_dpi_get, _godot_js_display_screen_size_get, _godot_js_display_setup_canvas, _godot_js_display_size_update, _godot_js_display_touchscreen_is_available, _godot_js_display_tts_available, _godot_js_display_vk_available, _godot_js_display_vk_cb, _godot_js_display_vk_hide, _godot_js_display_vk_show, _godot_js_display_window_blur_cb, _godot_js_display_window_icon_set, _godot_js_display_window_size_get, _godot_js_display_window_title_set, _godot_js_fetch_create, _godot_js_fetch_free, _godot_js_fetch_http_status_get, _godot_js_fetch_is_chunked, _godot_js_fetch_read_chunk, _godot_js_fetch_read_headers, _godot_js_fetch_state_get, _godot_js_input_drop_files_cb, _godot_js_input_gamepad_cb, _godot_js_input_gamepad_sample, _godot_js_input_gamepad_sample_count, _godot_js_input_gamepad_sample_get, _godot_js_input_key_cb, _godot_js_input_mouse_button_cb, _godot_js_input_mouse_move_cb, _godot_js_input_mouse_wheel_cb, _godot_js_input_paste_cb, _godot_js_input_touch_cb, _godot_js_input_vibrate_handheld, _godot_js_os_download_buffer, _godot_js_os_execute, _godot_js_os_finish_async, _godot_js_os_fs_is_persistent, _godot_js_os_fs_sync, _godot_js_os_has_feature, _godot_js_os_hw_concurrency_get, _godot_js_os_request_quit_cb, _godot_js_os_shell_open, _godot_js_pwa_cb, _godot_js_pwa_update, _godot_js_rtc_datachannel_close, _godot_js_rtc_datachannel_connect, _godot_js_rtc_datachannel_destroy, _godot_js_rtc_datachannel_get_buffered_amount, _godot_js_rtc_datachannel_id_get, _godot_js_rtc_datachannel_is_negotiated, _godot_js_rtc_datachannel_is_ordered, _godot_js_rtc_datachannel_label_get, _godot_js_rtc_datachannel_max_packet_lifetime_get, _godot_js_rtc_datachannel_max_retransmits_get, _godot_js_rtc_datachannel_ready_state_get, _godot_js_rtc_datachannel_send, _godot_js_rtc_pc_close, _godot_js_rtc_pc_create, _godot_js_rtc_pc_datachannel_create, _godot_js_rtc_pc_destroy, _godot_js_rtc_pc_ice_candidate_add, _godot_js_rtc_pc_local_description_set, _godot_js_rtc_pc_offer_create, _godot_js_rtc_pc_remote_description_set, _godot_js_tts_get_voices, _godot_js_tts_is_paused, _godot_js_tts_is_speaking, _godot_js_tts_pause, _godot_js_tts_resume, _godot_js_tts_speak, _godot_js_tts_stop, _godot_js_websocket_buffered_amount, _godot_js_websocket_close, _godot_js_websocket_create, _godot_js_websocket_destroy, _godot_js_websocket_send, _godot_js_wrapper_create_cb, _godot_js_wrapper_create_object, _godot_js_wrapper_interface_get, _godot_js_wrapper_object_call, _godot_js_wrapper_object_get, _godot_js_wrapper_object_getvar, _godot_js_wrapper_object_set, _godot_js_wrapper_object_set_cb_ret, _godot_js_wrapper_object_setvar, _godot_js_wrapper_object_unref, _godot_webgl2_glFramebufferTextureMultiviewOVR, _godot_webgl2_glGetBufferSubData, _godot_webxr_get_bounds_geometry, _godot_webxr_get_color_texture, _godot_webxr_get_depth_texture, _godot_webxr_get_frame_rate, _godot_webxr_get_projection_for_view, _godot_webxr_get_render_target_size, _godot_webxr_get_supported_frame_rates, _godot_webxr_get_transform_for_view, _godot_webxr_get_velocity_texture, _godot_webxr_get_view_count, _godot_webxr_get_visibility_state, _godot_webxr_initialize, _godot_webxr_is_session_supported, _godot_webxr_is_supported, _godot_webxr_uninitialize, _godot_webxr_update_input_source, _godot_webxr_update_target_frame_rate ]; + +function checkIncomingModuleAPI() { + ignoredModuleProp("fetchSettings"); +} + +var wasmImports = { + "__assert_fail": ___assert_fail, + "__call_sighandler": ___call_sighandler, + "__dlsym": ___dlsym, + "__emscripten_init_main_thread_js": ___emscripten_init_main_thread_js, + "__emscripten_thread_cleanup": ___emscripten_thread_cleanup, + "__pthread_create_js": ___pthread_create_js, + "__syscall__newselect": ___syscall__newselect, + "__syscall_accept4": ___syscall_accept4, + "__syscall_bind": ___syscall_bind, + "__syscall_chdir": ___syscall_chdir, + "__syscall_chmod": ___syscall_chmod, + "__syscall_connect": ___syscall_connect, + "__syscall_faccessat": ___syscall_faccessat, + "__syscall_fchmod": ___syscall_fchmod, + "__syscall_fcntl64": ___syscall_fcntl64, + "__syscall_getcwd": ___syscall_getcwd, + "__syscall_getdents64": ___syscall_getdents64, + "__syscall_getsockname": ___syscall_getsockname, + "__syscall_getsockopt": ___syscall_getsockopt, + "__syscall_ioctl": ___syscall_ioctl, + "__syscall_listen": ___syscall_listen, + "__syscall_lstat64": ___syscall_lstat64, + "__syscall_mkdirat": ___syscall_mkdirat, + "__syscall_newfstatat": ___syscall_newfstatat, + "__syscall_openat": ___syscall_openat, + "__syscall_poll": ___syscall_poll, + "__syscall_readlinkat": ___syscall_readlinkat, + "__syscall_recvfrom": ___syscall_recvfrom, + "__syscall_renameat": ___syscall_renameat, + "__syscall_rmdir": ___syscall_rmdir, + "__syscall_sendto": ___syscall_sendto, + "__syscall_socket": ___syscall_socket, + "__syscall_stat64": ___syscall_stat64, + "__syscall_statfs64": ___syscall_statfs64, + "__syscall_symlink": ___syscall_symlink, + "__syscall_unlinkat": ___syscall_unlinkat, + "_emscripten_get_now_is_monotonic": __emscripten_get_now_is_monotonic, + "_emscripten_notify_mailbox_postmessage": __emscripten_notify_mailbox_postmessage, + "_emscripten_proxied_gl_context_activated_from_main_browser_thread": __emscripten_proxied_gl_context_activated_from_main_browser_thread, + "_emscripten_set_offscreencanvas_size": __emscripten_set_offscreencanvas_size, + "_emscripten_thread_mailbox_await": __emscripten_thread_mailbox_await, + "_emscripten_thread_set_strongref": __emscripten_thread_set_strongref, + "_emscripten_throw_longjmp": __emscripten_throw_longjmp, + "_gmtime_js": __gmtime_js, + "_localtime_js": __localtime_js, + "_setitimer_js": __setitimer_js, + "_tzset_js": __tzset_js, + "abort": _abort, + "dlopen": _dlopen, + "emscripten_cancel_main_loop": _emscripten_cancel_main_loop, + "emscripten_check_blocking_allowed": _emscripten_check_blocking_allowed, + "emscripten_console_error": _emscripten_console_error, + "emscripten_date_now": _emscripten_date_now, + "emscripten_exit_with_live_runtime": _emscripten_exit_with_live_runtime, + "emscripten_force_exit": _emscripten_force_exit, + "emscripten_get_now": _emscripten_get_now, + "emscripten_glActiveTexture": _emscripten_glActiveTexture, + "emscripten_glAttachShader": _emscripten_glAttachShader, + "emscripten_glBeginTransformFeedback": _emscripten_glBeginTransformFeedback, + "emscripten_glBindBuffer": _emscripten_glBindBuffer, + "emscripten_glBindBufferBase": _emscripten_glBindBufferBase, + "emscripten_glBindBufferRange": _emscripten_glBindBufferRange, + "emscripten_glBindFramebuffer": _emscripten_glBindFramebuffer, + "emscripten_glBindRenderbuffer": _emscripten_glBindRenderbuffer, + "emscripten_glBindTexture": _emscripten_glBindTexture, + "emscripten_glBindVertexArray": _emscripten_glBindVertexArray, + "emscripten_glBlendColor": _emscripten_glBlendColor, + "emscripten_glBlendEquation": _emscripten_glBlendEquation, + "emscripten_glBlendFunc": _emscripten_glBlendFunc, + "emscripten_glBlendFuncSeparate": _emscripten_glBlendFuncSeparate, + "emscripten_glBlitFramebuffer": _emscripten_glBlitFramebuffer, + "emscripten_glBufferData": _emscripten_glBufferData, + "emscripten_glBufferSubData": _emscripten_glBufferSubData, + "emscripten_glCheckFramebufferStatus": _emscripten_glCheckFramebufferStatus, + "emscripten_glClear": _emscripten_glClear, + "emscripten_glClearBufferfv": _emscripten_glClearBufferfv, + "emscripten_glClearColor": _emscripten_glClearColor, + "emscripten_glClearDepthf": _emscripten_glClearDepthf, + "emscripten_glColorMask": _emscripten_glColorMask, + "emscripten_glCompileShader": _emscripten_glCompileShader, + "emscripten_glCompressedTexImage2D": _emscripten_glCompressedTexImage2D, + "emscripten_glCopyBufferSubData": _emscripten_glCopyBufferSubData, + "emscripten_glCreateProgram": _emscripten_glCreateProgram, + "emscripten_glCreateShader": _emscripten_glCreateShader, + "emscripten_glCullFace": _emscripten_glCullFace, + "emscripten_glDeleteBuffers": _emscripten_glDeleteBuffers, + "emscripten_glDeleteFramebuffers": _emscripten_glDeleteFramebuffers, + "emscripten_glDeleteProgram": _emscripten_glDeleteProgram, + "emscripten_glDeleteQueries": _emscripten_glDeleteQueries, + "emscripten_glDeleteRenderbuffers": _emscripten_glDeleteRenderbuffers, + "emscripten_glDeleteShader": _emscripten_glDeleteShader, + "emscripten_glDeleteSync": _emscripten_glDeleteSync, + "emscripten_glDeleteTextures": _emscripten_glDeleteTextures, + "emscripten_glDeleteVertexArrays": _emscripten_glDeleteVertexArrays, + "emscripten_glDepthFunc": _emscripten_glDepthFunc, + "emscripten_glDepthMask": _emscripten_glDepthMask, + "emscripten_glDisable": _emscripten_glDisable, + "emscripten_glDisableVertexAttribArray": _emscripten_glDisableVertexAttribArray, + "emscripten_glDrawArrays": _emscripten_glDrawArrays, + "emscripten_glDrawArraysInstanced": _emscripten_glDrawArraysInstanced, + "emscripten_glDrawElements": _emscripten_glDrawElements, + "emscripten_glDrawElementsInstanced": _emscripten_glDrawElementsInstanced, + "emscripten_glEnable": _emscripten_glEnable, + "emscripten_glEnableVertexAttribArray": _emscripten_glEnableVertexAttribArray, + "emscripten_glEndTransformFeedback": _emscripten_glEndTransformFeedback, + "emscripten_glFenceSync": _emscripten_glFenceSync, + "emscripten_glFinish": _emscripten_glFinish, + "emscripten_glFramebufferRenderbuffer": _emscripten_glFramebufferRenderbuffer, + "emscripten_glFramebufferTexture2D": _emscripten_glFramebufferTexture2D, + "emscripten_glFramebufferTextureLayer": _emscripten_glFramebufferTextureLayer, + "emscripten_glFrontFace": _emscripten_glFrontFace, + "emscripten_glGenBuffers": _emscripten_glGenBuffers, + "emscripten_glGenFramebuffers": _emscripten_glGenFramebuffers, + "emscripten_glGenQueries": _emscripten_glGenQueries, + "emscripten_glGenRenderbuffers": _emscripten_glGenRenderbuffers, + "emscripten_glGenTextures": _emscripten_glGenTextures, + "emscripten_glGenVertexArrays": _emscripten_glGenVertexArrays, + "emscripten_glGenerateMipmap": _emscripten_glGenerateMipmap, + "emscripten_glGetFloatv": _emscripten_glGetFloatv, + "emscripten_glGetInteger64v": _emscripten_glGetInteger64v, + "emscripten_glGetProgramInfoLog": _emscripten_glGetProgramInfoLog, + "emscripten_glGetProgramiv": _emscripten_glGetProgramiv, + "emscripten_glGetShaderInfoLog": _emscripten_glGetShaderInfoLog, + "emscripten_glGetShaderiv": _emscripten_glGetShaderiv, + "emscripten_glGetString": _emscripten_glGetString, + "emscripten_glGetStringi": _emscripten_glGetStringi, + "emscripten_glGetSynciv": _emscripten_glGetSynciv, + "emscripten_glGetUniformBlockIndex": _emscripten_glGetUniformBlockIndex, + "emscripten_glGetUniformLocation": _emscripten_glGetUniformLocation, + "emscripten_glLinkProgram": _emscripten_glLinkProgram, + "emscripten_glPixelStorei": _emscripten_glPixelStorei, + "emscripten_glReadBuffer": _emscripten_glReadBuffer, + "emscripten_glReadPixels": _emscripten_glReadPixels, + "emscripten_glRenderbufferStorage": _emscripten_glRenderbufferStorage, + "emscripten_glScissor": _emscripten_glScissor, + "emscripten_glShaderSource": _emscripten_glShaderSource, + "emscripten_glTexImage2D": _emscripten_glTexImage2D, + "emscripten_glTexImage3D": _emscripten_glTexImage3D, + "emscripten_glTexParameterf": _emscripten_glTexParameterf, + "emscripten_glTexParameteri": _emscripten_glTexParameteri, + "emscripten_glTexStorage2D": _emscripten_glTexStorage2D, + "emscripten_glTexSubImage3D": _emscripten_glTexSubImage3D, + "emscripten_glTransformFeedbackVaryings": _emscripten_glTransformFeedbackVaryings, + "emscripten_glUniform1f": _emscripten_glUniform1f, + "emscripten_glUniform1i": _emscripten_glUniform1i, + "emscripten_glUniform1iv": _emscripten_glUniform1iv, + "emscripten_glUniform1ui": _emscripten_glUniform1ui, + "emscripten_glUniform1uiv": _emscripten_glUniform1uiv, + "emscripten_glUniform2f": _emscripten_glUniform2f, + "emscripten_glUniform2fv": _emscripten_glUniform2fv, + "emscripten_glUniform2iv": _emscripten_glUniform2iv, + "emscripten_glUniform3fv": _emscripten_glUniform3fv, + "emscripten_glUniform4f": _emscripten_glUniform4f, + "emscripten_glUniform4fv": _emscripten_glUniform4fv, + "emscripten_glUniformBlockBinding": _emscripten_glUniformBlockBinding, + "emscripten_glUniformMatrix4fv": _emscripten_glUniformMatrix4fv, + "emscripten_glUseProgram": _emscripten_glUseProgram, + "emscripten_glVertexAttrib4f": _emscripten_glVertexAttrib4f, + "emscripten_glVertexAttribDivisor": _emscripten_glVertexAttribDivisor, + "emscripten_glVertexAttribI4ui": _emscripten_glVertexAttribI4ui, + "emscripten_glVertexAttribIPointer": _emscripten_glVertexAttribIPointer, + "emscripten_glVertexAttribPointer": _emscripten_glVertexAttribPointer, + "emscripten_glViewport": _emscripten_glViewport, + "emscripten_num_logical_cores": _emscripten_num_logical_cores, + "emscripten_receive_on_main_thread_js": _emscripten_receive_on_main_thread_js, + "emscripten_resize_heap": _emscripten_resize_heap, + "emscripten_set_canvas_element_size": _emscripten_set_canvas_element_size, + "emscripten_set_main_loop": _emscripten_set_main_loop, + "emscripten_supports_offscreencanvas": _emscripten_supports_offscreencanvas, + "emscripten_webgl_destroy_context": _emscripten_webgl_destroy_context, + "emscripten_webgl_do_commit_frame": _emscripten_webgl_do_commit_frame, + "emscripten_webgl_do_create_context": _emscripten_webgl_do_create_context, + "emscripten_webgl_enable_extension": _emscripten_webgl_enable_extension, + "emscripten_webgl_init_context_attributes": _emscripten_webgl_init_context_attributes, + "emscripten_webgl_make_context_current_calling_thread": _emscripten_webgl_make_context_current_calling_thread, + "environ_get": _environ_get, + "environ_sizes_get": _environ_sizes_get, + "exit": _exit, + "fd_close": _fd_close, + "fd_fdstat_get": _fd_fdstat_get, + "fd_read": _fd_read, + "fd_seek": _fd_seek, + "fd_write": _fd_write, + "getaddrinfo": _getaddrinfo, + "getnameinfo": _getnameinfo, + "godot_audio_has_worklet": _godot_audio_has_worklet, + "godot_audio_init": _godot_audio_init, + "godot_audio_input_start": _godot_audio_input_start, + "godot_audio_input_stop": _godot_audio_input_stop, + "godot_audio_is_available": _godot_audio_is_available, + "godot_audio_resume": _godot_audio_resume, + "godot_audio_worklet_create": _godot_audio_worklet_create, + "godot_audio_worklet_start": _godot_audio_worklet_start, + "godot_audio_worklet_state_add": _godot_audio_worklet_state_add, + "godot_audio_worklet_state_get": _godot_audio_worklet_state_get, + "godot_audio_worklet_state_wait": _godot_audio_worklet_state_wait, + "godot_js_config_canvas_id_get": _godot_js_config_canvas_id_get, + "godot_js_config_locale_get": _godot_js_config_locale_get, + "godot_js_display_alert": _godot_js_display_alert, + "godot_js_display_canvas_focus": _godot_js_display_canvas_focus, + "godot_js_display_canvas_is_focused": _godot_js_display_canvas_is_focused, + "godot_js_display_clipboard_get": _godot_js_display_clipboard_get, + "godot_js_display_clipboard_set": _godot_js_display_clipboard_set, + "godot_js_display_cursor_is_hidden": _godot_js_display_cursor_is_hidden, + "godot_js_display_cursor_is_locked": _godot_js_display_cursor_is_locked, + "godot_js_display_cursor_lock_set": _godot_js_display_cursor_lock_set, + "godot_js_display_cursor_set_custom_shape": _godot_js_display_cursor_set_custom_shape, + "godot_js_display_cursor_set_shape": _godot_js_display_cursor_set_shape, + "godot_js_display_cursor_set_visible": _godot_js_display_cursor_set_visible, + "godot_js_display_desired_size_set": _godot_js_display_desired_size_set, + "godot_js_display_fullscreen_cb": _godot_js_display_fullscreen_cb, + "godot_js_display_fullscreen_exit": _godot_js_display_fullscreen_exit, + "godot_js_display_fullscreen_request": _godot_js_display_fullscreen_request, + "godot_js_display_has_webgl": _godot_js_display_has_webgl, + "godot_js_display_is_swap_ok_cancel": _godot_js_display_is_swap_ok_cancel, + "godot_js_display_notification_cb": _godot_js_display_notification_cb, + "godot_js_display_pixel_ratio_get": _godot_js_display_pixel_ratio_get, + "godot_js_display_screen_dpi_get": _godot_js_display_screen_dpi_get, + "godot_js_display_screen_size_get": _godot_js_display_screen_size_get, + "godot_js_display_setup_canvas": _godot_js_display_setup_canvas, + "godot_js_display_size_update": _godot_js_display_size_update, + "godot_js_display_touchscreen_is_available": _godot_js_display_touchscreen_is_available, + "godot_js_display_tts_available": _godot_js_display_tts_available, + "godot_js_display_vk_available": _godot_js_display_vk_available, + "godot_js_display_vk_cb": _godot_js_display_vk_cb, + "godot_js_display_vk_hide": _godot_js_display_vk_hide, + "godot_js_display_vk_show": _godot_js_display_vk_show, + "godot_js_display_window_blur_cb": _godot_js_display_window_blur_cb, + "godot_js_display_window_icon_set": _godot_js_display_window_icon_set, + "godot_js_display_window_size_get": _godot_js_display_window_size_get, + "godot_js_display_window_title_set": _godot_js_display_window_title_set, + "godot_js_eval": _godot_js_eval, + "godot_js_fetch_create": _godot_js_fetch_create, + "godot_js_fetch_free": _godot_js_fetch_free, + "godot_js_fetch_http_status_get": _godot_js_fetch_http_status_get, + "godot_js_fetch_is_chunked": _godot_js_fetch_is_chunked, + "godot_js_fetch_read_chunk": _godot_js_fetch_read_chunk, + "godot_js_fetch_read_headers": _godot_js_fetch_read_headers, + "godot_js_fetch_state_get": _godot_js_fetch_state_get, + "godot_js_input_drop_files_cb": _godot_js_input_drop_files_cb, + "godot_js_input_gamepad_cb": _godot_js_input_gamepad_cb, + "godot_js_input_gamepad_sample": _godot_js_input_gamepad_sample, + "godot_js_input_gamepad_sample_count": _godot_js_input_gamepad_sample_count, + "godot_js_input_gamepad_sample_get": _godot_js_input_gamepad_sample_get, + "godot_js_input_key_cb": _godot_js_input_key_cb, + "godot_js_input_mouse_button_cb": _godot_js_input_mouse_button_cb, + "godot_js_input_mouse_move_cb": _godot_js_input_mouse_move_cb, + "godot_js_input_mouse_wheel_cb": _godot_js_input_mouse_wheel_cb, + "godot_js_input_paste_cb": _godot_js_input_paste_cb, + "godot_js_input_touch_cb": _godot_js_input_touch_cb, + "godot_js_input_vibrate_handheld": _godot_js_input_vibrate_handheld, + "godot_js_os_download_buffer": _godot_js_os_download_buffer, + "godot_js_os_execute": _godot_js_os_execute, + "godot_js_os_finish_async": _godot_js_os_finish_async, + "godot_js_os_fs_is_persistent": _godot_js_os_fs_is_persistent, + "godot_js_os_fs_sync": _godot_js_os_fs_sync, + "godot_js_os_has_feature": _godot_js_os_has_feature, + "godot_js_os_hw_concurrency_get": _godot_js_os_hw_concurrency_get, + "godot_js_os_request_quit_cb": _godot_js_os_request_quit_cb, + "godot_js_os_shell_open": _godot_js_os_shell_open, + "godot_js_pwa_cb": _godot_js_pwa_cb, + "godot_js_pwa_update": _godot_js_pwa_update, + "godot_js_rtc_datachannel_close": _godot_js_rtc_datachannel_close, + "godot_js_rtc_datachannel_connect": _godot_js_rtc_datachannel_connect, + "godot_js_rtc_datachannel_destroy": _godot_js_rtc_datachannel_destroy, + "godot_js_rtc_datachannel_get_buffered_amount": _godot_js_rtc_datachannel_get_buffered_amount, + "godot_js_rtc_datachannel_id_get": _godot_js_rtc_datachannel_id_get, + "godot_js_rtc_datachannel_is_negotiated": _godot_js_rtc_datachannel_is_negotiated, + "godot_js_rtc_datachannel_is_ordered": _godot_js_rtc_datachannel_is_ordered, + "godot_js_rtc_datachannel_label_get": _godot_js_rtc_datachannel_label_get, + "godot_js_rtc_datachannel_max_packet_lifetime_get": _godot_js_rtc_datachannel_max_packet_lifetime_get, + "godot_js_rtc_datachannel_max_retransmits_get": _godot_js_rtc_datachannel_max_retransmits_get, + "godot_js_rtc_datachannel_protocol_get": _godot_js_rtc_datachannel_protocol_get, + "godot_js_rtc_datachannel_ready_state_get": _godot_js_rtc_datachannel_ready_state_get, + "godot_js_rtc_datachannel_send": _godot_js_rtc_datachannel_send, + "godot_js_rtc_pc_close": _godot_js_rtc_pc_close, + "godot_js_rtc_pc_create": _godot_js_rtc_pc_create, + "godot_js_rtc_pc_datachannel_create": _godot_js_rtc_pc_datachannel_create, + "godot_js_rtc_pc_destroy": _godot_js_rtc_pc_destroy, + "godot_js_rtc_pc_ice_candidate_add": _godot_js_rtc_pc_ice_candidate_add, + "godot_js_rtc_pc_local_description_set": _godot_js_rtc_pc_local_description_set, + "godot_js_rtc_pc_offer_create": _godot_js_rtc_pc_offer_create, + "godot_js_rtc_pc_remote_description_set": _godot_js_rtc_pc_remote_description_set, + "godot_js_tts_get_voices": _godot_js_tts_get_voices, + "godot_js_tts_is_paused": _godot_js_tts_is_paused, + "godot_js_tts_is_speaking": _godot_js_tts_is_speaking, + "godot_js_tts_pause": _godot_js_tts_pause, + "godot_js_tts_resume": _godot_js_tts_resume, + "godot_js_tts_speak": _godot_js_tts_speak, + "godot_js_tts_stop": _godot_js_tts_stop, + "godot_js_websocket_buffered_amount": _godot_js_websocket_buffered_amount, + "godot_js_websocket_close": _godot_js_websocket_close, + "godot_js_websocket_create": _godot_js_websocket_create, + "godot_js_websocket_destroy": _godot_js_websocket_destroy, + "godot_js_websocket_send": _godot_js_websocket_send, + "godot_js_wrapper_create_cb": _godot_js_wrapper_create_cb, + "godot_js_wrapper_create_object": _godot_js_wrapper_create_object, + "godot_js_wrapper_interface_get": _godot_js_wrapper_interface_get, + "godot_js_wrapper_object_call": _godot_js_wrapper_object_call, + "godot_js_wrapper_object_get": _godot_js_wrapper_object_get, + "godot_js_wrapper_object_getvar": _godot_js_wrapper_object_getvar, + "godot_js_wrapper_object_set": _godot_js_wrapper_object_set, + "godot_js_wrapper_object_set_cb_ret": _godot_js_wrapper_object_set_cb_ret, + "godot_js_wrapper_object_setvar": _godot_js_wrapper_object_setvar, + "godot_js_wrapper_object_unref": _godot_js_wrapper_object_unref, + "godot_webgl2_glFramebufferTextureMultiviewOVR": _godot_webgl2_glFramebufferTextureMultiviewOVR, + "godot_webgl2_glGetBufferSubData": _godot_webgl2_glGetBufferSubData, + "godot_webxr_get_bounds_geometry": _godot_webxr_get_bounds_geometry, + "godot_webxr_get_color_texture": _godot_webxr_get_color_texture, + "godot_webxr_get_depth_texture": _godot_webxr_get_depth_texture, + "godot_webxr_get_frame_rate": _godot_webxr_get_frame_rate, + "godot_webxr_get_projection_for_view": _godot_webxr_get_projection_for_view, + "godot_webxr_get_render_target_size": _godot_webxr_get_render_target_size, + "godot_webxr_get_supported_frame_rates": _godot_webxr_get_supported_frame_rates, + "godot_webxr_get_transform_for_view": _godot_webxr_get_transform_for_view, + "godot_webxr_get_velocity_texture": _godot_webxr_get_velocity_texture, + "godot_webxr_get_view_count": _godot_webxr_get_view_count, + "godot_webxr_get_visibility_state": _godot_webxr_get_visibility_state, + "godot_webxr_initialize": _godot_webxr_initialize, + "godot_webxr_is_session_supported": _godot_webxr_is_session_supported, + "godot_webxr_is_supported": _godot_webxr_is_supported, + "godot_webxr_uninitialize": _godot_webxr_uninitialize, + "godot_webxr_update_input_source": _godot_webxr_update_input_source, + "godot_webxr_update_target_frame_rate": _godot_webxr_update_target_frame_rate, + "invoke_ii": invoke_ii, + "invoke_iii": invoke_iii, + "invoke_iiii": invoke_iiii, + "invoke_iiiii": invoke_iiiii, + "invoke_iiiiii": invoke_iiiiii, + "invoke_vi": invoke_vi, + "invoke_vii": invoke_vii, + "invoke_viii": invoke_viii, + "invoke_viiii": invoke_viiii, + "invoke_viiiiiii": invoke_viiiiiii, + "invoke_viiiiiiii": invoke_viiiiiiii, + "invoke_viiij": invoke_viiij, + "memory": wasmMemory || Module["wasmMemory"], + "strftime": _strftime, + "strftime_l": _strftime_l +}; + +var asm = createWasm(); + +var ___wasm_call_ctors = createExportWrapper("__wasm_call_ctors"); + +var _emscripten_webgl_commit_frame = createExportWrapper("emscripten_webgl_commit_frame"); + +var _free = createExportWrapper("free"); + +var __Z14godot_web_mainiPPc = Module["__Z14godot_web_mainiPPc"] = createExportWrapper("_Z14godot_web_mainiPPc"); + +var _main = Module["_main"] = createExportWrapper("__main_argc_argv"); + +var _malloc = createExportWrapper("malloc"); + +var ___errno_location = createExportWrapper("__errno_location"); + +var _fflush = Module["_fflush"] = createExportWrapper("fflush"); + +var _htonl = createExportWrapper("htonl"); + +var _htons = createExportWrapper("htons"); + +var _ntohs = createExportWrapper("ntohs"); + +var __emwebxr_on_input_event = Module["__emwebxr_on_input_event"] = createExportWrapper("_emwebxr_on_input_event"); + +var __emwebxr_on_simple_event = Module["__emwebxr_on_simple_event"] = createExportWrapper("_emwebxr_on_simple_event"); + +var __emscripten_tls_init = Module["__emscripten_tls_init"] = createExportWrapper("_emscripten_tls_init"); + +var _pthread_self = Module["_pthread_self"] = function() { + return (_pthread_self = Module["_pthread_self"] = Module["asm"]["pthread_self"]).apply(null, arguments); +}; + +var _emscripten_webgl_get_current_context = createExportWrapper("emscripten_webgl_get_current_context"); + +var _emscripten_dispatch_to_thread_ = createExportWrapper("emscripten_dispatch_to_thread_"); + +var ___funcs_on_exit = createExportWrapper("__funcs_on_exit"); + +var __emscripten_thread_init = Module["__emscripten_thread_init"] = createExportWrapper("_emscripten_thread_init"); + +var __emscripten_thread_crashed = Module["__emscripten_thread_crashed"] = createExportWrapper("_emscripten_thread_crashed"); + +var _emscripten_main_thread_process_queued_calls = createExportWrapper("emscripten_main_thread_process_queued_calls"); + +var _emscripten_main_runtime_thread_id = createExportWrapper("emscripten_main_runtime_thread_id"); + +var __emscripten_run_in_main_runtime_thread_js = createExportWrapper("_emscripten_run_in_main_runtime_thread_js"); + +var _emscripten_stack_get_base = function() { + return (_emscripten_stack_get_base = Module["asm"]["emscripten_stack_get_base"]).apply(null, arguments); +}; + +var _emscripten_stack_get_end = function() { + return (_emscripten_stack_get_end = Module["asm"]["emscripten_stack_get_end"]).apply(null, arguments); +}; + +var __emscripten_thread_free_data = createExportWrapper("_emscripten_thread_free_data"); + +var __emscripten_thread_exit = Module["__emscripten_thread_exit"] = createExportWrapper("_emscripten_thread_exit"); + +var __emscripten_timeout = createExportWrapper("_emscripten_timeout"); + +var __emscripten_check_mailbox = Module["__emscripten_check_mailbox"] = createExportWrapper("_emscripten_check_mailbox"); + +var _setThrew = createExportWrapper("setThrew"); + +var _emscripten_stack_init = function() { + return (_emscripten_stack_init = Module["asm"]["emscripten_stack_init"]).apply(null, arguments); +}; + +var _emscripten_stack_set_limits = function() { + return (_emscripten_stack_set_limits = Module["asm"]["emscripten_stack_set_limits"]).apply(null, arguments); +}; + +var _emscripten_stack_get_free = function() { + return (_emscripten_stack_get_free = Module["asm"]["emscripten_stack_get_free"]).apply(null, arguments); +}; + +var stackSave = createExportWrapper("stackSave"); + +var stackRestore = createExportWrapper("stackRestore"); + +var stackAlloc = createExportWrapper("stackAlloc"); + +var _emscripten_stack_get_current = function() { + return (_emscripten_stack_get_current = Module["asm"]["emscripten_stack_get_current"]).apply(null, arguments); +}; + +var ___cxa_increment_exception_refcount = createExportWrapper("__cxa_increment_exception_refcount"); + +var ___cxa_is_pointer_type = createExportWrapper("__cxa_is_pointer_type"); + +var dynCall_vjiii = Module["dynCall_vjiii"] = createExportWrapper("dynCall_vjiii"); + +var dynCall_viiiiji = Module["dynCall_viiiiji"] = createExportWrapper("dynCall_viiiiji"); + +var dynCall_viiiiij = Module["dynCall_viiiiij"] = createExportWrapper("dynCall_viiiiij"); + +var dynCall_viiiij = Module["dynCall_viiiij"] = createExportWrapper("dynCall_viiiij"); + +var dynCall_ji = Module["dynCall_ji"] = createExportWrapper("dynCall_ji"); + +var dynCall_viiijii = Module["dynCall_viiijii"] = createExportWrapper("dynCall_viiijii"); + +var dynCall_vijiii = Module["dynCall_vijiii"] = createExportWrapper("dynCall_vijiii"); + +var dynCall_jij = Module["dynCall_jij"] = createExportWrapper("dynCall_jij"); + +var dynCall_iiij = Module["dynCall_iiij"] = createExportWrapper("dynCall_iiij"); + +var dynCall_iij = Module["dynCall_iij"] = createExportWrapper("dynCall_iij"); + +var dynCall_viij = Module["dynCall_viij"] = createExportWrapper("dynCall_viij"); + +var dynCall_jiij = Module["dynCall_jiij"] = createExportWrapper("dynCall_jiij"); + +var dynCall_jiii = Module["dynCall_jiii"] = createExportWrapper("dynCall_jiii"); + +var dynCall_jiiiiiii = Module["dynCall_jiiiiiii"] = createExportWrapper("dynCall_jiiiiiii"); + +var dynCall_jiiiii = Module["dynCall_jiiiii"] = createExportWrapper("dynCall_jiiiii"); + +var dynCall_ij = Module["dynCall_ij"] = createExportWrapper("dynCall_ij"); + +var dynCall_jiiiiiiiiii = Module["dynCall_jiiiiiiiiii"] = createExportWrapper("dynCall_jiiiiiiiiii"); + +var dynCall_jiiiiii = Module["dynCall_jiiiiii"] = createExportWrapper("dynCall_jiiiiii"); + +var dynCall_jiiiiiiii = Module["dynCall_jiiiiiiii"] = createExportWrapper("dynCall_jiiiiiiii"); + +var dynCall_jii = Module["dynCall_jii"] = createExportWrapper("dynCall_jii"); + +var dynCall_vij = Module["dynCall_vij"] = createExportWrapper("dynCall_vij"); + +var dynCall_viiij = Module["dynCall_viiij"] = createExportWrapper("dynCall_viiij"); + +var dynCall_viiiiiiij = Module["dynCall_viiiiiiij"] = createExportWrapper("dynCall_viiiiiiij"); + +var dynCall_jiji = Module["dynCall_jiji"] = createExportWrapper("dynCall_jiji"); + +var dynCall_jiiifi = Module["dynCall_jiiifi"] = createExportWrapper("dynCall_jiiifi"); + +var dynCall_jiifff = Module["dynCall_jiifff"] = createExportWrapper("dynCall_jiifff"); + +var dynCall_vijf = Module["dynCall_vijf"] = createExportWrapper("dynCall_vijf"); + +var dynCall_viiiiifiijii = Module["dynCall_viiiiifiijii"] = createExportWrapper("dynCall_viiiiifiijii"); + +var dynCall_viiiiifiiijjii = Module["dynCall_viiiiifiiijjii"] = createExportWrapper("dynCall_viiiiifiiijjii"); + +var dynCall_viiiiifiiijii = Module["dynCall_viiiiifiiijii"] = createExportWrapper("dynCall_viiiiifiiijii"); + +var dynCall_viiiiifiiiijjii = Module["dynCall_viiiiifiiiijjii"] = createExportWrapper("dynCall_viiiiifiiiijjii"); + +var dynCall_vijiiii = Module["dynCall_vijiiii"] = createExportWrapper("dynCall_vijiiii"); + +var dynCall_vijii = Module["dynCall_vijii"] = createExportWrapper("dynCall_vijii"); + +var dynCall_viijiiiiiiiii = Module["dynCall_viijiiiiiiiii"] = createExportWrapper("dynCall_viijiiiiiiiii"); + +var dynCall_viiiiiji = Module["dynCall_viiiiiji"] = createExportWrapper("dynCall_viiiiiji"); + +var dynCall_vijj = Module["dynCall_vijj"] = createExportWrapper("dynCall_vijj"); + +var dynCall_vijiiiiiidddd = Module["dynCall_vijiiiiiidddd"] = createExportWrapper("dynCall_vijiiiiiidddd"); + +var dynCall_jiiii = Module["dynCall_jiiii"] = createExportWrapper("dynCall_jiiii"); + +var dynCall_jiijiiii = Module["dynCall_jiijiiii"] = createExportWrapper("dynCall_jiijiiii"); + +var dynCall_jiiji = Module["dynCall_jiiji"] = createExportWrapper("dynCall_jiiji"); + +var dynCall_jiiiji = Module["dynCall_jiiiji"] = createExportWrapper("dynCall_jiiiji"); + +var dynCall_jiijii = Module["dynCall_jiijii"] = createExportWrapper("dynCall_jiijii"); + +var dynCall_iijiiij = Module["dynCall_iijiiij"] = createExportWrapper("dynCall_iijiiij"); + +var dynCall_jijjjiiiiijii = Module["dynCall_jijjjiiiiijii"] = createExportWrapper("dynCall_jijjjiiiiijii"); + +var dynCall_jijiiiiifiii = Module["dynCall_jijiiiiifiii"] = createExportWrapper("dynCall_jijiiiiifiii"); + +var dynCall_viijiiiiiifiii = Module["dynCall_viijiiiiiifiii"] = createExportWrapper("dynCall_viijiiiiiifiii"); + +var dynCall_viji = Module["dynCall_viji"] = createExportWrapper("dynCall_viji"); + +var dynCall_viiji = Module["dynCall_viiji"] = createExportWrapper("dynCall_viiji"); + +var dynCall_vijji = Module["dynCall_vijji"] = createExportWrapper("dynCall_vijji"); + +var dynCall_vijjii = Module["dynCall_vijjii"] = createExportWrapper("dynCall_vijjii"); + +var dynCall_fij = Module["dynCall_fij"] = createExportWrapper("dynCall_fij"); + +var dynCall_vijiffifff = Module["dynCall_vijiffifff"] = createExportWrapper("dynCall_vijiffifff"); + +var dynCall_vijff = Module["dynCall_vijff"] = createExportWrapper("dynCall_vijff"); + +var dynCall_vijiffff = Module["dynCall_vijiffff"] = createExportWrapper("dynCall_vijiffff"); + +var dynCall_vijjf = Module["dynCall_vijjf"] = createExportWrapper("dynCall_vijjf"); + +var dynCall_vijij = Module["dynCall_vijij"] = createExportWrapper("dynCall_vijij"); + +var dynCall_vijif = Module["dynCall_vijif"] = createExportWrapper("dynCall_vijif"); + +var dynCall_vijiiifi = Module["dynCall_vijiiifi"] = createExportWrapper("dynCall_vijiiifi"); + +var dynCall_vijiifi = Module["dynCall_vijiifi"] = createExportWrapper("dynCall_vijiifi"); + +var dynCall_vijiif = Module["dynCall_vijiif"] = createExportWrapper("dynCall_vijiif"); + +var dynCall_vijifi = Module["dynCall_vijifi"] = createExportWrapper("dynCall_vijifi"); + +var dynCall_vijijiii = Module["dynCall_vijijiii"] = createExportWrapper("dynCall_vijijiii"); + +var dynCall_vijijiiii = Module["dynCall_vijijiiii"] = createExportWrapper("dynCall_vijijiiii"); + +var dynCall_vijijiiiff = Module["dynCall_vijijiiiff"] = createExportWrapper("dynCall_vijijiiiff"); + +var dynCall_vijijii = Module["dynCall_vijijii"] = createExportWrapper("dynCall_vijijii"); + +var dynCall_vijiijiiiiii = Module["dynCall_vijiijiiiiii"] = createExportWrapper("dynCall_vijiijiiiiii"); + +var dynCall_vijiiij = Module["dynCall_vijiiij"] = createExportWrapper("dynCall_vijiiij"); + +var dynCall_vijiiiiiiji = Module["dynCall_vijiiiiiiji"] = createExportWrapper("dynCall_vijiiiiiiji"); + +var dynCall_vijjj = Module["dynCall_vijjj"] = createExportWrapper("dynCall_vijjj"); + +var dynCall_vijdddd = Module["dynCall_vijdddd"] = createExportWrapper("dynCall_vijdddd"); + +var dynCall_vijififi = Module["dynCall_vijififi"] = createExportWrapper("dynCall_vijififi"); + +var dynCall_iijji = Module["dynCall_iijji"] = createExportWrapper("dynCall_iijji"); + +var dynCall_viijj = Module["dynCall_viijj"] = createExportWrapper("dynCall_viijj"); + +var dynCall_iiiij = Module["dynCall_iiiij"] = createExportWrapper("dynCall_iiiij"); + +var dynCall_dij = Module["dynCall_dij"] = createExportWrapper("dynCall_dij"); + +var dynCall_vijd = Module["dynCall_vijd"] = createExportWrapper("dynCall_vijd"); + +var dynCall_viijiiii = Module["dynCall_viijiiii"] = createExportWrapper("dynCall_viijiiii"); + +var dynCall_viijiii = Module["dynCall_viijiii"] = createExportWrapper("dynCall_viijiii"); + +var dynCall_iiji = Module["dynCall_iiji"] = createExportWrapper("dynCall_iiji"); + +var dynCall_iiiijf = Module["dynCall_iiiijf"] = createExportWrapper("dynCall_iiiijf"); + +var dynCall_vijiiiii = Module["dynCall_vijiiiii"] = createExportWrapper("dynCall_vijiiiii"); + +var dynCall_viijd = Module["dynCall_viijd"] = createExportWrapper("dynCall_viijd"); + +var dynCall_diij = Module["dynCall_diij"] = createExportWrapper("dynCall_diij"); + +var dynCall_viiiji = Module["dynCall_viiiji"] = createExportWrapper("dynCall_viiiji"); + +var dynCall_viiijj = Module["dynCall_viiijj"] = createExportWrapper("dynCall_viiijj"); + +var dynCall_viijji = Module["dynCall_viijji"] = createExportWrapper("dynCall_viijji"); + +var dynCall_jiiij = Module["dynCall_jiiij"] = createExportWrapper("dynCall_jiiij"); + +var dynCall_viijii = Module["dynCall_viijii"] = createExportWrapper("dynCall_viijii"); + +var dynCall_jiijjj = Module["dynCall_jiijjj"] = createExportWrapper("dynCall_jiijjj"); + +var dynCall_jiijj = Module["dynCall_jiijj"] = createExportWrapper("dynCall_jiijj"); + +var dynCall_viiijiji = Module["dynCall_viiijiji"] = createExportWrapper("dynCall_viiijiji"); + +var dynCall_viiijjiji = Module["dynCall_viiijjiji"] = createExportWrapper("dynCall_viiijjiji"); + +var dynCall_viijiji = Module["dynCall_viijiji"] = createExportWrapper("dynCall_viijiji"); + +var dynCall_iiiiijiii = Module["dynCall_iiiiijiii"] = createExportWrapper("dynCall_iiiiijiii"); + +var dynCall_iiiiiijd = Module["dynCall_iiiiiijd"] = createExportWrapper("dynCall_iiiiiijd"); + +var dynCall_diidj = Module["dynCall_diidj"] = createExportWrapper("dynCall_diidj"); + +var dynCall_viiiijij = Module["dynCall_viiiijij"] = createExportWrapper("dynCall_viiiijij"); + +var dynCall_viiidjj = Module["dynCall_viiidjj"] = createExportWrapper("dynCall_viiidjj"); + +var dynCall_viidj = Module["dynCall_viidj"] = createExportWrapper("dynCall_viidj"); + +var dynCall_iiijj = Module["dynCall_iiijj"] = createExportWrapper("dynCall_iiijj"); + +var dynCall_jiid = Module["dynCall_jiid"] = createExportWrapper("dynCall_jiid"); + +var dynCall_viiiiddji = Module["dynCall_viiiiddji"] = createExportWrapper("dynCall_viiiiddji"); + +var dynCall_vijiiiiiiiii = Module["dynCall_vijiiiiiiiii"] = createExportWrapper("dynCall_vijiiiiiiiii"); + +var dynCall_vijiiiffi = Module["dynCall_vijiiiffi"] = createExportWrapper("dynCall_vijiiiffi"); + +var dynCall_vijiiifii = Module["dynCall_vijiiifii"] = createExportWrapper("dynCall_vijiiifii"); + +var dynCall_viijfii = Module["dynCall_viijfii"] = createExportWrapper("dynCall_viijfii"); + +var dynCall_viiiiiiiiiiijjjjjjifiiiiii = Module["dynCall_viiiiiiiiiiijjjjjjifiiiiii"] = createExportWrapper("dynCall_viiiiiiiiiiijjjjjjifiiiiii"); + +var dynCall_vijifff = Module["dynCall_vijifff"] = createExportWrapper("dynCall_vijifff"); + +var dynCall_fiji = Module["dynCall_fiji"] = createExportWrapper("dynCall_fiji"); + +var dynCall_vijiiffifffi = Module["dynCall_vijiiffifffi"] = createExportWrapper("dynCall_vijiiffifffi"); + +var dynCall_iijj = Module["dynCall_iijj"] = createExportWrapper("dynCall_iijj"); + +var dynCall_iijjfj = Module["dynCall_iijjfj"] = createExportWrapper("dynCall_iijjfj"); + +var dynCall_vijiji = Module["dynCall_vijiji"] = createExportWrapper("dynCall_vijiji"); + +var dynCall_jijii = Module["dynCall_jijii"] = createExportWrapper("dynCall_jijii"); + +var dynCall_vijid = Module["dynCall_vijid"] = createExportWrapper("dynCall_vijid"); + +var dynCall_vijiiiiii = Module["dynCall_vijiiiiii"] = createExportWrapper("dynCall_vijiiiiii"); + +var dynCall_vijiff = Module["dynCall_vijiff"] = createExportWrapper("dynCall_vijiff"); + +var dynCall_vijjjj = Module["dynCall_vijjjj"] = createExportWrapper("dynCall_vijjjj"); + +var dynCall_vijiiiiiii = Module["dynCall_vijiiiiiii"] = createExportWrapper("dynCall_vijiiiiiii"); + +var dynCall_jiiifiiiii = Module["dynCall_jiiifiiiii"] = createExportWrapper("dynCall_jiiifiiiii"); + +var dynCall_viiiifijii = Module["dynCall_viiiifijii"] = createExportWrapper("dynCall_viiiifijii"); + +var dynCall_viiiifiijjii = Module["dynCall_viiiifiijjii"] = createExportWrapper("dynCall_viiiifiijjii"); + +var dynCall_vijiiifiijii = Module["dynCall_vijiiifiijii"] = createExportWrapper("dynCall_vijiiifiijii"); + +var dynCall_vijiiifiiijjii = Module["dynCall_vijiiifiiijjii"] = createExportWrapper("dynCall_vijiiifiiijjii"); + +var dynCall_vijiiifiiijii = Module["dynCall_vijiiifiiijii"] = createExportWrapper("dynCall_vijiiifiiijii"); + +var dynCall_vijiiifiiiijjii = Module["dynCall_vijiiifiiiijjii"] = createExportWrapper("dynCall_vijiiifiiiijjii"); + +var dynCall_fijiiii = Module["dynCall_fijiiii"] = createExportWrapper("dynCall_fijiiii"); + +var dynCall_fijiiiii = Module["dynCall_fijiiiii"] = createExportWrapper("dynCall_fijiiiii"); + +var dynCall_iijii = Module["dynCall_iijii"] = createExportWrapper("dynCall_iijii"); + +var dynCall_iijiijiiiii = Module["dynCall_iijiijiiiii"] = createExportWrapper("dynCall_iijiijiiiii"); + +var dynCall_iijijiiiii = Module["dynCall_iijijiiiii"] = createExportWrapper("dynCall_iijijiiiii"); + +var dynCall_vijijj = Module["dynCall_vijijj"] = createExportWrapper("dynCall_vijijj"); + +var dynCall_vijiiijj = Module["dynCall_vijiiijj"] = createExportWrapper("dynCall_vijiiijj"); + +var dynCall_vijiijj = Module["dynCall_vijiijj"] = createExportWrapper("dynCall_vijiijj"); + +var dynCall_vijjiji = Module["dynCall_vijjiji"] = createExportWrapper("dynCall_vijjiji"); + +var dynCall_vijjiijii = Module["dynCall_vijjiijii"] = createExportWrapper("dynCall_vijjiijii"); + +var dynCall_fijii = Module["dynCall_fijii"] = createExportWrapper("dynCall_fijii"); + +var dynCall_iiiiiiij = Module["dynCall_iiiiiiij"] = createExportWrapper("dynCall_iiiiiiij"); + +var dynCall_vijiiiij = Module["dynCall_vijiiiij"] = createExportWrapper("dynCall_vijiiiij"); + +var dynCall_jijj = Module["dynCall_jijj"] = createExportWrapper("dynCall_jijj"); + +var dynCall_jiiif = Module["dynCall_jiiif"] = createExportWrapper("dynCall_jiiif"); + +var dynCall_vijfff = Module["dynCall_vijfff"] = createExportWrapper("dynCall_vijfff"); + +var dynCall_vijfiff = Module["dynCall_vijfiff"] = createExportWrapper("dynCall_vijfiff"); + +var dynCall_vijfi = Module["dynCall_vijfi"] = createExportWrapper("dynCall_vijfi"); + +var dynCall_vijffffi = Module["dynCall_vijffffi"] = createExportWrapper("dynCall_vijffffi"); + +var dynCall_vijiiffi = Module["dynCall_vijiiffi"] = createExportWrapper("dynCall_vijiiffi"); + +var dynCall_vijiifffffff = Module["dynCall_vijiifffffff"] = createExportWrapper("dynCall_vijiifffffff"); + +var dynCall_vijifiifffffifff = Module["dynCall_vijifiifffffifff"] = createExportWrapper("dynCall_vijifiifffffifff"); + +var dynCall_vijiiffffiffffj = Module["dynCall_vijiiffffiffffj"] = createExportWrapper("dynCall_vijiiffffiffffj"); + +var dynCall_vijiifff = Module["dynCall_vijiifff"] = createExportWrapper("dynCall_vijiifff"); + +var dynCall_vijiffffffff = Module["dynCall_vijiffffffff"] = createExportWrapper("dynCall_vijiffffffff"); + +var dynCall_vijiifiififff = Module["dynCall_vijiifiififff"] = createExportWrapper("dynCall_vijiifiififff"); + +var dynCall_vijifffij = Module["dynCall_vijifffij"] = createExportWrapper("dynCall_vijifffij"); + +var dynCall_viijjjiifjii = Module["dynCall_viijjjiifjii"] = createExportWrapper("dynCall_viijjjiifjii"); + +var dynCall_vijjjii = Module["dynCall_vijjjii"] = createExportWrapper("dynCall_vijjjii"); + +var dynCall_fijj = Module["dynCall_fijj"] = createExportWrapper("dynCall_fijj"); + +var dynCall_iijjiii = Module["dynCall_iijjiii"] = createExportWrapper("dynCall_iijjiii"); + +var dynCall_iiiiij = Module["dynCall_iiiiij"] = createExportWrapper("dynCall_iiiiij"); + +var dynCall_iiiiijj = Module["dynCall_iiiiijj"] = createExportWrapper("dynCall_iiiiijj"); + +var dynCall_iiiiiijj = Module["dynCall_iiiiiijj"] = createExportWrapper("dynCall_iiiiiijj"); + +function invoke_vii(index, a1, a2) { + var sp = stackSave(); + try { + getWasmTableEntry(index)(a1, a2); + } catch (e) { + stackRestore(sp); + if (e !== e + 0) throw e; + _setThrew(1, 0); + } +} + +function invoke_vi(index, a1) { + var sp = stackSave(); + try { + getWasmTableEntry(index)(a1); + } catch (e) { + stackRestore(sp); + if (e !== e + 0) throw e; + _setThrew(1, 0); + } +} + +function invoke_iiii(index, a1, a2, a3) { + var sp = stackSave(); + try { + return getWasmTableEntry(index)(a1, a2, a3); + } catch (e) { + stackRestore(sp); + if (e !== e + 0) throw e; + _setThrew(1, 0); + } +} + +function invoke_ii(index, a1) { + var sp = stackSave(); + try { + return getWasmTableEntry(index)(a1); + } catch (e) { + stackRestore(sp); + if (e !== e + 0) throw e; + _setThrew(1, 0); + } +} + +function invoke_iiiiii(index, a1, a2, a3, a4, a5) { + var sp = stackSave(); + try { + return getWasmTableEntry(index)(a1, a2, a3, a4, a5); + } catch (e) { + stackRestore(sp); + if (e !== e + 0) throw e; + _setThrew(1, 0); + } +} + +function invoke_viiii(index, a1, a2, a3, a4) { + var sp = stackSave(); + try { + getWasmTableEntry(index)(a1, a2, a3, a4); + } catch (e) { + stackRestore(sp); + if (e !== e + 0) throw e; + _setThrew(1, 0); + } +} + +function invoke_iii(index, a1, a2) { + var sp = stackSave(); + try { + return getWasmTableEntry(index)(a1, a2); + } catch (e) { + stackRestore(sp); + if (e !== e + 0) throw e; + _setThrew(1, 0); + } +} + +function invoke_iiiii(index, a1, a2, a3, a4) { + var sp = stackSave(); + try { + return getWasmTableEntry(index)(a1, a2, a3, a4); + } catch (e) { + stackRestore(sp); + if (e !== e + 0) throw e; + _setThrew(1, 0); + } +} + +function invoke_viiiiiiii(index, a1, a2, a3, a4, a5, a6, a7, a8) { + var sp = stackSave(); + try { + getWasmTableEntry(index)(a1, a2, a3, a4, a5, a6, a7, a8); + } catch (e) { + stackRestore(sp); + if (e !== e + 0) throw e; + _setThrew(1, 0); + } +} + +function invoke_viii(index, a1, a2, a3) { + var sp = stackSave(); + try { + getWasmTableEntry(index)(a1, a2, a3); + } catch (e) { + stackRestore(sp); + if (e !== e + 0) throw e; + _setThrew(1, 0); + } +} + +function invoke_viiiiiii(index, a1, a2, a3, a4, a5, a6, a7) { + var sp = stackSave(); + try { + getWasmTableEntry(index)(a1, a2, a3, a4, a5, a6, a7); + } catch (e) { + stackRestore(sp); + if (e !== e + 0) throw e; + _setThrew(1, 0); + } +} + +function invoke_viiij(index, a1, a2, a3, a4, a5) { + var sp = stackSave(); + try { + dynCall_viiij(index, a1, a2, a3, a4, a5); + } catch (e) { + stackRestore(sp); + if (e !== e + 0) throw e; + _setThrew(1, 0); + } +} + +Module["callMain"] = callMain; + +Module["keepRuntimeAlive"] = keepRuntimeAlive; + +Module["wasmMemory"] = wasmMemory; + +Module["cwrap"] = cwrap; + +Module["ExitStatus"] = ExitStatus; + +Module["PThread"] = PThread; + +var missingLibrarySymbols = [ "getHostByName", "traverseStack", "getCallstack", "emscriptenLog", "convertPCtoSourceLocation", "readEmAsmArgs", "jstoi_s", "listenOnce", "autoResumeAudioContext", "dynCallLegacy", "getDynCaller", "dynCall", "asmjsMangle", "HandleAllocator", "getNativeTypeSize", "STACK_SIZE", "STACK_ALIGN", "POINTER_SIZE", "ASSERTIONS", "writeI53ToI64Clamped", "writeI53ToI64Signaling", "writeI53ToU64Clamped", "writeI53ToU64Signaling", "convertI32PairToI53", "convertU32PairToI53", "uleb128Encode", "sigToWasmTypes", "generateFuncType", "convertJsFunctionToWasm", "getEmptyTableSlot", "updateTableMap", "getFunctionAddress", "addFunction", "removeFunction", "reallyNegative", "unSign", "strLen", "reSign", "formatString", "intArrayToString", "AsciiToString", "UTF16ToString", "stringToUTF16", "lengthBytesUTF16", "UTF32ToString", "stringToUTF32", "lengthBytesUTF32", "registerKeyEventCallback", "getBoundingClientRect", "fillMouseEventData", "registerMouseEventCallback", "registerWheelEventCallback", "registerUiEventCallback", "registerFocusEventCallback", "fillDeviceOrientationEventData", "registerDeviceOrientationEventCallback", "fillDeviceMotionEventData", "registerDeviceMotionEventCallback", "screenOrientation", "fillOrientationChangeEventData", "registerOrientationChangeEventCallback", "fillFullscreenChangeEventData", "registerFullscreenChangeEventCallback", "JSEvents_requestFullscreen", "JSEvents_resizeCanvasForFullscreen", "registerRestoreOldStyle", "hideEverythingExceptGivenElement", "restoreHiddenElements", "setLetterbox", "softFullscreenResizeWebGLRenderTarget", "doRequestFullscreen", "fillPointerlockChangeEventData", "registerPointerlockChangeEventCallback", "registerPointerlockErrorEventCallback", "requestPointerLock", "fillVisibilityChangeEventData", "registerVisibilityChangeEventCallback", "registerTouchEventCallback", "fillGamepadEventData", "registerGamepadEventCallback", "registerBeforeUnloadEventCallback", "fillBatteryEventData", "battery", "registerBatteryEventCallback", "setCanvasElementSize", "getCanvasSizeCallingThread", "getCanvasSizeMainThread", "getCanvasElementSize", "jsStackTrace", "stackTrace", "checkWasiClock", "wasiRightsToMuslOFlags", "wasiOFlagsToMuslOFlags", "createDyncallWrapper", "setImmediateWrapped", "clearImmediateWrapped", "polyfillSetImmediate", "getPromise", "makePromise", "idsToPromises", "makePromiseCallback", "ExceptionInfo", "_setNetworkCallback", "emscriptenWebGLGetUniform", "emscriptenWebGLGetVertexAttrib", "__glGetActiveAttribOrUniform", "writeGLArray", "emscripten_webgl_destroy_context_before_on_calling_thread", "registerWebGlEventCallback", "runAndAbortIfError", "SDL_unicode", "SDL_ttfContext", "SDL_audio", "GLFW_Window", "emscriptenWebGLGetIndexed", "ALLOC_NORMAL", "ALLOC_STACK", "allocate", "writeStringToMemory", "writeAsciiToMemory" ]; + +missingLibrarySymbols.forEach(missingLibrarySymbol); + +var unexportedSymbols = [ "run", "addOnPreRun", "addOnInit", "addOnPreMain", "addOnExit", "addOnPostRun", "addRunDependency", "removeRunDependency", "FS_createFolder", "FS_createPath", "FS_createDataFile", "FS_createLazyFile", "FS_createLink", "FS_createDevice", "FS_unlink", "out", "err", "abort", "stackAlloc", "stackSave", "stackRestore", "getTempRet0", "setTempRet0", "GROWABLE_HEAP_I8", "GROWABLE_HEAP_U8", "GROWABLE_HEAP_I16", "GROWABLE_HEAP_U16", "GROWABLE_HEAP_I32", "GROWABLE_HEAP_U32", "GROWABLE_HEAP_F32", "GROWABLE_HEAP_F64", "writeStackCookie", "checkStackCookie", "ptrToString", "zeroMemory", "exitJS", "getHeapMax", "emscripten_realloc_buffer", "ENV", "MONTH_DAYS_REGULAR", "MONTH_DAYS_LEAP", "MONTH_DAYS_REGULAR_CUMULATIVE", "MONTH_DAYS_LEAP_CUMULATIVE", "isLeapYear", "ydayFromDate", "arraySum", "addDays", "ERRNO_CODES", "ERRNO_MESSAGES", "setErrNo", "inetPton4", "inetNtop4", "inetPton6", "inetNtop6", "readSockaddr", "writeSockaddr", "DNS", "Protocols", "Sockets", "initRandomFill", "randomFill", "timers", "warnOnce", "UNWIND_CACHE", "readEmAsmArgsArray", "jstoi_q", "getExecutableName", "handleException", "runtimeKeepalivePush", "runtimeKeepalivePop", "callUserCallback", "maybeExit", "safeSetTimeout", "asyncLoad", "alignMemory", "mmapAlloc", "writeI53ToI64", "readI53FromI64", "readI53FromU64", "convertI32PairToI53Checked", "getCFunc", "ccall", "freeTableIndexes", "functionsInTableMap", "setValue", "getValue", "PATH", "PATH_FS", "UTF8Decoder", "UTF8ArrayToString", "UTF8ToString", "stringToUTF8Array", "stringToUTF8", "lengthBytesUTF8", "intArrayFromString", "stringToAscii", "UTF16Decoder", "stringToNewUTF8", "stringToUTF8OnStack", "writeArrayToMemory", "SYSCALLS", "getSocketFromFD", "getSocketAddress", "JSEvents", "specialHTMLTargets", "maybeCStringToJsString", "findEventTarget", "findCanvasEventTarget", "currentFullscreenStrategy", "restoreOldWindowedStyle", "setCanvasElementSizeCallingThread", "setCanvasElementSizeMainThread", "demangle", "demangleAll", "getEnvStrings", "doReadv", "doWritev", "dlopenMissingError", "promiseMap", "uncaughtExceptionCount", "exceptionLast", "exceptionCaught", "Browser", "setMainLoop", "wget", "preloadPlugins", "FS_createPreloadedFile", "FS_modeStringToFlags", "FS_getMode", "FS", "MEMFS", "TTY", "PIPEFS", "SOCKFS", "tempFixedLengthArray", "miniTempWebGLFloatBuffers", "miniTempWebGLIntBuffers", "heapObjectForWebGLType", "heapAccessShiftForWebGLHeap", "webgl_enable_ANGLE_instanced_arrays", "webgl_enable_OES_vertex_array_object", "webgl_enable_WEBGL_draw_buffers", "webgl_enable_WEBGL_multi_draw", "GL", "emscriptenWebGLGet", "computeUnpackAlignedImageSize", "colorChannelsInGlTextureFormat", "emscriptenWebGLGetTexPixelData", "__glGenObject", "webglGetUniformLocation", "webglPrepareUniformLocationsBeforeFirstUse", "webglGetLeftBracePos", "emscripten_webgl_power_preferences", "AL", "GLUT", "EGL", "GLEW", "IDBStore", "SDL", "SDL_gfx", "GLFW", "webgl_enable_WEBGL_draw_instanced_base_vertex_base_instance", "webgl_enable_WEBGL_multi_draw_instanced_base_vertex_base_instance", "allocateUTF8", "allocateUTF8OnStack", "terminateWorker", "killThread", "cleanupThread", "registerTLSInit", "cancelThread", "spawnThread", "exitOnMainThread", "proxyToMainThread", "emscripten_receive_on_main_thread_js_callArgs", "invokeEntryPoint", "checkMailbox", "GodotWebXR", "GodotWebSocket", "GodotRTCDataChannel", "GodotRTCPeerConnection", "GodotAudio", "GodotAudioWorklet", "GodotAudioScript", "GodotDisplayVK", "GodotDisplayCursor", "GodotDisplayScreen", "GodotDisplay", "GodotFetch", "IDHandler", "GodotConfig", "GodotFS", "GodotOS", "GodotEventListeners", "GodotPWA", "GodotRuntime", "GodotInputGamepads", "GodotInputDragDrop", "GodotInput", "GodotWebGL2", "GodotJSWrapper", "IDBFS" ]; + +unexportedSymbols.forEach(unexportedRuntimeSymbol); + +var calledRun; + +dependenciesFulfilled = function runCaller() { + if (!calledRun) run(); + if (!calledRun) dependenciesFulfilled = runCaller; +}; + +function callMain(args = []) { + assert(runDependencies == 0, 'cannot call main when async dependencies remain! (listen on Module["onRuntimeInitialized"])'); + assert(__ATPRERUN__.length == 0, "cannot call main when preRun functions remain to be called"); + var entryFunction = _main; + args.unshift(thisProgram); + var argc = args.length; + var argv = stackAlloc((argc + 1) * 4); + var argv_ptr = argv >> 2; + args.forEach(arg => { + GROWABLE_HEAP_I32()[argv_ptr++] = stringToUTF8OnStack(arg); + }); + GROWABLE_HEAP_I32()[argv_ptr] = 0; + try { + var ret = entryFunction(argc, argv); + exitJS(ret, true); + return ret; + } catch (e) { + return handleException(e); + } +} + +function stackCheckInit() { + assert(!ENVIRONMENT_IS_PTHREAD); + _emscripten_stack_init(); + writeStackCookie(); +} + +function run(args = arguments_) { + if (runDependencies > 0) { + return; + } + if (!ENVIRONMENT_IS_PTHREAD) stackCheckInit(); + if (ENVIRONMENT_IS_PTHREAD) { + readyPromiseResolve(Module); + initRuntime(); + startWorker(Module); + return; + } + preRun(); + if (runDependencies > 0) { + return; + } + function doRun() { + if (calledRun) return; + calledRun = true; + Module["calledRun"] = true; + if (ABORT) return; + initRuntime(); + preMain(); + readyPromiseResolve(Module); + if (Module["onRuntimeInitialized"]) Module["onRuntimeInitialized"](); + if (shouldRunNow) callMain(args); + postRun(); + } + if (Module["setStatus"]) { + Module["setStatus"]("Running..."); + setTimeout(function() { + setTimeout(function() { + Module["setStatus"](""); + }, 1); + doRun(); + }, 1); + } else { + doRun(); + } + checkStackCookie(); +} + +if (Module["preInit"]) { + if (typeof Module["preInit"] == "function") Module["preInit"] = [ Module["preInit"] ]; + while (Module["preInit"].length > 0) { + Module["preInit"].pop()(); + } +} + +var shouldRunNow = false; + +if (Module["noInitialRun"]) shouldRunNow = false; + +run(); + + + return Godot.ready +} + +); +})(); +if (typeof exports === 'object' && typeof module === 'object') + module.exports = Godot; +else if (typeof define === 'function' && define['amd']) + define([], function() { return Godot; }); +else if (typeof exports === 'object') + exports["Godot"] = Godot; + +const Features = { // eslint-disable-line no-unused-vars + /** + * Check whether WebGL is available. Optionally, specify a particular version of WebGL to check for. + * + * @param {number=} [majorVersion=1] The major WebGL version to check for. + * @returns {boolean} If the given major version of WebGL is available. + * @function Engine.isWebGLAvailable + */ + isWebGLAvailable: function (majorVersion = 1) { + try { + return !!document.createElement('canvas').getContext(['webgl', 'webgl2'][majorVersion - 1]); + } catch (e) { /* Not available */ } + return false; + }, + + /** + * Check whether the Fetch API available and supports streaming responses. + * + * @returns {boolean} If the Fetch API is available and supports streaming responses. + * @function Engine.isFetchAvailable + */ + isFetchAvailable: function () { + return 'fetch' in window && 'Response' in window && 'body' in window.Response.prototype; + }, + + /** + * Check whether the engine is running in a Secure Context. + * + * @returns {boolean} If the engine is running in a Secure Context. + * @function Engine.isSecureContext + */ + isSecureContext: function () { + return window['isSecureContext'] === true; + }, + + /** + * Check whether the engine is cross origin isolated. + * This value is dependent on Cross-Origin-Opener-Policy and Cross-Origin-Embedder-Policy headers sent by the server. + * + * @returns {boolean} If the engine is running in a Secure Context. + * @function Engine.isSecureContext + */ + isCrossOriginIsolated: function () { + return window['crossOriginIsolated'] === true; + }, + + /** + * Check whether SharedBufferArray is available. + * + * Most browsers require the page to be running in a secure context, and the + * the server to provide specific CORS headers for SharedArrayBuffer to be available. + * + * @returns {boolean} If SharedArrayBuffer is available. + * @function Engine.isSharedArrayBufferAvailable + */ + isSharedArrayBufferAvailable: function () { + return 'SharedArrayBuffer' in window; + }, + + /** + * Check whether the AudioContext supports AudioWorkletNodes. + * + * @returns {boolean} If AudioWorkletNode is available. + * @function Engine.isAudioWorkletAvailable + */ + isAudioWorkletAvailable: function () { + return 'AudioContext' in window && 'audioWorklet' in AudioContext.prototype; + }, + + /** + * Return an array of missing required features (as string). + * + * @returns {Array} A list of human-readable missing features. + * @function Engine.getMissingFeatures + */ + getMissingFeatures: function () { + const missing = []; + if (!Features.isWebGLAvailable(2)) { + missing.push('WebGL2 - Check web browser configuration and hardware support'); + } + if (!Features.isFetchAvailable()) { + missing.push('Fetch - Check web browser version'); + } + if (!Features.isSecureContext()) { + missing.push('Secure Context - Check web server configuration (use HTTPS)'); + } + if (!Features.isCrossOriginIsolated()) { + missing.push('Cross Origin Isolation - Check web server configuration (send correct headers)'); + } + if (!Features.isSharedArrayBufferAvailable()) { + missing.push('SharedArrayBuffer - Check web server configuration (send correct headers)'); + } + // Audio is normally optional since we have a dummy fallback. + return missing; + }, +}; + +const Preloader = /** @constructor */ function () { // eslint-disable-line no-unused-vars + function getTrackedResponse(response, load_status) { + function onloadprogress(reader, controller) { + return reader.read().then(function (result) { + if (load_status.done) { + return Promise.resolve(); + } + if (result.value) { + controller.enqueue(result.value); + load_status.loaded += result.value.length; + } + if (!result.done) { + return onloadprogress(reader, controller); + } + load_status.done = true; + return Promise.resolve(); + }); + } + const reader = response.body.getReader(); + return new Response(new ReadableStream({ + start: function (controller) { + onloadprogress(reader, controller).then(function () { + controller.close(); + }); + }, + }), { headers: response.headers }); + } + + function loadFetch(file, tracker, fileSize, raw) { + tracker[file] = { + total: fileSize || 0, + loaded: 0, + done: false, + }; + return fetch(file).then(function (response) { + if (!response.ok) { + return Promise.reject(new Error(`Failed loading file '${file}'`)); + } + const tr = getTrackedResponse(response, tracker[file]); + if (raw) { + return Promise.resolve(tr); + } + return tr.arrayBuffer(); + }); + } + + function retry(func, attempts = 1) { + function onerror(err) { + if (attempts <= 1) { + return Promise.reject(err); + } + return new Promise(function (resolve, reject) { + setTimeout(function () { + retry(func, attempts - 1).then(resolve).catch(reject); + }, 1000); + }); + } + return func().catch(onerror); + } + + const DOWNLOAD_ATTEMPTS_MAX = 4; + const loadingFiles = {}; + const lastProgress = { loaded: 0, total: 0 }; + let progressFunc = null; + + const animateProgress = function () { + let loaded = 0; + let total = 0; + let totalIsValid = true; + let progressIsFinal = true; + + Object.keys(loadingFiles).forEach(function (file) { + const stat = loadingFiles[file]; + if (!stat.done) { + progressIsFinal = false; + } + if (!totalIsValid || stat.total === 0) { + totalIsValid = false; + total = 0; + } else { + total += stat.total; + } + loaded += stat.loaded; + }); + if (loaded !== lastProgress.loaded || total !== lastProgress.total) { + lastProgress.loaded = loaded; + lastProgress.total = total; + if (typeof progressFunc === 'function') { + progressFunc(loaded, total); + } + } + if (!progressIsFinal) { + requestAnimationFrame(animateProgress); + } + }; + + this.animateProgress = animateProgress; + + this.setProgressFunc = function (callback) { + progressFunc = callback; + }; + + this.loadPromise = function (file, fileSize, raw = false) { + return retry(loadFetch.bind(null, file, loadingFiles, fileSize, raw), DOWNLOAD_ATTEMPTS_MAX); + }; + + this.preloadedFiles = []; + this.preload = function (pathOrBuffer, destPath, fileSize) { + let buffer = null; + if (typeof pathOrBuffer === 'string') { + const me = this; + return this.loadPromise(pathOrBuffer, fileSize).then(function (buf) { + me.preloadedFiles.push({ + path: destPath || pathOrBuffer, + buffer: buf, + }); + return Promise.resolve(); + }); + } else if (pathOrBuffer instanceof ArrayBuffer) { + buffer = new Uint8Array(pathOrBuffer); + } else if (ArrayBuffer.isView(pathOrBuffer)) { + buffer = new Uint8Array(pathOrBuffer.buffer); + } + if (buffer) { + this.preloadedFiles.push({ + path: destPath, + buffer: pathOrBuffer, + }); + return Promise.resolve(); + } + return Promise.reject(new Error('Invalid object for preloading')); + }; +}; + +/** + * An object used to configure the Engine instance based on godot export options, and to override those in custom HTML + * templates if needed. + * + * @header Engine configuration + * @summary The Engine configuration object. This is just a typedef, create it like a regular object, e.g.: + * + * ``const MyConfig = { executable: 'godot', unloadAfterInit: false }`` + * + * @typedef {Object} EngineConfig + */ +const EngineConfig = {}; // eslint-disable-line no-unused-vars + +/** + * @struct + * @constructor + * @ignore + */ +const InternalConfig = function (initConfig) { // eslint-disable-line no-unused-vars + const cfg = /** @lends {InternalConfig.prototype} */ { + /** + * Whether the unload the engine automatically after the instance is initialized. + * + * @memberof EngineConfig + * @default + * @type {boolean} + */ + unloadAfterInit: true, + /** + * The HTML DOM Canvas object to use. + * + * By default, the first canvas element in the document will be used is none is specified. + * + * @memberof EngineConfig + * @default + * @type {?HTMLCanvasElement} + */ + canvas: null, + /** + * The name of the WASM file without the extension. (Set by Godot Editor export process). + * + * @memberof EngineConfig + * @default + * @type {string} + */ + executable: '', + /** + * An alternative name for the game pck to load. The executable name is used otherwise. + * + * @memberof EngineConfig + * @default + * @type {?string} + */ + mainPack: null, + /** + * Specify a language code to select the proper localization for the game. + * + * The browser locale will be used if none is specified. See complete list of + * :ref:`supported locales `. + * + * @memberof EngineConfig + * @type {?string} + * @default + */ + locale: null, + /** + * The canvas resize policy determines how the canvas should be resized by Godot. + * + * ``0`` means Godot won't do any resizing. This is useful if you want to control the canvas size from + * javascript code in your template. + * + * ``1`` means Godot will resize the canvas on start, and when changing window size via engine functions. + * + * ``2`` means Godot will adapt the canvas size to match the whole browser window. + * + * @memberof EngineConfig + * @type {number} + * @default + */ + canvasResizePolicy: 2, + /** + * The arguments to be passed as command line arguments on startup. + * + * See :ref:`command line tutorial `. + * + * **Note**: :js:meth:`startGame ` will always add the ``--main-pack`` argument. + * + * @memberof EngineConfig + * @type {Array} + * @default + */ + args: [], + /** + * When enabled, the game canvas will automatically grab the focus when the engine starts. + * + * @memberof EngineConfig + * @type {boolean} + * @default + */ + focusCanvas: true, + /** + * When enabled, this will turn on experimental virtual keyboard support on mobile. + * + * @memberof EngineConfig + * @type {boolean} + * @default + */ + experimentalVK: false, + /** + * The progressive web app service worker to install. + * @memberof EngineConfig + * @default + * @type {string} + */ + serviceWorker: '', + /** + * @ignore + * @type {Array.} + */ + persistentPaths: ['/userfs'], + /** + * @ignore + * @type {boolean} + */ + persistentDrops: false, + /** + * @ignore + * @type {Array.} + */ + gdextensionLibs: [], + /** + * @ignore + * @type {Array.} + */ + fileSizes: [], + /** + * A callback function for handling Godot's ``OS.execute`` calls. + * + * This is for example used in the Web Editor template to switch between project manager and editor, and for running the game. + * + * @callback EngineConfig.onExecute + * @param {string} path The path that Godot's wants executed. + * @param {Array.} args The arguments of the "command" to execute. + */ + /** + * @ignore + * @type {?function(string, Array.)} + */ + onExecute: null, + /** + * A callback function for being notified when the Godot instance quits. + * + * **Note**: This function will not be called if the engine crashes or become unresponsive. + * + * @callback EngineConfig.onExit + * @param {number} status_code The status code returned by Godot on exit. + */ + /** + * @ignore + * @type {?function(number)} + */ + onExit: null, + /** + * A callback function for displaying download progress. + * + * The function is called once per frame while downloading files, so the usage of ``requestAnimationFrame()`` + * is not necessary. + * + * If the callback function receives a total amount of bytes as 0, this means that it is impossible to calculate. + * Possible reasons include: + * + * - Files are delivered with server-side chunked compression + * - Files are delivered with server-side compression on Chromium + * - Not all file downloads have started yet (usually on servers without multi-threading) + * + * @callback EngineConfig.onProgress + * @param {number} current The current amount of downloaded bytes so far. + * @param {number} total The total amount of bytes to be downloaded. + */ + /** + * @ignore + * @type {?function(number, number)} + */ + onProgress: null, + /** + * A callback function for handling the standard output stream. This method should usually only be used in debug pages. + * + * By default, ``console.log()`` is used. + * + * @callback EngineConfig.onPrint + * @param {...*} [var_args] A variadic number of arguments to be printed. + */ + /** + * @ignore + * @type {?function(...*)} + */ + onPrint: function () { + console.log.apply(console, Array.from(arguments)); // eslint-disable-line no-console + }, + /** + * A callback function for handling the standard error stream. This method should usually only be used in debug pages. + * + * By default, ``console.error()`` is used. + * + * @callback EngineConfig.onPrintError + * @param {...*} [var_args] A variadic number of arguments to be printed as errors. + */ + /** + * @ignore + * @type {?function(...*)} + */ + onPrintError: function (var_args) { + console.error.apply(console, Array.from(arguments)); // eslint-disable-line no-console + }, + }; + + /** + * @ignore + * @struct + * @constructor + * @param {EngineConfig} opts + */ + function Config(opts) { + this.update(opts); + } + + Config.prototype = cfg; + + /** + * @ignore + * @param {EngineConfig} opts + */ + Config.prototype.update = function (opts) { + const config = opts || {}; + // NOTE: We must explicitly pass the default, accessing it via + // the key will fail due to closure compiler renames. + function parse(key, def) { + if (typeof (config[key]) === 'undefined') { + return def; + } + return config[key]; + } + // Module config + this.unloadAfterInit = parse('unloadAfterInit', this.unloadAfterInit); + this.onPrintError = parse('onPrintError', this.onPrintError); + this.onPrint = parse('onPrint', this.onPrint); + this.onProgress = parse('onProgress', this.onProgress); + + // Godot config + this.canvas = parse('canvas', this.canvas); + this.executable = parse('executable', this.executable); + this.mainPack = parse('mainPack', this.mainPack); + this.locale = parse('locale', this.locale); + this.canvasResizePolicy = parse('canvasResizePolicy', this.canvasResizePolicy); + this.persistentPaths = parse('persistentPaths', this.persistentPaths); + this.persistentDrops = parse('persistentDrops', this.persistentDrops); + this.experimentalVK = parse('experimentalVK', this.experimentalVK); + this.focusCanvas = parse('focusCanvas', this.focusCanvas); + this.serviceWorker = parse('serviceWorker', this.serviceWorker); + this.gdextensionLibs = parse('gdextensionLibs', this.gdextensionLibs); + this.fileSizes = parse('fileSizes', this.fileSizes); + this.args = parse('args', this.args); + this.onExecute = parse('onExecute', this.onExecute); + this.onExit = parse('onExit', this.onExit); + }; + + /** + * @ignore + * @param {string} loadPath + * @param {Response} response + */ + Config.prototype.getModuleConfig = function (loadPath, response) { + let r = response; + return { + 'print': this.onPrint, + 'printErr': this.onPrintError, + 'thisProgram': this.executable, + 'noExitRuntime': false, + 'dynamicLibraries': [`${loadPath}.side.wasm`], + 'instantiateWasm': function (imports, onSuccess) { + function done(result) { + onSuccess(result['instance'], result['module']); + } + if (typeof (WebAssembly.instantiateStreaming) !== 'undefined') { + WebAssembly.instantiateStreaming(Promise.resolve(r), imports).then(done); + } else { + r.arrayBuffer().then(function (buffer) { + WebAssembly.instantiate(buffer, imports).then(done); + }); + } + r = null; + return {}; + }, + 'locateFile': function (path) { + if (!path.startsWith('godot.')) { + return path; + } else if (path.endsWith('.worker.js')) { + return `${loadPath}.worker.js`; + } else if (path.endsWith('.audio.worklet.js')) { + return `${loadPath}.audio.worklet.js`; + } else if (path.endsWith('.js')) { + return `${loadPath}.js`; + } else if (path.endsWith('.side.wasm')) { + return `${loadPath}.side.wasm`; + } else if (path.endsWith('.wasm')) { + return `${loadPath}.wasm`; + } + return path; + }, + }; + }; + + /** + * @ignore + * @param {function()} cleanup + */ + Config.prototype.getGodotConfig = function (cleanup) { + // Try to find a canvas + if (!(this.canvas instanceof HTMLCanvasElement)) { + const nodes = document.getElementsByTagName('canvas'); + if (nodes.length && nodes[0] instanceof HTMLCanvasElement) { + const first = nodes[0]; + this.canvas = /** @type {!HTMLCanvasElement} */ (first); + } + if (!this.canvas) { + throw new Error('No canvas found in page'); + } + } + // Canvas can grab focus on click, or key events won't work. + if (this.canvas.tabIndex < 0) { + this.canvas.tabIndex = 0; + } + + // Browser locale, or custom one if defined. + let locale = this.locale; + if (!locale) { + locale = navigator.languages ? navigator.languages[0] : navigator.language; + locale = locale.split('.')[0]; + } + locale = locale.replace('-', '_'); + const onExit = this.onExit; + + // Godot configuration. + return { + 'canvas': this.canvas, + 'canvasResizePolicy': this.canvasResizePolicy, + 'locale': locale, + 'persistentDrops': this.persistentDrops, + 'virtualKeyboard': this.experimentalVK, + 'focusCanvas': this.focusCanvas, + 'onExecute': this.onExecute, + 'onExit': function (p_code) { + cleanup(); // We always need to call the cleanup callback to free memory. + if (typeof (onExit) === 'function') { + onExit(p_code); + } + }, + }; + }; + return new Config(initConfig); +}; + +/** + * Projects exported for the Web expose the :js:class:`Engine` class to the JavaScript environment, that allows + * fine control over the engine's start-up process. + * + * This API is built in an asynchronous manner and requires basic understanding + * of `Promises `__. + * + * @module Engine + * @header Web export JavaScript reference + */ +const Engine = (function () { + const preloader = new Preloader(); + + let loadPromise = null; + let loadPath = ''; + let initPromise = null; + + /** + * @classdesc The ``Engine`` class provides methods for loading and starting exported projects on the Web. For default export + * settings, this is already part of the exported HTML page. To understand practical use of the ``Engine`` class, + * see :ref:`Custom HTML page for Web export `. + * + * @description Create a new Engine instance with the given configuration. + * + * @global + * @constructor + * @param {EngineConfig} initConfig The initial config for this instance. + */ + function Engine(initConfig) { // eslint-disable-line no-shadow + this.config = new InternalConfig(initConfig); + this.rtenv = null; + } + + /** + * Load the engine from the specified base path. + * + * @param {string} basePath Base path of the engine to load. + * @param {number=} [size=0] The file size if known. + * @returns {Promise} A Promise that resolves once the engine is loaded. + * + * @function Engine.load + */ + Engine.load = function (basePath, size) { + if (loadPromise == null) { + loadPath = basePath; + loadPromise = preloader.loadPromise(`${loadPath}.wasm`, size, true); + requestAnimationFrame(preloader.animateProgress); + } + return loadPromise; + }; + + /** + * Unload the engine to free memory. + * + * This method will be called automatically depending on the configuration. See :js:attr:`unloadAfterInit`. + * + * @function Engine.unload + */ + Engine.unload = function () { + loadPromise = null; + }; + + /** + * Safe Engine constructor, creates a new prototype for every new instance to avoid prototype pollution. + * @ignore + * @constructor + */ + function SafeEngine(initConfig) { + const proto = /** @lends Engine.prototype */ { + /** + * Initialize the engine instance. Optionally, pass the base path to the engine to load it, + * if it hasn't been loaded yet. See :js:meth:`Engine.load`. + * + * @param {string=} basePath Base path of the engine to load. + * @return {Promise} A ``Promise`` that resolves once the engine is loaded and initialized. + */ + init: function (basePath) { + if (initPromise) { + return initPromise; + } + if (loadPromise == null) { + if (!basePath) { + initPromise = Promise.reject(new Error('A base path must be provided when calling `init` and the engine is not loaded.')); + return initPromise; + } + Engine.load(basePath, this.config.fileSizes[`${basePath}.wasm`]); + } + const me = this; + function doInit(promise) { + // Care! Promise chaining is bogus with old emscripten versions. + // This caused a regression with the Mono build (which uses an older emscripten version). + // Make sure to test that when refactoring. + return new Promise(function (resolve, reject) { + promise.then(function (response) { + const cloned = new Response(response.clone().body, { 'headers': [['content-type', 'application/wasm']] }); + Godot(me.config.getModuleConfig(loadPath, cloned)).then(function (module) { + const paths = me.config.persistentPaths; + module['initFS'](paths).then(function (err) { + me.rtenv = module; + if (me.config.unloadAfterInit) { + Engine.unload(); + } + resolve(); + }); + }); + }); + }); + } + preloader.setProgressFunc(this.config.onProgress); + initPromise = doInit(loadPromise); + return initPromise; + }, + + /** + * Load a file so it is available in the instance's file system once it runs. Must be called **before** starting the + * instance. + * + * If not provided, the ``path`` is derived from the URL of the loaded file. + * + * @param {string|ArrayBuffer} file The file to preload. + * + * If a ``string`` the file will be loaded from that path. + * + * If an ``ArrayBuffer`` or a view on one, the buffer will used as the content of the file. + * + * @param {string=} path Path by which the file will be accessible. Required, if ``file`` is not a string. + * + * @returns {Promise} A Promise that resolves once the file is loaded. + */ + preloadFile: function (file, path) { + return preloader.preload(file, path, this.config.fileSizes[file]); + }, + + /** + * Start the engine instance using the given override configuration (if any). + * :js:meth:`startGame ` can be used in typical cases instead. + * + * This will initialize the instance if it is not initialized. For manual initialization, see :js:meth:`init `. + * The engine must be loaded beforehand. + * + * Fails if a canvas cannot be found on the page, or not specified in the configuration. + * + * @param {EngineConfig} override An optional configuration override. + * @return {Promise} Promise that resolves once the engine started. + */ + start: function (override) { + this.config.update(override); + const me = this; + return me.init().then(function () { + if (!me.rtenv) { + return Promise.reject(new Error('The engine must be initialized before it can be started')); + } + + let config = {}; + try { + config = me.config.getGodotConfig(function () { + me.rtenv = null; + }); + } catch (e) { + return Promise.reject(e); + } + // Godot configuration. + me.rtenv['initConfig'](config); + + // Preload GDExtension libraries. + const libs = []; + if (me.config.gdextensionLibs.length > 0 && !me.rtenv['loadDynamicLibrary']) { + return Promise.reject(new Error('GDExtension libraries are not supported by this engine version. ' + + 'Enable "Extensions Support" for your export preset and/or build your custom template with "dlink_enabled=yes".')); + } + me.config.gdextensionLibs.forEach(function (lib) { + libs.push(me.rtenv['loadDynamicLibrary'](lib, { 'loadAsync': true })); + }); + return Promise.all(libs).then(function () { + return new Promise(function (resolve, reject) { + preloader.preloadedFiles.forEach(function (file) { + me.rtenv['copyToFS'](file.path, file.buffer); + }); + preloader.preloadedFiles.length = 0; // Clear memory + me.rtenv['callMain'](me.config.args); + initPromise = null; + if (me.config.serviceWorker && 'serviceWorker' in navigator) { + navigator.serviceWorker.register(me.config.serviceWorker); + } + resolve(); + }); + }); + }); + }, + + /** + * Start the game instance using the given configuration override (if any). + * + * This will initialize the instance if it is not initialized. For manual initialization, see :js:meth:`init `. + * + * This will load the engine if it is not loaded, and preload the main pck. + * + * This method expects the initial config (or the override) to have both the :js:attr:`executable` and :js:attr:`mainPack` + * properties set (normally done by the editor during export). + * + * @param {EngineConfig} override An optional configuration override. + * @return {Promise} Promise that resolves once the game started. + */ + startGame: function (override) { + this.config.update(override); + // Add main-pack argument. + const exe = this.config.executable; + const pack = this.config.mainPack || `${exe}.pck`; + this.config.args = ['--main-pack', pack].concat(this.config.args); + // Start and init with execName as loadPath if not inited. + const me = this; + return Promise.all([ + this.init(exe), + this.preloadFile(pack, pack), + ]).then(function () { + return me.start.apply(me); + }); + }, + + /** + * Create a file at the specified ``path`` with the passed as ``buffer`` in the instance's file system. + * + * @param {string} path The location where the file will be created. + * @param {ArrayBuffer} buffer The content of the file. + */ + copyToFS: function (path, buffer) { + if (this.rtenv == null) { + throw new Error('Engine must be inited before copying files'); + } + this.rtenv['copyToFS'](path, buffer); + }, + + /** + * Request that the current instance quit. + * + * This is akin the user pressing the close button in the window manager, and will + * have no effect if the engine has crashed, or is stuck in a loop. + * + */ + requestQuit: function () { + if (this.rtenv) { + this.rtenv['request_quit'](); + } + }, + }; + + Engine.prototype = proto; + // Closure compiler exported instance methods. + Engine.prototype['init'] = Engine.prototype.init; + Engine.prototype['preloadFile'] = Engine.prototype.preloadFile; + Engine.prototype['start'] = Engine.prototype.start; + Engine.prototype['startGame'] = Engine.prototype.startGame; + Engine.prototype['copyToFS'] = Engine.prototype.copyToFS; + Engine.prototype['requestQuit'] = Engine.prototype.requestQuit; + // Also expose static methods as instance methods + Engine.prototype['load'] = Engine.load; + Engine.prototype['unload'] = Engine.unload; + return new Engine(initConfig); + } + + // Closure compiler exported static methods. + SafeEngine['load'] = Engine.load; + SafeEngine['unload'] = Engine.unload; + + // Feature-detection utilities. + SafeEngine['isWebGLAvailable'] = Features.isWebGLAvailable; + SafeEngine['isFetchAvailable'] = Features.isFetchAvailable; + SafeEngine['isSecureContext'] = Features.isSecureContext; + SafeEngine['isCrossOriginIsolated'] = Features.isCrossOriginIsolated; + SafeEngine['isSharedArrayBufferAvailable'] = Features.isSharedArrayBufferAvailable; + SafeEngine['isAudioWorkletAvailable'] = Features.isAudioWorkletAvailable; + SafeEngine['getMissingFeatures'] = Features.getMissingFeatures; + + return SafeEngine; +}()); +if (typeof window !== 'undefined') { + window['Engine'] = Engine; +} diff --git a/public/godot/index.png b/public/godot/index.png new file mode 100644 index 0000000000000000000000000000000000000000..487018a2bbe1aa13c570d5cd59d522a0bc19a13c GIT binary patch literal 323863 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 z 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ðAV@+YKuL;as}(6#UTM$1#oG_@U|w8j{Y!t=7OGga-Ip}!bJ{078O%vY zF*LYwwWxN>*8E87RF8N%g(jvD_uhJZ?}_`(fgAVT^|k~1_xI-qC7SMm{jO};r9F#9 zZ+G)fZe|>AXJ#Mb8UAwTnw79am zvAVi(@#58;;c#QPwY9yGJnru7UR}HVjz=CmaIg&R4a^jzb^3+%$G-kllzMY(=PO_N z&xTt+_m_UYTjbyT`k!CCxI*lzrkd831Ro~j=wl2J>Rq<_!t+1;oqzS2qleym>ZQwh z*8K6O|MhrVKl+#c{_ghXnaig>`pX|^(#~i9^s`St_vDR7j){bKzw@X5?%(6r%|GqyaU8Mi7jkV2qCw50l

p` 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

2Q?H0c3IbRXt5_qW zb}YC(89hX}I6dnM6rf=}KmZm&M$srB#2_q4AoNZ$Jpc)2kb7%JA}9g~#LVlSbQp%^ zaygw&-|0+KO6xS#cNn^`uH4_kQF-T#fQYo#Yh%@4px6-w3Tl-?$&5uH7q0-oU}GxD zg-ZtDk+B_gg^)n6j~*0iyhmsWIq}`YgPXT+0n7IG_SW`BOi3$cwd&&nL1&~w(1NP1 z)aahtt&Y0%%-4JrE%&|{e()M&} z6l>z9wV+kVG6go3TF%Sa^0*(cYD|$-i*)2O=T6wq&$cHUBUOfyO11*|Qj?)6Q%cKB zk$BdaaYIELf-F!Y$1LIErn)q(_Xk#;KP!U8bWnCjtyXHJeedd{v)FaRXFmT-Hv~_< z(Ho_;AGmtq#=))q!^2CLT8DDxOCE;2JPG}&A7UBoaR?c+5-I`I}TpOK>;@qA2VYqwe&6{U#Hh$>-OJdC7atQO&m%jez-~L07 zEhfjm_OCwioB!bB&2{Z`E5wB}lmyxo5mk^01VM=^_xAYomnx|wQ0{$)2n0kjiAGce zs<4nUT1$*EmIy4Y*@-P61yU)6nMI07VaZSgS){OF1R&Oh*#K#6tDzr^QzTj`0{}T^ z<_s7SltS&yP@v9~G(d(W<(_H8R6&|Bjqlri{Ixr$zxpeG{KJ3y!*!#E;aDjl6Mc!K z3wWNLn*z^*3K6{mLQ|oZ7>CX;XR}G+FdC1OF2^TF4Vm{o^2ksUYZ}j{w{G8tAuFY% zv7puN&YrR6wQH}x{^Cp1Oj}T6ZLfUfJ2<5mKJ~f%+c(1ybI3zUsI1fO(zz|^bNAp} z8vV>yU;V-F|C>*~@9{9ijos$a_dopT`ycu7AOErIH{SS}|L&iC`47JQ^rJs;Vdp77 zuksKE{c;jr7$I7dTB~i_8mN*qFy5=5f8+NuFWC5X&KUrKtRd+PZ%-5e444Hp3L)fs zmr<;6Mgiumv|;8D!o6&1trv^MYPH(j+)OEzQj}6ksdfJJT7i16OMQ2_eD|jW5tUN! z{)vbHFcB4jQVKH=Am>t9iy}EhrBvgpdtyFAxE@LbrHDXTA0yOGgAv);oG;H-eL7wC zw{9P_qk1xG-QErXri=xGt(B#kbJjH=Ry(zIRebKPaN}gTS`@G`k6Js*k<}`6tIUI7 zOUW5CF*eA&9{>#2HlCX_JDcqy=cAQen$+j^lpl%`J<+;xps=ujNysTLx(JvFO+!ur zoaA`g(>%mWV{PjsMmDF_>D}(uB6ML3$T1%;R>ecD zvDU2`X{{qV;!;ni)5-R1XSTgH84W3E4I9oRs?SPbYo~h`^Wg!;vRux;{_@M0E^Xd_ zewVVWanGPRCE}gSFSR)m=bE&%$yrpZM6YSlSUby zwv{Qm7^n+J&CXz#5-VLbP#2KsQkVxK&}eHN#(Lb_IcHTEcE{HDh@pdMloLzHlJ9@d z{qKKzgACueeFzFxxA(vBwcr2XfASs0ocz20{S&|SKYbhzT7xZsk7^(h4MvIr*yPw`jr>{qrde5*DM4w`?jL3NI?Sx9|06NDG&*CO1>Q< zB(I^w&^4O+VL3DHOMmvYuYdLVwrM=1dOH5=fA#zS-KT$d6bTWH(n;gSkNwC_v-kSv zpNTi_Xf@>X0eC-sw0KDmEmzfo1Cl!)Y<@7+k>K3e_O!T%kd|2w62-M7BGlU=hdSrTwW(3*7P zs^u`Gln_xhwFa_EYpo!}0-|tjq@}e`))

-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%0AtKbor(&d`kVhr9|IFH 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 YA37$;%P(pEJOBUy07*qoM6N<$g1X2-YybcN literal 0 HcmV?d00001 diff --git a/public/godot/index.worker.js b/public/godot/index.worker.js new file mode 100644 index 0000000..95147a2 --- /dev/null +++ b/public/godot/index.worker.js @@ -0,0 +1,161 @@ +/** + * @license + * Copyright 2015 The Emscripten Authors + * SPDX-License-Identifier: MIT + */ + +// Pthread Web Worker startup routine: +// This is the entry point file that is loaded first by each Web Worker +// that executes pthreads on the Emscripten application. + +'use strict'; + +var Module = {}; + +// Thread-local guard variable for one-time init of the JS state +var initializedJS = false; + +function assert(condition, text) { + if (!condition) abort('Assertion failed: ' + text); +} + +function threadPrintErr() { + var text = Array.prototype.slice.call(arguments).join(' '); + console.error(text); +} +function threadAlert() { + var text = Array.prototype.slice.call(arguments).join(' '); + postMessage({cmd: 'alert', text: text, threadId: Module['_pthread_self']()}); +} +// We don't need out() for now, but may need to add it if we want to use it +// here. Or, if this code all moves into the main JS, that problem will go +// away. (For now, adding it here increases code size for no benefit.) +var out = () => { throw 'out() is not defined in worker.js.'; } +var err = threadPrintErr; +self.alert = threadAlert; + +Module['instantiateWasm'] = (info, receiveInstance) => { + // Instantiate from the module posted from the main thread. + // We can just use sync instantiation in the worker. + var module = Module['wasmModule']; + // We don't need the module anymore; new threads will be spawned from the main thread. + Module['wasmModule'] = null; + var instance = new WebAssembly.Instance(module, info); + // TODO: Due to Closure regression https://github.com/google/closure-compiler/issues/3193, + // the above line no longer optimizes out down to the following line. + // When the regression is fixed, we can remove this if/else. + return receiveInstance(instance); +} + +// Turn unhandled rejected promises into errors so that the main thread will be +// notified about them. +self.onunhandledrejection = (e) => { + throw e.reason ?? e; +}; + +function handleMessage(e) { + try { + if (e.data.cmd === 'load') { // Preload command that is called once per worker to parse and load the Emscripten code. + + // Until we initialize the runtime, queue up any further incoming messages. + let messageQueue = []; + self.onmessage = (e) => messageQueue.push(e); + + // And add a callback for when the runtime is initialized. + self.startWorker = (instance) => { + Module = instance; + // Notify the main thread that this thread has loaded. + postMessage({ 'cmd': 'loaded' }); + // Process any messages that were queued before the thread was ready. + for (let msg of messageQueue) { + handleMessage(msg); + } + // Restore the real message handler. + self.onmessage = handleMessage; + }; + + // Module and memory were sent from main thread + Module['wasmModule'] = e.data.wasmModule; + + // Use `const` here to ensure that the variable is scoped only to + // that iteration, allowing safe reference from a closure. + for (const handler of e.data.handlers) { + Module[handler] = function() { + postMessage({ cmd: 'callHandler', handler, args: [...arguments] }); + } + } + + Module['wasmMemory'] = e.data.wasmMemory; + + Module['buffer'] = Module['wasmMemory'].buffer; + + Module['workerID'] = e.data.workerID; + + Module['ENVIRONMENT_IS_PTHREAD'] = true; + + if (typeof e.data.urlOrBlob == 'string') { + importScripts(e.data.urlOrBlob); + } else { + var objectUrl = URL.createObjectURL(e.data.urlOrBlob); + importScripts(objectUrl); + URL.revokeObjectURL(objectUrl); + } + Godot(Module); + } else if (e.data.cmd === 'run') { + // Pass the thread address to wasm to store it for fast access. + Module['__emscripten_thread_init'](e.data.pthread_ptr, /*isMainBrowserThread=*/0, /*isMainRuntimeThread=*/0, /*canBlock=*/1); + + // Await mailbox notifications with `Atomics.waitAsync` so we can start + // using the fast `Atomics.notify` notification path. + Module['__emscripten_thread_mailbox_await'](e.data.pthread_ptr); + + assert(e.data.pthread_ptr); + // Also call inside JS module to set up the stack frame for this pthread in JS module scope + Module['establishStackSpace'](); + Module['PThread'].receiveObjectTransfer(e.data); + Module['PThread'].threadInitTLS(); + + if (!initializedJS) { + initializedJS = true; + } + + try { + Module['invokeEntryPoint'](e.data.start_routine, e.data.arg); + } catch(ex) { + if (ex != 'unwind') { + // The pthread "crashed". Do not call `_emscripten_thread_exit` (which + // would make this thread joinable). Instead, re-throw the exception + // and let the top level handler propagate it back to the main thread. + throw ex; + } + } + } else if (e.data.cmd === 'cancel') { // Main thread is asking for a pthread_cancel() on this thread. + if (Module['_pthread_self']()) { + Module['__emscripten_thread_exit'](-1); + } + } else if (e.data.target === 'setimmediate') { + // no-op + } else if (e.data.cmd === 'checkMailbox') { + if (initializedJS) { + Module['checkMailbox'](); + } + } else if (e.data.cmd) { + // The received message looks like something that should be handled by this message + // handler, (since there is a e.data.cmd field present), but is not one of the + // recognized commands: + err('worker.js received unknown command ' + e.data.cmd); + err(e.data); + } + } catch(ex) { + err('worker.js onmessage() captured an uncaught exception: ' + ex); + if (ex && ex.stack) err(ex.stack); + if (Module['__emscripten_thread_crashed']) { + Module['__emscripten_thread_crashed'](); + } + throw ex; + } +}; + +self.onmessage = handleMessage; + + diff --git a/server.Dockerfile b/server.Dockerfile new file mode 100644 index 0000000..7ca598e --- /dev/null +++ b/server.Dockerfile @@ -0,0 +1,12 @@ + +from php:8.2-apache + +RUN apt update && \ + apt install -y postgresql-server-dev-15 && \ + docker-php-ext-install pdo_pgsql && \ + a2enmod rewrite headers + +RUN rm -rf /var/www/html && \ + ln -sf /app/public /var/www/html && \ + sed -i 's/80/8000/' /etc/apache2/ports.conf && \ + sed -i 's/80/8000/' /etc/apache2/sites-enabled/000-default.conf diff --git a/src/Command/LoginUrlCommand.php b/src/Command/LoginUrlCommand.php new file mode 100644 index 0000000..f830c00 --- /dev/null +++ b/src/Command/LoginUrlCommand.php @@ -0,0 +1,39 @@ +addArgument('auth_name', InputArgument::REQUIRED, 'Authentication name to use.'); + } + + protected function execute(InputInterface $input, OutputInterface $output): int + { + $io = new SymfonyStyle($input, $output); + $auth_name = $input->getArgument('auth_name'); + + $msg = $this->handler->encodeMessage($auth_name, "AUTH_LOGIN_SEED"); + + $io->writeln('URL: /login'); + + $io->success(""); + + return Command::SUCCESS; + } +} diff --git a/src/Controller/ClientLoaderController.php b/src/Controller/ClientLoaderController.php new file mode 100644 index 0000000..9551f7b --- /dev/null +++ b/src/Controller/ClientLoaderController.php @@ -0,0 +1,31 @@ +handler->parseMessage($slug, "AUTH_LOGIN_SEED", "5 min"); + + $size_pck = filesize("godot/index.pck"); + $size_wasm = filesize("godot/index.wasm"); + + return $this->render('client_loader/index.html.twig', + [ + 'controller_name' => $authName, + 'token' => $this->handler->encodeMessage($authName, 'AUTH_SEED'), + 'size_wasm' => $size_wasm, + 'size_pck' => $size_pck + ]); + } +} diff --git a/src/Entity/Character.php b/src/Entity/Character.php index b1bae6e..c5d63ce 100644 --- a/src/Entity/Character.php +++ b/src/Entity/Character.php @@ -167,6 +167,7 @@ class Character extends Thing } /** + * * @return Collection */ public function getTechniques(): Collection @@ -176,7 +177,7 @@ class Character extends Thing public function addTechnique(Technique $technique): static { - if (!$this->techniques->contains($technique)) { + if (! $this->techniques->contains($technique)) { $this->techniques->add($technique); } diff --git a/src/Entity/User.php b/src/Entity/User.php index 6d0051d..3350e09 100644 --- a/src/Entity/User.php +++ b/src/Entity/User.php @@ -8,6 +8,7 @@ use Doctrine\ORM\Mapping\JoinColumn; use Doctrine\ORM\Mapping\OneToOne; use Doctrine\ORM\Mapping\Table; use Symfony\Component\Security\Core\User\UserInterface; +use Symfony\Component\Serializer\Attribute\Groups; #[Entity(repositoryClass: 'App\Repository\UserRepository')] #[Table(name: '`user`')] @@ -15,18 +16,20 @@ class User extends Thing implements UserInterface { // from discord - #[ApiProperty(writable: false)] #[Column(length: 32)] + #[Groups('detail')] public string $authName; #[ApiProperty(writable: false)] #[OneToOne(inversedBy: 'owner')] #[JoinColumn(onDelete: 'cascade', nullable: true)] + #[Groups('detail')] public ?Dojo $dojo; // anonymous data used for the client #[ApiProperty()] #[Column(type: 'json')] + #[Groups('public')] public mixed $properties; public function __construct(string $authName) diff --git a/src/Security/AccessTokenHandler.php b/src/Security/AccessTokenHandler.php index 4726f30..a8e8c38 100644 --- a/src/Security/AccessTokenHandler.php +++ b/src/Security/AccessTokenHandler.php @@ -1,6 +1,7 @@ logger->info("Environment is " . $this->kernel->getEnvironment()); + + $validity = "8 hour"; + if ("dev" == $this->kernel->getEnvironment()) { + $validity = "1 year"; + } + + $tokenKeys = array( + "AUTH_SEED" => $validity + ); + + foreach ($tokenKeys as $key => $value) { + $authName = $this->parseMessage($accessToken, $key, $value); + + if ($authName !== NULL) { + return new UserBadge($authName, fn (string $id) => $this->getOrCreateUser($id)); + } + } + + throw new BadCredentialsException('Invalid credentials.'); + } + + private function getOrCreateUser(string $authName): User + { + $user = $this->userRepository->findOneByAuthName($authName); + if (NULL === $user) { + $user = new User($authName); + } + return $user; + } + + public function parseMessage(string $accessToken, string $seedKey, string $duration): ?string + { + $sign_seed = sodium_base642bin($_ENV[$seedKey], SODIUM_BASE64_VARIANT_ORIGINAL); $sign_pair = sodium_crypto_sign_seed_keypair($sign_seed); $sign_public = sodium_crypto_sign_publickey($sign_pair); $message_signed = sodium_base642bin($accessToken, SODIUM_BASE64_VARIANT_URLSAFE); $message = sodium_crypto_sign_open($message_signed, $sign_public); if ($message === FALSE) { - throw new BadCredentialsException('Invalid credentials.'); + return NULL; } $arr = explode('|', $message); @@ -38,22 +73,24 @@ class AccessTokenHandler implements AccessTokenHandlerInterface $ts = new DateTimeImmutable($arr[1], new DateTimeZone("UTC")); $now = new DateTimeImmutable("now", new DateTimeZone("UTC")); - $ts = $ts->add(DateInterval::createFromDateString('5 min')); + $ts = $ts->add(DateInterval::createFromDateString($duration)); if ($ts < $now) { throw new BadCredentialsException('Token has already expired.'); } - $auth_name = $arr[0]; - return new UserBadge($auth_name, fn (string $id) => $this->getOrCreateUser($id)); + return $arr[0]; } - private function getOrCreateUser(string $authName): User + public function encodeMessage(string $authName, string $seedKey): string { - $user = $this->userRepository->findOneByAuthName($authName); - if (NULL === $user) { - $user = new User($authName); - } - return $user; + $now = new DateTimeImmutable("now", new DateTimeZone("UTC")); + + $sign_seed = sodium_base642bin($_ENV[$seedKey], SODIUM_BASE64_VARIANT_ORIGINAL); + $sign_pair = sodium_crypto_sign_seed_keypair($sign_seed); + $sign_secret = sodium_crypto_sign_secretkey($sign_pair); + $message = sodium_crypto_sign($authName . '|' . $now->format("c"), $sign_secret); + + return sodium_bin2base64($message, SODIUM_BASE64_VARIANT_URLSAFE); } } diff --git a/src/State/TournamentRegistrationStateProcessor.php b/src/State/TournamentRegistrationStateProcessor.php index a921c30..f43adbb 100644 --- a/src/State/TournamentRegistrationStateProcessor.php +++ b/src/State/TournamentRegistrationStateProcessor.php @@ -33,9 +33,9 @@ class TournamentRegistrationStateProcessor implements ProcessorInterface throw new BadRequestException("Character is already registered!"); } - $registration->tournament->addCharacter($registration->character); - $this->em->persist($registration->tournament); - $this->em->persist($registration->character); + $tournament->addCharacter($character); + $this->em->persist($tournament); + $this->em->persist($character); $this->em->flush(); } } diff --git a/start_apache.sh b/start_apache.sh new file mode 100755 index 0000000..638a8dd --- /dev/null +++ b/start_apache.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +if ! podman inspect ag-server:latest >/dev/null 2>&1; then + podman build -f server.Dockerfile -t ag-server:latest +fi + +podman run --net=host -v $(pwd):/app -it --rm ag-server:latest diff --git a/symfony.lock b/symfony.lock index d405309..5983c6c 100644 --- a/symfony.lock +++ b/symfony.lock @@ -90,6 +90,18 @@ "tests/bootstrap.php" ] }, + "symfony/apache-pack": { + "version": "1.0", + "recipe": { + "repo": "github.com/symfony/recipes-contrib", + "branch": "main", + "version": "1.0", + "ref": "0f18b4decdf5695d692c1d0dfd65516a07a6adf1" + }, + "files": [ + "public/.htaccess" + ] + }, "symfony/console": { "version": "6.2", "recipe": { diff --git a/templates/client_loader/index.html.foo.twig b/templates/client_loader/index.html.foo.twig new file mode 100644 index 0000000..c499d6f --- /dev/null +++ b/templates/client_loader/index.html.foo.twig @@ -0,0 +1,248 @@ + + + + + + Animegame-Client + + + + + + + + HTML5 canvas appears to be unsupported in the current browser.
+ Please try updating or use a different browser. +
+

+ + + + + + diff --git a/templates/client_loader/index.html.old.twig b/templates/client_loader/index.html.old.twig new file mode 100644 index 0000000..934f689 --- /dev/null +++ b/templates/client_loader/index.html.old.twig @@ -0,0 +1,22 @@ +{% extends 'base.html.twig' %} + +{% block title %}Hello ClientLoaderController!{% endblock %} + +{% block body %} + + + +{% endblock %} diff --git a/templates/client_loader/index.html.twig b/templates/client_loader/index.html.twig new file mode 100644 index 0000000..1e4ad6c --- /dev/null +++ b/templates/client_loader/index.html.twig @@ -0,0 +1,248 @@ + + + + + + Animegame-Client + + + + + + + + HTML5 canvas appears to be unsupported in the current browser.
+ Please try updating or use a different browser. +
+
+ + + +
+ + + + + + diff --git a/tests/AbstractTest.php b/tests/AbstractTest.php index 7ce59bd..45b71ac 100644 --- a/tests/AbstractTest.php +++ b/tests/AbstractTest.php @@ -20,9 +20,9 @@ abstract class AbstractTest extends ApiTestCase self::bootKernel(); } - private static function generateAuthToken(string $authName) + private static function generateAuthToken(string $authName, string $seedKey) { - $sign_seed = sodium_base642bin($_ENV['AUTH_SEED'], SODIUM_BASE64_VARIANT_ORIGINAL); + $sign_seed = sodium_base642bin($_ENV[$seedKey], SODIUM_BASE64_VARIANT_ORIGINAL); $sign_pair = sodium_crypto_sign_seed_keypair($sign_seed); $sign_secret = sodium_crypto_sign_secretkey($sign_pair); $now = new \DateTimeImmutable("now", new DateTimeZone("UTC")); @@ -31,13 +31,13 @@ abstract class AbstractTest extends ApiTestCase return sodium_bin2base64(sodium_crypto_sign($message, $sign_secret), SODIUM_BASE64_VARIANT_URLSAFE); } - protected static function createClientWithToken($authName = "FooMan"): Client + protected static function createClientWithToken($authName = "FooMan", string $seedKey = 'AUTH_SEED'): Client { return static::createClient([], [ 'headers' => [ 'accept' => 'application/json', - 'X-AUTH-TOKEN' => static::generateAuthToken($authName) + 'X-AUTH-TOKEN' => static::generateAuthToken($authName, $seedKey) ] ]); } diff --git a/tests/UserTest.php b/tests/UserTest.php new file mode 100644 index 0000000..9d648af --- /dev/null +++ b/tests/UserTest.php @@ -0,0 +1,62 @@ +authName)->request('PATCH', $this->getIri($requestUser), + [ + 'headers' => [ + 'content-type' => 'application/merge-patch+json' + ], + 'json' => [ + 'authName' => 'foo.bar', + 'properties' => [ + 'a' => 1, + 'b' => true, + 'c' => null, + 'd' => 'text' + ] + ] + ]); + + $this->assertResponseStatusCodeSame(200); + + $this->assertEquals(1, $response->toArray()['properties']['a']); + $this->assertEquals(true, $response->toArray()['properties']['b']); + $this->assertEquals(null, $response->toArray()['properties']['c']); + $this->assertEquals('text', $response->toArray()['properties']['d']); + } + + /** + * Requirement: A user should NOT be able to update his authName + */ + public function testUpdateUserAuthnameNotPossible(): void + { + $requestUser = UserFactory::createOne(); + + $response = static::createClientWithToken($requestUser->authName)->request('PATCH', $this->getIri($requestUser), + [ + 'headers' => [ + 'content-type' => 'application/merge-patch+json' + ], + 'json' => [ + 'authName' => 'foo.bar' + ] + ]); + + $this->assertResponseStatusCodeSame(200); + + $this->assertNotEquals("foo.bar", $response->toArray()['authName']); + } +} +