summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatt Kosarek <matt.kosarek@canonical.com>2026-02-18 17:15:51 -0500
committerMatt Kosarek <matt.kosarek@canonical.com>2026-02-18 17:15:51 -0500
commit5429f265a5e47ff63363cb7c145de9198ca73c86 (patch)
tree1e601c2171897367f44bc7d39c39aa8981410e05
parent59260c4f7a265f1ad4db9e0ee5e469132cdef094 (diff)
bugfix: fixing themeing
-rw-r--r--.gitignore3
-rw-r--r--Makefile4
-rw-r--r--_posts/sitemap.org2
-rw-r--r--public/index.css10
-rw-r--r--public/posts/dec_29_2025.html18
-rw-r--r--public/posts/feed.xml2
-rw-r--r--public/posts/hello.html74
-rw-r--r--public/posts/jul_28_2025.html6
-rw-r--r--public/posts/june_08_2025.html6
-rw-r--r--public/posts/may_06_2025.html6
-rw-r--r--public/posts/sitemap.html20
-rw-r--r--public/resources/bunny.obj (renamed from themes/resources/bunny.obj)0
-rw-r--r--public/resources/grass-blade.png (renamed from themes/resources/grass-blade.png)bin314986 -> 314986 bytes
-rw-r--r--public/themes/dist/output.js3841
-rwxr-xr-xpublic/themes/dist/output.wasmbin101674 -> 0 bytes
-rwxr-xr-xthemes/dist/output.wasmbin101674 -> 101674 bytes
-rw-r--r--themes/src/spring/spring_theme.cpp346
17 files changed, 251 insertions, 4087 deletions
diff --git a/.gitignore b/.gitignore
index a8293ad..bdd8f6f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,4 +3,5 @@
.vscode
.cache
themes/dist
-.packages \ No newline at end of file
+.packages
+public/themes
diff --git a/Makefile b/Makefile
index 272d645..2491e29 100644
--- a/Makefile
+++ b/Makefile
@@ -7,7 +7,7 @@ posts:
emacs -Q --script publish.el
themes/builddir:
- meson setup themes/builddir --cross-file themes/emscripten.ini
+ meson setup themes themes/builddir --cross-file themes/emscripten.ini
themes: themes/builddir
meson compile -C themes/builddir
@@ -15,6 +15,8 @@ themes: themes/builddir
copy: posts themes
mkdir -p ./public/themes/dist
rsync -a themes/dist/ ./public/themes/dist/
+ mkdir -p ./public/themes/src/_shaders
+ rsync -a themes/src/_shaders/ ./public/themes/src/_shaders/
clean:
rm -rf public/themes
diff --git a/_posts/sitemap.org b/_posts/sitemap.org
index 4d17df1..3ea35fd 100644
--- a/_posts/sitemap.org
+++ b/_posts/sitemap.org
@@ -1,6 +1,6 @@
#+TITLE:
-#+DATE: 2026-02-18 at 17:00
+#+DATE: 2026-02-18 at 17:14
#+HTML_LINK_HOME: /
diff --git a/public/index.css b/public/index.css
index 4800826..63098f9 100644
--- a/public/index.css
+++ b/public/index.css
@@ -21,7 +21,7 @@ header > h1 {
}
header > nav {
- margin-top: 2rem;
+ margin-top: 1rem;
margin-bottom: 1rem;
padding-left: 0.25rem;
}
@@ -32,21 +32,23 @@ header > nav > ul {
list-style-type: none;
margin: 0;
padding: 0;
+ gap: 1rem;
}
header > nav > ul > li {
- padding-right: 1rem;
+ display: flex;
+ align-items: center;
}
header > nav > ul a {
text-decoration: none;
- color: blue;
+ color: darkviolet;
font-size: 1rem;
border-bottom: 1px solid transparent;
}
header > nav > ul a:hover {
- opacity: 0.7;
+ opacity: 0.8;
text-decoration: underline;
}
diff --git a/public/posts/dec_29_2025.html b/public/posts/dec_29_2025.html
index 94a3d6f..48981c7 100644
--- a/public/posts/dec_29_2025.html
+++ b/public/posts/dec_29_2025.html
@@ -29,17 +29,17 @@
</div>
</div>
<div id="content" class="content">
-<div id="outline-container-org056cf54" class="outline-2">
-<h2 id="org056cf54">What have I been up to?</h2>
-<div class="outline-text-2" id="text-org056cf54">
+<div id="outline-container-org762ecbe" class="outline-2">
+<h2 id="org762ecbe">What have I been up to?</h2>
+<div class="outline-text-2" id="text-org762ecbe">
<p>
2025 has been one busy year for me! I feel as though I've been working on a dozen things at once and have spent much of my working (and personal) days productively. Miracle finally feels like it's getting somewhere fast, the Flutter multi-window work is landing at a solid pace, and Mir is feeling like a truly solid option for Wayland compositor development. I will refrain from speaking too much on the Flutter and Mir work in this post, as those are best left in the hands of Canonical.
</p>
</div>
</div>
-<div id="outline-container-org1a29c1b" class="outline-2">
-<h2 id="org1a29c1b">Miracle Update</h2>
-<div class="outline-text-2" id="text-org1a29c1b">
+<div id="outline-container-org0499ab5" class="outline-2">
+<h2 id="org0499ab5">Miracle Update</h2>
+<div class="outline-text-2" id="text-org0499ab5">
<p>
Miracle has come a long way this past year. I now feel entirely confident using it as my daily driver, minus a few hiccups that I encounter in-between releases. A lot of great things are cooking for 2026 too,
</p>
@@ -108,9 +108,9 @@ v0.9.0 of Miracle will probably be a long time in the making. My estimate is tha
</p>
</div>
</div>
-<div id="outline-container-org5f1dca1" class="outline-2">
-<h2 id="org5f1dca1">Conclusion</h2>
-<div class="outline-text-2" id="text-org5f1dca1">
+<div id="outline-container-org719e1b4" class="outline-2">
+<h2 id="org719e1b4">Conclusion</h2>
+<div class="outline-text-2" id="text-org719e1b4">
<p>
2025 has been a whirlwind of a year, and I'm sure that 2026 won't slow down at all for me. A lot of the long term projects that I've been working on are finally coming together, and I feel as though I am on the cusp of making software that I'm truly proud of. On top of that, I am engaged! What a time to be alive :) I hope you all have a lovely New Year with your friends, family, cats, dogs, and everything else.
</p>
diff --git a/public/posts/feed.xml b/public/posts/feed.xml
index c28bcd8..d1388a0 100644
--- a/public/posts/feed.xml
+++ b/public/posts/feed.xml
@@ -5,7 +5,7 @@
<link>https://matthewkosarek.xyz/</link>
<description>The RSS feed for Matthew Kosarek's Blog</description>
<language>en-us</language>
- <lastBuildDate>Wed, 18 February 2026 17:00:00 -0400</lastBuildDate>
+ <lastBuildDate>Wed, 18 February 2026 17:14:00 -0400</lastBuildDate>
<item>
<title>Update December 29, 2025</title>
diff --git a/public/posts/hello.html b/public/posts/hello.html
index 6a1c144..629ed69 100644
--- a/public/posts/hello.html
+++ b/public/posts/hello.html
@@ -29,9 +29,9 @@
</div>
</div>
<div id="content" class="content">
-<div id="outline-container-org0cf8558" class="outline-2">
-<h2 id="org0cf8558">TLDR</h2>
-<div class="outline-text-2" id="text-org0cf8558">
+<div id="outline-container-org6bad422" class="outline-2">
+<h2 id="org6bad422">TLDR</h2>
+<div class="outline-text-2" id="text-org6bad422">
<ul class="org-ul">
<li>Create a new folder</li>
<li>Put <a href="https://raw.githubusercontent.com/mattkae/matthewkosarek-xyz/master/index.css">index.css</a>, <a href="https://raw.githubusercontent.com/mattkae/matthewkosarek-xyz/master/publish.el">publish.el</a>, and <a href="https://github.com/mattkae/matthewkosarek-xyz/blob/master/publish.sh">publish.sh</a> in the folder</li>
@@ -45,9 +45,9 @@
</ul>
</div>
</div>
-<div id="outline-container-org77a6316" class="outline-2">
-<h2 id="org77a6316">Introduction</h2>
-<div class="outline-text-2" id="text-org77a6316">
+<div id="outline-container-orgc7f45b6" class="outline-2">
+<h2 id="orgc7f45b6">Introduction</h2>
+<div class="outline-text-2" id="text-orgc7f45b6">
<p>
I've recently fallen in love with <code>org-mode</code>, specifically when I use it with <a href="https://www.orgroam.com/">org-roam</a>. I find the whole workflow of creating, tagging, and - later on - searching for information on my computer to be very elegant. On top of that, now that I have the time, I want to begin writing blog posts to better work out my thoughts. With both of these things in mind, I am again turning to the universal tool for human prospering: <code>org-mode</code>. This time, I want to see how it can help me turn a simple org file into a blog post on my website. My requirements are:
</p>
@@ -70,9 +70,9 @@ And that's pretty much it for now. Without further ado, let's jump into getting
</p>
</div>
</div>
-<div id="outline-container-orgbff2646" class="outline-2">
-<h2 id="orgbff2646">Basic HTML File</h2>
-<div class="outline-text-2" id="text-orgbff2646">
+<div id="outline-container-orga3a87b9" class="outline-2">
+<h2 id="orga3a87b9">Basic HTML File</h2>
+<div class="outline-text-2" id="text-orga3a87b9">
<p>
As a pilot, we are going to use this org file that I am currently writing (<code>hello.org</code>) as our guinea pig. The goal is to have this org file be our very first blog post.
</p>
@@ -112,9 +112,9 @@ We then do a <code>chmod +x publish.sh</code> to make it an executable and run i
</p>
</div>
</div>
-<div id="outline-container-org1fe1f78" class="outline-2">
-<h2 id="org1fe1f78">Disabling features that we don't want</h2>
-<div class="outline-text-2" id="text-org1fe1f78">
+<div id="outline-container-orgf20d464" class="outline-2">
+<h2 id="orgf20d464">Disabling features that we don't want</h2>
+<div class="outline-text-2" id="text-orgf20d464">
<p>
The next thing will be to remove some of the generated items that I didn't ask for, namely the table of contents, author, section numbers, creation time stamp, and the validation link.
</p>
@@ -143,9 +143,9 @@ The next thing will be to remove some of the generated items that I didn't ask f
</div>
</div>
</div>
-<div id="outline-container-org29c37b8" class="outline-2">
-<h2 id="org29c37b8">Styling &amp; Code Highlighting</h2>
-<div class="outline-text-2" id="text-org29c37b8">
+<div id="outline-container-orgb6e0609" class="outline-2">
+<h2 id="orgb6e0609">Styling &amp; Code Highlighting</h2>
+<div class="outline-text-2" id="text-orgb6e0609">
<p>
Next thing on our list is custom styling. This can be achieved by first installing the <code>htmlize</code> package from <code>melpa</code> / <code>elpa</code>. The EmacsWiki describes this as "a package for exporting the contents of an Emacs buffer to HTML while respecting display properties such as colors, fonts, underlining, invisibility, etc" (<a href="https://www.emacswiki.org/emacs/Htmlize">reference</a>). If used "out-of-the-box", the buffer will be exported to HTML with all of the styles inlined (e.g. if you underline something in your org file, you will generate a <code>&lt;span style="text-decoration: underline"&gt;...&lt;/span&gt;</code>). However, we are more interested in styling everything by ourselves: we don't want <code>htmlize</code> making assumptions about what underlining means to us! Luckily, <code>htmlize</code> gives us the option to export with class names instead of inline styles so that we can specify each style for ourselves.
</p>
@@ -315,9 +315,9 @@ If we run the publish again, we can see that we have full styling on our code sn
</p>
</div>
</div>
-<div id="outline-container-org31d350d" class="outline-2">
-<h2 id="org31d350d">Images</h2>
-<div class="outline-text-2" id="text-org31d350d">
+<div id="outline-container-org456f7f8" class="outline-2">
+<h2 id="org456f7f8">Images</h2>
+<div class="outline-text-2" id="text-org456f7f8">
<p>
Our first two criteria have been met! Next on the list is solving images. As an example, let's use this <a href="file:///_posts/assets/squirrel.jpg">squirrel image</a> that I found online with an open source license. The ideal situation would be:
</p>
@@ -362,16 +362,16 @@ So what's the fix here? Well, we have two options, but I am going to go with the
That's all there is to it! There are simpler ways as well, but that should do it:
</p>
-<div id="orgfe091db" class="figure">
+<div id="org04b7deb" class="figure">
<p><img src="/_posts/assets/squirrel.jpg" alt="squirrel.jpg" width="300" />
</p>
<p><span class="figure-number">Figure 1: </span>A Cute Squirrel</p>
</div>
</div>
</div>
-<div id="outline-container-org935062a" class="outline-2">
-<h2 id="org935062a">Creation Date</h2>
-<div class="outline-text-2" id="text-org935062a">
+<div id="outline-container-orgd7df786" class="outline-2">
+<h2 id="orgd7df786">Creation Date</h2>
+<div class="outline-text-2" id="text-orgd7df786">
<p>
Let's add the creation date below the title next. To start, we will modify the publish command to remove the title (<code>:with-title nil</code>) and, in its place, show a preamble bit of HTML that contains a formatted <code>div</code> with the title and the "last modified" span.z
</p>
@@ -430,9 +430,9 @@ Note that the downside of this is that the created date will change whenever you
</p>
</div>
</div>
-<div id="outline-container-orgaaeb54e" class="outline-2">
-<h2 id="orgaaeb54e">Generating the Directory</h2>
-<div class="outline-text-2" id="text-orgaaeb54e">
+<div id="outline-container-org6b24595" class="outline-2">
+<h2 id="org6b24595">Generating the Directory</h2>
+<div class="outline-text-2" id="text-org6b24595">
<p>
For every org file in my <code>_posts</code> folder, I would like to create a link to the generated HTML file at the <code>/posts.html</code> page of my website. You can think of this as the "directory" of all posts. My criteria is:
</p>
@@ -492,9 +492,9 @@ If you open the <code>sitemap.html</code> file in your browser, you will see a b
From here, you may customize it however you like. The following are my customizations.
</p>
</div>
-<div id="outline-container-org621ecf0" class="outline-3">
-<h3 id="org621ecf0">Sitemap Title</h3>
-<div class="outline-text-3" id="text-org621ecf0">
+<div id="outline-container-orgde34f50" class="outline-3">
+<h3 id="orgde34f50">Sitemap Title</h3>
+<div class="outline-text-3" id="text-orgde34f50">
<p>
I changed the title to "Matthew's Blog Posts".
</p>
@@ -516,9 +516,9 @@ I changed the title to "Matthew's Blog Posts".
</div>
</div>
</div>
-<div id="outline-container-orgf192f20" class="outline-3">
-<h3 id="orgf192f20">Format blog entries in the list</h3>
-<div class="outline-text-3" id="text-orgf192f20">
+<div id="outline-container-org8eecd95" class="outline-3">
+<h3 id="org8eecd95">Format blog entries in the list</h3>
+<div class="outline-text-3" id="text-org8eecd95">
<p>
I like to include the creation date on the blog posts. To do this, we can use <code>org-publish-find-property</code> to find the date property of the org file. Afterward, we can format a string that includes our formatted timestamp and the <code>org-publish-sitemap-default-entry</code>, which is just a link with the title of the post.
</p>
@@ -539,9 +539,9 @@ I like to include the creation date on the blog posts. To do this, we can use <c
</div>
</div>
</div>
-<div id="outline-container-orgac02911" class="outline-2">
-<h2 id="orgac02911">Tags &amp; Filtering</h2>
-<div class="outline-text-2" id="text-orgac02911">
+<div id="outline-container-orgcb3d39d" class="outline-2">
+<h2 id="orgcb3d39d">Tags &amp; Filtering</h2>
+<div class="outline-text-2" id="text-orgcb3d39d">
<p>
I use <a href="https://www.orgroam.com/">Org-roam</a> for all of my note-taking and, in the next blog post, I plan to demonstrate how I will hook up my Org-roam note-taking workflow to my blogging. In the meantime, just know that we can add tags to the top of our org files like this:
</p>
@@ -761,9 +761,9 @@ Finally, let's append the following to <code>posts/posts.css</code> so that our
</div>
</div>
</div>
-<div id="outline-container-org9e54591" class="outline-2">
-<h2 id="org9e54591">Conclusion</h2>
-<div class="outline-text-2" id="text-org9e54591">
+<div id="outline-container-org937024c" class="outline-2">
+<h2 id="org937024c">Conclusion</h2>
+<div class="outline-text-2" id="text-org937024c">
<p>
There are many more customizations that I plan to do on this system in the future, but I plan to leave this for now so that I can actually get to some blogging. I will proofread and fix my mistakes as time goes on, but this should be a good jumping off point for anyone interested in using org for their own blogging system.
</p>
diff --git a/public/posts/jul_28_2025.html b/public/posts/jul_28_2025.html
index 89a50fd..d93cf72 100644
--- a/public/posts/jul_28_2025.html
+++ b/public/posts/jul_28_2025.html
@@ -29,9 +29,9 @@
</div>
</div>
<div id="content" class="content">
-<div id="outline-container-org9b73ff7" class="outline-2">
-<h2 id="org9b73ff7">What have I been up to?</h2>
-<div class="outline-text-2" id="text-org9b73ff7">
+<div id="outline-container-org7b55006" class="outline-2">
+<h2 id="org7b55006">What have I been up to?</h2>
+<div class="outline-text-2" id="text-org7b55006">
<p>
Whoops! I missed this month's update by a <i>long</i> shot, but I still want to get it out there before the end of the month.
</p>
diff --git a/public/posts/june_08_2025.html b/public/posts/june_08_2025.html
index aba0196..f467a84 100644
--- a/public/posts/june_08_2025.html
+++ b/public/posts/june_08_2025.html
@@ -29,9 +29,9 @@
</div>
</div>
<div id="content" class="content">
-<div id="outline-container-org953a1f2" class="outline-2">
-<h2 id="org953a1f2">What have I been up to?</h2>
-<div class="outline-text-2" id="text-org953a1f2">
+<div id="outline-container-orgb3a2b27" class="outline-2">
+<h2 id="orgb3a2b27">What have I been up to?</h2>
+<div class="outline-text-2" id="text-orgb3a2b27">
<p>
Another month has gone by, so I guess it's time to see what I've been up to.
</p>
diff --git a/public/posts/may_06_2025.html b/public/posts/may_06_2025.html
index aca72d2..563bcab 100644
--- a/public/posts/may_06_2025.html
+++ b/public/posts/may_06_2025.html
@@ -29,9 +29,9 @@
</div>
</div>
<div id="content" class="content">
-<div id="outline-container-orgf30ad21" class="outline-2">
-<h2 id="orgf30ad21">What have I been up to?</h2>
-<div class="outline-text-2" id="text-orgf30ad21">
+<div id="outline-container-org8c64ed6" class="outline-2">
+<h2 id="org8c64ed6">What have I been up to?</h2>
+<div class="outline-text-2" id="text-org8c64ed6">
<p>
I've been meaning to do these little blog-post type updates for a while, and I figured now is as good a time as any. So let's start :)
</p>
diff --git a/public/posts/sitemap.html b/public/posts/sitemap.html
index 54f865b..9bcfbaf 100644
--- a/public/posts/sitemap.html
+++ b/public/posts/sitemap.html
@@ -34,13 +34,13 @@
<li><p>
<a href="dec_29_2025.html">Update December 29, 2025</a>
</p>
-<div class="sitemap_date" id="orgbb7f5a7">
+<div class="sitemap_date" id="org63552bd">
<p>
December 29, 2025
</p>
</div>
-<div class="sitemap_tag" id="org896446d">
+<div class="sitemap_tag" id="orgcae0db0">
<p>
update
</p>
@@ -49,13 +49,13 @@ update
<li><p>
<a href="jul_28_2025.html">Update July 28, 2025</a>
</p>
-<div class="sitemap_date" id="orgc23a3e5">
+<div class="sitemap_date" id="org04d89e2">
<p>
July 28, 2025
</p>
</div>
-<div class="sitemap_tag" id="org8910b95">
+<div class="sitemap_tag" id="orgd7ad92d">
<p>
update
</p>
@@ -64,13 +64,13 @@ update
<li><p>
<a href="june_08_2025.html">Update June 08, 2025</a>
</p>
-<div class="sitemap_date" id="orgbb6ff03">
+<div class="sitemap_date" id="org1099798">
<p>
June 08, 2025
</p>
</div>
-<div class="sitemap_tag" id="org8ef30c4">
+<div class="sitemap_tag" id="orgf02bca4">
<p>
update
</p>
@@ -79,13 +79,13 @@ update
<li><p>
<a href="may_06_2025.html">Update May 06, 2025</a>
</p>
-<div class="sitemap_date" id="org0762128">
+<div class="sitemap_date" id="org901b9bf">
<p>
May 06, 2025
</p>
</div>
-<div class="sitemap_tag" id="org12064c6">
+<div class="sitemap_tag" id="org0b4777f">
<p>
update
</p>
@@ -94,13 +94,13 @@ update
<li><p>
<a href="hello.html">Hello, Org</a>
</p>
-<div class="sitemap_date" id="orgb54315d">
+<div class="sitemap_date" id="orgf000d64">
<p>
June 20, 2023
</p>
</div>
-<div class="sitemap_tag" id="org705ac24">
+<div class="sitemap_tag" id="orga3ba3e0">
<p>
technology,home
</p>
diff --git a/themes/resources/bunny.obj b/public/resources/bunny.obj
index 18021c9..18021c9 100644
--- a/themes/resources/bunny.obj
+++ b/public/resources/bunny.obj
diff --git a/themes/resources/grass-blade.png b/public/resources/grass-blade.png
index 286cc23..286cc23 100644
--- a/themes/resources/grass-blade.png
+++ b/public/resources/grass-blade.png
Binary files differ
diff --git a/public/themes/dist/output.js b/public/themes/dist/output.js
deleted file mode 100644
index b19a1a3..0000000
--- a/public/themes/dist/output.js
+++ /dev/null
@@ -1,3841 +0,0 @@
-// include: shell.js
-// The Module object: Our interface to the outside world. We import
-// and export values on it. There are various ways Module can be used:
-// 1. Not defined. We create it here
-// 2. A function parameter, function(moduleArg) => Promise<Module>
-// 3. pre-run appended it, var Module = {}; ..generated code..
-// 4. External script tag defines var Module.
-// We need to check if Module already exists (e.g. case 3 above).
-// Substitution will be replaced with actual code on later stage of the build,
-// this way Closure Compiler will not mangle it (e.g. case 4. above).
-// Note that if you want to run closure, and also to use Module
-// after the generated code, you will need to define var Module = {};
-// before the code. Then that object will be used in the code, and you
-// can continue to use Module afterwards as well.
-var Module = typeof Module != 'undefined' ? Module : {};
-
-// Determine the runtime environment we are in. You can customize this by
-// setting the ENVIRONMENT setting at compile time (see settings.js).
-
-// Attempt to auto-detect the environment
-var ENVIRONMENT_IS_WEB = typeof window == 'object';
-var ENVIRONMENT_IS_WORKER = typeof importScripts == 'function';
-// N.b. Electron.js environment is simultaneously a NODE-environment, but
-// also a web environment.
-var ENVIRONMENT_IS_NODE = typeof process == 'object' && typeof process.versions == 'object' && typeof process.versions.node == 'string' && process.type != 'renderer';
-var ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIRONMENT_IS_WORKER;
-
-if (ENVIRONMENT_IS_NODE) {
- // `require()` is no-op in an ESM module, use `createRequire()` to construct
- // the require()` function. This is only necessary for multi-environment
- // builds, `-sENVIRONMENT=node` emits a static import declaration instead.
- // TODO: Swap all `require()`'s with `import()`'s?
-
-}
-
-// --pre-jses are emitted after the Module integration code, so that they can
-// refer to Module (if they choose; they can also define Module)
-
-
-// Sometimes an existing Module object exists with properties
-// meant to overwrite the default module functionality. Here
-// we collect those properties and reapply _after_ we configure
-// the current environment's defaults to avoid having to be so
-// defensive during initialization.
-var moduleOverrides = Object.assign({}, Module);
-
-var arguments_ = [];
-var thisProgram = './this.program';
-var quit_ = (status, toThrow) => {
- throw toThrow;
-};
-
-// `/` should be present at the end if `scriptDirectory` is not empty
-var scriptDirectory = '';
-function locateFile(path) {
- if (Module['locateFile']) {
- return Module['locateFile'](path, scriptDirectory);
- }
- return scriptDirectory + path;
-}
-
-// Hooks that are implemented differently in different runtime environments.
-var readAsync, readBinary;
-
-if (ENVIRONMENT_IS_NODE) {
- if (typeof process == 'undefined' || !process.release || process.release.name !== 'node') 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?)');
-
- var nodeVersion = process.versions.node;
- var numericVersion = nodeVersion.split('.').slice(0, 3);
- numericVersion = (numericVersion[0] * 10000) + (numericVersion[1] * 100) + (numericVersion[2].split('-')[0] * 1);
- var minVersion = 160000;
- if (numericVersion < 160000) {
- throw new Error('This emscripten-generated code requires node v16.0.0 (detected v' + nodeVersion + ')');
- }
-
- // These modules will usually be used on Node.js. Load them eagerly to avoid
- // the complexity of lazy-loading.
- var fs = require('fs');
- var nodePath = require('path');
-
- scriptDirectory = __dirname + '/';
-
-// include: node_shell_read.js
-readBinary = (filename) => {
- // We need to re-wrap `file://` strings to URLs. Normalizing isn't
- // necessary in that case, the path should already be absolute.
- filename = isFileURI(filename) ? new URL(filename) : nodePath.normalize(filename);
- var ret = fs.readFileSync(filename);
- assert(ret.buffer);
- return ret;
-};
-
-readAsync = (filename, binary = true) => {
- // See the comment in the `readBinary` function.
- filename = isFileURI(filename) ? new URL(filename) : nodePath.normalize(filename);
- return new Promise((resolve, reject) => {
- fs.readFile(filename, binary ? undefined : 'utf8', (err, data) => {
- if (err) reject(err);
- else resolve(binary ? data.buffer : data);
- });
- });
-};
-// end include: node_shell_read.js
- if (!Module['thisProgram'] && process.argv.length > 1) {
- thisProgram = process.argv[1].replace(/\\/g, '/');
- }
-
- arguments_ = process.argv.slice(2);
-
- if (typeof module != 'undefined') {
- module['exports'] = Module;
- }
-
- quit_ = (status, toThrow) => {
- process.exitCode = status;
- throw toThrow;
- };
-
-} else
-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?)');
-
-} else
-
-// Note that this includes Node.js workers when relevant (pthreads is enabled).
-// Node.js workers are detected as a combination of ENVIRONMENT_IS_WORKER and
-// ENVIRONMENT_IS_NODE.
-if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) {
- if (ENVIRONMENT_IS_WORKER) { // Check worker, not web, since window could be polyfilled
- scriptDirectory = self.location.href;
- } else if (typeof document != 'undefined' && document.currentScript) { // web
- scriptDirectory = document.currentScript.src;
- }
- // blob urls look like blob:http://site.com/etc/etc and we cannot infer anything from them.
- // otherwise, slice off the final part of the url to find the script directory.
- // if scriptDirectory does not contain a slash, lastIndexOf will return -1,
- // and scriptDirectory will correctly be replaced with an empty string.
- // If scriptDirectory contains a query (starting with ?) or a fragment (starting with #),
- // they are removed because they could contain a slash.
- if (scriptDirectory.startsWith('blob:')) {
- scriptDirectory = '';
- } else {
- scriptDirectory = scriptDirectory.substr(0, scriptDirectory.replace(/[?#].*/, '').lastIndexOf('/')+1);
- }
-
- 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?)');
-
- {
-// include: web_or_worker_shell_read.js
-if (ENVIRONMENT_IS_WORKER) {
- readBinary = (url) => {
- var xhr = new XMLHttpRequest();
- xhr.open('GET', url, false);
- xhr.responseType = 'arraybuffer';
- xhr.send(null);
- return new Uint8Array(/** @type{!ArrayBuffer} */(xhr.response));
- };
- }
-
- readAsync = (url) => {
- // Fetch has some additional restrictions over XHR, like it can't be used on a file:// url.
- // See https://github.com/github/fetch/pull/92#issuecomment-140665932
- // Cordova or Electron apps are typically loaded from a file:// url.
- // So use XHR on webview if URL is a file URL.
- if (isFileURI(url)) {
- return new Promise((resolve, reject) => {
- var xhr = new XMLHttpRequest();
- xhr.open('GET', url, true);
- xhr.responseType = 'arraybuffer';
- xhr.onload = () => {
- if (xhr.status == 200 || (xhr.status == 0 && xhr.response)) { // file URLs can return 0
- resolve(xhr.response);
- return;
- }
- reject(xhr.status);
- };
- xhr.onerror = reject;
- xhr.send(null);
- });
- }
- return fetch(url, { credentials: 'same-origin' })
- .then((response) => {
- if (response.ok) {
- return response.arrayBuffer();
- }
- return Promise.reject(new Error(response.status + ' : ' + response.url));
- })
- };
-// end include: web_or_worker_shell_read.js
- }
-} else
-{
- throw new Error('environment detection error');
-}
-
-var out = Module['print'] || console.log.bind(console);
-var err = Module['printErr'] || console.error.bind(console);
-
-// Merge back in the overrides
-Object.assign(Module, moduleOverrides);
-// Free the object hierarchy contained in the overrides, this lets the GC
-// reclaim data used.
-moduleOverrides = null;
-checkIncomingModuleAPI();
-
-// Emit code to handle expected values on the Module object. This applies Module.x
-// to the proper local x. This has two benefits: first, we only emit it if it is
-// expected to arrive, and second, by using a local everywhere else that can be
-// minified.
-
-if (Module['arguments']) arguments_ = Module['arguments'];legacyModuleProp('arguments', 'arguments_');
-
-if (Module['thisProgram']) thisProgram = Module['thisProgram'];legacyModuleProp('thisProgram', 'thisProgram');
-
-// perform assertions in shell.js after we set up out() and err(), as otherwise if an assertion fails it cannot print the message
-// Assertions on removed incoming Module JS APIs.
-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');
-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 emscripten_set_window_title in JS)');
-assert(typeof Module['TOTAL_MEMORY'] == 'undefined', 'Module.TOTAL_MEMORY has been renamed Module.INITIAL_MEMORY');
-legacyModuleProp('asm', 'wasmExports');
-legacyModuleProp('readAsync', 'readAsync');
-legacyModuleProp('readBinary', 'readBinary');
-legacyModuleProp('setWindowTitle', 'setWindowTitle');
-var IDBFS = 'IDBFS is no longer included by default; build with -lidbfs.js';
-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 FETCHFS = 'FETCHFS is no longer included by default; build with -lfetchfs.js';
-var ICASEFS = 'ICASEFS is no longer included by default; build with -licasefs.js';
-var JSFILEFS = 'JSFILEFS is no longer included by default; build with -ljsfilefs.js';
-var OPFS = 'OPFS is no longer included by default; build with -lopfs.js';
-
-var NODEFS = 'NODEFS is no longer included by default; build with -lnodefs.js';
-
-assert(!ENVIRONMENT_IS_SHELL, 'shell environment detected but not enabled at build time. Add `shell` to `-sENVIRONMENT` to enable.');
-
-// end include: shell.js
-
-// include: preamble.js
-// === Preamble library stuff ===
-
-// Documentation for the public APIs defined in this file must be updated in:
-// site/source/docs/api_reference/preamble.js.rst
-// A prebuilt local version of the documentation is available at:
-// site/build/text/docs/api_reference/preamble.js.txt
-// You can also build docs locally as HTML or other formats in site/
-// An online HTML version (which may be of a different version of Emscripten)
-// is up at http://kripken.github.io/emscripten-site/docs/api_reference/preamble.js.html
-
-var wasmBinary = Module['wasmBinary'];legacyModuleProp('wasmBinary', 'wasmBinary');
-
-if (typeof WebAssembly != 'object') {
- err('no native wasm support detected');
-}
-
-// Wasm globals
-
-var wasmMemory;
-
-//========================================
-// Runtime essentials
-//========================================
-
-// whether we are quitting the application. no code should run after this.
-// set in exit() and abort()
-var ABORT = false;
-
-// set by exit() and abort(). Passed to 'onExit' handler.
-// NOTE: This is also used as the process return code code in shell environments
-// but only when noExitRuntime is false.
-var EXITSTATUS;
-
-// In STRICT mode, we only define assert() when ASSERTIONS is set. i.e. we
-// don't define it at all in release modes. This matches the behaviour of
-// MINIMAL_RUNTIME.
-// TODO(sbc): Make this the default even without STRICT enabled.
-/** @type {function(*, string=)} */
-function assert(condition, text) {
- if (!condition) {
- abort('Assertion failed' + (text ? ': ' + text : ''));
- }
-}
-
-// We used to include malloc/free by default in the past. Show a helpful error in
-// builds with assertions.
-
-// Memory management
-
-var HEAP,
-/** @type {!Int8Array} */
- HEAP8,
-/** @type {!Uint8Array} */
- HEAPU8,
-/** @type {!Int16Array} */
- HEAP16,
-/** @type {!Uint16Array} */
- HEAPU16,
-/** @type {!Int32Array} */
- HEAP32,
-/** @type {!Uint32Array} */
- HEAPU32,
-/** @type {!Float32Array} */
- HEAPF32,
-/** @type {!Float64Array} */
- HEAPF64;
-
-// include: runtime_shared.js
-function updateMemoryViews() {
- var b = wasmMemory.buffer;
- Module['HEAP8'] = HEAP8 = new Int8Array(b);
- Module['HEAP16'] = HEAP16 = new Int16Array(b);
- Module['HEAPU8'] = HEAPU8 = new Uint8Array(b);
- Module['HEAPU16'] = HEAPU16 = new Uint16Array(b);
- Module['HEAP32'] = HEAP32 = new Int32Array(b);
- Module['HEAPU32'] = HEAPU32 = new Uint32Array(b);
- Module['HEAPF32'] = HEAPF32 = new Float32Array(b);
- Module['HEAPF64'] = HEAPF64 = new Float64Array(b);
-}
-
-// end include: runtime_shared.js
-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');
-
-// If memory is defined in wasm, the user can't provide it, or set INITIAL_MEMORY
-assert(!Module['wasmMemory'], 'Use of `wasmMemory` detected. Use -sIMPORTED_MEMORY to define wasmMemory externally');
-assert(!Module['INITIAL_MEMORY'], 'Detected runtime INITIAL_MEMORY setting. Use -sIMPORTED_MEMORY to define wasmMemory dynamically');
-
-// include: runtime_stack_check.js
-// Initializes the stack cookie. Called at the startup of main and at the startup of each thread in pthreads mode.
-function writeStackCookie() {
- var max = _emscripten_stack_get_end();
- assert((max & 3) == 0);
- // If the stack ends at address zero we write our cookies 4 bytes into the
- // stack. This prevents interference with SAFE_HEAP and ASAN which also
- // monitor writes to address zero.
- if (max == 0) {
- max += 4;
- }
- // The stack grow downwards towards _emscripten_stack_get_end.
- // We write cookies to the final two words in the stack and detect if they are
- // ever overwritten.
- HEAPU32[((max)>>2)] = 0x02135467;
- HEAPU32[(((max)+(4))>>2)] = 0x89BACDFE;
- // Also test the global address 0 for integrity.
- HEAPU32[((0)>>2)] = 1668509029;
-}
-
-function checkStackCookie() {
- if (ABORT) return;
- var max = _emscripten_stack_get_end();
- // See writeStackCookie().
- if (max == 0) {
- max += 4;
- }
- var cookie1 = HEAPU32[((max)>>2)];
- var cookie2 = HEAPU32[(((max)+(4))>>2)];
- if (cookie1 != 0x02135467 || cookie2 != 0x89BACDFE) {
- abort(`Stack overflow! Stack cookie has been overwritten at ${ptrToString(max)}, expected hex dwords 0x89BACDFE and 0x2135467, but received ${ptrToString(cookie2)} ${ptrToString(cookie1)}`);
- }
- // Also test the global address 0 for integrity.
- if (HEAPU32[((0)>>2)] != 0x63736d65 /* 'emsc' */) {
- abort('Runtime error: The application has corrupted its heap memory area (address zero)!');
- }
-}
-// end include: runtime_stack_check.js
-var __ATPRERUN__ = []; // functions called before the runtime is initialized
-var __ATINIT__ = []; // functions called during startup
-var __ATMAIN__ = []; // functions called when main() is to be run
-var __ATEXIT__ = []; // functions called during shutdown
-var __ATPOSTRUN__ = []; // functions called after the main() is called
-
-var runtimeInitialized = false;
-
-function preRun() {
- var preRuns = Module['preRun'];
- if (preRuns) {
- if (typeof preRuns == 'function') preRuns = [preRuns];
- preRuns.forEach(addOnPreRun);
- }
- callRuntimeCallbacks(__ATPRERUN__);
-}
-
-function initRuntime() {
- assert(!runtimeInitialized);
- runtimeInitialized = true;
-
- checkStackCookie();
-
-
- callRuntimeCallbacks(__ATINIT__);
-}
-
-function preMain() {
- checkStackCookie();
-
- callRuntimeCallbacks(__ATMAIN__);
-}
-
-function postRun() {
- checkStackCookie();
-
- var postRuns = Module['postRun'];
- if (postRuns) {
- if (typeof postRuns == 'function') postRuns = [postRuns];
- postRuns.forEach(addOnPostRun);
- }
-
- callRuntimeCallbacks(__ATPOSTRUN__);
-}
-
-function addOnPreRun(cb) {
- __ATPRERUN__.unshift(cb);
-}
-
-function addOnInit(cb) {
- __ATINIT__.unshift(cb);
-}
-
-function addOnPreMain(cb) {
- __ATMAIN__.unshift(cb);
-}
-
-function addOnExit(cb) {
-}
-
-function addOnPostRun(cb) {
- __ATPOSTRUN__.unshift(cb);
-}
-
-// include: runtime_math.js
-// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/imul
-
-// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/fround
-
-// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/clz32
-
-// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/trunc
-
-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');
-// end include: runtime_math.js
-// A counter of dependencies for calling run(). If we need to
-// do asynchronous work before running, increment this and
-// decrement it. Incrementing must happen in a place like
-// Module.preRun (used by emcc to add file preloading).
-// Note that you can add dependencies in preRun, even though
-// it happens right before run - run will be postponed until
-// the dependencies are met.
-var runDependencies = 0;
-var runDependencyWatcher = null;
-var dependenciesFulfilled = null; // overridden to take different actions when all run dependencies are fulfilled
-var runDependencyTracking = {};
-
-function getUniqueRunDependency(id) {
- var orig = id;
- while (1) {
- if (!runDependencyTracking[id]) return id;
- id = orig + Math.random();
- }
-}
-
-function addRunDependency(id) {
- runDependencies++;
-
- Module['monitorRunDependencies']?.(runDependencies);
-
- if (id) {
- assert(!runDependencyTracking[id]);
- runDependencyTracking[id] = 1;
- if (runDependencyWatcher === null && typeof setInterval != 'undefined') {
- // Check for missing dependencies every few seconds
- 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)');
- }
- }, 10000);
- }
- } else {
- err('warning: run dependency added without ID');
- }
-}
-
-function removeRunDependency(id) {
- runDependencies--;
-
- 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(); // can add another dependenciesFulfilled
- }
- }
-}
-
-/** @param {string|number=} what */
-function abort(what) {
- Module['onAbort']?.(what);
-
- what = 'Aborted(' + what + ')';
- // TODO(sbc): Should we remove printing and leave it up to whoever
- // catches the exception?
- err(what);
-
- ABORT = true;
-
- // Use a wasm runtime error, because a JS error might be seen as a foreign
- // exception, which means we'd run destructors on it. We need the error to
- // simply make the program stop.
- // FIXME This approach does not work in Wasm EH because it currently does not assume
- // all RuntimeErrors are from traps; it decides whether a RuntimeError is from
- // a trap or not based on a hidden field within the object. So at the moment
- // we don't have a way of throwing a wasm trap from JS. TODO Make a JS API that
- // allows this in the wasm spec.
-
- // Suppress closure compiler warning here. Closure compiler's builtin extern
- // definition for WebAssembly.RuntimeError claims it takes no arguments even
- // though it can.
- // TODO(https://github.com/google/closure-compiler/pull/3913): Remove if/when upstream closure gets fixed.
- /** @suppress {checkTypes} */
- var e = new WebAssembly.RuntimeError(what);
-
- // Throw the error whether or not MODULARIZE is set because abort is used
- // in code paths apart from instantiation where an exception is expected
- // to be thrown when abort is called.
- throw e;
-}
-
-// include: memoryprofiler.js
-// end include: memoryprofiler.js
-// show errors on likely calls to FS when it was not included
-var FS = {
- error() {
- abort('Filesystem support (FS) was not included. The problem is that you are using files from JS, but files were not used from C/C++, so filesystem support was not auto-included. You can force-include filesystem support with -sFORCE_FILESYSTEM');
- },
- init() { FS.error() },
- createDataFile() { FS.error() },
- createPreloadedFile() { FS.error() },
- createLazyFile() { FS.error() },
- open() { FS.error() },
- mkdev() { FS.error() },
- registerDevice() { FS.error() },
- analyzePath() { FS.error() },
-
- ErrnoError() { FS.error() },
-};
-Module['FS_createDataFile'] = FS.createDataFile;
-Module['FS_createPreloadedFile'] = FS.createPreloadedFile;
-
-// include: URIUtils.js
-// Prefix of data URIs emitted by SINGLE_FILE and related options.
-var dataURIPrefix = 'data:application/octet-stream;base64,';
-
-/**
- * Indicates whether filename is a base64 data URI.
- * @noinline
- */
-var isDataURI = (filename) => filename.startsWith(dataURIPrefix);
-
-/**
- * Indicates whether filename is delivered via file protocol (as opposed to http/https)
- * @noinline
- */
-var isFileURI = (filename) => filename.startsWith('file://');
-// end include: URIUtils.js
-function createExportWrapper(name, nargs) {
- return (...args) => {
- assert(runtimeInitialized, `native function \`${name}\` called before runtime initialization`);
- var f = wasmExports[name];
- assert(f, `exported native function \`${name}\` not found`);
- // Only assert for too many arguments. Too few can be valid since the missing arguments will be zero filled.
- assert(args.length <= nargs, `native function \`${name}\` called with ${args.length} args but expects ${nargs}`);
- return f(...args);
- };
-}
-
-// include: runtime_exceptions.js
-// end include: runtime_exceptions.js
-function findWasmBinary() {
- var f = 'output.wasm';
- if (!isDataURI(f)) {
- return locateFile(f);
- }
- return f;
-}
-
-var wasmBinaryFile;
-
-function getBinarySync(file) {
- if (file == wasmBinaryFile && wasmBinary) {
- return new Uint8Array(wasmBinary);
- }
- if (readBinary) {
- return readBinary(file);
- }
- throw 'both async and sync fetching of the wasm failed';
-}
-
-function getBinaryPromise(binaryFile) {
- // If we don't have the binary yet, load it asynchronously using readAsync.
- if (!wasmBinary
- ) {
- // Fetch the binary using readAsync
- return readAsync(binaryFile).then(
- (response) => new Uint8Array(/** @type{!ArrayBuffer} */(response)),
- // Fall back to getBinarySync if readAsync fails
- () => getBinarySync(binaryFile)
- );
- }
-
- // Otherwise, getBinarySync should be able to get it synchronously
- return Promise.resolve().then(() => getBinarySync(binaryFile));
-}
-
-function instantiateArrayBuffer(binaryFile, imports, receiver) {
- return getBinaryPromise(binaryFile).then((binary) => {
- return WebAssembly.instantiate(binary, imports);
- }).then(receiver, (reason) => {
- err(`failed to asynchronously prepare wasm: ${reason}`);
-
- // Warn on some common problems.
- 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) &&
- // Don't use streaming for file:// delivered objects in a webview, fetch them synchronously.
- !isFileURI(binaryFile) &&
- // Avoid instantiateStreaming() on Node.js environment for now, as while
- // Node.js v18.1.0 implements it, it does not have a full fetch()
- // implementation yet.
- //
- // Reference:
- // https://github.com/emscripten-core/emscripten/pull/16917
- !ENVIRONMENT_IS_NODE &&
- typeof fetch == 'function') {
- return fetch(binaryFile, { credentials: 'same-origin' }).then((response) => {
- // Suppress closure warning here since the upstream definition for
- // instantiateStreaming only allows Promise<Repsponse> rather than
- // an actual Response.
- // TODO(https://github.com/google/closure-compiler/pull/3913): Remove if/when upstream closure is fixed.
- /** @suppress {checkTypes} */
- var result = WebAssembly.instantiateStreaming(response, imports);
-
- return result.then(
- callback,
- function(reason) {
- // We expect the most common failure cause to be a bad MIME type for the binary,
- // in which case falling back to ArrayBuffer instantiation should work.
- err(`wasm streaming compile failed: ${reason}`);
- err('falling back to ArrayBuffer instantiation');
- return instantiateArrayBuffer(binaryFile, imports, callback);
- });
- });
- }
- return instantiateArrayBuffer(binaryFile, imports, callback);
-}
-
-function getWasmImports() {
- // prepare imports
- return {
- 'env': wasmImports,
- 'wasi_snapshot_preview1': wasmImports,
- }
-}
-
-// Create the wasm instance.
-// Receives the wasm imports, returns the exports.
-function createWasm() {
- var info = getWasmImports();
- // Load the wasm module and create an instance of using native support in the JS engine.
- // handle a generated wasm instance, receiving its exports and
- // performing other necessary setup
- /** @param {WebAssembly.Module=} module*/
- function receiveInstance(instance, module) {
- wasmExports = instance.exports;
-
-
-
- wasmMemory = wasmExports['memory'];
-
- assert(wasmMemory, 'memory not found in wasm exports');
- updateMemoryViews();
-
- wasmTable = wasmExports['__indirect_function_table'];
-
- assert(wasmTable, 'table not found in wasm exports');
-
- addOnInit(wasmExports['__wasm_call_ctors']);
-
- removeRunDependency('wasm-instantiate');
- return wasmExports;
- }
- // wait for the pthread pool (if any)
- addRunDependency('wasm-instantiate');
-
- // Prefer streaming instantiation if available.
- // Async compilation can be confusing when an error on the page overwrites Module
- // (for example, if the order of elements is wrong, and the one defining Module is
- // later), so we save Module and check it later.
- var trueModule = Module;
- function receiveInstantiationResult(result) {
- // 'result' is a ResultObject object which has both the module and instance.
- // receiveInstance() will swap in the exports (to Module.asm) so they can be called
- assert(Module === trueModule, 'the Module object should not be replaced during async compilation - perhaps the order of HTML elements is wrong?');
- trueModule = null;
- // 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, can restore the above PTHREADS-enabled path.
- receiveInstance(result['instance']);
- }
-
- // User shell pages can write their own Module.instantiateWasm = function(imports, successCallback) callback
- // to manually instantiate the Wasm module themselves. This allows pages to
- // run the instantiation parallel to any other async startup actions they are
- // performing.
- // Also pthreads and wasm workers initialize the wasm instance through this
- // path.
- if (Module['instantiateWasm']) {
- try {
- return Module['instantiateWasm'](info, receiveInstance);
- } catch(e) {
- err(`Module.instantiateWasm callback failed with error: ${e}`);
- return false;
- }
- }
-
- wasmBinaryFile ??= findWasmBinary();
-
- instantiateAsync(wasmBinary, wasmBinaryFile, info, receiveInstantiationResult);
- return {}; // no exports yet; we'll fill them in later
-}
-
-// Globals used by JS i64 conversions (see makeSetValue)
-var tempDouble;
-var tempI64;
-
-// include: runtime_debug.js
-// Endianness check
-(() => {
- var h16 = new Int16Array(1);
- var h8 = new Int8Array(h16.buffer);
- h16[0] = 0x6373;
- if (h8[0] !== 0x73 || h8[1] !== 0x63) throw 'Runtime error: expected the system to be little-endian! (Run with -sSUPPORT_BIG_ENDIAN to bypass)';
-})();
-
-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)');
-}
-
-function legacyModuleProp(prop, newName, incoming=true) {
- if (!Object.getOwnPropertyDescriptor(Module, prop)) {
- Object.defineProperty(Module, prop, {
- configurable: true,
- get() {
- let extra = incoming ? ' (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)' : '';
- abort(`\`Module.${prop}\` has been replaced by \`${newName}\`` + extra);
-
- }
- });
- }
-}
-
-function ignoredModuleProp(prop) {
- if (Object.getOwnPropertyDescriptor(Module, prop)) {
- abort(`\`Module.${prop}\` was supplied but \`${prop}\` not included in INCOMING_MODULE_JS_API`);
- }
-}
-
-// forcing the filesystem exports a few things by default
-function isExportedByForceFilesystem(name) {
- return name === 'FS_createPath' ||
- name === 'FS_createDataFile' ||
- name === 'FS_createPreloadedFile' ||
- name === 'FS_unlink' ||
- name === 'addRunDependency' ||
- // The old FS has some functionality that WasmFS lacks.
- name === 'FS_createLazyFile' ||
- name === 'FS_createDevice' ||
- name === 'removeRunDependency';
-}
-
-/**
- * Intercept access to a global symbol. This enables us to give informative
- * warnings/errors when folks attempt to use symbols they did not include in
- * their build, or no symbols that no longer exist.
- */
-function hookGlobalSymbolAccess(sym, func) {
- if (typeof globalThis != 'undefined' && !Object.getOwnPropertyDescriptor(globalThis, sym)) {
- Object.defineProperty(globalThis, sym, {
- configurable: true,
- get() {
- func();
- return undefined;
- }
- });
- }
-}
-
-function missingGlobal(sym, msg) {
- hookGlobalSymbolAccess(sym, () => {
- warnOnce(`\`${sym}\` is not longer defined by emscripten. ${msg}`);
- });
-}
-
-missingGlobal('buffer', 'Please use HEAP8.buffer or wasmMemory.buffer');
-missingGlobal('asm', 'Please use wasmExports instead');
-
-function missingLibrarySymbol(sym) {
- hookGlobalSymbolAccess(sym, () => {
- // Can't `abort()` here because it would break code that does runtime
- // checks. e.g. `if (typeof SDL === 'undefined')`.
- 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`;
- // DEFAULT_LIBRARY_FUNCS_TO_INCLUDE requires the name as it appears in
- // library.js, which means $name for a JS name with no prefix, or name
- // for a JS name like _name.
- 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);
- });
-
- // Any symbol that is not included from the JS library is also (by definition)
- // not exported on the Module object.
- unexportedRuntimeSymbol(sym);
-}
-
-function unexportedRuntimeSymbol(sym) {
- if (!Object.getOwnPropertyDescriptor(Module, sym)) {
- Object.defineProperty(Module, sym, {
- configurable: true,
- get() {
- var msg = `'${sym}' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the Emscripten FAQ)`;
- if (isExportedByForceFilesystem(sym)) {
- msg += '. Alternatively, forcing filesystem support (-sFORCE_FILESYSTEM) can export this for you';
- }
- abort(msg);
- }
- });
- }
-}
-
-// Used by XXXXX_DEBUG settings to output debug messages.
-function dbg(...args) {
- // TODO(sbc): Make this configurable somehow. Its not always convenient for
- // logging to show up as warnings.
- console.warn(...args);
-}
-// end include: runtime_debug.js
-// === Body ===
-// end include: preamble.js
-
-
- /** @constructor */
- function ExitStatus(status) {
- this.name = 'ExitStatus';
- this.message = `Program terminated with exit(${status})`;
- this.status = status;
- }
-
- var callRuntimeCallbacks = (callbacks) => {
- // Pass the module as the first argument.
- callbacks.forEach((f) => f(Module));
- };
-
-
- /**
- * @param {number} ptr
- * @param {string} type
- */
- function getValue(ptr, type = 'i8') {
- if (type.endsWith('*')) type = '*';
- switch (type) {
- case 'i1': return HEAP8[ptr];
- case 'i8': return HEAP8[ptr];
- case 'i16': return HEAP16[((ptr)>>1)];
- case 'i32': return HEAP32[((ptr)>>2)];
- case 'i64': abort('to do getValue(i64) use WASM_BIGINT');
- case 'float': return HEAPF32[((ptr)>>2)];
- case 'double': return HEAPF64[((ptr)>>3)];
- case '*': return HEAPU32[((ptr)>>2)];
- default: abort(`invalid type for getValue: ${type}`);
- }
- }
-
- var noExitRuntime = Module['noExitRuntime'] || true;
-
- var ptrToString = (ptr) => {
- assert(typeof ptr === 'number');
- // With CAN_ADDRESS_2GB or MEMORY64, pointers are already unsigned.
- ptr >>>= 0;
- return '0x' + ptr.toString(16).padStart(8, '0');
- };
-
-
- /**
- * @param {number} ptr
- * @param {number} value
- * @param {string} type
- */
- function setValue(ptr, value, type = 'i8') {
- if (type.endsWith('*')) type = '*';
- switch (type) {
- case 'i1': HEAP8[ptr] = value; break;
- case 'i8': HEAP8[ptr] = value; break;
- case 'i16': HEAP16[((ptr)>>1)] = value; break;
- case 'i32': HEAP32[((ptr)>>2)] = value; break;
- case 'i64': abort('to do setValue(i64) use WASM_BIGINT');
- case 'float': HEAPF32[((ptr)>>2)] = value; break;
- case 'double': HEAPF64[((ptr)>>3)] = value; break;
- case '*': HEAPU32[((ptr)>>2)] = value; break;
- default: abort(`invalid type for setValue: ${type}`);
- }
- }
-
- var stackRestore = (val) => __emscripten_stack_restore(val);
-
- var stackSave = () => _emscripten_stack_get_current();
-
- var warnOnce = (text) => {
- warnOnce.shown ||= {};
- if (!warnOnce.shown[text]) {
- warnOnce.shown[text] = 1;
- if (ENVIRONMENT_IS_NODE) text = 'warning: ' + text;
- err(text);
- }
- };
-
- var UTF8Decoder = typeof TextDecoder != 'undefined' ? new TextDecoder() : undefined;
-
- /**
- * Given a pointer 'idx' to a null-terminated UTF8-encoded string in the given
- * array that contains uint8 values, returns a copy of that string as a
- * Javascript String object.
- * heapOrArray is either a regular array, or a JavaScript typed array view.
- * @param {number=} idx
- * @param {number=} maxBytesToRead
- * @return {string}
- */
- var UTF8ArrayToString = (heapOrArray, idx = 0, maxBytesToRead = NaN) => {
- var endIdx = idx + maxBytesToRead;
- var endPtr = idx;
- // TextDecoder needs to know the byte length in advance, it doesn't stop on
- // null terminator by itself. Also, use the length info to avoid running tiny
- // strings through TextDecoder, since .subarray() allocates garbage.
- // (As a tiny code save trick, compare endPtr against endIdx using a negation,
- // so that undefined/NaN means Infinity)
- while (heapOrArray[endPtr] && !(endPtr >= endIdx)) ++endPtr;
-
- if (endPtr - idx > 16 && heapOrArray.buffer && UTF8Decoder) {
- return UTF8Decoder.decode(heapOrArray.subarray(idx, endPtr));
- }
- var str = '';
- // If building with TextDecoder, we have already computed the string length
- // above, so test loop end condition against that
- while (idx < endPtr) {
- // For UTF8 byte structure, see:
- // http://en.wikipedia.org/wiki/UTF-8#Description
- // https://www.ietf.org/rfc/rfc2279.txt
- // https://tools.ietf.org/html/rfc3629
- var u0 = heapOrArray[idx++];
- if (!(u0 & 0x80)) { str += String.fromCharCode(u0); continue; }
- var u1 = heapOrArray[idx++] & 63;
- if ((u0 & 0xE0) == 0xC0) { str += String.fromCharCode(((u0 & 31) << 6) | u1); continue; }
- var u2 = heapOrArray[idx++] & 63;
- if ((u0 & 0xF0) == 0xE0) {
- u0 = ((u0 & 15) << 12) | (u1 << 6) | u2;
- } else {
- if ((u0 & 0xF8) != 0xF0) 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 < 0x10000) {
- str += String.fromCharCode(u0);
- } else {
- var ch = u0 - 0x10000;
- str += String.fromCharCode(0xD800 | (ch >> 10), 0xDC00 | (ch & 0x3FF));
- }
- }
- return str;
- };
-
- /**
- * Given a pointer 'ptr' to a null-terminated UTF8-encoded string in the
- * emscripten HEAP, returns a copy of that string as a Javascript String object.
- *
- * @param {number} ptr
- * @param {number=} maxBytesToRead - An optional length that specifies the
- * maximum number of bytes to read. You can omit this parameter to scan the
- * string until the first 0 byte. If maxBytesToRead is passed, and the string
- * at [ptr, ptr+maxBytesToReadr[ contains a null byte in the middle, then the
- * string will cut short at that byte index (i.e. maxBytesToRead will not
- * produce a string of exact length [ptr, ptr+maxBytesToRead[) N.B. mixing
- * frequent uses of UTF8ToString() with and without maxBytesToRead may throw
- * JS JIT optimizations off, so it is worth to consider consistently using one
- * @return {string}
- */
- var UTF8ToString = (ptr, maxBytesToRead) => {
- assert(typeof ptr == 'number', `UTF8ToString expects a number (got ${typeof ptr})`);
- return ptr ? UTF8ArrayToString(HEAPU8, ptr, maxBytesToRead) : '';
- };
- var ___assert_fail = (condition, filename, line, func) => {
- abort(`Assertion failed: ${UTF8ToString(condition)}, at: ` + [filename ? UTF8ToString(filename) : 'unknown filename', line, func ? UTF8ToString(func) : 'unknown function']);
- };
-
- var __abort_js = () => {
- abort('native code called abort()');
- };
-
- function __emscripten_fetch_free(id) {
- if (Fetch.xhrs.has(id)) {
- var xhr = Fetch.xhrs.get(id);
- Fetch.xhrs.free(id);
- // check if fetch is still in progress and should be aborted
- if (xhr.readyState > 0 && xhr.readyState < 4) {
- xhr.abort();
- }
- }
- }
-
- var __emscripten_memcpy_js = (dest, src, num) => HEAPU8.copyWithin(dest, src, src + num);
-
- var isLeapYear = (year) => 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];
- var 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; // -1 since it's days since Jan 1
-
- return yday;
- };
-
- var convertI32PairToI53Checked = (lo, hi) => {
- assert(lo == (lo >>> 0) || lo == (lo|0)); // lo should either be a i32 or a u32
- assert(hi === (hi|0)); // hi should be a i32
- return ((hi + 0x200000) >>> 0 < 0x400001 - !!lo) ? (lo >>> 0) + hi * 4294967296 : NaN;
- };
- function __localtime_js(time_low, time_high,tmPtr) {
- var time = convertI32PairToI53Checked(time_low, time_high);
-
-
- var date = new Date(time*1000);
- HEAP32[((tmPtr)>>2)] = date.getSeconds();
- HEAP32[(((tmPtr)+(4))>>2)] = date.getMinutes();
- HEAP32[(((tmPtr)+(8))>>2)] = date.getHours();
- HEAP32[(((tmPtr)+(12))>>2)] = date.getDate();
- HEAP32[(((tmPtr)+(16))>>2)] = date.getMonth();
- HEAP32[(((tmPtr)+(20))>>2)] = date.getFullYear()-1900;
- HEAP32[(((tmPtr)+(24))>>2)] = date.getDay();
-
- var yday = ydayFromDate(date)|0;
- HEAP32[(((tmPtr)+(28))>>2)] = yday;
- HEAP32[(((tmPtr)+(36))>>2)] = -(date.getTimezoneOffset() * 60);
-
- // Attention: DST is in December in South, and some regions don't have DST at all.
- 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;
- HEAP32[(((tmPtr)+(32))>>2)] = dst;
- ;
- }
-
- var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => {
- assert(typeof str === 'string', `stringToUTF8Array expects a string (got ${typeof str})`);
- // Parameter maxBytesToWrite is not optional. Negative values, 0, null,
- // undefined and false each don't write out any bytes.
- if (!(maxBytesToWrite > 0))
- return 0;
-
- var startIdx = outIdx;
- var endIdx = outIdx + maxBytesToWrite - 1; // -1 for string null terminator.
- for (var i = 0; i < str.length; ++i) {
- // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code
- // unit, not a Unicode code point of the character! So decode
- // UTF16->UTF32->UTF8.
- // See http://unicode.org/faq/utf_bom.html#utf16-3
- // For UTF8 byte structure, see http://en.wikipedia.org/wiki/UTF-8#Description
- // and https://www.ietf.org/rfc/rfc2279.txt
- // and https://tools.ietf.org/html/rfc3629
- var u = str.charCodeAt(i); // possibly a lead surrogate
- if (u >= 0xD800 && u <= 0xDFFF) {
- var u1 = str.charCodeAt(++i);
- u = 0x10000 + ((u & 0x3FF) << 10) | (u1 & 0x3FF);
- }
- if (u <= 0x7F) {
- if (outIdx >= endIdx) break;
- heap[outIdx++] = u;
- } else if (u <= 0x7FF) {
- if (outIdx + 1 >= endIdx) break;
- heap[outIdx++] = 0xC0 | (u >> 6);
- heap[outIdx++] = 0x80 | (u & 63);
- } else if (u <= 0xFFFF) {
- if (outIdx + 2 >= endIdx) break;
- heap[outIdx++] = 0xE0 | (u >> 12);
- heap[outIdx++] = 0x80 | ((u >> 6) & 63);
- heap[outIdx++] = 0x80 | (u & 63);
- } else {
- if (outIdx + 3 >= endIdx) break;
- if (u > 0x10FFFF) 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++] = 0xF0 | (u >> 18);
- heap[outIdx++] = 0x80 | ((u >> 12) & 63);
- heap[outIdx++] = 0x80 | ((u >> 6) & 63);
- heap[outIdx++] = 0x80 | (u & 63);
- }
- }
- // Null-terminate the pointer to the buffer.
- heap[outIdx] = 0;
- return outIdx - startIdx;
- };
- var 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, HEAPU8, outPtr, maxBytesToWrite);
- };
-
- var lengthBytesUTF8 = (str) => {
- var len = 0;
- for (var i = 0; i < str.length; ++i) {
- // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code
- // unit, not a Unicode code point of the character! So decode
- // UTF16->UTF32->UTF8.
- // See http://unicode.org/faq/utf_bom.html#utf16-3
- var c = str.charCodeAt(i); // possibly a lead surrogate
- if (c <= 0x7F) {
- len++;
- } else if (c <= 0x7FF) {
- len += 2;
- } else if (c >= 0xD800 && c <= 0xDFFF) {
- len += 4; ++i;
- } else {
- len += 3;
- }
- }
- return len;
- };
- var __tzset_js = (timezone, daylight, std_name, dst_name) => {
- // TODO: Use (malleable) environment variables instead of system settings.
- 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();
-
- // Local standard timezone offset. Local standard time is not adjusted for
- // daylight savings. This code uses the fact that getTimezoneOffset returns
- // a greater value during Standard Time versus Daylight Saving Time (DST).
- // Thus it determines the expected output during Standard Time, and it
- // compares whether the output of the given date the same (Standard) or less
- // (DST).
- var stdTimezoneOffset = Math.max(winterOffset, summerOffset);
-
- // timezone is specified as seconds west of UTC ("The external variable
- // `timezone` shall be set to the difference, in seconds, between
- // Coordinated Universal Time (UTC) and local standard time."), the same
- // as returned by stdTimezoneOffset.
- // See http://pubs.opengroup.org/onlinepubs/009695399/functions/tzset.html
- HEAPU32[((timezone)>>2)] = stdTimezoneOffset * 60;
-
- HEAP32[((daylight)>>2)] = Number(winterOffset != summerOffset);
-
- var extractZone = (timezoneOffset) => {
- // Why inverse sign?
- // Read here https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getTimezoneOffset
- var sign = timezoneOffset >= 0 ? "-" : "+";
-
- var absOffset = Math.abs(timezoneOffset)
- var hours = String(Math.floor(absOffset / 60)).padStart(2, "0");
- var minutes = String(absOffset % 60).padStart(2, "0");
-
- return `UTC${sign}${hours}${minutes}`;
- }
-
- var winterName = extractZone(winterOffset);
- var summerName = extractZone(summerOffset);
- assert(winterName);
- assert(summerName);
- assert(lengthBytesUTF8(winterName) <= 16, `timezone name truncated to fit in TZNAME_MAX (${winterName})`);
- assert(lengthBytesUTF8(summerName) <= 16, `timezone name truncated to fit in TZNAME_MAX (${summerName})`);
- if (summerOffset < winterOffset) {
- // Northern hemisphere
- stringToUTF8(winterName, std_name, 17);
- stringToUTF8(summerName, dst_name, 17);
- } else {
- stringToUTF8(winterName, dst_name, 17);
- stringToUTF8(summerName, std_name, 17);
- }
- };
-
- var _emscripten_date_now = () => Date.now();
-
- var JSEvents = {
- removeAllEventListeners() {
- while (JSEvents.eventHandlers.length) {
- JSEvents._removeHandler(JSEvents.eventHandlers.length - 1);
- }
- JSEvents.deferredCalls = [];
- },
- inEventHandler:0,
- deferredCalls:[],
- deferCall(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;
- }
- // Test if the given call was already queued, and if so, don't add it again.
- for (var call of JSEvents.deferredCalls) {
- if (call.targetFunction == targetFunction && arraysHaveEqualContent(call.argsList, argsList)) {
- return;
- }
- }
- JSEvents.deferredCalls.push({
- targetFunction,
- precedence,
- argsList
- });
-
- JSEvents.deferredCalls.sort((x,y) => x.precedence < y.precedence);
- },
- removeDeferredCalls(targetFunction) {
- JSEvents.deferredCalls = JSEvents.deferredCalls.filter((call) => call.targetFunction != targetFunction);
- },
- canPerformEventHandlerRequests() {
- if (navigator.userActivation) {
- // Verify against transient activation status from UserActivation API
- // whether it is possible to perform a request here without needing to defer. See
- // https://developer.mozilla.org/en-US/docs/Web/Security/User_activation#transient_activation
- // and https://caniuse.com/mdn-api_useractivation
- // At the time of writing, Firefox does not support this API: https://bugzilla.mozilla.org/show_bug.cgi?id=1791079
- return navigator.userActivation.isActive;
- }
-
- return JSEvents.inEventHandler && JSEvents.currentEventHandler.allowsDeferredCalls;
- },
- runDeferredCalls() {
- if (!JSEvents.canPerformEventHandlerRequests()) {
- return;
- }
- var deferredCalls = JSEvents.deferredCalls;
- JSEvents.deferredCalls = [];
- for (var call of deferredCalls) {
- call.targetFunction(...call.argsList);
- }
- },
- eventHandlers:[],
- removeAllHandlersOnTarget:(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(i) {
- var h = JSEvents.eventHandlers[i];
- h.target.removeEventListener(h.eventTypeString, h.eventListenerFunc, h.useCapture);
- JSEvents.eventHandlers.splice(i, 1);
- },
- registerOrRemoveHandler(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;
- }
- if (eventHandler.callbackfunc) {
- eventHandler.eventListenerFunc = function(event) {
- // Increment nesting count for the event handler.
- ++JSEvents.inEventHandler;
- JSEvents.currentEventHandler = eventHandler;
- // Process any old deferred calls the user has placed.
- JSEvents.runDeferredCalls();
- // Process the actual event, calls back to user C code handler.
- eventHandler.handlerFunc(event);
- // Process any new deferred calls that were placed right now from this event handler.
- JSEvents.runDeferredCalls();
- // Out of event handler - restore nesting count.
- --JSEvents.inEventHandler;
- };
-
- eventHandler.target.addEventListener(eventHandler.eventTypeString,
- eventHandler.eventListenerFunc,
- eventHandler.useCapture);
- JSEvents.eventHandlers.push(eventHandler);
- } 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;
- },
- getNodeNameForTarget(target) {
- if (!target) return '';
- if (target == window) return '#window';
- if (target == screen) return '#screen';
- return target?.nodeName || '';
- },
- fullscreenEnabled() {
- return document.fullscreenEnabled
- // Safari 13.0.3 on macOS Catalina 10.15.1 still ships with prefixed webkitFullscreenEnabled.
- // TODO: If Safari at some point ships with unprefixed version, update the version check above.
- || document.webkitFullscreenEnabled
- ;
- },
- };
-
- var maybeCStringToJsString = (cString) => {
- // "cString > 2" checks if the input is a number, and isn't of the special
- // values we accept here, EMSCRIPTEN_EVENT_TARGET_* (which map to 0, 1, 2).
- // In other words, if cString > 2 then it's a pointer to a valid place in
- // memory, and points to a C string.
- return cString > 2 ? UTF8ToString(cString) : cString;
- };
-
- /** @type {Object} */
- var specialHTMLTargets = [0, typeof document != 'undefined' ? document : 0, typeof window != 'undefined' ? window : 0];
- var findEventTarget = (target) => {
- target = maybeCStringToJsString(target);
- var domElement = specialHTMLTargets[target] || (typeof document != 'undefined' ? document.querySelector(target) : undefined);
- return domElement;
- };
-
- var getBoundingClientRect = (e) => specialHTMLTargets.indexOf(e) < 0 ? e.getBoundingClientRect() : {'left':0,'top':0};
- var _emscripten_get_element_css_size = (target, width, height) => {
- target = findEventTarget(target);
- if (!target) return -4;
-
- var rect = getBoundingClientRect(target);
- HEAPF64[((width)>>3)] = rect.width;
- HEAPF64[((height)>>3)] = rect.height;
-
- return 0;
- };
-
- var _emscripten_is_main_browser_thread = () =>
- !ENVIRONMENT_IS_WORKER;
-
- var wasmTableMirror = [];
-
- /** @type {WebAssembly.Table} */
- var wasmTable;
- var 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;
- };
- var _emscripten_request_animation_frame_loop = (cb, userData) => {
- function tick(timeStamp) {
- if (getWasmTableEntry(cb)(timeStamp, userData)) {
- requestAnimationFrame(tick);
- }
- }
- return requestAnimationFrame(tick);
- };
-
- var getHeapMax = () =>
- // Stay one Wasm page short of 4GB: while e.g. Chrome is able to allocate
- // full 4GB Wasm memories, the size will wrap back to 0 bytes in Wasm side
- // for any code that deals with heap sizes, which would require special
- // casing all heap size related code to treat 0 specially.
- 2147483648;
-
- var alignMemory = (size, alignment) => {
- assert(alignment, "alignment argument is required");
- return Math.ceil(size / alignment) * alignment;
- };
-
- var growMemory = (size) => {
- var b = wasmMemory.buffer;
- var pages = ((size - b.byteLength + 65535) / 65536) | 0;
- try {
- // round size grow request up to wasm page size (fixed 64KB per spec)
- wasmMemory.grow(pages); // .grow() takes a delta compared to the previous size
- updateMemoryViews();
- return 1 /*success*/;
- } catch(e) {
- err(`growMemory: Attempted to grow heap from ${b.byteLength} bytes to ${size} bytes, but got error: ${e}`);
- }
- // implicit 0 return to save code size (caller will cast "undefined" into 0
- // anyhow)
- };
- var _emscripten_resize_heap = (requestedSize) => {
- var oldSize = HEAPU8.length;
- // With CAN_ADDRESS_2GB or MEMORY64, pointers are already unsigned.
- requestedSize >>>= 0;
- // With multithreaded builds, races can happen (another thread might increase the size
- // in between), so return a failure, and let the caller retry.
- assert(requestedSize > oldSize);
-
- // Memory resize rules:
- // 1. Always increase heap size to at least the requested size, rounded up
- // to next page multiple.
- // 2a. If MEMORY_GROWTH_LINEAR_STEP == -1, excessively resize the heap
- // geometrically: increase the heap size according to
- // MEMORY_GROWTH_GEOMETRIC_STEP factor (default +20%), At most
- // overreserve by MEMORY_GROWTH_GEOMETRIC_CAP bytes (default 96MB).
- // 2b. If MEMORY_GROWTH_LINEAR_STEP != -1, excessively resize the heap
- // linearly: increase the heap size by at least
- // MEMORY_GROWTH_LINEAR_STEP bytes.
- // 3. Max size for the heap is capped at 2048MB-WASM_PAGE_SIZE, or by
- // MAXIMUM_MEMORY, or by ASAN limit, depending on which is smallest
- // 4. If we were unable to allocate as much memory, it may be due to
- // over-eager decision to excessively reserve due to (3) above.
- // Hence if an allocation fails, cut down on the amount of excess
- // growth, in an attempt to succeed to perform a smaller allocation.
-
- // A limit is set for how much we can grow. We should not exceed that
- // (the wasm binary specifies it, so if we tried, we'd fail anyhow).
- var maxHeapSize = getHeapMax();
- if (requestedSize > maxHeapSize) {
- err(`Cannot enlarge memory, requested ${requestedSize} bytes, but the limit is ${maxHeapSize} bytes!`);
- return false;
- }
-
- // Loop through potential heap size increases. If we attempt a too eager
- // reservation that fails, cut down on the attempted size and reserve a
- // smaller bump instead. (max 3 times, chosen somewhat arbitrarily)
- for (var cutDown = 1; cutDown <= 4; cutDown *= 2) {
- var overGrownHeapSize = oldSize * (1 + 0.2 / cutDown); // ensure geometric growth
- // but limit overreserving (default to capping at +96MB overgrowth at most)
- overGrownHeapSize = Math.min(overGrownHeapSize, requestedSize + 100663296 );
-
- var newSize = Math.min(maxHeapSize, alignMemory(Math.max(requestedSize, overGrownHeapSize), 65536));
-
- var replacement = growMemory(newSize);
- if (replacement) {
-
- return true;
- }
- }
- err(`Failed to grow the heap from ${oldSize} bytes to ${newSize} bytes, not enough memory!`);
- return false;
- };
-
-
- var findCanvasEventTarget = findEventTarget;
- var _emscripten_set_canvas_element_size = (target, width, height) => {
- var canvas = findCanvasEventTarget(target);
- if (!canvas) return -4;
- canvas.width = width;
- canvas.height = height;
- return 0;
- };
-
-
-
-
- var fillMouseEventData = (eventStruct, e, target) => {
- assert(eventStruct % 4 == 0);
- HEAPF64[((eventStruct)>>3)] = e.timeStamp;
- var idx = ((eventStruct)>>2);
- HEAP32[idx + 2] = e.screenX;
- HEAP32[idx + 3] = e.screenY;
- HEAP32[idx + 4] = e.clientX;
- HEAP32[idx + 5] = e.clientY;
- HEAP8[eventStruct + 24] = e.ctrlKey;
- HEAP8[eventStruct + 25] = e.shiftKey;
- HEAP8[eventStruct + 26] = e.altKey;
- HEAP8[eventStruct + 27] = e.metaKey;
- HEAP16[idx*2 + 14] = e.button;
- HEAP16[idx*2 + 15] = e.buttons;
-
- HEAP32[idx + 8] = e["movementX"]
- ;
-
- HEAP32[idx + 9] = e["movementY"]
- ;
-
- // Note: rect contains doubles (truncated to placate SAFE_HEAP, which is the same behaviour when writing to HEAP32 anyway)
- var rect = getBoundingClientRect(target);
- HEAP32[idx + 10] = e.clientX - (rect.left | 0);
- HEAP32[idx + 11] = e.clientY - (rect.top | 0);
-
- };
-
-
-
- var registerMouseEventCallback = (target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) => {
- JSEvents.mouseEvent ||= _malloc(64);
- target = findEventTarget(target);
-
- var mouseEventHandlerFunc = (e = event) => {
- // TODO: Make this access thread safe, or this could update live while app is reading it.
- fillMouseEventData(JSEvents.mouseEvent, e, target);
-
- if (getWasmTableEntry(callbackfunc)(eventTypeId, JSEvents.mouseEvent, userData)) e.preventDefault();
- };
-
- var eventHandler = {
- target,
- allowsDeferredCalls: eventTypeString != 'mousemove' && eventTypeString != 'mouseenter' && eventTypeString != 'mouseleave', // Mouse move events do not allow fullscreen/pointer lock requests to be handled in them!
- eventTypeString,
- callbackfunc,
- handlerFunc: mouseEventHandlerFunc,
- useCapture
- };
- return JSEvents.registerOrRemoveHandler(eventHandler);
- };
- var _emscripten_set_click_callback_on_thread = (target, userData, useCapture, callbackfunc, targetThread) =>
- registerMouseEventCallback(target, userData, useCapture, callbackfunc, 4, "click", targetThread);
-
-
-
-
- var registerUiEventCallback = (target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) => {
- JSEvents.uiEvent ||= _malloc(36);
-
- target = findEventTarget(target);
-
- var uiEventHandlerFunc = (e = event) => {
- if (e.target != target) {
- // Never take ui events such as scroll via a 'bubbled' route, but always from the direct element that
- // was targeted. Otherwise e.g. if app logs a message in response to a page scroll, the Emscripten log
- // message box could cause to scroll, generating a new (bubbled) scroll message, causing a new log print,
- // causing a new scroll, etc..
- return;
- }
- var b = document.body; // Take document.body to a variable, Closure compiler does not outline access to it on its own.
- if (!b) {
- // During a page unload 'body' can be null, with "Cannot read property 'clientWidth' of null" being thrown
- return;
- }
- var uiEvent = JSEvents.uiEvent;
- HEAP32[((uiEvent)>>2)] = 0; // always zero for resize and scroll
- HEAP32[(((uiEvent)+(4))>>2)] = b.clientWidth;
- HEAP32[(((uiEvent)+(8))>>2)] = b.clientHeight;
- HEAP32[(((uiEvent)+(12))>>2)] = innerWidth;
- HEAP32[(((uiEvent)+(16))>>2)] = innerHeight;
- HEAP32[(((uiEvent)+(20))>>2)] = outerWidth;
- HEAP32[(((uiEvent)+(24))>>2)] = outerHeight;
- HEAP32[(((uiEvent)+(28))>>2)] = pageXOffset | 0; // scroll offsets are float
- HEAP32[(((uiEvent)+(32))>>2)] = pageYOffset | 0;
- if (getWasmTableEntry(callbackfunc)(eventTypeId, uiEvent, userData)) e.preventDefault();
- };
-
- var eventHandler = {
- target,
- eventTypeString,
- callbackfunc,
- handlerFunc: uiEventHandlerFunc,
- useCapture
- };
- return JSEvents.registerOrRemoveHandler(eventHandler);
- };
- var _emscripten_set_resize_callback_on_thread = (target, userData, useCapture, callbackfunc, targetThread) =>
- registerUiEventCallback(target, userData, useCapture, callbackfunc, 10, "resize", targetThread);
-
-
-
- class HandleAllocator {
- constructor() {
- // TODO(https://github.com/emscripten-core/emscripten/issues/21414):
- // Use inline field declarations.
- this.allocated = [undefined];
- this.freelist = [];
- }
- get(id) {
- assert(this.allocated[id] !== undefined, `invalid handle: ${id}`);
- return this.allocated[id];
- }
- has(id) {
- return this.allocated[id] !== undefined;
- }
- allocate(handle) {
- var id = this.freelist.pop() || this.allocated.length;
- this.allocated[id] = handle;
- return id;
- }
- free(id) {
- assert(this.allocated[id] !== undefined);
- // Set the slot to `undefined` rather than using `delete` here since
- // apparently arrays with holes in them can be less efficient.
- this.allocated[id] = undefined;
- this.freelist.push(id);
- }
- }
- var Fetch = {
- openDatabase(dbname, dbversion, onsuccess, onerror) {
- try {
- var openRequest = indexedDB.open(dbname, dbversion);
- } catch (e) {
- return onerror(e);
- }
-
- openRequest.onupgradeneeded = (event) => {
- var db = /** @type {IDBDatabase} */ (event.target.result);
- if (db.objectStoreNames.contains('FILES')) {
- db.deleteObjectStore('FILES');
- }
- db.createObjectStore('FILES');
- };
- openRequest.onsuccess = (event) => onsuccess(event.target.result);
- openRequest.onerror = onerror;
- },
- init() {
- Fetch.xhrs = new HandleAllocator();
- var onsuccess = (db) => {
- Fetch.dbInstance = db;
- removeRunDependency('library_fetch_init');
- };
-
- var onerror = () => {
- Fetch.dbInstance = false;
- removeRunDependency('library_fetch_init');
- };
-
- addRunDependency('library_fetch_init');
- Fetch.openDatabase('emscripten_filesystem', 1, onsuccess, onerror);
- },
- };
-
- function fetchXHR(fetch, onsuccess, onerror, onprogress, onreadystatechange) {
- var url = HEAPU32[(((fetch)+(8))>>2)];
- if (!url) {
- onerror(fetch, 0, 'no url specified!');
- return;
- }
- var url_ = UTF8ToString(url);
-
- var fetch_attr = fetch + 108;
- var requestMethod = UTF8ToString(fetch_attr + 0);
- requestMethod ||= 'GET';
- var timeoutMsecs = HEAPU32[(((fetch_attr)+(56))>>2)];
- var userName = HEAPU32[(((fetch_attr)+(68))>>2)];
- var password = HEAPU32[(((fetch_attr)+(72))>>2)];
- var requestHeaders = HEAPU32[(((fetch_attr)+(76))>>2)];
- var overriddenMimeType = HEAPU32[(((fetch_attr)+(80))>>2)];
- var dataPtr = HEAPU32[(((fetch_attr)+(84))>>2)];
- var dataLength = HEAPU32[(((fetch_attr)+(88))>>2)];
-
- var fetchAttributes = HEAPU32[(((fetch_attr)+(52))>>2)];
- var fetchAttrLoadToMemory = !!(fetchAttributes & 1);
- var fetchAttrStreamData = !!(fetchAttributes & 2);
- var fetchAttrSynchronous = !!(fetchAttributes & 64);
-
- var userNameStr = userName ? UTF8ToString(userName) : undefined;
- var passwordStr = password ? UTF8ToString(password) : undefined;
-
- var xhr = new XMLHttpRequest();
- xhr.withCredentials = !!HEAPU8[(fetch_attr)+(60)];;
- xhr.open(requestMethod, url_, !fetchAttrSynchronous, userNameStr, passwordStr);
- if (!fetchAttrSynchronous) xhr.timeout = timeoutMsecs; // XHR timeout field is only accessible in async XHRs, and must be set after .open() but before .send().
- xhr.url_ = url_; // Save the url for debugging purposes (and for comparing to the responseURL that server side advertised)
- assert(!fetchAttrStreamData, 'streaming uses moz-chunked-arraybuffer which is no longer supported; TODO: rewrite using fetch()');
- xhr.responseType = 'arraybuffer';
-
- if (overriddenMimeType) {
- var overriddenMimeTypeStr = UTF8ToString(overriddenMimeType);
- xhr.overrideMimeType(overriddenMimeTypeStr);
- }
- if (requestHeaders) {
- for (;;) {
- var key = HEAPU32[((requestHeaders)>>2)];
- if (!key) break;
- var value = HEAPU32[(((requestHeaders)+(4))>>2)];
- if (!value) break;
- requestHeaders += 8;
- var keyStr = UTF8ToString(key);
- var valueStr = UTF8ToString(value);
- xhr.setRequestHeader(keyStr, valueStr);
- }
- }
-
- var id = Fetch.xhrs.allocate(xhr);
- HEAPU32[((fetch)>>2)] = id;
- var data = (dataPtr && dataLength) ? HEAPU8.slice(dataPtr, dataPtr + dataLength) : null;
- // TODO: Support specifying custom headers to the request.
-
- // Share the code to save the response, as we need to do so both on success
- // and on error (despite an error, there may be a response, like a 404 page).
- // This receives a condition, which determines whether to save the xhr's
- // response, or just 0.
- function saveResponseAndStatus() {
- var ptr = 0;
- var ptrLen = 0;
- if (xhr.response && fetchAttrLoadToMemory && HEAPU32[(((fetch)+(12))>>2)] === 0) {
- ptrLen = xhr.response.byteLength;
- }
- if (ptrLen > 0) {
- // The data pointer malloc()ed here has the same lifetime as the emscripten_fetch_t structure itself has, and is
- // freed when emscripten_fetch_close() is called.
- ptr = _malloc(ptrLen);
- HEAPU8.set(new Uint8Array(/** @type{Array<number>} */(xhr.response)), ptr);
- }
- HEAPU32[(((fetch)+(12))>>2)] = ptr
- writeI53ToI64(fetch + 16, ptrLen);
- writeI53ToI64(fetch + 24, 0);
- var len = xhr.response ? xhr.response.byteLength : 0;
- if (len) {
- // If the final XHR.onload handler receives the bytedata to compute total length, report that,
- // otherwise don't write anything out here, which will retain the latest byte size reported in
- // the most recent XHR.onprogress handler.
- writeI53ToI64(fetch + 32, len);
- }
- HEAP16[(((fetch)+(40))>>1)] = xhr.readyState
- HEAP16[(((fetch)+(42))>>1)] = xhr.status
- if (xhr.statusText) stringToUTF8(xhr.statusText, fetch + 44, 64);
- }
-
- xhr.onload = (e) => {
- // check if xhr was aborted by user and don't try to call back
- if (!Fetch.xhrs.has(id)) {
- return;
- }
- saveResponseAndStatus();
- if (xhr.status >= 200 && xhr.status < 300) {
- onsuccess?.(fetch, xhr, e);
- } else {
- onerror?.(fetch, xhr, e);
- }
- };
- xhr.onerror = (e) => {
- // check if xhr was aborted by user and don't try to call back
- if (!Fetch.xhrs.has(id)) {
- return;
- }
- saveResponseAndStatus();
- onerror?.(fetch, xhr, e);
- };
- xhr.ontimeout = (e) => {
- // check if xhr was aborted by user and don't try to call back
- if (!Fetch.xhrs.has(id)) {
- return;
- }
- onerror?.(fetch, xhr, e);
- };
- xhr.onprogress = (e) => {
- // check if xhr was aborted by user and don't try to call back
- if (!Fetch.xhrs.has(id)) {
- return;
- }
- var ptrLen = (fetchAttrLoadToMemory && fetchAttrStreamData && xhr.response) ? xhr.response.byteLength : 0;
- var ptr = 0;
- if (ptrLen > 0 && fetchAttrLoadToMemory && fetchAttrStreamData) {
- assert(onprogress, 'When doing a streaming fetch, you should have an onprogress handler registered to receive the chunks!');
- // Allocate byte data in Emscripten heap for the streamed memory block (freed immediately after onprogress call)
- ptr = _malloc(ptrLen);
- HEAPU8.set(new Uint8Array(/** @type{Array<number>} */(xhr.response)), ptr);
- }
- HEAPU32[(((fetch)+(12))>>2)] = ptr
- writeI53ToI64(fetch + 16, ptrLen);
- writeI53ToI64(fetch + 24, e.loaded - ptrLen);
- writeI53ToI64(fetch + 32, e.total);
- HEAP16[(((fetch)+(40))>>1)] = xhr.readyState
- // If loading files from a source that does not give HTTP status code, assume success if we get data bytes
- if (xhr.readyState >= 3 && xhr.status === 0 && e.loaded > 0) xhr.status = 200;
- HEAP16[(((fetch)+(42))>>1)] = xhr.status
- if (xhr.statusText) stringToUTF8(xhr.statusText, fetch + 44, 64);
- onprogress?.(fetch, xhr, e);
- if (ptr) {
- _free(ptr);
- }
- };
- xhr.onreadystatechange = (e) => {
- // check if xhr was aborted by user and don't try to call back
- if (!Fetch.xhrs.has(id)) {
-
- return;
- }
- HEAP16[(((fetch)+(40))>>1)] = xhr.readyState
- if (xhr.readyState >= 2) {
- HEAP16[(((fetch)+(42))>>1)] = xhr.status
- }
- onreadystatechange?.(fetch, xhr, e);
- };
- try {
- xhr.send(data);
- } catch(e) {
- onerror?.(fetch, xhr, e);
- }
- }
-
- var handleException = (e) => {
- // Certain exception types we do not treat as errors since they are used for
- // internal control flow.
- // 1. ExitStatus, which is thrown by exit()
- // 2. "unwind", which is thrown by emscripten_unwind_to_js_event_loop() and others
- // that wish to return to JS event loop.
- 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 65536)');
- }
- }
- quit_(1, e);
- };
-
-
- var runtimeKeepaliveCounter = 0;
- var keepRuntimeAlive = () => noExitRuntime || runtimeKeepaliveCounter > 0;
- var _proc_exit = (code) => {
- EXITSTATUS = code;
- if (!keepRuntimeAlive()) {
- Module['onExit']?.(code);
- ABORT = true;
- }
- quit_(code, new ExitStatus(code));
- };
-
- /** @suppress {duplicate } */
- /** @param {boolean|number=} implicit */
- var exitJS = (status, implicit) => {
- EXITSTATUS = status;
-
- checkUnflushedContent();
-
- // if exit() was called explicitly, warn the user if the runtime isn't actually being shut down
- 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)`;
- err(msg);
- }
-
- _proc_exit(status);
- };
- var _exit = exitJS;
-
-
- var maybeExit = () => {
- if (!keepRuntimeAlive()) {
- try {
- _exit(EXITSTATUS);
- } catch (e) {
- handleException(e);
- }
- }
- };
- var callUserCallback = (func) => {
- if (ABORT) {
- err('user callback triggered after runtime exited or application aborted. Ignoring.');
- return;
- }
- try {
- func();
- maybeExit();
- } catch (e) {
- handleException(e);
- }
- };
-
- var readI53FromI64 = (ptr) => {
- return HEAPU32[((ptr)>>2)] + HEAP32[(((ptr)+(4))>>2)] * 4294967296;
- };
-
- var readI53FromU64 = (ptr) => {
- return HEAPU32[((ptr)>>2)] + HEAPU32[(((ptr)+(4))>>2)] * 4294967296;
- };
- var writeI53ToI64 = (ptr, num) => {
- HEAPU32[((ptr)>>2)] = num;
- var lower = HEAPU32[((ptr)>>2)];
- HEAPU32[(((ptr)+(4))>>2)] = (num - lower)/4294967296;
- var deserialized = (num >= 0) ? readI53FromU64(ptr) : readI53FromI64(ptr);
- var offset = ((ptr)>>2);
- if (deserialized != num) warnOnce(`writeI53ToI64() out of range: serialized JS Number ${num} to Wasm heap as bytes lo=${ptrToString(HEAPU32[offset])}, hi=${ptrToString(HEAPU32[offset+1])}, which deserializes back to ${deserialized} instead!`);
- };
-
-
- function fetchCacheData(/** @type {IDBDatabase} */ db, fetch, data, onsuccess, onerror) {
- if (!db) {
- onerror(fetch, 0, 'IndexedDB not available!');
- return;
- }
-
- var fetch_attr = fetch + 108;
- var destinationPath = HEAPU32[(((fetch_attr)+(64))>>2)];
- destinationPath ||= HEAPU32[(((fetch)+(8))>>2)];
- var destinationPathStr = UTF8ToString(destinationPath);
-
- try {
- var transaction = db.transaction(['FILES'], 'readwrite');
- var packages = transaction.objectStore('FILES');
- var putRequest = packages.put(data, destinationPathStr);
- putRequest.onsuccess = (event) => {
- HEAP16[(((fetch)+(40))>>1)] = 4 // Mimic XHR readyState 4 === 'DONE: The operation is complete'
- HEAP16[(((fetch)+(42))>>1)] = 200 // Mimic XHR HTTP status code 200 "OK"
- stringToUTF8("OK", fetch + 44, 64);
- onsuccess(fetch, 0, destinationPathStr);
- };
- putRequest.onerror = (error) => {
- // Most likely we got an error if IndexedDB is unwilling to store any more data for this page.
- // TODO: Can we identify and break down different IndexedDB-provided errors and convert those
- // to more HTTP status codes for more information?
- HEAP16[(((fetch)+(40))>>1)] = 4 // Mimic XHR readyState 4 === 'DONE: The operation is complete'
- HEAP16[(((fetch)+(42))>>1)] = 413 // Mimic XHR HTTP status code 413 "Payload Too Large"
- stringToUTF8("Payload Too Large", fetch + 44, 64);
- onerror(fetch, 0, error);
- };
- } catch(e) {
- onerror(fetch, 0, e);
- }
- }
-
- function fetchLoadCachedData(db, fetch, onsuccess, onerror) {
- if (!db) {
- onerror(fetch, 0, 'IndexedDB not available!');
- return;
- }
-
- var fetch_attr = fetch + 108;
- var path = HEAPU32[(((fetch_attr)+(64))>>2)];
- path ||= HEAPU32[(((fetch)+(8))>>2)];
- var pathStr = UTF8ToString(path);
-
- try {
- var transaction = db.transaction(['FILES'], 'readonly');
- var packages = transaction.objectStore('FILES');
- var getRequest = packages.get(pathStr);
- getRequest.onsuccess = (event) => {
- if (event.target.result) {
- var value = event.target.result;
- var len = value.byteLength || value.length;
- // The data pointer malloc()ed here has the same lifetime as the emscripten_fetch_t structure itself has, and is
- // freed when emscripten_fetch_close() is called.
- var ptr = _malloc(len);
- HEAPU8.set(new Uint8Array(value), ptr);
- HEAPU32[(((fetch)+(12))>>2)] = ptr;
- writeI53ToI64(fetch + 16, len);
- writeI53ToI64(fetch + 24, 0);
- writeI53ToI64(fetch + 32, len);
- HEAP16[(((fetch)+(40))>>1)] = 4 // Mimic XHR readyState 4 === 'DONE: The operation is complete'
- HEAP16[(((fetch)+(42))>>1)] = 200 // Mimic XHR HTTP status code 200 "OK"
- stringToUTF8("OK", fetch + 44, 64);
- onsuccess(fetch, 0, value);
- } else {
- // Succeeded to load, but the load came back with the value of undefined, treat that as an error since we never store undefined in db.
- HEAP16[(((fetch)+(40))>>1)] = 4 // Mimic XHR readyState 4 === 'DONE: The operation is complete'
- HEAP16[(((fetch)+(42))>>1)] = 404 // Mimic XHR HTTP status code 404 "Not Found"
- stringToUTF8("Not Found", fetch + 44, 64);
- onerror(fetch, 0, 'no data');
- }
- };
- getRequest.onerror = (error) => {
- HEAP16[(((fetch)+(40))>>1)] = 4 // Mimic XHR readyState 4 === 'DONE: The operation is complete'
- HEAP16[(((fetch)+(42))>>1)] = 404 // Mimic XHR HTTP status code 404 "Not Found"
- stringToUTF8("Not Found", fetch + 44, 64);
- onerror(fetch, 0, error);
- };
- } catch(e) {
- onerror(fetch, 0, e);
- }
- }
-
- function fetchDeleteCachedData(db, fetch, onsuccess, onerror) {
- if (!db) {
- onerror(fetch, 0, 'IndexedDB not available!');
- return;
- }
-
- var fetch_attr = fetch + 108;
- var path = HEAPU32[(((fetch_attr)+(64))>>2)];
- path ||= HEAPU32[(((fetch)+(8))>>2)];
-
- var pathStr = UTF8ToString(path);
-
- try {
- var transaction = db.transaction(['FILES'], 'readwrite');
- var packages = transaction.objectStore('FILES');
- var request = packages.delete(pathStr);
- request.onsuccess = (event) => {
- var value = event.target.result;
- HEAPU32[(((fetch)+(12))>>2)] = 0;
- writeI53ToI64(fetch + 16, 0);
- writeI53ToI64(fetch + 24, 0);
- writeI53ToI64(fetch + 32, 0);
- // Mimic XHR readyState 4 === 'DONE: The operation is complete'
- HEAP16[(((fetch)+(40))>>1)] = 4;
- // Mimic XHR HTTP status code 200 "OK"
- HEAP16[(((fetch)+(42))>>1)] = 200;
- stringToUTF8("OK", fetch + 44, 64);
- onsuccess(fetch, 0, value);
- };
- request.onerror = (error) => {
- HEAP16[(((fetch)+(40))>>1)] = 4 // Mimic XHR readyState 4 === 'DONE: The operation is complete'
- HEAP16[(((fetch)+(42))>>1)] = 404 // Mimic XHR HTTP status code 404 "Not Found"
- stringToUTF8("Not Found", fetch + 44, 64);
- onerror(fetch, 0, error);
- };
- } catch(e) {
- onerror(fetch, 0, e);
- }
- }
-
-
- function _emscripten_start_fetch(fetch, successcb, errorcb, progresscb, readystatechangecb) {
- // Avoid shutting down the runtime since we want to wait for the async
- // response.
-
-
- var fetch_attr = fetch + 108;
- var onsuccess = HEAPU32[(((fetch_attr)+(36))>>2)];
- var onerror = HEAPU32[(((fetch_attr)+(40))>>2)];
- var onprogress = HEAPU32[(((fetch_attr)+(44))>>2)];
- var onreadystatechange = HEAPU32[(((fetch_attr)+(48))>>2)];
- var fetchAttributes = HEAPU32[(((fetch_attr)+(52))>>2)];
- var fetchAttrSynchronous = !!(fetchAttributes & 64);
-
- function doCallback(f) {
- if (fetchAttrSynchronous) {
- f();
- } else {
- callUserCallback(f);
- }
- }
-
- var reportSuccess = (fetch, xhr, e) => {
-
- doCallback(() => {
- if (onsuccess) getWasmTableEntry(onsuccess)(fetch);
- else successcb?.(fetch);
- });
- };
-
- var reportProgress = (fetch, xhr, e) => {
- doCallback(() => {
- if (onprogress) getWasmTableEntry(onprogress)(fetch);
- else progresscb?.(fetch);
- });
- };
-
- var reportError = (fetch, xhr, e) => {
-
- doCallback(() => {
- if (onerror) getWasmTableEntry(onerror)(fetch);
- else errorcb?.(fetch);
- });
- };
-
- var reportReadyStateChange = (fetch, xhr, e) => {
- doCallback(() => {
- if (onreadystatechange) getWasmTableEntry(onreadystatechange)(fetch);
- else readystatechangecb?.(fetch);
- });
- };
-
- var performUncachedXhr = (fetch, xhr, e) => {
- fetchXHR(fetch, reportSuccess, reportError, reportProgress, reportReadyStateChange);
- };
-
- var cacheResultAndReportSuccess = (fetch, xhr, e) => {
- var storeSuccess = (fetch, xhr, e) => {
-
- doCallback(() => {
- if (onsuccess) getWasmTableEntry(onsuccess)(fetch);
- else successcb?.(fetch);
- });
- };
- var storeError = (fetch, xhr, e) => {
-
- doCallback(() => {
- if (onsuccess) getWasmTableEntry(onsuccess)(fetch);
- else successcb?.(fetch);
- });
- };
- fetchCacheData(Fetch.dbInstance, fetch, xhr.response, storeSuccess, storeError);
- };
-
- var performCachedXhr = (fetch, xhr, e) => {
- fetchXHR(fetch, cacheResultAndReportSuccess, reportError, reportProgress, reportReadyStateChange);
- };
-
- var requestMethod = UTF8ToString(fetch_attr + 0);
- var fetchAttrReplace = !!(fetchAttributes & 16);
- var fetchAttrPersistFile = !!(fetchAttributes & 4);
- var fetchAttrNoDownload = !!(fetchAttributes & 32);
- if (requestMethod === 'EM_IDB_STORE') {
- // TODO(?): Here we perform a clone of the data, because storing shared typed arrays to IndexedDB does not seem to be allowed.
- var ptr = HEAPU32[(((fetch_attr)+(84))>>2)];
- var size = HEAPU32[(((fetch_attr)+(88))>>2)];
- fetchCacheData(Fetch.dbInstance, fetch, HEAPU8.slice(ptr, ptr + size), reportSuccess, reportError);
- } else if (requestMethod === 'EM_IDB_DELETE') {
- fetchDeleteCachedData(Fetch.dbInstance, fetch, reportSuccess, reportError);
- } else if (!fetchAttrReplace) {
- fetchLoadCachedData(Fetch.dbInstance, fetch, reportSuccess, fetchAttrNoDownload ? reportError : (fetchAttrPersistFile ? performCachedXhr : performUncachedXhr));
- } else if (!fetchAttrNoDownload) {
- fetchXHR(fetch, fetchAttrPersistFile ? cacheResultAndReportSuccess : reportSuccess, reportError, reportProgress, reportReadyStateChange);
- } else {
- return 0; // todo: free
- }
- return fetch;
- }
-
- var GLctx;
-
- var webgl_enable_ANGLE_instanced_arrays = (ctx) => {
- // Extension available in WebGL 1 from Firefox 26 and Google Chrome 30 onwards. Core feature in WebGL 2.
- var ext = ctx.getExtension('ANGLE_instanced_arrays');
- // Because this extension is a core function in WebGL 2, assign the extension entry points in place of
- // where the core functions will reside in WebGL 2. This way the calling code can call these without
- // having to dynamically branch depending if running against WebGL 1 or WebGL 2.
- if (ext) {
- ctx['vertexAttribDivisor'] = (index, divisor) => ext['vertexAttribDivisorANGLE'](index, divisor);
- ctx['drawArraysInstanced'] = (mode, first, count, primcount) => ext['drawArraysInstancedANGLE'](mode, first, count, primcount);
- ctx['drawElementsInstanced'] = (mode, count, type, indices, primcount) => ext['drawElementsInstancedANGLE'](mode, count, type, indices, primcount);
- return 1;
- }
- };
-
- var webgl_enable_OES_vertex_array_object = (ctx) => {
- // Extension available in WebGL 1 from Firefox 25 and WebKit 536.28/desktop Safari 6.0.3 onwards. Core feature in WebGL 2.
- var ext = ctx.getExtension('OES_vertex_array_object');
- if (ext) {
- ctx['createVertexArray'] = () => ext['createVertexArrayOES']();
- ctx['deleteVertexArray'] = (vao) => ext['deleteVertexArrayOES'](vao);
- ctx['bindVertexArray'] = (vao) => ext['bindVertexArrayOES'](vao);
- ctx['isVertexArray'] = (vao) => ext['isVertexArrayOES'](vao);
- return 1;
- }
- };
-
- var webgl_enable_WEBGL_draw_buffers = (ctx) => {
- // Extension available in WebGL 1 from Firefox 28 onwards. Core feature in WebGL 2.
- var ext = ctx.getExtension('WEBGL_draw_buffers');
- if (ext) {
- ctx['drawBuffers'] = (n, bufs) => ext['drawBuffersWEBGL'](n, bufs);
- return 1;
- }
- };
-
- var webgl_enable_WEBGL_draw_instanced_base_vertex_base_instance = (ctx) =>
- // Closure is expected to be allowed to minify the '.dibvbi' property, so not accessing it quoted.
- !!(ctx.dibvbi = ctx.getExtension('WEBGL_draw_instanced_base_vertex_base_instance'));
-
- var webgl_enable_WEBGL_multi_draw_instanced_base_vertex_base_instance = (ctx) => {
- // Closure is expected to be allowed to minify the '.mdibvbi' property, so not accessing it quoted.
- return !!(ctx.mdibvbi = ctx.getExtension('WEBGL_multi_draw_instanced_base_vertex_base_instance'));
- };
-
- var webgl_enable_EXT_polygon_offset_clamp = (ctx) => {
- return !!(ctx.extPolygonOffsetClamp = ctx.getExtension('EXT_polygon_offset_clamp'));
- };
-
- var webgl_enable_EXT_clip_control = (ctx) => {
- return !!(ctx.extClipControl = ctx.getExtension('EXT_clip_control'));
- };
-
- var webgl_enable_WEBGL_polygon_mode = (ctx) => {
- return !!(ctx.webglPolygonMode = ctx.getExtension('WEBGL_polygon_mode'));
- };
-
- var webgl_enable_WEBGL_multi_draw = (ctx) => {
- // Closure is expected to be allowed to minify the '.multiDrawWebgl' property, so not accessing it quoted.
- return !!(ctx.multiDrawWebgl = ctx.getExtension('WEBGL_multi_draw'));
- };
-
- var getEmscriptenSupportedExtensions = (ctx) => {
- // Restrict the list of advertised extensions to those that we actually
- // support.
- var supportedExtensions = [
- // WebGL 1 extensions
- 'ANGLE_instanced_arrays',
- 'EXT_blend_minmax',
- 'EXT_disjoint_timer_query',
- 'EXT_frag_depth',
- 'EXT_shader_texture_lod',
- 'EXT_sRGB',
- 'OES_element_index_uint',
- 'OES_fbo_render_mipmap',
- 'OES_standard_derivatives',
- 'OES_texture_float',
- 'OES_texture_half_float',
- 'OES_texture_half_float_linear',
- 'OES_vertex_array_object',
- 'WEBGL_color_buffer_float',
- 'WEBGL_depth_texture',
- 'WEBGL_draw_buffers',
- // WebGL 2 extensions
- 'EXT_color_buffer_float',
- 'EXT_conservative_depth',
- 'EXT_disjoint_timer_query_webgl2',
- 'EXT_texture_norm16',
- 'NV_shader_noperspective_interpolation',
- 'WEBGL_clip_cull_distance',
- // WebGL 1 and WebGL 2 extensions
- 'EXT_clip_control',
- 'EXT_color_buffer_half_float',
- 'EXT_depth_clamp',
- 'EXT_float_blend',
- 'EXT_polygon_offset_clamp',
- 'EXT_texture_compression_bptc',
- 'EXT_texture_compression_rgtc',
- 'EXT_texture_filter_anisotropic',
- 'KHR_parallel_shader_compile',
- 'OES_texture_float_linear',
- 'WEBGL_blend_func_extended',
- 'WEBGL_compressed_texture_astc',
- 'WEBGL_compressed_texture_etc',
- 'WEBGL_compressed_texture_etc1',
- 'WEBGL_compressed_texture_s3tc',
- 'WEBGL_compressed_texture_s3tc_srgb',
- 'WEBGL_debug_renderer_info',
- 'WEBGL_debug_shaders',
- 'WEBGL_lose_context',
- 'WEBGL_multi_draw',
- 'WEBGL_polygon_mode'
- ];
- // .getSupportedExtensions() can return null if context is lost, so coerce to empty array.
- return (ctx.getSupportedExtensions() || []).filter(ext => supportedExtensions.includes(ext));
- };
-
- var registerPreMainLoop = (f) => {
- // Does nothing unless $MainLoop is included/used.
- typeof MainLoop != 'undefined' && MainLoop.preMainLoop.push(f);
- };
-
-
- var GL = {
- counter:1,
- buffers:[],
- mappedBuffers:{
- },
- programs:[],
- framebuffers:[],
- renderbuffers:[],
- textures:[],
- shaders:[],
- vaos:[],
- contexts:[],
- offscreenCanvases:{
- },
- queries:[],
- samplers:[],
- transformFeedbacks:[],
- syncs:[],
- byteSizeByTypeRoot:5120,
- byteSizeByType:[1,1,2,2,4,4,4,2,3,4,8],
- stringCache:{
- },
- stringiCache:{
- },
- unpackAlignment:4,
- unpackRowLength:0,
- recordError:(errorCode) => {
- if (!GL.lastError) {
- GL.lastError = errorCode;
- }
- },
- getNewId:(table) => {
- var ret = GL.counter++;
- for (var i = table.length; i < ret; i++) {
- table[i] = null;
- }
- return ret;
- },
- genObject:(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(0x502 /* GL_INVALID_OPERATION */);
- }
- HEAP32[(((buffers)+(i*4))>>2)] = id;
- }
- },
- MAX_TEMP_BUFFER_SIZE:2097152,
- numTempVertexBuffersPerSize:64,
- log2ceilLookup:(i) => 32 - Math.clz32(i === 0 ? 0 : i - 1),
- generateTempBuffers:(quads, context) => {
- var largestIndex = GL.log2ceilLookup(GL.MAX_TEMP_BUFFER_SIZE);
- context.tempVertexBufferCounters1 = [];
- context.tempVertexBufferCounters2 = [];
- context.tempVertexBufferCounters1.length = context.tempVertexBufferCounters2.length = largestIndex+1;
- context.tempVertexBuffers1 = [];
- context.tempVertexBuffers2 = [];
- context.tempVertexBuffers1.length = context.tempVertexBuffers2.length = largestIndex+1;
- context.tempIndexBuffers = [];
- context.tempIndexBuffers.length = largestIndex+1;
- for (var i = 0; i <= largestIndex; ++i) {
- context.tempIndexBuffers[i] = null; // Created on-demand
- context.tempVertexBufferCounters1[i] = context.tempVertexBufferCounters2[i] = 0;
- var ringbufferLength = GL.numTempVertexBuffersPerSize;
- context.tempVertexBuffers1[i] = [];
- context.tempVertexBuffers2[i] = [];
- var ringbuffer1 = context.tempVertexBuffers1[i];
- var ringbuffer2 = context.tempVertexBuffers2[i];
- ringbuffer1.length = ringbuffer2.length = ringbufferLength;
- for (var j = 0; j < ringbufferLength; ++j) {
- ringbuffer1[j] = ringbuffer2[j] = null; // Created on-demand
- }
- }
-
- if (quads) {
- // GL_QUAD indexes can be precalculated
- context.tempQuadIndexBuffer = GLctx.createBuffer();
- context.GLctx.bindBuffer(0x8893 /*GL_ELEMENT_ARRAY_BUFFER*/, context.tempQuadIndexBuffer);
- var numIndexes = GL.MAX_TEMP_BUFFER_SIZE >> 1;
- var quadIndexes = new Uint16Array(numIndexes);
- var i = 0, v = 0;
- while (1) {
- quadIndexes[i++] = v;
- if (i >= numIndexes) break;
- quadIndexes[i++] = v+1;
- if (i >= numIndexes) break;
- quadIndexes[i++] = v+2;
- if (i >= numIndexes) break;
- quadIndexes[i++] = v;
- if (i >= numIndexes) break;
- quadIndexes[i++] = v+2;
- if (i >= numIndexes) break;
- quadIndexes[i++] = v+3;
- if (i >= numIndexes) break;
- v += 4;
- }
- context.GLctx.bufferData(0x8893 /*GL_ELEMENT_ARRAY_BUFFER*/, quadIndexes, 0x88E4 /*GL_STATIC_DRAW*/);
- context.GLctx.bindBuffer(0x8893 /*GL_ELEMENT_ARRAY_BUFFER*/, null);
- }
- },
- getTempVertexBuffer:(sizeBytes) => {
- var idx = GL.log2ceilLookup(sizeBytes);
- var ringbuffer = GL.currentContext.tempVertexBuffers1[idx];
- var nextFreeBufferIndex = GL.currentContext.tempVertexBufferCounters1[idx];
- GL.currentContext.tempVertexBufferCounters1[idx] = (GL.currentContext.tempVertexBufferCounters1[idx]+1) & (GL.numTempVertexBuffersPerSize-1);
- var vbo = ringbuffer[nextFreeBufferIndex];
- if (vbo) {
- return vbo;
- }
- var prevVBO = GLctx.getParameter(0x8894 /*GL_ARRAY_BUFFER_BINDING*/);
- ringbuffer[nextFreeBufferIndex] = GLctx.createBuffer();
- GLctx.bindBuffer(0x8892 /*GL_ARRAY_BUFFER*/, ringbuffer[nextFreeBufferIndex]);
- GLctx.bufferData(0x8892 /*GL_ARRAY_BUFFER*/, 1 << idx, 0x88E8 /*GL_DYNAMIC_DRAW*/);
- GLctx.bindBuffer(0x8892 /*GL_ARRAY_BUFFER*/, prevVBO);
- return ringbuffer[nextFreeBufferIndex];
- },
- getTempIndexBuffer:(sizeBytes) => {
- var idx = GL.log2ceilLookup(sizeBytes);
- var ibo = GL.currentContext.tempIndexBuffers[idx];
- if (ibo) {
- return ibo;
- }
- var prevIBO = GLctx.getParameter(0x8895 /*ELEMENT_ARRAY_BUFFER_BINDING*/);
- GL.currentContext.tempIndexBuffers[idx] = GLctx.createBuffer();
- GLctx.bindBuffer(0x8893 /*GL_ELEMENT_ARRAY_BUFFER*/, GL.currentContext.tempIndexBuffers[idx]);
- GLctx.bufferData(0x8893 /*GL_ELEMENT_ARRAY_BUFFER*/, 1 << idx, 0x88E8 /*GL_DYNAMIC_DRAW*/);
- GLctx.bindBuffer(0x8893 /*GL_ELEMENT_ARRAY_BUFFER*/, prevIBO);
- return GL.currentContext.tempIndexBuffers[idx];
- },
- newRenderingFrameStarted:() => {
- if (!GL.currentContext) {
- return;
- }
- var vb = GL.currentContext.tempVertexBuffers1;
- GL.currentContext.tempVertexBuffers1 = GL.currentContext.tempVertexBuffers2;
- GL.currentContext.tempVertexBuffers2 = vb;
- vb = GL.currentContext.tempVertexBufferCounters1;
- GL.currentContext.tempVertexBufferCounters1 = GL.currentContext.tempVertexBufferCounters2;
- GL.currentContext.tempVertexBufferCounters2 = vb;
- var largestIndex = GL.log2ceilLookup(GL.MAX_TEMP_BUFFER_SIZE);
- for (var i = 0; i <= largestIndex; ++i) {
- GL.currentContext.tempVertexBufferCounters1[i] = 0;
- }
- },
- getSource:(shader, count, string, length) => {
- var source = '';
- for (var i = 0; i < count; ++i) {
- var len = length ? HEAPU32[(((length)+(i*4))>>2)] : undefined;
- source += UTF8ToString(HEAPU32[(((string)+(i*4))>>2)], len);
- }
- return source;
- },
- calcBufLength:(size, type, stride, count) => {
- if (stride > 0) {
- return count * stride; // XXXvlad this is not exactly correct I don't think
- }
- var typeSize = GL.byteSizeByType[type - GL.byteSizeByTypeRoot];
- return size * typeSize * count;
- },
- usedTempBuffers:[],
- preDrawHandleClientVertexAttribBindings:(count) => {
- GL.resetBufferBinding = false;
-
- // TODO: initial pass to detect ranges we need to upload, might not need
- // an upload per attrib
- for (var i = 0; i < GL.currentContext.maxVertexAttribs; ++i) {
- var cb = GL.currentContext.clientBuffers[i];
- if (!cb.clientside || !cb.enabled) continue;
-
- GL.resetBufferBinding = true;
-
- var size = GL.calcBufLength(cb.size, cb.type, cb.stride, count);
- var buf = GL.getTempVertexBuffer(size);
- GLctx.bindBuffer(0x8892 /*GL_ARRAY_BUFFER*/, buf);
- GLctx.bufferSubData(0x8892 /*GL_ARRAY_BUFFER*/,
- 0,
- HEAPU8.subarray(cb.ptr, cb.ptr + size));
- cb.vertexAttribPointerAdaptor.call(GLctx, i, cb.size, cb.type, cb.normalized, cb.stride, 0);
- }
- },
- postDrawHandleClientVertexAttribBindings:() => {
- if (GL.resetBufferBinding) {
- GLctx.bindBuffer(0x8892 /*GL_ARRAY_BUFFER*/, GL.buffers[GLctx.currentArrayBufferBinding]);
- }
- },
- createContext:(/** @type {HTMLCanvasElement} */ canvas, webGLContextAttributes) => {
-
- // BUG: Workaround Safari WebGL issue: After successfully acquiring WebGL
- // context on a canvas, calling .getContext() will always return that
- // context independent of which 'webgl' or 'webgl2'
- // context version was passed. See:
- // https://bugs.webkit.org/show_bug.cgi?id=222758
- // and:
- // https://github.com/emscripten-core/emscripten/issues/13295.
- // TODO: Once the bug is fixed and shipped in Safari, adjust the Safari
- // version field in above check.
- if (!canvas.getContextSafariWebGL2Fixed) {
- canvas.getContextSafariWebGL2Fixed = canvas.getContext;
- /** @type {function(this:HTMLCanvasElement, string, (Object|null)=): (Object|null)} */
- function fixedGetContext(ver, attrs) {
- var gl = canvas.getContextSafariWebGL2Fixed(ver, attrs);
- return ((ver == 'webgl') == (gl instanceof WebGLRenderingContext)) ? gl : null;
- }
- canvas.getContext = fixedGetContext;
- }
-
- var ctx =
- (webGLContextAttributes.majorVersion > 1)
- ?
- canvas.getContext("webgl2", webGLContextAttributes)
- :
- (canvas.getContext("webgl", webGLContextAttributes)
- // https://caniuse.com/#feat=webgl
- );
-
- if (!ctx) return 0;
-
- var handle = GL.registerContext(ctx, webGLContextAttributes);
-
- return handle;
- },
- registerContext:(ctx, webGLContextAttributes) => {
- // without pthreads a context is just an integer ID
- var handle = GL.getNewId(GL.contexts);
-
- var context = {
- handle,
- attributes: webGLContextAttributes,
- version: webGLContextAttributes.majorVersion,
- GLctx: ctx
- };
-
- // Store the created context object so that we can access the context
- // given a canvas without having to pass the parameters again.
- if (ctx.canvas) ctx.canvas.GLctxObject = context;
- GL.contexts[handle] = context;
- if (typeof webGLContextAttributes.enableExtensionsByDefault == 'undefined' || webGLContextAttributes.enableExtensionsByDefault) {
- GL.initExtensions(context);
- }
-
- context.maxVertexAttribs = context.GLctx.getParameter(0x8869 /*GL_MAX_VERTEX_ATTRIBS*/);
- context.clientBuffers = [];
- for (var i = 0; i < context.maxVertexAttribs; i++) {
- context.clientBuffers[i] = {
- enabled: false,
- clientside: false,
- size: 0,
- type: 0,
- normalized: 0,
- stride: 0,
- ptr: 0,
- vertexAttribPointerAdaptor: null,
- };
- }
-
- GL.generateTempBuffers(false, context);
-
- return handle;
- },
- makeContextCurrent:(contextHandle) => {
-
- // Active Emscripten GL layer context object.
- GL.currentContext = GL.contexts[contextHandle];
- // Active WebGL context object.
- Module.ctx = GLctx = GL.currentContext?.GLctx;
- return !(contextHandle && !GLctx);
- },
- getContext:(contextHandle) => {
- return GL.contexts[contextHandle];
- },
- deleteContext:(contextHandle) => {
- if (GL.currentContext === GL.contexts[contextHandle]) {
- GL.currentContext = null;
- }
- if (typeof JSEvents == 'object') {
- // Release all JS event handlers on the DOM element that the GL context is
- // associated with since the context is now deleted.
- JSEvents.removeAllHandlersOnTarget(GL.contexts[contextHandle].GLctx.canvas);
- }
- // Make sure the canvas object no longer refers to the context object so
- // there are no GC surprises.
- if (GL.contexts[contextHandle] && GL.contexts[contextHandle].GLctx.canvas) {
- GL.contexts[contextHandle].GLctx.canvas.GLctxObject = undefined;
- }
- GL.contexts[contextHandle] = null;
- },
- initExtensions:(context) => {
- // If this function is called without a specific context object, init the
- // extensions of the currently active context.
- context ||= GL.currentContext;
-
- if (context.initExtensionsDone) return;
- context.initExtensionsDone = true;
-
- var GLctx = context.GLctx;
-
- // Detect the presence of a few extensions manually, ction GL interop
- // layer itself will need to know if they exist.
-
- // Extensions that are available in both WebGL 1 and WebGL 2
- webgl_enable_WEBGL_multi_draw(GLctx);
- webgl_enable_EXT_polygon_offset_clamp(GLctx);
- webgl_enable_EXT_clip_control(GLctx);
- webgl_enable_WEBGL_polygon_mode(GLctx);
- // Extensions that are only available in WebGL 1 (the calls will be no-ops
- // if called on a WebGL 2 context active)
- webgl_enable_ANGLE_instanced_arrays(GLctx);
- webgl_enable_OES_vertex_array_object(GLctx);
- webgl_enable_WEBGL_draw_buffers(GLctx);
- // Extensions that are available from WebGL >= 2 (no-op if called on a WebGL 1 context active)
- webgl_enable_WEBGL_draw_instanced_base_vertex_base_instance(GLctx);
- webgl_enable_WEBGL_multi_draw_instanced_base_vertex_base_instance(GLctx);
-
- // On WebGL 2, EXT_disjoint_timer_query is replaced with an alternative
- // that's based on core APIs, and exposes only the queryCounterEXT()
- // entrypoint.
- if (context.version >= 2) {
- GLctx.disjointTimerQueryExt = GLctx.getExtension("EXT_disjoint_timer_query_webgl2");
- }
-
- // However, Firefox exposes the WebGL 1 version on WebGL 2 as well and
- // thus we look for the WebGL 1 version again if the WebGL 2 version
- // isn't present. https://bugzilla.mozilla.org/show_bug.cgi?id=1328882
- if (context.version < 2 || !GLctx.disjointTimerQueryExt)
- {
- GLctx.disjointTimerQueryExt = GLctx.getExtension("EXT_disjoint_timer_query");
- }
-
- getEmscriptenSupportedExtensions(GLctx).forEach((ext) => {
- // WEBGL_lose_context, WEBGL_debug_renderer_info and WEBGL_debug_shaders
- // are not enabled by default.
- if (!ext.includes('lose_context') && !ext.includes('debug')) {
- // Call .getExtension() to enable that extension permanently.
- GLctx.getExtension(ext);
- }
- });
- },
- };
-
-
- var webglPowerPreferences = ["default","low-power","high-performance"];
-
-
-
- /** @suppress {duplicate } */
- var _emscripten_webgl_do_create_context = (target, attributes) => {
- assert(attributes);
- var attr32 = ((attributes)>>2);
- var powerPreference = HEAP32[attr32 + (8>>2)];
- var contextAttributes = {
- 'alpha': !!HEAP8[attributes + 0],
- 'depth': !!HEAP8[attributes + 1],
- 'stencil': !!HEAP8[attributes + 2],
- 'antialias': !!HEAP8[attributes + 3],
- 'premultipliedAlpha': !!HEAP8[attributes + 4],
- 'preserveDrawingBuffer': !!HEAP8[attributes + 5],
- 'powerPreference': webglPowerPreferences[powerPreference],
- 'failIfMajorPerformanceCaveat': !!HEAP8[attributes + 12],
- // The following are not predefined WebGL context attributes in the WebGL specification, so the property names can be minified by Closure.
- majorVersion: HEAP32[attr32 + (16>>2)],
- minorVersion: HEAP32[attr32 + (20>>2)],
- enableExtensionsByDefault: HEAP8[attributes + 24],
- explicitSwapControl: HEAP8[attributes + 25],
- proxyContextToMainThread: HEAP32[attr32 + (28>>2)],
- renderViaOffscreenBackBuffer: HEAP8[attributes + 32]
- };
-
- var canvas = findCanvasEventTarget(target);
-
- if (!canvas) {
- return 0;
- }
-
- if (contextAttributes.explicitSwapControl) {
- return 0;
- }
-
- var contextHandle = GL.createContext(canvas, contextAttributes);
- return contextHandle;
- };
- var _emscripten_webgl_create_context = _emscripten_webgl_do_create_context;
-
- var _emscripten_webgl_make_context_current = (contextHandle) => {
- var success = GL.makeContextCurrent(contextHandle);
- return success ? 0 : -5;
- };
-
- var SYSCALLS = {
- varargs:undefined,
- getStr(ptr) {
- var ret = UTF8ToString(ptr);
- return ret;
- },
- };
- var _fd_close = (fd) => {
- abort('fd_close called without SYSCALLS_REQUIRE_FILESYSTEM');
- };
-
- function _fd_seek(fd,offset_low, offset_high,whence,newOffset) {
- var offset = convertI32PairToI53Checked(offset_low, offset_high);
-
-
- return 70;
- ;
- }
-
- var printCharBuffers = [null,[],[]];
-
- var printChar = (stream, curr) => {
- var buffer = printCharBuffers[stream];
- assert(buffer);
- if (curr === 0 || curr === 10) {
- (stream === 1 ? out : err)(UTF8ArrayToString(buffer));
- buffer.length = 0;
- } else {
- buffer.push(curr);
- }
- };
-
- var flush_NO_FILESYSTEM = () => {
- // flush anything remaining in the buffers during shutdown
- _fflush(0);
- if (printCharBuffers[1].length) printChar(1, 10);
- if (printCharBuffers[2].length) printChar(2, 10);
- };
-
-
- var _fd_write = (fd, iov, iovcnt, pnum) => {
- // hack to support printf in SYSCALLS_REQUIRE_FILESYSTEM=0
- var num = 0;
- for (var i = 0; i < iovcnt; i++) {
- var ptr = HEAPU32[((iov)>>2)];
- var len = HEAPU32[(((iov)+(4))>>2)];
- iov += 8;
- for (var j = 0; j < len; j++) {
- printChar(fd, HEAPU8[ptr+j]);
- }
- num += len;
- }
- HEAPU32[((pnum)>>2)] = num;
- return 0;
- };
-
- var _glAttachShader = (program, shader) => {
- GLctx.attachShader(GL.programs[program], GL.shaders[shader]);
- };
-
- var _glBindBuffer = (target, buffer) => {
- if (target == 0x8892 /*GL_ARRAY_BUFFER*/) {
- GLctx.currentArrayBufferBinding = buffer;
- } else if (target == 0x8893 /*GL_ELEMENT_ARRAY_BUFFER*/) {
- GLctx.currentElementArrayBufferBinding = buffer;
- }
-
- if (target == 0x88EB /*GL_PIXEL_PACK_BUFFER*/) {
- // In WebGL 2 glReadPixels entry point, we need to use a different WebGL 2
- // API function call when a buffer is bound to
- // GL_PIXEL_PACK_BUFFER_BINDING point, so must keep track whether that
- // binding point is non-null to know what is the proper API function to
- // call.
- GLctx.currentPixelPackBufferBinding = buffer;
- } else if (target == 0x88EC /*GL_PIXEL_UNPACK_BUFFER*/) {
- // In WebGL 2 gl(Compressed)Tex(Sub)Image[23]D entry points, we need to
- // use a different WebGL 2 API function call when a buffer is bound to
- // GL_PIXEL_UNPACK_BUFFER_BINDING point, so must keep track whether that
- // binding point is non-null to know what is the proper API function to
- // call.
- GLctx.currentPixelUnpackBufferBinding = buffer;
- }
- GLctx.bindBuffer(target, GL.buffers[buffer]);
- };
-
- var _glBindVertexArray = (vao) => {
- GLctx.bindVertexArray(GL.vaos[vao]);
- var ibo = GLctx.getParameter(0x8895 /*ELEMENT_ARRAY_BUFFER_BINDING*/);
- GLctx.currentElementArrayBufferBinding = ibo ? (ibo.name | 0) : 0;
- };
-
- var _glBlendFunc = (x0, x1) => GLctx.blendFunc(x0, x1);
-
- var _glBufferData = (target, size, data, usage) => {
-
- if (GL.currentContext.version >= 2) {
- // If size is zero, WebGL would interpret uploading the whole input
- // arraybuffer (starting from given offset), which would not make sense in
- // WebAssembly, so avoid uploading if size is zero. However we must still
- // call bufferData to establish a backing storage of zero bytes.
- if (data && size) {
- GLctx.bufferData(target, HEAPU8, usage, data, size);
- } else {
- GLctx.bufferData(target, size, usage);
- }
- return;
- }
- // N.b. here first form specifies a heap subarray, second form an integer
- // size, so the ?: code here is polymorphic. It is advised to avoid
- // randomly mixing both uses in calling code, to avoid any potential JS
- // engine JIT issues.
- GLctx.bufferData(target, data ? HEAPU8.subarray(data, data+size) : size, usage);
- };
-
- var _glBufferSubData = (target, offset, size, data) => {
- if (GL.currentContext.version >= 2) {
- size && GLctx.bufferSubData(target, offset, HEAPU8, data, size);
- return;
- }
- GLctx.bufferSubData(target, offset, HEAPU8.subarray(data, data+size));
- };
-
- var _glClear = (x0) => GLctx.clear(x0);
-
- var _glClearColor = (x0, x1, x2, x3) => GLctx.clearColor(x0, x1, x2, x3);
-
- var _glClearDepth = (x0) => GLctx.clearDepth(x0);
-
- var _glCompileShader = (shader) => {
- GLctx.compileShader(GL.shaders[shader]);
- };
-
- var _glCreateProgram = () => {
- var id = GL.getNewId(GL.programs);
- var program = GLctx.createProgram();
- // Store additional information needed for each shader program:
- program.name = id;
- // Lazy cache results of
- // glGetProgramiv(GL_ACTIVE_UNIFORM_MAX_LENGTH/GL_ACTIVE_ATTRIBUTE_MAX_LENGTH/GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH)
- program.maxUniformLength = program.maxAttributeLength = program.maxUniformBlockNameLength = 0;
- program.uniformIdCounter = 1;
- GL.programs[id] = program;
- return id;
- };
-
- var _glCreateShader = (shaderType) => {
- var id = GL.getNewId(GL.shaders);
- GL.shaders[id] = GLctx.createShader(shaderType);
-
- return id;
- };
-
- var _glDeleteBuffers = (n, buffers) => {
- for (var i = 0; i < n; i++) {
- var id = HEAP32[(((buffers)+(i*4))>>2)];
- var buffer = GL.buffers[id];
-
- // From spec: "glDeleteBuffers silently ignores 0's and names that do not
- // correspond to existing buffer objects."
- if (!buffer) continue;
-
- GLctx.deleteBuffer(buffer);
- buffer.name = 0;
- GL.buffers[id] = null;
-
- if (id == GLctx.currentArrayBufferBinding) GLctx.currentArrayBufferBinding = 0;
- if (id == GLctx.currentElementArrayBufferBinding) GLctx.currentElementArrayBufferBinding = 0;
- if (id == GLctx.currentPixelPackBufferBinding) GLctx.currentPixelPackBufferBinding = 0;
- if (id == GLctx.currentPixelUnpackBufferBinding) GLctx.currentPixelUnpackBufferBinding = 0;
- }
- };
-
- var _glDeleteProgram = (id) => {
- if (!id) return;
- var program = GL.programs[id];
- if (!program) {
- // glDeleteProgram actually signals an error when deleting a nonexisting
- // object, unlike some other GL delete functions.
- GL.recordError(0x501 /* GL_INVALID_VALUE */);
- return;
- }
- GLctx.deleteProgram(program);
- program.name = 0;
- GL.programs[id] = null;
- };
-
- var _glDeleteShader = (id) => {
- if (!id) return;
- var shader = GL.shaders[id];
- if (!shader) {
- // glDeleteShader actually signals an error when deleting a nonexisting
- // object, unlike some other GL delete functions.
- GL.recordError(0x501 /* GL_INVALID_VALUE */);
- return;
- }
- GLctx.deleteShader(shader);
- GL.shaders[id] = null;
- };
-
- var _glDeleteVertexArrays = (n, vaos) => {
- for (var i = 0; i < n; i++) {
- var id = HEAP32[(((vaos)+(i*4))>>2)];
- GLctx.deleteVertexArray(GL.vaos[id]);
- GL.vaos[id] = null;
- }
- };
-
- var _glDepthFunc = (x0) => GLctx.depthFunc(x0);
-
- var _glDepthMask = (flag) => {
- GLctx.depthMask(!!flag);
- };
-
- var _glDrawArrays = (mode, first, count) => {
- // bind any client-side buffers
- GL.preDrawHandleClientVertexAttribBindings(first + count);
-
- GLctx.drawArrays(mode, first, count);
-
- GL.postDrawHandleClientVertexAttribBindings();
- };
-
- var _glDrawArraysInstanced = (mode, first, count, primcount) => {
- GLctx.drawArraysInstanced(mode, first, count, primcount);
- };
-
- var _glDrawElements = (mode, count, type, indices) => {
- var buf;
- var vertexes = 0;
- if (!GLctx.currentElementArrayBufferBinding) {
- var size = GL.calcBufLength(1, type, 0, count);
- buf = GL.getTempIndexBuffer(size);
- GLctx.bindBuffer(0x8893 /*GL_ELEMENT_ARRAY_BUFFER*/, buf);
- GLctx.bufferSubData(0x8893 /*GL_ELEMENT_ARRAY_BUFFER*/,
- 0,
- HEAPU8.subarray(indices, indices + size));
-
- // Calculating vertex count if shader's attribute data is on client side
- if (count > 0) {
- for (var i = 0; i < GL.currentContext.maxVertexAttribs; ++i) {
- var cb = GL.currentContext.clientBuffers[i];
- if (cb.clientside && cb.enabled) {
- let arrayClass;
- switch(type) {
- case 0x1401 /* GL_UNSIGNED_BYTE */: arrayClass = Uint8Array; break;
- case 0x1403 /* GL_UNSIGNED_SHORT */: arrayClass = Uint16Array; break;
- case 0x1405 /* GL_UNSIGNED_INT */: arrayClass = Uint32Array; break;
- default:
- GL.recordError(0x502 /* GL_INVALID_OPERATION */);
- return;
- }
-
- vertexes = new arrayClass(HEAPU8.buffer, indices, count).reduce((max, current) => Math.max(max, current)) + 1;
- break;
- }
- }
- }
-
- // the index is now 0
- indices = 0;
- }
-
- // bind any client-side buffers
- GL.preDrawHandleClientVertexAttribBindings(vertexes);
-
- GLctx.drawElements(mode, count, type, indices);
-
- GL.postDrawHandleClientVertexAttribBindings(count);
-
- if (!GLctx.currentElementArrayBufferBinding) {
- GLctx.bindBuffer(0x8893 /*GL_ELEMENT_ARRAY_BUFFER*/, null);
- }
- };
-
- var _glEnable = (x0) => GLctx.enable(x0);
-
- var _glEnableVertexAttribArray = (index) => {
- var cb = GL.currentContext.clientBuffers[index];
- cb.enabled = true;
- GLctx.enableVertexAttribArray(index);
- };
-
- var _glGenBuffers = (n, buffers) => {
- GL.genObject(n, buffers, 'createBuffer', GL.buffers
- );
- };
-
- var _glGenVertexArrays = (n, arrays) => {
- GL.genObject(n, arrays, 'createVertexArray', GL.vaos
- );
- };
-
-
- var _glGetAttribLocation = (program, name) => {
- return GLctx.getAttribLocation(GL.programs[program], UTF8ToString(name));
- };
-
- var _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) HEAP32[((length)>>2)] = numBytesWrittenExclNull;
- };
-
- var _glGetProgramiv = (program, pname, p) => {
- if (!p) {
- // GLES2 specification does not specify how to behave if p is a null
- // pointer. Since calling this function does not make sense if p == null,
- // issue a GL error to notify user about it.
- GL.recordError(0x501 /* GL_INVALID_VALUE */);
- return;
- }
-
- if (program >= GL.counter) {
- GL.recordError(0x501 /* GL_INVALID_VALUE */);
- return;
- }
-
- program = GL.programs[program];
-
- if (pname == 0x8B84) { // GL_INFO_LOG_LENGTH
- var log = GLctx.getProgramInfoLog(program);
- if (log === null) log = '(unknown error)';
- HEAP32[((p)>>2)] = log.length + 1;
- } else if (pname == 0x8B87 /* GL_ACTIVE_UNIFORM_MAX_LENGTH */) {
- if (!program.maxUniformLength) {
- var numActiveUniforms = GLctx.getProgramParameter(program, 0x8B86/*GL_ACTIVE_UNIFORMS*/);
- for (var i = 0; i < numActiveUniforms; ++i) {
- program.maxUniformLength = Math.max(program.maxUniformLength, GLctx.getActiveUniform(program, i).name.length+1);
- }
- }
- HEAP32[((p)>>2)] = program.maxUniformLength;
- } else if (pname == 0x8B8A /* GL_ACTIVE_ATTRIBUTE_MAX_LENGTH */) {
- if (!program.maxAttributeLength) {
- var numActiveAttributes = GLctx.getProgramParameter(program, 0x8B89/*GL_ACTIVE_ATTRIBUTES*/);
- for (var i = 0; i < numActiveAttributes; ++i) {
- program.maxAttributeLength = Math.max(program.maxAttributeLength, GLctx.getActiveAttrib(program, i).name.length+1);
- }
- }
- HEAP32[((p)>>2)] = program.maxAttributeLength;
- } else if (pname == 0x8A35 /* GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH */) {
- if (!program.maxUniformBlockNameLength) {
- var numActiveUniformBlocks = GLctx.getProgramParameter(program, 0x8A36/*GL_ACTIVE_UNIFORM_BLOCKS*/);
- for (var i = 0; i < numActiveUniformBlocks; ++i) {
- program.maxUniformBlockNameLength = Math.max(program.maxUniformBlockNameLength, GLctx.getActiveUniformBlockName(program, i).length+1);
- }
- }
- HEAP32[((p)>>2)] = program.maxUniformBlockNameLength;
- } else {
- HEAP32[((p)>>2)] = GLctx.getProgramParameter(program, pname);
- }
- };
-
-
- var _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) HEAP32[((length)>>2)] = numBytesWrittenExclNull;
- };
-
- var _glGetShaderiv = (shader, pname, p) => {
- if (!p) {
- // GLES2 specification does not specify how to behave if p is a null
- // pointer. Since calling this function does not make sense if p == null,
- // issue a GL error to notify user about it.
- GL.recordError(0x501 /* GL_INVALID_VALUE */);
- return;
- }
- if (pname == 0x8B84) { // GL_INFO_LOG_LENGTH
- var log = GLctx.getShaderInfoLog(GL.shaders[shader]);
- if (log === null) log = '(unknown error)';
- // The GLES2 specification says that if the shader has an empty info log,
- // a value of 0 is returned. Otherwise the log has a null char appended.
- // (An empty string is falsey, so we can just check that instead of
- // looking at log.length.)
- var logLength = log ? log.length + 1 : 0;
- HEAP32[((p)>>2)] = logLength;
- } else if (pname == 0x8B88) { // GL_SHADER_SOURCE_LENGTH
- var source = GLctx.getShaderSource(GL.shaders[shader]);
- // source may be a null, or the empty string, both of which are falsey
- // values that we report a 0 length for.
- var sourceLength = source ? source.length + 1 : 0;
- HEAP32[((p)>>2)] = sourceLength;
- } else {
- HEAP32[((p)>>2)] = GLctx.getShaderParameter(GL.shaders[shader], pname);
- }
- };
-
- /** @suppress {checkTypes} */
- var jstoi_q = (str) => parseInt(str);
-
- /** @noinline */
- var webglGetLeftBracePos = (name) => name.slice(-1) == ']' && name.lastIndexOf('[');
-
- var webglPrepareUniformLocationsBeforeFirstUse = (program) => {
- var uniformLocsById = program.uniformLocsById, // Maps GLuint -> WebGLUniformLocation
- uniformSizeAndIdsByName = program.uniformSizeAndIdsByName, // Maps name -> [uniform array length, GLuint]
- i, j;
-
- // On the first time invocation of glGetUniformLocation on this shader program:
- // initialize cache data structures and discover which uniforms are arrays.
- if (!uniformLocsById) {
- // maps GLint integer locations to WebGLUniformLocations
- program.uniformLocsById = uniformLocsById = {};
- // maps integer locations back to uniform name strings, so that we can lazily fetch uniform array locations
- program.uniformArrayNamesById = {};
-
- var numActiveUniforms = GLctx.getProgramParameter(program, 0x8B86/*GL_ACTIVE_UNIFORMS*/);
- for (i = 0; i < numActiveUniforms; ++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;
-
- // Assign a new location.
- var id = program.uniformIdCounter;
- program.uniformIdCounter += sz;
- // Eagerly get the location of the uniformArray[0] base element.
- // The remaining indices >0 will be left for lazy evaluation to
- // improve performance. Those may never be needed to fetch, if the
- // application fills arrays always in full starting from the first
- // element of the array.
- uniformSizeAndIdsByName[arrayName] = [sz, id];
-
- // Store placeholder integers in place that highlight that these
- // >0 index locations are array indices pending population.
- for (j = 0; j < sz; ++j) {
- uniformLocsById[id] = j;
- program.uniformArrayNamesById[id++] = arrayName;
- }
- }
- }
- };
-
-
-
- var _glGetUniformLocation = (program, name) => {
-
- name = UTF8ToString(name);
-
- if (program = GL.programs[program]) {
- webglPrepareUniformLocationsBeforeFirstUse(program);
- var uniformLocsById = program.uniformLocsById; // Maps GLuint -> WebGLUniformLocation
- var arrayIndex = 0;
- var uniformBaseName = name;
-
- // Invariant: when populating integer IDs for uniform locations, we must
- // maintain the precondition that arrays reside in contiguous addresses,
- // i.e. for a 'vec4 colors[10];', colors[4] must be at location
- // colors[0]+4. However, user might call glGetUniformLocation(program,
- // "colors") for an array, so we cannot discover based on the user input
- // arguments whether the uniform we are dealing with is an array. The only
- // way to discover which uniforms are arrays is to enumerate over all the
- // active uniforms in the program.
- var leftBrace = webglGetLeftBracePos(name);
-
- // If user passed an array accessor "[index]", parse the array index off the accessor.
- if (leftBrace > 0) {
- arrayIndex = jstoi_q(name.slice(leftBrace + 1)) >>> 0; // "index]", coerce parseInt(']') with >>>0 to treat "foo[]" as "foo[0]" and foo[-1] as unsigned out-of-bounds.
- uniformBaseName = name.slice(0, leftBrace);
- }
-
- // Have we cached the location of this uniform before?
- // A pair [array length, GLint of the uniform location]
- var sizeAndId = program.uniformSizeAndIdsByName[uniformBaseName];
-
- // If an uniform with this name exists, and if its index is within the
- // array limits (if it's even an array), query the WebGLlocation, or
- // return an existing cached location.
- if (sizeAndId && arrayIndex < sizeAndId[0]) {
- arrayIndex += sizeAndId[1]; // Add the base location of the uniform to the array index offset.
- if ((uniformLocsById[arrayIndex] = uniformLocsById[arrayIndex] || GLctx.getUniformLocation(program, name))) {
- return arrayIndex;
- }
- }
- }
- else {
- // N.b. we are currently unable to distinguish between GL program IDs that
- // never existed vs GL program IDs that have been deleted, so report
- // GL_INVALID_VALUE in both cases.
- GL.recordError(0x501 /* GL_INVALID_VALUE */);
- }
- return -1;
- };
-
- var _glLinkProgram = (program) => {
- program = GL.programs[program];
- GLctx.linkProgram(program);
- // Invalidate earlier computed uniform->ID mappings, those have now become stale
- program.uniformLocsById = 0; // Mark as null-like so that glGetUniformLocation() knows to populate this again.
- program.uniformSizeAndIdsByName = {};
-
- };
-
- var _glShaderSource = (shader, count, string, length) => {
- var source = GL.getSource(shader, count, string, length);
-
- GLctx.shaderSource(GL.shaders[shader], source);
- };
-
- var webglGetUniformLocation = (location) => {
- var p = GLctx.currentProgram;
-
- if (p) {
- var webglLoc = p.uniformLocsById[location];
- // p.uniformLocsById[location] stores either an integer, or a
- // WebGLUniformLocation.
- // If an integer, we have not yet bound the location, so do it now. The
- // integer value specifies the array index we should bind to.
- if (typeof webglLoc == 'number') {
- p.uniformLocsById[location] = webglLoc = GLctx.getUniformLocation(p, p.uniformArrayNamesById[location] + (webglLoc > 0 ? `[${webglLoc}]` : ''));
- }
- // Else an already cached WebGLUniformLocation, return it.
- return webglLoc;
- } else {
- GL.recordError(0x502/*GL_INVALID_OPERATION*/);
- }
- };
-
- var _glUniform1f = (location, v0) => {
- GLctx.uniform1f(webglGetUniformLocation(location), v0);
- };
-
-
- var miniTempWebGLFloatBuffers = [];
-
- var _glUniformMatrix4fv = (location, count, transpose, value) => {
-
- if (GL.currentContext.version >= 2) {
- count && GLctx.uniformMatrix4fv(webglGetUniformLocation(location), !!transpose, HEAPF32, ((value)>>2), count*16);
- return;
- }
-
- if (count <= 18) {
- // avoid allocation when uploading few enough uniforms
- var view = miniTempWebGLFloatBuffers[16*count];
- // hoist the heap out of the loop for size and for pthreads+growth.
- var heap = HEAPF32;
- value = ((value)>>2);
- count *= 16;
- for (var i = 0; i < 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 = HEAPF32.subarray((((value)>>2)), ((value+count*64)>>2));
- }
- GLctx.uniformMatrix4fv(webglGetUniformLocation(location), !!transpose, view);
- };
-
- var _glUseProgram = (program) => {
- program = GL.programs[program];
- GLctx.useProgram(program);
- // Record the currently active program so that we can access the uniform
- // mapping table of that program.
- GLctx.currentProgram = program;
- };
-
- var _glVertexAttribDivisor = (index, divisor) => {
- GLctx.vertexAttribDivisor(index, divisor);
- };
-
- var _glVertexAttribPointer = (index, size, type, normalized, stride, ptr) => {
- var cb = GL.currentContext.clientBuffers[index];
- if (!GLctx.currentArrayBufferBinding) {
- cb.size = size;
- cb.type = type;
- cb.normalized = normalized;
- cb.stride = stride;
- cb.ptr = ptr;
- cb.clientside = true;
- cb.vertexAttribPointerAdaptor = function(index, size, type, normalized, stride, ptr) {
- this.vertexAttribPointer(index, size, type, normalized, stride, ptr);
- };
- return;
- }
- cb.clientside = false;
- GLctx.vertexAttribPointer(index, size, type, !!normalized, stride, ptr);
- };
-
-
-Fetch.init();;
-
- // Signal GL rendering layer that processing of a new frame is about to
- // start. This helps it optimize VBO double-buffering and reduce GPU stalls.
- registerPreMainLoop(() => GL.newRenderingFrameStarted());
- ;
-var miniTempWebGLFloatBuffersStorage = new Float32Array(288);
- // Create GL_POOL_TEMP_BUFFERS_SIZE+1 temporary buffers, for uploads of size 0 through GL_POOL_TEMP_BUFFERS_SIZE inclusive
- for (/**@suppress{duplicate}*/var i = 0; i <= 288; ++i) {
- miniTempWebGLFloatBuffers[i] = miniTempWebGLFloatBuffersStorage.subarray(0, i);
- };
-function checkIncomingModuleAPI() {
- ignoredModuleProp('fetchSettings');
-}
-var wasmImports = {
- /** @export */
- __assert_fail: ___assert_fail,
- /** @export */
- _abort_js: __abort_js,
- /** @export */
- _emscripten_fetch_free: __emscripten_fetch_free,
- /** @export */
- _emscripten_memcpy_js: __emscripten_memcpy_js,
- /** @export */
- _localtime_js: __localtime_js,
- /** @export */
- _tzset_js: __tzset_js,
- /** @export */
- emscripten_date_now: _emscripten_date_now,
- /** @export */
- emscripten_get_element_css_size: _emscripten_get_element_css_size,
- /** @export */
- emscripten_is_main_browser_thread: _emscripten_is_main_browser_thread,
- /** @export */
- emscripten_request_animation_frame_loop: _emscripten_request_animation_frame_loop,
- /** @export */
- emscripten_resize_heap: _emscripten_resize_heap,
- /** @export */
- emscripten_set_canvas_element_size: _emscripten_set_canvas_element_size,
- /** @export */
- emscripten_set_click_callback_on_thread: _emscripten_set_click_callback_on_thread,
- /** @export */
- emscripten_set_resize_callback_on_thread: _emscripten_set_resize_callback_on_thread,
- /** @export */
- emscripten_start_fetch: _emscripten_start_fetch,
- /** @export */
- emscripten_webgl_create_context: _emscripten_webgl_create_context,
- /** @export */
- emscripten_webgl_make_context_current: _emscripten_webgl_make_context_current,
- /** @export */
- fd_close: _fd_close,
- /** @export */
- fd_seek: _fd_seek,
- /** @export */
- fd_write: _fd_write,
- /** @export */
- glAttachShader: _glAttachShader,
- /** @export */
- glBindBuffer: _glBindBuffer,
- /** @export */
- glBindVertexArray: _glBindVertexArray,
- /** @export */
- glBlendFunc: _glBlendFunc,
- /** @export */
- glBufferData: _glBufferData,
- /** @export */
- glBufferSubData: _glBufferSubData,
- /** @export */
- glClear: _glClear,
- /** @export */
- glClearColor: _glClearColor,
- /** @export */
- glClearDepth: _glClearDepth,
- /** @export */
- glCompileShader: _glCompileShader,
- /** @export */
- glCreateProgram: _glCreateProgram,
- /** @export */
- glCreateShader: _glCreateShader,
- /** @export */
- glDeleteBuffers: _glDeleteBuffers,
- /** @export */
- glDeleteProgram: _glDeleteProgram,
- /** @export */
- glDeleteShader: _glDeleteShader,
- /** @export */
- glDeleteVertexArrays: _glDeleteVertexArrays,
- /** @export */
- glDepthFunc: _glDepthFunc,
- /** @export */
- glDepthMask: _glDepthMask,
- /** @export */
- glDrawArrays: _glDrawArrays,
- /** @export */
- glDrawArraysInstanced: _glDrawArraysInstanced,
- /** @export */
- glDrawElements: _glDrawElements,
- /** @export */
- glEnable: _glEnable,
- /** @export */
- glEnableVertexAttribArray: _glEnableVertexAttribArray,
- /** @export */
- glGenBuffers: _glGenBuffers,
- /** @export */
- glGenVertexArrays: _glGenVertexArrays,
- /** @export */
- glGetAttribLocation: _glGetAttribLocation,
- /** @export */
- glGetProgramInfoLog: _glGetProgramInfoLog,
- /** @export */
- glGetProgramiv: _glGetProgramiv,
- /** @export */
- glGetShaderInfoLog: _glGetShaderInfoLog,
- /** @export */
- glGetShaderiv: _glGetShaderiv,
- /** @export */
- glGetUniformLocation: _glGetUniformLocation,
- /** @export */
- glLinkProgram: _glLinkProgram,
- /** @export */
- glShaderSource: _glShaderSource,
- /** @export */
- glUniform1f: _glUniform1f,
- /** @export */
- glUniformMatrix4fv: _glUniformMatrix4fv,
- /** @export */
- glUseProgram: _glUseProgram,
- /** @export */
- glVertexAttribDivisor: _glVertexAttribDivisor,
- /** @export */
- glVertexAttribPointer: _glVertexAttribPointer
-};
-var wasmExports = createWasm();
-var ___wasm_call_ctors = createExportWrapper('__wasm_call_ctors', 0);
-var _main = Module['_main'] = createExportWrapper('main', 2);
-var _free = createExportWrapper('free', 1);
-var _malloc = createExportWrapper('malloc', 1);
-var _fflush = createExportWrapper('fflush', 1);
-var _strerror = createExportWrapper('strerror', 1);
-var __emscripten_tempret_set = createExportWrapper('_emscripten_tempret_set', 1);
-var __emscripten_tempret_get = createExportWrapper('_emscripten_tempret_get', 0);
-var _emscripten_stack_init = () => (_emscripten_stack_init = wasmExports['emscripten_stack_init'])();
-var _emscripten_stack_get_free = () => (_emscripten_stack_get_free = wasmExports['emscripten_stack_get_free'])();
-var _emscripten_stack_get_base = () => (_emscripten_stack_get_base = wasmExports['emscripten_stack_get_base'])();
-var _emscripten_stack_get_end = () => (_emscripten_stack_get_end = wasmExports['emscripten_stack_get_end'])();
-var __emscripten_stack_restore = (a0) => (__emscripten_stack_restore = wasmExports['_emscripten_stack_restore'])(a0);
-var __emscripten_stack_alloc = (a0) => (__emscripten_stack_alloc = wasmExports['_emscripten_stack_alloc'])(a0);
-var _emscripten_stack_get_current = () => (_emscripten_stack_get_current = wasmExports['emscripten_stack_get_current'])();
-var dynCall_jiji = Module['dynCall_jiji'] = createExportWrapper('dynCall_jiji', 5);
-
-
-// include: postamble.js
-// === Auto-generated postamble setup entry stuff ===
-
-var missingLibrarySymbols = [
- 'writeI53ToI64Clamped',
- 'writeI53ToI64Signaling',
- 'writeI53ToU64Clamped',
- 'writeI53ToU64Signaling',
- 'convertI32PairToI53',
- 'convertU32PairToI53',
- 'stackAlloc',
- 'getTempRet0',
- 'setTempRet0',
- 'zeroMemory',
- 'strError',
- 'inetPton4',
- 'inetNtop4',
- 'inetPton6',
- 'inetNtop6',
- 'readSockaddr',
- 'writeSockaddr',
- 'initRandomFill',
- 'randomFill',
- 'emscriptenLog',
- 'readEmAsmArgs',
- 'getExecutableName',
- 'listenOnce',
- 'autoResumeAudioContext',
- 'dynCallLegacy',
- 'getDynCaller',
- 'dynCall',
- 'runtimeKeepalivePush',
- 'runtimeKeepalivePop',
- 'asmjsMangle',
- 'asyncLoad',
- 'mmapAlloc',
- 'getNativeTypeSize',
- 'STACK_SIZE',
- 'STACK_ALIGN',
- 'POINTER_SIZE',
- 'ASSERTIONS',
- 'getCFunc',
- 'ccall',
- 'cwrap',
- 'uleb128Encode',
- 'sigToWasmTypes',
- 'generateFuncType',
- 'convertJsFunctionToWasm',
- 'getEmptyTableSlot',
- 'updateTableMap',
- 'getFunctionAddress',
- 'addFunction',
- 'removeFunction',
- 'reallyNegative',
- 'unSign',
- 'strLen',
- 'reSign',
- 'formatString',
- 'intArrayFromString',
- 'intArrayToString',
- 'AsciiToString',
- 'stringToAscii',
- 'UTF16ToString',
- 'stringToUTF16',
- 'lengthBytesUTF16',
- 'UTF32ToString',
- 'stringToUTF32',
- 'lengthBytesUTF32',
- 'stringToNewUTF8',
- 'stringToUTF8OnStack',
- 'writeArrayToMemory',
- 'registerKeyEventCallback',
- 'registerWheelEventCallback',
- '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',
- 'getCanvasElementSize',
- 'jsStackTrace',
- 'getCallstack',
- 'convertPCtoSourceLocation',
- 'getEnvStrings',
- 'checkWasiClock',
- 'wasiRightsToMuslOFlags',
- 'wasiOFlagsToMuslOFlags',
- 'createDyncallWrapper',
- 'safeSetTimeout',
- 'setImmediateWrapped',
- 'clearImmediateWrapped',
- 'polyfillSetImmediate',
- 'registerPostMainLoop',
- 'getPromise',
- 'makePromise',
- 'idsToPromises',
- 'makePromiseCallback',
- 'ExceptionInfo',
- 'findMatchingCatch',
- 'Browser_asyncPrepareDataCounter',
- 'safeRequestAnimationFrame',
- 'arraySum',
- 'addDays',
- 'getSocketFromFD',
- 'getSocketAddress',
- 'FS_createPreloadedFile',
- 'FS_modeStringToFlags',
- 'FS_getMode',
- 'FS_stdin_getChar',
- 'FS_unlink',
- 'FS_createDataFile',
- 'FS_mkdirTree',
- '_setNetworkCallback',
- 'heapObjectForWebGLType',
- 'toTypedArrayIndex',
- 'emscriptenWebGLGet',
- 'computeUnpackAlignedImageSize',
- 'colorChannelsInGlTextureFormat',
- 'emscriptenWebGLGetTexPixelData',
- 'emscriptenWebGLGetUniform',
- 'emscriptenWebGLGetVertexAttrib',
- '__glGetActiveAttribOrUniform',
- 'emscriptenWebGLGetBufferBinding',
- 'emscriptenWebGLValidateMapBufferTarget',
- 'writeGLArray',
- 'registerWebGlEventCallback',
- 'runAndAbortIfError',
- 'emscriptenWebGLGetIndexed',
- 'ALLOC_NORMAL',
- 'ALLOC_STACK',
- 'allocate',
- 'writeStringToMemory',
- 'writeAsciiToMemory',
- 'setErrNo',
- 'demangle',
- 'stackTrace',
-];
-missingLibrarySymbols.forEach(missingLibrarySymbol)
-
-var unexportedSymbols = [
- 'run',
- 'addOnPreRun',
- 'addOnInit',
- 'addOnPreMain',
- 'addOnExit',
- 'addOnPostRun',
- 'addRunDependency',
- 'removeRunDependency',
- 'out',
- 'err',
- 'callMain',
- 'abort',
- 'wasmMemory',
- 'wasmExports',
- 'writeStackCookie',
- 'checkStackCookie',
- 'writeI53ToI64',
- 'readI53FromI64',
- 'readI53FromU64',
- 'convertI32PairToI53Checked',
- 'stackSave',
- 'stackRestore',
- 'ptrToString',
- 'exitJS',
- 'getHeapMax',
- 'growMemory',
- 'ENV',
- 'ERRNO_CODES',
- 'DNS',
- 'Protocols',
- 'Sockets',
- 'timers',
- 'warnOnce',
- 'readEmAsmArgsArray',
- 'jstoi_q',
- 'jstoi_s',
- 'handleException',
- 'keepRuntimeAlive',
- 'callUserCallback',
- 'maybeExit',
- 'alignMemory',
- 'HandleAllocator',
- 'wasmTable',
- 'noExitRuntime',
- 'freeTableIndexes',
- 'functionsInTableMap',
- 'setValue',
- 'getValue',
- 'PATH',
- 'PATH_FS',
- 'UTF8Decoder',
- 'UTF8ArrayToString',
- 'UTF8ToString',
- 'stringToUTF8Array',
- 'stringToUTF8',
- 'lengthBytesUTF8',
- 'UTF16Decoder',
- 'JSEvents',
- 'specialHTMLTargets',
- 'maybeCStringToJsString',
- 'findEventTarget',
- 'findCanvasEventTarget',
- 'getBoundingClientRect',
- 'fillMouseEventData',
- 'registerMouseEventCallback',
- 'registerUiEventCallback',
- 'currentFullscreenStrategy',
- 'restoreOldWindowedStyle',
- 'UNWIND_CACHE',
- 'ExitStatus',
- 'flush_NO_FILESYSTEM',
- 'registerPreMainLoop',
- 'promiseMap',
- 'uncaughtExceptionCount',
- 'exceptionLast',
- 'exceptionCaught',
- 'Browser',
- 'getPreloadedImageData__data',
- 'wget',
- 'MONTH_DAYS_REGULAR',
- 'MONTH_DAYS_LEAP',
- 'MONTH_DAYS_REGULAR_CUMULATIVE',
- 'MONTH_DAYS_LEAP_CUMULATIVE',
- 'isLeapYear',
- 'ydayFromDate',
- 'SYSCALLS',
- 'preloadPlugins',
- 'FS_stdin_getChar_buffer',
- 'FS_createPath',
- 'FS_createDevice',
- 'FS_readFile',
- 'FS',
- 'FS_createLazyFile',
- 'MEMFS',
- 'TTY',
- 'PIPEFS',
- 'SOCKFS',
- 'tempFixedLengthArray',
- 'miniTempWebGLFloatBuffers',
- 'miniTempWebGLIntBuffers',
- 'webgl_enable_ANGLE_instanced_arrays',
- 'webgl_enable_OES_vertex_array_object',
- 'webgl_enable_WEBGL_draw_buffers',
- 'webgl_enable_WEBGL_multi_draw',
- 'webgl_enable_EXT_polygon_offset_clamp',
- 'webgl_enable_EXT_clip_control',
- 'webgl_enable_WEBGL_polygon_mode',
- 'GL',
- 'webglGetUniformLocation',
- 'webglPrepareUniformLocationsBeforeFirstUse',
- 'webglGetLeftBracePos',
- 'AL',
- 'GLUT',
- 'EGL',
- 'GLEW',
- 'IDBStore',
- 'SDL',
- 'SDL_gfx',
- 'webgl_enable_WEBGL_draw_instanced_base_vertex_base_instance',
- 'webgl_enable_WEBGL_multi_draw_instanced_base_vertex_base_instance',
- 'allocateUTF8',
- 'allocateUTF8OnStack',
- 'print',
- 'printErr',
- 'Fetch',
- 'fetchDeleteCachedData',
- 'fetchLoadCachedData',
- 'fetchCacheData',
- 'fetchXHR',
-];
-unexportedSymbols.forEach(unexportedRuntimeSymbol);
-
-
-
-var calledRun;
-var calledPrerun;
-
-dependenciesFulfilled = function runCaller() {
- // If run has never been called, and we should call run (INVOKE_RUN is true, and Module.noInitialRun is not false)
- if (!calledRun) run();
- if (!calledRun) dependenciesFulfilled = runCaller; // try this again later, after new deps are fulfilled
-};
-
-function callMain() {
- assert(runDependencies == 0, 'cannot call main when async dependencies remain! (listen on Module["onRuntimeInitialized"])');
- assert(calledPrerun, 'cannot call main without calling preRun first');
-
- var entryFunction = _main;
-
- var argc = 0;
- var argv = 0;
-
- try {
-
- var ret = entryFunction(argc, argv);
-
- // if we're not running an evented main loop, it's time to exit
- exitJS(ret, /* implicit = */ true);
- return ret;
- }
- catch (e) {
- return handleException(e);
- }
-}
-
-function stackCheckInit() {
- // This is normally called automatically during __wasm_call_ctors but need to
- // get these values before even running any of the ctors so we call it redundantly
- // here.
- _emscripten_stack_init();
- // TODO(sbc): Move writeStackCookie to native to to avoid this.
- writeStackCookie();
-}
-
-function run() {
-
- if (runDependencies > 0) {
- return;
- }
-
- stackCheckInit();
-
- if (!calledPrerun) {
- calledPrerun = 1;
- preRun();
-
- // a preRun added a dependency, run will be called later
- if (runDependencies > 0) {
- return;
- }
- }
-
- function doRun() {
- // run may have just been called through dependencies being fulfilled just in this very frame,
- // or while the async setStatus time below was happening
- if (calledRun) return;
- calledRun = 1;
- Module['calledRun'] = 1;
-
- if (ABORT) return;
-
- initRuntime();
-
- preMain();
-
- Module['onRuntimeInitialized']?.();
-
- if (shouldRunNow) callMain();
-
- postRun();
- }
-
- if (Module['setStatus']) {
- Module['setStatus']('Running...');
- setTimeout(() => {
- setTimeout(() => Module['setStatus'](''), 1);
- doRun();
- }, 1);
- } else
- {
- doRun();
- }
- checkStackCookie();
-}
-
-function checkUnflushedContent() {
- // Compiler settings do not allow exiting the runtime, so flushing
- // the streams is not possible. but in ASSERTIONS mode we check
- // if there was something to flush, and if so tell the user they
- // should request that the runtime be exitable.
- // Normally we would not even include flush() at all, but in ASSERTIONS
- // builds we do so just for this check, and here we see if there is any
- // content to flush, that is, we check if there would have been
- // something a non-ASSERTIONS build would have not seen.
- // How we flush the streams depends on whether we are in SYSCALLS_REQUIRE_FILESYSTEM=0
- // mode (which has its own special function for this; otherwise, all
- // the code is inside libc)
- var oldOut = out;
- var oldErr = err;
- var has = false;
- out = err = (x) => {
- has = true;
- }
- try { // it doesn't matter if it fails
- flush_NO_FILESYSTEM();
- } catch(e) {}
- out = oldOut;
- err = oldErr;
- if (has) {
- warnOnce('stdio streams had content in them that was not flushed. you should set EXIT_RUNTIME to 1 (see the Emscripten FAQ), or make sure to emit a newline when you printf etc.');
- warnOnce('(this may also be due to not including full filesystem support - try building with -sFORCE_FILESYSTEM)');
- }
-}
-
-if (Module['preInit']) {
- if (typeof Module['preInit'] == 'function') Module['preInit'] = [Module['preInit']];
- while (Module['preInit'].length > 0) {
- Module['preInit'].pop()();
- }
-}
-
-// shouldRunNow refers to calling main(), not run().
-var shouldRunNow = true;
-
-if (Module['noInitialRun']) shouldRunNow = false;
-
-run();
-
-// end include: postamble.js
-
diff --git a/public/themes/dist/output.wasm b/public/themes/dist/output.wasm
deleted file mode 100755
index 671e7bb..0000000
--- a/public/themes/dist/output.wasm
+++ /dev/null
Binary files differ
diff --git a/themes/dist/output.wasm b/themes/dist/output.wasm
index 671e7bb..550e5ff 100755
--- a/themes/dist/output.wasm
+++ b/themes/dist/output.wasm
Binary files differ
diff --git a/themes/src/spring/spring_theme.cpp b/themes/src/spring/spring_theme.cpp
index 8507194..8b09366 100644
--- a/themes/src/spring/spring_theme.cpp
+++ b/themes/src/spring/spring_theme.cpp
@@ -5,204 +5,204 @@
#include <emscripten/fetch.h>
void onBunnySuccess(emscripten_fetch_t *fetch) {
- SpringTheme* springTheme = (SpringTheme*)fetch->userData;
- springTheme->state = SpringThemeState::LoadedBunny;
- printf("Finished downloading %llu bytes from URL %s.\n", fetch->numBytes, fetch->url);
- const i32 len = fetch->numBytes;
- springTheme->bunnyMesh = Mesh3d_fromObj(&springTheme->renderer, fetch->data, len);
- // The data is now available at fetch->data[0] through fetch->data[fetch->numBytes-1];
- emscripten_fetch_close(fetch); // Free data associated with the fetch.
+ SpringTheme *springTheme = (SpringTheme *)fetch->userData;
+ springTheme->state = SpringThemeState::LoadedBunny;
+ printf("Finished downloading %llu bytes from URL %s.\n", fetch->numBytes,
+ fetch->url);
+ const i32 len = fetch->numBytes;
+ springTheme->bunnyMesh =
+ Mesh3d_fromObj(&springTheme->renderer, fetch->data, len);
+ // The data is now available at fetch->data[0] through
+ // fetch->data[fetch->numBytes-1];
+ emscripten_fetch_close(fetch); // Free data associated with the fetch.
}
void onBunnyFail(emscripten_fetch_t *fetch) {
- printf("Downloading %s failed, HTTP failure status code: %d.\n", fetch->url, fetch->status);
- emscripten_fetch_close(fetch); // Also free data on failure.
+ printf("Downloading %s failed, HTTP failure status code: %d.\n", fetch->url,
+ fetch->status);
+ emscripten_fetch_close(fetch); // Also free data on failure.
}
-inline void fetch_bunny(SpringTheme* theme) {
- emscripten_fetch_attr_t attr;
- emscripten_fetch_attr_init(&attr);
- strcpy(attr.requestMethod, "GET");
- attr.attributes = EMSCRIPTEN_FETCH_LOAD_TO_MEMORY;
- attr.onsuccess = onBunnySuccess;
- attr.onerror = onBunnyFail;
- auto* bunny_fetch = emscripten_fetch(&attr, "themes/resources/bunny.obj");
- bunny_fetch->userData = theme;
+inline void fetch_bunny(SpringTheme *theme) {
+ emscripten_fetch_attr_t attr;
+ emscripten_fetch_attr_init(&attr);
+ strcpy(attr.requestMethod, "GET");
+ attr.attributes = EMSCRIPTEN_FETCH_LOAD_TO_MEMORY;
+ attr.onsuccess = onBunnySuccess;
+ attr.onerror = onBunnyFail;
+ auto *bunny_fetch = emscripten_fetch(&attr, "resources/bunny.obj");
+ bunny_fetch->userData = theme;
}
-inline void on_shaders_loader(ShaderFetchResult* result) {
- SpringTheme* theme = (SpringTheme*)result->user_data;
- theme->renderer.load(theme->renderer.context, result->vertex.c_str(), result->fragment.c_str());
- theme->state = SpringThemeState::LoadedShader;
- fetch_bunny(theme);
+inline void on_shaders_loader(ShaderFetchResult *result) {
+ SpringTheme *theme = (SpringTheme *)result->user_data;
+ theme->renderer.load(theme->renderer.context, result->vertex.c_str(),
+ result->fragment.c_str());
+ theme->state = SpringThemeState::LoadedShader;
+ fetch_bunny(theme);
}
-SpringTheme::SpringTheme(WebglContext* context)
-{
- load(context);
-}
+SpringTheme::SpringTheme(WebglContext *context) { load(context); }
-SpringTheme::~SpringTheme()
-{
- unload();
-}
+SpringTheme::~SpringTheme() { unload(); }
+
+void SpringTheme::load(WebglContext *context) {
+ state = SpringThemeState::Loading;
+ renderer.context = context;
+ renderer.clearColor = Vector4(160, 231, 160, 255.f).toNormalizedColor();
-void SpringTheme::load(WebglContext* context) {
- state = SpringThemeState::Loading;
- renderer.context = context;
- renderer.clearColor = Vector4(160, 231, 160, 255.f).toNormalizedColor();
-
- fetch_shader(
- {
- "themes/src/_shaders/renderer3d.vert",
- "themes/src/_shaders/renderer3d.frag"
- },
- on_shaders_loader,
- this
- );
+ fetch_shader({"themes/src/_shaders/renderer3d.vert",
+ "themes/src/_shaders/renderer3d.frag"},
+ on_shaders_loader, this);
}
-inline Vector3 bunnyLerp(Vector3& start, Vector3& target, f32 t) {
- t = 3 * t *t - 2 * t * t * t;
- return start + ((target - start) * t);
+inline Vector3 bunnyLerp(Vector3 &start, Vector3 &target, f32 t) {
+ t = 3 * t * t - 2 * t * t * t;
+ return start + ((target - start) * t);
}
inline f32 verticalHopLerp(f32 start, f32 target, f32 t) {
- f32 ogt = t;
- t = 3 * t *t - 2 * t * t * t;
- if (ogt >= 0.5f) t = 1.f - t;
- return start + ((target - start) * t);
+ f32 ogt = t;
+ t = 3 * t * t - 2 * t * t * t;
+ if (ogt >= 0.5f)
+ t = 1.f - t;
+ return start + ((target - start) * t);
}
inline f32 rotationLerp(f32 start, f32 target, f32 t) {
- return start + ((target - start) * t);
+ return start + ((target - start) * t);
}
void SpringTheme::update(f32 dtSeconds) {
- switch (state) {
- case SpringThemeState::Loading: return;
- case SpringThemeState::LoadedShader: return;
- case SpringThemeState::LoadedBunny:
- state = SpringThemeState::Idle;
- stateTimer = 0.f;
- bunnyHopAnimationTimer = 0.f;
- break;
- case SpringThemeState::Idle: {
- bunnyHopAnimationTimer += dtSeconds;
- const f32 HOP_FREQUENCY = 6.f;
-
- if (bunnyHopAnimationTimer > stateTimer) {
- state = SpringThemeState::PreHop;
- f32 xDir = 1;
- f32 yDir = 1;
- if (bunnyTarget.x > 0) xDir = -1;
- if (bunnyTarget.z > 0) yDir = -1;
- bunnyTarget = bunnyPosition + Vector3(randomFloatBetween(0, xDir * 25), 0, randomFloatBetween(0, yDir * 25));
- auto direction = (bunnyTarget - bunnyPosition);
- auto distance = direction.length();
- direction = direction.normalize();
- numHops = ceil(distance / HOP_FREQUENCY);
- hopCount = 0;
-
- targetRotation = PI - atan2(direction.y, direction.x);
- stateTimer = ((bunnyTarget - bunnyPosition).length() / bunnySpeed) / numHops;
- bunnyHopAnimationTimer = 0.f;
- hopIncrement = (bunnyTarget - bunnyPosition) / numHops;
- }
- break;
- }
- case SpringThemeState::PreHop: {
- const f32 ROTATION_TIME = 0.5f;
- bunnyHopAnimationTimer += dtSeconds;
- f32 current = bunnyRotation + (targetRotation - bunnyRotation) * (bunnyHopAnimationTimer / ROTATION_TIME);
- bunnyMesh.model = Mat4x4().rotate(0, current, 0).translate(bunnyPosition);
-
- if (bunnyHopAnimationTimer > ROTATION_TIME) {
- bunnyRotation = targetRotation;
- bunnyHopAnimationTimer = 0;
- state = SpringThemeState::Hopping;
- }
- break;
- }
- case SpringThemeState::Hopping: {
- bunnyHopAnimationTimer += dtSeconds;
- f32 t = bunnyHopAnimationTimer / stateTimer;
-
- Vector3 nextPosition = bunnyPosition + hopIncrement;
- auto renderPos = bunnyLerp(bunnyPosition, nextPosition, t);
- if ((renderPos - nextPosition).length() < 0.01f) {
- hopCount += 1;
- bunnyHopAnimationTimer = 0.f;
- bunnyPosition = nextPosition;
- }
-
- renderPos.y = verticalHopLerp(0.f, 4.f, t);
-
- const f32 RMAX = PI / 16.f;
- f32 zRotation = 0;
- f32 start = 0.f;
- f32 end = PI / 8.f;
- f32 startTime = 0.f;
- f32 endTime = 0.f;
- bool disableRot = false;
-
- if (t >= 0.9f) {
- disableRot = true;
- }
- else if (t >= 0.7f) {
- start = -RMAX;
- end = 0.f;
- startTime = 0.7f;
- endTime = 0.9f;
- }
- else if (t >= 0.50f) {
- start = 0.f;
- end = -RMAX;
- startTime = 0.50f;
- endTime = 0.70f;
- }
- else if (t >= 0.40f) {
- disableRot = true;
- }
- else if (t >= 0.20f) {
- start = RMAX;
- end = 0.f;
- startTime = 0.20f;
- endTime = 0.40f;
- }
- else {
- start = 0.f;
- end = RMAX;
- startTime = 0.f;
- endTime = 0.20f;
- }
-
-
- if (!disableRot) {
- f32 totalTime = endTime - startTime;
- zRotation = rotationLerp(start, end, (totalTime - (endTime - t)) / totalTime);
- }
-
- bunnyMesh.model = Mat4x4().getZRotationMatrix(zRotation).rotate(0, bunnyRotation, 0).translate(renderPos);
- if (hopCount == numHops) {
- bunnyPosition = bunnyTarget;
- bunnyHopAnimationTimer = 0.f;
- state = SpringThemeState::Idle;
- stateTimer = randomFloatBetween(0.5f, 1.f);
- }
- break;
- }
- }
+ switch (state) {
+ case SpringThemeState::Loading:
+ return;
+ case SpringThemeState::LoadedShader:
+ return;
+ case SpringThemeState::LoadedBunny:
+ state = SpringThemeState::Idle;
+ stateTimer = 0.f;
+ bunnyHopAnimationTimer = 0.f;
+ break;
+ case SpringThemeState::Idle: {
+ bunnyHopAnimationTimer += dtSeconds;
+ const f32 HOP_FREQUENCY = 6.f;
+
+ if (bunnyHopAnimationTimer > stateTimer) {
+ state = SpringThemeState::PreHop;
+ f32 xDir = 1;
+ f32 yDir = 1;
+ if (bunnyTarget.x > 0)
+ xDir = -1;
+ if (bunnyTarget.z > 0)
+ yDir = -1;
+ bunnyTarget = bunnyPosition + Vector3(randomFloatBetween(0, xDir * 25), 0,
+ randomFloatBetween(0, yDir * 25));
+ auto direction = (bunnyTarget - bunnyPosition);
+ auto distance = direction.length();
+ direction = direction.normalize();
+ numHops = ceil(distance / HOP_FREQUENCY);
+ hopCount = 0;
+
+ targetRotation = PI - atan2(direction.y, direction.x);
+ stateTimer =
+ ((bunnyTarget - bunnyPosition).length() / bunnySpeed) / numHops;
+ bunnyHopAnimationTimer = 0.f;
+ hopIncrement = (bunnyTarget - bunnyPosition) / numHops;
+ }
+ break;
+ }
+ case SpringThemeState::PreHop: {
+ const f32 ROTATION_TIME = 0.5f;
+ bunnyHopAnimationTimer += dtSeconds;
+ f32 current = bunnyRotation + (targetRotation - bunnyRotation) *
+ (bunnyHopAnimationTimer / ROTATION_TIME);
+ bunnyMesh.model = Mat4x4().rotate(0, current, 0).translate(bunnyPosition);
+
+ if (bunnyHopAnimationTimer > ROTATION_TIME) {
+ bunnyRotation = targetRotation;
+ bunnyHopAnimationTimer = 0;
+ state = SpringThemeState::Hopping;
+ }
+ break;
+ }
+ case SpringThemeState::Hopping: {
+ bunnyHopAnimationTimer += dtSeconds;
+ f32 t = bunnyHopAnimationTimer / stateTimer;
+
+ Vector3 nextPosition = bunnyPosition + hopIncrement;
+ auto renderPos = bunnyLerp(bunnyPosition, nextPosition, t);
+ if ((renderPos - nextPosition).length() < 0.01f) {
+ hopCount += 1;
+ bunnyHopAnimationTimer = 0.f;
+ bunnyPosition = nextPosition;
+ }
+
+ renderPos.y = verticalHopLerp(0.f, 4.f, t);
+
+ const f32 RMAX = PI / 16.f;
+ f32 zRotation = 0;
+ f32 start = 0.f;
+ f32 end = PI / 8.f;
+ f32 startTime = 0.f;
+ f32 endTime = 0.f;
+ bool disableRot = false;
+
+ if (t >= 0.9f) {
+ disableRot = true;
+ } else if (t >= 0.7f) {
+ start = -RMAX;
+ end = 0.f;
+ startTime = 0.7f;
+ endTime = 0.9f;
+ } else if (t >= 0.50f) {
+ start = 0.f;
+ end = -RMAX;
+ startTime = 0.50f;
+ endTime = 0.70f;
+ } else if (t >= 0.40f) {
+ disableRot = true;
+ } else if (t >= 0.20f) {
+ start = RMAX;
+ end = 0.f;
+ startTime = 0.20f;
+ endTime = 0.40f;
+ } else {
+ start = 0.f;
+ end = RMAX;
+ startTime = 0.f;
+ endTime = 0.20f;
+ }
+
+ if (!disableRot) {
+ f32 totalTime = endTime - startTime;
+ zRotation =
+ rotationLerp(start, end, (totalTime - (endTime - t)) / totalTime);
+ }
+
+ bunnyMesh.model = Mat4x4()
+ .getZRotationMatrix(zRotation)
+ .rotate(0, bunnyRotation, 0)
+ .translate(renderPos);
+ if (hopCount == numHops) {
+ bunnyPosition = bunnyTarget;
+ bunnyHopAnimationTimer = 0.f;
+ state = SpringThemeState::Idle;
+ stateTimer = randomFloatBetween(0.5f, 1.f);
+ }
+ break;
+ }
+ }
}
void SpringTheme::render() {
- renderer.render();
- if (state != SpringThemeState::Loading) {
- bunnyMesh.render(&renderer);
- }
+ renderer.render();
+ if (state != SpringThemeState::Loading) {
+ bunnyMesh.render(&renderer);
+ }
}
-void SpringTheme::unload() {
- renderer.unload();
- bunnyMesh.unload();
+void SpringTheme::unload() {
+ renderer.unload();
+ bunnyMesh.unload();
}