Merge pull request #192 from fintelia/patch-1

Fix comment typo in basisu_transcoder.h
diff --git a/.reuse/dep5 b/.reuse/dep5
index 795dbe4..8f0cb36 100644
--- a/.reuse/dep5
+++ b/.reuse/dep5
@@ -7,14 +7,14 @@
 Copyright: 2019-2020 Binomial LLC
 License: Apache-2.0
 
-Files: apg_bmp.* CMakeLists.txt webgl/transcoder/CMakeLists.txt
+Files: encoder/apg_bmp.* CMakeLists.txt webgl/transcoder/CMakeLists.txt
 Copyright: 2019 Anton Gerdelan
 License: Apache-2.0
 
-Files: basisu_astc_decomp.*
+Files: encoder/basisu_astc_decomp.*
 Copyright: 2016 The Android Open Source Project
 License: Apache-2.0
 
-Files: lodepng.*
+Files: encoder/lodepng.*
 Copyright: 2005-2019 Lode Vandevenne
 License: Zlib
diff --git a/CMakeLists.txt b/CMakeLists.txt
index d1e4562..3f632e3 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -54,25 +54,25 @@
 endif()
 
 set(BASISU_SRC_LIST ${COMMON_SRC_LIST} 
-	basisu_backend.cpp
-	basisu_basis_file.cpp
-	basisu_comp.cpp
-	basisu_enc.cpp
-	basisu_etc.cpp
-	basisu_frontend.cpp
-	basisu_global_selector_palette_helpers.cpp
-	basisu_gpu_texture.cpp
-	basisu_pvrtc1_4.cpp
-	basisu_resampler.cpp
-	basisu_resample_filters.cpp
-	basisu_ssim.cpp
 	basisu_tool.cpp
-	basisu_astc_decomp.cpp
-	basisu_uastc_enc.cpp
-	basisu_bc7enc.cpp
-	lodepng.cpp
-	apg_bmp.c
-	jpgd.cpp
+	encoder/basisu_backend.cpp
+	encoder/basisu_basis_file.cpp
+	encoder/basisu_comp.cpp
+	encoder/basisu_enc.cpp
+	encoder/basisu_etc.cpp
+	encoder/basisu_frontend.cpp
+	encoder/basisu_global_selector_palette_helpers.cpp
+	encoder/basisu_gpu_texture.cpp
+	encoder/basisu_pvrtc1_4.cpp
+	encoder/basisu_resampler.cpp
+	encoder/basisu_resample_filters.cpp
+	encoder/basisu_ssim.cpp
+	encoder/basisu_astc_decomp.cpp
+	encoder/basisu_uastc_enc.cpp
+	encoder/basisu_bc7enc.cpp
+	encoder/lodepng.cpp
+	encoder/apg_bmp.c
+	encoder/jpgd.cpp
 	transcoder/basisu_transcoder.cpp
 	)
 
diff --git a/README.md b/README.md
index eda5f82..7579a79 100644
--- a/README.md
+++ b/README.md
@@ -13,7 +13,9 @@
 
 So far, we've compiled the code using MSVS 2019, under Ubuntu x64 using cmake with either clang 3.8 or gcc 5.4, and emscripten 1.35 to asm.js. (Be sure to use this version or later of emcc, as earlier versions fail with internal errors/exceptions during compilation.) The compressor is multithreaded by default, but this can be disabled using the -no_multithreading command line option. The transcoder is currently single threaded.
 
-Basis Universal supports "skip blocks" in ETC1S compressed texture arrays, which makes it useful for basic [compressed texture video](http://gamma.cs.unc.edu/MPTC/) applications. Note that Basis Universal is still at heart a GPU texture compression system, not a video codec, so bitrates will be larger than even MPEG1.
+Basis Universal supports "skip blocks" in ETC1S compressed texture arrays, which makes it useful for basic [compressed texture video](http://gamma.cs.unc.edu/MPTC/) applications. Note that Basis Universal is still at heart a GPU texture compression system, not a dedicated video codec, so bitrates will be larger than even MPEG1.
+
+[Release Notes](https://github.com/BinomialLLC/basis_universal/wiki/Release-Notes)
 
 ### Important Usage Notes
 
@@ -67,49 +69,6 @@
 a clean, checked-out repository periodically, or run it during CI tests
 before any build artifacts have been created.
 
-
-### Release notes
-
-3/25/20 release notes:
-- Added fuzz-safe JPEG reading. We support full-safe JPEG/BMP/TGA/PNG now.
-
-3/14/20 release notes:
-- UASTC support is in. We have removed BC7 mode 6 support from the ETC1S transcoder to reduce its size, although the format enum still works (it aliases to BC7 mode 5). We are still updating the docs for UASTC.
-- Adding fuzz-safe BMP support using apg_bmp. We will be adding fuzz-safe JPEG and TGA next.
-
-9/26/19 release notes:
-- Automatic global selector palettes are disabled by default, because searching the virtual selector codebook is very slow.
-You can enable them by specifying -auto_global_sel_pal on the command line, for slightly smaller files on small textures/images.
-- PVRTC2 RGB support added. This format looks great and transcoding is fast - approximately as good as BC1. It supports non-power of 2, non-square textures, and should be used instead of PVRTC1 whenever possible.
-- PVRTC2 RGBA support added. This format looks OK if the texture has a very simple alpha channel (like simple opacity mask). The texture should use premulitplied alpha, otherwise on alpha=0 pixels the color channel may slightly leak into the alpha channel due to issues with the PVRTC2 format itself. Transcoding is fast unless the texture's alpha channel is very complex.
-It's a tossup whether PVRTC1 or PVRTC2 would look better for alpha textures. 
-- ETC2 EAC R11/RG11 (unsigned) support checked in. Thanks to Juan Linietsky for suggesting it.
-- The format enum names have changed, but I tried to keep compatibility with old code. The actual values haven't changed so Javascript code should work without modifications. 
-- We're now using "enum class transcoder_texture_format" instead of "enum transcoder_texture_format" in basisu_transcoder.h
-- Fixed a couple encoder bugs (one assert in basisu_enc.h), and a uninitialized variable issue in the frontend. Neither issue would cause corrupted files or artifacts.
-- FXT1 RGB support is checked in, for Intel/3DFX GPU's. Mostly for completeness and to test block sizes other than 4x4.
-- The PVRTC1 wrap vs. clamp flag has been removed from the entire codebase, because PVRTC1 always uses wrap addressing when fetching the adjacent blocks (even when the user selects clamp UV addressing).
-
-Milestone 2 (9/19/19) release notes:
-
-- **Beware that the "transcoder_texture_format" enum names and their values are in flux** as we add new texture formats.
-This issue particularly affects Javascript code. Passing the old enum values to the transcoder will cause bugs. 
-We are adding a few more texture formats, renaming the enums and then stabilizing them on the next minor release (within a couple days or so).
-- This is a major transcoder update. The encoder hasn't been modified at all. 
-A minor update will be coming in a couple days which adds additional lower priority formats (notable PVRTC2 4bpp RGB) to the transcoder.
-- When the "BASISD_SUPPORT_BC7" transcoder macro is set to 0, both mode 5 and mode 6 BC7 transcoders are disabled.
-When cross compiling the transcoder for Web use to WebAssembly/asm.js, be sure to set BASISD_SUPPORT_BC7=0. You can also just disable the mode 6 transcoder by just setting BASISD_SUPPORT_BC7_MODE6_OPAQUE_ONLY=0.
-The older BC7 mode-6 RGB function seriously bloats the transcoder's compiled size. (The mode-6 transcoder is of marginal value and might be disabled by default or just removed.) The new BC7 mode 5 RGB/RGBA transcoder uses substantially smaller lookup tables and provides basically the same quality as mode-6 for RGB (becaue we're starting with ETC1S texture data.)
-Set BASISD_SUPPORT_BC7_MODE6_OPAQUE_ONLY to 0 when compiling on platforms which don't support BC7 well/at all, or if transcoder size is an issue.
-- Added ATC RGB/RGBA, ASTC 4x4 L/LA/RGB/RGBA, BC7 mode 5 RGB/RGBA, and PVRTC1 4bpp RGBA support to the transcoder and KTX writer.
-- Major perf. optimizations to all the transcoders. Transcoding to BC1 is approx. 2x faster when compiled native and executed on a Core i7. Similar perf. improvements should be seen when executed in WebAssembly. This was done by more closely coupling the .basis file decompression and format transcoding steps (before we unpacked to plain ETC1/ETC1S, then transcoded those bits, which was costly.)
-- PVRTC1 4bpp RGB opaque is slightly higher quality 
-- Added various uncompressed raster pixel formats to the transcoder. When outputting raw pixels, the transcoder writes to regular raster images, not blocks. 
-No dithering or downsampling yet, but it's coming.
-A couple of the parameters to basisu_transcoder::transcode_image_level() and  basisu_transcoder::transcode_slice() have new meanings when these methods are used with uncompressed raster pixel formats:
-"output_blocks_buf_size_in_blocks_or_pixels" and "output_row_pitch_in_blocks_or_pixels". There's also a new parameter, "output_rows_in_pixels". When transcoding to uncompressed raster pixel formats, these parameters are in pixels, not blocks. The output buffer is also treated as a plain raster image, not a 2D array of compressed blocks. These parameters are sanity checked, and if they look fishy the transcoder will return an error.
-- basisu command line tool's "-level" command line option changed to "-comp_level", to avoid confusion vs. the "-q" option. This option is NOT the same as the -q option, which directly controls the output quality. Most users shouldn't use this option. (See below.)
-
 ### Command Line Compression Tool
 
 The command line tool used to create, validate, and transcode/unpack .basis files is named "basisu". Run basisu without any parameters for help. 
@@ -189,19 +148,7 @@
 
 For video, level 1 should result in decent results on most clips. For less banding, level 2 can make a big difference. This is still an active area of development, and quality/encoding perf. will improve over time.
 
-### ETC1S Compression levels (advanced option)
-
-The encoder supports multiple compression "effort" levels using the "-comp_level X" command line option, where X ranges from [0,5]. Note that most users shouldn't be messing around with -comp_level. The -q option is the main option to control the quality level of .basis files. -comp_level is mostly intended for harder to handle content such as texture video. It modifies a number of internal encoder configuration parameters, which slows it down a bunch but allows it to achieve slightly higher quality per output bit.
-
-This option (along with -q or manually setting the codebook sizes) controls the tradeoff between encoding time and overall quality. The default is level 1, which is the sweet spot between encoding speed vs. overall quality. Here's a graph showing the encoding time and average quality across 59 images for each level:
-
-![Encoder Level vs. Time/Quality Graph](https://github.com/BinomialLLC/basis_universal/blob/master/encoder_lvl_vs_perf.png "Encoder Level vs. Encoding Time/Quality")
-
-This benchmark was done on a 20 core Xeon workstation. The results will be different on less powerful machines.
-
-Level 0 is fast, but this level disables several backend optimizations so it will generate larger files. It will also be quite brittle on complex textures or artificial textures.
-
-Note that -comp_level 2 is equivalent to the initial release's default, and -comp_level 4 is equivalent to the initial release's "-slower" option. Also, -slower is now equivalent to level 2 (not 4).
+To control the ETC1S encoder's quality vs. encoding speed tradeoff, see [ETC1S Compression Effort Levels](https://github.com/BinomialLLC/basis_universal/wiki/ETC1S-Compression-Effort-Levels).
 
 ### More detailed examples
 
@@ -243,223 +190,17 @@
 
 ### WebGL test 
 
-The "WebGL" directory contains two very simple WebGL demos that use the transcoder compiled to wasm with [emscripten](https://emscripten.org/). See more details [here](webgl/README.md).
+The "WebGL" directory contains three simple WebGL demos that use the transcoder and compressor compiled to wasm with [emscripten](https://emscripten.org/). See more details [here](webgl/README.md).
 
 ![Screenshot of 'texture' example running in a browser.](webgl/texture/preview.png)
 ![Screenshot of 'gltf' example running in a browser.](webgl/gltf/preview.png)
+![Screenshot of 'encode_test' example running in a browser.](webgl/encode_test/preview.png)
 
-### .basis baseline file format forwards and backwards compatibility
+### WebAssembly Support Using Emscripten
 
-Short form: Old transcoders will always be able to read baseline compressed texture data written by new encoders. And new transcoders will always still be able to read old .basis files generated by old encoders.
+Both the transcoder and now the compressor (as of 12/17/2020) may be compiled using emscripten to WebAssembly and used on the web. Currently, multithreading is not supported by the compressor when compiled with emscripten. A simple Web compression demo is in webgl/encode_test. All compressor features, including texture video, are supported and fully exposed.
 
-We have no intentions of changing the baseline file format (i.e. the file format written by this encoder), apart from critical bug fixes. We will be extending the format in the future to add features to the system, but old transcoders will still be able to transcode baseline texture data from .basis files written using new transcoders. .basis files are intended for very wide distribution of compressed texture data, like .jpeg or .png, so backwards and forwards compatibility is critical.
-
-So if you compile and ship the transcoder into an application today, we are making a guarantee to you that this transcoder will stay relevant/usable even as we enhance the system. To do this, the file format has the ability to be extended.
-
-Note: The one exception to this promise are .basis textures marked as video. We will be changing how a key symbol is interpreted to introduce skip blocks (conditional replenishment) into the system.
-
-### Encoder speed
-
-Total time for basisu.exe to compress a 1024x1024 ETC1S texture on a 7 year old 4-core 2.2GHz Core i7 laptop - timings are "without mipmaps/with mipmaps":
-
-* -comp_level 0: 
-
--q 128: 2.2/3.5 secs
-
--q 255: 1.5/2.5 secs
-
-* -comp_level 1:
-
--q 128: 4.1/6.2 secs
-
--q 255: 6.4/9.4 secs
-
-### Transcoder details
-
-The transcoder unpacks .basis files directly to various GPU texture formats, almost always without needing to decompress and recompress each block at the pixel level (which would be too slow and energy intensive in Javascript/WebAssembly). Small precomputed lookup tables are used to accelerate the direct conversion of the internal ETC1S format texture data to the desired output texture data. This new approach to GPU texture compression bypasses the need to recompress each block's pixels to the desired output format using Principle Component Anaylsis (PCA), or spend cycles determining the output selectors for each individual pixel. The ETC1S texture format is a strong subset of all the other block texture formats. The one exception is PVRTC1, where the transcoder needs to recompute the per-pixel selector ("modulation") values, but it does so using simple scalar operations.
-
-To use .basis files in an application, you only need the files in the "transcoder" directory. The entire transcoder lives in a single .cpp file: transcoder/basisu_transcoder.cpp. If compiling with gcc/clang, be sure strict aliasing is disabled when compiling this file, as I have not tested either the encoder or transcoder with strict aliasing enabled: -fno-strict-aliasing (The Linux kernel is also compiled with this option.) The transcoder can also be cross compiled using emscripten (emcc), for web use.
-
-To use the transcoder, #include "transcoder/basisu_transcoder.h". Call `basist::basisu_transcoder_init()` a single time (probably at startup). Also, ideally once at startup, you need to create a single instance of the `basist::etc1_global_selector_codebook` class, like this:
-
-`basist::etc1_global_selector_codebook sel_codebook(basist::g_global_selector_cb_size, basist::g_global_selector_cb);`
-
-Now you can use the transcoder, which is implemented in the "basisu_transcoder" class in transcoder/basisu_transcoder.h. The key methods are `start_decoding()`, `get_total_images()`, `get_image_info()`, `get_image_level_info()`, and `transcode_image_level()`. 
-
-I will be simplifying the transcoder so the caller doesn't need to deal with etc1_global_selector_codebook's next. To get an idea how to use the API, you can check out WebGL/basis_wrappers.cpp.
-
-`transcode_image_level()` and `transcode_slice()` are thread safe, i.e. you can decompress multiple images/slices from multiple threads. 
-
-To get development error messages printed to stdout when something goes wrong inside the transcoder, set the BASISU_DEVEL_MESSAGES macro to 1 in basisu_transcoder.h and recompile.
-
-### Shrinking the transcoder's compiled size
-
-These transcoder macros control which formats are supported by the transcoder at compile-time:
-
-- BASISD_SUPPORT_UASTC
-- BASISD_SUPPORT_DXT1 (BC1)
-- BASISD_SUPPORT_DXT5A (BC3/4/5)
-- BASISD_SUPPORT_BC7
-- BASISD_SUPPORT_BC7_MODE5
-- BASISD_SUPPORT_PVRTC1
-- BASISD_SUPPORT_ETC2_EAC_A8
-- BASISD_SUPPORT_ASTC
-- BASISD_SUPPORT_ATC
-- BASISD_SUPPORT_ASTC_HIGHER_OPAQUE_QUALITY
-- BASISD_SUPPORT_ETC2_EAC_RG11
-- BASISD_SUPPORT_FXT1
-- BASISD_SUPPORT_PVRTC2
-
-Each format requires its own set of precomputed ETC1S conversion tables. Disabling a format that you know will never be utilized will reduce the compiled size of the transcoder. 
-
-If you know your platform doesn't support BC7 or it's not necessary, be sure to set BASISD_SUPPORT_BC7=0. The tables for the mode 6 transcoder are very large (they bloat the compiled WebAssembly transcoder by around 400-500k). We'll probably be removing the mode 6 transcoder in a future update. 
-
-The ATC format (which achieves nearly the same quality as BC1/BC3) is for Adreno mobile devices only, and most of these devices probably support one of the newer texture formats. On many platforms/devices/API's you can disable it.
-
-### Quick Basis file details
-
-Internally, Basis files are composed of a non-uniform texture array of one or more 2D ETC1S or UASTC texture "slices". ETC1S is a simple subset of the ETC1 texture format popular on Android. ETC1S has no block flips, no 4x2 or 2x4 subblocks, and each block only uses 555 base colors. ETC1S is still 100% standard ETC1, so transcoding to ETC1 or the color block of ETC2 is a no-op. We chose ETC1S because it has the very valuable property that it can be quickly transcoded to almost any other GPU texture format at very high quality using only simple per-block operations with small 1D lookup tables. Transcoding ETC1S to BC1 usually only introduces around .3 dB Y PSNR quality loss, with less loss for ETC1S->BC7. Transcoding to PVRTC1 involves only simple block level operations to compute the endpoints, and simple per-pixel scalar operations to compute the modulation values.
-
-Basis files have a single set of compressed global endpoint/selector codebooks in ETC1S format, which all slices utilize. The ETC1S texture data is compressed using vector quantization (VQ) separately on the endpoints and selectors, followed by DPCM/RLE/psuedo-MTF/canonical Huffman coding. Each ETC1S texture slice may be a different resolution. Mipmaps (if any) are always stored in order from largest to smallest level. The file format supports either storing the selector codebook directly (using DPCM+Huffman), or storing the selector codebook using a hierarchical virtual codebook scheme. 
-
-Once the codebook and Huffman tables are decompressed, the slices are randomly accessible in any order. Opaque files always have one slice per image mipmap level, and files with alpha channels always have two slices per image mipmap level (even if some images in the file don't have alpha channels, i.e. alpha is all or nothing at the file level). The transcoder abstracts these details away into a simple "image" API, which is what most callers will use. An image is either one or more RGB slices (one per mipmap level), or one or more pairs of RGB/A slices (two per mipmap level). Internally, alpha slices are also stored in ETC1S format, like the color data, so selector correlations across color/alpha can be exploited. This also allows both RGB and alpha slices to be transcoded to opaque-only texture formats like ETC1, BC1, or PVRTC1 with no transparency.
-
-We currently only support CPU transcoding, but GPU assisted transcoding/format conversion is also possible by uploading the decompressed codebooks as textures and using compute shaders to convert the ETC1S codebook block indices to the desired output texture or pixel format.
-
-### Calling the encoder from C/C++
-
-I'm going to provide a simple C-style API to call the encoder directly. For now, you can call the C++ interface in basisu_comp.cpp/.h. See struct basis_compressor_params and class basis_compressor. Almost the entire command line tool's functionality is in basis_compressor. This class supports 100% in-memory compression with no file I/O.
-
-### GPU texture format support details
-
-Here's a [table](https://github.com/BinomialLLC/basis_universal/wiki/OpenGL-texture-format-enums-table) showing the supported compressed texture formats and their corresponding OpenGL texture formats.
-
-Internally, all ETC1S slices can be converted to any format, and the system is very flexible. The transcoder's image API supports converting alpha slices to color texture formats, which allows the user to transcode textures with alpha to two ETC1 images, etc.
-
-ETC1 - The system's internal texture format is ETC1S, so outputting ETC1 texture data is a no-op. We only use differential encodings, each subblock uses the same base color (the differential color is always [0,0,0]), and flips are always enabled.
-
-ETC2 - The color block will be ETC1S, and the alpha block is EAC. Conversion from ETC1S->EAC is very fast and nearly lossless.
-
-BC1/DXT1 - ETC1S->BC1 conversion loses approx. .3-.5 dB Y PSNR relative to the source ETC1S data. We don't currently use 3 color (punchthrough) blocks, but we could easily add them. Conversion to BC1 is very fast.
-
-BC3/DXT5 - The color block is BC1, the alpha block is BC4. ETC1S->BC4 is nearly lossless and very fast.
-
-BC4/DXT5A - ETC1S->BC4 conversion is nearly lossless and very fast.
-
-BC5/3DC/DXN - Two BC4 blocks. As the conversion from ETC1S->BC4 blocks is nearly lossless, we think this format (with large codebooks) will work well with high quality tangent space normal maps. Each channel gets its own ETC1S texture. Transcoding is very fast.
-
-BC7 - There are two transcoders, one for mode 6 RGB, and another for mode 5 RGB/RGBA. The conversion from ETC1S->BC7 mode 6 is nearly lossless, but the tables are very large. It is highly recommended you disable BC7 entirely (BASISD_SUPPORT_BC7=0) or disable the mode 6 transcoder (BASISD_SUPPORT_BC7_MODE6_OPAQUE_ONLY=0) at compilation time on platforms (like WebAssembly) where the compiled transcoder size matters.
-
-Transcoding to BC7 mode 5 is very fast, mode 6 is slightly slower.
-
-PVRTC1 4bpp - There are two transcoders, one for RGB and another for RGBA. The conversion from ETC1S->PVRTC1 RGB is a two step process. The first step finds the RGB bounding boxes of each ETC1S block, which is fast (we don't need to process the entire block's pixels, just the 1-4 used block colors). The first pass occurs during ETC1S transcoding. The second pass computes the per-pixel 2-bpp modulation values, which is fast because we can do this in a luma-like colorspace using simple scalar (not full RGB) operations. The second pass is highly optimized, and threading it would be easy. Quality is roughly the same as PVRTexTool's "Normal (Good Quality)" setting. ETC1S->PVRTC1 loses the most quality - several Y dB PSNR. 
-
-ETC1S->PVRTC1 RGBA is a three step process: first we unpack the ETC1S RGB slice, then the ETC1S A slice to a temp buffer, then we pack this data to PVRTC1 RGBA. The real-time transcoder is really only intended for relatively simple alpha channels, like opacity masks. If the output is too decorrelated or too complex opaque quality really suffers. We know how to improve PVRTC1 quality, but it would require another pass through the texture which would slow things down.
-
-Interestingly, the low pass filtering-like artifacts due to PVRTC1's unique block endpoint interpolation help obscure ETC1S chroma artifacts. 
-
-Currently, the PVRTC1 transcoder requires that the ETC1S texture's dimensions both be a power of two (but non-square is OK, although I believe iOS doesn't support that). We will be adding the ability to transcode non-pow2 ETC1S textures to larger pow2 PVRTC1 textures soon.
-
-Note that for PVRTC1, the transcoder differs slightly in how it computes the memory size of compressed textures. Basis only writes (or requires) the output buffer to be total_blocks * bytes_per_block. But OpenGL requires extra padding for very small textures:
-
-			 // https://www.khronos.org/registry/OpenGL/extensions/IMG/IMG_texture_compression_pvrtc.txt
-			 const uint32_t width = (orig_width + 3) & ~3;
-			 const uint32_t height = (orig_height + 3) & ~3;
-			 const uint32_t size_in_bytes = (std::max(8U, width) * std::max(8U, height) * 4 + 7) / 8;
-       
-When you call the transcoder and pass it a buffer that's larger than required, these extra padding bytes will be set to 0.
-
-PVRTC2 RGB - Fast and almost as high quality as BC1. It supports non-square, non-power of 2 textures.
-
-PVRTC2 RGBA - This format is slower and much more complex than PVRTC2 RGB. It will only work well with textures using premultiplied alpha. The alpha channel should be relatively simple (like opacity maps).
-
-ETC2 EAC R11/RG11 - R11 is roughly equivalent to BC4, and RG11 is like BC5. Transcoding is very fast and high quality.
-
-ASTC 4x4 - The ASTC transcoder supports void extent (constant color) blocks and several different endpoint precision modes and encodings: L, LA, RGB or RGBA. To shrink the compiled size of the ASTC transcoder, set BASISD_SUPPORT_ASTC_HIGHER_OPAQUE_QUALITY to 0, which lowers endpoint precision slightly.
-
-Note the ASTC transcoder assumes sRGB sampling won't be enabled when sampling the ASTC texture data. (ASTC decompression works slightly differently when sRGB reads are enabled vs. disabled.) Enabling sRGB reads will result in a tiny amount of higher error that is unlikely to be noticeable. This was a conscious decision we had to make because we could only afford to include one set of precomputed ETC1S->ASTC conversion tables into the transcoder. We may put in two tables into the next transcoder release and let the user decide what they want at compile and/or run-time.
-
-ATI ATC - There are two transcoders, one for RGB (which is similar to BC1), and one for RGBA_INTERPOLATED_ALPHA (which is basically a BC4 block followed by an ATC block). This format is only useful on Adreno GPU's, so to cut down on the transcoder's size you can set BASISD_SUPPORT_ATC to 0 at compilation time if you know you'll never need ATC data. Quality is very similar to BC1/BC3.
-
-RGB565, BGR564, ARGB 8888 and ARGB 4444 - Various uncompressed raw pixel formats. Internally the transcoder directly converts the ETC1S endpoint/selector data directly to uncompressed pixels. The output buffer is treated as a plain raster image, not as a 2D array of blocks. No dithering or downsampling is supported yet.
-
-### How to use the system 
-
-First, become familiar with the exact compressed texture formats your device hardware *and* rendering API support. Just because your device supports a particular format (like PVRTC2) doesn't mean your OS or API does (iOS doesn't support PVRTC2, even though their hardware did). On Android, ETC1/2 are popular. iOS supports PVRTC1 (pretty much always) and possibly ETC1/2 (but absolutely don't bet on it), and on desktop BC1-5/BC7 are king.
-
-Also, become familiar with any texture size restrictions. For example, on iOS, you can only use square power of 2 texture dimensions for PVRTC1, and there's nothing Basis can do for you today that works around this limitation. (We will be supporting the ability to trancode smaller non-pow2 textures into larger power of 2 PVRTC1 textures soon.)
-
-The primary issues that trip up mobile native/WebGL app developers: Older ETC1-only devices, which require some sort of annoying fallback to handle alpha textures. PVRTC1's requirement for square (on iOS) power of 2 texture dimensions (Android/iOS), and PVRTC1's unique artifacts compared to all the other formats also cause developer's issues.
-
-ETC2 EAC RGBA and ASTC work around these issues, but these formats are still not available everywhere yet (especially WebGL on iOS, which still only supports PVRTC1 even on hardware that supports ETC1/2 or ASTC). Unfortunately PVRTC2 (which we're supporting next) was never supported on iOS, even on hardware that could handle it.
-
-Here are the major texturing scenarios the system supports:
-
-1. For color-only textures, you can transcode to whatever format your target device supports. Remember that PVRTC1 requires square power of 2 size textures, and there's nothing Basis can currently do to help you work around this limitation. (Basic supports non-square PVRTC1 textures, but iOS doesn't.) For devices which support both ASTC and PVRTC1, ASTC will be much higher quality. For devices supporting both PVRTC2 and ASTC, for most opaque textures you can probably use PVRTC2 which will conserve memory.
-
-2. For alpha textures, you can create .basis files with alpha channels. To do this with the basisu compressor, either create 32-bit PNG files with alpha, or use two PNG files with the "-alpha_file" command line option to specify where the alpha data should come from. (For texture arrays, you can use multiple -file and -alpha_file command line options. Mipmap generation automatically supports alpha channels.) 
-
-Now deploy alpha content like this:
-
-ETC1-only devices/API's: Transcode to two ETC1 textures and sample and recombine them in a shader. You can either use one ETC1 texture that's twice as high/wide, or two separate ETC1 textures. Alternatly, you can transcode to a single 4444 or 8888 texture.
-
-ETC2 devices/API's: Just transcode to ETC2 EAC RGBA. ETC2 EAC's alpha quality is similar to BC3, and very high.
-
-PVRTC1 devices/API's: Use a single PVRTC1 RGBA texture. For more complex alpha channels, transcode to two PVRTC1 4bpp textures, and sample twice. The PVRTC1 encoder is a real-time encoder, so you'll need to evaluate it on your texture/image data. If the alpha data is too complex or decorrelated both RGB and A quality will seriously suffer. (Sorry - PVRTC1 is an unforgiving format.)
-
-Devices/API's supporting only BC1-5: Use BC3, which the transcoder supports. BC3's quality  is very high.
-
-Newer devices supporting BC7: Transcode to BC7 mode 5, which supports a high-quality alpha channel. Quality will be similar to BC3.
-
-Devices/API's supporting ASTC: Just transcode to ASTC, which supports a variety of internal block encodings that will be automatically chosen by the transcoder for every block: L, LA, RGB, RGBA. If the device supports both PVRTC1/2 and ASTC, ASTC 4x4 will give you more reliable and much higher quality than PVRTC1/2, but it uses up twice as much RAM (8bpp vs 4bpp).
-
-Device's/API's supprting ATC: Transcode to ATC_RGBA_INTERPOLATED_ALPHA. This format is basically equivalent to BC3.
-
-Device's/API's supporting PVRTC2: The real-time PVRTC2 RGBA transcoder can only handle simple opacity maps. You'll need to experiment to see if it's high enough quality. For devices which support both PVRTC2 and ASTC, ASTC 4x4 is preferable for alpha content although it will require 2x as much memory.
-
-3. For high quality tangent space normal maps, here's one suggested solution that should work well today:
-
-Compress with the -normal_map flag, which disables a lot of stuff that has interfered with normal maps in the past. Also compress with -comp_level 2-4, which creates the highest quality codebooks. Use larger codebooks (use the -max_endpoints and -max_selectors options directly, with larger values).
-
-Start with 2 component normalized XY tangent space normal maps (where XY range from [-1,1]) and encode them into two 8-bit channels (where XY is packed into [0,255]). Now put X in color, and Y in alpha, and compress that 32-bit PNG using basisu. The command line tool and encoder class support the option "-separate_rg_to_color_alpha" that swizzles 2 component RG normal maps to RRRG before compression, aiding this process.
-
-ETC1 only devices/API's: Transcode to two ETC1 textures and sample them in a shader, or use an uncompressed format. You can either use one ETC1 texture that's twice as high/wide, or two separate ETC1 textures. The transcoder supports transcoding alpha slices to any color output format using a special flag: `basist::basisu_transcoder::cDecodeFlagsTranscodeAlphaDataToOpaqueFormats`. This will look great because each channel gets its own endpoints and selectors.
-
-ETC2 devices/API's: Transcode to a single ETC2 EAC RGBA or a ETC2 EAC RG11 texture, sample once in shader. This should look great.
-
-PVRTC1 devices/API's: Transcode to two PVRTC1 opaque textures (RGB to one, A to another, which the transcoder supports using the cDecodeFlagsTranscodeAlphaDataToOpaqueFormats flag) and sample each in the shader. This should look fairly good. Its doubtful the PVRTC1 RGBA transcoder could handle two complex channels of data well.
-
-Devices/API's supporting BC1-5, BC6H, BC7: Transcode to a single BC5 textures, which used to be called "ATI 3DC". It has two high quality BC4 blocks in there, so it'll look great. You could also use BC7 mode 5, although BC5 will have slightly less error.
-
-Devices/API's supporting ASTC: Just transcode to ASTC. The block transcoder will automatically encode to the "LA" format. 
-
-### Special Transcoding Scenarios
-
-1. Color-only .basis files don't have alpha slices, so here's what currently happens when you transcode them to various texture formats (we are open to feedback or adding more options here):
-
-BC3/DXT5 or ETC2 EAC: The color data gets transcoded to output color, as you would expect. You'll get all-255 blocks in the output alpha blocks, because the transcoder doesn't have any alpha slice data to convert to the output format. (Alternately, we could convert a single channel of the color data (like G) to output alpha, and assume the user will swizzle in the shader, which could provide a tiny gain in ETC1S conversion quality. But now output alpha would require special interpretation and we would need to invoke the block transcoders twice.)
-
-BC4/DXT5A: This format is usually interpreted as holding single channel red-only data. We invoke the ETC1S->BC4 transcoder, which takes the red channel of the color slice (which we assume is grayscale, but doesn't have to be) and converts that to BC4/DXT5A blocks. (We could allow the user to select the source channel, if that is useful.)
-
-BC5/3DC: This format has two BC4 blocks, and is usually used for XY (red/green) tangent space normal maps. The first block (output red/or X) will have the R channel of the color slice (which we assume is actually grayscale, but doesn't have to be), and the output green channel (or Y) will have all-255 blocks. We could support converting the first two color components of the color ETC1S texture slice to BC5, but doing so doesn't seem to have any practical benefits (just use BC1 or BC7). Alternately we could support allowing the user to select a source channel other than red.
-
-Note that you can directly control exactly how transcoding works at the block level by calling a lower level API, basisu_transcoder::transcode_slice(). The higher level API (transcode_image_level) uses this low-level API internally. find_slice() and get_file_info() return all the slice information you would need to call this lower level API. I would study transcode_image_level()'s implementation before using the slice API to get familiar with it. The slice API was written first.
-
-2. To get uncompressed 16/32-bpp pixel data from a slice, call the transcoder with one of the uncompressed pixel formats. This will be faster than transcoding to ETC1S then unpacking the blocks yourself (on the CPU).
-
-### Next Major Steps - Higher Quality!
-
-Within the next couple months or so, we'll be adding ASTC 4x4 opaque and transparent (and maybe 6x6), PVRTC1 4bpp transparent, and BC7 transparent. Of these, PVRTC1 4bpp transparent will be the most challenging from a quality perspective, and ASTC will be the most challenging from a texture format perspective. The resulting quality will still be baseline ETC1S.
-
-We'll be upgrading the system's quality to something halfway in between BC1 and BC7 (but more towards BC7 than BC1). We're going to enlarge the codebooks with optional extended data, add 2 partitions so blocks can use multiple color endpoints, and add higher precision selectors and endpoints. We may allow codebook entries to be split up (with extra per-block data indicating which split codebook entry to use), creating larger codebooks that only the extended texture data references. We're going to leverage what we learned building our state of the art vectorized BC7 encoder (Basis BC7), and our open source [bc7enc16](https://github.com/richgel999/bc7enc16) encoder, while creating this. We currently think just BC7 modes 1 and 6 (and the ASTC equivalents) will be enough.
-
-We need a C-style API for the compressor class, and a bunch of compression/transcoding examples (native and WebGL). We also need to release a decent regression test.
-
-### Improvements vs. our earlier work
-
-Basis supports up to 16K codebooks for both endpoints and selectors for significantly higher quality textures, uses much higher quality codebook generators, the format uses a new prediction scheme for block endpoints (replicate one of 3 neighbors or use DPCM+Huffman from left neighbor), the format uses a selector history buffer, and RLE codes are implemented for all symbol types for high efficiency on simpler textures. The encoder also implements several new rate distortion optimization stages on both endpoint and selectors, and in Basis the encoder backend can call back into the frontend to reoptimize endpoints or selectors after the RDO stages modify the block codebook indices for better rate distortion performance. 
-
-The file format also supports very large non-uniform texture arrays, making the system usable as an RDO backend in specialized block-based video encoders. Internally, the encoder only handles blocks and all later RDO stages which assume a fixed 2D raster order of the blocks can be optionally disabled.
+To enable compression support compile the JavaScript wrappers in webgl/transcoding/basis_wrappers.cpp with BASISU_SUPPORT_ENCODING set to 1. See the webgl/encoding directory. 
 
 ### Special thanks
 A huge thanks to Google for partnering with us and enabling this system to be open sourced.
@@ -472,6 +213,8 @@
 
 Thanks to Mike Dussault (SpaceX) for supporting Binomial in the early days.
 
+Thanks to Graeme Devine at Magic Leap.
+
 Thanks to Matt Pritchard, formerly of Valve Software and Microsoft, for helping me with the computer hardware I used while building this system and its predecessor. 
 
 Thanks to John Brooks at Blue Shift, Inc. for inspiring this work by showing me his Dreamcast texture compression system around 2002, and for releasing etc2comp. I first saw the subblock flip estimation approach (used in basisu_etc.cpp) in etc2comp.
diff --git a/basisu.vcxproj b/basisu.vcxproj
index 3407176..f4ad5fd 100644
--- a/basisu.vcxproj
+++ b/basisu.vcxproj
@@ -147,52 +147,51 @@
     </Link>
   </ItemDefinitionGroup>
   <ItemGroup>
-    <ClCompile Include="apg_bmp.c" />
-    <ClCompile Include="basisu_astc_decomp.cpp" />
-    <ClCompile Include="basisu_bc7enc.cpp" />
-    <ClCompile Include="basisu_ssim.cpp" />
-    <ClCompile Include="basisu_uastc_enc.cpp" />
-    <ClCompile Include="jpgd.cpp" />
+    <ClCompile Include="encoder\apg_bmp.c" />
+    <ClCompile Include="encoder\basisu_astc_decomp.cpp" />
+    <ClCompile Include="encoder\basisu_backend.cpp" />
+    <ClCompile Include="encoder\basisu_basis_file.cpp" />
+    <ClCompile Include="encoder\basisu_bc7enc.cpp" />
+    <ClCompile Include="encoder\basisu_comp.cpp" />
+    <ClCompile Include="encoder\basisu_enc.cpp" />
+    <ClCompile Include="encoder\basisu_etc.cpp" />
+    <ClCompile Include="encoder\basisu_frontend.cpp" />
+    <ClCompile Include="encoder\basisu_global_selector_palette_helpers.cpp" />
+    <ClCompile Include="encoder\basisu_gpu_texture.cpp" />
+    <ClCompile Include="encoder\basisu_pvrtc1_4.cpp" />
+    <ClCompile Include="encoder\basisu_resampler.cpp" />
+    <ClCompile Include="encoder\basisu_resample_filters.cpp" />
+    <ClCompile Include="encoder\basisu_ssim.cpp" />
+    <ClCompile Include="encoder\basisu_uastc_enc.cpp" />
+    <ClCompile Include="encoder\jpgd.cpp" />
+    <ClCompile Include="encoder\lodepng.cpp" />
     <ClCompile Include="transcoder\basisu_transcoder.cpp" />
-    <ClInclude Include="apg_bmp.h" />
-    <ClInclude Include="basisu_bc7enc.h" />
-    <ClInclude Include="basisu_astc_decomp.h" />
-    <ClInclude Include="basisu_basis_file.h" />
-    <ClInclude Include="basisu_comp.h" />
-    <ClInclude Include="basisu_enc.h" />
-    <ClInclude Include="basisu_etc.h" />
-    <ClInclude Include="basisu_gpu_texture.h" />
-    <ClInclude Include="basisu_backend.h" />
-    <ClInclude Include="basisu_frontend.h" />
-    <ClInclude Include="basisu_pvrtc1_4.h" />
-    <ClInclude Include="basisu_global_selector_palette_helpers.h" />
-    <ClInclude Include="basisu_resampler.h" />
-    <ClInclude Include="basisu_resampler_filters.h" />
-    <ClCompile Include="basisu_resampler.cpp" />
-    <ClCompile Include="basisu_resample_filters.cpp" />
-    <ClInclude Include="basisu_ssim.h" />
-    <ClInclude Include="basisu_uastc_enc.h" />
-    <ClInclude Include="jpgd.h" />
-    <ClInclude Include="lodepng.h" />
+    <ClInclude Include="encoder\apg_bmp.h" />
+    <ClInclude Include="encoder\basisu_astc_decomp.h" />
+    <ClInclude Include="encoder\basisu_backend.h" />
+    <ClInclude Include="encoder\basisu_basis_file.h" />
+    <ClInclude Include="encoder\basisu_bc7enc.h" />
+    <ClInclude Include="encoder\basisu_comp.h" />
+    <ClInclude Include="encoder\basisu_enc.h" />
+    <ClInclude Include="encoder\basisu_etc.h" />
+    <ClInclude Include="encoder\basisu_frontend.h" />
+    <ClInclude Include="encoder\basisu_global_selector_palette_helpers.h" />
+    <ClInclude Include="encoder\basisu_gpu_texture.h" />
+    <ClInclude Include="encoder\basisu_miniz.h" />
+    <ClInclude Include="encoder\basisu_pvrtc1_4.h" />
+    <ClInclude Include="encoder\basisu_resampler.h" />
+    <ClInclude Include="encoder\basisu_resampler_filters.h" />
+    <ClInclude Include="encoder\basisu_ssim.h" />
+    <ClInclude Include="encoder\basisu_uastc_enc.h" />
+    <ClInclude Include="encoder\jpgd.h" />
+    <ClInclude Include="encoder\lodepng.h" />
     <ClInclude Include="transcoder\basisu.h" />
     <ClInclude Include="transcoder\basisu_transcoder.h" />
     <ClInclude Include="transcoder\basisu_transcoder_internal.h" />
-    <ClInclude Include="transcoder\basisu_file_headers.h" />
-    <ClInclude Include="transcoder\basisu_global_selector_cb.h" />
     <ClInclude Include="transcoder\basisu_global_selector_palette.h" />
     <ClInclude Include="transcoder\basisu_transcoder_uastc.h" />
   </ItemGroup>
   <ItemGroup>
-    <ClCompile Include="basisu_basis_file.cpp" />
-    <ClCompile Include="basisu_comp.cpp" />
-    <ClCompile Include="basisu_enc.cpp" />
-    <ClCompile Include="basisu_etc.cpp" />
-    <ClCompile Include="basisu_backend.cpp" />
-    <ClCompile Include="basisu_frontend.cpp" />
-    <ClCompile Include="basisu_pvrtc1_4.cpp" />
-    <ClCompile Include="basisu_global_selector_palette_helpers.cpp" />
-    <ClCompile Include="basisu_gpu_texture.cpp" />
-    <ClCompile Include="lodepng.cpp" />
     <ClCompile Include="basisu_tool.cpp" />
   </ItemGroup>
   <ItemGroup>
diff --git a/basisu.vcxproj.filters b/basisu.vcxproj.filters
index 1764b4b..4f7afed 100644
--- a/basisu.vcxproj.filters
+++ b/basisu.vcxproj.filters
@@ -1,44 +1,66 @@
 <?xml version="1.0" encoding="utf-8"?>
 <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <ItemGroup>
-    <ClCompile Include="basisu_resampler.cpp" />
-    <ClCompile Include="basisu_resample_filters.cpp" />
-    <ClCompile Include="basisu_basis_file.cpp" />
-    <ClCompile Include="basisu_comp.cpp" />
-    <ClCompile Include="basisu_enc.cpp" />
-    <ClCompile Include="basisu_etc.cpp" />
-    <ClCompile Include="basisu_backend.cpp" />
-    <ClCompile Include="basisu_frontend.cpp" />
-    <ClCompile Include="basisu_pvrtc1_4.cpp" />
-    <ClCompile Include="basisu_global_selector_palette_helpers.cpp" />
-    <ClCompile Include="basisu_gpu_texture.cpp" />
-    <ClCompile Include="lodepng.cpp" />
     <ClCompile Include="basisu_tool.cpp" />
     <ClCompile Include="transcoder\basisu_transcoder.cpp">
       <Filter>transcoder</Filter>
     </ClCompile>
-    <ClCompile Include="basisu_ssim.cpp" />
-    <ClCompile Include="basisu_astc_decomp.cpp" />
-    <ClCompile Include="basisu_uastc_enc.cpp" />
-    <ClCompile Include="basisu_bc7enc.cpp" />
-    <ClCompile Include="apg_bmp.c" />
-    <ClCompile Include="jpgd.cpp" />
+    <ClCompile Include="encoder\apg_bmp.c">
+      <Filter>encoder</Filter>
+    </ClCompile>
+    <ClCompile Include="encoder\basisu_astc_decomp.cpp">
+      <Filter>encoder</Filter>
+    </ClCompile>
+    <ClCompile Include="encoder\basisu_backend.cpp">
+      <Filter>encoder</Filter>
+    </ClCompile>
+    <ClCompile Include="encoder\basisu_basis_file.cpp">
+      <Filter>encoder</Filter>
+    </ClCompile>
+    <ClCompile Include="encoder\basisu_bc7enc.cpp">
+      <Filter>encoder</Filter>
+    </ClCompile>
+    <ClCompile Include="encoder\basisu_comp.cpp">
+      <Filter>encoder</Filter>
+    </ClCompile>
+    <ClCompile Include="encoder\basisu_enc.cpp">
+      <Filter>encoder</Filter>
+    </ClCompile>
+    <ClCompile Include="encoder\basisu_etc.cpp">
+      <Filter>encoder</Filter>
+    </ClCompile>
+    <ClCompile Include="encoder\basisu_frontend.cpp">
+      <Filter>encoder</Filter>
+    </ClCompile>
+    <ClCompile Include="encoder\basisu_global_selector_palette_helpers.cpp">
+      <Filter>encoder</Filter>
+    </ClCompile>
+    <ClCompile Include="encoder\basisu_gpu_texture.cpp">
+      <Filter>encoder</Filter>
+    </ClCompile>
+    <ClCompile Include="encoder\basisu_pvrtc1_4.cpp">
+      <Filter>encoder</Filter>
+    </ClCompile>
+    <ClCompile Include="encoder\basisu_resampler.cpp">
+      <Filter>encoder</Filter>
+    </ClCompile>
+    <ClCompile Include="encoder\basisu_uastc_enc.cpp">
+      <Filter>encoder</Filter>
+    </ClCompile>
+    <ClCompile Include="encoder\jpgd.cpp">
+      <Filter>encoder</Filter>
+    </ClCompile>
+    <ClCompile Include="encoder\lodepng.cpp">
+      <Filter>encoder</Filter>
+    </ClCompile>
+    <ClCompile Include="encoder\basisu_resample_filters.cpp">
+      <Filter>encoder</Filter>
+    </ClCompile>
+    <ClCompile Include="encoder\basisu_ssim.cpp">
+      <Filter>encoder</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
-    <ClInclude Include="basisu_basis_file.h" />
-    <ClInclude Include="basisu_comp.h" />
-    <ClInclude Include="basisu_enc.h" />
-    <ClInclude Include="basisu_etc.h" />
-    <ClInclude Include="basisu_gpu_texture.h" />
-    <ClInclude Include="basisu_backend.h" />
-    <ClInclude Include="basisu_frontend.h" />
-    <ClInclude Include="basisu_pvrtc1_4.h" />
-    <ClInclude Include="basisu_global_selector_palette_helpers.h" />
-    <ClInclude Include="basisu_resampler.h" />
-    <ClInclude Include="basisu_resampler_filters.h" />
-    <ClInclude Include="lodepng.h" />
-    <ClInclude Include="transcoder\basisu_file_headers.h" />
-    <ClInclude Include="transcoder\basisu_global_selector_cb.h" />
     <ClInclude Include="transcoder\basisu_global_selector_palette.h">
       <Filter>transcoder</Filter>
     </ClInclude>
@@ -51,15 +73,66 @@
     <ClInclude Include="transcoder\basisu_transcoder.h">
       <Filter>transcoder</Filter>
     </ClInclude>
-    <ClInclude Include="basisu_ssim.h" />
-    <ClInclude Include="basisu_astc_decomp.h" />
-    <ClInclude Include="basisu_uastc_enc.h" />
-    <ClInclude Include="basisu_bc7enc.h" />
     <ClInclude Include="transcoder\basisu_transcoder_uastc.h">
       <Filter>transcoder</Filter>
     </ClInclude>
-    <ClInclude Include="apg_bmp.h" />
-    <ClInclude Include="jpgd.h" />
+    <ClInclude Include="encoder\apg_bmp.h">
+      <Filter>encoder</Filter>
+    </ClInclude>
+    <ClInclude Include="encoder\basisu_astc_decomp.h">
+      <Filter>encoder</Filter>
+    </ClInclude>
+    <ClInclude Include="encoder\basisu_backend.h">
+      <Filter>encoder</Filter>
+    </ClInclude>
+    <ClInclude Include="encoder\basisu_basis_file.h">
+      <Filter>encoder</Filter>
+    </ClInclude>
+    <ClInclude Include="encoder\basisu_bc7enc.h">
+      <Filter>encoder</Filter>
+    </ClInclude>
+    <ClInclude Include="encoder\basisu_comp.h">
+      <Filter>encoder</Filter>
+    </ClInclude>
+    <ClInclude Include="encoder\basisu_enc.h">
+      <Filter>encoder</Filter>
+    </ClInclude>
+    <ClInclude Include="encoder\basisu_etc.h">
+      <Filter>encoder</Filter>
+    </ClInclude>
+    <ClInclude Include="encoder\basisu_frontend.h">
+      <Filter>encoder</Filter>
+    </ClInclude>
+    <ClInclude Include="encoder\basisu_global_selector_palette_helpers.h">
+      <Filter>encoder</Filter>
+    </ClInclude>
+    <ClInclude Include="encoder\basisu_gpu_texture.h">
+      <Filter>encoder</Filter>
+    </ClInclude>
+    <ClInclude Include="encoder\basisu_miniz.h">
+      <Filter>encoder</Filter>
+    </ClInclude>
+    <ClInclude Include="encoder\basisu_pvrtc1_4.h">
+      <Filter>encoder</Filter>
+    </ClInclude>
+    <ClInclude Include="encoder\basisu_resampler.h">
+      <Filter>encoder</Filter>
+    </ClInclude>
+    <ClInclude Include="encoder\basisu_uastc_enc.h">
+      <Filter>encoder</Filter>
+    </ClInclude>
+    <ClInclude Include="encoder\jpgd.h">
+      <Filter>encoder</Filter>
+    </ClInclude>
+    <ClInclude Include="encoder\lodepng.h">
+      <Filter>encoder</Filter>
+    </ClInclude>
+    <ClInclude Include="encoder\basisu_ssim.h">
+      <Filter>encoder</Filter>
+    </ClInclude>
+    <ClInclude Include="encoder\basisu_resampler_filters.h">
+      <Filter>encoder</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <None Include="transcoder\basisu_transcoder_tables_dxt1_6.inc">
@@ -91,5 +164,8 @@
     <Filter Include="transcoder">
       <UniqueIdentifier>{7a54aaad-1d10-4bdf-b8e9-c14ed2263ed8}</UniqueIdentifier>
     </Filter>
+    <Filter Include="encoder">
+      <UniqueIdentifier>{518dd5c5-a7e1-4e79-8bb4-253e2d540c2c}</UniqueIdentifier>
+    </Filter>
   </ItemGroup>
 </Project>
\ No newline at end of file
diff --git a/basisu_tool.cpp b/basisu_tool.cpp
index 3591ed2..aa168dc 100644
--- a/basisu_tool.cpp
+++ b/basisu_tool.cpp
@@ -18,15 +18,15 @@
 
 #include "transcoder/basisu.h"
 #include "transcoder/basisu_transcoder_internal.h"
-#include "basisu_enc.h"
-#include "basisu_etc.h"
-#include "basisu_gpu_texture.h"
-#include "basisu_frontend.h"
-#include "basisu_backend.h"
+#include "encoder/basisu_enc.h"
+#include "encoder/basisu_etc.h"
+#include "encoder/basisu_gpu_texture.h"
+#include "encoder/basisu_frontend.h"
+#include "encoder/basisu_backend.h"
 #include "transcoder/basisu_global_selector_palette.h"
-#include "basisu_comp.h"
+#include "encoder/basisu_comp.h"
 #include "transcoder/basisu_transcoder.h"
-#include "basisu_ssim.h"
+#include "encoder/basisu_ssim.h"
 
 // Set BASISU_CATCH_EXCEPTIONS if you want exceptions to crash the app, otherwise main() catches them.
 #define BASISU_CATCH_EXCEPTIONS 0
@@ -408,7 +408,7 @@
 			else if (strcasecmp(pArg, "-force_alpha") == 0)
 				m_comp_params.m_force_alpha = true;
 			else if ((strcasecmp(pArg, "-separate_rg_to_color_alpha") == 0) ||
-					(strcasecmp(pArg, "-seperate_rg_to_color_alpha") == 0)) // was mispelled for a while - whoops!
+			        (strcasecmp(pArg, "-seperate_rg_to_color_alpha") == 0)) // was mispelled for a while - whoops!
 			{
 				m_comp_params.m_swizzle[0] = 0;
 				m_comp_params.m_swizzle[1] = 0;
@@ -1591,11 +1591,11 @@
 	return true;
 }
 
-#include "basisu_astc_decomp.h"
-#include "basisu_pvrtc1_4.h"
+#include "encoder/basisu_astc_decomp.h"
+#include "encoder/basisu_pvrtc1_4.h"
 
 #define MINIZ_HEADER_FILE_ONLY
-#include "basisu_miniz.h"
+#include "encoder/basisu_miniz.h"
 static bool bench_mode(command_line_params& opts)
 {
 #if 0
diff --git a/apg_bmp.c b/encoder/apg_bmp.c
similarity index 100%
rename from apg_bmp.c
rename to encoder/apg_bmp.c
diff --git a/apg_bmp.h b/encoder/apg_bmp.h
similarity index 100%
rename from apg_bmp.h
rename to encoder/apg_bmp.h
diff --git a/basisu_astc_decomp.cpp b/encoder/basisu_astc_decomp.cpp
similarity index 99%
rename from basisu_astc_decomp.cpp
rename to encoder/basisu_astc_decomp.cpp
index 81a1800..f8d40d7 100644
--- a/basisu_astc_decomp.cpp
+++ b/encoder/basisu_astc_decomp.cpp
@@ -50,6 +50,13 @@
 
 #define DE_ASSERT assert
 
+#ifdef _MSC_VER
+#pragma warning (disable:4505) // unreferenced local function has been removed
+#elif defined(__GNUC__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-function"
+#endif
+
 namespace basisu_astc
 {
 	static bool inBounds(int v, int l, int h)
@@ -1548,3 +1555,7 @@
 
 } // astc
 } // basisu_astc
+
+#if defined(__GNUC__)
+#pragma GCC diagnostic pop
+#endif
\ No newline at end of file
diff --git a/basisu_astc_decomp.h b/encoder/basisu_astc_decomp.h
similarity index 94%
rename from basisu_astc_decomp.h
rename to encoder/basisu_astc_decomp.h
index 6cd053b..9ec2e46 100644
--- a/basisu_astc_decomp.h
+++ b/encoder/basisu_astc_decomp.h
@@ -23,7 +23,7 @@
  * \brief ASTC Utilities.
  *//*--------------------------------------------------------------------*/
 
-#include "transcoder/basisu.h" // to pick up the iterator debug level madness
+#include "../transcoder/basisu.h" // to pick up the iterator debug level madness
 #include <vector>
 #include <stdint.h>
 
diff --git a/basisu_backend.cpp b/encoder/basisu_backend.cpp
similarity index 100%
rename from basisu_backend.cpp
rename to encoder/basisu_backend.cpp
diff --git a/basisu_backend.h b/encoder/basisu_backend.h
similarity index 97%
rename from basisu_backend.h
rename to encoder/basisu_backend.h
index 171ca83..e8518e2 100644
--- a/basisu_backend.h
+++ b/encoder/basisu_backend.h
@@ -14,10 +14,10 @@
 // limitations under the License.
 #pragma once
 
-#include "transcoder/basisu.h"
+#include "../transcoder/basisu.h"
 #include "basisu_enc.h"
-#include "transcoder/basisu_transcoder_internal.h"
-#include "transcoder/basisu_global_selector_palette.h"
+#include "../transcoder/basisu_transcoder_internal.h"
+#include "../transcoder/basisu_global_selector_palette.h"
 #include "basisu_frontend.h"
 
 namespace basisu
diff --git a/basisu_basis_file.cpp b/encoder/basisu_basis_file.cpp
similarity index 99%
rename from basisu_basis_file.cpp
rename to encoder/basisu_basis_file.cpp
index ce6acd6..9662a9a 100644
--- a/basisu_basis_file.cpp
+++ b/encoder/basisu_basis_file.cpp
@@ -13,7 +13,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 #include "basisu_basis_file.h"
-#include "transcoder/basisu_transcoder.h"
+#include "../transcoder/basisu_transcoder.h"
 
 // The output file version. Keep in sync with BASISD_SUPPORTED_BASIS_VERSION.
 #define BASIS_FILE_VERSION (0x13)
diff --git a/basisu_basis_file.h b/encoder/basisu_basis_file.h
similarity index 97%
rename from basisu_basis_file.h
rename to encoder/basisu_basis_file.h
index df3abbd..7d9c577 100644
--- a/basisu_basis_file.h
+++ b/encoder/basisu_basis_file.h
@@ -13,7 +13,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 #pragma once
-#include "transcoder/basisu_file_headers.h"
+#include "../transcoder/basisu_file_headers.h"
 #include "basisu_backend.h"
 
 namespace basisu
diff --git a/basisu_bc7enc.cpp b/encoder/basisu_bc7enc.cpp
similarity index 100%
rename from basisu_bc7enc.cpp
rename to encoder/basisu_bc7enc.cpp
diff --git a/basisu_bc7enc.h b/encoder/basisu_bc7enc.h
similarity index 98%
rename from basisu_bc7enc.h
rename to encoder/basisu_bc7enc.h
index 0d7a090..3af606f 100644
--- a/basisu_bc7enc.h
+++ b/encoder/basisu_bc7enc.h
@@ -13,7 +13,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 #include "basisu_enc.h"
-#include "transcoder/basisu_transcoder_uastc.h"
+#include "../transcoder/basisu_transcoder_uastc.h"
 
 namespace basisu
 {
diff --git a/basisu_comp.cpp b/encoder/basisu_comp.cpp
similarity index 97%
rename from basisu_comp.cpp
rename to encoder/basisu_comp.cpp
index 7f39a66..fdaf3f0 100644
--- a/basisu_comp.cpp
+++ b/encoder/basisu_comp.cpp
@@ -202,8 +202,11 @@
 				const uint32_t first_index = block_index_iter;
 				const uint32_t last_index = minimum<uint32_t>(total_blocks, block_index_iter + N);
 
+				// FIXME: This sucks, but we're having a stack size related problem with std::function with emscripten.
+#ifndef __EMSCRIPTEN__
 				m_params.m_pJob_pool->add_job([this, first_index, last_index, num_blocks_x, num_blocks_y, total_blocks, &source_image, &tex, &total_blocks_processed]
 					{
+#endif
 						BASISU_NOTE_UNUSED(num_blocks_y);
 						
 						for (uint32_t block_index = first_index; block_index < last_index; block_index++)
@@ -228,11 +231,16 @@
 							}
 
 						}
+
+#ifndef __EMSCRIPTEN__
 					});
+#endif
 
 			} // block_index_iter
 
+#ifndef __EMSCRIPTEN__
 			m_params.m_pJob_pool->wait_for_all();
+#endif
 
 			if (m_params.m_rdo_uastc)
 			{
@@ -412,17 +420,16 @@
 				m_params.m_swizzle[2] != 2 ||
 				m_params.m_swizzle[3] != 3)
 			{
-				// Apply swizzle to incoming data
+				// Used for XY normal maps in RG - puts X in color, Y in alpha
 				for (uint32_t y = 0; y < file_image.get_height(); y++)
 					for (uint32_t x = 0; x < file_image.get_width(); x++)
 					{
 						const color_rgba &c = file_image(x, y);
 						file_image(x, y).set_noclamp_rgba(c[m_params.m_swizzle[0]], c[m_params.m_swizzle[1]], c[m_params.m_swizzle[2]], c[m_params.m_swizzle[3]]);
 					}
-
 				alpha_swizzled = m_params.m_swizzle[3] != 3;
 			}
-
+						
 			bool has_alpha = false;
 			if (m_params.m_force_alpha || alpha_swizzled)
 				has_alpha = true;
@@ -636,14 +643,20 @@
 			}
 		}
 
-		printf("Total basis file slices: %u\n", (uint32_t)m_slice_descs.size());
+		if (m_params.m_status_output)
+		{
+			printf("Total basis file slices: %u\n", (uint32_t)m_slice_descs.size());
+		}
 
 		for (uint32_t i = 0; i < m_slice_descs.size(); i++)
 		{
 			const basisu_backend_slice_desc &slice_desc = m_slice_descs[i];
 
-			printf("Slice: %u, alpha: %u, orig width/height: %ux%u, width/height: %ux%u, first_block: %u, image_index: %u, mip_level: %u, iframe: %u\n", 
-				i, slice_desc.m_alpha, slice_desc.m_orig_width, slice_desc.m_orig_height, slice_desc.m_width, slice_desc.m_height, slice_desc.m_first_block_index, slice_desc.m_source_file_index, slice_desc.m_mip_index, slice_desc.m_iframe);
+			if (m_params.m_status_output)
+			{
+				printf("Slice: %u, alpha: %u, orig width/height: %ux%u, width/height: %ux%u, first_block: %u, image_index: %u, mip_level: %u, iframe: %u\n",
+					i, slice_desc.m_alpha, slice_desc.m_orig_width, slice_desc.m_orig_height, slice_desc.m_width, slice_desc.m_height, slice_desc.m_first_block_index, slice_desc.m_source_file_index, slice_desc.m_mip_index, slice_desc.m_iframe);
+			}
 
 			if (m_any_source_image_has_alpha)
 			{
@@ -1222,7 +1235,6 @@
 		const uint8_vec& comp_data = m_basis_file.get_compressed_data();
 		if (m_params.m_write_output_basis_files)
 		{
-
 			const std::string& basis_filename = m_params.m_out_filename;
 
 			if (!write_vec_to_file(basis_filename.c_str(), comp_data))
@@ -1233,6 +1245,7 @@
 
 			printf("Wrote output .basis file \"%s\"\n", basis_filename.c_str());
 		}
+
 		size_t comp_size = 0;
 		if ((m_params.m_compute_stats) && (m_params.m_uastc) && (comp_data.size()))
 		{
diff --git a/basisu_comp.h b/encoder/basisu_comp.h
similarity index 94%
rename from basisu_comp.h
rename to encoder/basisu_comp.h
index aa77bef..7722e3f 100644
--- a/basisu_comp.h
+++ b/encoder/basisu_comp.h
@@ -16,8 +16,8 @@
 #include "basisu_frontend.h"
 #include "basisu_backend.h"
 #include "basisu_basis_file.h"
-#include "transcoder/basisu_global_selector_palette.h"
-#include "transcoder/basisu_transcoder.h"
+#include "../transcoder/basisu_global_selector_palette.h"
+#include "../transcoder/basisu_transcoder.h"
 #include "basisu_uastc_enc.h"
 
 namespace basisu
@@ -41,6 +41,10 @@
 
 	const uint32_t BASISU_MAX_SLICES = 0xFFFFFF;
 
+	const int BASISU_RDO_UASTC_DICT_SIZE_DEFAULT = 32768;
+	const int BASISU_RDO_UASTC_DICT_SIZE_MIN = 256;
+	const int BASISU_RDO_UASTC_DICT_SIZE_MAX = 65536;
+
 	struct image_stats
 	{
 		image_stats()
@@ -181,7 +185,7 @@
 		T m_max;
 		bool m_changed;
 	};
-
+		
 	struct basis_compressor_params
 	{
 		basis_compressor_params() :
@@ -199,7 +203,7 @@
 			m_quality_level(-1),
 			m_pack_uastc_flags(cPackUASTCLevelDefault),
 			m_rdo_uastc_quality_scalar(1.0f, 0.001f, 10.0f),
-			m_rdo_uastc_dict_size(32768, 256, 65536),
+			m_rdo_uastc_dict_size(BASISU_RDO_UASTC_DICT_SIZE_DEFAULT, BASISU_RDO_UASTC_DICT_SIZE_MIN, BASISU_RDO_UASTC_DICT_SIZE_MAX),
 			m_rdo_uastc_max_allowed_rms_increase_ratio(UASTC_RDO_DEFAULT_MAX_ALLOWED_RMS_INCREASE_RATIO, .01f, 100.0f),
 			m_rdo_uastc_skip_block_rms_thresh(UASTC_RDO_DEFAULT_SKIP_BLOCK_RMS_THRESH, .01f, 100.0f),
 			m_pJob_pool(nullptr)
@@ -212,6 +216,7 @@
 			m_pSel_codebook = NULL;
 
 			m_uastc.clear();
+			m_status_output.clear();
 
 			m_source_filenames.clear();
 			m_source_alpha_filenames.clear();
@@ -298,6 +303,9 @@
 
 		// Flip images across Y axis
 		bool_param<false> m_y_flip;
+
+		// If true, the compressor will print basis status to stdout during compression.
+		bool_param<true> m_status_output;
 		
 		// Output debug information during compression
 		bool_param<false> m_debug;
@@ -339,8 +347,8 @@
 		// Always put alpha slices in the output basis file, even when the input doesn't have alpha
 		bool_param<false> m_force_alpha; 
 		bool_param<true> m_multithreading;
-
-		// Swizzle incoming channels
+		
+		// Split the R channel to RGB and the G channel to alpha, then write a basis file with alpha channels
 		char m_swizzle[4];
 
 		bool_param<false> m_renormalize;
@@ -363,7 +371,7 @@
 		param<int> m_mip_smallest_dimension;
 				
 		// Codebook size (quality) control. 
-		// If m_quality_level != -1, it controls the quality level. It ranges from [0,255].
+		// If m_quality_level != -1, it controls the quality level. It ranges from [0,255] or [BASISU_QUALITY_MIN, BASISU_QUALITY_MAX].
 		// Otherwise m_max_endpoint_clusters/m_max_selector_clusters controls the codebook sizes directly.
 		uint32_t m_max_endpoint_clusters;
 		uint32_t m_max_selector_clusters;
diff --git a/basisu_enc.cpp b/encoder/basisu_enc.cpp
similarity index 98%
rename from basisu_enc.cpp
rename to encoder/basisu_enc.cpp
index 0c5f883..87b69dc 100644
--- a/basisu_enc.cpp
+++ b/encoder/basisu_enc.cpp
@@ -17,7 +17,7 @@
 #include "basisu_resampler.h"
 #include "basisu_resampler_filters.h"
 #include "basisu_etc.h"
-#include "transcoder/basisu_transcoder.h"
+#include "../transcoder/basisu_transcoder.h"
 #include "basisu_bc7enc.h"
 #include "apg_bmp.h"
 #include "jpgd.h"
@@ -282,38 +282,36 @@
 
 		return true;
 	}
-		
-	bool load_png(const char* pFilename, image& img)
+
+	bool load_png(const uint8_t *pBuf, size_t buf_size, image &img, const char *pFilename)
 	{
-		std::vector<uint8_t> buffer;
-		unsigned err = lodepng::load_file(buffer, std::string(pFilename));
-		if (err)
+		if (!buf_size)
 			return false;
 
-		unsigned w = 0, h = 0;
-				
-		if (sizeof(void *) == sizeof(uint32_t))
+		unsigned err = 0, w = 0, h = 0;
+
+		if (sizeof(void*) == sizeof(uint32_t))
 		{
 			// Inspect the image first on 32-bit builds, to see if the image would require too much memory.
 			lodepng::State state;
-			err = lodepng_inspect(&w, &h, &state, &buffer[0], buffer.size());
+			err = lodepng_inspect(&w, &h, &state, pBuf, buf_size);
 			if ((err != 0) || (!w) || (!h))
 				return false;
 
 			const uint32_t exepected_alloc_size = w * h * sizeof(uint32_t);
-	
+
 			// If the file is too large on 32-bit builds then just bail now, to prevent causing a memory exception.
 			if (exepected_alloc_size >= MAX_32BIT_ALLOC_SIZE)
 			{
-				error_printf("Image \"%s\" is too large (%ux%u) to process in a 32-bit build!\n", pFilename, w, h);
+				error_printf("Image \"%s\" is too large (%ux%u) to process in a 32-bit build!\n", (pFilename != nullptr) ? pFilename : "<memory>", w, h);
 				return false;
 			}
-			
+
 			w = h = 0;
 		}
-				
+
 		std::vector<uint8_t> out;
-		err = lodepng::decode(out, w, h, &buffer[0], buffer.size());
+		err = lodepng::decode(out, w, h, pBuf, buf_size);
 		if ((err != 0) || (!w) || (!h))
 			return false;
 
@@ -326,6 +324,17 @@
 
 		return true;
 	}
+		
+	bool load_png(const char* pFilename, image& img)
+	{
+		std::vector<uint8_t> buffer;
+		unsigned err = lodepng::load_file(buffer, std::string(pFilename));
+		if (err)
+			return false;
+
+
+		return load_png(buffer.data(), buffer.size(), img, pFilename);
+	}
 
 	bool load_jpg(const char *pFilename, image& img)
 	{
@@ -391,7 +400,7 @@
 			if ((!has_alpha) || ((image_save_flags & cImageSaveIgnoreAlpha) != 0))
 			{
 				const uint64_t total_bytes = (uint64_t)img.get_width() * 3U * (uint64_t)img.get_height();
-				uint8_vec rgb_pixels(total_bytes);
+				uint8_vec rgb_pixels(static_cast<size_t>(total_bytes));
 				uint8_t *pDst = &rgb_pixels[0];
 								
 				for (uint32_t y = 0; y < img.get_height(); y++)
@@ -1464,13 +1473,15 @@
 		std::unique_lock<std::mutex> lock(m_mutex);
 
 		m_queue.emplace_back(std::move(job));
-
+						
 		const size_t queue_size = m_queue.size();
 
 		lock.unlock();
 
 		if (queue_size > 1)
+		{
 			m_has_work.notify_one();
+		}
 	}
 
 	void job_pool::wait_for_all()
diff --git a/basisu_enc.h b/encoder/basisu_enc.h
similarity index 99%
rename from basisu_enc.h
rename to encoder/basisu_enc.h
index 80a8074..58719ad 100644
--- a/basisu_enc.h
+++ b/encoder/basisu_enc.h
@@ -13,8 +13,8 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 #pragma once
-#include "transcoder/basisu.h"
-#include "transcoder/basisu_transcoder_internal.h"
+#include "../transcoder/basisu.h"
+#include "../transcoder/basisu_transcoder_internal.h"
 
 #include <mutex>
 #include <atomic>
@@ -1690,7 +1690,9 @@
 
 		for (uint32_t thread_iter = 0; thread_iter < max_threads; thread_iter++)
 		{
+#ifndef __EMSCRIPTEN__
 			pJob_pool->add_job( [thread_iter, &local_clusters, &local_parent_clusters, &success_flags, &quantizers, &initial_codebook, &q, &limit_clusterizers, &max_codebook_size, &max_threads, &max_parent_codebook_size] {
+#endif
 
 				Quantizer& lq = quantizers[thread_iter];
 				uint_vec& cluster_indices = initial_codebook[thread_iter];
@@ -1731,11 +1733,15 @@
 					}
 				}
 
+#ifndef __EMSCRIPTEN__
 			} );
+#endif
 
 		} // thread_iter
 
+#ifndef __EMSCRIPTEN__
 		pJob_pool->wait_for_all();
+#endif
 
 		uint32_t total_clusters = 0, total_parent_clusters = 0;
 
@@ -2856,7 +2862,8 @@
 	};
 
 	// Image saving/loading/resampling
-		
+	
+	bool load_png(const uint8_t* pBuf, size_t buf_size, image& img, const char* pFilename = nullptr);
 	bool load_png(const char* pFilename, image& img);
 	inline bool load_png(const std::string &filename, image &img) { return load_png(filename.c_str(), img); }
 
diff --git a/basisu_etc.cpp b/encoder/basisu_etc.cpp
similarity index 100%
rename from basisu_etc.cpp
rename to encoder/basisu_etc.cpp
diff --git a/basisu_etc.h b/encoder/basisu_etc.h
similarity index 99%
rename from basisu_etc.h
rename to encoder/basisu_etc.h
index d8b0468..0c8a7be 100644
--- a/basisu_etc.h
+++ b/encoder/basisu_etc.h
@@ -13,7 +13,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 #pragma once
-#include "transcoder/basisu.h"
+#include "../transcoder/basisu.h"
 #include "basisu_enc.h"
 #include <set>
 
diff --git a/basisu_frontend.cpp b/encoder/basisu_frontend.cpp
similarity index 98%
rename from basisu_frontend.cpp
rename to encoder/basisu_frontend.cpp
index b09aa61..35ad68f 100644
--- a/basisu_frontend.cpp
+++ b/encoder/basisu_frontend.cpp
@@ -17,7 +17,7 @@
 // This code originally supported full ETC1 and ETC1S, so there's some legacy stuff to be cleaned up in here.
 // Add endpoint tiling support (where we force adjacent blocks to use the same endpoints during quantization), for a ~10% or more increase in bitrate at same SSIM. The backend already supports this.
 //
-#include "transcoder/basisu.h"
+#include "../transcoder/basisu.h"
 #include "basisu_frontend.h"
 #include <unordered_set>
 #include <unordered_map>
@@ -78,6 +78,7 @@
 		{
 			if (!p.m_pGlobal_sel_codebook)
 			{
+				debug_printf("basisu_frontend::init: No global sel codebook!\n");
 				assert(0);
 				return false;
 			}
@@ -481,8 +482,10 @@
 		{
 			const uint32_t first_index = block_index_iter;                                        
 			const uint32_t last_index = minimum<uint32_t>(m_total_blocks, first_index + N);       
-                                                                                      
+
+#ifndef __EMSCRIPTEN__
 			m_params.m_pJob_pool->add_job( [this, first_index, last_index] {
+#endif
 
 				for (uint32_t block_index = first_index; block_index < last_index; block_index++) 
 				{
@@ -507,7 +510,7 @@
 
 					optimizer.init(optimizer_params, optimizer_results);
 					optimizer.compute();
-			
+
 					etc_block &blk = m_etc1_blocks_etc1s[block_index];
 
 					memset(&blk, 0, sizeof(blk));
@@ -520,10 +523,15 @@
 							blk.set_selector(x, y, selectors[x + y * 4]);
 				}
 
+#ifndef __EMSCRIPTEN__
 			} );
+#endif
+
 		}
-		                                     
+
+#ifndef __EMSCRIPTEN__
 		m_params.m_pJob_pool->wait_for_all();
+#endif
 	}
 
 	void basisu_frontend::init_endpoint_training_vectors()
@@ -540,7 +548,9 @@
 			const uint32_t first_index = block_index_iter;
 			const uint32_t last_index = minimum<uint32_t>(m_total_blocks, first_index + N);
 
+#ifndef __EMSCRIPTEN__
 			m_params.m_pJob_pool->add_job( [this, first_index, last_index, &training_vecs] {
+#endif
 
 				for (uint32_t block_index = first_index; block_index < last_index; block_index++)
 				{			
@@ -562,11 +572,15 @@
 
 				} // block_index;
 
+#ifndef __EMSCRIPTEN__
 			} );
+#endif
 
 		} // block_index_iter
 
+#ifndef __EMSCRIPTEN__
 		m_params.m_pJob_pool->wait_for_all();
+#endif
 	}
 
 	void basisu_frontend::generate_endpoint_clusters()
@@ -707,7 +721,9 @@
 			const uint32_t first_index = cluster_index_iter;                                    
 			const uint32_t last_index = minimum<uint32_t>((uint32_t)m_endpoint_clusters.size(), cluster_index_iter + N);   
 
+#ifndef __EMSCRIPTEN__
 			m_params.m_pJob_pool->add_job( [this, first_index, last_index] {
+#endif
 
 				for (uint32_t cluster_index = first_index; cluster_index < last_index; cluster_index++)
 				{
@@ -775,10 +791,15 @@
 					}
 				} // cluster_index
 
+#ifndef __EMSCRIPTEN__
 			} );
+#endif
+
 		} // cluster_index_iter
 
+#ifndef __EMSCRIPTEN__
 		m_params.m_pJob_pool->wait_for_all();
+#endif
 
 		vector_sort(m_subblock_endpoint_quant_err_vec);
 	}
@@ -893,8 +914,10 @@
 		{
 			const uint32_t first_index = cluster_index_iter;                                    
 			const uint32_t last_index = minimum<uint32_t>((uint32_t)m_endpoint_clusters.size(), cluster_index_iter + N);   
-			
+
+#ifndef __EMSCRIPTEN__
 			m_params.m_pJob_pool->add_job( [this, first_index, last_index, step ] {
+#endif
 
 				for (uint32_t cluster_index = first_index; cluster_index < last_index; cluster_index++)
 				{
@@ -1012,11 +1035,15 @@
 				
 				} // cluster_index
 
+#ifndef __EMSCRIPTEN__
 			} );
+#endif
 
 		} // cluster_index_iter
 
+#ifndef __EMSCRIPTEN__
 		m_params.m_pJob_pool->wait_for_all();
+#endif
 	}
 
 	bool basisu_frontend::check_etc1s_constraints() const
@@ -1081,7 +1108,9 @@
 			const uint32_t first_index = block_index_iter;
 			const uint32_t last_index = minimum<uint32_t>(m_total_blocks, first_index + N);
 
+#ifndef __EMSCRIPTEN__
 			m_params.m_pJob_pool->add_job( [this, first_index, last_index, &best_cluster_indices, &block_clusters] {
+#endif
 
 				for (uint32_t block_index = first_index; block_index < last_index; block_index++)
 				{
@@ -1154,12 +1183,16 @@
 					best_cluster_indices[block_index] = best_cluster_index;
 
 				} // block_index
-			
+
+#ifndef __EMSCRIPTEN__
 			} );
+#endif
 						
 		} // block_index_iter
-		
+
+#ifndef __EMSCRIPTEN__
 		m_params.m_pJob_pool->wait_for_all();
+#endif
 
 		std::vector<typename std::vector<uint32_t> > optimized_endpoint_clusters(m_endpoint_clusters.size());
 		uint32_t total_subblocks_reassigned = 0;
@@ -1264,7 +1297,9 @@
 			const uint32_t first_index = block_index_iter;
 			const uint32_t last_index = minimum<uint32_t>(m_total_blocks, first_index + N);
 
+#ifndef __EMSCRIPTEN__
 			m_params.m_pJob_pool->add_job( [this, first_index, last_index] {
+#endif
 				
 				for (uint32_t block_index = first_index; block_index < last_index; block_index++)
 				{
@@ -1288,12 +1323,16 @@
 					blk.determine_selectors(pSource_pixels, m_params.m_perceptual);
 						
 				} // block_index
-			
+
+#ifndef __EMSCRIPTEN__
 			} );
+#endif
 
 		} // block_index_iter
 
+#ifndef __EMSCRIPTEN__
 		m_params.m_pJob_pool->wait_for_all();
+#endif
 
 		m_orig_encoded_blocks = m_encoded_blocks;
 	}
@@ -1355,7 +1394,9 @@
 			const uint32_t first_index = block_index_iter;
 			const uint32_t last_index = minimum<uint32_t>(m_total_blocks, first_index + N);
 
+#ifndef __EMSCRIPTEN__
 			m_params.m_pJob_pool->add_job( [this, first_index, last_index, &training_vecs] {
+#endif
 
 				for (uint32_t block_index = first_index; block_index < last_index; block_index++)
 				{
@@ -1382,11 +1423,15 @@
 				
 				} // block_index
 
+#ifndef __EMSCRIPTEN__
 			} );
+#endif
 
 		} // block_index_iter
 
+#ifndef __EMSCRIPTEN__
 		m_params.m_pJob_pool->wait_for_all();
+#endif
 
 		vec16F_clusterizer selector_clusterizer;
 		for (uint32_t i = 0; i < m_total_blocks; i++)
@@ -1474,8 +1519,10 @@
 			{
 				const uint32_t first_index = cluster_index_iter;                                    
 				const uint32_t last_index = minimum<uint32_t>((uint32_t)total_selector_clusters, cluster_index_iter + N);   
-			
+
+#ifndef __EMSCRIPTEN__
 				m_params.m_pJob_pool->add_job( [this, first_index, last_index, &total_clusters_processed, &total_selector_clusters] {
+#endif
 					
 					for (uint32_t cluster_index = first_index; cluster_index < last_index; cluster_index++)
 					{
@@ -1528,11 +1575,15 @@
 
 					} // cluster_index
 
+#ifndef __EMSCRIPTEN__
 				} );
+#endif
 
 			} // cluster_index_iter
 
+#ifndef __EMSCRIPTEN__
 			m_params.m_pJob_pool->wait_for_all();
+#endif
 		}
 		else
 		{
@@ -1552,8 +1603,10 @@
 			{
 				const uint32_t first_index = cluster_index_iter;                                    
 				const uint32_t last_index = minimum<uint32_t>((uint32_t)total_selector_clusters, cluster_index_iter + N);   
-			
+
+#ifndef __EMSCRIPTEN__			
 				m_params.m_pJob_pool->add_job( [this, first_index, last_index, &uses_hybrid_sel_codebook, &total_clusters_processed, &total_selector_clusters] {
+#endif
 					
 					for (uint32_t cluster_index = first_index; cluster_index < last_index; cluster_index++)
 					{
@@ -1667,11 +1720,15 @@
 
 					} // cluster_index
 
+#ifndef __EMSCRIPTEN__
 				} );
+#endif
 
 			} // cluster_index_iter
 
+#ifndef __EMSCRIPTEN__
 			m_params.m_pJob_pool->wait_for_all();
+#endif
 
 		} // if (m_params.m_pGlobal_sel_codebook)
 
@@ -1741,7 +1798,9 @@
 				const uint32_t first_index = block_index_iter;
 				const uint32_t last_index = minimum<uint32_t>(m_total_blocks, first_index + N);
 
+#ifndef __EMSCRIPTEN__
 				m_params.m_pJob_pool->add_job( [this, first_index, last_index, &new_cluster_indices] {
+#endif
 
 				for (uint32_t block_index = first_index; block_index < last_index; block_index++)
 				{
@@ -1804,11 +1863,15 @@
 					
 				} // block_index
 
+#ifndef __EMSCRIPTEN__
 				} );
+#endif
 
 			} // block_index_iter
-						
+
+#ifndef __EMSCRIPTEN__
 			m_params.m_pJob_pool->wait_for_all();
+#endif
 			
 			m_selector_cluster_indices.swap(new_cluster_indices);
 		}
@@ -2112,8 +2175,11 @@
 		{
 			const uint32_t first_index = cluster_index_iter;                                    
 			const uint32_t last_index = minimum<uint32_t>((uint32_t)new_endpoint_cluster_block_indices.size(), cluster_index_iter + N);   
-			
+
+#ifndef __EMSCRIPTEN__
 			m_params.m_pJob_pool->add_job( [this, first_index, last_index, &cluster_improved, &cluster_valid, &new_endpoint_cluster_block_indices, &pBlock_selector_indices ] {
+#endif
+
 				for (uint32_t cluster_index = first_index; cluster_index < last_index; cluster_index++)
 				{
 					const std::vector<uint32_t>& cluster_block_indices = new_endpoint_cluster_block_indices[cluster_index];
@@ -2198,11 +2264,16 @@
 					cluster_valid[cluster_index] = true;
 
 				} // cluster_index
+
+#ifndef __EMSCRIPTEN__
 			} );
+#endif
 
 		} // cluster_index_iter
 
+#ifndef __EMSCRIPTEN__
 		m_params.m_pJob_pool->wait_for_all();
+#endif
 				
 		uint32_t total_unused_clusters = 0;
 		uint32_t total_improved_clusters = 0;
diff --git a/basisu_frontend.h b/encoder/basisu_frontend.h
similarity index 99%
rename from basisu_frontend.h
rename to encoder/basisu_frontend.h
index e4ccf14..e5f7954 100644
--- a/basisu_frontend.h
+++ b/encoder/basisu_frontend.h
@@ -17,7 +17,7 @@
 #include "basisu_etc.h"
 #include "basisu_gpu_texture.h"
 #include "basisu_global_selector_palette_helpers.h"
-#include "transcoder/basisu_file_headers.h"
+#include "../transcoder/basisu_file_headers.h"
 
 namespace basisu
 {
diff --git a/basisu_global_selector_palette_helpers.cpp b/encoder/basisu_global_selector_palette_helpers.cpp
similarity index 100%
rename from basisu_global_selector_palette_helpers.cpp
rename to encoder/basisu_global_selector_palette_helpers.cpp
diff --git a/basisu_global_selector_palette_helpers.h b/encoder/basisu_global_selector_palette_helpers.h
similarity index 94%
rename from basisu_global_selector_palette_helpers.h
rename to encoder/basisu_global_selector_palette_helpers.h
index 32692c5..9e9cdbd 100644
--- a/basisu_global_selector_palette_helpers.h
+++ b/encoder/basisu_global_selector_palette_helpers.h
@@ -14,9 +14,9 @@
 // limitations under the License.
 #pragma once
 
-#include "transcoder/basisu.h"
+#include "../transcoder/basisu.h"
 #include "basisu_etc.h"
-#include "transcoder/basisu_global_selector_palette.h"
+#include "../transcoder/basisu_global_selector_palette.h"
 
 namespace basisu
 {
diff --git a/basisu_gpu_texture.cpp b/encoder/basisu_gpu_texture.cpp
similarity index 100%
rename from basisu_gpu_texture.cpp
rename to encoder/basisu_gpu_texture.cpp
diff --git a/basisu_gpu_texture.h b/encoder/basisu_gpu_texture.h
similarity index 98%
rename from basisu_gpu_texture.h
rename to encoder/basisu_gpu_texture.h
index 7cf2b41..7ca9272 100644
--- a/basisu_gpu_texture.h
+++ b/encoder/basisu_gpu_texture.h
@@ -13,7 +13,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 #pragma once
-#include "transcoder/basisu.h"
+#include "../transcoder/basisu.h"
 #include "basisu_etc.h"
 
 namespace basisu
diff --git a/basisu_miniz.h b/encoder/basisu_miniz.h
similarity index 100%
rename from basisu_miniz.h
rename to encoder/basisu_miniz.h
diff --git a/basisu_pvrtc1_4.cpp b/encoder/basisu_pvrtc1_4.cpp
similarity index 100%
rename from basisu_pvrtc1_4.cpp
rename to encoder/basisu_pvrtc1_4.cpp
diff --git a/basisu_pvrtc1_4.h b/encoder/basisu_pvrtc1_4.h
similarity index 100%
rename from basisu_pvrtc1_4.h
rename to encoder/basisu_pvrtc1_4.h
diff --git a/basisu_resample_filters.cpp b/encoder/basisu_resample_filters.cpp
similarity index 88%
rename from basisu_resample_filters.cpp
rename to encoder/basisu_resample_filters.cpp
index 39df8bd..c0adb13 100644
--- a/basisu_resample_filters.cpp
+++ b/encoder/basisu_resample_filters.cpp
@@ -310,10 +310,22 @@
 
 	const resample_filter g_resample_filters[] =
 	{
-		 { "box", box_filter, BOX_FILTER_SUPPORT }, { "tent", tent_filter, TENT_FILTER_SUPPORT }, { "bell", bell_filter, BELL_SUPPORT }, { "b-spline", B_spline_filter, B_SPLINE_SUPPORT },
-		 { "mitchell", mitchell_filter, MITCHELL_SUPPORT }, { "lanczos3", lanczos3_filter, LANCZOS3_SUPPORT }, { "blackman", blackman_filter, BLACKMAN_SUPPORT }, { "lanczos4", lanczos4_filter, LANCZOS4_SUPPORT },
-		 { "lanczos6", lanczos6_filter, LANCZOS6_SUPPORT }, { "lanczos12", lanczos12_filter, LANCZOS12_SUPPORT }, { "kaiser", kaiser_filter, KAISER_SUPPORT }, { "gaussian", gaussian_filter, GAUSSIAN_SUPPORT },
-		 { "catmullrom", catmull_rom_filter, CATMULL_ROM_SUPPORT }, { "quadratic_interp", quadratic_interp_filter, QUADRATIC_SUPPORT }, { "quadratic_approx", quadratic_approx_filter, QUADRATIC_SUPPORT }, { "quadratic_mix", quadratic_mix_filter, QUADRATIC_SUPPORT },
+		{ "box", box_filter, BOX_FILTER_SUPPORT }, 
+		{ "tent", tent_filter, TENT_FILTER_SUPPORT }, 
+		{ "bell", bell_filter, BELL_SUPPORT }, 
+		{ "b-spline", B_spline_filter, B_SPLINE_SUPPORT },
+		{ "mitchell", mitchell_filter, MITCHELL_SUPPORT }, 
+		{ "blackman", blackman_filter, BLACKMAN_SUPPORT }, 
+		{ "lanczos3", lanczos3_filter, LANCZOS3_SUPPORT },
+		{ "lanczos4", lanczos4_filter, LANCZOS4_SUPPORT },
+		{ "lanczos6", lanczos6_filter, LANCZOS6_SUPPORT }, 
+		{ "lanczos12", lanczos12_filter, LANCZOS12_SUPPORT }, 
+		{ "kaiser", kaiser_filter, KAISER_SUPPORT }, 
+		{ "gaussian", gaussian_filter, GAUSSIAN_SUPPORT },
+		{ "catmullrom", catmull_rom_filter, CATMULL_ROM_SUPPORT }, 
+		{ "quadratic_interp", quadratic_interp_filter, QUADRATIC_SUPPORT }, 
+		{ "quadratic_approx", quadratic_approx_filter, QUADRATIC_SUPPORT }, 
+		{ "quadratic_mix", quadratic_mix_filter, QUADRATIC_SUPPORT },
 	};
 
 	const int g_num_resample_filters = BASISU_ARRAY_SIZE(g_resample_filters);
diff --git a/basisu_resampler.cpp b/encoder/basisu_resampler.cpp
similarity index 100%
rename from basisu_resampler.cpp
rename to encoder/basisu_resampler.cpp
diff --git a/basisu_resampler.h b/encoder/basisu_resampler.h
similarity index 98%
rename from basisu_resampler.h
rename to encoder/basisu_resampler.h
index c3f2e05..dc0978c 100644
--- a/basisu_resampler.h
+++ b/encoder/basisu_resampler.h
@@ -13,7 +13,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 #pragma once
-#include "transcoder/basisu.h"
+#include "../transcoder/basisu.h"
 
 #define BASISU_RESAMPLER_DEBUG_OPS (0)
 #define BASISU_RESAMPLER_DEFAULT_FILTER "lanczos4"
diff --git a/basisu_resampler_filters.h b/encoder/basisu_resampler_filters.h
similarity index 96%
rename from basisu_resampler_filters.h
rename to encoder/basisu_resampler_filters.h
index 5659c5f..0ebb51c 100644
--- a/basisu_resampler_filters.h
+++ b/encoder/basisu_resampler_filters.h
@@ -14,7 +14,7 @@
 // limitations under the License.
 #pragma once
 
-#include "transcoder/basisu.h"
+#include "../transcoder/basisu.h"
 
 namespace basisu
 {
diff --git a/basisu_ssim.cpp b/encoder/basisu_ssim.cpp
similarity index 100%
rename from basisu_ssim.cpp
rename to encoder/basisu_ssim.cpp
diff --git a/basisu_ssim.h b/encoder/basisu_ssim.h
similarity index 100%
rename from basisu_ssim.h
rename to encoder/basisu_ssim.h
diff --git a/basisu_uastc_enc.cpp b/encoder/basisu_uastc_enc.cpp
similarity index 99%
rename from basisu_uastc_enc.cpp
rename to encoder/basisu_uastc_enc.cpp
index c4fb9eb..9b75b84 100644
--- a/basisu_uastc_enc.cpp
+++ b/encoder/basisu_uastc_enc.cpp
@@ -3098,6 +3098,11 @@
 
 	void encode_uastc(const uint8_t* pRGBAPixels, uastc_block& output_block, uint32_t flags)
 	{
+//		printf("encode_uastc: \n");
+//		for (int i = 0; i < 16; i++)
+//			printf("[%u %u %u %u] ", pRGBAPixels[i * 4 + 0], pRGBAPixels[i * 4 + 1], pRGBAPixels[i * 4 + 2], pRGBAPixels[i * 4 + 3]);
+//		printf("\n");
+
 		const color_rgba(*block)[4] = reinterpret_cast<const color_rgba(*)[4]>(pRGBAPixels);
 
 		bool solid_color = true, has_alpha = false, is_la = true;
@@ -3139,6 +3144,8 @@
 
 			pack_uastc(output_block, solid_results, etc1_blk, etc1_bias, eac_a8_blk, false, false);
 
+//			printf(" Solid\n");
+
 			return;
 		}
 		
@@ -3594,7 +3601,13 @@
 
 		// Finally, pack the UASTC block with its hints and we're done.
 		pack_uastc(output_block, best_results, etc1_blk, etc1_bias, eac_a8_blk, bc1_hint0, bc1_hint1);
+
+//		printf(" Packed: ");
+//		for (int i = 0; i < 16; i++)
+//			printf("%X ", output_block.m_bytes[i]);
+//		printf("\n");
 	}
+
 	static bool uastc_recompute_hints(basist::uastc_block* pBlock, const color_rgba* pBlock_pixels, uint32_t flags, const unpacked_uastc_block *pUnpacked_blk)
 	{
 		unpacked_uastc_block unpacked_blk;
@@ -3761,7 +3774,7 @@
 	{
 		std::size_t operator()(selector_bitsequence const& s) const noexcept
 		{
-			return hash_hsieh((uint8_t *)&s, sizeof(s)) ^ s.m_sel;
+			return static_cast<std::size_t>(hash_hsieh((uint8_t *)&s, sizeof(s)) ^ s.m_sel);
 		}
 	};
 		
@@ -4053,7 +4066,9 @@
 				const uint32_t first_index = block_index_iter;
 				const uint32_t last_index = minimum<uint32_t>(num_blocks, block_index_iter + blocks_per_job);
 
+#ifndef __EMSCRIPTEN__
 				pJob_pool->add_job([first_index, last_index, pBlocks, pBlock_pixels, &params, flags, &total_skipped, &total_modified, &total_refined, &all_succeeded, &stat_mutex] {
+#endif
 
 					uint32_t job_skipped = 0, job_modified = 0, job_refined = 0;
 
@@ -4068,11 +4083,16 @@
 						total_refined += job_refined;
 					}
 
+#ifndef __EMSCRIPTEN__
 					}
 				);
+#endif
+
 			} // block_index_iter
 
+#ifndef __EMSCRIPTEN__
 			pJob_pool->wait_for_all();
+#endif
 
 			status = all_succeeded;
 		}
diff --git a/basisu_uastc_enc.h b/encoder/basisu_uastc_enc.h
similarity index 98%
rename from basisu_uastc_enc.h
rename to encoder/basisu_uastc_enc.h
index 0ccad7d..eeb2525 100644
--- a/basisu_uastc_enc.h
+++ b/encoder/basisu_uastc_enc.h
@@ -15,7 +15,7 @@
 #pragma once
 #include "basisu_etc.h"
 
-#include "transcoder/basisu_transcoder_uastc.h"
+#include "../transcoder/basisu_transcoder_uastc.h"
 
 namespace basisu
 {
diff --git a/jpgd.cpp b/encoder/jpgd.cpp
similarity index 100%
rename from jpgd.cpp
rename to encoder/jpgd.cpp
diff --git a/jpgd.h b/encoder/jpgd.h
similarity index 100%
rename from jpgd.h
rename to encoder/jpgd.h
diff --git a/lodepng.cpp b/encoder/lodepng.cpp
similarity index 100%
rename from lodepng.cpp
rename to encoder/lodepng.cpp
diff --git a/lodepng.h b/encoder/lodepng.h
similarity index 100%
rename from lodepng.h
rename to encoder/lodepng.h
diff --git a/transcoder/basisu_transcoder.cpp b/transcoder/basisu_transcoder.cpp
index 9366f0a..a77bb82 100644
--- a/transcoder/basisu_transcoder.cpp
+++ b/transcoder/basisu_transcoder.cpp
@@ -9577,7 +9577,7 @@
 		uint32_t num_blocks_x, uint32_t num_blocks_y, uint32_t orig_width, uint32_t orig_height, uint32_t level_index,
 		uint32_t slice_offset, uint32_t slice_length,
 		uint32_t decode_flags,
-		bool basis_file_has_alpha_slices,
+		bool has_alpha,
 		bool is_video,
 		uint32_t output_row_pitch_in_blocks_or_pixels,
 		basisu_transcoder_state* pState,
@@ -9603,7 +9603,7 @@
 			}
 		}
 
-		if ((target_format == transcoder_texture_format::cTFPVRTC1_4_RGBA) && (!basis_file_has_alpha_slices))
+		if ((target_format == transcoder_texture_format::cTFPVRTC1_4_RGBA) && (!has_alpha))
 		{
 			// Switch to PVRTC1 RGB if the input doesn't have alpha.
 			target_format = transcoder_texture_format::cTFPVRTC1_4_RGB;
@@ -9628,7 +9628,7 @@
 		{
 			//status = transcode_slice(pData, data_size, slice_index, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cETC1, bytes_per_block_or_pixel, decode_flags, output_row_pitch_in_blocks_or_pixels, pState);
 			status = transcode_slice(pOutput_blocks, num_blocks_x, num_blocks_y, pCompressed_data + slice_offset, slice_length, block_format::cETC1,
-				bytes_per_block_or_pixel, false, basis_file_has_alpha_slices, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, pState, output_rows_in_pixels, channel0, channel1);
+				bytes_per_block_or_pixel, false, has_alpha, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, pState, output_rows_in_pixels, channel0, channel1);
 				
 			if (!status)
 			{
@@ -9640,7 +9640,7 @@
 		{
 			//status = transcode_slice(pData, data_size, slice_index, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cETC2_RGBA, bytes_per_block_or_pixel, decode_flags, output_row_pitch_in_blocks_or_pixels, pState);
 			status = transcode_slice(pOutput_blocks, num_blocks_x, num_blocks_y, pCompressed_data + slice_offset, slice_length, block_format::cETC2_RGBA,
-				bytes_per_block_or_pixel, false, basis_file_has_alpha_slices, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, pState, output_rows_in_pixels, channel0, channel1);
+				bytes_per_block_or_pixel, false, has_alpha, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, pState, output_rows_in_pixels, channel0, channel1);
 			if (!status)
 			{
 				BASISU_DEVEL_ERROR("basisu_lowlevel_uastc_transcoder::transcode_image: transcode_slice() to ETC2 failed\n");
@@ -9652,7 +9652,7 @@
 			// TODO: ETC1S allows BC1 from alpha channel. That doesn't seem actually useful, though.
 			//status = transcode_slice(pData, data_size, slice_index, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cBC1, bytes_per_block_or_pixel, decode_flags, output_row_pitch_in_blocks_or_pixels, pState);
 			status = transcode_slice(pOutput_blocks, num_blocks_x, num_blocks_y, pCompressed_data + slice_offset, slice_length, block_format::cBC1,
-				bytes_per_block_or_pixel, true, basis_file_has_alpha_slices, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, pState, output_rows_in_pixels, channel0, channel1);
+				bytes_per_block_or_pixel, true, has_alpha, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, pState, output_rows_in_pixels, channel0, channel1);
 			if (!status)
 			{
 				BASISU_DEVEL_ERROR("basisu_lowlevel_uastc_transcoder::transcode_image: transcode_slice() to BC1 failed\n");
@@ -9663,7 +9663,7 @@
 		{
 			//status = transcode_slice(pData, data_size, slice_index, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cBC3, bytes_per_block_or_pixel, decode_flags, output_row_pitch_in_blocks_or_pixels, pState);
 			status = transcode_slice(pOutput_blocks, num_blocks_x, num_blocks_y, pCompressed_data + slice_offset, slice_length, block_format::cBC3,
-				bytes_per_block_or_pixel, false, basis_file_has_alpha_slices, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, pState, output_rows_in_pixels, channel0, channel1);
+				bytes_per_block_or_pixel, false, has_alpha, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, pState, output_rows_in_pixels, channel0, channel1);
 			if (!status)
 			{
 				BASISU_DEVEL_ERROR("basisu_lowlevel_uastc_transcoder::transcode_image: transcode_slice() to BC3 failed\n");
@@ -9674,10 +9674,10 @@
 		{
 			//status = transcode_slice(pData, data_size, slice_index, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cBC4, bytes_per_block_or_pixel, decode_flags, output_row_pitch_in_blocks_or_pixels, pState,
 			//	nullptr, 0,
-			//	((basis_file_has_alpha_slices) && (transcode_alpha_data_to_opaque_formats)) ? 3 : 0);
+			//	((has_alpha) && (transcode_alpha_data_to_opaque_formats)) ? 3 : 0);
 			status = transcode_slice(pOutput_blocks, num_blocks_x, num_blocks_y, pCompressed_data + slice_offset, slice_length, block_format::cBC4,
-				bytes_per_block_or_pixel, false, basis_file_has_alpha_slices, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, pState, output_rows_in_pixels,
-				((basis_file_has_alpha_slices) && (transcode_alpha_data_to_opaque_formats)) ? 3 : 0);
+				bytes_per_block_or_pixel, false, has_alpha, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, pState, output_rows_in_pixels,
+				((has_alpha) && (transcode_alpha_data_to_opaque_formats)) ? 3 : 0);
 			if (!status)
 			{
 				BASISU_DEVEL_ERROR("basisu_lowlevel_uastc_transcoder::transcode_image: transcode_slice() to BC4 failed\n");
@@ -9690,7 +9690,7 @@
 			//	nullptr, 0,
 			//	0, 3);
 			status = transcode_slice(pOutput_blocks, num_blocks_x, num_blocks_y, pCompressed_data + slice_offset, slice_length, block_format::cBC5,
-				bytes_per_block_or_pixel, false, basis_file_has_alpha_slices, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, pState, output_rows_in_pixels,
+				bytes_per_block_or_pixel, false, has_alpha, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, pState, output_rows_in_pixels,
 				0, 3);
 			if (!status)
 			{
@@ -9703,7 +9703,7 @@
 		{
 			//status = transcode_slice(pData, data_size, slice_index, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cBC7, bytes_per_block_or_pixel, decode_flags, output_row_pitch_in_blocks_or_pixels, pState);
 			status = transcode_slice(pOutput_blocks, num_blocks_x, num_blocks_y, pCompressed_data + slice_offset, slice_length, block_format::cBC7,
-				bytes_per_block_or_pixel, false, basis_file_has_alpha_slices, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, pState, output_rows_in_pixels);
+				bytes_per_block_or_pixel, false, has_alpha, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, pState, output_rows_in_pixels);
 			if (!status)
 			{
 				BASISU_DEVEL_ERROR("basisu_lowlevel_uastc_transcoder::transcode_image: transcode_slice() to BC7 failed\n");
@@ -9714,7 +9714,7 @@
 		{
 			//status = transcode_slice(pData, data_size, slice_index, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cPVRTC1_4_RGB, bytes_per_block_or_pixel, decode_flags, output_row_pitch_in_blocks_or_pixels, pState);
 			status = transcode_slice(pOutput_blocks, num_blocks_x, num_blocks_y, pCompressed_data + slice_offset, slice_length, block_format::cPVRTC1_4_RGB,
-				bytes_per_block_or_pixel, false, basis_file_has_alpha_slices, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, pState, output_rows_in_pixels);
+				bytes_per_block_or_pixel, false, has_alpha, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, pState, output_rows_in_pixels);
 			if (!status)
 			{
 				BASISU_DEVEL_ERROR("basisu_lowlevel_uastc_transcoder::transcode_image: transcode_slice() to PVRTC1 RGB 4bpp failed\n");
@@ -9725,7 +9725,7 @@
 		{
 			//status = transcode_slice(pData, data_size, slice_index, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cPVRTC1_4_RGBA, bytes_per_block_or_pixel, decode_flags, output_row_pitch_in_blocks_or_pixels, pState);
 			status = transcode_slice(pOutput_blocks, num_blocks_x, num_blocks_y, pCompressed_data + slice_offset, slice_length, block_format::cPVRTC1_4_RGBA,
-				bytes_per_block_or_pixel, false, basis_file_has_alpha_slices, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, pState, output_rows_in_pixels);
+				bytes_per_block_or_pixel, false, has_alpha, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, pState, output_rows_in_pixels);
 			if (!status)
 			{
 				BASISU_DEVEL_ERROR("basisu_lowlevel_uastc_transcoder::transcode_image: transcode_slice() to PVRTC1 RGBA 4bpp failed\n");
@@ -9736,7 +9736,7 @@
 		{
 			//status = transcode_slice(pData, data_size, slice_index, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cASTC_4x4, bytes_per_block_or_pixel, decode_flags, output_row_pitch_in_blocks_or_pixels, pState);
 			status = transcode_slice(pOutput_blocks, num_blocks_x, num_blocks_y, pCompressed_data + slice_offset, slice_length, block_format::cASTC_4x4,
-				bytes_per_block_or_pixel, false, basis_file_has_alpha_slices, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, pState, output_rows_in_pixels);
+				bytes_per_block_or_pixel, false, has_alpha, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, pState, output_rows_in_pixels);
 			if (!status)
 			{
 				BASISU_DEVEL_ERROR("basisu_lowlevel_uastc_transcoder::transcode_image: transcode_slice() to ASTC 4x4 failed\n");
@@ -9768,10 +9768,10 @@
 		{
 			//status = transcode_slice(pData, data_size, slice_index, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cETC2_EAC_R11, bytes_per_block_or_pixel, decode_flags, output_row_pitch_in_blocks_or_pixels, pState,
 			//	nullptr, 0,
-			//	((basis_file_has_alpha_slices) && (transcode_alpha_data_to_opaque_formats)) ? 3 : 0);
+			//	((has_alpha) && (transcode_alpha_data_to_opaque_formats)) ? 3 : 0);
 			status = transcode_slice(pOutput_blocks, num_blocks_x, num_blocks_y, pCompressed_data + slice_offset, slice_length, block_format::cETC2_EAC_R11,
-				bytes_per_block_or_pixel, false, basis_file_has_alpha_slices, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, pState, output_rows_in_pixels,
-				((basis_file_has_alpha_slices) && (transcode_alpha_data_to_opaque_formats)) ? 3 : 0);
+				bytes_per_block_or_pixel, false, has_alpha, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, pState, output_rows_in_pixels,
+				((has_alpha) && (transcode_alpha_data_to_opaque_formats)) ? 3 : 0);
 			if (!status)
 			{
 				BASISU_DEVEL_ERROR("basisu_lowlevel_uastc_transcoder::transcode_image: transcode_slice() to EAC R11 failed\n");
@@ -9784,7 +9784,7 @@
 			//	nullptr, 0,
 			//	0, 3);
 			status = transcode_slice(pOutput_blocks, num_blocks_x, num_blocks_y, pCompressed_data + slice_offset, slice_length, block_format::cETC2_EAC_RG11,
-				bytes_per_block_or_pixel, false, basis_file_has_alpha_slices, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, pState, output_rows_in_pixels,
+				bytes_per_block_or_pixel, false, has_alpha, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, pState, output_rows_in_pixels,
 				0, 3);
 			if (!status)
 			{
@@ -9796,7 +9796,7 @@
 		{
 			//status = transcode_slice(pData, data_size, slice_index, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cRGBA32, bytes_per_block_or_pixel, decode_flags, output_row_pitch_in_blocks_or_pixels, pState);
 			status = transcode_slice(pOutput_blocks, num_blocks_x, num_blocks_y, pCompressed_data + slice_offset, slice_length, block_format::cRGBA32,
-				bytes_per_block_or_pixel, false, basis_file_has_alpha_slices, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, pState, output_rows_in_pixels);
+				bytes_per_block_or_pixel, false, has_alpha, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, pState, output_rows_in_pixels);
 			if (!status)
 			{
 				BASISU_DEVEL_ERROR("basisu_lowlevel_uastc_transcoder::transcode_image: transcode_slice() to RGBA32 failed\n");
@@ -9807,7 +9807,7 @@
 		{
 			//status = transcode_slice(pData, data_size, slice_index, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cRGB565, bytes_per_block_or_pixel, decode_flags, output_row_pitch_in_blocks_or_pixels, pState);
 			status = transcode_slice(pOutput_blocks, num_blocks_x, num_blocks_y, pCompressed_data + slice_offset, slice_length, block_format::cRGB565,
-				bytes_per_block_or_pixel, false, basis_file_has_alpha_slices, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, pState, output_rows_in_pixels);
+				bytes_per_block_or_pixel, false, has_alpha, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, pState, output_rows_in_pixels);
 			if (!status)
 			{
 				BASISU_DEVEL_ERROR("basisu_lowlevel_uastc_transcoder::transcode_image: transcode_slice() to RGB565 failed\n");
@@ -9818,7 +9818,7 @@
 		{
 			//status = transcode_slice(pData, data_size, slice_index, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cBGR565, bytes_per_block_or_pixel, decode_flags, output_row_pitch_in_blocks_or_pixels, pState);
 			status = transcode_slice(pOutput_blocks, num_blocks_x, num_blocks_y, pCompressed_data + slice_offset, slice_length, block_format::cBGR565,
-				bytes_per_block_or_pixel, false, basis_file_has_alpha_slices, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, pState, output_rows_in_pixels);
+				bytes_per_block_or_pixel, false, has_alpha, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, pState, output_rows_in_pixels);
 			if (!status)
 			{
 				BASISU_DEVEL_ERROR("basisu_lowlevel_uastc_transcoder::transcode_image: transcode_slice() to RGB565 failed\n");
@@ -9829,7 +9829,7 @@
 		{
 			//status = transcode_slice(pData, data_size, slice_index, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cRGBA4444, bytes_per_block_or_pixel, decode_flags, output_row_pitch_in_blocks_or_pixels, pState);
 			status = transcode_slice(pOutput_blocks, num_blocks_x, num_blocks_y, pCompressed_data + slice_offset, slice_length, block_format::cRGBA4444,
-				bytes_per_block_or_pixel, false, basis_file_has_alpha_slices, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, pState, output_rows_in_pixels);
+				bytes_per_block_or_pixel, false, has_alpha, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, pState, output_rows_in_pixels);
 			if (!status)
 			{
 				BASISU_DEVEL_ERROR("basisu_lowlevel_uastc_transcoder::transcode_image: transcode_slice() to RGBA4444 failed\n");
@@ -10239,6 +10239,21 @@
 		image_info.m_total_blocks = image_info.m_num_blocks_x * image_info.m_num_blocks_y;
 		image_info.m_first_slice_index = slice_index;
 
+		image_info.m_rgb_file_ofs = slice_desc.m_file_ofs;
+		image_info.m_rgb_file_len = slice_desc.m_file_size;
+		image_info.m_alpha_file_ofs = 0;
+		image_info.m_alpha_file_len = 0;
+
+		if (pHeader->m_tex_format == (int)basis_tex_format::cETC1S)
+		{
+			if (pHeader->m_flags & cBASISHeaderFlagHasAlphaSlices)
+			{
+				assert((slice_index + 1) < (int)pHeader->m_total_slices);
+				image_info.m_alpha_file_ofs = pSlice_descs[slice_index + 1].m_file_ofs;
+				image_info.m_alpha_file_len = pSlice_descs[slice_index + 1].m_file_size;
+			}
+		}
+
 		return true;
 	}
 
@@ -10258,11 +10273,14 @@
 		file_info.m_total_header_size = sizeof(basis_file_header) + pHeader->m_total_slices * sizeof(basis_slice_desc);
 
 		file_info.m_total_selectors = pHeader->m_total_selectors;
+		file_info.m_selector_codebook_ofs = pHeader->m_selector_cb_file_ofs;
 		file_info.m_selector_codebook_size = pHeader->m_selector_cb_file_size;
 
 		file_info.m_total_endpoints = pHeader->m_total_endpoints;
+		file_info.m_endpoint_codebook_ofs = pHeader->m_endpoint_cb_file_ofs;
 		file_info.m_endpoint_codebook_size = pHeader->m_endpoint_cb_file_size;
 
+		file_info.m_tables_ofs = pHeader->m_tables_file_ofs;
 		file_info.m_tables_size = pHeader->m_tables_file_size;
 
 		file_info.m_tex_format = static_cast<basis_tex_format>(static_cast<int>(pHeader->m_tex_format));
@@ -12454,7 +12472,12 @@
 				bits = read_bits64(blk.m_bytes, bit_ofs, std::min<int>(64, 128 - (int)bit_ofs));
 			else
 			{
+#ifdef __EMSCRIPTEN__
+				bits = blk.m_dwords[2];
+				bits |= (((uint64_t)blk.m_dwords[3]) << 32U);
+#else
 				bits = blk.m_qwords[1];
+#endif
 				
 				if (bit_ofs >= 64U)
 					bits >>= (bit_ofs - 64U);
diff --git a/transcoder/basisu_transcoder.h b/transcoder/basisu_transcoder.h
index a359804..c6051cd 100644
--- a/transcoder/basisu_transcoder.h
+++ b/transcoder/basisu_transcoder.h
@@ -280,7 +280,7 @@
 			uint32_t num_blocks_x, uint32_t num_blocks_y, uint32_t orig_width, uint32_t orig_height, uint32_t level_index,
 			uint32_t slice_offset, uint32_t slice_length, 
 			uint32_t decode_flags = 0,
-			bool basis_file_has_alpha_slices = false,
+			bool has_alpha = false,
 			bool is_video = false,
 			uint32_t output_row_pitch_in_blocks_or_pixels = 0,
 			basisu_transcoder_state* pState = nullptr,
@@ -351,6 +351,11 @@
 		uint32_t m_total_blocks;
 
 		uint32_t m_first_slice_index;	
+
+		uint32_t m_rgb_file_ofs;
+		uint32_t m_rgb_file_len;
+		uint32_t m_alpha_file_ofs;
+		uint32_t m_alpha_file_len;
 								
 		bool m_alpha_flag;		// true if the image has alpha data
 		bool m_iframe_flag;		// true if the image is an I-Frame
@@ -362,12 +367,16 @@
 		uint32_t m_total_header_size;
 
 		uint32_t m_total_selectors;
+		uint32_t m_selector_codebook_ofs;
 		uint32_t m_selector_codebook_size;
 
 		uint32_t m_total_endpoints;
+		uint32_t m_endpoint_codebook_ofs;
 		uint32_t m_endpoint_codebook_size;
 
+		uint32_t m_tables_ofs;
 		uint32_t m_tables_size;
+
 		uint32_t m_slices_size;	
 
 		basis_texture_type m_tex_type;
diff --git a/transcoder/basisu_transcoder_uastc.h b/transcoder/basisu_transcoder_uastc.h
index 7d520dc..d501a2a 100644
--- a/transcoder/basisu_transcoder_uastc.h
+++ b/transcoder/basisu_transcoder_uastc.h
@@ -205,7 +205,10 @@
 		{
 			uint8_t m_bytes[16];
 			uint32_t m_dwords[4];
+
+#ifndef __EMSCRIPTEN__
 			uint64_t m_qwords[2];
+#endif
 		};
 	};
 
diff --git a/webgl/README.md b/webgl/README.md
index 4ad633b..79b6cb9 100644
--- a/webgl/README.md
+++ b/webgl/README.md
@@ -40,6 +40,14 @@
 
 ![Screenshot showing a basis texture rendered as the base color texture for a 3D model in a webpage.](gltf/preview.png)
 
+## Compressor (encode_test)
+
+This demo shows how to use the compressor from JavaScript. To use it, select a .PNG file then hit the "Encode!" button. The compressor will dynamically generate a .basis file in memory which will then be immediately transcoded and displayed. Hit the "Download!" button to locally download the generated .basis file. 
+
+To view the compressor's textual debug output, open your browser's developer debug console (under Developer Tools in Chrome) and enable the Debug checkbox before hitting the "Encode!" button. Multithreading is not currently supported when the compressor is compiled to WebAssembly, so compression will be slower than using the stand-alone command line tool.
+
+![Screenshot showing the encode_test demo](encode_test/preview.png)
+
 ## Testing locally
 
 See [how to run things locally](https://threejs.org/docs/#manual/en/introduction/How-to-run-things-locally), or (with [Node.js](https://nodejs.org/en/) installed), run:
@@ -49,3 +57,5 @@
 ```
 
 The console will display a `localhost` URL for local testing, and (on supported WiFi networks and devices) may also display an IP address accessible by other devices on the same network. Note that mobile devices must support WebAssembly to run this demo. Learn more about [remote debugging your android devices](https://developers.google.com/web/tools/chrome-devtools/remote-debugging/).
+
+Alternately, use [Web Server for Chrome](https://chrome.google.com/webstore/detail/web-server-for-chrome/ofhbbkphhbklhfoeikjpcbhemlocgigb), browse to your local "webgl" directory, and then select 127.0.0.1:8887 under "Web Server URL(s).
diff --git a/webgl/encode_test/assets/kodim03.png b/webgl/encode_test/assets/kodim03.png
new file mode 100644
index 0000000..639a417
--- /dev/null
+++ b/webgl/encode_test/assets/kodim03.png
Binary files differ
diff --git a/webgl/encode_test/assets/kodim18.png b/webgl/encode_test/assets/kodim18.png
new file mode 100644
index 0000000..187fec2
--- /dev/null
+++ b/webgl/encode_test/assets/kodim18.png
Binary files differ
diff --git a/webgl/encode_test/assets/kodim18_64x64.png b/webgl/encode_test/assets/kodim18_64x64.png
new file mode 100644
index 0000000..1166093
--- /dev/null
+++ b/webgl/encode_test/assets/kodim18_64x64.png
Binary files differ
diff --git a/webgl/encode_test/assets/kodim26_uastc_1024.basis b/webgl/encode_test/assets/kodim26_uastc_1024.basis
new file mode 100644
index 0000000..671d188
--- /dev/null
+++ b/webgl/encode_test/assets/kodim26_uastc_1024.basis
Binary files differ
diff --git a/webgl/encode_test/dxt-to-rgb565.js b/webgl/encode_test/dxt-to-rgb565.js
new file mode 100644
index 0000000..8e35be4
--- /dev/null
+++ b/webgl/encode_test/dxt-to-rgb565.js
@@ -0,0 +1,128 @@
+/**
+ * Transcodes DXT into RGB565.
+ * This is an optimized version of dxtToRgb565Unoptimized() below.
+ * Optimizations:
+ * 1. Use integer math to compute c2 and c3 instead of floating point
+ *    math.  Specifically:
+ *      c2 = 5/8 * c0 + 3/8 * c1
+ *      c3 = 3/8 * c0 + 5/8 * c1
+ *    This is about a 40% performance improvement.  It also appears to
+ *    match what hardware DXT decoders do, as the colors produced
+ *    by this integer math match what hardware produces, while the
+ *    floating point in dxtToRgb565Unoptimized() produce slightly
+ *    different colors (for one GPU this was tested on).
+ * 2. Unroll the inner loop.  Another ~10% improvement.
+ * 3. Compute r0, g0, b0, r1, g1, b1 only once instead of twice.
+ *    Another 10% improvement.
+ * 4. Use a Uint16Array instead of a Uint8Array.  Another 10% improvement.
+ * @param {Uint16Array} src The src DXT bits as a Uint16Array.
+ * @param {number} srcByteOffset
+ * @param {number} width
+ * @param {number} height
+ * @return {Uint16Array} dst
+ */
+function dxtToRgb565(src, src16Offset, width, height) {
+  var c = new Uint16Array(4);
+  var dst = new Uint16Array(width * height);
+  var nWords = (width * height) / 4;
+  var m = 0;
+  var dstI = 0;
+  var i = 0;
+  var r0 = 0, g0 = 0, b0 = 0, r1 = 0, g1 = 0, b1 = 0;
+
+  var blockWidth = width / 4;
+  var blockHeight = height / 4;
+  for (var blockY = 0; blockY < blockHeight; blockY++) {
+    for (var blockX = 0; blockX < blockWidth; blockX++) {
+      i = src16Offset + 4 * (blockY * blockWidth + blockX);
+      c[0] = src[i];
+      c[1] = src[i + 1];
+	  
+      r0 = c[0] & 0x1f;
+      g0 = c[0] & 0x7e0;
+      b0 = c[0] & 0xf800;
+      r1 = c[1] & 0x1f;
+      g1 = c[1] & 0x7e0;
+      b1 = c[1] & 0xf800;
+      // Interpolate between c0 and c1 to get c2 and c3.
+      // Note that we approximate 1/3 as 3/8 and 2/3 as 5/8 for
+      // speed.  This also appears to be what the hardware DXT
+      // decoder in many GPUs does :)
+
+	  // rg FIXME: This is most likely leading to wrong results vs. a GPU
+	  
+      c[2] = ((5 * r0 + 3 * r1) >> 3)
+             | (((5 * g0 + 3 * g1) >> 3) & 0x7e0)
+             | (((5 * b0 + 3 * b1) >> 3) & 0xf800);
+      c[3] = ((5 * r1 + 3 * r0) >> 3)
+             | (((5 * g1 + 3 * g0) >> 3) & 0x7e0)
+             | (((5 * b1 + 3 * b0) >> 3) & 0xf800);
+      m = src[i + 2];
+      dstI = (blockY * 4) * width + blockX * 4;
+      dst[dstI] = c[m & 0x3];
+      dst[dstI + 1] = c[(m >> 2) & 0x3];
+      dst[dstI + 2] = c[(m >> 4) & 0x3];
+      dst[dstI + 3] = c[(m >> 6) & 0x3];
+      dstI += width;
+      dst[dstI] = c[(m >> 8) & 0x3];
+      dst[dstI + 1] = c[(m >> 10) & 0x3];
+      dst[dstI + 2] = c[(m >> 12) & 0x3];
+      dst[dstI + 3] = c[(m >> 14)];
+      m = src[i + 3];
+      dstI += width;
+      dst[dstI] = c[m & 0x3];
+      dst[dstI + 1] = c[(m >> 2) & 0x3];
+      dst[dstI + 2] = c[(m >> 4) & 0x3];
+      dst[dstI + 3] = c[(m >> 6) & 0x3];
+      dstI += width;
+      dst[dstI] = c[(m >> 8) & 0x3];
+      dst[dstI + 1] = c[(m >> 10) & 0x3];
+      dst[dstI + 2] = c[(m >> 12) & 0x3];
+      dst[dstI + 3] = c[(m >> 14)];
+    }
+  }
+  return dst;
+}
+
+
+/**
+ * An unoptimized version of dxtToRgb565.  Also, the floating
+ * point math used to compute the colors actually results in
+ * slightly different colors compared to hardware DXT decoders.
+ * @param {Uint8Array} src
+ * @param {number} srcByteOffset
+ * @param {number} width
+ * @param {number} height
+ * @return {Uint16Array} dst
+ */
+function dxtToRgb565Unoptimized(src, srcByteOffset, width, height) {
+  var c = new Uint16Array(4);
+  var dst = new Uint16Array(width * height);
+  var nWords = (width * height) / 4;
+
+  var blockWidth = width / 4;
+  var blockHeight = height / 4;
+  for (var blockY = 0; blockY < blockHeight; blockY++) {
+    for (var blockX = 0; blockX < blockWidth; blockX++) {
+      var i = srcByteOffset + 8 * (blockY * blockWidth + blockX);
+      c[0] = src[i] | (src[i + 1] << 8);
+      c[1] = src[i + 2] | (src[i + 3] << 8);
+      c[2] = (2 * (c[0] & 0x1f) + 1 * (c[1] & 0x1f)) / 3
+             | (((2 * (c[0] & 0x7e0) + 1 * (c[1] & 0x7e0)) / 3) & 0x7e0)
+             | (((2 * (c[0] & 0xf800) + 1 * (c[1] & 0xf800)) / 3) & 0xf800);
+      c[3] = (2 * (c[1] & 0x1f) + 1 * (c[0] & 0x1f)) / 3
+             | (((2 * (c[1] & 0x7e0) + 1 * (c[0] & 0x7e0)) / 3) & 0x7e0)
+             | (((2 * (c[1] & 0xf800) + 1 * (c[0] & 0xf800)) / 3) & 0xf800);
+      for (var row = 0; row < 4; row++) {
+        var m = src[i + 4 + row];
+        var dstI = (blockY * 4 + row) * width + blockX * 4;
+        dst[dstI++] = c[m & 0x3];
+        dst[dstI++] = c[(m >> 2) & 0x3];
+        dst[dstI++] = c[(m >> 4) & 0x3];
+        dst[dstI++] = c[(m >> 6) & 0x3];
+      }
+    }
+  }
+  return dst;
+}
+
diff --git a/webgl/encode_test/index.html b/webgl/encode_test/index.html
new file mode 100644
index 0000000..8be010c
--- /dev/null
+++ b/webgl/encode_test/index.html
@@ -0,0 +1,589 @@
+<html>
+<head>
+<script src="renderer.js"></script>
+<script src="dxt-to-rgb565.js"></script>
+<script src="../encoder/build/basis_encoder.js"></script>
+<script type="text/javascript">
+function log(s) {
+  var div = document.createElement('div');
+  div.innerHTML = s;
+  document.getElementById('logger').appendChild(div);
+}
+
+function logTime(desc, t) {
+  log(t + 'ms ' + desc);
+}
+
+function isDef(v) {
+  return typeof v != 'undefined';
+}
+
+function elem(id) {
+  return document.getElementById(id);
+}
+
+formatTable = function(rows) {
+  var colLengths = [];
+
+  for (var i = 0; i < rows.length; i++) {
+    var row = rows[i];
+    for (var j = 0; j < row.length; j++) {
+      if (colLengths.length <= j) colLengths.push(0);
+      if (colLengths[j] < row[j].length) colLengths[j] = row[j].length;
+    }
+  }
+
+  function formatRow(row) {
+    var parts = [];
+    for (var i = 0; i < colLengths.length; i++) {
+      var s = row.length > i ? row[i] : '';
+      var padding = (new Array(1 + colLengths[i] - s.length)).join(' ');
+      if (s && s[0] >= '0' && s[0] <= '9') {
+        // Right-align numbers.
+        parts.push(padding + s);
+      } else {
+        parts.push(s + padding);
+      }
+    }
+    return parts.join(' | ');
+  }
+
+  var width = 0;
+  for (var i = 0; i < colLengths.length; i++) {
+    width += colLengths[i];
+    // Add another 3 for the separator.
+    if (i != 0) width += 3;
+  }
+
+  var lines = [];
+  lines.push(formatRow(rows[0]));
+  lines.push((new Array(width + 1)).join('-'));
+  for (var i = 1; i < rows.length; i++) {
+    lines.push(formatRow(rows[i]));
+  }
+
+  return lines.join('\n');
+};
+
+
+function loadArrayBuffer(uri, callback) {
+  log('Loading ' + uri + '...');
+  var xhr = new XMLHttpRequest();
+  xhr.responseType = "arraybuffer";
+  xhr.open('GET', uri, true);
+  xhr.onreadystatechange = function(e) {
+    if (xhr.readyState == 4 && xhr.status == 200) {
+      callback(xhr.response);
+    }
+  }
+  xhr.send(null);
+}
+
+// ASTC format, from:
+// https://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_astc/
+COMPRESSED_RGBA_ASTC_4x4_KHR = 0x93B0;
+
+// DXT formats, from:
+// http://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_s3tc/
+COMPRESSED_RGB_S3TC_DXT1_EXT  = 0x83F0;
+COMPRESSED_RGBA_S3TC_DXT1_EXT = 0x83F1;
+COMPRESSED_RGBA_S3TC_DXT3_EXT = 0x83F2;
+COMPRESSED_RGBA_S3TC_DXT5_EXT = 0x83F3;
+
+// BC7 format, from:
+// https://www.khronos.org/registry/webgl/extensions/EXT_texture_compression_bptc/
+COMPRESSED_RGBA_BPTC_UNORM = 0x8E8C;
+
+// ETC format, from:
+// https://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_etc1/
+COMPRESSED_RGB_ETC1_WEBGL = 0x8D64;
+
+// PVRTC format, from:
+// https://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_pvrtc/
+COMPRESSED_RGB_PVRTC_4BPPV1_IMG = 0x8C00;
+COMPRESSED_RGBA_PVRTC_4BPPV1_IMG = 0x8C02;
+
+// Same as the Module.transcoder_texture_format enum
+BASIS_FORMAT = {
+  cTFETC1: 0,
+  cTFETC2: 1,
+  cTFBC1: 2,
+  cTFBC3: 3,
+  cTFBC4: 4,
+  cTFBC5: 5,
+  cTFBC7: 6,
+  cTFPVRTC1_4_RGB: 8,
+  cTFPVRTC1_4_RGBA: 9,
+  cTFASTC_4x4: 10,
+  cTFATC_RGB: 11,
+  cTFATC_RGBA_INTERPOLATED_ALPHA: 12,
+  cTFRGBA32: 13,
+  cTFRGB565: 14,
+  cTFBGR565: 15,
+  cTFRGBA4444: 16,
+  cTFFXT1_RGB: 17,
+  cTFPVRTC2_4_RGB: 18,
+  cTFPVRTC2_4_RGBA: 19,
+  cTFETC2_EAC_R11: 20,				
+  cTFETC2_EAC_RG11: 21	
+};
+
+BASIS_FORMAT_NAMES = {};
+for (var name in BASIS_FORMAT) {
+  BASIS_FORMAT_NAMES[BASIS_FORMAT[name]] = name;
+}
+
+DXT_FORMAT_MAP = {};
+DXT_FORMAT_MAP[BASIS_FORMAT.cTFBC1] = COMPRESSED_RGB_S3TC_DXT1_EXT;
+DXT_FORMAT_MAP[BASIS_FORMAT.cTFBC3] = COMPRESSED_RGBA_S3TC_DXT5_EXT;
+DXT_FORMAT_MAP[BASIS_FORMAT.cTFBC7] = COMPRESSED_RGBA_BPTC_UNORM; 
+
+var astcSupported = false;
+var etcSupported = false;
+var dxtSupported = false;
+var bc7Supported = false;
+var pvrtcSupported = false;
+var drawMode = 0;
+
+var tex, width, height, images, levels, have_alpha, alignedWidth, alignedHeight, format, displayWidth, displayHeight;
+
+function redraw()
+{
+  if (!width)
+   return;
+
+  renderer.drawTexture(tex, displayWidth, displayHeight, drawMode);
+}
+
+function dumpBasisFileDesc(basisFile)
+{
+  var basisFileDesc = basisFile.getFileDesc();
+
+  log('------');  
+  log('getFileDesc():');
+  log('version: ' + basisFileDesc.version);
+  log('us per frame: ' + basisFileDesc.usPerFrame);
+  log('total images: ' + basisFileDesc.totalImages);
+  log('userdata0: ' + basisFileDesc.userdata0 + ' userdata1: ' + basisFileDesc.userdata1);
+  log('texFormat: ' + basisFileDesc.texFormat);
+  log('yFlipped: ' + basisFileDesc.yFlipped + ' hasAlphaSlices: ' + basisFileDesc.hasAlphaSlices);
+  
+  if (basisFileDesc.texFormat == Module.basis_tex_format.cETC1S.value)
+  {
+	  log('numEndpoints: ' + basisFileDesc.numEndpoints);
+	  log('endpointPaletteOfs: ' + basisFileDesc.endpointPaletteOfs);
+	  log('endpointPaletteLen: ' + basisFileDesc.endpointPaletteLen);
+	  log('numSelectors: ' + basisFileDesc.numSelectors);
+	  log('selectorPaletteOfs: ' + basisFileDesc.selectorPaletteOfs);
+	  log('selectorPaletteLen: ' + basisFileDesc.selectorPaletteLen);
+	  log('tablesOfs: ' + basisFileDesc.tablesOfs);
+	  log('tablesLen: ' + basisFileDesc.tablesLen);
+  }
+  log('------');
+  log('getImageDesc() for all images:');
+  var image_index;
+  for (image_index = 0; image_index < basisFileDesc.totalImages; image_index++)
+  {
+     log('image: ' + image_index);
+	 
+	 var basisImageDesc = basisFile.getImageDesc(image_index);
+	 
+	 log('origWidth: ' + basisImageDesc.origWidth + ' origWidth: ' + basisImageDesc.origHeight);
+	 log('numBlocksX: ' + basisImageDesc.numBlocksX + ' origWidth: ' + basisImageDesc.numBlocksY);
+	 log('numLevels: ' + basisImageDesc.numLevels);
+	 log('alphaFlag: ' + basisImageDesc.alphaFlag + ' iframeFlag: ' + basisImageDesc.iframeFlag);
+
+	 log('getImageLevelDesc() for all mipmap levels:');
+	 var level_index;
+	 for (level_index = 0; level_index < basisImageDesc.numLevels; level_index++)
+	 {
+	 	var basisImageLevelDesc = basisFile.getImageLevelDesc(image_index, level_index);
+		
+		log('level: ' + level_index + 
+		    ' rgb_file_offset: ' + basisImageLevelDesc.rgbFileOfs + ' rgb_file_len: ' + basisImageLevelDesc.rgbFileLen);
+
+		if (basisFileDesc.hasAlphaSlices)			
+			log('alpha_file_offset: ' + basisImageLevelDesc.alphaFileOfs + ' alpha_file_len: ' + basisImageLevelDesc.alphaFileLen);
+	 }
+  }
+  
+  log('------');
+}
+
+function dataLoaded(data)
+{
+  log('Done loading .basis file, decoded header:');
+
+  const { BasisFile, initializeBasis, encodeBasisTexture } = Module;
+  initializeBasis();
+
+  const startTime = performance.now();
+
+  const basisFile = new BasisFile(new Uint8Array(data));
+
+  width = basisFile.getImageWidth(0, 0);
+  height = basisFile.getImageHeight(0, 0);
+  images = basisFile.getNumImages();
+  levels = basisFile.getNumLevels(0);
+  has_alpha = basisFile.getHasAlpha();
+  
+  dumpBasisFileDesc(basisFile);
+
+  if (!width || !height || !images || !levels) {
+    console.warn('Invalid .basis file');
+    basisFile.close();
+    basisFile.delete();
+    return;
+  }
+  
+  // Note: If the file is UASTC, the preferred formats are ASTC/BC7.
+  // If the file is ETC1S and doesn't have alpha, the preferred formats are ETC1 and BC1. For alpha, the preferred formats are ETC2, BC3 or BC7. 
+
+  var formatString = 'UNKNOWN';
+  if (astcSupported)
+  {
+    formatString = 'ASTC';
+    format = BASIS_FORMAT.cTFASTC_4x4;
+  }
+  else if (bc7Supported)
+  {
+    formatString = 'BC7';
+    format = BASIS_FORMAT.cTFBC7;
+  }
+  else if (dxtSupported)
+  {
+    if (has_alpha)
+    {
+      formatString = 'BC3';
+      format = BASIS_FORMAT.cTFBC3;
+    }
+    else
+    {
+      formatString = 'BC1';
+      format = BASIS_FORMAT.cTFBC1;
+    }
+  }
+  else if (pvrtcSupported)
+  {
+    if (has_alpha)
+    {
+      formatString = 'PVRTC1_RGBA';
+      format = BASIS_FORMAT.cTFPVRTC1_4_RGBA;
+    }
+    else
+    {
+      formatString = 'PVRTC1_RGB';
+      format = BASIS_FORMAT.cTFPVRTC1_4_RGB;
+    }
+    
+    if (
+         ((width & (width - 1)) != 0) || ((height & (height - 1)) != 0)
+        )
+    {
+      log('ERROR: PVRTC1 requires square power of 2 textures');
+    }
+    if (width != height)
+    {
+      log('ERROR: PVRTC1 requires square power of 2 textures');    
+    }
+  }
+  else if (etcSupported)
+  {
+    formatString = 'ETC1';
+    format = BASIS_FORMAT.cTFETC1;
+  }
+  else
+  {
+    formatString = 'RGB565';
+    format = BASIS_FORMAT.cTFRGB565;
+    log('Decoding .basis data to 565');
+  }
+
+  elem('format').innerText = formatString;
+
+  if (!basisFile.startTranscoding()) {
+    log('startTranscoding failed');
+    console.warn('startTranscoding failed');
+    basisFile.close();
+    basisFile.delete();
+    return;
+  }
+
+  const dstSize = basisFile.getImageTranscodedSizeInBytes(0, 0, format);
+  const dst = new Uint8Array(dstSize);
+  
+  //log(dstSize);
+
+//  if (!basisFile.transcodeImage(dst, 0, 0, format, 1, 0)) {
+  if (!basisFile.transcodeImage(dst, 0, 0, format, 0, 0)) {
+    log('basisFile.transcodeImage failed');
+    console.warn('transcodeImage failed');
+    basisFile.close();
+    basisFile.delete();
+       
+    return;
+  }
+
+  const elapsed = performance.now() - startTime;
+
+  basisFile.close();
+  basisFile.delete();
+
+  log('width: ' + width);
+  log('height: ' + height);
+  log('images: ' + images);
+  log('first image mipmap levels: ' + levels);
+  log('has_alpha: ' + has_alpha);
+  logTime('transcoding time', elapsed.toFixed(2));
+
+  alignedWidth = (width + 3) & ~3;
+  alignedHeight = (height + 3) & ~3;
+  
+  displayWidth = alignedWidth;
+  displayHeight = alignedHeight;
+
+  var canvas = elem('canvas');
+  canvas.width = alignedWidth;
+  canvas.height = alignedHeight;
+
+  if (format === BASIS_FORMAT.cTFASTC_4x4)
+  {
+    tex = renderer.createCompressedTexture(dst, alignedWidth, alignedHeight, COMPRESSED_RGBA_ASTC_4x4_KHR);
+  }
+  else if ((format === BASIS_FORMAT.cTFBC3) || (format === BASIS_FORMAT.cTFBC1) || (format == BASIS_FORMAT.cTFBC7))
+  {
+     tex = renderer.createCompressedTexture(dst, alignedWidth, alignedHeight, DXT_FORMAT_MAP[format]);
+  }
+  else if (format === BASIS_FORMAT.cTFETC1)
+  {
+    tex = renderer.createCompressedTexture(dst, alignedWidth, alignedHeight, COMPRESSED_RGB_ETC1_WEBGL);
+  }
+  else if (format === BASIS_FORMAT.cTFPVRTC1_4_RGB)
+  {
+    tex = renderer.createCompressedTexture(dst, alignedWidth, alignedHeight, COMPRESSED_RGB_PVRTC_4BPPV1_IMG);
+  }
+  else if (format === BASIS_FORMAT.cTFPVRTC1_4_RGBA)
+  {
+    tex = renderer.createCompressedTexture(dst, alignedWidth, alignedHeight, COMPRESSED_RGBA_PVRTC_4BPPV1_IMG);
+  }
+  else
+  {
+   canvas.width = width;
+   canvas.height = height;
+   displayWidth = width;
+   displayHeight = height;
+
+   // Create 565 texture. 
+   var dstTex = new Uint16Array(width * height);
+   
+   // Convert the array of bytes to an array of uint16's.
+   var pix = 0;
+   for (var y = 0; y < height; y++)
+      for (var x = 0; x < width; x++, pix++)
+         dstTex[pix] = dst[2 * pix + 0] | (dst[2 * pix + 1] << 8);
+
+   tex = renderer.createRgb565Texture(dstTex, width, height);
+  }
+
+  redraw();
+}
+
+function download_file(filename, body) 
+{
+  var element = document.createElement('a');
+  
+  //element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));
+
+  const blob = new Blob([body]);  
+  const url = URL.createObjectURL(blob);
+  element.setAttribute('href', url);
+  
+  element.setAttribute('download', filename);
+
+  element.style.display = 'none';
+  document.body.appendChild(element);
+
+  element.click();
+
+  document.body.removeChild(element);
+}
+
+var encodedBasisFile;
+
+function PNGDataLoaded(data)
+{
+	const { BasisFile, BasisEncoder, initializeBasis, encodeBasisTexture } = Module;
+	
+	initializeBasis();
+	
+	// Create a destination buffer to hold the compressed .basis file data. If this buffer isn't large enough compression will fail.
+	var basisFileData = new Uint8Array(1024*1024*10);
+			
+	var num_output_bytes;
+	
+	// Compress using the BasisEncoder class.
+	log('BasisEncoder::encode() started:');
+
+	const basisEncoder = new BasisEncoder();
+
+	const qualityLevel = parseInt(elem('EncodeQuality').value, 10);
+	const uastcFlag = elem('EncodeUASTC').checked;
+
+	basisEncoder.setSliceSourceImage(0, new Uint8Array(data), 0, 0, true);
+	basisEncoder.setDebug(elem('Debug').checked);
+	basisEncoder.setComputeStats(elem('ComputeStats').checked);
+	basisEncoder.setPerceptual(elem('SRGB').checked);
+	basisEncoder.setMipSRGB(elem('SRGB').checked);
+	basisEncoder.setQualityLevel(qualityLevel);
+	basisEncoder.setUASTC(uastcFlag);
+	basisEncoder.setMipGen(elem('Mipmaps').checked);
+	
+	if (!uastcFlag)
+		log('Encoding at ETC1S quality level ' + qualityLevel);
+	
+	num_output_bytes = basisEncoder.encode(basisFileData);
+	
+	var actualBasisFileData = new Uint8Array(basisFileData.buffer, 0, num_output_bytes);
+
+	basisEncoder.delete();
+	   
+	if (num_output_bytes == 0)
+	{
+		log('encodeBasisTexture() failed!');
+	}
+	else
+	{
+		log('encodeBasisTexture() succeeded, output size ' + num_output_bytes);
+		
+		encodedBasisFile = actualBasisFileData;
+		
+		//download("test.basis", actualBasisFileData);
+	}
+	  
+	if (num_output_bytes != 0)
+	{
+		dataLoaded(actualBasisFileData);
+	}
+}
+
+function runLoadFile() {
+  elem('logger').innerHTML = '';
+  loadArrayBuffer(elem('file').value, dataLoaded);
+}
+
+function runEncodePNGFile() {
+  elem('logger').innerHTML = '';
+  loadArrayBuffer(elem('pngfile').value, PNGDataLoaded);
+}
+
+function alphaBlend() { drawMode = 0; redraw(); }
+function viewRGB() { drawMode = 1; redraw(); }
+function viewAlpha() { drawMode = 2; redraw(); }
+
+function downloadEncodedFile() 
+{
+	if (encodedBasisFile)
+	{	
+		if (encodedBasisFile.length)
+			download_file("encoded_file.basis", encodedBasisFile);
+	}
+}
+
+</script>
+</head>
+<body>
+  <br>
+  <div style="font-size: 24pt; font-weight: bold">
+    Basis Universal compressed texture transcoding and encoding test
+  </div>
+
+  <br>This demo uses the Basis C++ transcoder (compiled to Javascript using Emscripten) to transcode a .basis file to <b id='format'>FORMAT</b>
+  <br>Thanks to Evan Parker for providing <a href="https://github.com/toji/webgl-texture-utils">webgl-texture-utils</a> and this test bed.
+  <br>
+  <br>
+      .basis file:
+      <input id="file" type="text" size=30 value="assets/kodim26_uastc_1024.basis"></input>
+      <input type="button" value="Transcode!" onclick="runLoadFile()"></input>
+  <br>
+  
+  <br>
+      .png file:
+      <input id="pngfile" type="text" size=30 value="assets/kodim18_64x64.png"></input>
+      <input type="button" value="Encode!" onclick="runEncodePNGFile()"></input>
+  <br>
+      <input type="button" value="Download Encoded .basis File" onclick="downloadEncodedFile()">
+  <br>
+      Debug:
+      <input type="checkbox" id="Debug">
+  <br>
+      Compute Stats:
+      <input type="checkbox" id="ComputeStats">
+  <br>
+      sRGB:
+      <input type="checkbox" id="SRGB">
+  <br>
+  	  Mipmaps:
+	  <input type="checkbox" id="Mipmaps">
+  <br>
+  	  UASTC:
+	  <input type="checkbox" id="EncodeUASTC">
+   
+
+  <br>
+   	  
+      ETC1S Quality:
+      <input type="range" min="1" max="255" value="10" class="slider" id="EncodeQuality"> 
+	  
+  <br>
+      
+  <br>
+      <input type="button" value="Alpha blend" onclick="alphaBlend()"></input>
+      <input type="button" value="View RGB" onclick="viewRGB()"></input>
+     <input type="button" value="View Alpha" onclick="viewAlpha()"></input>
+
+  <div style="position:absolute; left: 525px; top:130px; font-size: 20pt; font-weight: bold; color: red">
+    <div id="no-compressed-tex" style="display: none; width: 768px; font-size: 20pt; font-weight: bold; color: red">
+      NOTE: Your browser does not support several compressed texture format, so using RGB565.
+    </div>
+    <canvas id='canvas'></canvas>
+  </div>
+  <br><br>
+  <div id='logger'></div>
+</body>
+<script>
+  BASIS({onRuntimeInitialized : () => {
+  
+  	elem('SRGB').checked = true;
+	
+    var gl = elem('canvas').getContext('webgl');
+    
+    astcSupported = !!gl.getExtension('WEBGL_compressed_texture_astc');
+    etcSupported = !!gl.getExtension('WEBGL_compressed_texture_etc1');
+    dxtSupported = !!gl.getExtension('WEBGL_compressed_texture_s3tc');
+    pvrtcSupported = !!(gl.getExtension('WEBGL_compressed_texture_pvrtc')) || !!(gl.getExtension('WEBKIT_WEBGL_compressed_texture_pvrtc'));
+    bc7Supported = !!gl.getExtension('EXT_texture_compression_bptc');
+    
+   // HACK HACK - for testing uncompressed
+   //astcSupported = false;
+   //etcSupported = false;
+   //dxtSupported = false;
+   //bc7Supported = false;
+   //pvrtcSupported = false;
+
+    window.renderer = new Renderer(gl);
+
+    elem('file').addEventListener('keydown', function(e) {
+      if (e.keyCode == 13) {
+        runLoadFile();
+      }
+    }, false);
+
+    if (!(astcSupported || etcSupported || dxtSupported || pvrtcSupported))
+    {
+//      elem('nodxt').style.display = 'block';
+    }
+
+    runLoadFile();
+  }}).then(module => window.Module = module);
+</script>
+</html>
diff --git a/webgl/encode_test/preview.png b/webgl/encode_test/preview.png
new file mode 100644
index 0000000..99c399d
--- /dev/null
+++ b/webgl/encode_test/preview.png
Binary files differ
diff --git a/webgl/encode_test/renderer.js b/webgl/encode_test/renderer.js
new file mode 100644
index 0000000..26f1a65
--- /dev/null
+++ b/webgl/encode_test/renderer.js
@@ -0,0 +1,246 @@
+/**
+ * Constructs a renderer object.
+ * @param {WebGLRenderingContext} gl The GL context.
+ * @constructor
+ */
+var Renderer = function(gl) {
+  /**
+   * The GL context.
+   * @type {WebGLRenderingContext}
+   * @private
+   */
+  this.gl_ = gl;
+
+  /**
+   * The WebGLProgram.
+   * @type {WebGLProgram}
+   * @private
+   */
+  this.program_ = gl.createProgram();
+
+  /**
+   * @type {WebGLShader}
+   * @private
+   */
+  this.vertexShader_ = this.compileShader_(
+      Renderer.vertexShaderSource_, gl.VERTEX_SHADER);
+
+  /**
+   * @type {WebGLShader}
+   * @private
+   */
+  this.fragmentShader_ = this.compileShader_(
+      Renderer.fragmentShaderSource_, gl.FRAGMENT_SHADER);
+
+  /**
+   * Cached uniform locations.
+   * @type {Object.<string, WebGLUniformLocation>}
+   * @private
+   */
+  this.uniformLocations_ = {};
+
+  /**
+   * Cached attribute locations.
+   * @type {Object.<string, WebGLActiveInfo>}
+   * @private
+   */
+  this.attribLocations_ = {};
+
+  /**
+   * A vertex buffer containing a single quad with xy coordinates from [-1,-1]
+   * to [1,1] and uv coordinates from [0,0] to [1,1].
+   * @private
+   */
+  this.quadVertexBuffer_ = gl.createBuffer();
+  gl.bindBuffer(gl.ARRAY_BUFFER, this.quadVertexBuffer_);
+  var vertices = new Float32Array(
+      [-1.0, -1.0, 0.0, 1.0,
+       +1.0, -1.0, 1.0, 1.0,
+       -1.0, +1.0, 0.0, 0.0,
+        1.0, +1.0, 1.0, 0.0]);
+  gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
+
+
+  // init shaders
+
+  gl.attachShader(this.program_, this.vertexShader_);
+  gl.attachShader(this.program_, this.fragmentShader_);
+  gl.bindAttribLocation(this.program_, 0, 'vert');
+  gl.linkProgram(this.program_);
+  gl.useProgram(this.program_);
+  gl.enableVertexAttribArray(0);
+
+  gl.enable(gl.DEPTH_TEST);
+  gl.disable(gl.CULL_FACE);
+
+  var count = gl.getProgramParameter(this.program_, gl.ACTIVE_UNIFORMS);
+  for (var i = 0; i < /** @type {number} */(count); i++) {
+    var info = gl.getActiveUniform(this.program_, i);
+    var result = gl.getUniformLocation(this.program_, info.name);
+    this.uniformLocations_[info.name] = result;
+  }
+
+  count = gl.getProgramParameter(this.program_, gl.ACTIVE_ATTRIBUTES);
+  for (var i = 0; i < /** @type {number} */(count); i++) {
+    var info = gl.getActiveAttrib(this.program_, i);
+    var result = gl.getAttribLocation(this.program_, info.name);
+    this.attribLocations_[info.name] = result;
+  }
+};
+
+
+Renderer.prototype.finishInit = function() {
+  this.draw();
+};
+
+
+Renderer.prototype.createDxtTexture = function(dxtData, width, height, format) {
+  var gl = this.gl_;
+  var tex = gl.createTexture();
+  gl.bindTexture(gl.TEXTURE_2D, tex);
+  gl.compressedTexImage2D(
+      gl.TEXTURE_2D,
+      0,
+      format,
+      width,
+      height,
+      0,
+      dxtData);
+  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
+  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
+  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+  //gl.generateMipmap(gl.TEXTURE_2D)
+  gl.bindTexture(gl.TEXTURE_2D, null);
+  return tex;
+};
+
+Renderer.prototype.createCompressedTexture = function(data, width, height, format) {
+  var gl = this.gl_;
+  var tex = gl.createTexture();
+  gl.bindTexture(gl.TEXTURE_2D, tex);
+  gl.compressedTexImage2D(
+      gl.TEXTURE_2D,
+      0,
+      format,
+      width,
+      height,
+      0,
+      data);
+  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
+  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
+  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+  //gl.generateMipmap(gl.TEXTURE_2D)
+  gl.bindTexture(gl.TEXTURE_2D, null);
+  return tex;
+};
+
+
+Renderer.prototype.createRgb565Texture = function(rgb565Data, width, height) {
+  var gl = this.gl_;
+  var tex = gl.createTexture();
+  gl.bindTexture(gl.TEXTURE_2D, tex);
+  gl.texImage2D(
+    gl.TEXTURE_2D,
+    0,
+    gl.RGB,
+    width,
+    height,
+    0,
+    gl.RGB,
+    gl.UNSIGNED_SHORT_5_6_5,
+    rgb565Data);
+  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
+  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
+  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+  //gl.generateMipmap(gl.TEXTURE_2D)
+  gl.bindTexture(gl.TEXTURE_2D, null);
+  return tex;
+};
+
+
+Renderer.prototype.drawTexture = function(texture, width, height, mode) {
+  var gl = this.gl_;
+  // draw scene
+  gl.clearColor(0, 0, 0, 1);
+  gl.clearDepth(1.0);
+  gl.viewport(0, 0, width, height);
+  gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
+
+  gl.activeTexture(gl.TEXTURE0);
+  gl.bindTexture(gl.TEXTURE_2D, texture);
+  gl.uniform1i(this.uniformLocations_.texSampler, 0);
+
+  var x = 0.0;
+  var y = 0.0;
+  if (mode == 1)
+  	x = 1.0;
+  else if (mode == 2)
+    y = 1.0;
+	
+  gl.uniform4f(this.uniformLocations_.control, x, y, 0.0, 0.0);
+
+  gl.enableVertexAttribArray(this.attribLocations_.vert);
+  gl.bindBuffer(gl.ARRAY_BUFFER, this.quadVertexBuffer_);
+  gl.vertexAttribPointer(this.attribLocations_.vert, 4, gl.FLOAT,
+      false, 0, 0);
+  gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
+};
+
+
+/**
+ * Compiles a GLSL shader and returns a WebGLShader.
+ * @param {string} shaderSource The shader source code string.
+ * @param {number} type Either VERTEX_SHADER or FRAGMENT_SHADER.
+ * @return {WebGLShader} The new WebGLShader.
+ * @private
+ */
+Renderer.prototype.compileShader_ = function(shaderSource, type) {
+  var gl = this.gl_;
+  var shader = gl.createShader(type);
+  gl.shaderSource(shader, shaderSource);
+  gl.compileShader(shader);
+  return shader;
+};
+
+
+/**
+ * @type {string}
+ * @private
+ */
+Renderer.vertexShaderSource_ = [
+  'attribute vec4 vert;',
+  'varying vec2 v_texCoord;',
+  'void main() {',
+  '  gl_Position = vec4(vert.xy, 0.0, 1.0);',
+  '  v_texCoord = vert.zw;',
+  '}'
+  ].join('\n');
+
+
+/**
+ * @type {string}
+ * @private '  gl_FragColor = texture2D(texSampler, v_texCoord);',
+ */
+Renderer.fragmentShaderSource_ = [
+  'precision highp float;',
+  'uniform sampler2D texSampler;',
+  'uniform vec4 control;',
+  'varying vec2 v_texCoord;',
+  'void main() {',
+  '  vec4 c;',
+  '  c = texture2D(texSampler, v_texCoord);',
+  '  if (control.x > 0.0)',
+  '  {',
+  '   	c.w = 1.0;',
+  '  }',
+  '	 else if (control.y > 0.0)',
+  '	 {',
+  '   	c.rgb = c.aaa; c.w = 1.0;',
+  '  }',
+  '  gl_FragColor = c;',
+  '}'
+  ].join('\n');
+  
diff --git a/webgl/encoder/.gitignore b/webgl/encoder/.gitignore
new file mode 100644
index 0000000..1ab0538
--- /dev/null
+++ b/webgl/encoder/.gitignore
@@ -0,0 +1,4 @@
+build/*
+!build/basis_loader.js
+!build/basis_encoder.js
+!build/basis_encoder.wasm
diff --git a/webgl/encoder/CMakeLists.txt b/webgl/encoder/CMakeLists.txt
new file mode 100644
index 0000000..ed014a0
--- /dev/null
+++ b/webgl/encoder/CMakeLists.txt
@@ -0,0 +1,51 @@
+cmake_minimum_required(VERSION 3.0)
+
+project(basisu_encoder_js)
+
+if (EMSCRIPTEN)
+  set(CMAKE_CXX_STANDARD 11)
+
+  add_executable(basis_encoder.js
+    ../transcoder/basis_wrappers.cpp
+    ../../transcoder/basisu_transcoder.cpp
+	../../encoder/basisu_backend.cpp                         
+	../../encoder/basisu_basis_file.cpp                      
+	../../encoder/basisu_comp.cpp                            
+	../../encoder/basisu_enc.cpp                             
+	../../encoder/basisu_etc.cpp                             
+	../../encoder/basisu_frontend.cpp                        
+	../../encoder/basisu_global_selector_palette_helpers.cpp 
+	../../encoder/basisu_gpu_texture.cpp                     
+	../../encoder/basisu_pvrtc1_4.cpp                        
+	../../encoder/basisu_resampler.cpp                       
+	../../encoder/basisu_resample_filters.cpp                
+	../../encoder/basisu_ssim.cpp                            
+	../../encoder/basisu_astc_decomp.cpp                     
+	../../encoder/basisu_uastc_enc.cpp                       
+	../../encoder/basisu_bc7enc.cpp                          
+	../../encoder/lodepng.cpp                                
+	../../encoder/apg_bmp.c                                  
+	../../encoder/jpgd.cpp                                   
+  )
+
+  #target_compile_definitions(basis_encoder.js PRIVATE NDEBUG BASISD_SUPPORT_UASTC=1 BASISD_SUPPORT_BC7=1 BASISD_SUPPORT_ATC=0 BASISD_SUPPORT_ASTC_HIGHER_OPAQUE_QUALITY=0 BASISD_SUPPORT_PVRTC2=0 BASISD_SUPPORT_FXT1=0 BASISD_SUPPORT_ETC2_EAC_RG11=0 BASISU_SUPPORT_ENCODING=1)
+  #target_compile_options(basis_encoder.js PRIVATE -fno-strict-aliasing -O3)
+  
+  #target_compile_definitions(basis_encoder.js PRIVATE DEBUG BASISD_SUPPORT_UASTC=1 BASISD_SUPPORT_BC7=1 BASISD_SUPPORT_ATC=0 BASISD_SUPPORT_ASTC_HIGHER_OPAQUE_QUALITY=0 BASISD_SUPPORT_PVRTC2=0 BASISD_SUPPORT_FXT1=0 BASISD_SUPPORT_ETC2_EAC_RG11=0 BASISU_SUPPORT_ENCODING=1)
+  #target_compile_options(basis_encoder.js PRIVATE -fno-strict-aliasing -g -O1 -fsanitize=undefined -fsanitize=address)
+  
+  target_compile_definitions(basis_encoder.js PRIVATE NDEBUG BASISD_SUPPORT_UASTC=1 BASISD_SUPPORT_BC7=1 BASISD_SUPPORT_ATC=0 BASISD_SUPPORT_ASTC_HIGHER_OPAQUE_QUALITY=0 BASISD_SUPPORT_PVRTC2=0 BASISD_SUPPORT_FXT1=0 BASISD_SUPPORT_ETC2_EAC_RG11=0 BASISU_SUPPORT_ENCODING=1)
+  target_compile_options(basis_encoder.js PRIVATE -fno-strict-aliasing -O3)
+  
+  target_include_directories(basis_encoder.js PRIVATE ../../transcoder)
+
+  set_target_properties(basis_encoder.js PROPERTIES
+      OUTPUT_NAME "basis_encoder"
+      SUFFIX ".js"
+	  
+      #LINK_FLAGS "--bind -s ALLOW_MEMORY_GROWTH=1 -O3 -s ASSERTIONS=0 -s MALLOC=emmalloc -s MODULARIZE=1 -s EXPORT_NAME=BASIS ")
+	  
+	  #LINK_FLAGS "--bind -s INITIAL_MEMORY=299958272 -g -s DEMANGLE_SUPPORT=1 -s ALLOW_MEMORY_GROWTH=1 -O1 -s ASSERTIONS=1 -s MALLOC=emmalloc -s MODULARIZE=1 -s EXPORT_NAME=BASIS -fsanitize=undefined -fsanitize=address")
+	  
+	  LINK_FLAGS "--bind -s ALLOW_MEMORY_GROWTH=1 -O3 -s ASSERTIONS=0 -s INITIAL_MEMORY=299958272 -s MALLOC=emmalloc -s MODULARIZE=1 -s EXPORT_NAME=BASIS")
+endif()
diff --git a/webgl/encoder/README.md b/webgl/encoder/README.md
new file mode 100644
index 0000000..2055d02
--- /dev/null
+++ b/webgl/encoder/README.md
@@ -0,0 +1,7 @@
+Prebuilt versions of `basis_encoder.js` and `basis_encoder.wasm` are included in the `build/` folder, and are sufficient for local demos. Note the encoder also includes the transcoder. To build the encoder yourself, first install emscripten ([tutorial](https://webassembly.org/getting-started/developers-guide/)) and cmake ([download](https://cmake.org/download/)). Then run:
+
+```shell
+cd webgl/encoder/build/
+emcmake cmake ../
+make
+```
diff --git a/webgl/encoder/build/basis_encoder.js b/webgl/encoder/build/basis_encoder.js
new file mode 100644
index 0000000..4adc300
--- /dev/null
+++ b/webgl/encoder/build/basis_encoder.js
@@ -0,0 +1,21 @@
+
+var BASIS = (function() {
+  var _scriptDir = typeof document !== 'undefined' && document.currentScript ? document.currentScript.src : undefined;
+  if (typeof __filename !== 'undefined') _scriptDir = _scriptDir || __filename;
+  return (
+function(BASIS) {
+  BASIS = BASIS || {};
+
+var Module=typeof BASIS!=="undefined"?BASIS:{};var readyPromiseResolve,readyPromiseReject;Module["ready"]=new Promise(function(resolve,reject){readyPromiseResolve=resolve;readyPromiseReject=reject});var moduleOverrides={};var key;for(key in Module){if(Module.hasOwnProperty(key)){moduleOverrides[key]=Module[key]}}var arguments_=[];var thisProgram="./this.program";var quit_=function(status,toThrow){throw toThrow};var ENVIRONMENT_IS_WEB=false;var ENVIRONMENT_IS_WORKER=false;var ENVIRONMENT_IS_NODE=false;var ENVIRONMENT_IS_SHELL=false;ENVIRONMENT_IS_WEB=typeof window==="object";ENVIRONMENT_IS_WORKER=typeof importScripts==="function";ENVIRONMENT_IS_NODE=typeof process==="object"&&typeof process.versions==="object"&&typeof process.versions.node==="string";ENVIRONMENT_IS_SHELL=!ENVIRONMENT_IS_WEB&&!ENVIRONMENT_IS_NODE&&!ENVIRONMENT_IS_WORKER;var scriptDirectory="";function locateFile(path){if(Module["locateFile"]){return Module["locateFile"](path,scriptDirectory)}return scriptDirectory+path}var read_,readAsync,readBinary,setWindowTitle;var nodeFS;var nodePath;if(ENVIRONMENT_IS_NODE){if(ENVIRONMENT_IS_WORKER){scriptDirectory=require("path").dirname(scriptDirectory)+"/"}else{scriptDirectory=__dirname+"/"}read_=function shell_read(filename,binary){if(!nodeFS)nodeFS=require("fs");if(!nodePath)nodePath=require("path");filename=nodePath["normalize"](filename);return nodeFS["readFileSync"](filename,binary?null:"utf8")};readBinary=function readBinary(filename){var ret=read_(filename,true);if(!ret.buffer){ret=new Uint8Array(ret)}assert(ret.buffer);return ret};if(process["argv"].length>1){thisProgram=process["argv"][1].replace(/\\/g,"/")}arguments_=process["argv"].slice(2);process["on"]("uncaughtException",function(ex){if(!(ex instanceof ExitStatus)){throw ex}});process["on"]("unhandledRejection",abort);quit_=function(status){process["exit"](status)};Module["inspect"]=function(){return"[Emscripten Module object]"}}else if(ENVIRONMENT_IS_SHELL){if(typeof read!="undefined"){read_=function shell_read(f){return read(f)}}readBinary=function readBinary(f){var data;if(typeof readbuffer==="function"){return new Uint8Array(readbuffer(f))}data=read(f,"binary");assert(typeof data==="object");return data};if(typeof scriptArgs!="undefined"){arguments_=scriptArgs}else if(typeof arguments!="undefined"){arguments_=arguments}if(typeof quit==="function"){quit_=function(status){quit(status)}}if(typeof print!=="undefined"){if(typeof console==="undefined")console={};console.log=print;console.warn=console.error=typeof printErr!=="undefined"?printErr:print}}else if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){if(ENVIRONMENT_IS_WORKER){scriptDirectory=self.location.href}else if(typeof document!=="undefined"&&document.currentScript){scriptDirectory=document.currentScript.src}if(_scriptDir){scriptDirectory=_scriptDir}if(scriptDirectory.indexOf("blob:")!==0){scriptDirectory=scriptDirectory.substr(0,scriptDirectory.lastIndexOf("/")+1)}else{scriptDirectory=""}{read_=function shell_read(url){var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.send(null);return xhr.responseText};if(ENVIRONMENT_IS_WORKER){readBinary=function readBinary(url){var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.responseType="arraybuffer";xhr.send(null);return new Uint8Array(xhr.response)}}readAsync=function readAsync(url,onload,onerror){var xhr=new XMLHttpRequest;xhr.open("GET",url,true);xhr.responseType="arraybuffer";xhr.onload=function xhr_onload(){if(xhr.status==200||xhr.status==0&&xhr.response){onload(xhr.response);return}onerror()};xhr.onerror=onerror;xhr.send(null)}}setWindowTitle=function(title){document.title=title}}else{}var out=Module["print"]||console.log.bind(console);var err=Module["printErr"]||console.warn.bind(console);for(key in moduleOverrides){if(moduleOverrides.hasOwnProperty(key)){Module[key]=moduleOverrides[key]}}moduleOverrides=null;if(Module["arguments"])arguments_=Module["arguments"];if(Module["thisProgram"])thisProgram=Module["thisProgram"];if(Module["quit"])quit_=Module["quit"];var STACK_ALIGN=16;function alignMemory(size,factor){if(!factor)factor=STACK_ALIGN;return Math.ceil(size/factor)*factor}var tempRet0=0;var setTempRet0=function(value){tempRet0=value};var getTempRet0=function(){return tempRet0};var wasmBinary;if(Module["wasmBinary"])wasmBinary=Module["wasmBinary"];var noExitRuntime;if(Module["noExitRuntime"])noExitRuntime=Module["noExitRuntime"];if(typeof WebAssembly!=="object"){abort("no native wasm support detected")}var wasmMemory;var ABORT=false;var EXITSTATUS;function assert(condition,text){if(!condition){abort("Assertion failed: "+text)}}var UTF8Decoder=typeof TextDecoder!=="undefined"?new TextDecoder("utf8"):undefined;function UTF8ArrayToString(heap,idx,maxBytesToRead){var endIdx=idx+maxBytesToRead;var endPtr=idx;while(heap[endPtr]&&!(endPtr>=endIdx))++endPtr;if(endPtr-idx>16&&heap.subarray&&UTF8Decoder){return UTF8Decoder.decode(heap.subarray(idx,endPtr))}else{var str="";while(idx<endPtr){var u0=heap[idx++];if(!(u0&128)){str+=String.fromCharCode(u0);continue}var u1=heap[idx++]&63;if((u0&224)==192){str+=String.fromCharCode((u0&31)<<6|u1);continue}var u2=heap[idx++]&63;if((u0&240)==224){u0=(u0&15)<<12|u1<<6|u2}else{u0=(u0&7)<<18|u1<<12|u2<<6|heap[idx++]&63}if(u0<65536){str+=String.fromCharCode(u0)}else{var ch=u0-65536;str+=String.fromCharCode(55296|ch>>10,56320|ch&1023)}}}return str}function UTF8ToString(ptr,maxBytesToRead){return ptr?UTF8ArrayToString(HEAPU8,ptr,maxBytesToRead):""}function stringToUTF8Array(str,heap,outIdx,maxBytesToWrite){if(!(maxBytesToWrite>0))return 0;var startIdx=outIdx;var endIdx=outIdx+maxBytesToWrite-1;for(var i=0;i<str.length;++i){var u=str.charCodeAt(i);if(u>=55296&&u<=57343){var u1=str.charCodeAt(++i);u=65536+((u&1023)<<10)|u1&1023}if(u<=127){if(outIdx>=endIdx)break;heap[outIdx++]=u}else if(u<=2047){if(outIdx+1>=endIdx)break;heap[outIdx++]=192|u>>6;heap[outIdx++]=128|u&63}else if(u<=65535){if(outIdx+2>=endIdx)break;heap[outIdx++]=224|u>>12;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}else{if(outIdx+3>=endIdx)break;heap[outIdx++]=240|u>>18;heap[outIdx++]=128|u>>12&63;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}}heap[outIdx]=0;return outIdx-startIdx}function stringToUTF8(str,outPtr,maxBytesToWrite){return stringToUTF8Array(str,HEAPU8,outPtr,maxBytesToWrite)}function lengthBytesUTF8(str){var len=0;for(var i=0;i<str.length;++i){var u=str.charCodeAt(i);if(u>=55296&&u<=57343)u=65536+((u&1023)<<10)|str.charCodeAt(++i)&1023;if(u<=127)++len;else if(u<=2047)len+=2;else if(u<=65535)len+=3;else len+=4}return len}var UTF16Decoder=typeof TextDecoder!=="undefined"?new TextDecoder("utf-16le"):undefined;function UTF16ToString(ptr,maxBytesToRead){var endPtr=ptr;var idx=endPtr>>1;var maxIdx=idx+maxBytesToRead/2;while(!(idx>=maxIdx)&&HEAPU16[idx])++idx;endPtr=idx<<1;if(endPtr-ptr>32&&UTF16Decoder){return UTF16Decoder.decode(HEAPU8.subarray(ptr,endPtr))}else{var str="";for(var i=0;!(i>=maxBytesToRead/2);++i){var codeUnit=HEAP16[ptr+i*2>>1];if(codeUnit==0)break;str+=String.fromCharCode(codeUnit)}return str}}function stringToUTF16(str,outPtr,maxBytesToWrite){if(maxBytesToWrite===undefined){maxBytesToWrite=2147483647}if(maxBytesToWrite<2)return 0;maxBytesToWrite-=2;var startPtr=outPtr;var numCharsToWrite=maxBytesToWrite<str.length*2?maxBytesToWrite/2:str.length;for(var i=0;i<numCharsToWrite;++i){var codeUnit=str.charCodeAt(i);HEAP16[outPtr>>1]=codeUnit;outPtr+=2}HEAP16[outPtr>>1]=0;return outPtr-startPtr}function lengthBytesUTF16(str){return str.length*2}function UTF32ToString(ptr,maxBytesToRead){var i=0;var str="";while(!(i>=maxBytesToRead/4)){var utf32=HEAP32[ptr+i*4>>2];if(utf32==0)break;++i;if(utf32>=65536){var ch=utf32-65536;str+=String.fromCharCode(55296|ch>>10,56320|ch&1023)}else{str+=String.fromCharCode(utf32)}}return str}function stringToUTF32(str,outPtr,maxBytesToWrite){if(maxBytesToWrite===undefined){maxBytesToWrite=2147483647}if(maxBytesToWrite<4)return 0;var startPtr=outPtr;var endPtr=startPtr+maxBytesToWrite-4;for(var i=0;i<str.length;++i){var codeUnit=str.charCodeAt(i);if(codeUnit>=55296&&codeUnit<=57343){var trailSurrogate=str.charCodeAt(++i);codeUnit=65536+((codeUnit&1023)<<10)|trailSurrogate&1023}HEAP32[outPtr>>2]=codeUnit;outPtr+=4;if(outPtr+4>endPtr)break}HEAP32[outPtr>>2]=0;return outPtr-startPtr}function lengthBytesUTF32(str){var len=0;for(var i=0;i<str.length;++i){var codeUnit=str.charCodeAt(i);if(codeUnit>=55296&&codeUnit<=57343)++i;len+=4}return len}function alignUp(x,multiple){if(x%multiple>0){x+=multiple-x%multiple}return x}var buffer,HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;function updateGlobalBufferAndViews(buf){buffer=buf;Module["HEAP8"]=HEAP8=new Int8Array(buf);Module["HEAP16"]=HEAP16=new Int16Array(buf);Module["HEAP32"]=HEAP32=new Int32Array(buf);Module["HEAPU8"]=HEAPU8=new Uint8Array(buf);Module["HEAPU16"]=HEAPU16=new Uint16Array(buf);Module["HEAPU32"]=HEAPU32=new Uint32Array(buf);Module["HEAPF32"]=HEAPF32=new Float32Array(buf);Module["HEAPF64"]=HEAPF64=new Float64Array(buf)}var INITIAL_MEMORY=Module["INITIAL_MEMORY"]||299958272;var wasmTable;var __ATPRERUN__=[];var __ATINIT__=[];var __ATMAIN__=[];var __ATPOSTRUN__=[];var runtimeInitialized=false;function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="function")Module["preRun"]=[Module["preRun"]];while(Module["preRun"].length){addOnPreRun(Module["preRun"].shift())}}callRuntimeCallbacks(__ATPRERUN__)}function initRuntime(){runtimeInitialized=true;if(!Module["noFSInit"]&&!FS.init.initialized)FS.init();TTY.init();callRuntimeCallbacks(__ATINIT__)}function preMain(){FS.ignorePermissions=false;callRuntimeCallbacks(__ATMAIN__)}function postRun(){if(Module["postRun"]){if(typeof Module["postRun"]=="function")Module["postRun"]=[Module["postRun"]];while(Module["postRun"].length){addOnPostRun(Module["postRun"].shift())}}callRuntimeCallbacks(__ATPOSTRUN__)}function addOnPreRun(cb){__ATPRERUN__.unshift(cb)}function addOnPostRun(cb){__ATPOSTRUN__.unshift(cb)}var runDependencies=0;var runDependencyWatcher=null;var dependenciesFulfilled=null;function getUniqueRunDependency(id){return id}function addRunDependency(id){runDependencies++;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}}function removeRunDependency(id){runDependencies--;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}if(runDependencies==0){if(runDependencyWatcher!==null){clearInterval(runDependencyWatcher);runDependencyWatcher=null}if(dependenciesFulfilled){var callback=dependenciesFulfilled;dependenciesFulfilled=null;callback()}}}Module["preloadedImages"]={};Module["preloadedAudios"]={};function abort(what){if(Module["onAbort"]){Module["onAbort"](what)}what+="";err(what);ABORT=true;EXITSTATUS=1;what="abort("+what+"). Build with -s ASSERTIONS=1 for more info.";var e=new WebAssembly.RuntimeError(what);readyPromiseReject(e);throw e}function hasPrefix(str,prefix){return String.prototype.startsWith?str.startsWith(prefix):str.indexOf(prefix)===0}var dataURIPrefix="data:application/octet-stream;base64,";function isDataURI(filename){return hasPrefix(filename,dataURIPrefix)}var fileURIPrefix="file://";function isFileURI(filename){return hasPrefix(filename,fileURIPrefix)}var wasmBinaryFile="basis_encoder.wasm";if(!isDataURI(wasmBinaryFile)){wasmBinaryFile=locateFile(wasmBinaryFile)}function getBinary(){try{if(wasmBinary){return new Uint8Array(wasmBinary)}if(readBinary){return readBinary(wasmBinaryFile)}else{throw"both async and sync fetching of the wasm failed"}}catch(err){abort(err)}}function getBinaryPromise(){if(!wasmBinary&&(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER)&&typeof fetch==="function"&&!isFileURI(wasmBinaryFile)){return fetch(wasmBinaryFile,{credentials:"same-origin"}).then(function(response){if(!response["ok"]){throw"failed to load wasm binary file at '"+wasmBinaryFile+"'"}return response["arrayBuffer"]()}).catch(function(){return getBinary()})}return Promise.resolve().then(getBinary)}function createWasm(){var info={"a":asmLibraryArg};function receiveInstance(instance,module){var exports=instance.exports;Module["asm"]=exports;wasmMemory=Module["asm"]["Z"];updateGlobalBufferAndViews(wasmMemory.buffer);wasmTable=Module["asm"]["_"];removeRunDependency("wasm-instantiate")}addRunDependency("wasm-instantiate");function receiveInstantiatedSource(output){receiveInstance(output["instance"])}function instantiateArrayBuffer(receiver){return getBinaryPromise().then(function(binary){return WebAssembly.instantiate(binary,info)}).then(receiver,function(reason){err("failed to asynchronously prepare wasm: "+reason);abort(reason)})}function instantiateAsync(){if(!wasmBinary&&typeof WebAssembly.instantiateStreaming==="function"&&!isDataURI(wasmBinaryFile)&&!isFileURI(wasmBinaryFile)&&typeof fetch==="function"){return fetch(wasmBinaryFile,{credentials:"same-origin"}).then(function(response){var result=WebAssembly.instantiateStreaming(response,info);return result.then(receiveInstantiatedSource,function(reason){err("wasm streaming compile failed: "+reason);err("falling back to ArrayBuffer instantiation");return instantiateArrayBuffer(receiveInstantiatedSource)})})}else{return instantiateArrayBuffer(receiveInstantiatedSource)}}if(Module["instantiateWasm"]){try{var exports=Module["instantiateWasm"](info,receiveInstance);return exports}catch(e){err("Module.instantiateWasm callback failed with error: "+e);return false}}instantiateAsync().catch(readyPromiseReject);return{}}var tempDouble;var tempI64;function callRuntimeCallbacks(callbacks){while(callbacks.length>0){var callback=callbacks.shift();if(typeof callback=="function"){callback(Module);continue}var func=callback.func;if(typeof func==="number"){if(callback.arg===undefined){wasmTable.get(func)()}else{wasmTable.get(func)(callback.arg)}}else{func(callback.arg===undefined?null:callback.arg)}}}var ExceptionInfoAttrs={DESTRUCTOR_OFFSET:0,REFCOUNT_OFFSET:4,TYPE_OFFSET:8,CAUGHT_OFFSET:12,RETHROWN_OFFSET:13,SIZE:16};function ___cxa_allocate_exception(size){return _malloc(size+ExceptionInfoAttrs.SIZE)+ExceptionInfoAttrs.SIZE}function ExceptionInfo(excPtr){this.excPtr=excPtr;this.ptr=excPtr-ExceptionInfoAttrs.SIZE;this.set_type=function(type){HEAP32[this.ptr+ExceptionInfoAttrs.TYPE_OFFSET>>2]=type};this.get_type=function(){return HEAP32[this.ptr+ExceptionInfoAttrs.TYPE_OFFSET>>2]};this.set_destructor=function(destructor){HEAP32[this.ptr+ExceptionInfoAttrs.DESTRUCTOR_OFFSET>>2]=destructor};this.get_destructor=function(){return HEAP32[this.ptr+ExceptionInfoAttrs.DESTRUCTOR_OFFSET>>2]};this.set_refcount=function(refcount){HEAP32[this.ptr+ExceptionInfoAttrs.REFCOUNT_OFFSET>>2]=refcount};this.set_caught=function(caught){caught=caught?1:0;HEAP8[this.ptr+ExceptionInfoAttrs.CAUGHT_OFFSET>>0]=caught};this.get_caught=function(){return HEAP8[this.ptr+ExceptionInfoAttrs.CAUGHT_OFFSET>>0]!=0};this.set_rethrown=function(rethrown){rethrown=rethrown?1:0;HEAP8[this.ptr+ExceptionInfoAttrs.RETHROWN_OFFSET>>0]=rethrown};this.get_rethrown=function(){return HEAP8[this.ptr+ExceptionInfoAttrs.RETHROWN_OFFSET>>0]!=0};this.init=function(type,destructor){this.set_type(type);this.set_destructor(destructor);this.set_refcount(0);this.set_caught(false);this.set_rethrown(false)};this.add_ref=function(){var value=HEAP32[this.ptr+ExceptionInfoAttrs.REFCOUNT_OFFSET>>2];HEAP32[this.ptr+ExceptionInfoAttrs.REFCOUNT_OFFSET>>2]=value+1};this.release_ref=function(){var prev=HEAP32[this.ptr+ExceptionInfoAttrs.REFCOUNT_OFFSET>>2];HEAP32[this.ptr+ExceptionInfoAttrs.REFCOUNT_OFFSET>>2]=prev-1;return prev===1}}var exceptionLast=0;var uncaughtExceptionCount=0;function ___cxa_throw(ptr,type,destructor){var info=new ExceptionInfo(ptr);info.init(type,destructor);exceptionLast=ptr;uncaughtExceptionCount++;throw ptr}function setErrNo(value){HEAP32[___errno_location()>>2]=value;return value}var PATH={splitPath:function(filename){var splitPathRe=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;return splitPathRe.exec(filename).slice(1)},normalizeArray:function(parts,allowAboveRoot){var up=0;for(var i=parts.length-1;i>=0;i--){var last=parts[i];if(last==="."){parts.splice(i,1)}else if(last===".."){parts.splice(i,1);up++}else if(up){parts.splice(i,1);up--}}if(allowAboveRoot){for(;up;up--){parts.unshift("..")}}return parts},normalize:function(path){var isAbsolute=path.charAt(0)==="/",trailingSlash=path.substr(-1)==="/";path=PATH.normalizeArray(path.split("/").filter(function(p){return!!p}),!isAbsolute).join("/");if(!path&&!isAbsolute){path="."}if(path&&trailingSlash){path+="/"}return(isAbsolute?"/":"")+path},dirname:function(path){var result=PATH.splitPath(path),root=result[0],dir=result[1];if(!root&&!dir){return"."}if(dir){dir=dir.substr(0,dir.length-1)}return root+dir},basename:function(path){if(path==="/")return"/";path=PATH.normalize(path);path=path.replace(/\/$/,"");var lastSlash=path.lastIndexOf("/");if(lastSlash===-1)return path;return path.substr(lastSlash+1)},extname:function(path){return PATH.splitPath(path)[3]},join:function(){var paths=Array.prototype.slice.call(arguments,0);return PATH.normalize(paths.join("/"))},join2:function(l,r){return PATH.normalize(l+"/"+r)}};function getRandomDevice(){if(typeof crypto==="object"&&typeof crypto["getRandomValues"]==="function"){var randomBuffer=new Uint8Array(1);return function(){crypto.getRandomValues(randomBuffer);return randomBuffer[0]}}else if(ENVIRONMENT_IS_NODE){try{var crypto_module=require("crypto");return function(){return crypto_module["randomBytes"](1)[0]}}catch(e){}}return function(){abort("randomDevice")}}var PATH_FS={resolve:function(){var resolvedPath="",resolvedAbsolute=false;for(var i=arguments.length-1;i>=-1&&!resolvedAbsolute;i--){var path=i>=0?arguments[i]:FS.cwd();if(typeof path!=="string"){throw new TypeError("Arguments to path.resolve must be strings")}else if(!path){return""}resolvedPath=path+"/"+resolvedPath;resolvedAbsolute=path.charAt(0)==="/"}resolvedPath=PATH.normalizeArray(resolvedPath.split("/").filter(function(p){return!!p}),!resolvedAbsolute).join("/");return(resolvedAbsolute?"/":"")+resolvedPath||"."},relative:function(from,to){from=PATH_FS.resolve(from).substr(1);to=PATH_FS.resolve(to).substr(1);function trim(arr){var start=0;for(;start<arr.length;start++){if(arr[start]!=="")break}var end=arr.length-1;for(;end>=0;end--){if(arr[end]!=="")break}if(start>end)return[];return arr.slice(start,end-start+1)}var fromParts=trim(from.split("/"));var toParts=trim(to.split("/"));var length=Math.min(fromParts.length,toParts.length);var samePartsLength=length;for(var i=0;i<length;i++){if(fromParts[i]!==toParts[i]){samePartsLength=i;break}}var outputParts=[];for(var i=samePartsLength;i<fromParts.length;i++){outputParts.push("..")}outputParts=outputParts.concat(toParts.slice(samePartsLength));return outputParts.join("/")}};var TTY={ttys:[],init:function(){},shutdown:function(){},register:function(dev,ops){TTY.ttys[dev]={input:[],output:[],ops:ops};FS.registerDevice(dev,TTY.stream_ops)},stream_ops:{open:function(stream){var tty=TTY.ttys[stream.node.rdev];if(!tty){throw new FS.ErrnoError(43)}stream.tty=tty;stream.seekable=false},close:function(stream){stream.tty.ops.flush(stream.tty)},flush:function(stream){stream.tty.ops.flush(stream.tty)},read:function(stream,buffer,offset,length,pos){if(!stream.tty||!stream.tty.ops.get_char){throw new FS.ErrnoError(60)}var bytesRead=0;for(var i=0;i<length;i++){var result;try{result=stream.tty.ops.get_char(stream.tty)}catch(e){throw new FS.ErrnoError(29)}if(result===undefined&&bytesRead===0){throw new FS.ErrnoError(6)}if(result===null||result===undefined)break;bytesRead++;buffer[offset+i]=result}if(bytesRead){stream.node.timestamp=Date.now()}return bytesRead},write:function(stream,buffer,offset,length,pos){if(!stream.tty||!stream.tty.ops.put_char){throw new FS.ErrnoError(60)}try{for(var i=0;i<length;i++){stream.tty.ops.put_char(stream.tty,buffer[offset+i])}}catch(e){throw new FS.ErrnoError(29)}if(length){stream.node.timestamp=Date.now()}return i}},default_tty_ops:{get_char:function(tty){if(!tty.input.length){var result=null;if(ENVIRONMENT_IS_NODE){var BUFSIZE=256;var buf=Buffer.alloc?Buffer.alloc(BUFSIZE):new Buffer(BUFSIZE);var bytesRead=0;try{bytesRead=nodeFS.readSync(process.stdin.fd,buf,0,BUFSIZE,null)}catch(e){if(e.toString().indexOf("EOF")!=-1)bytesRead=0;else throw e}if(bytesRead>0){result=buf.slice(0,bytesRead).toString("utf-8")}else{result=null}}else if(typeof window!="undefined"&&typeof window.prompt=="function"){result=window.prompt("Input: ");if(result!==null){result+="\n"}}else if(typeof readline=="function"){result=readline();if(result!==null){result+="\n"}}if(!result){return null}tty.input=intArrayFromString(result,true)}return tty.input.shift()},put_char:function(tty,val){if(val===null||val===10){out(UTF8ArrayToString(tty.output,0));tty.output=[]}else{if(val!=0)tty.output.push(val)}},flush:function(tty){if(tty.output&&tty.output.length>0){out(UTF8ArrayToString(tty.output,0));tty.output=[]}}},default_tty1_ops:{put_char:function(tty,val){if(val===null||val===10){err(UTF8ArrayToString(tty.output,0));tty.output=[]}else{if(val!=0)tty.output.push(val)}},flush:function(tty){if(tty.output&&tty.output.length>0){err(UTF8ArrayToString(tty.output,0));tty.output=[]}}}};function mmapAlloc(size){var alignedSize=alignMemory(size,16384);var ptr=_malloc(alignedSize);while(size<alignedSize)HEAP8[ptr+size++]=0;return ptr}var MEMFS={ops_table:null,mount:function(mount){return MEMFS.createNode(null,"/",16384|511,0)},createNode:function(parent,name,mode,dev){if(FS.isBlkdev(mode)||FS.isFIFO(mode)){throw new FS.ErrnoError(63)}if(!MEMFS.ops_table){MEMFS.ops_table={dir:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr,lookup:MEMFS.node_ops.lookup,mknod:MEMFS.node_ops.mknod,rename:MEMFS.node_ops.rename,unlink:MEMFS.node_ops.unlink,rmdir:MEMFS.node_ops.rmdir,readdir:MEMFS.node_ops.readdir,symlink:MEMFS.node_ops.symlink},stream:{llseek:MEMFS.stream_ops.llseek}},file:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr},stream:{llseek:MEMFS.stream_ops.llseek,read:MEMFS.stream_ops.read,write:MEMFS.stream_ops.write,allocate:MEMFS.stream_ops.allocate,mmap:MEMFS.stream_ops.mmap,msync:MEMFS.stream_ops.msync}},link:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr,readlink:MEMFS.node_ops.readlink},stream:{}},chrdev:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr},stream:FS.chrdev_stream_ops}}}var node=FS.createNode(parent,name,mode,dev);if(FS.isDir(node.mode)){node.node_ops=MEMFS.ops_table.dir.node;node.stream_ops=MEMFS.ops_table.dir.stream;node.contents={}}else if(FS.isFile(node.mode)){node.node_ops=MEMFS.ops_table.file.node;node.stream_ops=MEMFS.ops_table.file.stream;node.usedBytes=0;node.contents=null}else if(FS.isLink(node.mode)){node.node_ops=MEMFS.ops_table.link.node;node.stream_ops=MEMFS.ops_table.link.stream}else if(FS.isChrdev(node.mode)){node.node_ops=MEMFS.ops_table.chrdev.node;node.stream_ops=MEMFS.ops_table.chrdev.stream}node.timestamp=Date.now();if(parent){parent.contents[name]=node}return node},getFileDataAsRegularArray:function(node){if(node.contents&&node.contents.subarray){var arr=[];for(var i=0;i<node.usedBytes;++i)arr.push(node.contents[i]);return arr}return node.contents},getFileDataAsTypedArray:function(node){if(!node.contents)return new Uint8Array(0);if(node.contents.subarray)return node.contents.subarray(0,node.usedBytes);return new Uint8Array(node.contents)},expandFileStorage:function(node,newCapacity){var prevCapacity=node.contents?node.contents.length:0;if(prevCapacity>=newCapacity)return;var CAPACITY_DOUBLING_MAX=1024*1024;newCapacity=Math.max(newCapacity,prevCapacity*(prevCapacity<CAPACITY_DOUBLING_MAX?2:1.125)>>>0);if(prevCapacity!=0)newCapacity=Math.max(newCapacity,256);var oldContents=node.contents;node.contents=new Uint8Array(newCapacity);if(node.usedBytes>0)node.contents.set(oldContents.subarray(0,node.usedBytes),0);return},resizeFileStorage:function(node,newSize){if(node.usedBytes==newSize)return;if(newSize==0){node.contents=null;node.usedBytes=0;return}if(!node.contents||node.contents.subarray){var oldContents=node.contents;node.contents=new Uint8Array(newSize);if(oldContents){node.contents.set(oldContents.subarray(0,Math.min(newSize,node.usedBytes)))}node.usedBytes=newSize;return}if(!node.contents)node.contents=[];if(node.contents.length>newSize)node.contents.length=newSize;else while(node.contents.length<newSize)node.contents.push(0);node.usedBytes=newSize},node_ops:{getattr:function(node){var attr={};attr.dev=FS.isChrdev(node.mode)?node.id:1;attr.ino=node.id;attr.mode=node.mode;attr.nlink=1;attr.uid=0;attr.gid=0;attr.rdev=node.rdev;if(FS.isDir(node.mode)){attr.size=4096}else if(FS.isFile(node.mode)){attr.size=node.usedBytes}else if(FS.isLink(node.mode)){attr.size=node.link.length}else{attr.size=0}attr.atime=new Date(node.timestamp);attr.mtime=new Date(node.timestamp);attr.ctime=new Date(node.timestamp);attr.blksize=4096;attr.blocks=Math.ceil(attr.size/attr.blksize);return attr},setattr:function(node,attr){if(attr.mode!==undefined){node.mode=attr.mode}if(attr.timestamp!==undefined){node.timestamp=attr.timestamp}if(attr.size!==undefined){MEMFS.resizeFileStorage(node,attr.size)}},lookup:function(parent,name){throw FS.genericErrors[44]},mknod:function(parent,name,mode,dev){return MEMFS.createNode(parent,name,mode,dev)},rename:function(old_node,new_dir,new_name){if(FS.isDir(old_node.mode)){var new_node;try{new_node=FS.lookupNode(new_dir,new_name)}catch(e){}if(new_node){for(var i in new_node.contents){throw new FS.ErrnoError(55)}}}delete old_node.parent.contents[old_node.name];old_node.name=new_name;new_dir.contents[new_name]=old_node;old_node.parent=new_dir},unlink:function(parent,name){delete parent.contents[name]},rmdir:function(parent,name){var node=FS.lookupNode(parent,name);for(var i in node.contents){throw new FS.ErrnoError(55)}delete parent.contents[name]},readdir:function(node){var entries=[".",".."];for(var key in node.contents){if(!node.contents.hasOwnProperty(key)){continue}entries.push(key)}return entries},symlink:function(parent,newname,oldpath){var node=MEMFS.createNode(parent,newname,511|40960,0);node.link=oldpath;return node},readlink:function(node){if(!FS.isLink(node.mode)){throw new FS.ErrnoError(28)}return node.link}},stream_ops:{read:function(stream,buffer,offset,length,position){var contents=stream.node.contents;if(position>=stream.node.usedBytes)return 0;var size=Math.min(stream.node.usedBytes-position,length);if(size>8&&contents.subarray){buffer.set(contents.subarray(position,position+size),offset)}else{for(var i=0;i<size;i++)buffer[offset+i]=contents[position+i]}return size},write:function(stream,buffer,offset,length,position,canOwn){if(buffer.buffer===HEAP8.buffer){canOwn=false}if(!length)return 0;var node=stream.node;node.timestamp=Date.now();if(buffer.subarray&&(!node.contents||node.contents.subarray)){if(canOwn){node.contents=buffer.subarray(offset,offset+length);node.usedBytes=length;return length}else if(node.usedBytes===0&&position===0){node.contents=buffer.slice(offset,offset+length);node.usedBytes=length;return length}else if(position+length<=node.usedBytes){node.contents.set(buffer.subarray(offset,offset+length),position);return length}}MEMFS.expandFileStorage(node,position+length);if(node.contents.subarray&&buffer.subarray){node.contents.set(buffer.subarray(offset,offset+length),position)}else{for(var i=0;i<length;i++){node.contents[position+i]=buffer[offset+i]}}node.usedBytes=Math.max(node.usedBytes,position+length);return length},llseek:function(stream,offset,whence){var position=offset;if(whence===1){position+=stream.position}else if(whence===2){if(FS.isFile(stream.node.mode)){position+=stream.node.usedBytes}}if(position<0){throw new FS.ErrnoError(28)}return position},allocate:function(stream,offset,length){MEMFS.expandFileStorage(stream.node,offset+length);stream.node.usedBytes=Math.max(stream.node.usedBytes,offset+length)},mmap:function(stream,address,length,position,prot,flags){assert(address===0);if(!FS.isFile(stream.node.mode)){throw new FS.ErrnoError(43)}var ptr;var allocated;var contents=stream.node.contents;if(!(flags&2)&&contents.buffer===buffer){allocated=false;ptr=contents.byteOffset}else{if(position>0||position+length<contents.length){if(contents.subarray){contents=contents.subarray(position,position+length)}else{contents=Array.prototype.slice.call(contents,position,position+length)}}allocated=true;ptr=mmapAlloc(length);if(!ptr){throw new FS.ErrnoError(48)}HEAP8.set(contents,ptr)}return{ptr:ptr,allocated:allocated}},msync:function(stream,buffer,offset,length,mmapFlags){if(!FS.isFile(stream.node.mode)){throw new FS.ErrnoError(43)}if(mmapFlags&2){return 0}var bytesWritten=MEMFS.stream_ops.write(stream,buffer,0,length,offset,false);return 0}}};var FS={root:null,mounts:[],devices:{},streams:[],nextInode:1,nameTable:null,currentPath:"/",initialized:false,ignorePermissions:true,trackingDelegate:{},tracking:{openFlags:{READ:1,WRITE:2}},ErrnoError:null,genericErrors:{},filesystems:null,syncFSRequests:0,lookupPath:function(path,opts){path=PATH_FS.resolve(FS.cwd(),path);opts=opts||{};if(!path)return{path:"",node:null};var defaults={follow_mount:true,recurse_count:0};for(var key in defaults){if(opts[key]===undefined){opts[key]=defaults[key]}}if(opts.recurse_count>8){throw new FS.ErrnoError(32)}var parts=PATH.normalizeArray(path.split("/").filter(function(p){return!!p}),false);var current=FS.root;var current_path="/";for(var i=0;i<parts.length;i++){var islast=i===parts.length-1;if(islast&&opts.parent){break}current=FS.lookupNode(current,parts[i]);current_path=PATH.join2(current_path,parts[i]);if(FS.isMountpoint(current)){if(!islast||islast&&opts.follow_mount){current=current.mounted.root}}if(!islast||opts.follow){var count=0;while(FS.isLink(current.mode)){var link=FS.readlink(current_path);current_path=PATH_FS.resolve(PATH.dirname(current_path),link);var lookup=FS.lookupPath(current_path,{recurse_count:opts.recurse_count});current=lookup.node;if(count++>40){throw new FS.ErrnoError(32)}}}}return{path:current_path,node:current}},getPath:function(node){var path;while(true){if(FS.isRoot(node)){var mount=node.mount.mountpoint;if(!path)return mount;return mount[mount.length-1]!=="/"?mount+"/"+path:mount+path}path=path?node.name+"/"+path:node.name;node=node.parent}},hashName:function(parentid,name){var hash=0;for(var i=0;i<name.length;i++){hash=(hash<<5)-hash+name.charCodeAt(i)|0}return(parentid+hash>>>0)%FS.nameTable.length},hashAddNode:function(node){var hash=FS.hashName(node.parent.id,node.name);node.name_next=FS.nameTable[hash];FS.nameTable[hash]=node},hashRemoveNode:function(node){var hash=FS.hashName(node.parent.id,node.name);if(FS.nameTable[hash]===node){FS.nameTable[hash]=node.name_next}else{var current=FS.nameTable[hash];while(current){if(current.name_next===node){current.name_next=node.name_next;break}current=current.name_next}}},lookupNode:function(parent,name){var errCode=FS.mayLookup(parent);if(errCode){throw new FS.ErrnoError(errCode,parent)}var hash=FS.hashName(parent.id,name);for(var node=FS.nameTable[hash];node;node=node.name_next){var nodeName=node.name;if(node.parent.id===parent.id&&nodeName===name){return node}}return FS.lookup(parent,name)},createNode:function(parent,name,mode,rdev){var node=new FS.FSNode(parent,name,mode,rdev);FS.hashAddNode(node);return node},destroyNode:function(node){FS.hashRemoveNode(node)},isRoot:function(node){return node===node.parent},isMountpoint:function(node){return!!node.mounted},isFile:function(mode){return(mode&61440)===32768},isDir:function(mode){return(mode&61440)===16384},isLink:function(mode){return(mode&61440)===40960},isChrdev:function(mode){return(mode&61440)===8192},isBlkdev:function(mode){return(mode&61440)===24576},isFIFO:function(mode){return(mode&61440)===4096},isSocket:function(mode){return(mode&49152)===49152},flagModes:{"r":0,"r+":2,"w":577,"w+":578,"a":1089,"a+":1090},modeStringToFlags:function(str){var flags=FS.flagModes[str];if(typeof flags==="undefined"){throw new Error("Unknown file open mode: "+str)}return flags},flagsToPermissionString:function(flag){var perms=["r","w","rw"][flag&3];if(flag&512){perms+="w"}return perms},nodePermissions:function(node,perms){if(FS.ignorePermissions){return 0}if(perms.indexOf("r")!==-1&&!(node.mode&292)){return 2}else if(perms.indexOf("w")!==-1&&!(node.mode&146)){return 2}else if(perms.indexOf("x")!==-1&&!(node.mode&73)){return 2}return 0},mayLookup:function(dir){var errCode=FS.nodePermissions(dir,"x");if(errCode)return errCode;if(!dir.node_ops.lookup)return 2;return 0},mayCreate:function(dir,name){try{var node=FS.lookupNode(dir,name);return 20}catch(e){}return FS.nodePermissions(dir,"wx")},mayDelete:function(dir,name,isdir){var node;try{node=FS.lookupNode(dir,name)}catch(e){return e.errno}var errCode=FS.nodePermissions(dir,"wx");if(errCode){return errCode}if(isdir){if(!FS.isDir(node.mode)){return 54}if(FS.isRoot(node)||FS.getPath(node)===FS.cwd()){return 10}}else{if(FS.isDir(node.mode)){return 31}}return 0},mayOpen:function(node,flags){if(!node){return 44}if(FS.isLink(node.mode)){return 32}else if(FS.isDir(node.mode)){if(FS.flagsToPermissionString(flags)!=="r"||flags&512){return 31}}return FS.nodePermissions(node,FS.flagsToPermissionString(flags))},MAX_OPEN_FDS:4096,nextfd:function(fd_start,fd_end){fd_start=fd_start||0;fd_end=fd_end||FS.MAX_OPEN_FDS;for(var fd=fd_start;fd<=fd_end;fd++){if(!FS.streams[fd]){return fd}}throw new FS.ErrnoError(33)},getStream:function(fd){return FS.streams[fd]},createStream:function(stream,fd_start,fd_end){if(!FS.FSStream){FS.FSStream=function(){};FS.FSStream.prototype={object:{get:function(){return this.node},set:function(val){this.node=val}},isRead:{get:function(){return(this.flags&2097155)!==1}},isWrite:{get:function(){return(this.flags&2097155)!==0}},isAppend:{get:function(){return this.flags&1024}}}}var newStream=new FS.FSStream;for(var p in stream){newStream[p]=stream[p]}stream=newStream;var fd=FS.nextfd(fd_start,fd_end);stream.fd=fd;FS.streams[fd]=stream;return stream},closeStream:function(fd){FS.streams[fd]=null},chrdev_stream_ops:{open:function(stream){var device=FS.getDevice(stream.node.rdev);stream.stream_ops=device.stream_ops;if(stream.stream_ops.open){stream.stream_ops.open(stream)}},llseek:function(){throw new FS.ErrnoError(70)}},major:function(dev){return dev>>8},minor:function(dev){return dev&255},makedev:function(ma,mi){return ma<<8|mi},registerDevice:function(dev,ops){FS.devices[dev]={stream_ops:ops}},getDevice:function(dev){return FS.devices[dev]},getMounts:function(mount){var mounts=[];var check=[mount];while(check.length){var m=check.pop();mounts.push(m);check.push.apply(check,m.mounts)}return mounts},syncfs:function(populate,callback){if(typeof populate==="function"){callback=populate;populate=false}FS.syncFSRequests++;if(FS.syncFSRequests>1){err("warning: "+FS.syncFSRequests+" FS.syncfs operations in flight at once, probably just doing extra work")}var mounts=FS.getMounts(FS.root.mount);var completed=0;function doCallback(errCode){FS.syncFSRequests--;return callback(errCode)}function done(errCode){if(errCode){if(!done.errored){done.errored=true;return doCallback(errCode)}return}if(++completed>=mounts.length){doCallback(null)}}mounts.forEach(function(mount){if(!mount.type.syncfs){return done(null)}mount.type.syncfs(mount,populate,done)})},mount:function(type,opts,mountpoint){var root=mountpoint==="/";var pseudo=!mountpoint;var node;if(root&&FS.root){throw new FS.ErrnoError(10)}else if(!root&&!pseudo){var lookup=FS.lookupPath(mountpoint,{follow_mount:false});mountpoint=lookup.path;node=lookup.node;if(FS.isMountpoint(node)){throw new FS.ErrnoError(10)}if(!FS.isDir(node.mode)){throw new FS.ErrnoError(54)}}var mount={type:type,opts:opts,mountpoint:mountpoint,mounts:[]};var mountRoot=type.mount(mount);mountRoot.mount=mount;mount.root=mountRoot;if(root){FS.root=mountRoot}else if(node){node.mounted=mount;if(node.mount){node.mount.mounts.push(mount)}}return mountRoot},unmount:function(mountpoint){var lookup=FS.lookupPath(mountpoint,{follow_mount:false});if(!FS.isMountpoint(lookup.node)){throw new FS.ErrnoError(28)}var node=lookup.node;var mount=node.mounted;var mounts=FS.getMounts(mount);Object.keys(FS.nameTable).forEach(function(hash){var current=FS.nameTable[hash];while(current){var next=current.name_next;if(mounts.indexOf(current.mount)!==-1){FS.destroyNode(current)}current=next}});node.mounted=null;var idx=node.mount.mounts.indexOf(mount);node.mount.mounts.splice(idx,1)},lookup:function(parent,name){return parent.node_ops.lookup(parent,name)},mknod:function(path,mode,dev){var lookup=FS.lookupPath(path,{parent:true});var parent=lookup.node;var name=PATH.basename(path);if(!name||name==="."||name===".."){throw new FS.ErrnoError(28)}var errCode=FS.mayCreate(parent,name);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.mknod){throw new FS.ErrnoError(63)}return parent.node_ops.mknod(parent,name,mode,dev)},create:function(path,mode){mode=mode!==undefined?mode:438;mode&=4095;mode|=32768;return FS.mknod(path,mode,0)},mkdir:function(path,mode){mode=mode!==undefined?mode:511;mode&=511|512;mode|=16384;return FS.mknod(path,mode,0)},mkdirTree:function(path,mode){var dirs=path.split("/");var d="";for(var i=0;i<dirs.length;++i){if(!dirs[i])continue;d+="/"+dirs[i];try{FS.mkdir(d,mode)}catch(e){if(e.errno!=20)throw e}}},mkdev:function(path,mode,dev){if(typeof dev==="undefined"){dev=mode;mode=438}mode|=8192;return FS.mknod(path,mode,dev)},symlink:function(oldpath,newpath){if(!PATH_FS.resolve(oldpath)){throw new FS.ErrnoError(44)}var lookup=FS.lookupPath(newpath,{parent:true});var parent=lookup.node;if(!parent){throw new FS.ErrnoError(44)}var newname=PATH.basename(newpath);var errCode=FS.mayCreate(parent,newname);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.symlink){throw new FS.ErrnoError(63)}return parent.node_ops.symlink(parent,newname,oldpath)},rename:function(old_path,new_path){var old_dirname=PATH.dirname(old_path);var new_dirname=PATH.dirname(new_path);var old_name=PATH.basename(old_path);var new_name=PATH.basename(new_path);var lookup,old_dir,new_dir;lookup=FS.lookupPath(old_path,{parent:true});old_dir=lookup.node;lookup=FS.lookupPath(new_path,{parent:true});new_dir=lookup.node;if(!old_dir||!new_dir)throw new FS.ErrnoError(44);if(old_dir.mount!==new_dir.mount){throw new FS.ErrnoError(75)}var old_node=FS.lookupNode(old_dir,old_name);var relative=PATH_FS.relative(old_path,new_dirname);if(relative.charAt(0)!=="."){throw new FS.ErrnoError(28)}relative=PATH_FS.relative(new_path,old_dirname);if(relative.charAt(0)!=="."){throw new FS.ErrnoError(55)}var new_node;try{new_node=FS.lookupNode(new_dir,new_name)}catch(e){}if(old_node===new_node){return}var isdir=FS.isDir(old_node.mode);var errCode=FS.mayDelete(old_dir,old_name,isdir);if(errCode){throw new FS.ErrnoError(errCode)}errCode=new_node?FS.mayDelete(new_dir,new_name,isdir):FS.mayCreate(new_dir,new_name);if(errCode){throw new FS.ErrnoError(errCode)}if(!old_dir.node_ops.rename){throw new FS.ErrnoError(63)}if(FS.isMountpoint(old_node)||new_node&&FS.isMountpoint(new_node)){throw new FS.ErrnoError(10)}if(new_dir!==old_dir){errCode=FS.nodePermissions(old_dir,"w");if(errCode){throw new FS.ErrnoError(errCode)}}try{if(FS.trackingDelegate["willMovePath"]){FS.trackingDelegate["willMovePath"](old_path,new_path)}}catch(e){err("FS.trackingDelegate['willMovePath']('"+old_path+"', '"+new_path+"') threw an exception: "+e.message)}FS.hashRemoveNode(old_node);try{old_dir.node_ops.rename(old_node,new_dir,new_name)}catch(e){throw e}finally{FS.hashAddNode(old_node)}try{if(FS.trackingDelegate["onMovePath"])FS.trackingDelegate["onMovePath"](old_path,new_path)}catch(e){err("FS.trackingDelegate['onMovePath']('"+old_path+"', '"+new_path+"') threw an exception: "+e.message)}},rmdir:function(path){var lookup=FS.lookupPath(path,{parent:true});var parent=lookup.node;var name=PATH.basename(path);var node=FS.lookupNode(parent,name);var errCode=FS.mayDelete(parent,name,true);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.rmdir){throw new FS.ErrnoError(63)}if(FS.isMountpoint(node)){throw new FS.ErrnoError(10)}try{if(FS.trackingDelegate["willDeletePath"]){FS.trackingDelegate["willDeletePath"](path)}}catch(e){err("FS.trackingDelegate['willDeletePath']('"+path+"') threw an exception: "+e.message)}parent.node_ops.rmdir(parent,name);FS.destroyNode(node);try{if(FS.trackingDelegate["onDeletePath"])FS.trackingDelegate["onDeletePath"](path)}catch(e){err("FS.trackingDelegate['onDeletePath']('"+path+"') threw an exception: "+e.message)}},readdir:function(path){var lookup=FS.lookupPath(path,{follow:true});var node=lookup.node;if(!node.node_ops.readdir){throw new FS.ErrnoError(54)}return node.node_ops.readdir(node)},unlink:function(path){var lookup=FS.lookupPath(path,{parent:true});var parent=lookup.node;var name=PATH.basename(path);var node=FS.lookupNode(parent,name);var errCode=FS.mayDelete(parent,name,false);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.unlink){throw new FS.ErrnoError(63)}if(FS.isMountpoint(node)){throw new FS.ErrnoError(10)}try{if(FS.trackingDelegate["willDeletePath"]){FS.trackingDelegate["willDeletePath"](path)}}catch(e){err("FS.trackingDelegate['willDeletePath']('"+path+"') threw an exception: "+e.message)}parent.node_ops.unlink(parent,name);FS.destroyNode(node);try{if(FS.trackingDelegate["onDeletePath"])FS.trackingDelegate["onDeletePath"](path)}catch(e){err("FS.trackingDelegate['onDeletePath']('"+path+"') threw an exception: "+e.message)}},readlink:function(path){var lookup=FS.lookupPath(path);var link=lookup.node;if(!link){throw new FS.ErrnoError(44)}if(!link.node_ops.readlink){throw new FS.ErrnoError(28)}return PATH_FS.resolve(FS.getPath(link.parent),link.node_ops.readlink(link))},stat:function(path,dontFollow){var lookup=FS.lookupPath(path,{follow:!dontFollow});var node=lookup.node;if(!node){throw new FS.ErrnoError(44)}if(!node.node_ops.getattr){throw new FS.ErrnoError(63)}return node.node_ops.getattr(node)},lstat:function(path){return FS.stat(path,true)},chmod:function(path,mode,dontFollow){var node;if(typeof path==="string"){var lookup=FS.lookupPath(path,{follow:!dontFollow});node=lookup.node}else{node=path}if(!node.node_ops.setattr){throw new FS.ErrnoError(63)}node.node_ops.setattr(node,{mode:mode&4095|node.mode&~4095,timestamp:Date.now()})},lchmod:function(path,mode){FS.chmod(path,mode,true)},fchmod:function(fd,mode){var stream=FS.getStream(fd);if(!stream){throw new FS.ErrnoError(8)}FS.chmod(stream.node,mode)},chown:function(path,uid,gid,dontFollow){var node;if(typeof path==="string"){var lookup=FS.lookupPath(path,{follow:!dontFollow});node=lookup.node}else{node=path}if(!node.node_ops.setattr){throw new FS.ErrnoError(63)}node.node_ops.setattr(node,{timestamp:Date.now()})},lchown:function(path,uid,gid){FS.chown(path,uid,gid,true)},fchown:function(fd,uid,gid){var stream=FS.getStream(fd);if(!stream){throw new FS.ErrnoError(8)}FS.chown(stream.node,uid,gid)},truncate:function(path,len){if(len<0){throw new FS.ErrnoError(28)}var node;if(typeof path==="string"){var lookup=FS.lookupPath(path,{follow:true});node=lookup.node}else{node=path}if(!node.node_ops.setattr){throw new FS.ErrnoError(63)}if(FS.isDir(node.mode)){throw new FS.ErrnoError(31)}if(!FS.isFile(node.mode)){throw new FS.ErrnoError(28)}var errCode=FS.nodePermissions(node,"w");if(errCode){throw new FS.ErrnoError(errCode)}node.node_ops.setattr(node,{size:len,timestamp:Date.now()})},ftruncate:function(fd,len){var stream=FS.getStream(fd);if(!stream){throw new FS.ErrnoError(8)}if((stream.flags&2097155)===0){throw new FS.ErrnoError(28)}FS.truncate(stream.node,len)},utime:function(path,atime,mtime){var lookup=FS.lookupPath(path,{follow:true});var node=lookup.node;node.node_ops.setattr(node,{timestamp:Math.max(atime,mtime)})},open:function(path,flags,mode,fd_start,fd_end){if(path===""){throw new FS.ErrnoError(44)}flags=typeof flags==="string"?FS.modeStringToFlags(flags):flags;mode=typeof mode==="undefined"?438:mode;if(flags&64){mode=mode&4095|32768}else{mode=0}var node;if(typeof path==="object"){node=path}else{path=PATH.normalize(path);try{var lookup=FS.lookupPath(path,{follow:!(flags&131072)});node=lookup.node}catch(e){}}var created=false;if(flags&64){if(node){if(flags&128){throw new FS.ErrnoError(20)}}else{node=FS.mknod(path,mode,0);created=true}}if(!node){throw new FS.ErrnoError(44)}if(FS.isChrdev(node.mode)){flags&=~512}if(flags&65536&&!FS.isDir(node.mode)){throw new FS.ErrnoError(54)}if(!created){var errCode=FS.mayOpen(node,flags);if(errCode){throw new FS.ErrnoError(errCode)}}if(flags&512){FS.truncate(node,0)}flags&=~(128|512|131072);var stream=FS.createStream({node:node,path:FS.getPath(node),flags:flags,seekable:true,position:0,stream_ops:node.stream_ops,ungotten:[],error:false},fd_start,fd_end);if(stream.stream_ops.open){stream.stream_ops.open(stream)}if(Module["logReadFiles"]&&!(flags&1)){if(!FS.readFiles)FS.readFiles={};if(!(path in FS.readFiles)){FS.readFiles[path]=1;err("FS.trackingDelegate error on read file: "+path)}}try{if(FS.trackingDelegate["onOpenFile"]){var trackingFlags=0;if((flags&2097155)!==1){trackingFlags|=FS.tracking.openFlags.READ}if((flags&2097155)!==0){trackingFlags|=FS.tracking.openFlags.WRITE}FS.trackingDelegate["onOpenFile"](path,trackingFlags)}}catch(e){err("FS.trackingDelegate['onOpenFile']('"+path+"', flags) threw an exception: "+e.message)}return stream},close:function(stream){if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if(stream.getdents)stream.getdents=null;try{if(stream.stream_ops.close){stream.stream_ops.close(stream)}}catch(e){throw e}finally{FS.closeStream(stream.fd)}stream.fd=null},isClosed:function(stream){return stream.fd===null},llseek:function(stream,offset,whence){if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if(!stream.seekable||!stream.stream_ops.llseek){throw new FS.ErrnoError(70)}if(whence!=0&&whence!=1&&whence!=2){throw new FS.ErrnoError(28)}stream.position=stream.stream_ops.llseek(stream,offset,whence);stream.ungotten=[];return stream.position},read:function(stream,buffer,offset,length,position){if(length<0||position<0){throw new FS.ErrnoError(28)}if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if((stream.flags&2097155)===1){throw new FS.ErrnoError(8)}if(FS.isDir(stream.node.mode)){throw new FS.ErrnoError(31)}if(!stream.stream_ops.read){throw new FS.ErrnoError(28)}var seeking=typeof position!=="undefined";if(!seeking){position=stream.position}else if(!stream.seekable){throw new FS.ErrnoError(70)}var bytesRead=stream.stream_ops.read(stream,buffer,offset,length,position);if(!seeking)stream.position+=bytesRead;return bytesRead},write:function(stream,buffer,offset,length,position,canOwn){if(length<0||position<0){throw new FS.ErrnoError(28)}if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if((stream.flags&2097155)===0){throw new FS.ErrnoError(8)}if(FS.isDir(stream.node.mode)){throw new FS.ErrnoError(31)}if(!stream.stream_ops.write){throw new FS.ErrnoError(28)}if(stream.seekable&&stream.flags&1024){FS.llseek(stream,0,2)}var seeking=typeof position!=="undefined";if(!seeking){position=stream.position}else if(!stream.seekable){throw new FS.ErrnoError(70)}var bytesWritten=stream.stream_ops.write(stream,buffer,offset,length,position,canOwn);if(!seeking)stream.position+=bytesWritten;try{if(stream.path&&FS.trackingDelegate["onWriteToFile"])FS.trackingDelegate["onWriteToFile"](stream.path)}catch(e){err("FS.trackingDelegate['onWriteToFile']('"+stream.path+"') threw an exception: "+e.message)}return bytesWritten},allocate:function(stream,offset,length){if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if(offset<0||length<=0){throw new FS.ErrnoError(28)}if((stream.flags&2097155)===0){throw new FS.ErrnoError(8)}if(!FS.isFile(stream.node.mode)&&!FS.isDir(stream.node.mode)){throw new FS.ErrnoError(43)}if(!stream.stream_ops.allocate){throw new FS.ErrnoError(138)}stream.stream_ops.allocate(stream,offset,length)},mmap:function(stream,address,length,position,prot,flags){if((prot&2)!==0&&(flags&2)===0&&(stream.flags&2097155)!==2){throw new FS.ErrnoError(2)}if((stream.flags&2097155)===1){throw new FS.ErrnoError(2)}if(!stream.stream_ops.mmap){throw new FS.ErrnoError(43)}return stream.stream_ops.mmap(stream,address,length,position,prot,flags)},msync:function(stream,buffer,offset,length,mmapFlags){if(!stream||!stream.stream_ops.msync){return 0}return stream.stream_ops.msync(stream,buffer,offset,length,mmapFlags)},munmap:function(stream){return 0},ioctl:function(stream,cmd,arg){if(!stream.stream_ops.ioctl){throw new FS.ErrnoError(59)}return stream.stream_ops.ioctl(stream,cmd,arg)},readFile:function(path,opts){opts=opts||{};opts.flags=opts.flags||0;opts.encoding=opts.encoding||"binary";if(opts.encoding!=="utf8"&&opts.encoding!=="binary"){throw new Error('Invalid encoding type "'+opts.encoding+'"')}var ret;var stream=FS.open(path,opts.flags);var stat=FS.stat(path);var length=stat.size;var buf=new Uint8Array(length);FS.read(stream,buf,0,length,0);if(opts.encoding==="utf8"){ret=UTF8ArrayToString(buf,0)}else if(opts.encoding==="binary"){ret=buf}FS.close(stream);return ret},writeFile:function(path,data,opts){opts=opts||{};opts.flags=opts.flags||577;var stream=FS.open(path,opts.flags,opts.mode);if(typeof data==="string"){var buf=new Uint8Array(lengthBytesUTF8(data)+1);var actualNumBytes=stringToUTF8Array(data,buf,0,buf.length);FS.write(stream,buf,0,actualNumBytes,undefined,opts.canOwn)}else if(ArrayBuffer.isView(data)){FS.write(stream,data,0,data.byteLength,undefined,opts.canOwn)}else{throw new Error("Unsupported data type")}FS.close(stream)},cwd:function(){return FS.currentPath},chdir:function(path){var lookup=FS.lookupPath(path,{follow:true});if(lookup.node===null){throw new FS.ErrnoError(44)}if(!FS.isDir(lookup.node.mode)){throw new FS.ErrnoError(54)}var errCode=FS.nodePermissions(lookup.node,"x");if(errCode){throw new FS.ErrnoError(errCode)}FS.currentPath=lookup.path},createDefaultDirectories:function(){FS.mkdir("/tmp");FS.mkdir("/home");FS.mkdir("/home/web_user")},createDefaultDevices:function(){FS.mkdir("/dev");FS.registerDevice(FS.makedev(1,3),{read:function(){return 0},write:function(stream,buffer,offset,length,pos){return length}});FS.mkdev("/dev/null",FS.makedev(1,3));TTY.register(FS.makedev(5,0),TTY.default_tty_ops);TTY.register(FS.makedev(6,0),TTY.default_tty1_ops);FS.mkdev("/dev/tty",FS.makedev(5,0));FS.mkdev("/dev/tty1",FS.makedev(6,0));var random_device=getRandomDevice();FS.createDevice("/dev","random",random_device);FS.createDevice("/dev","urandom",random_device);FS.mkdir("/dev/shm");FS.mkdir("/dev/shm/tmp")},createSpecialDirectories:function(){FS.mkdir("/proc");FS.mkdir("/proc/self");FS.mkdir("/proc/self/fd");FS.mount({mount:function(){var node=FS.createNode("/proc/self","fd",16384|511,73);node.node_ops={lookup:function(parent,name){var fd=+name;var stream=FS.getStream(fd);if(!stream)throw new FS.ErrnoError(8);var ret={parent:null,mount:{mountpoint:"fake"},node_ops:{readlink:function(){return stream.path}}};ret.parent=ret;return ret}};return node}},{},"/proc/self/fd")},createStandardStreams:function(){if(Module["stdin"]){FS.createDevice("/dev","stdin",Module["stdin"])}else{FS.symlink("/dev/tty","/dev/stdin")}if(Module["stdout"]){FS.createDevice("/dev","stdout",null,Module["stdout"])}else{FS.symlink("/dev/tty","/dev/stdout")}if(Module["stderr"]){FS.createDevice("/dev","stderr",null,Module["stderr"])}else{FS.symlink("/dev/tty1","/dev/stderr")}var stdin=FS.open("/dev/stdin",0);var stdout=FS.open("/dev/stdout",1);var stderr=FS.open("/dev/stderr",1)},ensureErrnoError:function(){if(FS.ErrnoError)return;FS.ErrnoError=function ErrnoError(errno,node){this.node=node;this.setErrno=function(errno){this.errno=errno};this.setErrno(errno);this.message="FS error"};FS.ErrnoError.prototype=new Error;FS.ErrnoError.prototype.constructor=FS.ErrnoError;[44].forEach(function(code){FS.genericErrors[code]=new FS.ErrnoError(code);FS.genericErrors[code].stack="<generic error, no stack>"})},staticInit:function(){FS.ensureErrnoError();FS.nameTable=new Array(4096);FS.mount(MEMFS,{},"/");FS.createDefaultDirectories();FS.createDefaultDevices();FS.createSpecialDirectories();FS.filesystems={"MEMFS":MEMFS}},init:function(input,output,error){FS.init.initialized=true;FS.ensureErrnoError();Module["stdin"]=input||Module["stdin"];Module["stdout"]=output||Module["stdout"];Module["stderr"]=error||Module["stderr"];FS.createStandardStreams()},quit:function(){FS.init.initialized=false;var fflush=Module["_fflush"];if(fflush)fflush(0);for(var i=0;i<FS.streams.length;i++){var stream=FS.streams[i];if(!stream){continue}FS.close(stream)}},getMode:function(canRead,canWrite){var mode=0;if(canRead)mode|=292|73;if(canWrite)mode|=146;return mode},findObject:function(path,dontResolveLastLink){var ret=FS.analyzePath(path,dontResolveLastLink);if(ret.exists){return ret.object}else{return null}},analyzePath:function(path,dontResolveLastLink){try{var lookup=FS.lookupPath(path,{follow:!dontResolveLastLink});path=lookup.path}catch(e){}var ret={isRoot:false,exists:false,error:0,name:null,path:null,object:null,parentExists:false,parentPath:null,parentObject:null};try{var lookup=FS.lookupPath(path,{parent:true});ret.parentExists=true;ret.parentPath=lookup.path;ret.parentObject=lookup.node;ret.name=PATH.basename(path);lookup=FS.lookupPath(path,{follow:!dontResolveLastLink});ret.exists=true;ret.path=lookup.path;ret.object=lookup.node;ret.name=lookup.node.name;ret.isRoot=lookup.path==="/"}catch(e){ret.error=e.errno}return ret},createPath:function(parent,path,canRead,canWrite){parent=typeof parent==="string"?parent:FS.getPath(parent);var parts=path.split("/").reverse();while(parts.length){var part=parts.pop();if(!part)continue;var current=PATH.join2(parent,part);try{FS.mkdir(current)}catch(e){}parent=current}return current},createFile:function(parent,name,properties,canRead,canWrite){var path=PATH.join2(typeof parent==="string"?parent:FS.getPath(parent),name);var mode=FS.getMode(canRead,canWrite);return FS.create(path,mode)},createDataFile:function(parent,name,data,canRead,canWrite,canOwn){var path=name?PATH.join2(typeof parent==="string"?parent:FS.getPath(parent),name):parent;var mode=FS.getMode(canRead,canWrite);var node=FS.create(path,mode);if(data){if(typeof data==="string"){var arr=new Array(data.length);for(var i=0,len=data.length;i<len;++i)arr[i]=data.charCodeAt(i);data=arr}FS.chmod(node,mode|146);var stream=FS.open(node,577);FS.write(stream,data,0,data.length,0,canOwn);FS.close(stream);FS.chmod(node,mode)}return node},createDevice:function(parent,name,input,output){var path=PATH.join2(typeof parent==="string"?parent:FS.getPath(parent),name);var mode=FS.getMode(!!input,!!output);if(!FS.createDevice.major)FS.createDevice.major=64;var dev=FS.makedev(FS.createDevice.major++,0);FS.registerDevice(dev,{open:function(stream){stream.seekable=false},close:function(stream){if(output&&output.buffer&&output.buffer.length){output(10)}},read:function(stream,buffer,offset,length,pos){var bytesRead=0;for(var i=0;i<length;i++){var result;try{result=input()}catch(e){throw new FS.ErrnoError(29)}if(result===undefined&&bytesRead===0){throw new FS.ErrnoError(6)}if(result===null||result===undefined)break;bytesRead++;buffer[offset+i]=result}if(bytesRead){stream.node.timestamp=Date.now()}return bytesRead},write:function(stream,buffer,offset,length,pos){for(var i=0;i<length;i++){try{output(buffer[offset+i])}catch(e){throw new FS.ErrnoError(29)}}if(length){stream.node.timestamp=Date.now()}return i}});return FS.mkdev(path,mode,dev)},forceLoadFile:function(obj){if(obj.isDevice||obj.isFolder||obj.link||obj.contents)return true;if(typeof XMLHttpRequest!=="undefined"){throw new Error("Lazy loading should have been performed (contents set) in createLazyFile, but it was not. Lazy loading only works in web workers. Use --embed-file or --preload-file in emcc on the main thread.")}else if(read_){try{obj.contents=intArrayFromString(read_(obj.url),true);obj.usedBytes=obj.contents.length}catch(e){throw new FS.ErrnoError(29)}}else{throw new Error("Cannot load without read() or XMLHttpRequest.")}},createLazyFile:function(parent,name,url,canRead,canWrite){function LazyUint8Array(){this.lengthKnown=false;this.chunks=[]}LazyUint8Array.prototype.get=function LazyUint8Array_get(idx){if(idx>this.length-1||idx<0){return undefined}var chunkOffset=idx%this.chunkSize;var chunkNum=idx/this.chunkSize|0;return this.getter(chunkNum)[chunkOffset]};LazyUint8Array.prototype.setDataGetter=function LazyUint8Array_setDataGetter(getter){this.getter=getter};LazyUint8Array.prototype.cacheLength=function LazyUint8Array_cacheLength(){var xhr=new XMLHttpRequest;xhr.open("HEAD",url,false);xhr.send(null);if(!(xhr.status>=200&&xhr.status<300||xhr.status===304))throw new Error("Couldn't load "+url+". Status: "+xhr.status);var datalength=Number(xhr.getResponseHeader("Content-length"));var header;var hasByteServing=(header=xhr.getResponseHeader("Accept-Ranges"))&&header==="bytes";var usesGzip=(header=xhr.getResponseHeader("Content-Encoding"))&&header==="gzip";var chunkSize=1024*1024;if(!hasByteServing)chunkSize=datalength;var doXHR=function(from,to){if(from>to)throw new Error("invalid range ("+from+", "+to+") or no bytes requested!");if(to>datalength-1)throw new Error("only "+datalength+" bytes available! programmer error!");var xhr=new XMLHttpRequest;xhr.open("GET",url,false);if(datalength!==chunkSize)xhr.setRequestHeader("Range","bytes="+from+"-"+to);if(typeof Uint8Array!="undefined")xhr.responseType="arraybuffer";if(xhr.overrideMimeType){xhr.overrideMimeType("text/plain; charset=x-user-defined")}xhr.send(null);if(!(xhr.status>=200&&xhr.status<300||xhr.status===304))throw new Error("Couldn't load "+url+". Status: "+xhr.status);if(xhr.response!==undefined){return new Uint8Array(xhr.response||[])}else{return intArrayFromString(xhr.responseText||"",true)}};var lazyArray=this;lazyArray.setDataGetter(function(chunkNum){var start=chunkNum*chunkSize;var end=(chunkNum+1)*chunkSize-1;end=Math.min(end,datalength-1);if(typeof lazyArray.chunks[chunkNum]==="undefined"){lazyArray.chunks[chunkNum]=doXHR(start,end)}if(typeof lazyArray.chunks[chunkNum]==="undefined")throw new Error("doXHR failed!");return lazyArray.chunks[chunkNum]});if(usesGzip||!datalength){chunkSize=datalength=1;datalength=this.getter(0).length;chunkSize=datalength;out("LazyFiles on gzip forces download of the whole file when length is accessed")}this._length=datalength;this._chunkSize=chunkSize;this.lengthKnown=true};if(typeof XMLHttpRequest!=="undefined"){if(!ENVIRONMENT_IS_WORKER)throw"Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc";var lazyArray=new LazyUint8Array;Object.defineProperties(lazyArray,{length:{get:function(){if(!this.lengthKnown){this.cacheLength()}return this._length}},chunkSize:{get:function(){if(!this.lengthKnown){this.cacheLength()}return this._chunkSize}}});var properties={isDevice:false,contents:lazyArray}}else{var properties={isDevice:false,url:url}}var node=FS.createFile(parent,name,properties,canRead,canWrite);if(properties.contents){node.contents=properties.contents}else if(properties.url){node.contents=null;node.url=properties.url}Object.defineProperties(node,{usedBytes:{get:function(){return this.contents.length}}});var stream_ops={};var keys=Object.keys(node.stream_ops);keys.forEach(function(key){var fn=node.stream_ops[key];stream_ops[key]=function forceLoadLazyFile(){FS.forceLoadFile(node);return fn.apply(null,arguments)}});stream_ops.read=function stream_ops_read(stream,buffer,offset,length,position){FS.forceLoadFile(node);var contents=stream.node.contents;if(position>=contents.length)return 0;var size=Math.min(contents.length-position,length);if(contents.slice){for(var i=0;i<size;i++){buffer[offset+i]=contents[position+i]}}else{for(var i=0;i<size;i++){buffer[offset+i]=contents.get(position+i)}}return size};node.stream_ops=stream_ops;return node},createPreloadedFile:function(parent,name,url,canRead,canWrite,onload,onerror,dontCreateFile,canOwn,preFinish){Browser.init();var fullname=name?PATH_FS.resolve(PATH.join2(parent,name)):parent;var dep=getUniqueRunDependency("cp "+fullname);function processData(byteArray){function finish(byteArray){if(preFinish)preFinish();if(!dontCreateFile){FS.createDataFile(parent,name,byteArray,canRead,canWrite,canOwn)}if(onload)onload();removeRunDependency(dep)}var handled=false;Module["preloadPlugins"].forEach(function(plugin){if(handled)return;if(plugin["canHandle"](fullname)){plugin["handle"](byteArray,fullname,finish,function(){if(onerror)onerror();removeRunDependency(dep)});handled=true}});if(!handled)finish(byteArray)}addRunDependency(dep);if(typeof url=="string"){Browser.asyncLoad(url,function(byteArray){processData(byteArray)},onerror)}else{processData(url)}},indexedDB:function(){return window.indexedDB||window.mozIndexedDB||window.webkitIndexedDB||window.msIndexedDB},DB_NAME:function(){return"EM_FS_"+window.location.pathname},DB_VERSION:20,DB_STORE_NAME:"FILE_DATA",saveFilesToDB:function(paths,onload,onerror){onload=onload||function(){};onerror=onerror||function(){};var indexedDB=FS.indexedDB();try{var openRequest=indexedDB.open(FS.DB_NAME(),FS.DB_VERSION)}catch(e){return onerror(e)}openRequest.onupgradeneeded=function openRequest_onupgradeneeded(){out("creating db");var db=openRequest.result;db.createObjectStore(FS.DB_STORE_NAME)};openRequest.onsuccess=function openRequest_onsuccess(){var db=openRequest.result;var transaction=db.transaction([FS.DB_STORE_NAME],"readwrite");var files=transaction.objectStore(FS.DB_STORE_NAME);var ok=0,fail=0,total=paths.length;function finish(){if(fail==0)onload();else onerror()}paths.forEach(function(path){var putRequest=files.put(FS.analyzePath(path).object.contents,path);putRequest.onsuccess=function putRequest_onsuccess(){ok++;if(ok+fail==total)finish()};putRequest.onerror=function putRequest_onerror(){fail++;if(ok+fail==total)finish()}});transaction.onerror=onerror};openRequest.onerror=onerror},loadFilesFromDB:function(paths,onload,onerror){onload=onload||function(){};onerror=onerror||function(){};var indexedDB=FS.indexedDB();try{var openRequest=indexedDB.open(FS.DB_NAME(),FS.DB_VERSION)}catch(e){return onerror(e)}openRequest.onupgradeneeded=onerror;openRequest.onsuccess=function openRequest_onsuccess(){var db=openRequest.result;try{var transaction=db.transaction([FS.DB_STORE_NAME],"readonly")}catch(e){onerror(e);return}var files=transaction.objectStore(FS.DB_STORE_NAME);var ok=0,fail=0,total=paths.length;function finish(){if(fail==0)onload();else onerror()}paths.forEach(function(path){var getRequest=files.get(path);getRequest.onsuccess=function getRequest_onsuccess(){if(FS.analyzePath(path).exists){FS.unlink(path)}FS.createDataFile(PATH.dirname(path),PATH.basename(path),getRequest.result,true,true,true);ok++;if(ok+fail==total)finish()};getRequest.onerror=function getRequest_onerror(){fail++;if(ok+fail==total)finish()}});transaction.onerror=onerror};openRequest.onerror=onerror}};var SYSCALLS={mappings:{},DEFAULT_POLLMASK:5,umask:511,calculateAt:function(dirfd,path){if(path[0]!=="/"){var dir;if(dirfd===-100){dir=FS.cwd()}else{var dirstream=FS.getStream(dirfd);if(!dirstream)throw new FS.ErrnoError(8);dir=dirstream.path}path=PATH.join2(dir,path)}return path},doStat:function(func,path,buf){try{var stat=func(path)}catch(e){if(e&&e.node&&PATH.normalize(path)!==PATH.normalize(FS.getPath(e.node))){return-54}throw e}HEAP32[buf>>2]=stat.dev;HEAP32[buf+4>>2]=0;HEAP32[buf+8>>2]=stat.ino;HEAP32[buf+12>>2]=stat.mode;HEAP32[buf+16>>2]=stat.nlink;HEAP32[buf+20>>2]=stat.uid;HEAP32[buf+24>>2]=stat.gid;HEAP32[buf+28>>2]=stat.rdev;HEAP32[buf+32>>2]=0;tempI64=[stat.size>>>0,(tempDouble=stat.size,+Math.abs(tempDouble)>=1?tempDouble>0?(Math.min(+Math.floor(tempDouble/4294967296),4294967295)|0)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[buf+40>>2]=tempI64[0],HEAP32[buf+44>>2]=tempI64[1];HEAP32[buf+48>>2]=4096;HEAP32[buf+52>>2]=stat.blocks;HEAP32[buf+56>>2]=stat.atime.getTime()/1e3|0;HEAP32[buf+60>>2]=0;HEAP32[buf+64>>2]=stat.mtime.getTime()/1e3|0;HEAP32[buf+68>>2]=0;HEAP32[buf+72>>2]=stat.ctime.getTime()/1e3|0;HEAP32[buf+76>>2]=0;tempI64=[stat.ino>>>0,(tempDouble=stat.ino,+Math.abs(tempDouble)>=1?tempDouble>0?(Math.min(+Math.floor(tempDouble/4294967296),4294967295)|0)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[buf+80>>2]=tempI64[0],HEAP32[buf+84>>2]=tempI64[1];return 0},doMsync:function(addr,stream,len,flags,offset){var buffer=HEAPU8.slice(addr,addr+len);FS.msync(stream,buffer,offset,len,flags)},doMkdir:function(path,mode){path=PATH.normalize(path);if(path[path.length-1]==="/")path=path.substr(0,path.length-1);FS.mkdir(path,mode,0);return 0},doMknod:function(path,mode,dev){switch(mode&61440){case 32768:case 8192:case 24576:case 4096:case 49152:break;default:return-28}FS.mknod(path,mode,dev);return 0},doReadlink:function(path,buf,bufsize){if(bufsize<=0)return-28;var ret=FS.readlink(path);var len=Math.min(bufsize,lengthBytesUTF8(ret));var endChar=HEAP8[buf+len];stringToUTF8(ret,buf,bufsize+1);HEAP8[buf+len]=endChar;return len},doAccess:function(path,amode){if(amode&~7){return-28}var node;var lookup=FS.lookupPath(path,{follow:true});node=lookup.node;if(!node){return-44}var perms="";if(amode&4)perms+="r";if(amode&2)perms+="w";if(amode&1)perms+="x";if(perms&&FS.nodePermissions(node,perms)){return-2}return 0},doDup:function(path,flags,suggestFD){var suggest=FS.getStream(suggestFD);if(suggest)FS.close(suggest);return FS.open(path,flags,0,suggestFD,suggestFD).fd},doReadv:function(stream,iov,iovcnt,offset){var ret=0;for(var i=0;i<iovcnt;i++){var ptr=HEAP32[iov+i*8>>2];var len=HEAP32[iov+(i*8+4)>>2];var curr=FS.read(stream,HEAP8,ptr,len,offset);if(curr<0)return-1;ret+=curr;if(curr<len)break}return ret},doWritev:function(stream,iov,iovcnt,offset){var ret=0;for(var i=0;i<iovcnt;i++){var ptr=HEAP32[iov+i*8>>2];var len=HEAP32[iov+(i*8+4)>>2];var curr=FS.write(stream,HEAP8,ptr,len,offset);if(curr<0)return-1;ret+=curr}return ret},varargs:undefined,get:function(){SYSCALLS.varargs+=4;var ret=HEAP32[SYSCALLS.varargs-4>>2];return ret},getStr:function(ptr){var ret=UTF8ToString(ptr);return ret},getStreamFromFD:function(fd){var stream=FS.getStream(fd);if(!stream)throw new FS.ErrnoError(8);return stream},get64:function(low,high){return low}};function ___sys_fcntl64(fd,cmd,varargs){SYSCALLS.varargs=varargs;try{var stream=SYSCALLS.getStreamFromFD(fd);switch(cmd){case 0:{var arg=SYSCALLS.get();if(arg<0){return-28}var newStream;newStream=FS.open(stream.path,stream.flags,0,arg);return newStream.fd}case 1:case 2:return 0;case 3:return stream.flags;case 4:{var arg=SYSCALLS.get();stream.flags|=arg;return 0}case 12:{var arg=SYSCALLS.get();var offset=0;HEAP16[arg+offset>>1]=2;return 0}case 13:case 14:return 0;case 16:case 8:return-28;case 9:setErrNo(28);return-1;default:{return-28}}}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return-e.errno}}function ___sys_ioctl(fd,op,varargs){SYSCALLS.varargs=varargs;try{var stream=SYSCALLS.getStreamFromFD(fd);switch(op){case 21509:case 21505:{if(!stream.tty)return-59;return 0}case 21510:case 21511:case 21512:case 21506:case 21507:case 21508:{if(!stream.tty)return-59;return 0}case 21519:{if(!stream.tty)return-59;var argp=SYSCALLS.get();HEAP32[argp>>2]=0;return 0}case 21520:{if(!stream.tty)return-59;return-28}case 21531:{var argp=SYSCALLS.get();return FS.ioctl(stream,op,argp)}case 21523:{if(!stream.tty)return-59;return 0}case 21524:{if(!stream.tty)return-59;return 0}default:abort("bad ioctl syscall "+op)}}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return-e.errno}}function ___sys_open(path,flags,varargs){SYSCALLS.varargs=varargs;try{var pathname=SYSCALLS.getStr(path);var mode=SYSCALLS.get();var stream=FS.open(pathname,flags,mode);return stream.fd}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return-e.errno}}var structRegistrations={};function runDestructors(destructors){while(destructors.length){var ptr=destructors.pop();var del=destructors.pop();del(ptr)}}function simpleReadValueFromPointer(pointer){return this["fromWireType"](HEAPU32[pointer>>2])}var awaitingDependencies={};var registeredTypes={};var typeDependencies={};var char_0=48;var char_9=57;function makeLegalFunctionName(name){if(undefined===name){return"_unknown"}name=name.replace(/[^a-zA-Z0-9_]/g,"$");var f=name.charCodeAt(0);if(f>=char_0&&f<=char_9){return"_"+name}else{return name}}function createNamedFunction(name,body){name=makeLegalFunctionName(name);return new Function("body","return function "+name+"() {\n"+'    "use strict";'+"    return body.apply(this, arguments);\n"+"};\n")(body)}function extendError(baseErrorType,errorName){var errorClass=createNamedFunction(errorName,function(message){this.name=errorName;this.message=message;var stack=new Error(message).stack;if(stack!==undefined){this.stack=this.toString()+"\n"+stack.replace(/^Error(:[^\n]*)?\n/,"")}});errorClass.prototype=Object.create(baseErrorType.prototype);errorClass.prototype.constructor=errorClass;errorClass.prototype.toString=function(){if(this.message===undefined){return this.name}else{return this.name+": "+this.message}};return errorClass}var InternalError=undefined;function throwInternalError(message){throw new InternalError(message)}function whenDependentTypesAreResolved(myTypes,dependentTypes,getTypeConverters){myTypes.forEach(function(type){typeDependencies[type]=dependentTypes});function onComplete(typeConverters){var myTypeConverters=getTypeConverters(typeConverters);if(myTypeConverters.length!==myTypes.length){throwInternalError("Mismatched type converter count")}for(var i=0;i<myTypes.length;++i){registerType(myTypes[i],myTypeConverters[i])}}var typeConverters=new Array(dependentTypes.length);var unregisteredTypes=[];var registered=0;dependentTypes.forEach(function(dt,i){if(registeredTypes.hasOwnProperty(dt)){typeConverters[i]=registeredTypes[dt]}else{unregisteredTypes.push(dt);if(!awaitingDependencies.hasOwnProperty(dt)){awaitingDependencies[dt]=[]}awaitingDependencies[dt].push(function(){typeConverters[i]=registeredTypes[dt];++registered;if(registered===unregisteredTypes.length){onComplete(typeConverters)}})}});if(0===unregisteredTypes.length){onComplete(typeConverters)}}function __embind_finalize_value_object(structType){var reg=structRegistrations[structType];delete structRegistrations[structType];var rawConstructor=reg.rawConstructor;var rawDestructor=reg.rawDestructor;var fieldRecords=reg.fields;var fieldTypes=fieldRecords.map(function(field){return field.getterReturnType}).concat(fieldRecords.map(function(field){return field.setterArgumentType}));whenDependentTypesAreResolved([structType],fieldTypes,function(fieldTypes){var fields={};fieldRecords.forEach(function(field,i){var fieldName=field.fieldName;var getterReturnType=fieldTypes[i];var getter=field.getter;var getterContext=field.getterContext;var setterArgumentType=fieldTypes[i+fieldRecords.length];var setter=field.setter;var setterContext=field.setterContext;fields[fieldName]={read:function(ptr){return getterReturnType["fromWireType"](getter(getterContext,ptr))},write:function(ptr,o){var destructors=[];setter(setterContext,ptr,setterArgumentType["toWireType"](destructors,o));runDestructors(destructors)}}});return[{name:reg.name,"fromWireType":function(ptr){var rv={};for(var i in fields){rv[i]=fields[i].read(ptr)}rawDestructor(ptr);return rv},"toWireType":function(destructors,o){for(var fieldName in fields){if(!(fieldName in o)){throw new TypeError('Missing field:  "'+fieldName+'"')}}var ptr=rawConstructor();for(fieldName in fields){fields[fieldName].write(ptr,o[fieldName])}if(destructors!==null){destructors.push(rawDestructor,ptr)}return ptr},"argPackAdvance":8,"readValueFromPointer":simpleReadValueFromPointer,destructorFunction:rawDestructor}]})}function getShiftFromSize(size){switch(size){case 1:return 0;case 2:return 1;case 4:return 2;case 8:return 3;default:throw new TypeError("Unknown type size: "+size)}}function embind_init_charCodes(){var codes=new Array(256);for(var i=0;i<256;++i){codes[i]=String.fromCharCode(i)}embind_charCodes=codes}var embind_charCodes=undefined;function readLatin1String(ptr){var ret="";var c=ptr;while(HEAPU8[c]){ret+=embind_charCodes[HEAPU8[c++]]}return ret}var BindingError=undefined;function throwBindingError(message){throw new BindingError(message)}function registerType(rawType,registeredInstance,options){options=options||{};if(!("argPackAdvance"in registeredInstance)){throw new TypeError("registerType registeredInstance requires argPackAdvance")}var name=registeredInstance.name;if(!rawType){throwBindingError('type "'+name+'" must have a positive integer typeid pointer')}if(registeredTypes.hasOwnProperty(rawType)){if(options.ignoreDuplicateRegistrations){return}else{throwBindingError("Cannot register type '"+name+"' twice")}}registeredTypes[rawType]=registeredInstance;delete typeDependencies[rawType];if(awaitingDependencies.hasOwnProperty(rawType)){var callbacks=awaitingDependencies[rawType];delete awaitingDependencies[rawType];callbacks.forEach(function(cb){cb()})}}function __embind_register_bool(rawType,name,size,trueValue,falseValue){var shift=getShiftFromSize(size);name=readLatin1String(name);registerType(rawType,{name:name,"fromWireType":function(wt){return!!wt},"toWireType":function(destructors,o){return o?trueValue:falseValue},"argPackAdvance":8,"readValueFromPointer":function(pointer){var heap;if(size===1){heap=HEAP8}else if(size===2){heap=HEAP16}else if(size===4){heap=HEAP32}else{throw new TypeError("Unknown boolean type size: "+name)}return this["fromWireType"](heap[pointer>>shift])},destructorFunction:null})}function ClassHandle_isAliasOf(other){if(!(this instanceof ClassHandle)){return false}if(!(other instanceof ClassHandle)){return false}var leftClass=this.$$.ptrType.registeredClass;var left=this.$$.ptr;var rightClass=other.$$.ptrType.registeredClass;var right=other.$$.ptr;while(leftClass.baseClass){left=leftClass.upcast(left);leftClass=leftClass.baseClass}while(rightClass.baseClass){right=rightClass.upcast(right);rightClass=rightClass.baseClass}return leftClass===rightClass&&left===right}function shallowCopyInternalPointer(o){return{count:o.count,deleteScheduled:o.deleteScheduled,preservePointerOnDelete:o.preservePointerOnDelete,ptr:o.ptr,ptrType:o.ptrType,smartPtr:o.smartPtr,smartPtrType:o.smartPtrType}}function throwInstanceAlreadyDeleted(obj){function getInstanceTypeName(handle){return handle.$$.ptrType.registeredClass.name}throwBindingError(getInstanceTypeName(obj)+" instance already deleted")}var finalizationGroup=false;function detachFinalizer(handle){}function runDestructor($$){if($$.smartPtr){$$.smartPtrType.rawDestructor($$.smartPtr)}else{$$.ptrType.registeredClass.rawDestructor($$.ptr)}}function releaseClassHandle($$){$$.count.value-=1;var toDelete=0===$$.count.value;if(toDelete){runDestructor($$)}}function attachFinalizer(handle){if("undefined"===typeof FinalizationGroup){attachFinalizer=function(handle){return handle};return handle}finalizationGroup=new FinalizationGroup(function(iter){for(var result=iter.next();!result.done;result=iter.next()){var $$=result.value;if(!$$.ptr){console.warn("object already deleted: "+$$.ptr)}else{releaseClassHandle($$)}}});attachFinalizer=function(handle){finalizationGroup.register(handle,handle.$$,handle.$$);return handle};detachFinalizer=function(handle){finalizationGroup.unregister(handle.$$)};return attachFinalizer(handle)}function ClassHandle_clone(){if(!this.$$.ptr){throwInstanceAlreadyDeleted(this)}if(this.$$.preservePointerOnDelete){this.$$.count.value+=1;return this}else{var clone=attachFinalizer(Object.create(Object.getPrototypeOf(this),{$$:{value:shallowCopyInternalPointer(this.$$)}}));clone.$$.count.value+=1;clone.$$.deleteScheduled=false;return clone}}function ClassHandle_delete(){if(!this.$$.ptr){throwInstanceAlreadyDeleted(this)}if(this.$$.deleteScheduled&&!this.$$.preservePointerOnDelete){throwBindingError("Object already scheduled for deletion")}detachFinalizer(this);releaseClassHandle(this.$$);if(!this.$$.preservePointerOnDelete){this.$$.smartPtr=undefined;this.$$.ptr=undefined}}function ClassHandle_isDeleted(){return!this.$$.ptr}var delayFunction=undefined;var deletionQueue=[];function flushPendingDeletes(){while(deletionQueue.length){var obj=deletionQueue.pop();obj.$$.deleteScheduled=false;obj["delete"]()}}function ClassHandle_deleteLater(){if(!this.$$.ptr){throwInstanceAlreadyDeleted(this)}if(this.$$.deleteScheduled&&!this.$$.preservePointerOnDelete){throwBindingError("Object already scheduled for deletion")}deletionQueue.push(this);if(deletionQueue.length===1&&delayFunction){delayFunction(flushPendingDeletes)}this.$$.deleteScheduled=true;return this}function init_ClassHandle(){ClassHandle.prototype["isAliasOf"]=ClassHandle_isAliasOf;ClassHandle.prototype["clone"]=ClassHandle_clone;ClassHandle.prototype["delete"]=ClassHandle_delete;ClassHandle.prototype["isDeleted"]=ClassHandle_isDeleted;ClassHandle.prototype["deleteLater"]=ClassHandle_deleteLater}function ClassHandle(){}var registeredPointers={};function ensureOverloadTable(proto,methodName,humanName){if(undefined===proto[methodName].overloadTable){var prevFunc=proto[methodName];proto[methodName]=function(){if(!proto[methodName].overloadTable.hasOwnProperty(arguments.length)){throwBindingError("Function '"+humanName+"' called with an invalid number of arguments ("+arguments.length+") - expects one of ("+proto[methodName].overloadTable+")!")}return proto[methodName].overloadTable[arguments.length].apply(this,arguments)};proto[methodName].overloadTable=[];proto[methodName].overloadTable[prevFunc.argCount]=prevFunc}}function exposePublicSymbol(name,value,numArguments){if(Module.hasOwnProperty(name)){if(undefined===numArguments||undefined!==Module[name].overloadTable&&undefined!==Module[name].overloadTable[numArguments]){throwBindingError("Cannot register public name '"+name+"' twice")}ensureOverloadTable(Module,name,name);if(Module.hasOwnProperty(numArguments)){throwBindingError("Cannot register multiple overloads of a function with the same number of arguments ("+numArguments+")!")}Module[name].overloadTable[numArguments]=value}else{Module[name]=value;if(undefined!==numArguments){Module[name].numArguments=numArguments}}}function RegisteredClass(name,constructor,instancePrototype,rawDestructor,baseClass,getActualType,upcast,downcast){this.name=name;this.constructor=constructor;this.instancePrototype=instancePrototype;this.rawDestructor=rawDestructor;this.baseClass=baseClass;this.getActualType=getActualType;this.upcast=upcast;this.downcast=downcast;this.pureVirtualFunctions=[]}function upcastPointer(ptr,ptrClass,desiredClass){while(ptrClass!==desiredClass){if(!ptrClass.upcast){throwBindingError("Expected null or instance of "+desiredClass.name+", got an instance of "+ptrClass.name)}ptr=ptrClass.upcast(ptr);ptrClass=ptrClass.baseClass}return ptr}function constNoSmartPtrRawPointerToWireType(destructors,handle){if(handle===null){if(this.isReference){throwBindingError("null is not a valid "+this.name)}return 0}if(!handle.$$){throwBindingError('Cannot pass "'+_embind_repr(handle)+'" as a '+this.name)}if(!handle.$$.ptr){throwBindingError("Cannot pass deleted object as a pointer of type "+this.name)}var handleClass=handle.$$.ptrType.registeredClass;var ptr=upcastPointer(handle.$$.ptr,handleClass,this.registeredClass);return ptr}function genericPointerToWireType(destructors,handle){var ptr;if(handle===null){if(this.isReference){throwBindingError("null is not a valid "+this.name)}if(this.isSmartPointer){ptr=this.rawConstructor();if(destructors!==null){destructors.push(this.rawDestructor,ptr)}return ptr}else{return 0}}if(!handle.$$){throwBindingError('Cannot pass "'+_embind_repr(handle)+'" as a '+this.name)}if(!handle.$$.ptr){throwBindingError("Cannot pass deleted object as a pointer of type "+this.name)}if(!this.isConst&&handle.$$.ptrType.isConst){throwBindingError("Cannot convert argument of type "+(handle.$$.smartPtrType?handle.$$.smartPtrType.name:handle.$$.ptrType.name)+" to parameter type "+this.name)}var handleClass=handle.$$.ptrType.registeredClass;ptr=upcastPointer(handle.$$.ptr,handleClass,this.registeredClass);if(this.isSmartPointer){if(undefined===handle.$$.smartPtr){throwBindingError("Passing raw pointer to smart pointer is illegal")}switch(this.sharingPolicy){case 0:if(handle.$$.smartPtrType===this){ptr=handle.$$.smartPtr}else{throwBindingError("Cannot convert argument of type "+(handle.$$.smartPtrType?handle.$$.smartPtrType.name:handle.$$.ptrType.name)+" to parameter type "+this.name)}break;case 1:ptr=handle.$$.smartPtr;break;case 2:if(handle.$$.smartPtrType===this){ptr=handle.$$.smartPtr}else{var clonedHandle=handle["clone"]();ptr=this.rawShare(ptr,__emval_register(function(){clonedHandle["delete"]()}));if(destructors!==null){destructors.push(this.rawDestructor,ptr)}}break;default:throwBindingError("Unsupporting sharing policy")}}return ptr}function nonConstNoSmartPtrRawPointerToWireType(destructors,handle){if(handle===null){if(this.isReference){throwBindingError("null is not a valid "+this.name)}return 0}if(!handle.$$){throwBindingError('Cannot pass "'+_embind_repr(handle)+'" as a '+this.name)}if(!handle.$$.ptr){throwBindingError("Cannot pass deleted object as a pointer of type "+this.name)}if(handle.$$.ptrType.isConst){throwBindingError("Cannot convert argument of type "+handle.$$.ptrType.name+" to parameter type "+this.name)}var handleClass=handle.$$.ptrType.registeredClass;var ptr=upcastPointer(handle.$$.ptr,handleClass,this.registeredClass);return ptr}function RegisteredPointer_getPointee(ptr){if(this.rawGetPointee){ptr=this.rawGetPointee(ptr)}return ptr}function RegisteredPointer_destructor(ptr){if(this.rawDestructor){this.rawDestructor(ptr)}}function RegisteredPointer_deleteObject(handle){if(handle!==null){handle["delete"]()}}function downcastPointer(ptr,ptrClass,desiredClass){if(ptrClass===desiredClass){return ptr}if(undefined===desiredClass.baseClass){return null}var rv=downcastPointer(ptr,ptrClass,desiredClass.baseClass);if(rv===null){return null}return desiredClass.downcast(rv)}function getInheritedInstanceCount(){return Object.keys(registeredInstances).length}function getLiveInheritedInstances(){var rv=[];for(var k in registeredInstances){if(registeredInstances.hasOwnProperty(k)){rv.push(registeredInstances[k])}}return rv}function setDelayFunction(fn){delayFunction=fn;if(deletionQueue.length&&delayFunction){delayFunction(flushPendingDeletes)}}function init_embind(){Module["getInheritedInstanceCount"]=getInheritedInstanceCount;Module["getLiveInheritedInstances"]=getLiveInheritedInstances;Module["flushPendingDeletes"]=flushPendingDeletes;Module["setDelayFunction"]=setDelayFunction}var registeredInstances={};function getBasestPointer(class_,ptr){if(ptr===undefined){throwBindingError("ptr should not be undefined")}while(class_.baseClass){ptr=class_.upcast(ptr);class_=class_.baseClass}return ptr}function getInheritedInstance(class_,ptr){ptr=getBasestPointer(class_,ptr);return registeredInstances[ptr]}function makeClassHandle(prototype,record){if(!record.ptrType||!record.ptr){throwInternalError("makeClassHandle requires ptr and ptrType")}var hasSmartPtrType=!!record.smartPtrType;var hasSmartPtr=!!record.smartPtr;if(hasSmartPtrType!==hasSmartPtr){throwInternalError("Both smartPtrType and smartPtr must be specified")}record.count={value:1};return attachFinalizer(Object.create(prototype,{$$:{value:record}}))}function RegisteredPointer_fromWireType(ptr){var rawPointer=this.getPointee(ptr);if(!rawPointer){this.destructor(ptr);return null}var registeredInstance=getInheritedInstance(this.registeredClass,rawPointer);if(undefined!==registeredInstance){if(0===registeredInstance.$$.count.value){registeredInstance.$$.ptr=rawPointer;registeredInstance.$$.smartPtr=ptr;return registeredInstance["clone"]()}else{var rv=registeredInstance["clone"]();this.destructor(ptr);return rv}}function makeDefaultHandle(){if(this.isSmartPointer){return makeClassHandle(this.registeredClass.instancePrototype,{ptrType:this.pointeeType,ptr:rawPointer,smartPtrType:this,smartPtr:ptr})}else{return makeClassHandle(this.registeredClass.instancePrototype,{ptrType:this,ptr:ptr})}}var actualType=this.registeredClass.getActualType(rawPointer);var registeredPointerRecord=registeredPointers[actualType];if(!registeredPointerRecord){return makeDefaultHandle.call(this)}var toType;if(this.isConst){toType=registeredPointerRecord.constPointerType}else{toType=registeredPointerRecord.pointerType}var dp=downcastPointer(rawPointer,this.registeredClass,toType.registeredClass);if(dp===null){return makeDefaultHandle.call(this)}if(this.isSmartPointer){return makeClassHandle(toType.registeredClass.instancePrototype,{ptrType:toType,ptr:dp,smartPtrType:this,smartPtr:ptr})}else{return makeClassHandle(toType.registeredClass.instancePrototype,{ptrType:toType,ptr:dp})}}function init_RegisteredPointer(){RegisteredPointer.prototype.getPointee=RegisteredPointer_getPointee;RegisteredPointer.prototype.destructor=RegisteredPointer_destructor;RegisteredPointer.prototype["argPackAdvance"]=8;RegisteredPointer.prototype["readValueFromPointer"]=simpleReadValueFromPointer;RegisteredPointer.prototype["deleteObject"]=RegisteredPointer_deleteObject;RegisteredPointer.prototype["fromWireType"]=RegisteredPointer_fromWireType}function RegisteredPointer(name,registeredClass,isReference,isConst,isSmartPointer,pointeeType,sharingPolicy,rawGetPointee,rawConstructor,rawShare,rawDestructor){this.name=name;this.registeredClass=registeredClass;this.isReference=isReference;this.isConst=isConst;this.isSmartPointer=isSmartPointer;this.pointeeType=pointeeType;this.sharingPolicy=sharingPolicy;this.rawGetPointee=rawGetPointee;this.rawConstructor=rawConstructor;this.rawShare=rawShare;this.rawDestructor=rawDestructor;if(!isSmartPointer&&registeredClass.baseClass===undefined){if(isConst){this["toWireType"]=constNoSmartPtrRawPointerToWireType;this.destructorFunction=null}else{this["toWireType"]=nonConstNoSmartPtrRawPointerToWireType;this.destructorFunction=null}}else{this["toWireType"]=genericPointerToWireType}}function replacePublicSymbol(name,value,numArguments){if(!Module.hasOwnProperty(name)){throwInternalError("Replacing nonexistant public symbol")}if(undefined!==Module[name].overloadTable&&undefined!==numArguments){Module[name].overloadTable[numArguments]=value}else{Module[name]=value;Module[name].argCount=numArguments}}function dynCallLegacy(sig,ptr,args){if(args&&args.length){return Module["dynCall_"+sig].apply(null,[ptr].concat(args))}return Module["dynCall_"+sig].call(null,ptr)}function dynCall(sig,ptr,args){if(sig.indexOf("j")!=-1){return dynCallLegacy(sig,ptr,args)}return wasmTable.get(ptr).apply(null,args)}function getDynCaller(sig,ptr){assert(sig.indexOf("j")>=0,"getDynCaller should only be called with i64 sigs");var argCache=[];return function(){argCache.length=arguments.length;for(var i=0;i<arguments.length;i++){argCache[i]=arguments[i]}return dynCall(sig,ptr,argCache)}}function embind__requireFunction(signature,rawFunction){signature=readLatin1String(signature);function makeDynCaller(){if(signature.indexOf("j")!=-1){return getDynCaller(signature,rawFunction)}return wasmTable.get(rawFunction)}var fp=makeDynCaller();if(typeof fp!=="function"){throwBindingError("unknown function pointer with signature "+signature+": "+rawFunction)}return fp}var UnboundTypeError=undefined;function getTypeName(type){var ptr=___getTypeName(type);var rv=readLatin1String(ptr);_free(ptr);return rv}function throwUnboundTypeError(message,types){var unboundTypes=[];var seen={};function visit(type){if(seen[type]){return}if(registeredTypes[type]){return}if(typeDependencies[type]){typeDependencies[type].forEach(visit);return}unboundTypes.push(type);seen[type]=true}types.forEach(visit);throw new UnboundTypeError(message+": "+unboundTypes.map(getTypeName).join([", "]))}function __embind_register_class(rawType,rawPointerType,rawConstPointerType,baseClassRawType,getActualTypeSignature,getActualType,upcastSignature,upcast,downcastSignature,downcast,name,destructorSignature,rawDestructor){name=readLatin1String(name);getActualType=embind__requireFunction(getActualTypeSignature,getActualType);if(upcast){upcast=embind__requireFunction(upcastSignature,upcast)}if(downcast){downcast=embind__requireFunction(downcastSignature,downcast)}rawDestructor=embind__requireFunction(destructorSignature,rawDestructor);var legalFunctionName=makeLegalFunctionName(name);exposePublicSymbol(legalFunctionName,function(){throwUnboundTypeError("Cannot construct "+name+" due to unbound types",[baseClassRawType])});whenDependentTypesAreResolved([rawType,rawPointerType,rawConstPointerType],baseClassRawType?[baseClassRawType]:[],function(base){base=base[0];var baseClass;var basePrototype;if(baseClassRawType){baseClass=base.registeredClass;basePrototype=baseClass.instancePrototype}else{basePrototype=ClassHandle.prototype}var constructor=createNamedFunction(legalFunctionName,function(){if(Object.getPrototypeOf(this)!==instancePrototype){throw new BindingError("Use 'new' to construct "+name)}if(undefined===registeredClass.constructor_body){throw new BindingError(name+" has no accessible constructor")}var body=registeredClass.constructor_body[arguments.length];if(undefined===body){throw new BindingError("Tried to invoke ctor of "+name+" with invalid number of parameters ("+arguments.length+") - expected ("+Object.keys(registeredClass.constructor_body).toString()+") parameters instead!")}return body.apply(this,arguments)});var instancePrototype=Object.create(basePrototype,{constructor:{value:constructor}});constructor.prototype=instancePrototype;var registeredClass=new RegisteredClass(name,constructor,instancePrototype,rawDestructor,baseClass,getActualType,upcast,downcast);var referenceConverter=new RegisteredPointer(name,registeredClass,true,false,false);var pointerConverter=new RegisteredPointer(name+"*",registeredClass,false,false,false);var constPointerConverter=new RegisteredPointer(name+" const*",registeredClass,false,true,false);registeredPointers[rawType]={pointerType:pointerConverter,constPointerType:constPointerConverter};replacePublicSymbol(legalFunctionName,constructor);return[referenceConverter,pointerConverter,constPointerConverter]})}function heap32VectorToArray(count,firstElement){var array=[];for(var i=0;i<count;i++){array.push(HEAP32[(firstElement>>2)+i])}return array}function __embind_register_class_constructor(rawClassType,argCount,rawArgTypesAddr,invokerSignature,invoker,rawConstructor){assert(argCount>0);var rawArgTypes=heap32VectorToArray(argCount,rawArgTypesAddr);invoker=embind__requireFunction(invokerSignature,invoker);var args=[rawConstructor];var destructors=[];whenDependentTypesAreResolved([],[rawClassType],function(classType){classType=classType[0];var humanName="constructor "+classType.name;if(undefined===classType.registeredClass.constructor_body){classType.registeredClass.constructor_body=[]}if(undefined!==classType.registeredClass.constructor_body[argCount-1]){throw new BindingError("Cannot register multiple constructors with identical number of parameters ("+(argCount-1)+") for class '"+classType.name+"'! Overload resolution is currently only performed using the parameter count, not actual type info!")}classType.registeredClass.constructor_body[argCount-1]=function unboundTypeHandler(){throwUnboundTypeError("Cannot construct "+classType.name+" due to unbound types",rawArgTypes)};whenDependentTypesAreResolved([],rawArgTypes,function(argTypes){classType.registeredClass.constructor_body[argCount-1]=function constructor_body(){if(arguments.length!==argCount-1){throwBindingError(humanName+" called with "+arguments.length+" arguments, expected "+(argCount-1))}destructors.length=0;args.length=argCount;for(var i=1;i<argCount;++i){args[i]=argTypes[i]["toWireType"](destructors,arguments[i-1])}var ptr=invoker.apply(null,args);runDestructors(destructors);return argTypes[0]["fromWireType"](ptr)};return[]});return[]})}function new_(constructor,argumentList){if(!(constructor instanceof Function)){throw new TypeError("new_ called with constructor type "+typeof constructor+" which is not a function")}var dummy=createNamedFunction(constructor.name||"unknownFunctionName",function(){});dummy.prototype=constructor.prototype;var obj=new dummy;var r=constructor.apply(obj,argumentList);return r instanceof Object?r:obj}function craftInvokerFunction(humanName,argTypes,classType,cppInvokerFunc,cppTargetFunc){var argCount=argTypes.length;if(argCount<2){throwBindingError("argTypes array size mismatch! Must at least get return value and 'this' types!")}var isClassMethodFunc=argTypes[1]!==null&&classType!==null;var needsDestructorStack=false;for(var i=1;i<argTypes.length;++i){if(argTypes[i]!==null&&argTypes[i].destructorFunction===undefined){needsDestructorStack=true;break}}var returns=argTypes[0].name!=="void";var argsList="";var argsListWired="";for(var i=0;i<argCount-2;++i){argsList+=(i!==0?", ":"")+"arg"+i;argsListWired+=(i!==0?", ":"")+"arg"+i+"Wired"}var invokerFnBody="return function "+makeLegalFunctionName(humanName)+"("+argsList+") {\n"+"if (arguments.length !== "+(argCount-2)+") {\n"+"throwBindingError('function "+humanName+" called with ' + arguments.length + ' arguments, expected "+(argCount-2)+" args!');\n"+"}\n";if(needsDestructorStack){invokerFnBody+="var destructors = [];\n"}var dtorStack=needsDestructorStack?"destructors":"null";var args1=["throwBindingError","invoker","fn","runDestructors","retType","classParam"];var args2=[throwBindingError,cppInvokerFunc,cppTargetFunc,runDestructors,argTypes[0],argTypes[1]];if(isClassMethodFunc){invokerFnBody+="var thisWired = classParam.toWireType("+dtorStack+", this);\n"}for(var i=0;i<argCount-2;++i){invokerFnBody+="var arg"+i+"Wired = argType"+i+".toWireType("+dtorStack+", arg"+i+"); // "+argTypes[i+2].name+"\n";args1.push("argType"+i);args2.push(argTypes[i+2])}if(isClassMethodFunc){argsListWired="thisWired"+(argsListWired.length>0?", ":"")+argsListWired}invokerFnBody+=(returns?"var rv = ":"")+"invoker(fn"+(argsListWired.length>0?", ":"")+argsListWired+");\n";if(needsDestructorStack){invokerFnBody+="runDestructors(destructors);\n"}else{for(var i=isClassMethodFunc?1:2;i<argTypes.length;++i){var paramName=i===1?"thisWired":"arg"+(i-2)+"Wired";if(argTypes[i].destructorFunction!==null){invokerFnBody+=paramName+"_dtor("+paramName+"); // "+argTypes[i].name+"\n";args1.push(paramName+"_dtor");args2.push(argTypes[i].destructorFunction)}}}if(returns){invokerFnBody+="var ret = retType.fromWireType(rv);\n"+"return ret;\n"}else{}invokerFnBody+="}\n";args1.push(invokerFnBody);var invokerFunction=new_(Function,args1).apply(null,args2);return invokerFunction}function __embind_register_class_function(rawClassType,methodName,argCount,rawArgTypesAddr,invokerSignature,rawInvoker,context,isPureVirtual){var rawArgTypes=heap32VectorToArray(argCount,rawArgTypesAddr);methodName=readLatin1String(methodName);rawInvoker=embind__requireFunction(invokerSignature,rawInvoker);whenDependentTypesAreResolved([],[rawClassType],function(classType){classType=classType[0];var humanName=classType.name+"."+methodName;if(isPureVirtual){classType.registeredClass.pureVirtualFunctions.push(methodName)}function unboundTypesHandler(){throwUnboundTypeError("Cannot call "+humanName+" due to unbound types",rawArgTypes)}var proto=classType.registeredClass.instancePrototype;var method=proto[methodName];if(undefined===method||undefined===method.overloadTable&&method.className!==classType.name&&method.argCount===argCount-2){unboundTypesHandler.argCount=argCount-2;unboundTypesHandler.className=classType.name;proto[methodName]=unboundTypesHandler}else{ensureOverloadTable(proto,methodName,humanName);proto[methodName].overloadTable[argCount-2]=unboundTypesHandler}whenDependentTypesAreResolved([],rawArgTypes,function(argTypes){var memberFunction=craftInvokerFunction(humanName,argTypes,classType,rawInvoker,context);if(undefined===proto[methodName].overloadTable){memberFunction.argCount=argCount-2;proto[methodName]=memberFunction}else{proto[methodName].overloadTable[argCount-2]=memberFunction}return[]});return[]})}function __embind_register_constant(name,type,value){name=readLatin1String(name);whenDependentTypesAreResolved([],[type],function(type){type=type[0];Module[name]=type["fromWireType"](value);return[]})}var emval_free_list=[];var emval_handle_array=[{},{value:undefined},{value:null},{value:true},{value:false}];function __emval_decref(handle){if(handle>4&&0===--emval_handle_array[handle].refcount){emval_handle_array[handle]=undefined;emval_free_list.push(handle)}}function count_emval_handles(){var count=0;for(var i=5;i<emval_handle_array.length;++i){if(emval_handle_array[i]!==undefined){++count}}return count}function get_first_emval(){for(var i=5;i<emval_handle_array.length;++i){if(emval_handle_array[i]!==undefined){return emval_handle_array[i]}}return null}function init_emval(){Module["count_emval_handles"]=count_emval_handles;Module["get_first_emval"]=get_first_emval}function __emval_register(value){switch(value){case undefined:{return 1}case null:{return 2}case true:{return 3}case false:{return 4}default:{var handle=emval_free_list.length?emval_free_list.pop():emval_handle_array.length;emval_handle_array[handle]={refcount:1,value:value};return handle}}}function __embind_register_emval(rawType,name){name=readLatin1String(name);registerType(rawType,{name:name,"fromWireType":function(handle){var rv=emval_handle_array[handle].value;__emval_decref(handle);return rv},"toWireType":function(destructors,value){return __emval_register(value)},"argPackAdvance":8,"readValueFromPointer":simpleReadValueFromPointer,destructorFunction:null})}function enumReadValueFromPointer(name,shift,signed){switch(shift){case 0:return function(pointer){var heap=signed?HEAP8:HEAPU8;return this["fromWireType"](heap[pointer])};case 1:return function(pointer){var heap=signed?HEAP16:HEAPU16;return this["fromWireType"](heap[pointer>>1])};case 2:return function(pointer){var heap=signed?HEAP32:HEAPU32;return this["fromWireType"](heap[pointer>>2])};default:throw new TypeError("Unknown integer type: "+name)}}function __embind_register_enum(rawType,name,size,isSigned){var shift=getShiftFromSize(size);name=readLatin1String(name);function ctor(){}ctor.values={};registerType(rawType,{name:name,constructor:ctor,"fromWireType":function(c){return this.constructor.values[c]},"toWireType":function(destructors,c){return c.value},"argPackAdvance":8,"readValueFromPointer":enumReadValueFromPointer(name,shift,isSigned),destructorFunction:null});exposePublicSymbol(name,ctor)}function requireRegisteredType(rawType,humanName){var impl=registeredTypes[rawType];if(undefined===impl){throwBindingError(humanName+" has unknown type "+getTypeName(rawType))}return impl}function __embind_register_enum_value(rawEnumType,name,enumValue){var enumType=requireRegisteredType(rawEnumType,"enum");name=readLatin1String(name);var Enum=enumType.constructor;var Value=Object.create(enumType.constructor.prototype,{value:{value:enumValue},constructor:{value:createNamedFunction(enumType.name+"_"+name,function(){})}});Enum.values[enumValue]=Value;Enum[name]=Value}function _embind_repr(v){if(v===null){return"null"}var t=typeof v;if(t==="object"||t==="array"||t==="function"){return v.toString()}else{return""+v}}function floatReadValueFromPointer(name,shift){switch(shift){case 2:return function(pointer){return this["fromWireType"](HEAPF32[pointer>>2])};case 3:return function(pointer){return this["fromWireType"](HEAPF64[pointer>>3])};default:throw new TypeError("Unknown float type: "+name)}}function __embind_register_float(rawType,name,size){var shift=getShiftFromSize(size);name=readLatin1String(name);registerType(rawType,{name:name,"fromWireType":function(value){return value},"toWireType":function(destructors,value){if(typeof value!=="number"&&typeof value!=="boolean"){throw new TypeError('Cannot convert "'+_embind_repr(value)+'" to '+this.name)}return value},"argPackAdvance":8,"readValueFromPointer":floatReadValueFromPointer(name,shift),destructorFunction:null})}function __embind_register_function(name,argCount,rawArgTypesAddr,signature,rawInvoker,fn){var argTypes=heap32VectorToArray(argCount,rawArgTypesAddr);name=readLatin1String(name);rawInvoker=embind__requireFunction(signature,rawInvoker);exposePublicSymbol(name,function(){throwUnboundTypeError("Cannot call "+name+" due to unbound types",argTypes)},argCount-1);whenDependentTypesAreResolved([],argTypes,function(argTypes){var invokerArgsArray=[argTypes[0],null].concat(argTypes.slice(1));replacePublicSymbol(name,craftInvokerFunction(name,invokerArgsArray,null,rawInvoker,fn),argCount-1);return[]})}function integerReadValueFromPointer(name,shift,signed){switch(shift){case 0:return signed?function readS8FromPointer(pointer){return HEAP8[pointer]}:function readU8FromPointer(pointer){return HEAPU8[pointer]};case 1:return signed?function readS16FromPointer(pointer){return HEAP16[pointer>>1]}:function readU16FromPointer(pointer){return HEAPU16[pointer>>1]};case 2:return signed?function readS32FromPointer(pointer){return HEAP32[pointer>>2]}:function readU32FromPointer(pointer){return HEAPU32[pointer>>2]};default:throw new TypeError("Unknown integer type: "+name)}}function __embind_register_integer(primitiveType,name,size,minRange,maxRange){name=readLatin1String(name);if(maxRange===-1){maxRange=4294967295}var shift=getShiftFromSize(size);var fromWireType=function(value){return value};if(minRange===0){var bitshift=32-8*size;fromWireType=function(value){return value<<bitshift>>>bitshift}}var isUnsignedType=name.indexOf("unsigned")!=-1;registerType(primitiveType,{name:name,"fromWireType":fromWireType,"toWireType":function(destructors,value){if(typeof value!=="number"&&typeof value!=="boolean"){throw new TypeError('Cannot convert "'+_embind_repr(value)+'" to '+this.name)}if(value<minRange||value>maxRange){throw new TypeError('Passing a number "'+_embind_repr(value)+'" from JS side to C/C++ side to an argument of type "'+name+'", which is outside the valid range ['+minRange+", "+maxRange+"]!")}return isUnsignedType?value>>>0:value|0},"argPackAdvance":8,"readValueFromPointer":integerReadValueFromPointer(name,shift,minRange!==0),destructorFunction:null})}function __embind_register_memory_view(rawType,dataTypeIndex,name){var typeMapping=[Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array];var TA=typeMapping[dataTypeIndex];function decodeMemoryView(handle){handle=handle>>2;var heap=HEAPU32;var size=heap[handle];var data=heap[handle+1];return new TA(buffer,data,size)}name=readLatin1String(name);registerType(rawType,{name:name,"fromWireType":decodeMemoryView,"argPackAdvance":8,"readValueFromPointer":decodeMemoryView},{ignoreDuplicateRegistrations:true})}function __embind_register_std_string(rawType,name){name=readLatin1String(name);var stdStringIsUTF8=name==="std::string";registerType(rawType,{name:name,"fromWireType":function(value){var length=HEAPU32[value>>2];var str;if(stdStringIsUTF8){var decodeStartPtr=value+4;for(var i=0;i<=length;++i){var currentBytePtr=value+4+i;if(i==length||HEAPU8[currentBytePtr]==0){var maxRead=currentBytePtr-decodeStartPtr;var stringSegment=UTF8ToString(decodeStartPtr,maxRead);if(str===undefined){str=stringSegment}else{str+=String.fromCharCode(0);str+=stringSegment}decodeStartPtr=currentBytePtr+1}}}else{var a=new Array(length);for(var i=0;i<length;++i){a[i]=String.fromCharCode(HEAPU8[value+4+i])}str=a.join("")}_free(value);return str},"toWireType":function(destructors,value){if(value instanceof ArrayBuffer){value=new Uint8Array(value)}var getLength;var valueIsOfTypeString=typeof value==="string";if(!(valueIsOfTypeString||value instanceof Uint8Array||value instanceof Uint8ClampedArray||value instanceof Int8Array)){throwBindingError("Cannot pass non-string to std::string")}if(stdStringIsUTF8&&valueIsOfTypeString){getLength=function(){return lengthBytesUTF8(value)}}else{getLength=function(){return value.length}}var length=getLength();var ptr=_malloc(4+length+1);HEAPU32[ptr>>2]=length;if(stdStringIsUTF8&&valueIsOfTypeString){stringToUTF8(value,ptr+4,length+1)}else{if(valueIsOfTypeString){for(var i=0;i<length;++i){var charCode=value.charCodeAt(i);if(charCode>255){_free(ptr);throwBindingError("String has UTF-16 code units that do not fit in 8 bits")}HEAPU8[ptr+4+i]=charCode}}else{for(var i=0;i<length;++i){HEAPU8[ptr+4+i]=value[i]}}}if(destructors!==null){destructors.push(_free,ptr)}return ptr},"argPackAdvance":8,"readValueFromPointer":simpleReadValueFromPointer,destructorFunction:function(ptr){_free(ptr)}})}function __embind_register_std_wstring(rawType,charSize,name){name=readLatin1String(name);var decodeString,encodeString,getHeap,lengthBytesUTF,shift;if(charSize===2){decodeString=UTF16ToString;encodeString=stringToUTF16;lengthBytesUTF=lengthBytesUTF16;getHeap=function(){return HEAPU16};shift=1}else if(charSize===4){decodeString=UTF32ToString;encodeString=stringToUTF32;lengthBytesUTF=lengthBytesUTF32;getHeap=function(){return HEAPU32};shift=2}registerType(rawType,{name:name,"fromWireType":function(value){var length=HEAPU32[value>>2];var HEAP=getHeap();var str;var decodeStartPtr=value+4;for(var i=0;i<=length;++i){var currentBytePtr=value+4+i*charSize;if(i==length||HEAP[currentBytePtr>>shift]==0){var maxReadBytes=currentBytePtr-decodeStartPtr;var stringSegment=decodeString(decodeStartPtr,maxReadBytes);if(str===undefined){str=stringSegment}else{str+=String.fromCharCode(0);str+=stringSegment}decodeStartPtr=currentBytePtr+charSize}}_free(value);return str},"toWireType":function(destructors,value){if(!(typeof value==="string")){throwBindingError("Cannot pass non-string to C++ string type "+name)}var length=lengthBytesUTF(value);var ptr=_malloc(4+length+charSize);HEAPU32[ptr>>2]=length>>shift;encodeString(value,ptr+4,length+charSize);if(destructors!==null){destructors.push(_free,ptr)}return ptr},"argPackAdvance":8,"readValueFromPointer":simpleReadValueFromPointer,destructorFunction:function(ptr){_free(ptr)}})}function __embind_register_value_object(rawType,name,constructorSignature,rawConstructor,destructorSignature,rawDestructor){structRegistrations[rawType]={name:readLatin1String(name),rawConstructor:embind__requireFunction(constructorSignature,rawConstructor),rawDestructor:embind__requireFunction(destructorSignature,rawDestructor),fields:[]}}function __embind_register_value_object_field(structType,fieldName,getterReturnType,getterSignature,getter,getterContext,setterArgumentType,setterSignature,setter,setterContext){structRegistrations[structType].fields.push({fieldName:readLatin1String(fieldName),getterReturnType:getterReturnType,getter:embind__requireFunction(getterSignature,getter),getterContext:getterContext,setterArgumentType:setterArgumentType,setter:embind__requireFunction(setterSignature,setter),setterContext:setterContext})}function __embind_register_void(rawType,name){name=readLatin1String(name);registerType(rawType,{isVoid:true,name:name,"argPackAdvance":0,"fromWireType":function(){return undefined},"toWireType":function(destructors,o){return undefined}})}function requireHandle(handle){if(!handle){throwBindingError("Cannot use deleted val. handle = "+handle)}return emval_handle_array[handle].value}function __emval_as(handle,returnType,destructorsRef){handle=requireHandle(handle);returnType=requireRegisteredType(returnType,"emval::as");var destructors=[];var rd=__emval_register(destructors);HEAP32[destructorsRef>>2]=rd;return returnType["toWireType"](destructors,handle)}var emval_symbols={};function getStringOrSymbol(address){var symbol=emval_symbols[address];if(symbol===undefined){return readLatin1String(address)}else{return symbol}}var emval_methodCallers=[];function __emval_call_void_method(caller,handle,methodName,args){caller=emval_methodCallers[caller];handle=requireHandle(handle);methodName=getStringOrSymbol(methodName);caller(handle,methodName,null,args)}function emval_get_global(){if(typeof globalThis==="object"){return globalThis}return function(){return Function}()("return this")()}function __emval_get_global(name){if(name===0){return __emval_register(emval_get_global())}else{name=getStringOrSymbol(name);return __emval_register(emval_get_global()[name])}}function __emval_addMethodCaller(caller){var id=emval_methodCallers.length;emval_methodCallers.push(caller);return id}function __emval_lookupTypes(argCount,argTypes){var a=new Array(argCount);for(var i=0;i<argCount;++i){a[i]=requireRegisteredType(HEAP32[(argTypes>>2)+i],"parameter "+i)}return a}function __emval_get_method_caller(argCount,argTypes){var types=__emval_lookupTypes(argCount,argTypes);var retType=types[0];var signatureName=retType.name+"_$"+types.slice(1).map(function(t){return t.name}).join("_")+"$";var params=["retType"];var args=[retType];var argsList="";for(var i=0;i<argCount-1;++i){argsList+=(i!==0?", ":"")+"arg"+i;params.push("argType"+i);args.push(types[1+i])}var functionName=makeLegalFunctionName("methodCaller_"+signatureName);var functionBody="return function "+functionName+"(handle, name, destructors, args) {\n";var offset=0;for(var i=0;i<argCount-1;++i){functionBody+="    var arg"+i+" = argType"+i+".readValueFromPointer(args"+(offset?"+"+offset:"")+");\n";offset+=types[i+1]["argPackAdvance"]}functionBody+="    var rv = handle[name]("+argsList+");\n";for(var i=0;i<argCount-1;++i){if(types[i+1]["deleteObject"]){functionBody+="    argType"+i+".deleteObject(arg"+i+");\n"}}if(!retType.isVoid){functionBody+="    return retType.toWireType(destructors, rv);\n"}functionBody+="};\n";params.push(functionBody);var invokerFunction=new_(Function,params).apply(null,args);return __emval_addMethodCaller(invokerFunction)}function __emval_get_module_property(name){name=getStringOrSymbol(name);return __emval_register(Module[name])}function __emval_get_property(handle,key){handle=requireHandle(handle);key=requireHandle(key);return __emval_register(handle[key])}function __emval_incref(handle){if(handle>4){emval_handle_array[handle].refcount+=1}}function craftEmvalAllocator(argCount){var argsList="";for(var i=0;i<argCount;++i){argsList+=(i!==0?", ":"")+"arg"+i}var functionBody="return function emval_allocator_"+argCount+"(constructor, argTypes, args) {\n";for(var i=0;i<argCount;++i){functionBody+="var argType"+i+" = requireRegisteredType(Module['HEAP32'][(argTypes >>> 2) + "+i+'], "parameter '+i+'");\n'+"var arg"+i+" = argType"+i+".readValueFromPointer(args);\n"+"args += argType"+i+"['argPackAdvance'];\n"}functionBody+="var obj = new constructor("+argsList+");\n"+"return __emval_register(obj);\n"+"}\n";return new Function("requireRegisteredType","Module","__emval_register",functionBody)(requireRegisteredType,Module,__emval_register)}var emval_newers={};function __emval_new(handle,argCount,argTypes,args){handle=requireHandle(handle);var newer=emval_newers[argCount];if(!newer){newer=craftEmvalAllocator(argCount);emval_newers[argCount]=newer}return newer(handle,argTypes,args)}function __emval_new_cstring(v){return __emval_register(getStringOrSymbol(v))}function __emval_run_destructors(handle){var destructors=emval_handle_array[handle].value;runDestructors(destructors);__emval_decref(handle)}function _abort(){abort()}function _longjmp(env,value){_setThrew(env,value||1);throw"longjmp"}function _emscripten_longjmp(a0,a1){return _longjmp(a0,a1)}function _emscripten_memcpy_big(dest,src,num){HEAPU8.copyWithin(dest,src,src+num)}function _emscripten_get_heap_size(){return HEAPU8.length}function emscripten_realloc_buffer(size){try{wasmMemory.grow(size-buffer.byteLength+65535>>>16);updateGlobalBufferAndViews(wasmMemory.buffer);return 1}catch(e){}}function _emscripten_resize_heap(requestedSize){requestedSize=requestedSize>>>0;var oldSize=_emscripten_get_heap_size();var maxHeapSize=2147483648;if(requestedSize>maxHeapSize){return false}var minHeapSize=16777216;for(var cutDown=1;cutDown<=4;cutDown*=2){var overGrownHeapSize=oldSize*(1+.2/cutDown);overGrownHeapSize=Math.min(overGrownHeapSize,requestedSize+100663296);var newSize=Math.min(maxHeapSize,alignUp(Math.max(minHeapSize,requestedSize,overGrownHeapSize),65536));var replacement=emscripten_realloc_buffer(newSize);if(replacement){return true}}return false}function _fd_close(fd){try{var stream=SYSCALLS.getStreamFromFD(fd);FS.close(stream);return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return e.errno}}function _fd_read(fd,iov,iovcnt,pnum){try{var stream=SYSCALLS.getStreamFromFD(fd);var num=SYSCALLS.doReadv(stream,iov,iovcnt);HEAP32[pnum>>2]=num;return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return e.errno}}function _fd_seek(fd,offset_low,offset_high,whence,newOffset){try{var stream=SYSCALLS.getStreamFromFD(fd);var HIGH_OFFSET=4294967296;var offset=offset_high*HIGH_OFFSET+(offset_low>>>0);var DOUBLE_LIMIT=9007199254740992;if(offset<=-DOUBLE_LIMIT||offset>=DOUBLE_LIMIT){return-61}FS.llseek(stream,offset,whence);tempI64=[stream.position>>>0,(tempDouble=stream.position,+Math.abs(tempDouble)>=1?tempDouble>0?(Math.min(+Math.floor(tempDouble/4294967296),4294967295)|0)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[newOffset>>2]=tempI64[0],HEAP32[newOffset+4>>2]=tempI64[1];if(stream.getdents&&offset===0&&whence===0)stream.getdents=null;return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return e.errno}}function _fd_write(fd,iov,iovcnt,pnum){try{var stream=SYSCALLS.getStreamFromFD(fd);var num=SYSCALLS.doWritev(stream,iov,iovcnt);HEAP32[pnum>>2]=num;return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return e.errno}}function _getTempRet0(){return getTempRet0()|0}function _gettimeofday(ptr){var now=Date.now();HEAP32[ptr>>2]=now/1e3|0;HEAP32[ptr+4>>2]=now%1e3*1e3|0;return 0}function _pthread_join(){return 28}function _setTempRet0($i){setTempRet0($i|0)}function _sysconf(name){switch(name){case 30:return 16384;case 85:var maxHeapSize=2147483648;return maxHeapSize/16384;case 132:case 133:case 12:case 137:case 138:case 15:case 235:case 16:case 17:case 18:case 19:case 20:case 149:case 13:case 10:case 236:case 153:case 9:case 21:case 22:case 159:case 154:case 14:case 77:case 78:case 139:case 80:case 81:case 82:case 68:case 67:case 164:case 11:case 29:case 47:case 48:case 95:case 52:case 51:case 46:case 79:return 200809;case 27:case 246:case 127:case 128:case 23:case 24:case 160:case 161:case 181:case 182:case 242:case 183:case 184:case 243:case 244:case 245:case 165:case 178:case 179:case 49:case 50:case 168:case 169:case 175:case 170:case 171:case 172:case 97:case 76:case 32:case 173:case 35:return-1;case 176:case 177:case 7:case 155:case 8:case 157:case 125:case 126:case 92:case 93:case 129:case 130:case 131:case 94:case 91:return 1;case 74:case 60:case 69:case 70:case 4:return 1024;case 31:case 42:case 72:return 32;case 87:case 26:case 33:return 2147483647;case 34:case 1:return 47839;case 38:case 36:return 99;case 43:case 37:return 2048;case 0:return 2097152;case 3:return 65536;case 28:return 32768;case 44:return 32767;case 75:return 16384;case 39:return 1e3;case 89:return 700;case 71:return 256;case 40:return 255;case 2:return 100;case 180:return 64;case 25:return 20;case 5:return 16;case 6:return 6;case 73:return 4;case 84:{if(typeof navigator==="object")return navigator["hardwareConcurrency"]||1;return 1}}setErrNo(28);return-1}var FSNode=function(parent,name,mode,rdev){if(!parent){parent=this}this.parent=parent;this.mount=parent.mount;this.mounted=null;this.id=FS.nextInode++;this.name=name;this.mode=mode;this.node_ops={};this.stream_ops={};this.rdev=rdev};var readMode=292|73;var writeMode=146;Object.defineProperties(FSNode.prototype,{read:{get:function(){return(this.mode&readMode)===readMode},set:function(val){val?this.mode|=readMode:this.mode&=~readMode}},write:{get:function(){return(this.mode&writeMode)===writeMode},set:function(val){val?this.mode|=writeMode:this.mode&=~writeMode}},isFolder:{get:function(){return FS.isDir(this.mode)}},isDevice:{get:function(){return FS.isChrdev(this.mode)}}});FS.FSNode=FSNode;FS.staticInit();InternalError=Module["InternalError"]=extendError(Error,"InternalError");embind_init_charCodes();BindingError=Module["BindingError"]=extendError(Error,"BindingError");init_ClassHandle();init_RegisteredPointer();init_embind();UnboundTypeError=Module["UnboundTypeError"]=extendError(Error,"UnboundTypeError");init_emval();function intArrayFromString(stringy,dontAddNull,length){var len=length>0?length:lengthBytesUTF8(stringy)+1;var u8array=new Array(len);var numBytesWritten=stringToUTF8Array(stringy,u8array,0,u8array.length);if(dontAddNull)u8array.length=numBytesWritten;return u8array}__ATINIT__.push({func:function(){___wasm_call_ctors()}});var asmLibraryArg={"J":___cxa_allocate_exception,"I":___cxa_throw,"F":___sys_fcntl64,"R":___sys_ioctl,"S":___sys_open,"B":__embind_finalize_value_object,"U":__embind_register_bool,"A":__embind_register_class,"z":__embind_register_class_constructor,"a":__embind_register_class_function,"d":__embind_register_constant,"T":__embind_register_emval,"w":__embind_register_enum,"c":__embind_register_enum_value,"G":__embind_register_float,"n":__embind_register_function,"l":__embind_register_integer,"i":__embind_register_memory_view,"H":__embind_register_std_string,"x":__embind_register_std_wstring,"C":__embind_register_value_object,"e":__embind_register_value_object_field,"V":__embind_register_void,"p":__emval_as,"s":__emval_call_void_method,"b":__emval_decref,"K":__emval_get_global,"t":__emval_get_method_caller,"v":__emval_get_module_property,"g":__emval_get_property,"m":__emval_incref,"u":__emval_new,"h":__emval_new_cstring,"o":__emval_run_destructors,"k":_abort,"r":_emscripten_longjmp,"M":_emscripten_memcpy_big,"N":_emscripten_resize_heap,"E":_fd_close,"Q":_fd_read,"L":_fd_seek,"D":_fd_write,"j":_getTempRet0,"y":_gettimeofday,"X":invoke_ii,"q":invoke_vi,"W":invoke_vii,"Y":invoke_viii,"P":_pthread_join,"f":_setTempRet0,"O":_sysconf};var asm=createWasm();var ___wasm_call_ctors=Module["___wasm_call_ctors"]=function(){return(___wasm_call_ctors=Module["___wasm_call_ctors"]=Module["asm"]["$"]).apply(null,arguments)};var _malloc=Module["_malloc"]=function(){return(_malloc=Module["_malloc"]=Module["asm"]["aa"]).apply(null,arguments)};var _free=Module["_free"]=function(){return(_free=Module["_free"]=Module["asm"]["ba"]).apply(null,arguments)};var ___getTypeName=Module["___getTypeName"]=function(){return(___getTypeName=Module["___getTypeName"]=Module["asm"]["ca"]).apply(null,arguments)};var ___embind_register_native_and_builtin_types=Module["___embind_register_native_and_builtin_types"]=function(){return(___embind_register_native_and_builtin_types=Module["___embind_register_native_and_builtin_types"]=Module["asm"]["da"]).apply(null,arguments)};var ___errno_location=Module["___errno_location"]=function(){return(___errno_location=Module["___errno_location"]=Module["asm"]["ea"]).apply(null,arguments)};var stackSave=Module["stackSave"]=function(){return(stackSave=Module["stackSave"]=Module["asm"]["fa"]).apply(null,arguments)};var stackRestore=Module["stackRestore"]=function(){return(stackRestore=Module["stackRestore"]=Module["asm"]["ga"]).apply(null,arguments)};var _setThrew=Module["_setThrew"]=function(){return(_setThrew=Module["_setThrew"]=Module["asm"]["ha"]).apply(null,arguments)};var dynCall_jiiii=Module["dynCall_jiiii"]=function(){return(dynCall_jiiii=Module["dynCall_jiiii"]=Module["asm"]["ia"]).apply(null,arguments)};var dynCall_jiji=Module["dynCall_jiji"]=function(){return(dynCall_jiji=Module["dynCall_jiji"]=Module["asm"]["ja"]).apply(null,arguments)};function invoke_vi(index,a1){var sp=stackSave();try{wasmTable.get(index)(a1)}catch(e){stackRestore(sp);if(e!==e+0&&e!=="longjmp")throw e;_setThrew(1,0)}}function invoke_viii(index,a1,a2,a3){var sp=stackSave();try{wasmTable.get(index)(a1,a2,a3)}catch(e){stackRestore(sp);if(e!==e+0&&e!=="longjmp")throw e;_setThrew(1,0)}}function invoke_ii(index,a1){var sp=stackSave();try{return wasmTable.get(index)(a1)}catch(e){stackRestore(sp);if(e!==e+0&&e!=="longjmp")throw e;_setThrew(1,0)}}function invoke_vii(index,a1,a2){var sp=stackSave();try{wasmTable.get(index)(a1,a2)}catch(e){stackRestore(sp);if(e!==e+0&&e!=="longjmp")throw e;_setThrew(1,0)}}var calledRun;function ExitStatus(status){this.name="ExitStatus";this.message="Program terminated with exit("+status+")";this.status=status}dependenciesFulfilled=function runCaller(){if(!calledRun)run();if(!calledRun)dependenciesFulfilled=runCaller};function run(args){args=args||arguments_;if(runDependencies>0){return}preRun();if(runDependencies>0)return;function doRun(){if(calledRun)return;calledRun=true;Module["calledRun"]=true;if(ABORT)return;initRuntime();preMain();readyPromiseResolve(Module);if(Module["onRuntimeInitialized"])Module["onRuntimeInitialized"]();postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout(function(){setTimeout(function(){Module["setStatus"]("")},1);doRun()},1)}else{doRun()}}Module["run"]=run;if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].pop()()}}noExitRuntime=true;run();
+
+
+  return BASIS.ready
+}
+);
+})();
+if (typeof exports === 'object' && typeof module === 'object')
+  module.exports = BASIS;
+else if (typeof define === 'function' && define['amd'])
+  define([], function() { return BASIS; });
+else if (typeof exports === 'object')
+  exports["BASIS"] = BASIS;
diff --git a/webgl/encoder/build/basis_encoder.wasm b/webgl/encoder/build/basis_encoder.wasm
new file mode 100644
index 0000000..3c39bfe
--- /dev/null
+++ b/webgl/encoder/build/basis_encoder.wasm
Binary files differ
diff --git a/webgl/encoder/build/basis_loader.js b/webgl/encoder/build/basis_loader.js
new file mode 100644
index 0000000..ce3e685
--- /dev/null
+++ b/webgl/encoder/build/basis_loader.js
@@ -0,0 +1,495 @@
+/*
+ * Basis Loader
+ * Note: This is the same as transcoder/build/basis_loader.js, except modified to import basis_encoder.js (which also includes the transcoder).
+ *
+ * Usage:
+ * // basis_loader.js should be loaded from the same directory as
+ * // basis_encoder.js and basis_encoder.wasm
+ *
+ * // Create the texture loader and set the WebGL context it should use. Spawns
+ * // a worker which handles all of the transcoding.
+ * let basisLoader = new BasisLoader();
+ * basisLoader.setWebGLContext(gl);
+ *
+ * // To allow separate color and alpha textures to be returned in cases where
+ * // it would provide higher quality:
+ * basisLoader.allowSeparateAlpha = true;
+ *
+ * // loadFromUrl() returns a promise which resolves to a completed WebGL
+ * // texture or rejects if there's an error loading.
+ * basisBasics.loadFromUrl(fullPathToTexture).then((result) => {
+ *   // WebGL color+alpha texture;
+ *   result.texture;
+ *
+ *   // WebGL alpha texture, only if basisLoader.allowSeparateAlpha is true.
+ *   // null if alpha is encoded in result.texture or result.alpha is false.
+ *   result.alphaTexture;
+ *
+ *   // True if the texture contained an alpha channel.
+ *   result.alpha;
+ *
+ *   // Number of mip levels in texture/alphaTexture
+ *   result.mipLevels;
+ *
+ *   // Dimensions of the base mip level.
+ *   result.width;
+ *   result.height;
+ * });
+ */
+
+// This file contains the code both for the main thread interface and the
+// worker that does the transcoding.
+const IN_WORKER = typeof importScripts === "function";
+const SCRIPT_PATH = typeof document !== 'undefined' && document.currentScript ? document.currentScript.src : undefined;
+
+if (!IN_WORKER) {
+  //
+  // Main Thread
+  //
+  class PendingTextureRequest {
+    constructor(gl, url) {
+      this.gl = gl;
+      this.url = url;
+      this.texture = null;
+      this.alphaTexture = null;
+      this.promise = new Promise((resolve, reject) => {
+        this.resolve = resolve;
+        this.reject = reject;
+      });
+    }
+
+    uploadImageData(webglFormat, buffer, mipLevels) {
+      let gl = this.gl;
+      let texture = gl.createTexture();
+      gl.bindTexture(gl.TEXTURE_2D, texture);
+      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
+      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, mipLevels.length > 1 || webglFormat.uncompressed ? gl.LINEAR_MIPMAP_LINEAR : gl.LINEAR);
+
+      let levelData = null;
+
+      for (let mipLevel of mipLevels) {
+        if (!webglFormat.uncompressed) {
+          levelData = new Uint8Array(buffer, mipLevel.offset, mipLevel.size);
+          gl.compressedTexImage2D(
+            gl.TEXTURE_2D,
+            mipLevel.level,
+            webglFormat.format,
+            mipLevel.width,
+            mipLevel.height,
+            0,
+            levelData);
+        } else {
+          switch (webglFormat.type) {
+            case WebGLRenderingContext.UNSIGNED_SHORT_4_4_4_4:
+            case WebGLRenderingContext.UNSIGNED_SHORT_5_5_5_1:
+            case WebGLRenderingContext.UNSIGNED_SHORT_5_6_5:
+              levelData = new Uint16Array(buffer, mipLevel.offset, mipLevel.size / 2);
+              break;
+            default:
+              levelData = new Uint8Array(buffer, mipLevel.offset, mipLevel.size);
+              break;
+          }
+          gl.texImage2D(
+            gl.TEXTURE_2D,
+            mipLevel.level,
+            webglFormat.format,
+            mipLevel.width,
+            mipLevel.height,
+            0,
+            webglFormat.format,
+            webglFormat.type,
+            levelData);
+        }
+      }
+
+      if (webglFormat.uncompressed && mipLevels.length == 1) {
+        gl.generateMipmap(gl.TEXTURE_2D);
+      }
+
+      return texture;
+    }
+  };
+
+  class BasisLoader {
+    constructor() {
+      this.gl = null;
+      this.supportedFormats = {};
+      this.pendingTextures = {};
+      this.nextPendingTextureId = 1;
+      this.allowSeparateAlpha = false;
+
+      // Reload the current script as a worker
+      this.worker = new Worker(SCRIPT_PATH);
+      this.worker.onmessage = (msg) => {
+        // Find the pending texture associated with the data we just received
+        // from the worker.
+        let pendingTexture = this.pendingTextures[msg.data.id];
+        if (!pendingTexture) {
+          if (msg.data.error) {
+            console.error(`Basis transcode failed: ${msg.data.error}`);
+          }
+          console.error(`Invalid pending texture ID: ${msg.data.id}`);
+          return;
+        }
+
+        // Remove the pending texture from the waiting list.
+        delete this.pendingTextures[msg.data.id];
+
+        // If the worker indicated an error has occured handle it now.
+        if (msg.data.error) {
+          console.error(`Basis transcode failed: ${msg.data.error}`);
+          pendingTexture.reject(`${msg.data.error}`);
+          return;
+        }
+
+        // Upload the image data returned by the worker.
+        pendingTexture.texture = pendingTexture.uploadImageData(
+            msg.data.webglFormat,
+            msg.data.buffer,
+            msg.data.mipLevels);
+
+        if (msg.data.alphaBuffer) {
+          pendingTexture.alphaTexture = pendingTexture.uploadImageData(
+              msg.data.webglFormat,
+              msg.data.alphaBuffer,
+              msg.data.mipLevels);
+        }
+
+        pendingTexture.resolve({
+          mipLevels: msg.data.mipLevels.length,
+          width: msg.data.mipLevels[0].width,
+          height: msg.data.mipLevels[0].height,
+          alpha: msg.data.hasAlpha,
+          texture: pendingTexture.texture,
+          alphaTexture: pendingTexture.alphaTexture,
+        });
+      };
+    }
+
+    setWebGLContext(gl) {
+      if (this.gl != gl) {
+        this.gl = gl;
+        if (gl) {
+          this.supportedFormats = {
+            s3tc: !!gl.getExtension('WEBGL_compressed_texture_s3tc'),
+            etc1: !!gl.getExtension('WEBGL_compressed_texture_etc1'),
+            etc2: !!gl.getExtension('WEBGL_compressed_texture_etc'),
+            pvrtc: !!gl.getExtension('WEBGL_compressed_texture_pvrtc'),
+            astc: !!gl.getExtension('WEBGL_compressed_texture_astc'),
+            bptc: !!gl.getExtension('EXT_texture_compression_bptc')
+          };
+        } else {
+          this.supportedFormats = {};
+        }
+      }
+    }
+
+    // This method changes the active texture unit's TEXTURE_2D binding
+    // immediately prior to resolving the returned promise.
+    loadFromUrl(url) {
+      let pendingTexture = new PendingTextureRequest(this.gl, url);
+      this.pendingTextures[this.nextPendingTextureId] = pendingTexture;
+
+      this.worker.postMessage({
+        id: this.nextPendingTextureId,
+        url: url,
+        allowSeparateAlpha: this.allowSeparateAlpha,
+        supportedFormats: this.supportedFormats
+      });
+
+      this.nextPendingTextureId++;
+      return pendingTexture.promise;
+    }
+  }
+
+  window.BasisLoader = BasisLoader;
+
+} else {
+  //
+  // Worker
+  //
+  importScripts('basis_encoder.js');
+
+  let BasisFile = null;
+
+  const BASIS_INITIALIZED = BASIS().then((module) => {
+    BasisFile = module.BasisFile;
+    module.initializeBasis();
+  });
+
+  // Copied from enum class transcoder_texture_format in basisu_transcoder.h with minor javascript-ification
+  const BASIS_FORMAT = {
+    // Compressed formats
+
+    // ETC1-2
+    cTFETC1_RGB: 0,							// Opaque only, returns RGB or alpha data if cDecodeFlagsTranscodeAlphaDataToOpaqueFormats flag is specified
+    cTFETC2_RGBA: 1,							// Opaque+alpha, ETC2_EAC_A8 block followed by a ETC1 block, alpha channel will be opaque for opaque .basis files
+
+    // BC1-5, BC7 (desktop, some mobile devices)
+    cTFBC1_RGB: 2,							// Opaque only, no punchthrough alpha support yet, transcodes alpha slice if cDecodeFlagsTranscodeAlphaDataToOpaqueFormats flag is specified
+    cTFBC3_RGBA: 3, 							// Opaque+alpha, BC4 followed by a BC1 block, alpha channel will be opaque for opaque .basis files
+    cTFBC4_R: 4,								// Red only, alpha slice is transcoded to output if cDecodeFlagsTranscodeAlphaDataToOpaqueFormats flag is specified
+    cTFBC5_RG: 5,								// XY: Two BC4 blocks, X=R and Y=Alpha, .basis file should have alpha data (if not Y will be all 255's)
+    cTFBC7_RGBA: 6,							// RGB or RGBA, mode 5 for ETC1S, modes (1,2,3,5,6,7) for UASTC
+
+    // PVRTC1 4bpp (mobile, PowerVR devices)
+    cTFPVRTC1_4_RGB: 8,						// Opaque only, RGB or alpha if cDecodeFlagsTranscodeAlphaDataToOpaqueFormats flag is specified, nearly lowest quality of any texture format.
+    cTFPVRTC1_4_RGBA: 9,					// Opaque+alpha, most useful for simple opacity maps. If .basis file doesn't have alpha cTFPVRTC1_4_RGB will be used instead. Lowest quality of any supported texture format.
+
+    // ASTC (mobile, Intel devices, hopefully all desktop GPU's one day)
+    cTFASTC_4x4_RGBA: 10,					// Opaque+alpha, ASTC 4x4, alpha channel will be opaque for opaque .basis files. Transcoder uses RGB/RGBA/L/LA modes, void extent, and up to two ([0,47] and [0,255]) endpoint precisions.
+
+    // Uncompressed (raw pixel) formats
+    cTFRGBA32: 13,							// 32bpp RGBA image stored in raster (not block) order in memory, R is first byte, A is last byte.
+    cTFRGB565: 14,							// 166pp RGB image stored in raster (not block) order in memory, R at bit position 11
+    cTFBGR565: 15,							// 16bpp RGB image stored in raster (not block) order in memory, R at bit position 0
+    cTFRGBA4444: 16,							// 16bpp RGBA image stored in raster (not block) order in memory, R at bit position 12, A at bit position 0
+
+    cTFTotalTextureFormats: 22,
+  };
+
+  // WebGL compressed formats types, from:
+  // http://www.khronos.org/registry/webgl/extensions/
+
+  // https://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_s3tc/
+  const COMPRESSED_RGB_S3TC_DXT1_EXT  = 0x83F0;
+  const COMPRESSED_RGBA_S3TC_DXT1_EXT = 0x83F1;
+  const COMPRESSED_RGBA_S3TC_DXT3_EXT = 0x83F2;
+  const COMPRESSED_RGBA_S3TC_DXT5_EXT = 0x83F3;
+
+  // https://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_etc1/
+  const COMPRESSED_RGB_ETC1_WEBGL = 0x8D64;
+
+  // https://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_etc/
+  const COMPRESSED_R11_EAC                        = 0x9270;
+  const COMPRESSED_SIGNED_R11_EAC                 = 0x9271;
+  const COMPRESSED_RG11_EAC                       = 0x9272;
+  const COMPRESSED_SIGNED_RG11_EAC                = 0x9273;
+  const COMPRESSED_RGB8_ETC2                      = 0x9274;
+  const COMPRESSED_SRGB8_ETC2                     = 0x9275;
+  const COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2  = 0x9276;
+  const COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 = 0x9277;
+  const COMPRESSED_RGBA8_ETC2_EAC                 = 0x9278;
+  const COMPRESSED_SRGB8_ALPHA8_ETC2_EAC          = 0x9279;
+
+  // https://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_astc/
+  const COMPRESSED_RGBA_ASTC_4x4_KHR = 0x93B0;
+
+  // https://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_pvrtc/
+  const COMPRESSED_RGB_PVRTC_4BPPV1_IMG = 0x8C00;
+  const COMPRESSED_RGB_PVRTC_2BPPV1_IMG  = 0x8C01;
+  const COMPRESSED_RGBA_PVRTC_4BPPV1_IMG = 0x8C02;
+  const COMPRESSED_RGBA_PVRTC_2BPPV1_IMG = 0x8C03;
+
+  // https://www.khronos.org/registry/webgl/extensions/EXT_texture_compression_bptc/
+  const COMPRESSED_RGBA_BPTC_UNORM_EXT = 0x8E8C;
+  const COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT = 0x8E8D;
+  const COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT = 0x8E8E;
+  const COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT = 0x8E8F;
+
+  const BASIS_WEBGL_FORMAT_MAP = {};
+  // Compressed formats
+  BASIS_WEBGL_FORMAT_MAP[BASIS_FORMAT.cTFBC1_RGB] = { format: COMPRESSED_RGB_S3TC_DXT1_EXT };
+  BASIS_WEBGL_FORMAT_MAP[BASIS_FORMAT.cTFBC3_RGBA] = { format: COMPRESSED_RGBA_S3TC_DXT5_EXT };
+  BASIS_WEBGL_FORMAT_MAP[BASIS_FORMAT.cTFBC7_RGBA] = { format: COMPRESSED_RGBA_BPTC_UNORM_EXT };
+  BASIS_WEBGL_FORMAT_MAP[BASIS_FORMAT.cTFETC1_RGB] = { format: COMPRESSED_RGB_ETC1_WEBGL };
+  BASIS_WEBGL_FORMAT_MAP[BASIS_FORMAT.cTFETC2_RGBA] = { format: COMPRESSED_RGBA8_ETC2_EAC };
+  BASIS_WEBGL_FORMAT_MAP[BASIS_FORMAT.cTFASTC_4x4_RGBA] = { format: COMPRESSED_RGBA_ASTC_4x4_KHR };
+  BASIS_WEBGL_FORMAT_MAP[BASIS_FORMAT.cTFPVRTC1_4_RGB] = { format: COMPRESSED_RGB_PVRTC_4BPPV1_IMG };
+  BASIS_WEBGL_FORMAT_MAP[BASIS_FORMAT.cTFPVRTC1_4_RGBA] = { format: COMPRESSED_RGBA_PVRTC_4BPPV1_IMG };
+
+  // Uncompressed formats
+  BASIS_WEBGL_FORMAT_MAP[BASIS_FORMAT.cTFRGBA32] = { uncompressed: true, format: WebGLRenderingContext.RGBA, type: WebGLRenderingContext.UNSIGNED_BYTE };
+  BASIS_WEBGL_FORMAT_MAP[BASIS_FORMAT.cTFRGB565] = { uncompressed: true, format: WebGLRenderingContext.RGB, type: WebGLRenderingContext.UNSIGNED_SHORT_5_6_5 };
+  BASIS_WEBGL_FORMAT_MAP[BASIS_FORMAT.cTFRGBA4444] = { uncompressed: true, format: WebGLRenderingContext.RGBA, type: WebGLRenderingContext.UNSIGNED_SHORT_4_4_4_4 };
+
+  // Notifies the main thread when a texture has failed to load for any reason.
+  function fail(id, errorMsg) {
+    postMessage({
+      id: id,
+      error: errorMsg
+    });
+  }
+
+  function basisFileFail(id, basisFile, errorMsg) {
+    fail(id, errorMsg);
+    basisFile.close();
+    basisFile.delete();
+  }
+
+  // This utility currently only transcodes the first image in the file.
+  const IMAGE_INDEX = 0;
+  const TOP_LEVEL_MIP = 0;
+
+  function transcode(id, arrayBuffer, supportedFormats, allowSeparateAlpha) {
+    let basisData = new Uint8Array(arrayBuffer);
+
+    let basisFile = new BasisFile(basisData);
+    let images = basisFile.getNumImages();
+    let levels = basisFile.getNumLevels(IMAGE_INDEX);
+    let hasAlpha = basisFile.getHasAlpha();
+    if (!images || !levels) {
+      basisFileFail(id, basisFile, 'Invalid Basis data');
+      return;
+    }
+
+    if (!basisFile.startTranscoding()) {
+      basisFileFail(id, basisFile, 'startTranscoding failed');
+      return;
+    }
+
+    let basisFormat = undefined;
+    let needsSecondaryAlpha = false;
+    if (hasAlpha) {
+      if (supportedFormats.etc2) {
+        basisFormat = BASIS_FORMAT.cTFETC2_RGBA;
+      } else if (supportedFormats.bptc) {
+        basisFormat = BASIS_FORMAT.cTFBC7_RGBA;
+      } else if (supportedFormats.s3tc) {
+        basisFormat = BASIS_FORMAT.cTFBC3_RGBA;
+      } else if (supportedFormats.astc) {
+        basisFormat = BASIS_FORMAT.cTFASTC_4x4_RGBA;
+      } else if (supportedFormats.pvrtc) {
+        if (allowSeparateAlpha) {
+          basisFormat = BASIS_FORMAT.cTFPVRTC1_4_RGB;
+          needsSecondaryAlpha = true;
+        } else {
+          basisFormat = BASIS_FORMAT.cTFPVRTC1_4_RGBA;
+        }
+      } else if (supportedFormats.etc1 && allowSeparateAlpha) {
+        basisFormat = BASIS_FORMAT.cTFETC1_RGB;
+        needsSecondaryAlpha = true;
+      } else {
+        // If we don't support any appropriate compressed formats transcode to
+        // raw pixels. This is something of a last resort, because the GPU
+        // upload will be significantly slower and take a lot more memory, but
+        // at least it prevents you from needing to store a fallback JPG/PNG and
+        // the download size will still likely be smaller.
+        basisFormat = BASIS_FORMAT.RGBA32;
+      }
+    } else {
+      if (supportedFormats.etc1) {
+        // Should be the highest quality, so use when available.
+        // http://richg42.blogspot.com/2018/05/basis-universal-gpu-texture-format.html
+        basisFormat = BASIS_FORMAT.cTFETC1_RGB;
+      } else if (supportedFormats.bptc) {
+        basisFormat = BASIS_FORMAT.cTFBC7_RGBA;
+      } else if (supportedFormats.s3tc) {
+        basisFormat = BASIS_FORMAT.cTFBC1_RGB;
+      } else if (supportedFormats.etc2) {
+        basisFormat = BASIS_FORMAT.cTFETC2_RGBA;
+      } else if (supportedFormats.astc) {
+        basisFormat = BASIS_FORMAT.cTFASTC_4x4_RGBA;
+      } else if (supportedFormats.pvrtc) {
+        basisFormat = BASIS_FORMAT.cTFPVRTC1_4_RGB;
+      } else {
+        // See note on uncompressed transcode above.
+        basisFormat = BASIS_FORMAT.cTFRGB565;
+      }
+    }
+
+    if (basisFormat === undefined) {
+      basisFileFail(id, basisFile, 'No supported transcode formats');
+      return;
+    }
+
+    let webglFormat = BASIS_WEBGL_FORMAT_MAP[basisFormat];
+
+    // If we're not using compressed textures it'll be cheaper to generate
+    // mipmaps on the fly, so only transcode a single level.
+    if (webglFormat.uncompressed) {
+      levels = 1;
+    }
+
+    // Gather information about each mip level to be transcoded.
+    let mipLevels = [];
+    let totalTranscodeSize = 0;
+
+    for (let mipLevel = 0; mipLevel < levels; ++mipLevel) {
+      let transcodeSize = basisFile.getImageTranscodedSizeInBytes(IMAGE_INDEX, mipLevel, basisFormat);
+      mipLevels.push({
+        level: mipLevel,
+        offset: totalTranscodeSize,
+        size: transcodeSize,
+        width: basisFile.getImageWidth(IMAGE_INDEX, mipLevel),
+        height: basisFile.getImageHeight(IMAGE_INDEX, mipLevel),
+      });
+      totalTranscodeSize += transcodeSize;
+    }
+
+    // Allocate a buffer large enough to hold all of the transcoded mip levels at once.
+    let transcodeData = new Uint8Array(totalTranscodeSize);
+    let alphaTranscodeData = needsSecondaryAlpha ? new Uint8Array(totalTranscodeSize) : null;
+
+    // Transcode each mip level into the appropriate section of the overall buffer.
+    for (let mipLevel of mipLevels) {
+      let levelData = new Uint8Array(transcodeData.buffer, mipLevel.offset, mipLevel.size);
+      if (!basisFile.transcodeImage(levelData, IMAGE_INDEX, mipLevel.level, basisFormat, 1, 0)) {
+        basisFileFail(id, basisFile, 'transcodeImage failed');
+        return;
+      }
+      if (needsSecondaryAlpha) {
+        let alphaLevelData = new Uint8Array(alphaTranscodeData.buffer, mipLevel.offset, mipLevel.size);
+        if (!basisFile.transcodeImage(alphaLevelData, IMAGE_INDEX, mipLevel.level, basisFormat, 1, 1)) {
+          basisFileFail(id, basisFile, 'alpha transcodeImage failed');
+          return;
+        }
+      }
+    }
+
+    basisFile.close();
+    basisFile.delete();
+
+    // Post the transcoded results back to the main thread.
+    let transferList = [transcodeData.buffer];
+    if (needsSecondaryAlpha) {
+      transferList.push(alphaTranscodeData.buffer);
+    }
+    postMessage({
+      id: id,
+      buffer: transcodeData.buffer,
+      alphaBuffer: needsSecondaryAlpha ? alphaTranscodeData.buffer : null,
+      webglFormat: webglFormat,
+      mipLevels: mipLevels,
+      hasAlpha: hasAlpha,
+    }, transferList);
+  }
+
+  onmessage = (msg) => {
+    // Each call to the worker must contain:
+    let url = msg.data.url; // The URL of the basis image OR
+    let buffer = msg.data.buffer; // An array buffer with the basis image data
+    let allowSeparateAlpha = msg.data.allowSeparateAlpha;
+    let supportedFormats = msg.data.supportedFormats; // The formats this device supports
+    let id = msg.data.id; // A unique ID for the texture
+
+    if (url) {
+      // Make the call to fetch the basis texture data
+      fetch(url).then(function(response) {
+        if (response.ok) {
+          response.arrayBuffer().then((arrayBuffer) => {
+            if (BasisFile) {
+              transcode(id, arrayBuffer, supportedFormats, allowSeparateAlpha);
+            } else {
+              BASIS_INITIALIZED.then(() => {
+                transcode(id, arrayBuffer, supportedFormats, allowSeparateAlpha);
+              });
+            }
+          });
+        } else {
+          fail(id, `Fetch failed: ${response.status}, ${response.statusText}`);
+        }
+      });
+    } else if (buffer) {
+      if (BasisFile) {
+        transcode(id, buffer, supportedFormats, allowSeparateAlpha);
+      } else {
+        BASIS_INITIALIZED.then(() => {
+          transcode(id, buffer, supportedFormats, allowSeparateAlpha);
+        });
+      }
+    } else {
+      fail(id, `No url or buffer specified`);
+    }
+  };
+}
diff --git a/webgl/index.html b/webgl/index.html
index 4273e04..cfb482e 100644
--- a/webgl/index.html
+++ b/webgl/index.html
@@ -11,5 +11,6 @@
 </p>
 <ul>
   <li><a href="texture/">Simple texture</a></li>
-    <li><a href="gltf/">3D model (glTF 2.0)</a></li>
+  <li><a href="gltf/">3D model (glTF 2.0)</a></li>
+  <li><a href="encode_test/">Texture encoding test</a></li>
 </ul>
diff --git a/webgl/texture/assets/kodim01_mipmapped.basis b/webgl/texture/assets/kodim01_mipmapped.basis
new file mode 100644
index 0000000..dfaf2b5
--- /dev/null
+++ b/webgl/texture/assets/kodim01_mipmapped.basis
Binary files differ
diff --git a/webgl/texture/assets/kodim18_uastc.basis b/webgl/texture/assets/kodim18_uastc.basis
new file mode 100644
index 0000000..ca13590
--- /dev/null
+++ b/webgl/texture/assets/kodim18_uastc.basis
Binary files differ
diff --git a/webgl/texture/index.html b/webgl/texture/index.html
index b0d7473..b346ece 100644
--- a/webgl/texture/index.html
+++ b/webgl/texture/index.html
@@ -103,6 +103,7 @@
 COMPRESSED_RGB_PVRTC_4BPPV1_IMG = 0x8C00;
 COMPRESSED_RGBA_PVRTC_4BPPV1_IMG = 0x8C02;
 
+// Same as the Module.transcoder_texture_format enum
 BASIS_FORMAT = {
   cTFETC1: 0,
   cTFETC2: 1,
@@ -120,6 +121,11 @@
   cTFRGB565: 14,
   cTFBGR565: 15,
   cTFRGBA4444: 16,
+  cTFFXT1_RGB: 17,
+  cTFPVRTC2_4_RGB: 18,
+  cTFPVRTC2_4_RGBA: 19,
+  cTFETC2_EAC_R11: 20,              
+  cTFETC2_EAC_RG11: 21  
 };
 
 BASIS_FORMAT_NAMES = {};
@@ -149,6 +155,61 @@
   renderer.drawTexture(tex, displayWidth, displayHeight, drawMode);
 }
 
+function dumpBasisFileDesc(basisFile)
+{
+  var basisFileDesc = basisFile.getFileDesc();
+
+  log('------');  
+  log('getFileDesc():');
+  log('version: ' + basisFileDesc.version);
+  log('us per frame: ' + basisFileDesc.usPerFrame);
+  log('total images: ' + basisFileDesc.totalImages);
+  log('userdata0: ' + basisFileDesc.userdata0 + ' userdata1: ' + basisFileDesc.userdata1);
+  log('texFormat: ' + basisFileDesc.texFormat);
+  log('yFlipped: ' + basisFileDesc.yFlipped + ' hasAlphaSlices: ' + basisFileDesc.hasAlphaSlices);
+  
+  if (basisFileDesc.texFormat == Module.basis_tex_format.cETC1S.value)
+  {
+      log('numEndpoints: ' + basisFileDesc.numEndpoints);
+      log('endpointPaletteOfs: ' + basisFileDesc.endpointPaletteOfs);
+      log('endpointPaletteLen: ' + basisFileDesc.endpointPaletteLen);
+      log('numSelectors: ' + basisFileDesc.numSelectors);
+      log('selectorPaletteOfs: ' + basisFileDesc.selectorPaletteOfs);
+      log('selectorPaletteLen: ' + basisFileDesc.selectorPaletteLen);
+      log('tablesOfs: ' + basisFileDesc.tablesOfs);
+      log('tablesLen: ' + basisFileDesc.tablesLen);
+  }
+  log('------');
+  log('getImageDesc() for all images:');
+  var image_index;
+  for (image_index = 0; image_index < basisFileDesc.totalImages; image_index++)
+  {
+     log('image: ' + image_index);
+     
+     var basisImageDesc = basisFile.getImageDesc(image_index);
+     
+     log('origWidth: ' + basisImageDesc.origWidth + ' origWidth: ' + basisImageDesc.origHeight);
+     log('numBlocksX: ' + basisImageDesc.numBlocksX + ' origWidth: ' + basisImageDesc.numBlocksY);
+     log('numLevels: ' + basisImageDesc.numLevels);
+     log('alphaFlag: ' + basisImageDesc.alphaFlag + ' iframeFlag: ' + basisImageDesc.iframeFlag);
+
+     log('getImageLevelDesc() for all mipmap levels:');
+     var level_index;
+     for (level_index = 0; level_index < basisImageDesc.numLevels; level_index++)
+     {
+        var basisImageLevelDesc = basisFile.getImageLevelDesc(image_index, level_index);
+        
+        log('level: ' + level_index + 
+            ' rgb_file_offset: ' + basisImageLevelDesc.rgbFileOfs + ' rgb_file_len: ' + basisImageLevelDesc.rgbFileLen);
+
+        if (basisFileDesc.hasAlphaSlices)           
+            log('alpha_file_offset: ' + basisImageLevelDesc.alphaFileOfs + ' alpha_file_len: ' + basisImageLevelDesc.alphaFileLen);
+     }
+  }
+  
+  log('------');
+}
+
 function dataLoaded(data)
 {
   log('Done loading .basis file, decoded header:');
@@ -165,7 +226,9 @@
   images = basisFile.getNumImages();
   levels = basisFile.getNumLevels(0);
   has_alpha = basisFile.getHasAlpha();
-
+  
+  dumpBasisFileDesc(basisFile);
+  
   if (!width || !height || !images || !levels) {
     console.warn('Invalid .basis file');
     basisFile.close();
@@ -237,6 +300,8 @@
   }
 
   elem('format').innerText = formatString;
+  
+  log('format: ' + format);
 
   if (!basisFile.startTranscoding()) {
     log('startTranscoding failed');
@@ -245,20 +310,146 @@
     basisFile.delete();
     return;
   }
-
+  
+  const isUncompressedFormat = Module.formatIsUncompressed(format);
+  
+  const blockWidth = isUncompressedFormat ? 1 : 4, blockHeight = isUncompressedFormat ? 1 : 4;
+  
+  const bytesPerBlockOrPixel = Module.getBytesPerBlockOrPixel(format);
+  log('isUncompressedFormat: ' + isUncompressedFormat + ' bytesPerBlockOrPixel: ' + bytesPerBlockOrPixel);
+      
   const dstSize = basisFile.getImageTranscodedSizeInBytes(0, 0, format);
   const dst = new Uint8Array(dstSize);
   
-  log(dstSize);
+//  log('getImageTranscodedSizeInBytes() returned ' + dstSize);
 
-//  if (!basisFile.transcodeImage(dst, 0, 0, format, 1, 0)) {
-  if (!basisFile.transcodeImage(dst, 0, 0, format, 0, 0)) {
-    log('basisFile.transcodeImage failed');
-    console.warn('transcodeImage failed');
-    basisFile.close();
-    basisFile.delete();
-       
-    return;
+  // Use the low or high level transcoding API's. The high level API's require .basis files, while the low-level API's just work off blobs of memory and parameters. 
+  if (elem('ContainerIndependentTranscoding').checked)
+  {
+      // Always transcode the first image and the first mipmap level
+      const image_index = 0;
+      const level_index = 0;
+      
+      // Get the .basis file description
+	  var basisFileDesc = basisFile.getFileDesc();
+
+	  // Get the description of the file's first image (there could be multiple images, for texture arrays or videos)
+      var basisImageDesc = basisFile.getImageDesc(image_index);
+
+      // Get the description of this image's mipmap level
+      var basisImageLevelDesc = basisFile.getImageLevelDesc(image_index, level_index);
+      
+      var status = false;
+
+      // If we're transcoding to ETC1S, use the LowLevelETC1SImageTranscoder class. Otherwise use the transcodeUASTCImage() function.
+      if (basisFileDesc.texFormat == Module.basis_tex_format.cETC1S.value)
+      {
+	     // Create an instance of the LowLevelETC1SImageTranscoder class.
+         const etc1s_transcoder = new Module.LowLevelETC1SImageTranscoder();
+
+         // Create Uint8Array's pointing into the various bits of the .basis file holding the compressed data for the codebooks and the Huffman tables.
+         var selectorPalette = new Uint8Array(data, basisFileDesc.selectorPaletteOfs, basisFileDesc.selectorPaletteLen);
+         var endpointPalette = new Uint8Array(data, basisFileDesc.endpointPaletteOfs, basisFileDesc.endpointPaletteLen);
+         var tables = new Uint8Array(data, basisFileDesc.tablesOfs, basisFileDesc.tablesLen);
+
+         // Create a Uint8Array pointing to the image's compressed data. 
+		 // If it's an opaque .basis file, there will only be RGB data. For transparant .basis files, each RGB slice will be immediately followed by an alpha slice.
+		 // Compressed ETC1S alpha data is guaranteed to immediately follow the RGB data (it's always at odd slices in the .basis file).
+         var compData = new Uint8Array(data, basisImageLevelDesc.rgbFileOfs, basisImageLevelDesc.rgbFileLen + basisImageLevelDesc.alphaFileLen);
+
+         // Decompress the palettes. This only has to be done once for each .basis file.
+		 var status = etc1s_transcoder.decodePalettes(basisFileDesc.numEndpoints, endpointPalette, basisFileDesc.numSelectors, selectorPalette);
+         if (status)
+         {
+			 // Decompress the Huffman tables. This only has to be done once for each .basis file.
+             status = etc1s_transcoder.decodeTables(tables);
+             if (status)
+             {
+			    // Now transcode the image using the container independent transcode API. This API does not interpret any .basis file structures - only the compressed ETC1S data.
+                status = etc1s_transcoder.transcodeImage(
+                    format,
+                    dst, dstSize / bytesPerBlockOrPixel,
+                    compData,
+                    basisImageDesc.numBlocksX, basisImageDesc.numBlocksY, basisImageDesc.origWidth, basisImageDesc.origHeight, level_index,
+                    0, basisImageLevelDesc.rgbFileLen, basisFileDesc.hasAlphaSlices ? basisImageLevelDesc.rgbFileLen : 0, basisImageLevelDesc.alphaFileLen,
+                    0,
+                    basisFileDesc.hasAlphaSlices,
+                    basisFileDesc.isVideo,
+                    0,
+                    0);
+                    
+                if (!status)
+                  log('transcodeImage() failed');
+             }
+             else
+             {
+               log('decodeTables() failed');
+             }
+         }
+         else
+         {
+            log('decodePalettes() failed');
+         }
+         
+         etc1s_transcoder.delete();
+         
+         if (!status)
+         {
+            log('etc1s_transcoder failed');
+            console.warn('etc1s_transcoder failed');
+            basisFile.close();
+            basisFile.delete();
+            return;
+         }
+         else
+         {
+            log('Successfully called etc1s_transcoder.transcodeImage()');
+         }
+      }
+      else
+      {
+         // Create a Uint8Array pointing to the image's compressed data. 
+         var compData = new Uint8Array(data, basisImageLevelDesc.rgbFileOfs, basisImageLevelDesc.rgbFileLen);
+
+         // Transcode the UASTC texture data to the desired output format.
+         status = Module.transcodeUASTCImage(
+            format,
+            dst, dstSize / bytesPerBlockOrPixel,
+            compData,
+            basisImageDesc.numBlocksX, basisImageDesc.numBlocksY, basisImageDesc.origWidth, basisImageDesc.origHeight, level_index,
+            0, basisImageLevelDesc.rgbFileLen, 
+            0,
+            basisFileDesc.hasAlphaSlices,
+            basisFileDesc.isVideo,
+            0,
+            0,
+            -1, -1);
+            
+         if (!status)
+         {
+            log('transcodeUASTCImage() failed');
+            console.warn('transcodeUASTCImage() failed');
+            basisFile.close();
+            basisFile.delete();
+            return;
+         }
+         else
+         {
+            log('Successfully called transcodeUASTCImage()');
+         }
+      }
+  }
+  else
+  {
+    // Use the high-level transcode API, which requires a .basis file. 
+    if (!basisFile.transcodeImage(dst, 0, 0, format, 0, 0)) {
+        log('basisFile.transcodeImage failed');
+        console.warn('transcodeImage failed');
+        basisFile.close();
+        basisFile.delete();
+        
+        return;
+    }
   }
 
   const elapsed = performance.now() - startTime;
@@ -347,13 +538,18 @@
   <br>
   <br>
       .basis file:
-      <input id="file" type="text" size=30 value="assets/kodim26_uastc_1024.basis"></input>
+      <input id="file" type="text" size=30 value="assets/kodim03.basis"></input>
       <input type="button" value="Run!" onclick="runLoadFile()"></input>
   <br>
   <br>
       <input type="button" value="Alpha blend" onclick="alphaBlend()"></input>
       <input type="button" value="View RGB" onclick="viewRGB()"></input>
      <input type="button" value="View Alpha" onclick="viewAlpha()"></input>
+  
+  <br>
+  <br>
+      Use Container Independent Transcoding API's:
+      <input type="checkbox" id="ContainerIndependentTranscoding">
 
   <div style="position:absolute; left: 525px; top:130px; font-size: 20pt; font-weight: bold; color: red">
     <div id="no-compressed-tex" style="display: none; width: 768px; font-size: 20pt; font-weight: bold; color: red">
diff --git a/webgl/transcoder/CMakeLists.txt b/webgl/transcoder/CMakeLists.txt
index 2216c53..70f963b 100644
--- a/webgl/transcoder/CMakeLists.txt
+++ b/webgl/transcoder/CMakeLists.txt
@@ -10,8 +10,8 @@
     basis_wrappers.cpp
   )
 
-  target_compile_definitions(basis_transcoder.js PRIVATE NDEBUG BASISD_SUPPORT_UASTC=1 BASISD_SUPPORT_BC7=1 BASISD_SUPPORT_ATC=0 BASISD_SUPPORT_ASTC_HIGHER_OPAQUE_QUALITY=0 BASISD_SUPPORT_PVRTC2=0 BASISD_SUPPORT_FXT1=0 BASISD_SUPPORT_ETC2_EAC_RG11=0)
-  target_compile_options(basis_transcoder.js PRIVATE -O3)
+  target_compile_definitions(basis_transcoder.js PRIVATE NDEBUG BASISD_SUPPORT_UASTC=1 BASISD_SUPPORT_BC7=1 BASISD_SUPPORT_ATC=0 BASISD_SUPPORT_ASTC_HIGHER_OPAQUE_QUALITY=0 BASISD_SUPPORT_PVRTC2=0 BASISD_SUPPORT_FXT1=0 BASISD_SUPPORT_ETC2_EAC_RG11=0 BASISU_SUPPORT_ENCODING=0)
+  target_compile_options(basis_transcoder.js PRIVATE -O3 -fno-strict-aliasing)
   target_include_directories(basis_transcoder.js PRIVATE ../../transcoder)
 
   set_target_properties(basis_transcoder.js PROPERTIES
diff --git a/webgl/transcoder/basis_wrappers.cpp b/webgl/transcoder/basis_wrappers.cpp
index a6cbffe..8056b0d 100644
--- a/webgl/transcoder/basis_wrappers.cpp
+++ b/webgl/transcoder/basis_wrappers.cpp
@@ -1,244 +1,951 @@
-// basis_wrappers.cpp - Simple C-style wrappers to the C++ transcoder for WebGL use.
+// basis_wrappers.cpp - Wrappers to the C++ compressor and transcoder for WebAssembly/WebGL use.
+//
+// Important: 
+// Compile with -fno-strict-aliasing
+// The "initializeBasis()" function MUST be called at least once before using either the compressor or transcoder.
+//
+// There are four main categories of wrappers in this module:
+// 1. Transcoding, low-level .basis file information: See class basis_file. Only depends on transcoder/basisu_transcoder.cpp.
+//    getFileDesc(), getImageDesc(), getImageLevelDesc(): These functions return low-level information about where compressed data is located for each image in a .basis file.
+//    This is useful for when you want to extract the compressed data and embed it into your own file formats, for container independent transcoding.
+//
+// 2. Encoding (optional): See class basis_encoder. Encodes PNG or 32bpp images to .basis files in memory. Must compile with BASISU_SUPPORT_ENCODING=1. 
+//    Requires basisu_transcoder.cpp as well as all the .cpp files in the "encoder" directory. Results in a larger WebAssembly executable.
+//
+// 3. Low level transcoding/container independent transcoding: See class lowlevel_etc1s_image_transcoder or function transcodeUASTCImage(). For
+//    transcoding raw compressed ETC1S/UASTC texture data from non-.basis files (say from KTX2) to GPU texture data.
+//
+// 4. Helpers, transcoder texture format information: See functions getBytesPerBlockOrPixel(), formatHasAlpha(), etc.
+
+// If BASISU_SUPPORT_ENCODING is 1, wrappers for the compressor will be included. Otherwise, only the wrappers for the transcoder will be compiled in.
+#ifndef BASISU_SUPPORT_ENCODING
+#define BASISU_SUPPORT_ENCODING 0
+#endif
+
+// Enable debug printf()'s in this module.
+#ifndef BASISU_DEBUG_PRINTF
+#define BASISU_DEBUG_PRINTF 0
+#endif
+
 #include "basisu_transcoder.h"
 #include <emscripten/bind.h>
 #include <algorithm>
 
+#if BASISU_SUPPORT_ENCODING
+#include "../../encoder/basisu_comp.h"
+#include "../../encoder/basisu_resampler_filters.h"
+#endif
+
 using namespace emscripten;
 using namespace basist;
+using namespace basisu;
 
-static basist::etc1_global_selector_codebook *g_pGlobal_codebook;
+static basist::etc1_global_selector_codebook* g_pGlobal_codebook;
 
 void basis_init()
 {
-  basisu_transcoder_init();
+#if BASISU_DEBUG_PRINTF
+	printf("basis_init()\n");
+#endif   
 
-  if (!g_pGlobal_codebook)
-    g_pGlobal_codebook = new basist::etc1_global_selector_codebook(g_global_selector_cb_size, g_global_selector_cb);
+	if (g_pGlobal_codebook)
+		return;
+
+#if BASISU_SUPPORT_ENCODING
+	basisu_encoder_init();
+#endif
+
+	basisu_transcoder_init();
+
+	g_pGlobal_codebook = new basist::etc1_global_selector_codebook(g_global_selector_cb_size, g_global_selector_cb);
+}
+
+static void copy_from_jsbuffer(const emscripten::val& srcBuffer, std::vector<uint8_t>& dstVec)
+{
+	unsigned int length = srcBuffer["length"].as<unsigned int>();
+
+	dstVec.resize(length);
+
+	emscripten::val memory = emscripten::val::module_property("HEAP8")["buffer"];
+	emscripten::val memoryView = srcBuffer["constructor"].new_(memory, reinterpret_cast<uintptr_t>(dstVec.data()), length);
+	
+	// Copy the bytes from the Javascript buffer.
+	memoryView.call<void>("set", srcBuffer);
+}
+
+static bool copy_to_jsbuffer(const emscripten::val& dstBuffer, const std::vector<uint8_t>& srcVec)
+{
+	if (srcVec.empty())
+	{
+#if BASISU_DEBUG_PRINTF	
+		printf("copy_to_jsbuffer: Provided source buffer is empty\n");
+#endif
+		return false;
+	}
+		
+	// Make sure the provided buffer from Javascript is big enough. If not, bail.
+	int dstBufferLen = dstBuffer["byteLength"].as<int>();
+			
+	if (srcVec.size() > dstBufferLen)
+	{
+#if BASISU_DEBUG_PRINTF	
+		printf("copy_to_jsbuffer: Provided destination buffer is too small (wanted %u bytes, got %u bytes)!\n", (uint32_t)srcVec.size(), dstBufferLen);
+#endif
+		assert(0);
+		return false;
+	}
+
+	emscripten::val memory = emscripten::val::module_property("HEAP8")["buffer"];
+	emscripten::val memoryView = emscripten::val::global("Uint8Array").new_(memory, reinterpret_cast<uintptr_t>(srcVec.data()), srcVec.size());
+
+	// Copy the bytes into the Javascript buffer.
+	dstBuffer.call<void>("set", memoryView);
+	
+	return true;
 }
 
 #define MAGIC 0xDEADBEE1
 
-struct basis_file
+struct basis_file_desc
 {
-  int m_magic = 0;
-	basisu_transcoder m_transcoder;
-  std::vector<uint8_t> m_file;
+	uint32_t m_version;
+	
+	uint32_t m_us_per_frame;
+	
+	uint32_t m_total_images;
+	
+	uint32_t m_userdata0;
+	uint32_t m_userdata1;
+	
+	// Type of texture (cETC1S or cUASTC4x4)
+	uint32_t m_tex_format; // basis_tex_format 
+	
+	bool m_y_flipped;
+	bool m_has_alpha_slices;
+		
+	// ETC1S endpoint codebook
+	uint32_t m_num_endpoints;
+	uint32_t m_endpoint_palette_ofs;
+	uint32_t m_endpoint_palette_len;
 
-  basis_file(const emscripten::val& jsBuffer)
-    : m_file([&]() {
-        size_t byteLength = jsBuffer["byteLength"].as<size_t>();
-        return std::vector<uint8_t>(byteLength);
-      }()),
-      m_transcoder(g_pGlobal_codebook)
-  {
-    unsigned int length = jsBuffer["length"].as<unsigned int>();
-    emscripten::val memory = emscripten::val::module_property("HEAP8")["buffer"];
-    emscripten::val memoryView = jsBuffer["constructor"].new_(memory, reinterpret_cast<uintptr_t>(m_file.data()), length);
-    memoryView.call<void>("set", jsBuffer);
+	// ETC1S selector codebook
+	uint32_t m_num_selectors;
+	uint32_t m_selector_palette_ofs;
+	uint32_t m_selector_palette_len;
 
-    if (!m_transcoder.validate_header(m_file.data(), m_file.size())) {
-      m_file.clear();
-    }
-
-    // Initialized after validation
-    m_magic = MAGIC;
-  }
-
-  void close() {
-    assert(m_magic == MAGIC);
-    m_file.clear();
-  }
-
-  uint32_t getHasAlpha() {
-    assert(m_magic == MAGIC);
-    if (m_magic != MAGIC)
-      return 0;
-
-    basisu_image_level_info li;
-    if (!m_transcoder.get_image_level_info(m_file.data(), m_file.size(), li, 0, 0))
-      return 0;
-
-    return li.m_alpha_flag;
-  }
-
-  uint32_t getNumImages() {
-    assert(m_magic == MAGIC);
-    if (m_magic != MAGIC)
-      return 0;
-
-    return m_transcoder.get_total_images(m_file.data(), m_file.size());
-  }
-
-  uint32_t getNumLevels(uint32_t image_index) {
-    assert(m_magic == MAGIC);
-    if (m_magic != MAGIC)
-      return 0;
-
-    basisu_image_info ii;
-    if (!m_transcoder.get_image_info(m_file.data(), m_file.size(), ii, image_index))
-      return 0;
-
-    return ii.m_total_levels;
-  }
-
-  uint32_t getImageWidth(uint32_t image_index, uint32_t level_index) {
-    assert(m_magic == MAGIC);
-    if (m_magic != MAGIC)
-      return 0;
-
-    uint32_t orig_width, orig_height, total_blocks;
-    if (!m_transcoder.get_image_level_desc(m_file.data(), m_file.size(), image_index, level_index, orig_width, orig_height, total_blocks))
-      return 0;
-
-    return orig_width;
-  }
-
-  uint32_t getImageHeight(uint32_t image_index, uint32_t level_index) {
-    assert(m_magic == MAGIC);
-    if (m_magic != MAGIC)
-      return 0;
-
-    uint32_t orig_width, orig_height, total_blocks;
-    if (!m_transcoder.get_image_level_desc(m_file.data(), m_file.size(), image_index, level_index, orig_width, orig_height, total_blocks))
-      return 0;
-
-    return orig_height;
-  }
-
-  uint32_t getImageTranscodedSizeInBytes(uint32_t image_index, uint32_t level_index, uint32_t format) {
-    assert(m_magic == MAGIC);
-    if (m_magic != MAGIC)
-      return 0;
-
-    if (format >= (int)transcoder_texture_format::cTFTotalTextureFormats)
-      return 0;
-
-	 uint32_t orig_width, orig_height, total_blocks;
-	 if (!m_transcoder.get_image_level_desc(m_file.data(), m_file.size(), image_index, level_index, orig_width, orig_height, total_blocks))
-		 return 0;
-
-	 const transcoder_texture_format transcoder_format = static_cast<transcoder_texture_format>(format);
-
-	 if (basis_transcoder_format_is_uncompressed(transcoder_format))
-	 {
-		 // Uncompressed formats are just plain raster images.
-		 const uint32_t bytes_per_pixel = basis_get_uncompressed_bytes_per_pixel(transcoder_format);
-		 const uint32_t bytes_per_line = orig_width * bytes_per_pixel;
-		 const uint32_t bytes_per_slice = bytes_per_line * orig_height;
-		 return bytes_per_slice;
-	 }
-	 else
-	 {
-		 // Compressed formats are 2D arrays of blocks.
-		 const uint32_t bytes_per_block = basis_get_bytes_per_block_or_pixel(transcoder_format);
-
-		 if (transcoder_format == transcoder_texture_format::cTFPVRTC1_4_RGB || transcoder_format == transcoder_texture_format::cTFPVRTC1_4_RGBA)
-		 {
-			 // For PVRTC1, Basis only writes (or requires) total_blocks * bytes_per_block. But GL requires extra padding for very small textures: 
-			  // https://www.khronos.org/registry/OpenGL/extensions/IMG/IMG_texture_compression_pvrtc.txt
-			 const uint32_t width = (orig_width + 3) & ~3;
-			 const uint32_t height = (orig_height + 3) & ~3;
-			 const uint32_t size_in_bytes = (std::max(8U, width) * std::max(8U, height) * 4 + 7) / 8;
-			 return size_in_bytes;
-		 }
-
-		 return total_blocks * bytes_per_block;
-	 }
-  }
-  
-  bool isUASTC() {
-    assert(m_magic == MAGIC);
-    if (m_magic != MAGIC)
-      return false;
-
-    return m_transcoder.get_tex_format(m_file.data(), m_file.size()) == basis_tex_format::cUASTC4x4;
-  }
-
-  uint32_t startTranscoding() {
-    assert(m_magic == MAGIC);
-    if (m_magic != MAGIC)
-      return 0;
-
-    return m_transcoder.start_transcoding(m_file.data(), m_file.size());
-  }
-
-  uint32_t transcodeImage(const emscripten::val& dst, uint32_t image_index, uint32_t level_index, uint32_t format, uint32_t unused, uint32_t get_alpha_for_opaque_formats) {
-     (void)unused;
-     
-	  assert(m_magic == MAGIC);
-	  if (m_magic != MAGIC)
-		  return 0;
-
-	  if (format >= (int)transcoder_texture_format::cTFTotalTextureFormats)
-		  return 0;
-
-	  const transcoder_texture_format transcoder_format = static_cast<transcoder_texture_format>(format);
-
-     uint32_t orig_width, orig_height, total_blocks;
-	  if (!m_transcoder.get_image_level_desc(m_file.data(), m_file.size(), image_index, level_index, orig_width, orig_height, total_blocks))
-		  return 0;
-	  
-	  std::vector<uint8_t> dst_data;
-	  
-	  uint32_t flags = get_alpha_for_opaque_formats ? cDecodeFlagsTranscodeAlphaDataToOpaqueFormats : 0;
-
-	  uint32_t status;
-
-	  if (basis_transcoder_format_is_uncompressed(transcoder_format))
-	  {
-		  const uint32_t bytes_per_pixel = basis_get_uncompressed_bytes_per_pixel(transcoder_format);
-		  const uint32_t bytes_per_line = orig_width * bytes_per_pixel;
-		  const uint32_t bytes_per_slice = bytes_per_line * orig_height;
-
-		  dst_data.resize(bytes_per_slice);
-
-		  status = m_transcoder.transcode_image_level(
-			  m_file.data(), m_file.size(), image_index, level_index,
-			  dst_data.data(), orig_width * orig_height,
-			  transcoder_format,
-			  flags,
-			  orig_width,
-			  nullptr,
-			  orig_height);
-	  }
-	  else
-	  {
-		  uint32_t bytes_per_block = basis_get_bytes_per_block_or_pixel(transcoder_format);
-
-		  uint32_t required_size = total_blocks * bytes_per_block;
-
-		  if (transcoder_format == transcoder_texture_format::cTFPVRTC1_4_RGB || transcoder_format == transcoder_texture_format::cTFPVRTC1_4_RGBA)
-		  {
-			  // For PVRTC1, Basis only writes (or requires) total_blocks * bytes_per_block. But GL requires extra padding for very small textures: 
-			  // https://www.khronos.org/registry/OpenGL/extensions/IMG/IMG_texture_compression_pvrtc.txt
-			  // The transcoder will clear the extra bytes followed the used blocks to 0.
-			  const uint32_t width = (orig_width + 3) & ~3;
-			  const uint32_t height = (orig_height + 3) & ~3;
-			  required_size = (std::max(8U, width) * std::max(8U, height) * 4 + 7) / 8;
-			  assert(required_size >= total_blocks * bytes_per_block);
-		  }
-
-		  dst_data.resize(required_size);
-
-		  status = m_transcoder.transcode_image_level(
-			  m_file.data(), m_file.size(), image_index, level_index,
-			  dst_data.data(), dst_data.size() / bytes_per_block,
-			  static_cast<basist::transcoder_texture_format>(format),
-			  flags);
-	  }
-
-	  emscripten::val memory = emscripten::val::module_property("HEAP8")["buffer"];
-	  emscripten::val memoryView = emscripten::val::global("Uint8Array").new_(memory, reinterpret_cast<uintptr_t>(dst_data.data()), dst_data.size());
-
-	  dst.call<void>("set", memoryView);
-	  return status;
-  }
+	// Huffman codelength tables	
+	uint32_t m_tables_ofs;
+	uint32_t m_tables_len;
 };
 
-EMSCRIPTEN_BINDINGS(basis_transcoder) {
+struct basis_image_desc
+{
+	uint32_t m_orig_width;
+	uint32_t m_orig_height;
+	uint32_t m_num_blocks_x;
+	uint32_t m_num_blocks_y;
+	uint32_t m_num_levels;
 
+	// Will be true if the image has alpha (for UASTC this may vary per-image)
+	bool m_alpha_flag;	
+	bool m_iframe_flag;
+};
+
+struct basis_image_level_desc
+{
+	// File offset/length of the compressed ETC1S or UASTC texture data.
+	uint32_t m_rgb_file_ofs;
+	uint32_t m_rgb_file_len;
+
+	// Optional alpha data file offset/length - will be 0's for UASTC or opaque ETC1S files.	
+	uint32_t m_alpha_file_ofs;
+	uint32_t m_alpha_file_len;
+};
+
+struct basis_file
+{
+	int m_magic = 0;
+	basisu_transcoder m_transcoder;
+	std::vector<uint8_t> m_file;
+
+	basis_file(const emscripten::val& jsBuffer)
+		: m_file([&]() {
+		size_t byteLength = jsBuffer["byteLength"].as<size_t>();
+		return std::vector<uint8_t>(byteLength);
+			}()),
+		m_transcoder(g_pGlobal_codebook)
+	{
+		if (!g_pGlobal_codebook)
+		{
+#if BASISU_DEBUG_PRINTF   
+			printf("basis_file::basis_file: Must call basis_init() first!\n");
+#endif   		
+			assert(0);
+			return;
+		}
+	
+		unsigned int length = jsBuffer["length"].as<unsigned int>();
+		emscripten::val memory = emscripten::val::module_property("HEAP8")["buffer"];
+		emscripten::val memoryView = jsBuffer["constructor"].new_(memory, reinterpret_cast<uintptr_t>(m_file.data()), length);
+		memoryView.call<void>("set", jsBuffer);
+
+		if (!m_transcoder.validate_header(m_file.data(), m_file.size())) {
+			m_file.clear();
+		}
+
+		// Initialized after validation
+		m_magic = MAGIC;
+	}
+
+			void close() {
+				assert(m_magic == MAGIC);
+				m_file.clear();
+			}
+
+			uint32_t getHasAlpha() {
+				assert(m_magic == MAGIC);
+				if (m_magic != MAGIC)
+					return 0;
+
+				basisu_image_level_info li;
+				if (!m_transcoder.get_image_level_info(m_file.data(), m_file.size(), li, 0, 0))
+					return 0;
+
+				return li.m_alpha_flag;
+			}
+
+			uint32_t getNumImages() {
+				assert(m_magic == MAGIC);
+				if (m_magic != MAGIC)
+					return 0;
+
+				return m_transcoder.get_total_images(m_file.data(), m_file.size());
+			}
+
+			uint32_t getNumLevels(uint32_t image_index) {
+				assert(m_magic == MAGIC);
+				if (m_magic != MAGIC)
+					return 0;
+
+				basisu_image_info ii;
+				if (!m_transcoder.get_image_info(m_file.data(), m_file.size(), ii, image_index))
+					return 0;
+
+				return ii.m_total_levels;
+			}
+
+			uint32_t getImageWidth(uint32_t image_index, uint32_t level_index) {
+				assert(m_magic == MAGIC);
+				if (m_magic != MAGIC)
+					return 0;
+
+				uint32_t orig_width, orig_height, total_blocks;
+				if (!m_transcoder.get_image_level_desc(m_file.data(), m_file.size(), image_index, level_index, orig_width, orig_height, total_blocks))
+					return 0;
+
+				return orig_width;
+			}
+
+			uint32_t getImageHeight(uint32_t image_index, uint32_t level_index) {
+				assert(m_magic == MAGIC);
+				if (m_magic != MAGIC)
+					return 0;
+
+				uint32_t orig_width, orig_height, total_blocks;
+				if (!m_transcoder.get_image_level_desc(m_file.data(), m_file.size(), image_index, level_index, orig_width, orig_height, total_blocks))
+					return 0;
+
+				return orig_height;
+			}
+									
+			basis_file_desc getFileDesc() {
+				basis_file_desc result;
+				memset(&result, 0, sizeof(result));
+				
+				assert(m_magic == MAGIC);
+				if (m_magic != MAGIC)
+					return result;
+								
+				basisu_file_info file_info;
+								
+				if (!m_transcoder.get_file_info(m_file.data(), m_file.size(), file_info))
+				{
+					assert(0);
+					return result;
+				}
+				
+				result.m_version = file_info.m_version;
+				result.m_us_per_frame = file_info.m_us_per_frame;
+				result.m_total_images = file_info.m_total_images;
+				result.m_userdata0 = file_info.m_userdata0;
+				result.m_userdata1 = file_info.m_userdata1;
+				result.m_tex_format = static_cast<uint32_t>(file_info.m_tex_format);
+				result.m_y_flipped = file_info.m_y_flipped;
+				result.m_has_alpha_slices = file_info.m_has_alpha_slices;
+				
+				result.m_num_endpoints = file_info.m_total_endpoints;
+				result.m_endpoint_palette_ofs = file_info.m_endpoint_codebook_ofs;
+				result.m_endpoint_palette_len = file_info.m_endpoint_codebook_size;
+				
+				result.m_num_selectors = file_info.m_total_selectors;
+				result.m_selector_palette_ofs = file_info.m_selector_codebook_ofs;
+				result.m_selector_palette_len = file_info.m_selector_codebook_size;
+				
+				result.m_tables_ofs = file_info.m_tables_ofs;
+				result.m_tables_len = file_info.m_tables_size;
+
+				return result;
+			}
+			
+			basis_image_desc getImageDesc(uint32_t image_index) {
+				basis_image_desc result;
+				memset(&result, 0, sizeof(result));
+				
+				assert(m_magic == MAGIC);
+				if (m_magic != MAGIC)
+					return result;
+								
+				basisu_image_info image_info;
+				
+				// bool get_image_info(const void *pData, uint32_t data_size, basisu_image_info &image_info, uint32_t image_index) const;
+				if (!m_transcoder.get_image_info(m_file.data(), m_file.size(), image_info, image_index))
+				{
+					assert(0);
+					return result;
+				}
+				
+				result.m_orig_width = image_info.m_orig_width;
+				result.m_orig_height = image_info.m_orig_height;
+				result.m_num_blocks_x = image_info.m_num_blocks_x;
+				result.m_num_blocks_y = image_info.m_num_blocks_y;
+				result.m_num_levels = image_info.m_total_levels;
+				result.m_alpha_flag = image_info.m_alpha_flag;
+				result.m_iframe_flag = image_info.m_iframe_flag;
+				
+				return result;
+			}
+			
+			basis_image_level_desc getImageLevelDesc(uint32_t image_index, uint32_t level_index) {
+				basis_image_level_desc result;
+				memset(&result, 0, sizeof(result));
+				
+				assert(m_magic == MAGIC);
+				if (m_magic != MAGIC)
+					return result;
+								
+				basisu_image_level_info image_info;
+				
+				if (!m_transcoder.get_image_level_info(m_file.data(), m_file.size(), image_info, image_index, level_index))
+				{
+					assert(0);
+					return result;
+				}
+				
+				result.m_rgb_file_ofs = image_info.m_rgb_file_ofs;
+				result.m_rgb_file_len = image_info.m_rgb_file_len;
+				result.m_alpha_file_ofs = image_info.m_alpha_file_ofs;
+				result.m_alpha_file_len = image_info.m_alpha_file_len;
+				
+				return result;
+			}
+
+			uint32_t getImageTranscodedSizeInBytes(uint32_t image_index, uint32_t level_index, uint32_t format) {
+				assert(m_magic == MAGIC);
+				if (m_magic != MAGIC)
+					return 0;
+
+				if (format >= (int)transcoder_texture_format::cTFTotalTextureFormats)
+					return 0;
+
+				uint32_t orig_width, orig_height, total_blocks;
+				if (!m_transcoder.get_image_level_desc(m_file.data(), m_file.size(), image_index, level_index, orig_width, orig_height, total_blocks))
+					return 0;
+
+				const transcoder_texture_format transcoder_format = static_cast<transcoder_texture_format>(format);
+
+				if (basis_transcoder_format_is_uncompressed(transcoder_format))
+				{
+					// Uncompressed formats are just plain raster images.
+					const uint32_t bytes_per_pixel = basis_get_uncompressed_bytes_per_pixel(transcoder_format);
+					const uint32_t bytes_per_line = orig_width * bytes_per_pixel;
+					const uint32_t bytes_per_slice = bytes_per_line * orig_height;
+					return bytes_per_slice;
+				}
+				else
+				{
+					// Compressed formats are 2D arrays of blocks.
+					const uint32_t bytes_per_block = basis_get_bytes_per_block_or_pixel(transcoder_format);
+
+					if (transcoder_format == transcoder_texture_format::cTFPVRTC1_4_RGB || transcoder_format == transcoder_texture_format::cTFPVRTC1_4_RGBA)
+					{
+						// For PVRTC1, Basis only writes (or requires) total_blocks * bytes_per_block. But GL requires extra padding for very small textures: 
+						 // https://www.khronos.org/registry/OpenGL/extensions/IMG/IMG_texture_compression_pvrtc.txt
+						const uint32_t width = (orig_width + 3) & ~3;
+						const uint32_t height = (orig_height + 3) & ~3;
+						const uint32_t size_in_bytes = (std::max(8U, width) * std::max(8U, height) * 4 + 7) / 8;
+						return size_in_bytes;
+					}
+
+					return total_blocks * bytes_per_block;
+				}
+			}
+
+			bool isUASTC() {
+				assert(m_magic == MAGIC);
+				if (m_magic != MAGIC)
+					return false;
+
+				return m_transcoder.get_tex_format(m_file.data(), m_file.size()) == basis_tex_format::cUASTC4x4;
+			}
+
+			uint32_t startTranscoding() {
+				assert(m_magic == MAGIC);
+				if (m_magic != MAGIC)
+					return 0;
+
+				return m_transcoder.start_transcoding(m_file.data(), m_file.size());
+			}
+
+			uint32_t transcodeImage(const emscripten::val& dst, uint32_t image_index, uint32_t level_index, uint32_t format, uint32_t unused, uint32_t get_alpha_for_opaque_formats) {
+				(void)unused;
+
+				assert(m_magic == MAGIC);
+				if (m_magic != MAGIC)
+					return 0;
+
+				if (format >= (int)transcoder_texture_format::cTFTotalTextureFormats)
+					return 0;
+
+				const transcoder_texture_format transcoder_format = static_cast<transcoder_texture_format>(format);
+
+				uint32_t orig_width, orig_height, total_blocks;
+				if (!m_transcoder.get_image_level_desc(m_file.data(), m_file.size(), image_index, level_index, orig_width, orig_height, total_blocks))
+					return 0;
+
+				std::vector<uint8_t> dst_data;
+
+				uint32_t flags = get_alpha_for_opaque_formats ? cDecodeFlagsTranscodeAlphaDataToOpaqueFormats : 0;
+
+				uint32_t status;
+
+				if (basis_transcoder_format_is_uncompressed(transcoder_format))
+				{
+					const uint32_t bytes_per_pixel = basis_get_uncompressed_bytes_per_pixel(transcoder_format);
+					const uint32_t bytes_per_line = orig_width * bytes_per_pixel;
+					const uint32_t bytes_per_slice = bytes_per_line * orig_height;
+
+					dst_data.resize(bytes_per_slice);
+
+					status = m_transcoder.transcode_image_level(
+						m_file.data(), m_file.size(), image_index, level_index,
+						dst_data.data(), orig_width * orig_height,
+						transcoder_format,
+						flags,
+						orig_width,
+						nullptr,
+						orig_height);
+				}
+				else
+				{
+					uint32_t bytes_per_block = basis_get_bytes_per_block_or_pixel(transcoder_format);
+
+					uint32_t required_size = total_blocks * bytes_per_block;
+
+					if (transcoder_format == transcoder_texture_format::cTFPVRTC1_4_RGB || transcoder_format == transcoder_texture_format::cTFPVRTC1_4_RGBA)
+					{
+						// For PVRTC1, Basis only writes (or requires) total_blocks * bytes_per_block. But GL requires extra padding for very small textures: 
+						// https://www.khronos.org/registry/OpenGL/extensions/IMG/IMG_texture_compression_pvrtc.txt
+						// The transcoder will clear the extra bytes followed the used blocks to 0.
+						const uint32_t width = (orig_width + 3) & ~3;
+						const uint32_t height = (orig_height + 3) & ~3;
+						required_size = (std::max(8U, width) * std::max(8U, height) * 4 + 7) / 8;
+						assert(required_size >= total_blocks * bytes_per_block);
+					}
+
+					dst_data.resize(required_size);
+
+					status = m_transcoder.transcode_image_level(
+						m_file.data(), m_file.size(), image_index, level_index,
+						dst_data.data(), dst_data.size() / bytes_per_block,
+						static_cast<basist::transcoder_texture_format>(format),
+						flags);
+				}
+
+				emscripten::val memory = emscripten::val::module_property("HEAP8")["buffer"];
+				emscripten::val memoryView = emscripten::val::global("Uint8Array").new_(memory, reinterpret_cast<uintptr_t>(dst_data.data()), dst_data.size());
+
+				dst.call<void>("set", memoryView);
+				return status;
+			}
+};
+
+#if BASISU_SUPPORT_ENCODING
+class basis_encoder
+{
+public:
+	basis_compressor_params m_params;
+
+	basis_encoder()
+	{
+	}
+
+	bool set_slice_source_image(uint32_t slice_index, const emscripten::val& src_image_js_val, uint32_t src_image_width, uint32_t src_image_height, bool src_image_is_png)
+	{
+		// Resize the source_images array if necessary
+		if (slice_index >= m_params.m_source_images.size())
+			m_params.m_source_images.resize(slice_index + 1);
+
+		// First copy the src image buffer to the heap.
+		std::vector<uint8_t> src_image_buf;
+		copy_from_jsbuffer(src_image_js_val, src_image_buf);
+
+		// Now extract the source image.
+		image& src_img = m_params.m_source_images[slice_index];
+		if (src_image_is_png)
+		{
+			// It's a PNG file, so try and parse it.
+			if (!load_png(src_image_buf.data(), src_image_buf.size(), src_img, nullptr))
+			{
+#if BASISU_DEBUG_PRINTF
+				printf("basis_encoder::set_slice_source_image: Failed parsing provided PNG file!\n");
+#endif   
+				return false;
+			}
+
+			src_image_width = src_img.get_width();
+			src_image_height = src_img.get_height();
+		}
+		else
+		{
+			// It's a raw image, so check the buffer's size.
+			if (src_image_buf.size() != src_image_width * src_image_height * sizeof(uint32_t))
+			{
+#if BASISU_DEBUG_PRINTF
+				printf("basis_encoder::set_slice_source_image: Provided source buffer has an invalid size!\n");
+#endif   
+				return false;
+			}
+
+			// Copy the raw image's data into our source image.
+			src_img.resize(src_image_width, src_image_height);
+			memcpy(src_img.get_ptr(), src_image_buf.data(), src_image_width * src_image_height * sizeof(uint32_t));
+		}
+		
+		return true;
+	}
+	
+	uint32_t encode(const emscripten::val& dst_basis_file_js_val)
+	{
+		if (!g_pGlobal_codebook)
+		{
+#if BASISU_DEBUG_PRINTF   
+			printf("basis_encoder::encode: Must call basis_init() first!\n");
+#endif   		
+			assert(0);
+			return 0;
+		}
+
+		basist::etc1_global_selector_codebook sel_codebook(basist::g_global_selector_cb_size, basist::g_global_selector_cb);
+
+		// We don't use threading for now, but the compressor needs a job pool.
+		job_pool jpool(1);
+
+		// Initialize the compression parameters structure. This is the same structure that the command line tool fills in.
+		basis_compressor_params &params = m_params;
+
+		params.m_pJob_pool = &jpool;
+
+		// Disabling multithreading for now, which sucks.
+		params.m_multithreading = false;
+		
+		params.m_status_output = params.m_debug;
+
+		params.m_read_source_images = false;
+		params.m_write_output_basis_files = false;
+		params.m_pSel_codebook = &sel_codebook;
+
+		basis_compressor comp;
+
+		if (!comp.init(params))
+		{
+#if BASISU_DEBUG_PRINTF   
+			printf("Failed initializing BasisU compressor! One or more provided parameters may be invalid.\n");
+#endif	  
+			return 0;
+		}
+
+#if BASISU_DEBUG_PRINTF   
+		printf("Begin BasisU compression\n");
+#endif   
+
+		basis_compressor::error_code ec = comp.process();
+
+#if BASISU_DEBUG_PRINTF
+		printf("BasisU compression done, status %u, %u bytes\n", (uint32_t)ec, (uint32_t)comp.get_output_basis_file().size());
+#endif   
+
+		if (ec != basis_compressor::cECSuccess)
+		{
+			// Something failed during compression.
+#if BASISU_DEBUG_PRINTF	  
+			printf("BasisU compression failed with status %u!\n", (uint32_t)ec);
+#endif	  
+			return 0;
+		}
+
+		// Compression succeeded, so copy the .basis file bytes to the caller's buffer.
+		if (!copy_to_jsbuffer(dst_basis_file_js_val, comp.get_output_basis_file()))
+			return 0;
+
+		// Return the file size of the .basis file in bytes.
+		return (uint32_t)comp.get_output_basis_file().size();
+	}
+};
+#endif
+
+class lowlevel_etc1s_image_transcoder : public basisu_lowlevel_etc1s_transcoder
+{
+	// Using our own transcoder state, for video support.
+	basisu_transcoder_state m_state;
+	
+public:
+	lowlevel_etc1s_image_transcoder() : 
+		basisu_lowlevel_etc1s_transcoder(g_pGlobal_codebook)
+	{
+	}
+	
+	bool decode_palettes(uint32_t num_endpoints, const emscripten::val& endpoint_data, uint32_t num_selectors, const emscripten::val& selector_data)
+	{
+		std::vector<uint8_t> temp_endpoint_data, temp_selector_data;
+		copy_from_jsbuffer(endpoint_data, temp_endpoint_data);
+		copy_from_jsbuffer(selector_data, temp_selector_data);
+
+#if 0		
+		printf("decode_palettes: %u %u %u %u, %u %u\n", 
+			num_endpoints, (uint32_t)temp_endpoint_data.size(),
+			num_selectors, (uint32_t)temp_selector_data.size(),
+			temp_endpoint_data[0], temp_selector_data[0]);
+#endif			
+		
+		if (!temp_endpoint_data.size() || !temp_selector_data.size())
+		{
+#if BASISU_DEBUG_PRINTF   
+			printf("decode_tables: endpoint_data and/or selector_data is empty\n");
+#endif   	
+			assert(0);
+			return false;
+		}
+		
+		return basisu_lowlevel_etc1s_transcoder::decode_palettes(num_endpoints, &temp_endpoint_data[0], (uint32_t)temp_endpoint_data.size(), 
+			num_selectors, &temp_selector_data[0], (uint32_t)temp_selector_data.size());
+	}
+	
+	bool decode_tables(const emscripten::val& table_data)
+	{
+		std::vector<uint8_t> temp_table_data;
+		copy_from_jsbuffer(table_data, temp_table_data);
+		
+		if (!temp_table_data.size())
+		{
+#if BASISU_DEBUG_PRINTF   
+			printf("decode_tables: table_data is empty\n");
+#endif   	
+			assert(0);
+			return false;
+		}
+		
+		return basisu_lowlevel_etc1s_transcoder::decode_tables(&temp_table_data[0], (uint32_t)temp_table_data.size());
+	}
+			
+	bool transcode_image(
+		uint32_t target_format, // see transcoder_texture_format
+		const emscripten::val& output_blocks, uint32_t output_blocks_buf_size_in_blocks_or_pixels,
+		const emscripten::val& compressed_data,
+		uint32_t num_blocks_x, uint32_t num_blocks_y, uint32_t orig_width, uint32_t orig_height, uint32_t level_index, 
+		uint32_t rgb_offset, uint32_t rgb_length, uint32_t alpha_offset, uint32_t alpha_length,
+		uint32_t decode_flags, // see cDecodeFlagsPVRTCDecodeToNextPow2
+		bool basis_file_has_alpha_slices,
+		bool is_video,
+		uint32_t output_row_pitch_in_blocks_or_pixels,
+		uint32_t output_rows_in_pixels)
+	{
+		if (!g_pGlobal_codebook)
+		{
+#if BASISU_DEBUG_PRINTF   
+			printf("transcode_etc1s_image: basis_init() must be called first\n");
+#endif   	
+			assert(0);
+			return false;
+		}
+		
+		// FIXME: Access the JavaScript buffer directly vs. copying it.
+		std::vector<uint8_t> temp_comp_data;
+		copy_from_jsbuffer(compressed_data, temp_comp_data);
+		
+		if (!temp_comp_data.size())
+		{
+#if BASISU_DEBUG_PRINTF   
+			printf("transcode_etc1s_image: compressed_data is empty\n");
+#endif   
+			assert(0);
+			return false;
+		}
+		
+		uint32_t output_blocks_len = output_blocks["byteLength"].as<uint32_t>();
+		if (!output_blocks_len)
+		{
+#if BASISU_DEBUG_PRINTF   
+			printf("transcode_etc1s_image: output_blocks is empty\n");
+#endif   
+			assert(0);
+			return false;
+		}
+		
+		std::vector<uint8_t> temp_output_blocks(output_blocks_len);
+						
+		bool status = basisu_lowlevel_etc1s_transcoder::transcode_image(
+			(transcoder_texture_format)target_format,
+			&temp_output_blocks[0], output_blocks_buf_size_in_blocks_or_pixels,
+			&temp_comp_data[0], temp_comp_data.size(),
+			num_blocks_x, num_blocks_y, orig_width, orig_height, level_index,
+			rgb_offset, rgb_length, alpha_offset, alpha_length,
+			decode_flags,
+			basis_file_has_alpha_slices,
+			is_video,
+			output_row_pitch_in_blocks_or_pixels,
+			&m_state,
+			output_rows_in_pixels);
+			
+		if (!status)
+		{
+#if BASISU_DEBUG_PRINTF   
+			printf("transcode_etc1s_image: basisu_lowlevel_etc1s_transcoder::transcode_image failed\n");
+#endif   
+			assert(0);
+			return false;
+		}
+		
+		if (!copy_to_jsbuffer(output_blocks, temp_output_blocks))
+			return false;
+
+		return true;
+	}
+};
+
+bool transcode_uastc_image(
+	uint32_t target_format_int, // see transcoder_texture_format
+	const emscripten::val& output_blocks, uint32_t output_blocks_buf_size_in_blocks_or_pixels,
+	const emscripten::val& compressed_data,
+	uint32_t num_blocks_x, uint32_t num_blocks_y, uint32_t orig_width, uint32_t orig_height, uint32_t level_index,
+	uint32_t slice_offset, uint32_t slice_length, 
+	uint32_t decode_flags, // see cDecodeFlagsPVRTCDecodeToNextPow2
+	bool has_alpha,
+	bool is_video,
+	uint32_t output_row_pitch_in_blocks_or_pixels,
+	uint32_t output_rows_in_pixels,
+	int channel0, int channel1)
+{
+	transcoder_texture_format target_format = static_cast<transcoder_texture_format>(target_format_int);
+	
+	if (!g_pGlobal_codebook)
+	{
+#if BASISU_DEBUG_PRINTF   
+		printf("transcode_uastc_image: basis_init() must be called first\n");
+#endif   	
+		assert(0);
+		return false;
+	}
+			
+	// FIXME: Access the JavaScript buffer directly vs. copying it.
+	std::vector<uint8_t> temp_comp_data;
+	copy_from_jsbuffer(compressed_data, temp_comp_data);
+	
+	if (!temp_comp_data.size())
+	{
+#if BASISU_DEBUG_PRINTF   
+		printf("transcode_uastc_image: compressed_data is empty\n");
+#endif   
+		assert(0);
+		return false;
+	}
+	
+	uint32_t output_blocks_len = output_blocks["byteLength"].as<uint32_t>();
+	if (!output_blocks_len)
+	{
+#if BASISU_DEBUG_PRINTF   
+		printf("transcode_uastc_image: output_blocks is empty\n");
+#endif   
+		assert(0);
+		return false;
+	}
+
+#if 0	
+	printf("format: %u\n", (uint32_t)target_format);
+	printf("output_blocks size: %u buf size: %u\n", output_blocks_len, output_blocks_buf_size_in_blocks_or_pixels);
+	printf("compressed_data size: %u\n", compressed_data["byteLength"].as<uint32_t>());
+	printf("%u %u %u %u %u\n", num_blocks_x, num_blocks_y, orig_width, orig_height, level_index);
+	printf("%u %u\n", slice_offset, slice_length);
+	printf("%u\n", decode_flags);
+	printf("has_alpha: %u is_video: %u\n", has_alpha, is_video);
+#endif	
+	
+	std::vector<uint8_t> temp_output_blocks(output_blocks_len);
+	
+	basisu_lowlevel_uastc_transcoder transcoder;
+	
+	bool status = transcoder.transcode_image(
+		(transcoder_texture_format)target_format,
+		&temp_output_blocks[0], output_blocks_buf_size_in_blocks_or_pixels,
+		&temp_comp_data[0], temp_comp_data.size(),		
+		num_blocks_x, num_blocks_y, orig_width, orig_height, level_index,
+		slice_offset, slice_length,
+		decode_flags,
+		has_alpha,
+		is_video,
+		output_row_pitch_in_blocks_or_pixels,
+		nullptr,
+		output_rows_in_pixels,
+		channel0, channel1);
+	
+	if (!status)
+	{
+#if BASISU_DEBUG_PRINTF   
+		printf("transcode_uastc_image: basisu_lowlevel_uastc_transcoder::transcode_image failed\n");
+#endif   
+		assert(0);
+		return false;
+	}
+	
+	if (!copy_to_jsbuffer(output_blocks, temp_output_blocks))
+		return false;
+
+	return true;
+}
+
+uint32_t get_bytes_per_block_or_pixel(uint32_t transcoder_tex_fmt)
+{
+	return basis_get_bytes_per_block_or_pixel(static_cast<transcoder_texture_format>(transcoder_tex_fmt));
+}
+
+bool format_has_alpha(uint32_t transcoder_tex_fmt)
+{
+	return basis_transcoder_format_has_alpha(static_cast<transcoder_texture_format>(transcoder_tex_fmt));
+}
+
+bool format_is_uncompressed(uint32_t transcoder_tex_fmt)
+{
+	return basis_transcoder_format_is_uncompressed(static_cast<transcoder_texture_format>(transcoder_tex_fmt));
+}
+
+bool is_format_supported(uint32_t transcoder_tex_fmt)
+{
+	return basis_is_format_supported(static_cast<transcoder_texture_format>(transcoder_tex_fmt));
+}
+
+uint32_t get_format_block_width(uint32_t transcoder_tex_fmt)
+{
+	return basis_get_block_width(static_cast<transcoder_texture_format>(transcoder_tex_fmt));
+}
+
+uint32_t get_format_block_height(uint32_t transcoder_tex_fmt)
+{
+	return basis_get_block_height(static_cast<transcoder_texture_format>(transcoder_tex_fmt));
+}
+
+EMSCRIPTEN_BINDINGS(basis_codec) {
   function("initializeBasis", &basis_init);
 
+  // Expose BasisFileDesc structure
+  value_object<basis_file_desc>("BasisFileDesc")
+	  .field("version", &basis_file_desc::m_version)
+	  .field("usPerFrame", &basis_file_desc::m_us_per_frame)
+	  .field("totalImages", &basis_file_desc::m_total_images)
+	  .field("userdata0", &basis_file_desc::m_userdata0)
+	  .field("userdata1", &basis_file_desc::m_userdata1)
+	  .field("texFormat", &basis_file_desc::m_tex_format)
+	  .field("yFlipped", &basis_file_desc::m_y_flipped)
+	  .field("hasAlphaSlices", &basis_file_desc::m_has_alpha_slices)
+	  .field("numEndpoints", &basis_file_desc::m_num_endpoints)
+	  .field("endpointPaletteOfs", &basis_file_desc::m_endpoint_palette_ofs)
+	  .field("endpointPaletteLen", &basis_file_desc::m_endpoint_palette_len)
+	  .field("numSelectors", &basis_file_desc::m_num_selectors)
+	  .field("selectorPaletteOfs", &basis_file_desc::m_selector_palette_ofs)
+	  .field("selectorPaletteLen", &basis_file_desc::m_selector_palette_len)
+	  .field("tablesOfs", &basis_file_desc::m_tables_ofs)
+	  .field("tablesLen", &basis_file_desc::m_tables_len)
+    ;
+
+  // Expose BasisImageDesc structure  	
+  value_object<basis_image_desc>("BasisImageDesc")
+    .field("origWidth", &basis_image_desc::m_orig_width)		
+    .field("origHeight", &basis_image_desc::m_orig_height)
+    .field("numBlocksX", &basis_image_desc::m_num_blocks_x)
+    .field("numBlocksY", &basis_image_desc::m_num_blocks_y)
+    .field("numLevels", &basis_image_desc::m_num_levels)
+    .field("alphaFlag", &basis_image_desc::m_alpha_flag)
+    .field("iframeFlag", &basis_image_desc::m_iframe_flag)
+    ;	  
+
+  // Expose BasisImageLevelDesc structure
+  value_object<basis_image_level_desc>("BasisImageLevelDesc")
+    .field("rgbFileOfs", &basis_image_level_desc::m_rgb_file_ofs)		
+    .field("rgbFileLen", &basis_image_level_desc::m_rgb_file_len)
+    .field("alphaFileOfs", &basis_image_level_desc::m_alpha_file_ofs)
+    .field("alphaFileLen", &basis_image_level_desc::m_alpha_file_len)
+    ;	  	
+
+  // Expose some key enums to JavaScript code.
+
+  // enum class transcoder_texture_format
+  enum_<transcoder_texture_format>("transcoder_texture_format")
+        .value("cTFETC1_RGB", transcoder_texture_format::cTFETC1_RGB)
+		.value("cTFETC2_RGBA", transcoder_texture_format::cTFETC2_RGBA)
+		.value("cTFBC1_RGB", transcoder_texture_format::cTFBC1_RGB)
+		.value("cTFBC3_RGBA", transcoder_texture_format::cTFBC3_RGBA)
+		.value("cTFBC4_R", transcoder_texture_format::cTFBC4_R)
+		.value("cTFBC5_RG", transcoder_texture_format::cTFBC5_RG)
+		.value("cTFBC7_RGBA", transcoder_texture_format::cTFBC7_RGBA)		
+		.value("cTFPVRTC1_4_RGB", transcoder_texture_format::cTFPVRTC1_4_RGB)		
+		.value("cTFPVRTC1_4_RGBA", transcoder_texture_format::cTFPVRTC1_4_RGBA)		
+		.value("cTFASTC_4x4_RGBA", transcoder_texture_format::cTFASTC_4x4_RGBA)		
+		.value("cTFATC_RGB", transcoder_texture_format::cTFATC_RGB)		
+		.value("cTFATC_RGBA", transcoder_texture_format::cTFATC_RGBA)		
+		.value("cTFFXT1_RGB", transcoder_texture_format::cTFFXT1_RGB)		
+		.value("cTFPVRTC2_4_RGB", transcoder_texture_format::cTFPVRTC2_4_RGB)		
+		.value("cTFPVRTC2_4_RGBA", transcoder_texture_format::cTFPVRTC2_4_RGBA)		
+		.value("cTFETC2_EAC_R11", transcoder_texture_format::cTFETC2_EAC_R11)		
+		.value("cTFETC2_EAC_RG11", transcoder_texture_format::cTFETC2_EAC_RG11)		
+		.value("cTFRGBA32", transcoder_texture_format::cTFRGBA32)		
+		.value("cTFRGB565", transcoder_texture_format::cTFRGB565)		
+		.value("cTFBGR565", transcoder_texture_format::cTFBGR565)		
+		.value("cTFRGBA4444", transcoder_texture_format::cTFRGBA4444)		
+		.value("cTFTotalTextureFormats", transcoder_texture_format::cTFTotalTextureFormats)		
+	;
+
+	// Expose some useful transcoder_texture_format helper functions
+	function("getBytesPerBlockOrPixel", &get_bytes_per_block_or_pixel);
+	function("formatHasAlpha", &format_has_alpha);
+	function("formatIsUncompressed", &format_is_uncompressed);
+	function("isFormatSupported", &is_format_supported);
+	function("getFormatBlockWidth", &get_format_block_width);
+	function("getFormatBlockHeight", &get_format_block_height);
+
+	// Expose enum basis_texture_type
+	enum_<basis_texture_type>("basis_texture_type")
+   		.value("cBASISTexType2D", cBASISTexType2D)	
+		.value("cBASISTexType2DArray", cBASISTexType2DArray)	
+		.value("cBASISTexTypeCubemapArray", cBASISTexTypeCubemapArray)	
+		.value("cBASISTexTypeVideoFrames", cBASISTexTypeVideoFrames)	
+		.value("cBASISTexTypeVolume", cBASISTexTypeVolume)	
+	;
+	
+	// Expose enum basis_tex_format
+	enum_<basis_tex_format>("basis_tex_format")
+   		.value("cETC1S", basis_tex_format::cETC1S)	
+		.value("cUASTC4x4", basis_tex_format::cUASTC4x4)	
+	;
+   
+  // Transcoder object. If all you want to do is transcode already encoded .basis files, this is all you really need.
   class_<basis_file>("BasisFile")
     .constructor<const emscripten::val&>()
     .function("close", optional_override([](basis_file& self) {
@@ -262,15 +969,326 @@
     .function("getImageHeight", optional_override([](basis_file& self, uint32_t imageIndex, uint32_t levelIndex) {
       return self.getImageHeight(imageIndex, levelIndex);
     }))
+	// format is enum class transcoder_texture_format
     .function("getImageTranscodedSizeInBytes", optional_override([](basis_file& self, uint32_t imageIndex, uint32_t levelIndex, uint32_t format) {
       return self.getImageTranscodedSizeInBytes(imageIndex, levelIndex, format);
     }))
     .function("startTranscoding", optional_override([](basis_file& self) {
       return self.startTranscoding();
     }))
+	// format is enum class transcoder_texture_format
     .function("transcodeImage", optional_override([](basis_file& self, const emscripten::val& dst, uint32_t imageIndex, uint32_t levelIndex, uint32_t format, uint32_t unused, uint32_t getAlphaForOpaqueFormats) {
       return self.transcodeImage(dst, imageIndex, levelIndex, format, unused, getAlphaForOpaqueFormats);
     }))
-  ;
+	// Returns low-level information about the basis file.
+	.function("getFileDesc", optional_override([](basis_file& self) {
+      return self.getFileDesc();
+    }))
+	// Returns low-level information about a specific image in a basis file. An image can contain 1 or more mipmap levels.
+	.function("getImageDesc", optional_override([](basis_file& self, uint32_t imageIndex) {
+      return self.getImageDesc(imageIndex);
+    }))
+	// Returns low-level information about a specific image mipmap level in a basis file.
+	.function("getImageLevelDesc", optional_override([](basis_file& self, uint32_t imageIndex, uint32_t levelIndex) {
+      return self.getImageLevelDesc(imageIndex, levelIndex);
+    }))
 
+  ;
+      
+  // Low-level container independent transcoding of ETC1S and UASTC slice data.
+  // These functions allow the caller to transcode compressed ETC1S or UASTC texture data that is embedded within arbitrary data files, such as from KTX2.
+  enum_<basisu_decode_flags>("basisu_decode_flags")
+	.value("cDecodeFlagsPVRTCDecodeToNextPow2", cDecodeFlagsPVRTCDecodeToNextPow2)	
+	.value("cDecodeFlagsTranscodeAlphaDataToOpaqueFormats", cDecodeFlagsTranscodeAlphaDataToOpaqueFormats)	
+	.value("cDecodeFlagsBC1ForbidThreeColorBlocks", cDecodeFlagsBC1ForbidThreeColorBlocks)	
+	.value("cDecodeFlagsOutputHasAlphaIndices", cDecodeFlagsOutputHasAlphaIndices)	
+	.value("cDecodeFlagsHighQuality", cDecodeFlagsHighQuality)	
+  ;
+  
+  // The low-level ETC1S transcoder is a class because it has persistent state (such as the endpoint/selector codebooks and Huffman tables, and transcoder state for video)
+  class_<lowlevel_etc1s_image_transcoder>("LowLevelETC1SImageTranscoder")
+  	.constructor<>()
+	.function("decodePalettes", &lowlevel_etc1s_image_transcoder::decode_palettes)
+	.function("decodeTables", &lowlevel_etc1s_image_transcoder::decode_tables)
+	.function("transcodeImage", &lowlevel_etc1s_image_transcoder::transcode_image)
+   ;  
+
+  // The low-level UASTC transcoder is a single function.   
+  function("transcodeUASTCImage", &transcode_uastc_image);
+
+  // Optional encoding/compression support
+  
+#if BASISU_SUPPORT_ENCODING
+
+	// Compressor Constants
+	
+    constant("BASISU_MAX_SUPPORTED_TEXTURE_DIMENSION", BASISU_MAX_SUPPORTED_TEXTURE_DIMENSION);
+	constant("BASISU_DEFAULT_ENDPOINT_RDO_THRESH", BASISU_DEFAULT_ENDPOINT_RDO_THRESH);
+	constant("BASISU_DEFAULT_SELECTOR_RDO_THRESH", BASISU_DEFAULT_SELECTOR_RDO_THRESH);
+	constant("BASISU_DEFAULT_QUALITY", BASISU_DEFAULT_QUALITY);
+	constant("BASISU_DEFAULT_HYBRID_SEL_CB_QUALITY_THRESH", BASISU_DEFAULT_HYBRID_SEL_CB_QUALITY_THRESH);
+	constant("BASISU_MAX_IMAGE_DIMENSION", BASISU_MAX_IMAGE_DIMENSION);
+	constant("BASISU_QUALITY_MIN", BASISU_QUALITY_MIN);
+	constant("BASISU_QUALITY_MAX", BASISU_QUALITY_MAX);
+	constant("BASISU_MAX_ENDPOINT_CLUSTERS", BASISU_MAX_ENDPOINT_CLUSTERS);
+	constant("BASISU_MAX_SELECTOR_CLUSTERS", BASISU_MAX_SELECTOR_CLUSTERS);
+	constant("BASISU_MAX_SLICES", BASISU_MAX_SLICES);
+	constant("BASISU_RDO_UASTC_DICT_SIZE_DEFAULT", BASISU_RDO_UASTC_DICT_SIZE_DEFAULT);
+	constant("BASISU_RDO_UASTC_DICT_SIZE_MIN", BASISU_RDO_UASTC_DICT_SIZE_MIN);
+	constant("BASISU_RDO_UASTC_DICT_SIZE_MAX", BASISU_RDO_UASTC_DICT_SIZE_MAX);
+	constant("BASISU_MAX_RESAMPLER_FILTERS", g_num_resample_filters);
+	constant("BASISU_DEFAULT_COMPRESSION_LEVEL", BASISU_DEFAULT_COMPRESSION_LEVEL);
+	constant("BASISU_MAX_COMPRESSION_LEVEL", BASISU_MAX_COMPRESSION_LEVEL);
+		
+	constant("cPackUASTCLevelFastest", cPackUASTCLevelFastest);
+	constant("cPackUASTCLevelFaster", cPackUASTCLevelFaster);
+	constant("cPackUASTCLevelDefault", cPackUASTCLevelDefault);
+	constant("cPackUASTCLevelSlower", cPackUASTCLevelSlower);
+	constant("cPackUASTCLevelVerySlow", cPackUASTCLevelVerySlow);
+	constant("cPackUASTCLevelMask", cPackUASTCLevelMask);
+	constant("cPackUASTCFavorUASTCError", cPackUASTCFavorUASTCError);
+	constant("cPackUASTCFavorBC7Error", cPackUASTCFavorBC7Error);
+	constant("cPackUASTCETC1FasterHints", cPackUASTCETC1FasterHints);
+	constant("cPackUASTCETC1FastestHints", cPackUASTCETC1FastestHints);
+	constant("cPackUASTCETC1DisableFlipAndIndividual", cPackUASTCETC1DisableFlipAndIndividual);
+	
+	constant("UASTC_RDO_DEFAULT_MAX_ALLOWED_RMS_INCREASE_RATIO", UASTC_RDO_DEFAULT_MAX_ALLOWED_RMS_INCREASE_RATIO);
+	constant("UASTC_RDO_DEFAULT_SKIP_BLOCK_RMS_THRESH", UASTC_RDO_DEFAULT_SKIP_BLOCK_RMS_THRESH);
+
+  // Compression/encoding object.
+  // You create this object, call the set() methods to fill in the parameters/source images/options, call encode(), and you get back a .basis file.
+  // You can call .encode() multiple times, changing the parameters/options in between calls.
+  class_<basis_encoder>("BasisEncoder")
+  	.constructor<>()
+
+	// Compresses the provided source slice(s) to an output .basis file.	
+	// At the minimum, you must provided at least 1 source slice by calling setSliceSourceImage() before calling this method.
+	.function("encode", optional_override([](basis_encoder& self, const emscripten::val& dst_basis_file_js_val) {
+		return self.encode(dst_basis_file_js_val);
+	}))
+
+	// Sets the slice's source image, either from a PNG file or from a raw 32-bit RGBA raster image. 
+	// If the input is a raster image, the buffer must be width*height*4 bytes in size. The raster image is stored in top down scanline order.
+	// The first texel is the top-left texel. The texel byte order in memory is R,G,B,A (R first at offset 0, A last at offset 3).
+	// slice_index is the slice to change. Valid range is [0,BASISU_MAX_SLICES-1].
+	.function("setSliceSourceImage", optional_override([](basis_encoder& self, uint32_t slice_index, const emscripten::val& src_image_js_val, uint32_t width, uint32_t height, bool src_image_is_png) {
+		return self.set_slice_source_image(slice_index, src_image_js_val, width, height, src_image_is_png);
+	}))
+
+	// If true, the encoder will output a UASTC texture, otherwise a ETC1S texture.
+	.function("setUASTC", optional_override([](basis_encoder& self, bool uastc_flag) {
+		self.m_params.m_uastc = uastc_flag;
+	}))
+
+	// If true the source images will be Y flipped before compression.	
+	.function("setYFlip", optional_override([](basis_encoder& self, bool y_flip_flag) {
+		self.m_params.m_y_flip = y_flip_flag;
+	}))
+
+	// Enables debug output	to stdout
+	.function("setDebug", optional_override([](basis_encoder& self, bool debug_flag) {
+		self.m_params.m_debug = debug_flag;
+	}))
+	
+	// If true, the input is assumed to be in sRGB space. Be sure to set this correctly! (Examples: True on photos, albedo/spec maps, and false on normal maps.)
+	.function("setPerceptual", optional_override([](basis_encoder& self, bool perceptual_flag) {
+		self.m_params.m_perceptual = perceptual_flag;
+	}))
+	
+	// Check source images for active/used alpha channels
+	.function("setCheckForAlpha", optional_override([](basis_encoder& self, bool check_for_alpha_flag) {
+		self.m_params.m_check_for_alpha = check_for_alpha_flag;
+	}))
+	
+	// Fource output .basis file to have an alpha channel
+	.function("setForceAlpha", optional_override([](basis_encoder& self, bool force_alpha_flag) {
+		self.m_params.m_force_alpha = force_alpha_flag;
+	}))
+	
+	// Set source image component swizzle.
+	// r,g,b,a - valid range is [0,3]
+	.function("setSwizzle", optional_override([](basis_encoder& self, uint32_t r, uint32_t g, uint32_t b, uint32_t a) {
+		assert((r < 4) && (g < 4) && (b < 4) && (a < 4));
+		self.m_params.m_swizzle[0] = (char)r;
+		self.m_params.m_swizzle[1] = (char)g;
+		self.m_params.m_swizzle[2] = (char)b;
+		self.m_params.m_swizzle[3] = (char)a;
+	}))
+	
+	// If true, the input is assumed to be a normal map, and all source texels will be renormalized before encoding.
+	.function("setRenormalize", optional_override([](basis_encoder& self, bool renormalize_flag) {
+		self.m_params.m_renormalize = renormalize_flag;
+	}))
+	
+	// Sets the max # of endpoint clusters for ETC1S mode. Use instead of setQualityLevel.
+	// Default is 512, range is [1,BASISU_MAX_ENDPOINT_CLUSTERS]
+	.function("setMaxEndpointClusters", optional_override([](basis_encoder& self, uint32_t max_endpoint_clusters) {
+		assert(max_endpoint_clusters <= BASISU_MAX_ENDPOINT_CLUSTERS);
+		self.m_params.m_max_endpoint_clusters = max_endpoint_clusters;
+	}))
+	
+	// Sets the max # of selectors clusters for ETC1S mode. Use instead of setQualityLevel.
+	// Default is 512, range is [1,BASISU_MAX_ENDPOINT_CLUSTERS]
+	.function("setMaxSelectorClusters", optional_override([](basis_encoder& self, uint32_t max_selector_clusters) {
+		assert(max_selector_clusters <= BASISU_MAX_SELECTOR_CLUSTERS);
+		self.m_params.m_max_selector_clusters = max_selector_clusters;
+	}))
+	
+	// Sets the ETC1S encoder's quality level, which controls the file size vs. quality tradeoff.
+	// Default is -1 (meaning unused - the compressor will use m_max_endpoint_clusters/m_max_selector_clusters instead to control the codebook sizes).
+	// Range is [1,BASISU_QUALITY_MAX]
+	.function("setQualityLevel", optional_override([](basis_encoder& self, int quality_level) {
+		assert(quality_level >= -1 && quality_level <= BASISU_QUALITY_MAX);
+		self.m_params.m_quality_level = quality_level;
+	}))
+
+	// The compression_level parameter controls the encoder perf vs. file size tradeoff for ETC1S files. 
+	// It does not directly control file size vs. quality - see quality_level().
+	// Default is BASISU_DEFAULT_COMPRESSION_LEVEL, range is [0,BASISU_MAX_COMPRESSION_LEVEL]
+	.function("setCompressionLevel", optional_override([](basis_encoder& self, int comp_level) {
+		assert(comp_level >= 0 && comp_level <= BASISU_MAX_COMPRESSION_LEVEL);
+		self.m_params.m_compression_level = comp_level;
+	}))
+	
+	// setNormalMapMode is the same as the basisu.exe "-normal_map" option. It tunes several codec parameters so compression works better on normal maps.
+	.function("setNormalMap", optional_override([](basis_encoder& self) {
+		self.m_params.m_perceptual = false;
+		self.m_params.m_mip_srgb = false;
+		self.m_params.m_no_selector_rdo = true;
+		self.m_params.m_no_endpoint_rdo = true;
+	}))
+	
+	// Sets selector RDO threshold
+	// Default is BASISU_DEFAULT_SELECTOR_RDO_THRESH, range is [0,1e+10]
+	.function("setSelectorRDOThresh", optional_override([](basis_encoder& self, float selector_rdo_thresh) {
+		self.m_params.m_selector_rdo_thresh = selector_rdo_thresh;
+	}))
+	
+	// Sets endpoint RDO threshold
+	// Default is BASISU_DEFAULT_ENDPOINT_RDO_THRESH, range is [0,1e+10]
+	.function("setEndpointRDOThresh", optional_override([](basis_encoder& self, float endpoint_rdo_thresh) {
+		self.m_params.m_endpoint_rdo_thresh = endpoint_rdo_thresh;
+	}))
+	
+	// --- Mip-map options
+	
+	// If true mipmaps will be generated from the source images
+	.function("setMipGen", optional_override([](basis_encoder& self, bool mip_gen_flag) {
+		self.m_params.m_mip_gen = mip_gen_flag;
+	}))
+	
+	// Set mipmap filter's scale factor
+	// default is 1, range is [.000125, 4.0]
+	.function("setMipScale", optional_override([](basis_encoder& self, float mip_scale) {
+		self.m_params.m_mip_scale = mip_scale;
+	}))
+	
+	// Sets the mipmap filter to apply
+	// mip_filter must be < BASISU_MAX_RESAMPLER_FILTERS
+	// See the end of basisu_resample_filters.cpp: g_resample_filters[]
+	.function("setMipFilter", optional_override([](basis_encoder& self, uint32_t mip_filter) {
+		assert(mip_filter < g_num_resample_filters);
+		if (mip_filter < g_num_resample_filters)
+			self.m_params.m_mip_filter = g_resample_filters[mip_filter].name;
+	}))
+	
+	// If true mipmap filtering occurs in sRGB space - this generally should match the perceptual parameter.
+	.function("setMipSRGB", optional_override([](basis_encoder& self, bool mip_srgb_flag) {
+		self.m_params.m_mip_srgb = mip_srgb_flag;
+	}))
+	
+	// If true, the input is assumed to be a normal map, and the texels of each mipmap will be renormalized before encoding.
+	.function("setMipRenormalize", optional_override([](basis_encoder& self, bool mip_renormalize_flag) {
+		self.m_params.m_mip_renormalize = mip_renormalize_flag;
+	}))
+	
+	// If true the source texture will be sampled using wrap addressing during mipmap generation, otherwise clamp.
+	.function("setMipWrapping", optional_override([](basis_encoder& self, bool mip_wrapping_flag) {
+		self.m_params.m_mip_wrapping = mip_wrapping_flag;
+	}))
+
+	// Sets the mipmap generator's smallest allowed dimension.	
+	// default is 1, range is [1,16384]
+	.function("setMipSmallestDimension", optional_override([](basis_encoder& self, int mip_smallest_dimension) {
+		self.m_params.m_mip_smallest_dimension = mip_smallest_dimension;
+	}))
+
+	// Sets the .basis texture type. 
+	// cBASISTexTypeVideoFrames changes the encoder into video mode.
+	// tex_type is enum basis_texture_type
+	// default is cBASISTexType2D
+	.function("setTexType", optional_override([](basis_encoder& self, uint32_t tex_type) {
+		assert(tex_type < cBASISTexTypeTotal);
+		self.m_params.m_tex_type = (basist::basis_texture_type)tex_type;
+	}))
+	
+	.function("setUserData0", optional_override([](basis_encoder& self, uint32_t userdata0) {
+		self.m_params.m_userdata0 = userdata0;
+	}))
+	
+	.function("setUserData1", optional_override([](basis_encoder& self, uint32_t userdata1) {
+		self.m_params.m_userdata1 = userdata1;
+	}))
+
+	// UASTC specific flags.
+
+	// Sets the UASTC encoding performance vs. quality tradeoff, and other lesser used UASTC encoder flags.
+	// This is a combination of flags. See cPackUASTCLevelDefault, etc.
+	.function("setPackUASTCFlags", optional_override([](basis_encoder& self, uint32_t pack_uastc_flags) {
+		assert((pack_uastc_flags & cPackUASTCLevelMask) >= cPackUASTCLevelFastest);
+		assert((pack_uastc_flags & cPackUASTCLevelMask) <= cPackUASTCLevelVerySlow);
+		self.m_params.m_pack_uastc_flags = pack_uastc_flags;
+	}))
+
+	// If true, the RDO post-processor will be applied to the encoded UASTC texture data.
+	.function("setRDOUASTC", optional_override([](basis_encoder& self, bool rdo_uastc) {
+		self.m_params.m_rdo_uastc = rdo_uastc;
+	}))
+	
+	// Default is 1.0 range is [0.001, 10.0]
+	.function("setRDOUASTCQualityScalar", optional_override([](basis_encoder& self, float rdo_quality) {
+		self.m_params.m_rdo_uastc_quality_scalar = rdo_quality;
+	}))
+
+    // Default is BASISU_RDO_UASTC_DICT_SIZE_DEFAULT, range is [BASISU_RDO_UASTC_DICT_SIZE_MIN, BASISU_RDO_UASTC_DICT_SIZE_MAX]
+	.function("setRDOUASTCDictSize", optional_override([](basis_encoder& self, int dict_size) {
+		assert((dict_size >= BASISU_RDO_UASTC_DICT_SIZE_MIN) && (dict_size <= BASISU_RDO_UASTC_DICT_SIZE_MAX));
+		self.m_params.m_rdo_uastc_dict_size = dict_size;
+	}))
+
+    // Default is UASTC_RDO_DEFAULT_MAX_ALLOWED_RMS_INCREASE_RATIO, range is [01, 100.0]
+	.function("setRDOUASTCMaxAllowedRMSIncreaseRatio", optional_override([](basis_encoder& self, float rdo_uastc_max_allowed_rms_increase_ratio) {
+		self.m_params.m_rdo_uastc_max_allowed_rms_increase_ratio = rdo_uastc_max_allowed_rms_increase_ratio;
+	}))
+
+	// Default is UASTC_RDO_DEFAULT_SKIP_BLOCK_RMS_THRESH, range is [.01f, 100.0f]
+	.function("setRDOUASTCSkipBlockRMSThresh", optional_override([](basis_encoder& self, float rdo_uastc_skip_block_rms_thresh) {
+		self.m_params.m_rdo_uastc_skip_block_rms_thresh = rdo_uastc_skip_block_rms_thresh;
+	}))
+	
+	// --- Low level options
+	
+	// Disables selector RDO	
+	.function("setNoSelectorRDO", optional_override([](basis_encoder& self, bool no_selector_rdo_flag) {
+		self.m_params.m_no_selector_rdo = no_selector_rdo_flag;
+	}))
+	
+	// Disables endpoint RDO
+	.function("setNoEndpointRDO", optional_override([](basis_encoder& self, bool no_endpoint_rdo_flag) {
+		self.m_params.m_no_endpoint_rdo = no_endpoint_rdo_flag;
+	}))
+	
+	// Display output PSNR statistics
+	.function("setComputeStats", optional_override([](basis_encoder& self, bool compute_stats_flag) {
+		self.m_params.m_compute_stats = compute_stats_flag;
+	}))
+
+	// Write output .PNG files for debugging
+	.function("setDebugImages", optional_override([](basis_encoder& self, bool debug_images_flag) {
+		self.m_params.m_debug_images = debug_images_flag;
+	}))
+
+  ;
+#endif // BASISU_SUPPORT_ENCODING
+    
 }
diff --git a/webgl/transcoder/build/basis_transcoder.js b/webgl/transcoder/build/basis_transcoder.js
index 5856bb0..95de34e 100644
--- a/webgl/transcoder/build/basis_transcoder.js
+++ b/webgl/transcoder/build/basis_transcoder.js
@@ -6,16 +6,16 @@
 function(BASIS) {
   BASIS = BASIS || {};
 
-var Module=typeof BASIS!=="undefined"?BASIS:{};var moduleOverrides={};var key;for(key in Module){if(Module.hasOwnProperty(key)){moduleOverrides[key]=Module[key]}}var arguments_=[];var thisProgram="./this.program";var quit_=function(status,toThrow){throw toThrow};var ENVIRONMENT_IS_WEB=false;var ENVIRONMENT_IS_WORKER=false;var ENVIRONMENT_IS_NODE=false;var ENVIRONMENT_IS_SHELL=false;ENVIRONMENT_IS_WEB=typeof window==="object";ENVIRONMENT_IS_WORKER=typeof importScripts==="function";ENVIRONMENT_IS_NODE=typeof process==="object"&&typeof process.versions==="object"&&typeof process.versions.node==="string";ENVIRONMENT_IS_SHELL=!ENVIRONMENT_IS_WEB&&!ENVIRONMENT_IS_NODE&&!ENVIRONMENT_IS_WORKER;var scriptDirectory="";function locateFile(path){if(Module["locateFile"]){return Module["locateFile"](path,scriptDirectory)}return scriptDirectory+path}var read_,readAsync,readBinary,setWindowTitle;var nodeFS;var nodePath;if(ENVIRONMENT_IS_NODE){if(ENVIRONMENT_IS_WORKER){scriptDirectory=require("path").dirname(scriptDirectory)+"/"}else{scriptDirectory=__dirname+"/"}read_=function shell_read(filename,binary){if(!nodeFS)nodeFS=require("fs");if(!nodePath)nodePath=require("path");filename=nodePath["normalize"](filename);return nodeFS["readFileSync"](filename,binary?null:"utf8")};readBinary=function readBinary(filename){var ret=read_(filename,true);if(!ret.buffer){ret=new Uint8Array(ret)}assert(ret.buffer);return ret};if(process["argv"].length>1){thisProgram=process["argv"][1].replace(/\\/g,"/")}arguments_=process["argv"].slice(2);process["on"]("uncaughtException",function(ex){if(!(ex instanceof ExitStatus)){throw ex}});process["on"]("unhandledRejection",abort);quit_=function(status){process["exit"](status)};Module["inspect"]=function(){return"[Emscripten Module object]"}}else if(ENVIRONMENT_IS_SHELL){if(typeof read!="undefined"){read_=function shell_read(f){return read(f)}}readBinary=function readBinary(f){var data;if(typeof readbuffer==="function"){return new Uint8Array(readbuffer(f))}data=read(f,"binary");assert(typeof data==="object");return data};if(typeof scriptArgs!="undefined"){arguments_=scriptArgs}else if(typeof arguments!="undefined"){arguments_=arguments}if(typeof quit==="function"){quit_=function(status){quit(status)}}if(typeof print!=="undefined"){if(typeof console==="undefined")console={};console.log=print;console.warn=console.error=typeof printErr!=="undefined"?printErr:print}}else if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){if(ENVIRONMENT_IS_WORKER){scriptDirectory=self.location.href}else if(document.currentScript){scriptDirectory=document.currentScript.src}if(_scriptDir){scriptDirectory=_scriptDir}if(scriptDirectory.indexOf("blob:")!==0){scriptDirectory=scriptDirectory.substr(0,scriptDirectory.lastIndexOf("/")+1)}else{scriptDirectory=""}{read_=function shell_read(url){var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.send(null);return xhr.responseText};if(ENVIRONMENT_IS_WORKER){readBinary=function readBinary(url){var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.responseType="arraybuffer";xhr.send(null);return new Uint8Array(xhr.response)}}readAsync=function readAsync(url,onload,onerror){var xhr=new XMLHttpRequest;xhr.open("GET",url,true);xhr.responseType="arraybuffer";xhr.onload=function xhr_onload(){if(xhr.status==200||xhr.status==0&&xhr.response){onload(xhr.response);return}onerror()};xhr.onerror=onerror;xhr.send(null)}}setWindowTitle=function(title){document.title=title}}else{}var out=Module["print"]||console.log.bind(console);var err=Module["printErr"]||console.warn.bind(console);for(key in moduleOverrides){if(moduleOverrides.hasOwnProperty(key)){Module[key]=moduleOverrides[key]}}moduleOverrides=null;if(Module["arguments"])arguments_=Module["arguments"];if(Module["thisProgram"])thisProgram=Module["thisProgram"];if(Module["quit"])quit_=Module["quit"];var tempRet0=0;var setTempRet0=function(value){tempRet0=value};var wasmBinary;if(Module["wasmBinary"])wasmBinary=Module["wasmBinary"];var noExitRuntime;if(Module["noExitRuntime"])noExitRuntime=Module["noExitRuntime"];if(typeof WebAssembly!=="object"){err("no native wasm support detected")}var wasmMemory;var wasmTable=new WebAssembly.Table({"initial":59,"maximum":59+0,"element":"anyfunc"});var ABORT=false;var EXITSTATUS=0;function assert(condition,text){if(!condition){abort("Assertion failed: "+text)}}var UTF8Decoder=typeof TextDecoder!=="undefined"?new TextDecoder("utf8"):undefined;function UTF8ArrayToString(u8Array,idx,maxBytesToRead){var endIdx=idx+maxBytesToRead;var endPtr=idx;while(u8Array[endPtr]&&!(endPtr>=endIdx))++endPtr;if(endPtr-idx>16&&u8Array.subarray&&UTF8Decoder){return UTF8Decoder.decode(u8Array.subarray(idx,endPtr))}else{var str="";while(idx<endPtr){var u0=u8Array[idx++];if(!(u0&128)){str+=String.fromCharCode(u0);continue}var u1=u8Array[idx++]&63;if((u0&224)==192){str+=String.fromCharCode((u0&31)<<6|u1);continue}var u2=u8Array[idx++]&63;if((u0&240)==224){u0=(u0&15)<<12|u1<<6|u2}else{u0=(u0&7)<<18|u1<<12|u2<<6|u8Array[idx++]&63}if(u0<65536){str+=String.fromCharCode(u0)}else{var ch=u0-65536;str+=String.fromCharCode(55296|ch>>10,56320|ch&1023)}}}return str}function UTF8ToString(ptr,maxBytesToRead){return ptr?UTF8ArrayToString(HEAPU8,ptr,maxBytesToRead):""}function stringToUTF8Array(str,outU8Array,outIdx,maxBytesToWrite){if(!(maxBytesToWrite>0))return 0;var startIdx=outIdx;var endIdx=outIdx+maxBytesToWrite-1;for(var i=0;i<str.length;++i){var u=str.charCodeAt(i);if(u>=55296&&u<=57343){var u1=str.charCodeAt(++i);u=65536+((u&1023)<<10)|u1&1023}if(u<=127){if(outIdx>=endIdx)break;outU8Array[outIdx++]=u}else if(u<=2047){if(outIdx+1>=endIdx)break;outU8Array[outIdx++]=192|u>>6;outU8Array[outIdx++]=128|u&63}else if(u<=65535){if(outIdx+2>=endIdx)break;outU8Array[outIdx++]=224|u>>12;outU8Array[outIdx++]=128|u>>6&63;outU8Array[outIdx++]=128|u&63}else{if(outIdx+3>=endIdx)break;outU8Array[outIdx++]=240|u>>18;outU8Array[outIdx++]=128|u>>12&63;outU8Array[outIdx++]=128|u>>6&63;outU8Array[outIdx++]=128|u&63}}outU8Array[outIdx]=0;return outIdx-startIdx}function stringToUTF8(str,outPtr,maxBytesToWrite){return stringToUTF8Array(str,HEAPU8,outPtr,maxBytesToWrite)}function lengthBytesUTF8(str){var len=0;for(var i=0;i<str.length;++i){var u=str.charCodeAt(i);if(u>=55296&&u<=57343)u=65536+((u&1023)<<10)|str.charCodeAt(++i)&1023;if(u<=127)++len;else if(u<=2047)len+=2;else if(u<=65535)len+=3;else len+=4}return len}var UTF16Decoder=typeof TextDecoder!=="undefined"?new TextDecoder("utf-16le"):undefined;function UTF16ToString(ptr){var endPtr=ptr;var idx=endPtr>>1;while(HEAP16[idx])++idx;endPtr=idx<<1;if(endPtr-ptr>32&&UTF16Decoder){return UTF16Decoder.decode(HEAPU8.subarray(ptr,endPtr))}else{var i=0;var str="";while(1){var codeUnit=HEAP16[ptr+i*2>>1];if(codeUnit==0)return str;++i;str+=String.fromCharCode(codeUnit)}}}function stringToUTF16(str,outPtr,maxBytesToWrite){if(maxBytesToWrite===undefined){maxBytesToWrite=2147483647}if(maxBytesToWrite<2)return 0;maxBytesToWrite-=2;var startPtr=outPtr;var numCharsToWrite=maxBytesToWrite<str.length*2?maxBytesToWrite/2:str.length;for(var i=0;i<numCharsToWrite;++i){var codeUnit=str.charCodeAt(i);HEAP16[outPtr>>1]=codeUnit;outPtr+=2}HEAP16[outPtr>>1]=0;return outPtr-startPtr}function lengthBytesUTF16(str){return str.length*2}function UTF32ToString(ptr){var i=0;var str="";while(1){var utf32=HEAP32[ptr+i*4>>2];if(utf32==0)return str;++i;if(utf32>=65536){var ch=utf32-65536;str+=String.fromCharCode(55296|ch>>10,56320|ch&1023)}else{str+=String.fromCharCode(utf32)}}}function stringToUTF32(str,outPtr,maxBytesToWrite){if(maxBytesToWrite===undefined){maxBytesToWrite=2147483647}if(maxBytesToWrite<4)return 0;var startPtr=outPtr;var endPtr=startPtr+maxBytesToWrite-4;for(var i=0;i<str.length;++i){var codeUnit=str.charCodeAt(i);if(codeUnit>=55296&&codeUnit<=57343){var trailSurrogate=str.charCodeAt(++i);codeUnit=65536+((codeUnit&1023)<<10)|trailSurrogate&1023}HEAP32[outPtr>>2]=codeUnit;outPtr+=4;if(outPtr+4>endPtr)break}HEAP32[outPtr>>2]=0;return outPtr-startPtr}function lengthBytesUTF32(str){var len=0;for(var i=0;i<str.length;++i){var codeUnit=str.charCodeAt(i);if(codeUnit>=55296&&codeUnit<=57343)++i;len+=4}return len}var WASM_PAGE_SIZE=65536;function alignUp(x,multiple){if(x%multiple>0){x+=multiple-x%multiple}return x}var buffer,HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;function updateGlobalBufferAndViews(buf){buffer=buf;Module["HEAP8"]=HEAP8=new Int8Array(buf);Module["HEAP16"]=HEAP16=new Int16Array(buf);Module["HEAP32"]=HEAP32=new Int32Array(buf);Module["HEAPU8"]=HEAPU8=new Uint8Array(buf);Module["HEAPU16"]=HEAPU16=new Uint16Array(buf);Module["HEAPU32"]=HEAPU32=new Uint32Array(buf);Module["HEAPF32"]=HEAPF32=new Float32Array(buf);Module["HEAPF64"]=HEAPF64=new Float64Array(buf)}var DYNAMIC_BASE=5561216,DYNAMICTOP_PTR=318176;var INITIAL_INITIAL_MEMORY=Module["INITIAL_MEMORY"]||16777216;if(Module["wasmMemory"]){wasmMemory=Module["wasmMemory"]}else{wasmMemory=new WebAssembly.Memory({"initial":INITIAL_INITIAL_MEMORY/WASM_PAGE_SIZE})}if(wasmMemory){buffer=wasmMemory.buffer}INITIAL_INITIAL_MEMORY=buffer.byteLength;updateGlobalBufferAndViews(buffer);HEAP32[DYNAMICTOP_PTR>>2]=DYNAMIC_BASE;function callRuntimeCallbacks(callbacks){while(callbacks.length>0){var callback=callbacks.shift();if(typeof callback=="function"){callback();continue}var func=callback.func;if(typeof func==="number"){if(callback.arg===undefined){Module["dynCall_v"](func)}else{Module["dynCall_vi"](func,callback.arg)}}else{func(callback.arg===undefined?null:callback.arg)}}}var __ATPRERUN__=[];var __ATINIT__=[];var __ATMAIN__=[];var __ATPOSTRUN__=[];var runtimeInitialized=false;function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="function")Module["preRun"]=[Module["preRun"]];while(Module["preRun"].length){addOnPreRun(Module["preRun"].shift())}}callRuntimeCallbacks(__ATPRERUN__)}function initRuntime(){runtimeInitialized=true;callRuntimeCallbacks(__ATINIT__)}function preMain(){callRuntimeCallbacks(__ATMAIN__)}function postRun(){if(Module["postRun"]){if(typeof Module["postRun"]=="function")Module["postRun"]=[Module["postRun"]];while(Module["postRun"].length){addOnPostRun(Module["postRun"].shift())}}callRuntimeCallbacks(__ATPOSTRUN__)}function addOnPreRun(cb){__ATPRERUN__.unshift(cb)}function addOnPostRun(cb){__ATPOSTRUN__.unshift(cb)}var Math_ceil=Math.ceil;var Math_floor=Math.floor;var runDependencies=0;var runDependencyWatcher=null;var dependenciesFulfilled=null;function addRunDependency(id){runDependencies++;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}}function removeRunDependency(id){runDependencies--;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}if(runDependencies==0){if(runDependencyWatcher!==null){clearInterval(runDependencyWatcher);runDependencyWatcher=null}if(dependenciesFulfilled){var callback=dependenciesFulfilled;dependenciesFulfilled=null;callback()}}}Module["preloadedImages"]={};Module["preloadedAudios"]={};function abort(what){if(Module["onAbort"]){Module["onAbort"](what)}what+="";out(what);err(what);ABORT=true;EXITSTATUS=1;what="abort("+what+"). Build with -s ASSERTIONS=1 for more info.";throw new WebAssembly.RuntimeError(what)}var dataURIPrefix="data:application/octet-stream;base64,";function isDataURI(filename){return String.prototype.startsWith?filename.startsWith(dataURIPrefix):filename.indexOf(dataURIPrefix)===0}var wasmBinaryFile="basis_transcoder.wasm";if(!isDataURI(wasmBinaryFile)){wasmBinaryFile=locateFile(wasmBinaryFile)}function getBinary(){try{if(wasmBinary){return new Uint8Array(wasmBinary)}if(readBinary){return readBinary(wasmBinaryFile)}else{throw"both async and sync fetching of the wasm failed"}}catch(err){abort(err)}}function getBinaryPromise(){if(!wasmBinary&&(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER)&&typeof fetch==="function"){return fetch(wasmBinaryFile,{credentials:"same-origin"}).then(function(response){if(!response["ok"]){throw"failed to load wasm binary file at '"+wasmBinaryFile+"'"}return response["arrayBuffer"]()}).catch(function(){return getBinary()})}return new Promise(function(resolve,reject){resolve(getBinary())})}function createWasm(){var info={"a":asmLibraryArg};function receiveInstance(instance,module){var exports=instance.exports;Module["asm"]=exports;removeRunDependency("wasm-instantiate")}addRunDependency("wasm-instantiate");function receiveInstantiatedSource(output){receiveInstance(output["instance"])}function instantiateArrayBuffer(receiver){return getBinaryPromise().then(function(binary){return WebAssembly.instantiate(binary,info)}).then(receiver,function(reason){err("failed to asynchronously prepare wasm: "+reason);abort(reason)})}function instantiateAsync(){if(!wasmBinary&&typeof WebAssembly.instantiateStreaming==="function"&&!isDataURI(wasmBinaryFile)&&typeof fetch==="function"){fetch(wasmBinaryFile,{credentials:"same-origin"}).then(function(response){var result=WebAssembly.instantiateStreaming(response,info);return result.then(receiveInstantiatedSource,function(reason){err("wasm streaming compile failed: "+reason);err("falling back to ArrayBuffer instantiation");instantiateArrayBuffer(receiveInstantiatedSource)})})}else{return instantiateArrayBuffer(receiveInstantiatedSource)}}if(Module["instantiateWasm"]){try{var exports=Module["instantiateWasm"](info,receiveInstance);return exports}catch(e){err("Module.instantiateWasm callback failed with error: "+e);return false}}instantiateAsync();return{}}__ATINIT__.push({func:function(){___wasm_call_ctors()}});function ___cxa_allocate_exception(size){return _malloc(size)}var ___exception_infos={};var ___exception_last=0;function __ZSt18uncaught_exceptionv(){return __ZSt18uncaught_exceptionv.uncaught_exceptions>0}function ___cxa_throw(ptr,type,destructor){___exception_infos[ptr]={ptr:ptr,adjusted:[ptr],type:type,destructor:destructor,refcount:0,caught:false,rethrown:false};___exception_last=ptr;if(!("uncaught_exception"in __ZSt18uncaught_exceptionv)){__ZSt18uncaught_exceptionv.uncaught_exceptions=1}else{__ZSt18uncaught_exceptionv.uncaught_exceptions++}throw ptr}function getShiftFromSize(size){switch(size){case 1:return 0;case 2:return 1;case 4:return 2;case 8:return 3;default:throw new TypeError("Unknown type size: "+size)}}function embind_init_charCodes(){var codes=new Array(256);for(var i=0;i<256;++i){codes[i]=String.fromCharCode(i)}embind_charCodes=codes}var embind_charCodes=undefined;function readLatin1String(ptr){var ret="";var c=ptr;while(HEAPU8[c]){ret+=embind_charCodes[HEAPU8[c++]]}return ret}var awaitingDependencies={};var registeredTypes={};var typeDependencies={};var char_0=48;var char_9=57;function makeLegalFunctionName(name){if(undefined===name){return"_unknown"}name=name.replace(/[^a-zA-Z0-9_]/g,"$");var f=name.charCodeAt(0);if(f>=char_0&&f<=char_9){return"_"+name}else{return name}}function createNamedFunction(name,body){name=makeLegalFunctionName(name);return new Function("body","return function "+name+"() {\n"+'    "use strict";'+"    return body.apply(this, arguments);\n"+"};\n")(body)}function extendError(baseErrorType,errorName){var errorClass=createNamedFunction(errorName,function(message){this.name=errorName;this.message=message;var stack=new Error(message).stack;if(stack!==undefined){this.stack=this.toString()+"\n"+stack.replace(/^Error(:[^\n]*)?\n/,"")}});errorClass.prototype=Object.create(baseErrorType.prototype);errorClass.prototype.constructor=errorClass;errorClass.prototype.toString=function(){if(this.message===undefined){return this.name}else{return this.name+": "+this.message}};return errorClass}var BindingError=undefined;function throwBindingError(message){throw new BindingError(message)}var InternalError=undefined;function throwInternalError(message){throw new InternalError(message)}function whenDependentTypesAreResolved(myTypes,dependentTypes,getTypeConverters){myTypes.forEach(function(type){typeDependencies[type]=dependentTypes});function onComplete(typeConverters){var myTypeConverters=getTypeConverters(typeConverters);if(myTypeConverters.length!==myTypes.length){throwInternalError("Mismatched type converter count")}for(var i=0;i<myTypes.length;++i){registerType(myTypes[i],myTypeConverters[i])}}var typeConverters=new Array(dependentTypes.length);var unregisteredTypes=[];var registered=0;dependentTypes.forEach(function(dt,i){if(registeredTypes.hasOwnProperty(dt)){typeConverters[i]=registeredTypes[dt]}else{unregisteredTypes.push(dt);if(!awaitingDependencies.hasOwnProperty(dt)){awaitingDependencies[dt]=[]}awaitingDependencies[dt].push(function(){typeConverters[i]=registeredTypes[dt];++registered;if(registered===unregisteredTypes.length){onComplete(typeConverters)}})}});if(0===unregisteredTypes.length){onComplete(typeConverters)}}function registerType(rawType,registeredInstance,options){options=options||{};if(!("argPackAdvance"in registeredInstance)){throw new TypeError("registerType registeredInstance requires argPackAdvance")}var name=registeredInstance.name;if(!rawType){throwBindingError('type "'+name+'" must have a positive integer typeid pointer')}if(registeredTypes.hasOwnProperty(rawType)){if(options.ignoreDuplicateRegistrations){return}else{throwBindingError("Cannot register type '"+name+"' twice")}}registeredTypes[rawType]=registeredInstance;delete typeDependencies[rawType];if(awaitingDependencies.hasOwnProperty(rawType)){var callbacks=awaitingDependencies[rawType];delete awaitingDependencies[rawType];callbacks.forEach(function(cb){cb()})}}function __embind_register_bool(rawType,name,size,trueValue,falseValue){var shift=getShiftFromSize(size);name=readLatin1String(name);registerType(rawType,{name:name,"fromWireType":function(wt){return!!wt},"toWireType":function(destructors,o){return o?trueValue:falseValue},"argPackAdvance":8,"readValueFromPointer":function(pointer){var heap;if(size===1){heap=HEAP8}else if(size===2){heap=HEAP16}else if(size===4){heap=HEAP32}else{throw new TypeError("Unknown boolean type size: "+name)}return this["fromWireType"](heap[pointer>>shift])},destructorFunction:null})}function ClassHandle_isAliasOf(other){if(!(this instanceof ClassHandle)){return false}if(!(other instanceof ClassHandle)){return false}var leftClass=this.$$.ptrType.registeredClass;var left=this.$$.ptr;var rightClass=other.$$.ptrType.registeredClass;var right=other.$$.ptr;while(leftClass.baseClass){left=leftClass.upcast(left);leftClass=leftClass.baseClass}while(rightClass.baseClass){right=rightClass.upcast(right);rightClass=rightClass.baseClass}return leftClass===rightClass&&left===right}function shallowCopyInternalPointer(o){return{count:o.count,deleteScheduled:o.deleteScheduled,preservePointerOnDelete:o.preservePointerOnDelete,ptr:o.ptr,ptrType:o.ptrType,smartPtr:o.smartPtr,smartPtrType:o.smartPtrType}}function throwInstanceAlreadyDeleted(obj){function getInstanceTypeName(handle){return handle.$$.ptrType.registeredClass.name}throwBindingError(getInstanceTypeName(obj)+" instance already deleted")}var finalizationGroup=false;function detachFinalizer(handle){}function runDestructor($$){if($$.smartPtr){$$.smartPtrType.rawDestructor($$.smartPtr)}else{$$.ptrType.registeredClass.rawDestructor($$.ptr)}}function releaseClassHandle($$){$$.count.value-=1;var toDelete=0===$$.count.value;if(toDelete){runDestructor($$)}}function attachFinalizer(handle){if("undefined"===typeof FinalizationGroup){attachFinalizer=function(handle){return handle};return handle}finalizationGroup=new FinalizationGroup(function(iter){for(var result=iter.next();!result.done;result=iter.next()){var $$=result.value;if(!$$.ptr){console.warn("object already deleted: "+$$.ptr)}else{releaseClassHandle($$)}}});attachFinalizer=function(handle){finalizationGroup.register(handle,handle.$$,handle.$$);return handle};detachFinalizer=function(handle){finalizationGroup.unregister(handle.$$)};return attachFinalizer(handle)}function ClassHandle_clone(){if(!this.$$.ptr){throwInstanceAlreadyDeleted(this)}if(this.$$.preservePointerOnDelete){this.$$.count.value+=1;return this}else{var clone=attachFinalizer(Object.create(Object.getPrototypeOf(this),{$$:{value:shallowCopyInternalPointer(this.$$)}}));clone.$$.count.value+=1;clone.$$.deleteScheduled=false;return clone}}function ClassHandle_delete(){if(!this.$$.ptr){throwInstanceAlreadyDeleted(this)}if(this.$$.deleteScheduled&&!this.$$.preservePointerOnDelete){throwBindingError("Object already scheduled for deletion")}detachFinalizer(this);releaseClassHandle(this.$$);if(!this.$$.preservePointerOnDelete){this.$$.smartPtr=undefined;this.$$.ptr=undefined}}function ClassHandle_isDeleted(){return!this.$$.ptr}var delayFunction=undefined;var deletionQueue=[];function flushPendingDeletes(){while(deletionQueue.length){var obj=deletionQueue.pop();obj.$$.deleteScheduled=false;obj["delete"]()}}function ClassHandle_deleteLater(){if(!this.$$.ptr){throwInstanceAlreadyDeleted(this)}if(this.$$.deleteScheduled&&!this.$$.preservePointerOnDelete){throwBindingError("Object already scheduled for deletion")}deletionQueue.push(this);if(deletionQueue.length===1&&delayFunction){delayFunction(flushPendingDeletes)}this.$$.deleteScheduled=true;return this}function init_ClassHandle(){ClassHandle.prototype["isAliasOf"]=ClassHandle_isAliasOf;ClassHandle.prototype["clone"]=ClassHandle_clone;ClassHandle.prototype["delete"]=ClassHandle_delete;ClassHandle.prototype["isDeleted"]=ClassHandle_isDeleted;ClassHandle.prototype["deleteLater"]=ClassHandle_deleteLater}function ClassHandle(){}var registeredPointers={};function ensureOverloadTable(proto,methodName,humanName){if(undefined===proto[methodName].overloadTable){var prevFunc=proto[methodName];proto[methodName]=function(){if(!proto[methodName].overloadTable.hasOwnProperty(arguments.length)){throwBindingError("Function '"+humanName+"' called with an invalid number of arguments ("+arguments.length+") - expects one of ("+proto[methodName].overloadTable+")!")}return proto[methodName].overloadTable[arguments.length].apply(this,arguments)};proto[methodName].overloadTable=[];proto[methodName].overloadTable[prevFunc.argCount]=prevFunc}}function exposePublicSymbol(name,value,numArguments){if(Module.hasOwnProperty(name)){if(undefined===numArguments||undefined!==Module[name].overloadTable&&undefined!==Module[name].overloadTable[numArguments]){throwBindingError("Cannot register public name '"+name+"' twice")}ensureOverloadTable(Module,name,name);if(Module.hasOwnProperty(numArguments)){throwBindingError("Cannot register multiple overloads of a function with the same number of arguments ("+numArguments+")!")}Module[name].overloadTable[numArguments]=value}else{Module[name]=value;if(undefined!==numArguments){Module[name].numArguments=numArguments}}}function RegisteredClass(name,constructor,instancePrototype,rawDestructor,baseClass,getActualType,upcast,downcast){this.name=name;this.constructor=constructor;this.instancePrototype=instancePrototype;this.rawDestructor=rawDestructor;this.baseClass=baseClass;this.getActualType=getActualType;this.upcast=upcast;this.downcast=downcast;this.pureVirtualFunctions=[]}function upcastPointer(ptr,ptrClass,desiredClass){while(ptrClass!==desiredClass){if(!ptrClass.upcast){throwBindingError("Expected null or instance of "+desiredClass.name+", got an instance of "+ptrClass.name)}ptr=ptrClass.upcast(ptr);ptrClass=ptrClass.baseClass}return ptr}function constNoSmartPtrRawPointerToWireType(destructors,handle){if(handle===null){if(this.isReference){throwBindingError("null is not a valid "+this.name)}return 0}if(!handle.$$){throwBindingError('Cannot pass "'+_embind_repr(handle)+'" as a '+this.name)}if(!handle.$$.ptr){throwBindingError("Cannot pass deleted object as a pointer of type "+this.name)}var handleClass=handle.$$.ptrType.registeredClass;var ptr=upcastPointer(handle.$$.ptr,handleClass,this.registeredClass);return ptr}function genericPointerToWireType(destructors,handle){var ptr;if(handle===null){if(this.isReference){throwBindingError("null is not a valid "+this.name)}if(this.isSmartPointer){ptr=this.rawConstructor();if(destructors!==null){destructors.push(this.rawDestructor,ptr)}return ptr}else{return 0}}if(!handle.$$){throwBindingError('Cannot pass "'+_embind_repr(handle)+'" as a '+this.name)}if(!handle.$$.ptr){throwBindingError("Cannot pass deleted object as a pointer of type "+this.name)}if(!this.isConst&&handle.$$.ptrType.isConst){throwBindingError("Cannot convert argument of type "+(handle.$$.smartPtrType?handle.$$.smartPtrType.name:handle.$$.ptrType.name)+" to parameter type "+this.name)}var handleClass=handle.$$.ptrType.registeredClass;ptr=upcastPointer(handle.$$.ptr,handleClass,this.registeredClass);if(this.isSmartPointer){if(undefined===handle.$$.smartPtr){throwBindingError("Passing raw pointer to smart pointer is illegal")}switch(this.sharingPolicy){case 0:if(handle.$$.smartPtrType===this){ptr=handle.$$.smartPtr}else{throwBindingError("Cannot convert argument of type "+(handle.$$.smartPtrType?handle.$$.smartPtrType.name:handle.$$.ptrType.name)+" to parameter type "+this.name)}break;case 1:ptr=handle.$$.smartPtr;break;case 2:if(handle.$$.smartPtrType===this){ptr=handle.$$.smartPtr}else{var clonedHandle=handle["clone"]();ptr=this.rawShare(ptr,__emval_register(function(){clonedHandle["delete"]()}));if(destructors!==null){destructors.push(this.rawDestructor,ptr)}}break;default:throwBindingError("Unsupporting sharing policy")}}return ptr}function nonConstNoSmartPtrRawPointerToWireType(destructors,handle){if(handle===null){if(this.isReference){throwBindingError("null is not a valid "+this.name)}return 0}if(!handle.$$){throwBindingError('Cannot pass "'+_embind_repr(handle)+'" as a '+this.name)}if(!handle.$$.ptr){throwBindingError("Cannot pass deleted object as a pointer of type "+this.name)}if(handle.$$.ptrType.isConst){throwBindingError("Cannot convert argument of type "+handle.$$.ptrType.name+" to parameter type "+this.name)}var handleClass=handle.$$.ptrType.registeredClass;var ptr=upcastPointer(handle.$$.ptr,handleClass,this.registeredClass);return ptr}function simpleReadValueFromPointer(pointer){return this["fromWireType"](HEAPU32[pointer>>2])}function RegisteredPointer_getPointee(ptr){if(this.rawGetPointee){ptr=this.rawGetPointee(ptr)}return ptr}function RegisteredPointer_destructor(ptr){if(this.rawDestructor){this.rawDestructor(ptr)}}function RegisteredPointer_deleteObject(handle){if(handle!==null){handle["delete"]()}}function downcastPointer(ptr,ptrClass,desiredClass){if(ptrClass===desiredClass){return ptr}if(undefined===desiredClass.baseClass){return null}var rv=downcastPointer(ptr,ptrClass,desiredClass.baseClass);if(rv===null){return null}return desiredClass.downcast(rv)}function getInheritedInstanceCount(){return Object.keys(registeredInstances).length}function getLiveInheritedInstances(){var rv=[];for(var k in registeredInstances){if(registeredInstances.hasOwnProperty(k)){rv.push(registeredInstances[k])}}return rv}function setDelayFunction(fn){delayFunction=fn;if(deletionQueue.length&&delayFunction){delayFunction(flushPendingDeletes)}}function init_embind(){Module["getInheritedInstanceCount"]=getInheritedInstanceCount;Module["getLiveInheritedInstances"]=getLiveInheritedInstances;Module["flushPendingDeletes"]=flushPendingDeletes;Module["setDelayFunction"]=setDelayFunction}var registeredInstances={};function getBasestPointer(class_,ptr){if(ptr===undefined){throwBindingError("ptr should not be undefined")}while(class_.baseClass){ptr=class_.upcast(ptr);class_=class_.baseClass}return ptr}function getInheritedInstance(class_,ptr){ptr=getBasestPointer(class_,ptr);return registeredInstances[ptr]}function makeClassHandle(prototype,record){if(!record.ptrType||!record.ptr){throwInternalError("makeClassHandle requires ptr and ptrType")}var hasSmartPtrType=!!record.smartPtrType;var hasSmartPtr=!!record.smartPtr;if(hasSmartPtrType!==hasSmartPtr){throwInternalError("Both smartPtrType and smartPtr must be specified")}record.count={value:1};return attachFinalizer(Object.create(prototype,{$$:{value:record}}))}function RegisteredPointer_fromWireType(ptr){var rawPointer=this.getPointee(ptr);if(!rawPointer){this.destructor(ptr);return null}var registeredInstance=getInheritedInstance(this.registeredClass,rawPointer);if(undefined!==registeredInstance){if(0===registeredInstance.$$.count.value){registeredInstance.$$.ptr=rawPointer;registeredInstance.$$.smartPtr=ptr;return registeredInstance["clone"]()}else{var rv=registeredInstance["clone"]();this.destructor(ptr);return rv}}function makeDefaultHandle(){if(this.isSmartPointer){return makeClassHandle(this.registeredClass.instancePrototype,{ptrType:this.pointeeType,ptr:rawPointer,smartPtrType:this,smartPtr:ptr})}else{return makeClassHandle(this.registeredClass.instancePrototype,{ptrType:this,ptr:ptr})}}var actualType=this.registeredClass.getActualType(rawPointer);var registeredPointerRecord=registeredPointers[actualType];if(!registeredPointerRecord){return makeDefaultHandle.call(this)}var toType;if(this.isConst){toType=registeredPointerRecord.constPointerType}else{toType=registeredPointerRecord.pointerType}var dp=downcastPointer(rawPointer,this.registeredClass,toType.registeredClass);if(dp===null){return makeDefaultHandle.call(this)}if(this.isSmartPointer){return makeClassHandle(toType.registeredClass.instancePrototype,{ptrType:toType,ptr:dp,smartPtrType:this,smartPtr:ptr})}else{return makeClassHandle(toType.registeredClass.instancePrototype,{ptrType:toType,ptr:dp})}}function init_RegisteredPointer(){RegisteredPointer.prototype.getPointee=RegisteredPointer_getPointee;RegisteredPointer.prototype.destructor=RegisteredPointer_destructor;RegisteredPointer.prototype["argPackAdvance"]=8;RegisteredPointer.prototype["readValueFromPointer"]=simpleReadValueFromPointer;RegisteredPointer.prototype["deleteObject"]=RegisteredPointer_deleteObject;RegisteredPointer.prototype["fromWireType"]=RegisteredPointer_fromWireType}function RegisteredPointer(name,registeredClass,isReference,isConst,isSmartPointer,pointeeType,sharingPolicy,rawGetPointee,rawConstructor,rawShare,rawDestructor){this.name=name;this.registeredClass=registeredClass;this.isReference=isReference;this.isConst=isConst;this.isSmartPointer=isSmartPointer;this.pointeeType=pointeeType;this.sharingPolicy=sharingPolicy;this.rawGetPointee=rawGetPointee;this.rawConstructor=rawConstructor;this.rawShare=rawShare;this.rawDestructor=rawDestructor;if(!isSmartPointer&&registeredClass.baseClass===undefined){if(isConst){this["toWireType"]=constNoSmartPtrRawPointerToWireType;this.destructorFunction=null}else{this["toWireType"]=nonConstNoSmartPtrRawPointerToWireType;this.destructorFunction=null}}else{this["toWireType"]=genericPointerToWireType}}function replacePublicSymbol(name,value,numArguments){if(!Module.hasOwnProperty(name)){throwInternalError("Replacing nonexistant public symbol")}if(undefined!==Module[name].overloadTable&&undefined!==numArguments){Module[name].overloadTable[numArguments]=value}else{Module[name]=value;Module[name].argCount=numArguments}}function embind__requireFunction(signature,rawFunction){signature=readLatin1String(signature);function makeDynCaller(dynCall){var args=[];for(var i=1;i<signature.length;++i){args.push("a"+i)}var name="dynCall_"+signature+"_"+rawFunction;var body="return function "+name+"("+args.join(", ")+") {\n";body+="    return dynCall(rawFunction"+(args.length?", ":"")+args.join(", ")+");\n";body+="};\n";return new Function("dynCall","rawFunction",body)(dynCall,rawFunction)}var dc=Module["dynCall_"+signature];var fp=makeDynCaller(dc);if(typeof fp!=="function"){throwBindingError("unknown function pointer with signature "+signature+": "+rawFunction)}return fp}var UnboundTypeError=undefined;function getTypeName(type){var ptr=___getTypeName(type);var rv=readLatin1String(ptr);_free(ptr);return rv}function throwUnboundTypeError(message,types){var unboundTypes=[];var seen={};function visit(type){if(seen[type]){return}if(registeredTypes[type]){return}if(typeDependencies[type]){typeDependencies[type].forEach(visit);return}unboundTypes.push(type);seen[type]=true}types.forEach(visit);throw new UnboundTypeError(message+": "+unboundTypes.map(getTypeName).join([", "]))}function __embind_register_class(rawType,rawPointerType,rawConstPointerType,baseClassRawType,getActualTypeSignature,getActualType,upcastSignature,upcast,downcastSignature,downcast,name,destructorSignature,rawDestructor){name=readLatin1String(name);getActualType=embind__requireFunction(getActualTypeSignature,getActualType);if(upcast){upcast=embind__requireFunction(upcastSignature,upcast)}if(downcast){downcast=embind__requireFunction(downcastSignature,downcast)}rawDestructor=embind__requireFunction(destructorSignature,rawDestructor);var legalFunctionName=makeLegalFunctionName(name);exposePublicSymbol(legalFunctionName,function(){throwUnboundTypeError("Cannot construct "+name+" due to unbound types",[baseClassRawType])});whenDependentTypesAreResolved([rawType,rawPointerType,rawConstPointerType],baseClassRawType?[baseClassRawType]:[],function(base){base=base[0];var baseClass;var basePrototype;if(baseClassRawType){baseClass=base.registeredClass;basePrototype=baseClass.instancePrototype}else{basePrototype=ClassHandle.prototype}var constructor=createNamedFunction(legalFunctionName,function(){if(Object.getPrototypeOf(this)!==instancePrototype){throw new BindingError("Use 'new' to construct "+name)}if(undefined===registeredClass.constructor_body){throw new BindingError(name+" has no accessible constructor")}var body=registeredClass.constructor_body[arguments.length];if(undefined===body){throw new BindingError("Tried to invoke ctor of "+name+" with invalid number of parameters ("+arguments.length+") - expected ("+Object.keys(registeredClass.constructor_body).toString()+") parameters instead!")}return body.apply(this,arguments)});var instancePrototype=Object.create(basePrototype,{constructor:{value:constructor}});constructor.prototype=instancePrototype;var registeredClass=new RegisteredClass(name,constructor,instancePrototype,rawDestructor,baseClass,getActualType,upcast,downcast);var referenceConverter=new RegisteredPointer(name,registeredClass,true,false,false);var pointerConverter=new RegisteredPointer(name+"*",registeredClass,false,false,false);var constPointerConverter=new RegisteredPointer(name+" const*",registeredClass,false,true,false);registeredPointers[rawType]={pointerType:pointerConverter,constPointerType:constPointerConverter};replacePublicSymbol(legalFunctionName,constructor);return[referenceConverter,pointerConverter,constPointerConverter]})}function heap32VectorToArray(count,firstElement){var array=[];for(var i=0;i<count;i++){array.push(HEAP32[(firstElement>>2)+i])}return array}function runDestructors(destructors){while(destructors.length){var ptr=destructors.pop();var del=destructors.pop();del(ptr)}}function __embind_register_class_constructor(rawClassType,argCount,rawArgTypesAddr,invokerSignature,invoker,rawConstructor){assert(argCount>0);var rawArgTypes=heap32VectorToArray(argCount,rawArgTypesAddr);invoker=embind__requireFunction(invokerSignature,invoker);var args=[rawConstructor];var destructors=[];whenDependentTypesAreResolved([],[rawClassType],function(classType){classType=classType[0];var humanName="constructor "+classType.name;if(undefined===classType.registeredClass.constructor_body){classType.registeredClass.constructor_body=[]}if(undefined!==classType.registeredClass.constructor_body[argCount-1]){throw new BindingError("Cannot register multiple constructors with identical number of parameters ("+(argCount-1)+") for class '"+classType.name+"'! Overload resolution is currently only performed using the parameter count, not actual type info!")}classType.registeredClass.constructor_body[argCount-1]=function unboundTypeHandler(){throwUnboundTypeError("Cannot construct "+classType.name+" due to unbound types",rawArgTypes)};whenDependentTypesAreResolved([],rawArgTypes,function(argTypes){classType.registeredClass.constructor_body[argCount-1]=function constructor_body(){if(arguments.length!==argCount-1){throwBindingError(humanName+" called with "+arguments.length+" arguments, expected "+(argCount-1))}destructors.length=0;args.length=argCount;for(var i=1;i<argCount;++i){args[i]=argTypes[i]["toWireType"](destructors,arguments[i-1])}var ptr=invoker.apply(null,args);runDestructors(destructors);return argTypes[0]["fromWireType"](ptr)};return[]});return[]})}function new_(constructor,argumentList){if(!(constructor instanceof Function)){throw new TypeError("new_ called with constructor type "+typeof constructor+" which is not a function")}var dummy=createNamedFunction(constructor.name||"unknownFunctionName",function(){});dummy.prototype=constructor.prototype;var obj=new dummy;var r=constructor.apply(obj,argumentList);return r instanceof Object?r:obj}function craftInvokerFunction(humanName,argTypes,classType,cppInvokerFunc,cppTargetFunc){var argCount=argTypes.length;if(argCount<2){throwBindingError("argTypes array size mismatch! Must at least get return value and 'this' types!")}var isClassMethodFunc=argTypes[1]!==null&&classType!==null;var needsDestructorStack=false;for(var i=1;i<argTypes.length;++i){if(argTypes[i]!==null&&argTypes[i].destructorFunction===undefined){needsDestructorStack=true;break}}var returns=argTypes[0].name!=="void";var argsList="";var argsListWired="";for(var i=0;i<argCount-2;++i){argsList+=(i!==0?", ":"")+"arg"+i;argsListWired+=(i!==0?", ":"")+"arg"+i+"Wired"}var invokerFnBody="return function "+makeLegalFunctionName(humanName)+"("+argsList+") {\n"+"if (arguments.length !== "+(argCount-2)+") {\n"+"throwBindingError('function "+humanName+" called with ' + arguments.length + ' arguments, expected "+(argCount-2)+" args!');\n"+"}\n";if(needsDestructorStack){invokerFnBody+="var destructors = [];\n"}var dtorStack=needsDestructorStack?"destructors":"null";var args1=["throwBindingError","invoker","fn","runDestructors","retType","classParam"];var args2=[throwBindingError,cppInvokerFunc,cppTargetFunc,runDestructors,argTypes[0],argTypes[1]];if(isClassMethodFunc){invokerFnBody+="var thisWired = classParam.toWireType("+dtorStack+", this);\n"}for(var i=0;i<argCount-2;++i){invokerFnBody+="var arg"+i+"Wired = argType"+i+".toWireType("+dtorStack+", arg"+i+"); // "+argTypes[i+2].name+"\n";args1.push("argType"+i);args2.push(argTypes[i+2])}if(isClassMethodFunc){argsListWired="thisWired"+(argsListWired.length>0?", ":"")+argsListWired}invokerFnBody+=(returns?"var rv = ":"")+"invoker(fn"+(argsListWired.length>0?", ":"")+argsListWired+");\n";if(needsDestructorStack){invokerFnBody+="runDestructors(destructors);\n"}else{for(var i=isClassMethodFunc?1:2;i<argTypes.length;++i){var paramName=i===1?"thisWired":"arg"+(i-2)+"Wired";if(argTypes[i].destructorFunction!==null){invokerFnBody+=paramName+"_dtor("+paramName+"); // "+argTypes[i].name+"\n";args1.push(paramName+"_dtor");args2.push(argTypes[i].destructorFunction)}}}if(returns){invokerFnBody+="var ret = retType.fromWireType(rv);\n"+"return ret;\n"}else{}invokerFnBody+="}\n";args1.push(invokerFnBody);var invokerFunction=new_(Function,args1).apply(null,args2);return invokerFunction}function __embind_register_class_function(rawClassType,methodName,argCount,rawArgTypesAddr,invokerSignature,rawInvoker,context,isPureVirtual){var rawArgTypes=heap32VectorToArray(argCount,rawArgTypesAddr);methodName=readLatin1String(methodName);rawInvoker=embind__requireFunction(invokerSignature,rawInvoker);whenDependentTypesAreResolved([],[rawClassType],function(classType){classType=classType[0];var humanName=classType.name+"."+methodName;if(isPureVirtual){classType.registeredClass.pureVirtualFunctions.push(methodName)}function unboundTypesHandler(){throwUnboundTypeError("Cannot call "+humanName+" due to unbound types",rawArgTypes)}var proto=classType.registeredClass.instancePrototype;var method=proto[methodName];if(undefined===method||undefined===method.overloadTable&&method.className!==classType.name&&method.argCount===argCount-2){unboundTypesHandler.argCount=argCount-2;unboundTypesHandler.className=classType.name;proto[methodName]=unboundTypesHandler}else{ensureOverloadTable(proto,methodName,humanName);proto[methodName].overloadTable[argCount-2]=unboundTypesHandler}whenDependentTypesAreResolved([],rawArgTypes,function(argTypes){var memberFunction=craftInvokerFunction(humanName,argTypes,classType,rawInvoker,context);if(undefined===proto[methodName].overloadTable){memberFunction.argCount=argCount-2;proto[methodName]=memberFunction}else{proto[methodName].overloadTable[argCount-2]=memberFunction}return[]});return[]})}var emval_free_list=[];var emval_handle_array=[{},{value:undefined},{value:null},{value:true},{value:false}];function __emval_decref(handle){if(handle>4&&0===--emval_handle_array[handle].refcount){emval_handle_array[handle]=undefined;emval_free_list.push(handle)}}function count_emval_handles(){var count=0;for(var i=5;i<emval_handle_array.length;++i){if(emval_handle_array[i]!==undefined){++count}}return count}function get_first_emval(){for(var i=5;i<emval_handle_array.length;++i){if(emval_handle_array[i]!==undefined){return emval_handle_array[i]}}return null}function init_emval(){Module["count_emval_handles"]=count_emval_handles;Module["get_first_emval"]=get_first_emval}function __emval_register(value){switch(value){case undefined:{return 1}case null:{return 2}case true:{return 3}case false:{return 4}default:{var handle=emval_free_list.length?emval_free_list.pop():emval_handle_array.length;emval_handle_array[handle]={refcount:1,value:value};return handle}}}function __embind_register_emval(rawType,name){name=readLatin1String(name);registerType(rawType,{name:name,"fromWireType":function(handle){var rv=emval_handle_array[handle].value;__emval_decref(handle);return rv},"toWireType":function(destructors,value){return __emval_register(value)},"argPackAdvance":8,"readValueFromPointer":simpleReadValueFromPointer,destructorFunction:null})}function _embind_repr(v){if(v===null){return"null"}var t=typeof v;if(t==="object"||t==="array"||t==="function"){return v.toString()}else{return""+v}}function floatReadValueFromPointer(name,shift){switch(shift){case 2:return function(pointer){return this["fromWireType"](HEAPF32[pointer>>2])};case 3:return function(pointer){return this["fromWireType"](HEAPF64[pointer>>3])};default:throw new TypeError("Unknown float type: "+name)}}function __embind_register_float(rawType,name,size){var shift=getShiftFromSize(size);name=readLatin1String(name);registerType(rawType,{name:name,"fromWireType":function(value){return value},"toWireType":function(destructors,value){if(typeof value!=="number"&&typeof value!=="boolean"){throw new TypeError('Cannot convert "'+_embind_repr(value)+'" to '+this.name)}return value},"argPackAdvance":8,"readValueFromPointer":floatReadValueFromPointer(name,shift),destructorFunction:null})}function __embind_register_function(name,argCount,rawArgTypesAddr,signature,rawInvoker,fn){var argTypes=heap32VectorToArray(argCount,rawArgTypesAddr);name=readLatin1String(name);rawInvoker=embind__requireFunction(signature,rawInvoker);exposePublicSymbol(name,function(){throwUnboundTypeError("Cannot call "+name+" due to unbound types",argTypes)},argCount-1);whenDependentTypesAreResolved([],argTypes,function(argTypes){var invokerArgsArray=[argTypes[0],null].concat(argTypes.slice(1));replacePublicSymbol(name,craftInvokerFunction(name,invokerArgsArray,null,rawInvoker,fn),argCount-1);return[]})}function integerReadValueFromPointer(name,shift,signed){switch(shift){case 0:return signed?function readS8FromPointer(pointer){return HEAP8[pointer]}:function readU8FromPointer(pointer){return HEAPU8[pointer]};case 1:return signed?function readS16FromPointer(pointer){return HEAP16[pointer>>1]}:function readU16FromPointer(pointer){return HEAPU16[pointer>>1]};case 2:return signed?function readS32FromPointer(pointer){return HEAP32[pointer>>2]}:function readU32FromPointer(pointer){return HEAPU32[pointer>>2]};default:throw new TypeError("Unknown integer type: "+name)}}function __embind_register_integer(primitiveType,name,size,minRange,maxRange){name=readLatin1String(name);if(maxRange===-1){maxRange=4294967295}var shift=getShiftFromSize(size);var fromWireType=function(value){return value};if(minRange===0){var bitshift=32-8*size;fromWireType=function(value){return value<<bitshift>>>bitshift}}var isUnsignedType=name.indexOf("unsigned")!=-1;registerType(primitiveType,{name:name,"fromWireType":fromWireType,"toWireType":function(destructors,value){if(typeof value!=="number"&&typeof value!=="boolean"){throw new TypeError('Cannot convert "'+_embind_repr(value)+'" to '+this.name)}if(value<minRange||value>maxRange){throw new TypeError('Passing a number "'+_embind_repr(value)+'" from JS side to C/C++ side to an argument of type "'+name+'", which is outside the valid range ['+minRange+", "+maxRange+"]!")}return isUnsignedType?value>>>0:value|0},"argPackAdvance":8,"readValueFromPointer":integerReadValueFromPointer(name,shift,minRange!==0),destructorFunction:null})}function __embind_register_memory_view(rawType,dataTypeIndex,name){var typeMapping=[Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array];var TA=typeMapping[dataTypeIndex];function decodeMemoryView(handle){handle=handle>>2;var heap=HEAPU32;var size=heap[handle];var data=heap[handle+1];return new TA(buffer,data,size)}name=readLatin1String(name);registerType(rawType,{name:name,"fromWireType":decodeMemoryView,"argPackAdvance":8,"readValueFromPointer":decodeMemoryView},{ignoreDuplicateRegistrations:true})}function __embind_register_std_string(rawType,name){name=readLatin1String(name);var stdStringIsUTF8=name==="std::string";registerType(rawType,{name:name,"fromWireType":function(value){var length=HEAPU32[value>>2];var str;if(stdStringIsUTF8){var endChar=HEAPU8[value+4+length];var endCharSwap=0;if(endChar!=0){endCharSwap=endChar;HEAPU8[value+4+length]=0}var decodeStartPtr=value+4;for(var i=0;i<=length;++i){var currentBytePtr=value+4+i;if(HEAPU8[currentBytePtr]==0){var stringSegment=UTF8ToString(decodeStartPtr);if(str===undefined){str=stringSegment}else{str+=String.fromCharCode(0);str+=stringSegment}decodeStartPtr=currentBytePtr+1}}if(endCharSwap!=0){HEAPU8[value+4+length]=endCharSwap}}else{var a=new Array(length);for(var i=0;i<length;++i){a[i]=String.fromCharCode(HEAPU8[value+4+i])}str=a.join("")}_free(value);return str},"toWireType":function(destructors,value){if(value instanceof ArrayBuffer){value=new Uint8Array(value)}var getLength;var valueIsOfTypeString=typeof value==="string";if(!(valueIsOfTypeString||value instanceof Uint8Array||value instanceof Uint8ClampedArray||value instanceof Int8Array)){throwBindingError("Cannot pass non-string to std::string")}if(stdStringIsUTF8&&valueIsOfTypeString){getLength=function(){return lengthBytesUTF8(value)}}else{getLength=function(){return value.length}}var length=getLength();var ptr=_malloc(4+length+1);HEAPU32[ptr>>2]=length;if(stdStringIsUTF8&&valueIsOfTypeString){stringToUTF8(value,ptr+4,length+1)}else{if(valueIsOfTypeString){for(var i=0;i<length;++i){var charCode=value.charCodeAt(i);if(charCode>255){_free(ptr);throwBindingError("String has UTF-16 code units that do not fit in 8 bits")}HEAPU8[ptr+4+i]=charCode}}else{for(var i=0;i<length;++i){HEAPU8[ptr+4+i]=value[i]}}}if(destructors!==null){destructors.push(_free,ptr)}return ptr},"argPackAdvance":8,"readValueFromPointer":simpleReadValueFromPointer,destructorFunction:function(ptr){_free(ptr)}})}function __embind_register_std_wstring(rawType,charSize,name){name=readLatin1String(name);var decodeString,encodeString,getHeap,lengthBytesUTF,shift;if(charSize===2){decodeString=UTF16ToString;encodeString=stringToUTF16;lengthBytesUTF=lengthBytesUTF16;getHeap=function(){return HEAPU16};shift=1}else if(charSize===4){decodeString=UTF32ToString;encodeString=stringToUTF32;lengthBytesUTF=lengthBytesUTF32;getHeap=function(){return HEAPU32};shift=2}registerType(rawType,{name:name,"fromWireType":function(value){var length=HEAPU32[value>>2];var HEAP=getHeap();var str;var endChar=HEAP[value+4+length*charSize>>shift];var endCharSwap=0;if(endChar!=0){endCharSwap=endChar;HEAP[value+4+length*charSize>>shift]=0}var decodeStartPtr=value+4;for(var i=0;i<=length;++i){var currentBytePtr=value+4+i*charSize;if(HEAP[currentBytePtr>>shift]==0){var stringSegment=decodeString(decodeStartPtr);if(str===undefined){str=stringSegment}else{str+=String.fromCharCode(0);str+=stringSegment}decodeStartPtr=currentBytePtr+charSize}}if(endCharSwap!=0){HEAP[value+4+length*charSize>>shift]=endCharSwap}_free(value);return str},"toWireType":function(destructors,value){if(!(typeof value==="string")){throwBindingError("Cannot pass non-string to C++ string type "+name)}var length=lengthBytesUTF(value);var ptr=_malloc(4+length+charSize);HEAPU32[ptr>>2]=length>>shift;encodeString(value,ptr+4,length+charSize);if(destructors!==null){destructors.push(_free,ptr)}return ptr},"argPackAdvance":8,"readValueFromPointer":simpleReadValueFromPointer,destructorFunction:function(ptr){_free(ptr)}})}function __embind_register_void(rawType,name){name=readLatin1String(name);registerType(rawType,{isVoid:true,name:name,"argPackAdvance":0,"fromWireType":function(){return undefined},"toWireType":function(destructors,o){return undefined}})}function requireHandle(handle){if(!handle){throwBindingError("Cannot use deleted val. handle = "+handle)}return emval_handle_array[handle].value}function requireRegisteredType(rawType,humanName){var impl=registeredTypes[rawType];if(undefined===impl){throwBindingError(humanName+" has unknown type "+getTypeName(rawType))}return impl}function __emval_as(handle,returnType,destructorsRef){handle=requireHandle(handle);returnType=requireRegisteredType(returnType,"emval::as");var destructors=[];var rd=__emval_register(destructors);HEAP32[destructorsRef>>2]=rd;return returnType["toWireType"](destructors,handle)}var emval_symbols={};function getStringOrSymbol(address){var symbol=emval_symbols[address];if(symbol===undefined){return readLatin1String(address)}else{return symbol}}var emval_methodCallers=[];function __emval_call_void_method(caller,handle,methodName,args){caller=emval_methodCallers[caller];handle=requireHandle(handle);methodName=getStringOrSymbol(methodName);caller(handle,methodName,null,args)}function emval_get_global(){if(typeof globalThis==="object"){return globalThis}return function(){return Function}()("return this")()}function __emval_get_global(name){if(name===0){return __emval_register(emval_get_global())}else{name=getStringOrSymbol(name);return __emval_register(emval_get_global()[name])}}function __emval_addMethodCaller(caller){var id=emval_methodCallers.length;emval_methodCallers.push(caller);return id}function __emval_lookupTypes(argCount,argTypes){var a=new Array(argCount);for(var i=0;i<argCount;++i){a[i]=requireRegisteredType(HEAP32[(argTypes>>2)+i],"parameter "+i)}return a}function __emval_get_method_caller(argCount,argTypes){var types=__emval_lookupTypes(argCount,argTypes);var retType=types[0];var signatureName=retType.name+"_$"+types.slice(1).map(function(t){return t.name}).join("_")+"$";var params=["retType"];var args=[retType];var argsList="";for(var i=0;i<argCount-1;++i){argsList+=(i!==0?", ":"")+"arg"+i;params.push("argType"+i);args.push(types[1+i])}var functionName=makeLegalFunctionName("methodCaller_"+signatureName);var functionBody="return function "+functionName+"(handle, name, destructors, args) {\n";var offset=0;for(var i=0;i<argCount-1;++i){functionBody+="    var arg"+i+" = argType"+i+".readValueFromPointer(args"+(offset?"+"+offset:"")+");\n";offset+=types[i+1]["argPackAdvance"]}functionBody+="    var rv = handle[name]("+argsList+");\n";for(var i=0;i<argCount-1;++i){if(types[i+1]["deleteObject"]){functionBody+="    argType"+i+".deleteObject(arg"+i+");\n"}}if(!retType.isVoid){functionBody+="    return retType.toWireType(destructors, rv);\n"}functionBody+="};\n";params.push(functionBody);var invokerFunction=new_(Function,params).apply(null,args);return __emval_addMethodCaller(invokerFunction)}function __emval_get_module_property(name){name=getStringOrSymbol(name);return __emval_register(Module[name])}function __emval_get_property(handle,key){handle=requireHandle(handle);key=requireHandle(key);return __emval_register(handle[key])}function __emval_incref(handle){if(handle>4){emval_handle_array[handle].refcount+=1}}function craftEmvalAllocator(argCount){var argsList="";for(var i=0;i<argCount;++i){argsList+=(i!==0?", ":"")+"arg"+i}var functionBody="return function emval_allocator_"+argCount+"(constructor, argTypes, args) {\n";for(var i=0;i<argCount;++i){functionBody+="var argType"+i+" = requireRegisteredType(Module['HEAP32'][(argTypes >> 2) + "+i+'], "parameter '+i+'");\n'+"var arg"+i+" = argType"+i+".readValueFromPointer(args);\n"+"args += argType"+i+"['argPackAdvance'];\n"}functionBody+="var obj = new constructor("+argsList+");\n"+"return __emval_register(obj);\n"+"}\n";return new Function("requireRegisteredType","Module","__emval_register",functionBody)(requireRegisteredType,Module,__emval_register)}var emval_newers={};function __emval_new(handle,argCount,argTypes,args){handle=requireHandle(handle);var newer=emval_newers[argCount];if(!newer){newer=craftEmvalAllocator(argCount);emval_newers[argCount]=newer}return newer(handle,argTypes,args)}function __emval_new_cstring(v){return __emval_register(getStringOrSymbol(v))}function __emval_run_destructors(handle){var destructors=emval_handle_array[handle].value;runDestructors(destructors);__emval_decref(handle)}function _abort(){abort()}function _emscripten_get_heap_size(){return HEAPU8.length}function _emscripten_memcpy_big(dest,src,num){HEAPU8.copyWithin(dest,src,src+num)}function emscripten_realloc_buffer(size){try{wasmMemory.grow(size-buffer.byteLength+65535>>16);updateGlobalBufferAndViews(wasmMemory.buffer);return 1}catch(e){}}function _emscripten_resize_heap(requestedSize){var oldSize=_emscripten_get_heap_size();var PAGE_MULTIPLE=65536;var maxHeapSize=2147483648-PAGE_MULTIPLE;if(requestedSize>maxHeapSize){return false}var minHeapSize=16777216;for(var cutDown=1;cutDown<=4;cutDown*=2){var overGrownHeapSize=oldSize*(1+.2/cutDown);overGrownHeapSize=Math.min(overGrownHeapSize,requestedSize+100663296);var newSize=Math.min(maxHeapSize,alignUp(Math.max(minHeapSize,requestedSize,overGrownHeapSize),PAGE_MULTIPLE));var replacement=emscripten_realloc_buffer(newSize);if(replacement){return true}}return false}var PATH={splitPath:function(filename){var splitPathRe=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;return splitPathRe.exec(filename).slice(1)},normalizeArray:function(parts,allowAboveRoot){var up=0;for(var i=parts.length-1;i>=0;i--){var last=parts[i];if(last==="."){parts.splice(i,1)}else if(last===".."){parts.splice(i,1);up++}else if(up){parts.splice(i,1);up--}}if(allowAboveRoot){for(;up;up--){parts.unshift("..")}}return parts},normalize:function(path){var isAbsolute=path.charAt(0)==="/",trailingSlash=path.substr(-1)==="/";path=PATH.normalizeArray(path.split("/").filter(function(p){return!!p}),!isAbsolute).join("/");if(!path&&!isAbsolute){path="."}if(path&&trailingSlash){path+="/"}return(isAbsolute?"/":"")+path},dirname:function(path){var result=PATH.splitPath(path),root=result[0],dir=result[1];if(!root&&!dir){return"."}if(dir){dir=dir.substr(0,dir.length-1)}return root+dir},basename:function(path){if(path==="/")return"/";var lastSlash=path.lastIndexOf("/");if(lastSlash===-1)return path;return path.substr(lastSlash+1)},extname:function(path){return PATH.splitPath(path)[3]},join:function(){var paths=Array.prototype.slice.call(arguments,0);return PATH.normalize(paths.join("/"))},join2:function(l,r){return PATH.normalize(l+"/"+r)}};var SYSCALLS={mappings:{},buffers:[null,[],[]],printChar:function(stream,curr){var buffer=SYSCALLS.buffers[stream];if(curr===0||curr===10){(stream===1?out:err)(UTF8ArrayToString(buffer,0));buffer.length=0}else{buffer.push(curr)}},varargs:undefined,get:function(){SYSCALLS.varargs+=4;var ret=HEAP32[SYSCALLS.varargs-4>>2];return ret},getStr:function(ptr){var ret=UTF8ToString(ptr);return ret},get64:function(low,high){return low}};function _fd_close(fd){return 0}function _fd_seek(fd,offset_low,offset_high,whence,newOffset){}function _fd_write(fd,iov,iovcnt,pnum){var num=0;for(var i=0;i<iovcnt;i++){var ptr=HEAP32[iov+i*8>>2];var len=HEAP32[iov+(i*8+4)>>2];for(var j=0;j<len;j++){SYSCALLS.printChar(fd,HEAPU8[ptr+j])}num+=len}HEAP32[pnum>>2]=num;return 0}function _roundf(d){d=+d;return d>=+0?+Math_floor(d+ +.5):+Math_ceil(d-+.5)}function _setTempRet0($i){setTempRet0($i|0)}embind_init_charCodes();BindingError=Module["BindingError"]=extendError(Error,"BindingError");InternalError=Module["InternalError"]=extendError(Error,"InternalError");init_ClassHandle();init_RegisteredPointer();init_embind();UnboundTypeError=Module["UnboundTypeError"]=extendError(Error,"UnboundTypeError");init_emval();var asmLibraryArg={"G":___cxa_allocate_exception,"D":___cxa_throw,"A":__embind_register_bool,"t":__embind_register_class,"s":__embind_register_class_constructor,"c":__embind_register_class_function,"z":__embind_register_emval,"j":__embind_register_float,"x":__embind_register_function,"d":__embind_register_integer,"b":__embind_register_memory_view,"k":__embind_register_std_string,"i":__embind_register_std_wstring,"B":__embind_register_void,"r":__emval_as,"m":__emval_call_void_method,"a":__emval_decref,"F":__emval_get_global,"n":__emval_get_method_caller,"p":__emval_get_module_property,"f":__emval_get_property,"h":__emval_incref,"o":__emval_new,"g":__emval_new_cstring,"q":__emval_run_destructors,"E":_abort,"w":_emscripten_memcpy_big,"y":_emscripten_resize_heap,"C":_fd_close,"u":_fd_seek,"l":_fd_write,"memory":wasmMemory,"e":_roundf,"v":_setTempRet0,"table":wasmTable};var asm=createWasm();Module["asm"]=asm;var ___wasm_call_ctors=Module["___wasm_call_ctors"]=function(){return(___wasm_call_ctors=Module["___wasm_call_ctors"]=Module["asm"]["H"]).apply(null,arguments)};var _malloc=Module["_malloc"]=function(){return(_malloc=Module["_malloc"]=Module["asm"]["I"]).apply(null,arguments)};var _free=Module["_free"]=function(){return(_free=Module["_free"]=Module["asm"]["J"]).apply(null,arguments)};var ___getTypeName=Module["___getTypeName"]=function(){return(___getTypeName=Module["___getTypeName"]=Module["asm"]["K"]).apply(null,arguments)};var ___embind_register_native_and_builtin_types=Module["___embind_register_native_and_builtin_types"]=function(){return(___embind_register_native_and_builtin_types=Module["___embind_register_native_and_builtin_types"]=Module["asm"]["L"]).apply(null,arguments)};var dynCall_viii=Module["dynCall_viii"]=function(){return(dynCall_viii=Module["dynCall_viii"]=Module["asm"]["M"]).apply(null,arguments)};var dynCall_ii=Module["dynCall_ii"]=function(){return(dynCall_ii=Module["dynCall_ii"]=Module["asm"]["N"]).apply(null,arguments)};var dynCall_vi=Module["dynCall_vi"]=function(){return(dynCall_vi=Module["dynCall_vi"]=Module["asm"]["O"]).apply(null,arguments)};var dynCall_v=Module["dynCall_v"]=function(){return(dynCall_v=Module["dynCall_v"]=Module["asm"]["P"]).apply(null,arguments)};var dynCall_iii=Module["dynCall_iii"]=function(){return(dynCall_iii=Module["dynCall_iii"]=Module["asm"]["Q"]).apply(null,arguments)};var dynCall_vii=Module["dynCall_vii"]=function(){return(dynCall_vii=Module["dynCall_vii"]=Module["asm"]["R"]).apply(null,arguments)};var dynCall_iiii=Module["dynCall_iiii"]=function(){return(dynCall_iiii=Module["dynCall_iiii"]=Module["asm"]["S"]).apply(null,arguments)};var dynCall_iiiii=Module["dynCall_iiiii"]=function(){return(dynCall_iiiii=Module["dynCall_iiiii"]=Module["asm"]["T"]).apply(null,arguments)};var dynCall_iiiiii=Module["dynCall_iiiiii"]=function(){return(dynCall_iiiiii=Module["dynCall_iiiiii"]=Module["asm"]["U"]).apply(null,arguments)};var dynCall_iiiiiiii=Module["dynCall_iiiiiiii"]=function(){return(dynCall_iiiiiiii=Module["dynCall_iiiiiiii"]=Module["asm"]["V"]).apply(null,arguments)};var dynCall_iiiiiiiii=Module["dynCall_iiiiiiiii"]=function(){return(dynCall_iiiiiiiii=Module["dynCall_iiiiiiiii"]=Module["asm"]["W"]).apply(null,arguments)};var dynCall_iidiiii=Module["dynCall_iidiiii"]=function(){return(dynCall_iidiiii=Module["dynCall_iidiiii"]=Module["asm"]["X"]).apply(null,arguments)};var dynCall_jiji=Module["dynCall_jiji"]=function(){return(dynCall_jiji=Module["dynCall_jiji"]=Module["asm"]["Y"]).apply(null,arguments)};var dynCall_viiiiii=Module["dynCall_viiiiii"]=function(){return(dynCall_viiiiii=Module["dynCall_viiiiii"]=Module["asm"]["Z"]).apply(null,arguments)};var dynCall_viiiii=Module["dynCall_viiiii"]=function(){return(dynCall_viiiii=Module["dynCall_viiiii"]=Module["asm"]["_"]).apply(null,arguments)};var dynCall_viiii=Module["dynCall_viiii"]=function(){return(dynCall_viiii=Module["dynCall_viiii"]=Module["asm"]["$"]).apply(null,arguments)};Module["asm"]=asm;var calledRun;Module["then"]=function(func){if(calledRun){func(Module)}else{var old=Module["onRuntimeInitialized"];Module["onRuntimeInitialized"]=function(){if(old)old();func(Module)}}return Module};function ExitStatus(status){this.name="ExitStatus";this.message="Program terminated with exit("+status+")";this.status=status}dependenciesFulfilled=function runCaller(){if(!calledRun)run();if(!calledRun)dependenciesFulfilled=runCaller};function run(args){args=args||arguments_;if(runDependencies>0){return}preRun();if(runDependencies>0)return;function doRun(){if(calledRun)return;calledRun=true;Module["calledRun"]=true;if(ABORT)return;initRuntime();preMain();if(Module["onRuntimeInitialized"])Module["onRuntimeInitialized"]();postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout(function(){setTimeout(function(){Module["setStatus"]("")},1);doRun()},1)}else{doRun()}}Module["run"]=run;if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].pop()()}}noExitRuntime=true;run();
+var Module=typeof BASIS!=="undefined"?BASIS:{};var readyPromiseResolve,readyPromiseReject;Module["ready"]=new Promise(function(resolve,reject){readyPromiseResolve=resolve;readyPromiseReject=reject});var moduleOverrides={};var key;for(key in Module){if(Module.hasOwnProperty(key)){moduleOverrides[key]=Module[key]}}var arguments_=[];var thisProgram="./this.program";var quit_=function(status,toThrow){throw toThrow};var ENVIRONMENT_IS_WEB=false;var ENVIRONMENT_IS_WORKER=false;var ENVIRONMENT_IS_NODE=false;var ENVIRONMENT_IS_SHELL=false;ENVIRONMENT_IS_WEB=typeof window==="object";ENVIRONMENT_IS_WORKER=typeof importScripts==="function";ENVIRONMENT_IS_NODE=typeof process==="object"&&typeof process.versions==="object"&&typeof process.versions.node==="string";ENVIRONMENT_IS_SHELL=!ENVIRONMENT_IS_WEB&&!ENVIRONMENT_IS_NODE&&!ENVIRONMENT_IS_WORKER;var scriptDirectory="";function locateFile(path){if(Module["locateFile"]){return Module["locateFile"](path,scriptDirectory)}return scriptDirectory+path}var read_,readAsync,readBinary,setWindowTitle;var nodeFS;var nodePath;if(ENVIRONMENT_IS_NODE){if(ENVIRONMENT_IS_WORKER){scriptDirectory=require("path").dirname(scriptDirectory)+"/"}else{scriptDirectory=__dirname+"/"}read_=function shell_read(filename,binary){if(!nodeFS)nodeFS=require("fs");if(!nodePath)nodePath=require("path");filename=nodePath["normalize"](filename);return nodeFS["readFileSync"](filename,binary?null:"utf8")};readBinary=function readBinary(filename){var ret=read_(filename,true);if(!ret.buffer){ret=new Uint8Array(ret)}assert(ret.buffer);return ret};if(process["argv"].length>1){thisProgram=process["argv"][1].replace(/\\/g,"/")}arguments_=process["argv"].slice(2);process["on"]("uncaughtException",function(ex){if(!(ex instanceof ExitStatus)){throw ex}});process["on"]("unhandledRejection",abort);quit_=function(status){process["exit"](status)};Module["inspect"]=function(){return"[Emscripten Module object]"}}else if(ENVIRONMENT_IS_SHELL){if(typeof read!="undefined"){read_=function shell_read(f){return read(f)}}readBinary=function readBinary(f){var data;if(typeof readbuffer==="function"){return new Uint8Array(readbuffer(f))}data=read(f,"binary");assert(typeof data==="object");return data};if(typeof scriptArgs!="undefined"){arguments_=scriptArgs}else if(typeof arguments!="undefined"){arguments_=arguments}if(typeof quit==="function"){quit_=function(status){quit(status)}}if(typeof print!=="undefined"){if(typeof console==="undefined")console={};console.log=print;console.warn=console.error=typeof printErr!=="undefined"?printErr:print}}else if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){if(ENVIRONMENT_IS_WORKER){scriptDirectory=self.location.href}else if(typeof document!=="undefined"&&document.currentScript){scriptDirectory=document.currentScript.src}if(_scriptDir){scriptDirectory=_scriptDir}if(scriptDirectory.indexOf("blob:")!==0){scriptDirectory=scriptDirectory.substr(0,scriptDirectory.lastIndexOf("/")+1)}else{scriptDirectory=""}{read_=function shell_read(url){var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.send(null);return xhr.responseText};if(ENVIRONMENT_IS_WORKER){readBinary=function readBinary(url){var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.responseType="arraybuffer";xhr.send(null);return new Uint8Array(xhr.response)}}readAsync=function readAsync(url,onload,onerror){var xhr=new XMLHttpRequest;xhr.open("GET",url,true);xhr.responseType="arraybuffer";xhr.onload=function xhr_onload(){if(xhr.status==200||xhr.status==0&&xhr.response){onload(xhr.response);return}onerror()};xhr.onerror=onerror;xhr.send(null)}}setWindowTitle=function(title){document.title=title}}else{}var out=Module["print"]||console.log.bind(console);var err=Module["printErr"]||console.warn.bind(console);for(key in moduleOverrides){if(moduleOverrides.hasOwnProperty(key)){Module[key]=moduleOverrides[key]}}moduleOverrides=null;if(Module["arguments"])arguments_=Module["arguments"];if(Module["thisProgram"])thisProgram=Module["thisProgram"];if(Module["quit"])quit_=Module["quit"];var wasmBinary;if(Module["wasmBinary"])wasmBinary=Module["wasmBinary"];var noExitRuntime;if(Module["noExitRuntime"])noExitRuntime=Module["noExitRuntime"];if(typeof WebAssembly!=="object"){abort("no native wasm support detected")}var wasmMemory;var ABORT=false;var EXITSTATUS;function assert(condition,text){if(!condition){abort("Assertion failed: "+text)}}var UTF8Decoder=typeof TextDecoder!=="undefined"?new TextDecoder("utf8"):undefined;function UTF8ArrayToString(heap,idx,maxBytesToRead){var endIdx=idx+maxBytesToRead;var endPtr=idx;while(heap[endPtr]&&!(endPtr>=endIdx))++endPtr;if(endPtr-idx>16&&heap.subarray&&UTF8Decoder){return UTF8Decoder.decode(heap.subarray(idx,endPtr))}else{var str="";while(idx<endPtr){var u0=heap[idx++];if(!(u0&128)){str+=String.fromCharCode(u0);continue}var u1=heap[idx++]&63;if((u0&224)==192){str+=String.fromCharCode((u0&31)<<6|u1);continue}var u2=heap[idx++]&63;if((u0&240)==224){u0=(u0&15)<<12|u1<<6|u2}else{u0=(u0&7)<<18|u1<<12|u2<<6|heap[idx++]&63}if(u0<65536){str+=String.fromCharCode(u0)}else{var ch=u0-65536;str+=String.fromCharCode(55296|ch>>10,56320|ch&1023)}}}return str}function UTF8ToString(ptr,maxBytesToRead){return ptr?UTF8ArrayToString(HEAPU8,ptr,maxBytesToRead):""}function stringToUTF8Array(str,heap,outIdx,maxBytesToWrite){if(!(maxBytesToWrite>0))return 0;var startIdx=outIdx;var endIdx=outIdx+maxBytesToWrite-1;for(var i=0;i<str.length;++i){var u=str.charCodeAt(i);if(u>=55296&&u<=57343){var u1=str.charCodeAt(++i);u=65536+((u&1023)<<10)|u1&1023}if(u<=127){if(outIdx>=endIdx)break;heap[outIdx++]=u}else if(u<=2047){if(outIdx+1>=endIdx)break;heap[outIdx++]=192|u>>6;heap[outIdx++]=128|u&63}else if(u<=65535){if(outIdx+2>=endIdx)break;heap[outIdx++]=224|u>>12;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}else{if(outIdx+3>=endIdx)break;heap[outIdx++]=240|u>>18;heap[outIdx++]=128|u>>12&63;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}}heap[outIdx]=0;return outIdx-startIdx}function stringToUTF8(str,outPtr,maxBytesToWrite){return stringToUTF8Array(str,HEAPU8,outPtr,maxBytesToWrite)}function lengthBytesUTF8(str){var len=0;for(var i=0;i<str.length;++i){var u=str.charCodeAt(i);if(u>=55296&&u<=57343)u=65536+((u&1023)<<10)|str.charCodeAt(++i)&1023;if(u<=127)++len;else if(u<=2047)len+=2;else if(u<=65535)len+=3;else len+=4}return len}var UTF16Decoder=typeof TextDecoder!=="undefined"?new TextDecoder("utf-16le"):undefined;function UTF16ToString(ptr,maxBytesToRead){var endPtr=ptr;var idx=endPtr>>1;var maxIdx=idx+maxBytesToRead/2;while(!(idx>=maxIdx)&&HEAPU16[idx])++idx;endPtr=idx<<1;if(endPtr-ptr>32&&UTF16Decoder){return UTF16Decoder.decode(HEAPU8.subarray(ptr,endPtr))}else{var str="";for(var i=0;!(i>=maxBytesToRead/2);++i){var codeUnit=HEAP16[ptr+i*2>>1];if(codeUnit==0)break;str+=String.fromCharCode(codeUnit)}return str}}function stringToUTF16(str,outPtr,maxBytesToWrite){if(maxBytesToWrite===undefined){maxBytesToWrite=2147483647}if(maxBytesToWrite<2)return 0;maxBytesToWrite-=2;var startPtr=outPtr;var numCharsToWrite=maxBytesToWrite<str.length*2?maxBytesToWrite/2:str.length;for(var i=0;i<numCharsToWrite;++i){var codeUnit=str.charCodeAt(i);HEAP16[outPtr>>1]=codeUnit;outPtr+=2}HEAP16[outPtr>>1]=0;return outPtr-startPtr}function lengthBytesUTF16(str){return str.length*2}function UTF32ToString(ptr,maxBytesToRead){var i=0;var str="";while(!(i>=maxBytesToRead/4)){var utf32=HEAP32[ptr+i*4>>2];if(utf32==0)break;++i;if(utf32>=65536){var ch=utf32-65536;str+=String.fromCharCode(55296|ch>>10,56320|ch&1023)}else{str+=String.fromCharCode(utf32)}}return str}function stringToUTF32(str,outPtr,maxBytesToWrite){if(maxBytesToWrite===undefined){maxBytesToWrite=2147483647}if(maxBytesToWrite<4)return 0;var startPtr=outPtr;var endPtr=startPtr+maxBytesToWrite-4;for(var i=0;i<str.length;++i){var codeUnit=str.charCodeAt(i);if(codeUnit>=55296&&codeUnit<=57343){var trailSurrogate=str.charCodeAt(++i);codeUnit=65536+((codeUnit&1023)<<10)|trailSurrogate&1023}HEAP32[outPtr>>2]=codeUnit;outPtr+=4;if(outPtr+4>endPtr)break}HEAP32[outPtr>>2]=0;return outPtr-startPtr}function lengthBytesUTF32(str){var len=0;for(var i=0;i<str.length;++i){var codeUnit=str.charCodeAt(i);if(codeUnit>=55296&&codeUnit<=57343)++i;len+=4}return len}function alignUp(x,multiple){if(x%multiple>0){x+=multiple-x%multiple}return x}var buffer,HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;function updateGlobalBufferAndViews(buf){buffer=buf;Module["HEAP8"]=HEAP8=new Int8Array(buf);Module["HEAP16"]=HEAP16=new Int16Array(buf);Module["HEAP32"]=HEAP32=new Int32Array(buf);Module["HEAPU8"]=HEAPU8=new Uint8Array(buf);Module["HEAPU16"]=HEAPU16=new Uint16Array(buf);Module["HEAPU32"]=HEAPU32=new Uint32Array(buf);Module["HEAPF32"]=HEAPF32=new Float32Array(buf);Module["HEAPF64"]=HEAPF64=new Float64Array(buf)}var INITIAL_MEMORY=Module["INITIAL_MEMORY"]||16777216;var wasmTable;var __ATPRERUN__=[];var __ATINIT__=[];var __ATMAIN__=[];var __ATPOSTRUN__=[];var runtimeInitialized=false;function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="function")Module["preRun"]=[Module["preRun"]];while(Module["preRun"].length){addOnPreRun(Module["preRun"].shift())}}callRuntimeCallbacks(__ATPRERUN__)}function initRuntime(){runtimeInitialized=true;callRuntimeCallbacks(__ATINIT__)}function preMain(){callRuntimeCallbacks(__ATMAIN__)}function postRun(){if(Module["postRun"]){if(typeof Module["postRun"]=="function")Module["postRun"]=[Module["postRun"]];while(Module["postRun"].length){addOnPostRun(Module["postRun"].shift())}}callRuntimeCallbacks(__ATPOSTRUN__)}function addOnPreRun(cb){__ATPRERUN__.unshift(cb)}function addOnPostRun(cb){__ATPOSTRUN__.unshift(cb)}var runDependencies=0;var runDependencyWatcher=null;var dependenciesFulfilled=null;function addRunDependency(id){runDependencies++;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}}function removeRunDependency(id){runDependencies--;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}if(runDependencies==0){if(runDependencyWatcher!==null){clearInterval(runDependencyWatcher);runDependencyWatcher=null}if(dependenciesFulfilled){var callback=dependenciesFulfilled;dependenciesFulfilled=null;callback()}}}Module["preloadedImages"]={};Module["preloadedAudios"]={};function abort(what){if(Module["onAbort"]){Module["onAbort"](what)}what+="";err(what);ABORT=true;EXITSTATUS=1;what="abort("+what+"). Build with -s ASSERTIONS=1 for more info.";var e=new WebAssembly.RuntimeError(what);readyPromiseReject(e);throw e}function hasPrefix(str,prefix){return String.prototype.startsWith?str.startsWith(prefix):str.indexOf(prefix)===0}var dataURIPrefix="data:application/octet-stream;base64,";function isDataURI(filename){return hasPrefix(filename,dataURIPrefix)}var fileURIPrefix="file://";function isFileURI(filename){return hasPrefix(filename,fileURIPrefix)}var wasmBinaryFile="basis_transcoder.wasm";if(!isDataURI(wasmBinaryFile)){wasmBinaryFile=locateFile(wasmBinaryFile)}function getBinary(){try{if(wasmBinary){return new Uint8Array(wasmBinary)}if(readBinary){return readBinary(wasmBinaryFile)}else{throw"both async and sync fetching of the wasm failed"}}catch(err){abort(err)}}function getBinaryPromise(){if(!wasmBinary&&(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER)&&typeof fetch==="function"&&!isFileURI(wasmBinaryFile)){return fetch(wasmBinaryFile,{credentials:"same-origin"}).then(function(response){if(!response["ok"]){throw"failed to load wasm binary file at '"+wasmBinaryFile+"'"}return response["arrayBuffer"]()}).catch(function(){return getBinary()})}return Promise.resolve().then(getBinary)}function createWasm(){var info={"a":asmLibraryArg};function receiveInstance(instance,module){var exports=instance.exports;Module["asm"]=exports;wasmMemory=Module["asm"]["H"];updateGlobalBufferAndViews(wasmMemory.buffer);wasmTable=Module["asm"]["I"];removeRunDependency("wasm-instantiate")}addRunDependency("wasm-instantiate");function receiveInstantiatedSource(output){receiveInstance(output["instance"])}function instantiateArrayBuffer(receiver){return getBinaryPromise().then(function(binary){return WebAssembly.instantiate(binary,info)}).then(receiver,function(reason){err("failed to asynchronously prepare wasm: "+reason);abort(reason)})}function instantiateAsync(){if(!wasmBinary&&typeof WebAssembly.instantiateStreaming==="function"&&!isDataURI(wasmBinaryFile)&&!isFileURI(wasmBinaryFile)&&typeof fetch==="function"){return fetch(wasmBinaryFile,{credentials:"same-origin"}).then(function(response){var result=WebAssembly.instantiateStreaming(response,info);return result.then(receiveInstantiatedSource,function(reason){err("wasm streaming compile failed: "+reason);err("falling back to ArrayBuffer instantiation");return instantiateArrayBuffer(receiveInstantiatedSource)})})}else{return instantiateArrayBuffer(receiveInstantiatedSource)}}if(Module["instantiateWasm"]){try{var exports=Module["instantiateWasm"](info,receiveInstance);return exports}catch(e){err("Module.instantiateWasm callback failed with error: "+e);return false}}instantiateAsync().catch(readyPromiseReject);return{}}function callRuntimeCallbacks(callbacks){while(callbacks.length>0){var callback=callbacks.shift();if(typeof callback=="function"){callback(Module);continue}var func=callback.func;if(typeof func==="number"){if(callback.arg===undefined){wasmTable.get(func)()}else{wasmTable.get(func)(callback.arg)}}else{func(callback.arg===undefined?null:callback.arg)}}}var ExceptionInfoAttrs={DESTRUCTOR_OFFSET:0,REFCOUNT_OFFSET:4,TYPE_OFFSET:8,CAUGHT_OFFSET:12,RETHROWN_OFFSET:13,SIZE:16};function ___cxa_allocate_exception(size){return _malloc(size+ExceptionInfoAttrs.SIZE)+ExceptionInfoAttrs.SIZE}function ExceptionInfo(excPtr){this.excPtr=excPtr;this.ptr=excPtr-ExceptionInfoAttrs.SIZE;this.set_type=function(type){HEAP32[this.ptr+ExceptionInfoAttrs.TYPE_OFFSET>>2]=type};this.get_type=function(){return HEAP32[this.ptr+ExceptionInfoAttrs.TYPE_OFFSET>>2]};this.set_destructor=function(destructor){HEAP32[this.ptr+ExceptionInfoAttrs.DESTRUCTOR_OFFSET>>2]=destructor};this.get_destructor=function(){return HEAP32[this.ptr+ExceptionInfoAttrs.DESTRUCTOR_OFFSET>>2]};this.set_refcount=function(refcount){HEAP32[this.ptr+ExceptionInfoAttrs.REFCOUNT_OFFSET>>2]=refcount};this.set_caught=function(caught){caught=caught?1:0;HEAP8[this.ptr+ExceptionInfoAttrs.CAUGHT_OFFSET>>0]=caught};this.get_caught=function(){return HEAP8[this.ptr+ExceptionInfoAttrs.CAUGHT_OFFSET>>0]!=0};this.set_rethrown=function(rethrown){rethrown=rethrown?1:0;HEAP8[this.ptr+ExceptionInfoAttrs.RETHROWN_OFFSET>>0]=rethrown};this.get_rethrown=function(){return HEAP8[this.ptr+ExceptionInfoAttrs.RETHROWN_OFFSET>>0]!=0};this.init=function(type,destructor){this.set_type(type);this.set_destructor(destructor);this.set_refcount(0);this.set_caught(false);this.set_rethrown(false)};this.add_ref=function(){var value=HEAP32[this.ptr+ExceptionInfoAttrs.REFCOUNT_OFFSET>>2];HEAP32[this.ptr+ExceptionInfoAttrs.REFCOUNT_OFFSET>>2]=value+1};this.release_ref=function(){var prev=HEAP32[this.ptr+ExceptionInfoAttrs.REFCOUNT_OFFSET>>2];HEAP32[this.ptr+ExceptionInfoAttrs.REFCOUNT_OFFSET>>2]=prev-1;return prev===1}}var exceptionLast=0;var uncaughtExceptionCount=0;function ___cxa_throw(ptr,type,destructor){var info=new ExceptionInfo(ptr);info.init(type,destructor);exceptionLast=ptr;uncaughtExceptionCount++;throw ptr}var structRegistrations={};function runDestructors(destructors){while(destructors.length){var ptr=destructors.pop();var del=destructors.pop();del(ptr)}}function simpleReadValueFromPointer(pointer){return this["fromWireType"](HEAPU32[pointer>>2])}var awaitingDependencies={};var registeredTypes={};var typeDependencies={};var char_0=48;var char_9=57;function makeLegalFunctionName(name){if(undefined===name){return"_unknown"}name=name.replace(/[^a-zA-Z0-9_]/g,"$");var f=name.charCodeAt(0);if(f>=char_0&&f<=char_9){return"_"+name}else{return name}}function createNamedFunction(name,body){name=makeLegalFunctionName(name);return new Function("body","return function "+name+"() {\n"+'    "use strict";'+"    return body.apply(this, arguments);\n"+"};\n")(body)}function extendError(baseErrorType,errorName){var errorClass=createNamedFunction(errorName,function(message){this.name=errorName;this.message=message;var stack=new Error(message).stack;if(stack!==undefined){this.stack=this.toString()+"\n"+stack.replace(/^Error(:[^\n]*)?\n/,"")}});errorClass.prototype=Object.create(baseErrorType.prototype);errorClass.prototype.constructor=errorClass;errorClass.prototype.toString=function(){if(this.message===undefined){return this.name}else{return this.name+": "+this.message}};return errorClass}var InternalError=undefined;function throwInternalError(message){throw new InternalError(message)}function whenDependentTypesAreResolved(myTypes,dependentTypes,getTypeConverters){myTypes.forEach(function(type){typeDependencies[type]=dependentTypes});function onComplete(typeConverters){var myTypeConverters=getTypeConverters(typeConverters);if(myTypeConverters.length!==myTypes.length){throwInternalError("Mismatched type converter count")}for(var i=0;i<myTypes.length;++i){registerType(myTypes[i],myTypeConverters[i])}}var typeConverters=new Array(dependentTypes.length);var unregisteredTypes=[];var registered=0;dependentTypes.forEach(function(dt,i){if(registeredTypes.hasOwnProperty(dt)){typeConverters[i]=registeredTypes[dt]}else{unregisteredTypes.push(dt);if(!awaitingDependencies.hasOwnProperty(dt)){awaitingDependencies[dt]=[]}awaitingDependencies[dt].push(function(){typeConverters[i]=registeredTypes[dt];++registered;if(registered===unregisteredTypes.length){onComplete(typeConverters)}})}});if(0===unregisteredTypes.length){onComplete(typeConverters)}}function __embind_finalize_value_object(structType){var reg=structRegistrations[structType];delete structRegistrations[structType];var rawConstructor=reg.rawConstructor;var rawDestructor=reg.rawDestructor;var fieldRecords=reg.fields;var fieldTypes=fieldRecords.map(function(field){return field.getterReturnType}).concat(fieldRecords.map(function(field){return field.setterArgumentType}));whenDependentTypesAreResolved([structType],fieldTypes,function(fieldTypes){var fields={};fieldRecords.forEach(function(field,i){var fieldName=field.fieldName;var getterReturnType=fieldTypes[i];var getter=field.getter;var getterContext=field.getterContext;var setterArgumentType=fieldTypes[i+fieldRecords.length];var setter=field.setter;var setterContext=field.setterContext;fields[fieldName]={read:function(ptr){return getterReturnType["fromWireType"](getter(getterContext,ptr))},write:function(ptr,o){var destructors=[];setter(setterContext,ptr,setterArgumentType["toWireType"](destructors,o));runDestructors(destructors)}}});return[{name:reg.name,"fromWireType":function(ptr){var rv={};for(var i in fields){rv[i]=fields[i].read(ptr)}rawDestructor(ptr);return rv},"toWireType":function(destructors,o){for(var fieldName in fields){if(!(fieldName in o)){throw new TypeError('Missing field:  "'+fieldName+'"')}}var ptr=rawConstructor();for(fieldName in fields){fields[fieldName].write(ptr,o[fieldName])}if(destructors!==null){destructors.push(rawDestructor,ptr)}return ptr},"argPackAdvance":8,"readValueFromPointer":simpleReadValueFromPointer,destructorFunction:rawDestructor}]})}function getShiftFromSize(size){switch(size){case 1:return 0;case 2:return 1;case 4:return 2;case 8:return 3;default:throw new TypeError("Unknown type size: "+size)}}function embind_init_charCodes(){var codes=new Array(256);for(var i=0;i<256;++i){codes[i]=String.fromCharCode(i)}embind_charCodes=codes}var embind_charCodes=undefined;function readLatin1String(ptr){var ret="";var c=ptr;while(HEAPU8[c]){ret+=embind_charCodes[HEAPU8[c++]]}return ret}var BindingError=undefined;function throwBindingError(message){throw new BindingError(message)}function registerType(rawType,registeredInstance,options){options=options||{};if(!("argPackAdvance"in registeredInstance)){throw new TypeError("registerType registeredInstance requires argPackAdvance")}var name=registeredInstance.name;if(!rawType){throwBindingError('type "'+name+'" must have a positive integer typeid pointer')}if(registeredTypes.hasOwnProperty(rawType)){if(options.ignoreDuplicateRegistrations){return}else{throwBindingError("Cannot register type '"+name+"' twice")}}registeredTypes[rawType]=registeredInstance;delete typeDependencies[rawType];if(awaitingDependencies.hasOwnProperty(rawType)){var callbacks=awaitingDependencies[rawType];delete awaitingDependencies[rawType];callbacks.forEach(function(cb){cb()})}}function __embind_register_bool(rawType,name,size,trueValue,falseValue){var shift=getShiftFromSize(size);name=readLatin1String(name);registerType(rawType,{name:name,"fromWireType":function(wt){return!!wt},"toWireType":function(destructors,o){return o?trueValue:falseValue},"argPackAdvance":8,"readValueFromPointer":function(pointer){var heap;if(size===1){heap=HEAP8}else if(size===2){heap=HEAP16}else if(size===4){heap=HEAP32}else{throw new TypeError("Unknown boolean type size: "+name)}return this["fromWireType"](heap[pointer>>shift])},destructorFunction:null})}function ClassHandle_isAliasOf(other){if(!(this instanceof ClassHandle)){return false}if(!(other instanceof ClassHandle)){return false}var leftClass=this.$$.ptrType.registeredClass;var left=this.$$.ptr;var rightClass=other.$$.ptrType.registeredClass;var right=other.$$.ptr;while(leftClass.baseClass){left=leftClass.upcast(left);leftClass=leftClass.baseClass}while(rightClass.baseClass){right=rightClass.upcast(right);rightClass=rightClass.baseClass}return leftClass===rightClass&&left===right}function shallowCopyInternalPointer(o){return{count:o.count,deleteScheduled:o.deleteScheduled,preservePointerOnDelete:o.preservePointerOnDelete,ptr:o.ptr,ptrType:o.ptrType,smartPtr:o.smartPtr,smartPtrType:o.smartPtrType}}function throwInstanceAlreadyDeleted(obj){function getInstanceTypeName(handle){return handle.$$.ptrType.registeredClass.name}throwBindingError(getInstanceTypeName(obj)+" instance already deleted")}var finalizationGroup=false;function detachFinalizer(handle){}function runDestructor($$){if($$.smartPtr){$$.smartPtrType.rawDestructor($$.smartPtr)}else{$$.ptrType.registeredClass.rawDestructor($$.ptr)}}function releaseClassHandle($$){$$.count.value-=1;var toDelete=0===$$.count.value;if(toDelete){runDestructor($$)}}function attachFinalizer(handle){if("undefined"===typeof FinalizationGroup){attachFinalizer=function(handle){return handle};return handle}finalizationGroup=new FinalizationGroup(function(iter){for(var result=iter.next();!result.done;result=iter.next()){var $$=result.value;if(!$$.ptr){console.warn("object already deleted: "+$$.ptr)}else{releaseClassHandle($$)}}});attachFinalizer=function(handle){finalizationGroup.register(handle,handle.$$,handle.$$);return handle};detachFinalizer=function(handle){finalizationGroup.unregister(handle.$$)};return attachFinalizer(handle)}function ClassHandle_clone(){if(!this.$$.ptr){throwInstanceAlreadyDeleted(this)}if(this.$$.preservePointerOnDelete){this.$$.count.value+=1;return this}else{var clone=attachFinalizer(Object.create(Object.getPrototypeOf(this),{$$:{value:shallowCopyInternalPointer(this.$$)}}));clone.$$.count.value+=1;clone.$$.deleteScheduled=false;return clone}}function ClassHandle_delete(){if(!this.$$.ptr){throwInstanceAlreadyDeleted(this)}if(this.$$.deleteScheduled&&!this.$$.preservePointerOnDelete){throwBindingError("Object already scheduled for deletion")}detachFinalizer(this);releaseClassHandle(this.$$);if(!this.$$.preservePointerOnDelete){this.$$.smartPtr=undefined;this.$$.ptr=undefined}}function ClassHandle_isDeleted(){return!this.$$.ptr}var delayFunction=undefined;var deletionQueue=[];function flushPendingDeletes(){while(deletionQueue.length){var obj=deletionQueue.pop();obj.$$.deleteScheduled=false;obj["delete"]()}}function ClassHandle_deleteLater(){if(!this.$$.ptr){throwInstanceAlreadyDeleted(this)}if(this.$$.deleteScheduled&&!this.$$.preservePointerOnDelete){throwBindingError("Object already scheduled for deletion")}deletionQueue.push(this);if(deletionQueue.length===1&&delayFunction){delayFunction(flushPendingDeletes)}this.$$.deleteScheduled=true;return this}function init_ClassHandle(){ClassHandle.prototype["isAliasOf"]=ClassHandle_isAliasOf;ClassHandle.prototype["clone"]=ClassHandle_clone;ClassHandle.prototype["delete"]=ClassHandle_delete;ClassHandle.prototype["isDeleted"]=ClassHandle_isDeleted;ClassHandle.prototype["deleteLater"]=ClassHandle_deleteLater}function ClassHandle(){}var registeredPointers={};function ensureOverloadTable(proto,methodName,humanName){if(undefined===proto[methodName].overloadTable){var prevFunc=proto[methodName];proto[methodName]=function(){if(!proto[methodName].overloadTable.hasOwnProperty(arguments.length)){throwBindingError("Function '"+humanName+"' called with an invalid number of arguments ("+arguments.length+") - expects one of ("+proto[methodName].overloadTable+")!")}return proto[methodName].overloadTable[arguments.length].apply(this,arguments)};proto[methodName].overloadTable=[];proto[methodName].overloadTable[prevFunc.argCount]=prevFunc}}function exposePublicSymbol(name,value,numArguments){if(Module.hasOwnProperty(name)){if(undefined===numArguments||undefined!==Module[name].overloadTable&&undefined!==Module[name].overloadTable[numArguments]){throwBindingError("Cannot register public name '"+name+"' twice")}ensureOverloadTable(Module,name,name);if(Module.hasOwnProperty(numArguments)){throwBindingError("Cannot register multiple overloads of a function with the same number of arguments ("+numArguments+")!")}Module[name].overloadTable[numArguments]=value}else{Module[name]=value;if(undefined!==numArguments){Module[name].numArguments=numArguments}}}function RegisteredClass(name,constructor,instancePrototype,rawDestructor,baseClass,getActualType,upcast,downcast){this.name=name;this.constructor=constructor;this.instancePrototype=instancePrototype;this.rawDestructor=rawDestructor;this.baseClass=baseClass;this.getActualType=getActualType;this.upcast=upcast;this.downcast=downcast;this.pureVirtualFunctions=[]}function upcastPointer(ptr,ptrClass,desiredClass){while(ptrClass!==desiredClass){if(!ptrClass.upcast){throwBindingError("Expected null or instance of "+desiredClass.name+", got an instance of "+ptrClass.name)}ptr=ptrClass.upcast(ptr);ptrClass=ptrClass.baseClass}return ptr}function constNoSmartPtrRawPointerToWireType(destructors,handle){if(handle===null){if(this.isReference){throwBindingError("null is not a valid "+this.name)}return 0}if(!handle.$$){throwBindingError('Cannot pass "'+_embind_repr(handle)+'" as a '+this.name)}if(!handle.$$.ptr){throwBindingError("Cannot pass deleted object as a pointer of type "+this.name)}var handleClass=handle.$$.ptrType.registeredClass;var ptr=upcastPointer(handle.$$.ptr,handleClass,this.registeredClass);return ptr}function genericPointerToWireType(destructors,handle){var ptr;if(handle===null){if(this.isReference){throwBindingError("null is not a valid "+this.name)}if(this.isSmartPointer){ptr=this.rawConstructor();if(destructors!==null){destructors.push(this.rawDestructor,ptr)}return ptr}else{return 0}}if(!handle.$$){throwBindingError('Cannot pass "'+_embind_repr(handle)+'" as a '+this.name)}if(!handle.$$.ptr){throwBindingError("Cannot pass deleted object as a pointer of type "+this.name)}if(!this.isConst&&handle.$$.ptrType.isConst){throwBindingError("Cannot convert argument of type "+(handle.$$.smartPtrType?handle.$$.smartPtrType.name:handle.$$.ptrType.name)+" to parameter type "+this.name)}var handleClass=handle.$$.ptrType.registeredClass;ptr=upcastPointer(handle.$$.ptr,handleClass,this.registeredClass);if(this.isSmartPointer){if(undefined===handle.$$.smartPtr){throwBindingError("Passing raw pointer to smart pointer is illegal")}switch(this.sharingPolicy){case 0:if(handle.$$.smartPtrType===this){ptr=handle.$$.smartPtr}else{throwBindingError("Cannot convert argument of type "+(handle.$$.smartPtrType?handle.$$.smartPtrType.name:handle.$$.ptrType.name)+" to parameter type "+this.name)}break;case 1:ptr=handle.$$.smartPtr;break;case 2:if(handle.$$.smartPtrType===this){ptr=handle.$$.smartPtr}else{var clonedHandle=handle["clone"]();ptr=this.rawShare(ptr,__emval_register(function(){clonedHandle["delete"]()}));if(destructors!==null){destructors.push(this.rawDestructor,ptr)}}break;default:throwBindingError("Unsupporting sharing policy")}}return ptr}function nonConstNoSmartPtrRawPointerToWireType(destructors,handle){if(handle===null){if(this.isReference){throwBindingError("null is not a valid "+this.name)}return 0}if(!handle.$$){throwBindingError('Cannot pass "'+_embind_repr(handle)+'" as a '+this.name)}if(!handle.$$.ptr){throwBindingError("Cannot pass deleted object as a pointer of type "+this.name)}if(handle.$$.ptrType.isConst){throwBindingError("Cannot convert argument of type "+handle.$$.ptrType.name+" to parameter type "+this.name)}var handleClass=handle.$$.ptrType.registeredClass;var ptr=upcastPointer(handle.$$.ptr,handleClass,this.registeredClass);return ptr}function RegisteredPointer_getPointee(ptr){if(this.rawGetPointee){ptr=this.rawGetPointee(ptr)}return ptr}function RegisteredPointer_destructor(ptr){if(this.rawDestructor){this.rawDestructor(ptr)}}function RegisteredPointer_deleteObject(handle){if(handle!==null){handle["delete"]()}}function downcastPointer(ptr,ptrClass,desiredClass){if(ptrClass===desiredClass){return ptr}if(undefined===desiredClass.baseClass){return null}var rv=downcastPointer(ptr,ptrClass,desiredClass.baseClass);if(rv===null){return null}return desiredClass.downcast(rv)}function getInheritedInstanceCount(){return Object.keys(registeredInstances).length}function getLiveInheritedInstances(){var rv=[];for(var k in registeredInstances){if(registeredInstances.hasOwnProperty(k)){rv.push(registeredInstances[k])}}return rv}function setDelayFunction(fn){delayFunction=fn;if(deletionQueue.length&&delayFunction){delayFunction(flushPendingDeletes)}}function init_embind(){Module["getInheritedInstanceCount"]=getInheritedInstanceCount;Module["getLiveInheritedInstances"]=getLiveInheritedInstances;Module["flushPendingDeletes"]=flushPendingDeletes;Module["setDelayFunction"]=setDelayFunction}var registeredInstances={};function getBasestPointer(class_,ptr){if(ptr===undefined){throwBindingError("ptr should not be undefined")}while(class_.baseClass){ptr=class_.upcast(ptr);class_=class_.baseClass}return ptr}function getInheritedInstance(class_,ptr){ptr=getBasestPointer(class_,ptr);return registeredInstances[ptr]}function makeClassHandle(prototype,record){if(!record.ptrType||!record.ptr){throwInternalError("makeClassHandle requires ptr and ptrType")}var hasSmartPtrType=!!record.smartPtrType;var hasSmartPtr=!!record.smartPtr;if(hasSmartPtrType!==hasSmartPtr){throwInternalError("Both smartPtrType and smartPtr must be specified")}record.count={value:1};return attachFinalizer(Object.create(prototype,{$$:{value:record}}))}function RegisteredPointer_fromWireType(ptr){var rawPointer=this.getPointee(ptr);if(!rawPointer){this.destructor(ptr);return null}var registeredInstance=getInheritedInstance(this.registeredClass,rawPointer);if(undefined!==registeredInstance){if(0===registeredInstance.$$.count.value){registeredInstance.$$.ptr=rawPointer;registeredInstance.$$.smartPtr=ptr;return registeredInstance["clone"]()}else{var rv=registeredInstance["clone"]();this.destructor(ptr);return rv}}function makeDefaultHandle(){if(this.isSmartPointer){return makeClassHandle(this.registeredClass.instancePrototype,{ptrType:this.pointeeType,ptr:rawPointer,smartPtrType:this,smartPtr:ptr})}else{return makeClassHandle(this.registeredClass.instancePrototype,{ptrType:this,ptr:ptr})}}var actualType=this.registeredClass.getActualType(rawPointer);var registeredPointerRecord=registeredPointers[actualType];if(!registeredPointerRecord){return makeDefaultHandle.call(this)}var toType;if(this.isConst){toType=registeredPointerRecord.constPointerType}else{toType=registeredPointerRecord.pointerType}var dp=downcastPointer(rawPointer,this.registeredClass,toType.registeredClass);if(dp===null){return makeDefaultHandle.call(this)}if(this.isSmartPointer){return makeClassHandle(toType.registeredClass.instancePrototype,{ptrType:toType,ptr:dp,smartPtrType:this,smartPtr:ptr})}else{return makeClassHandle(toType.registeredClass.instancePrototype,{ptrType:toType,ptr:dp})}}function init_RegisteredPointer(){RegisteredPointer.prototype.getPointee=RegisteredPointer_getPointee;RegisteredPointer.prototype.destructor=RegisteredPointer_destructor;RegisteredPointer.prototype["argPackAdvance"]=8;RegisteredPointer.prototype["readValueFromPointer"]=simpleReadValueFromPointer;RegisteredPointer.prototype["deleteObject"]=RegisteredPointer_deleteObject;RegisteredPointer.prototype["fromWireType"]=RegisteredPointer_fromWireType}function RegisteredPointer(name,registeredClass,isReference,isConst,isSmartPointer,pointeeType,sharingPolicy,rawGetPointee,rawConstructor,rawShare,rawDestructor){this.name=name;this.registeredClass=registeredClass;this.isReference=isReference;this.isConst=isConst;this.isSmartPointer=isSmartPointer;this.pointeeType=pointeeType;this.sharingPolicy=sharingPolicy;this.rawGetPointee=rawGetPointee;this.rawConstructor=rawConstructor;this.rawShare=rawShare;this.rawDestructor=rawDestructor;if(!isSmartPointer&&registeredClass.baseClass===undefined){if(isConst){this["toWireType"]=constNoSmartPtrRawPointerToWireType;this.destructorFunction=null}else{this["toWireType"]=nonConstNoSmartPtrRawPointerToWireType;this.destructorFunction=null}}else{this["toWireType"]=genericPointerToWireType}}function replacePublicSymbol(name,value,numArguments){if(!Module.hasOwnProperty(name)){throwInternalError("Replacing nonexistant public symbol")}if(undefined!==Module[name].overloadTable&&undefined!==numArguments){Module[name].overloadTable[numArguments]=value}else{Module[name]=value;Module[name].argCount=numArguments}}function dynCallLegacy(sig,ptr,args){if(args&&args.length){return Module["dynCall_"+sig].apply(null,[ptr].concat(args))}return Module["dynCall_"+sig].call(null,ptr)}function dynCall(sig,ptr,args){if(sig.indexOf("j")!=-1){return dynCallLegacy(sig,ptr,args)}return wasmTable.get(ptr).apply(null,args)}function getDynCaller(sig,ptr){assert(sig.indexOf("j")>=0,"getDynCaller should only be called with i64 sigs");var argCache=[];return function(){argCache.length=arguments.length;for(var i=0;i<arguments.length;i++){argCache[i]=arguments[i]}return dynCall(sig,ptr,argCache)}}function embind__requireFunction(signature,rawFunction){signature=readLatin1String(signature);function makeDynCaller(){if(signature.indexOf("j")!=-1){return getDynCaller(signature,rawFunction)}return wasmTable.get(rawFunction)}var fp=makeDynCaller();if(typeof fp!=="function"){throwBindingError("unknown function pointer with signature "+signature+": "+rawFunction)}return fp}var UnboundTypeError=undefined;function getTypeName(type){var ptr=___getTypeName(type);var rv=readLatin1String(ptr);_free(ptr);return rv}function throwUnboundTypeError(message,types){var unboundTypes=[];var seen={};function visit(type){if(seen[type]){return}if(registeredTypes[type]){return}if(typeDependencies[type]){typeDependencies[type].forEach(visit);return}unboundTypes.push(type);seen[type]=true}types.forEach(visit);throw new UnboundTypeError(message+": "+unboundTypes.map(getTypeName).join([", "]))}function __embind_register_class(rawType,rawPointerType,rawConstPointerType,baseClassRawType,getActualTypeSignature,getActualType,upcastSignature,upcast,downcastSignature,downcast,name,destructorSignature,rawDestructor){name=readLatin1String(name);getActualType=embind__requireFunction(getActualTypeSignature,getActualType);if(upcast){upcast=embind__requireFunction(upcastSignature,upcast)}if(downcast){downcast=embind__requireFunction(downcastSignature,downcast)}rawDestructor=embind__requireFunction(destructorSignature,rawDestructor);var legalFunctionName=makeLegalFunctionName(name);exposePublicSymbol(legalFunctionName,function(){throwUnboundTypeError("Cannot construct "+name+" due to unbound types",[baseClassRawType])});whenDependentTypesAreResolved([rawType,rawPointerType,rawConstPointerType],baseClassRawType?[baseClassRawType]:[],function(base){base=base[0];var baseClass;var basePrototype;if(baseClassRawType){baseClass=base.registeredClass;basePrototype=baseClass.instancePrototype}else{basePrototype=ClassHandle.prototype}var constructor=createNamedFunction(legalFunctionName,function(){if(Object.getPrototypeOf(this)!==instancePrototype){throw new BindingError("Use 'new' to construct "+name)}if(undefined===registeredClass.constructor_body){throw new BindingError(name+" has no accessible constructor")}var body=registeredClass.constructor_body[arguments.length];if(undefined===body){throw new BindingError("Tried to invoke ctor of "+name+" with invalid number of parameters ("+arguments.length+") - expected ("+Object.keys(registeredClass.constructor_body).toString()+") parameters instead!")}return body.apply(this,arguments)});var instancePrototype=Object.create(basePrototype,{constructor:{value:constructor}});constructor.prototype=instancePrototype;var registeredClass=new RegisteredClass(name,constructor,instancePrototype,rawDestructor,baseClass,getActualType,upcast,downcast);var referenceConverter=new RegisteredPointer(name,registeredClass,true,false,false);var pointerConverter=new RegisteredPointer(name+"*",registeredClass,false,false,false);var constPointerConverter=new RegisteredPointer(name+" const*",registeredClass,false,true,false);registeredPointers[rawType]={pointerType:pointerConverter,constPointerType:constPointerConverter};replacePublicSymbol(legalFunctionName,constructor);return[referenceConverter,pointerConverter,constPointerConverter]})}function heap32VectorToArray(count,firstElement){var array=[];for(var i=0;i<count;i++){array.push(HEAP32[(firstElement>>2)+i])}return array}function __embind_register_class_constructor(rawClassType,argCount,rawArgTypesAddr,invokerSignature,invoker,rawConstructor){assert(argCount>0);var rawArgTypes=heap32VectorToArray(argCount,rawArgTypesAddr);invoker=embind__requireFunction(invokerSignature,invoker);var args=[rawConstructor];var destructors=[];whenDependentTypesAreResolved([],[rawClassType],function(classType){classType=classType[0];var humanName="constructor "+classType.name;if(undefined===classType.registeredClass.constructor_body){classType.registeredClass.constructor_body=[]}if(undefined!==classType.registeredClass.constructor_body[argCount-1]){throw new BindingError("Cannot register multiple constructors with identical number of parameters ("+(argCount-1)+") for class '"+classType.name+"'! Overload resolution is currently only performed using the parameter count, not actual type info!")}classType.registeredClass.constructor_body[argCount-1]=function unboundTypeHandler(){throwUnboundTypeError("Cannot construct "+classType.name+" due to unbound types",rawArgTypes)};whenDependentTypesAreResolved([],rawArgTypes,function(argTypes){classType.registeredClass.constructor_body[argCount-1]=function constructor_body(){if(arguments.length!==argCount-1){throwBindingError(humanName+" called with "+arguments.length+" arguments, expected "+(argCount-1))}destructors.length=0;args.length=argCount;for(var i=1;i<argCount;++i){args[i]=argTypes[i]["toWireType"](destructors,arguments[i-1])}var ptr=invoker.apply(null,args);runDestructors(destructors);return argTypes[0]["fromWireType"](ptr)};return[]});return[]})}function new_(constructor,argumentList){if(!(constructor instanceof Function)){throw new TypeError("new_ called with constructor type "+typeof constructor+" which is not a function")}var dummy=createNamedFunction(constructor.name||"unknownFunctionName",function(){});dummy.prototype=constructor.prototype;var obj=new dummy;var r=constructor.apply(obj,argumentList);return r instanceof Object?r:obj}function craftInvokerFunction(humanName,argTypes,classType,cppInvokerFunc,cppTargetFunc){var argCount=argTypes.length;if(argCount<2){throwBindingError("argTypes array size mismatch! Must at least get return value and 'this' types!")}var isClassMethodFunc=argTypes[1]!==null&&classType!==null;var needsDestructorStack=false;for(var i=1;i<argTypes.length;++i){if(argTypes[i]!==null&&argTypes[i].destructorFunction===undefined){needsDestructorStack=true;break}}var returns=argTypes[0].name!=="void";var argsList="";var argsListWired="";for(var i=0;i<argCount-2;++i){argsList+=(i!==0?", ":"")+"arg"+i;argsListWired+=(i!==0?", ":"")+"arg"+i+"Wired"}var invokerFnBody="return function "+makeLegalFunctionName(humanName)+"("+argsList+") {\n"+"if (arguments.length !== "+(argCount-2)+") {\n"+"throwBindingError('function "+humanName+" called with ' + arguments.length + ' arguments, expected "+(argCount-2)+" args!');\n"+"}\n";if(needsDestructorStack){invokerFnBody+="var destructors = [];\n"}var dtorStack=needsDestructorStack?"destructors":"null";var args1=["throwBindingError","invoker","fn","runDestructors","retType","classParam"];var args2=[throwBindingError,cppInvokerFunc,cppTargetFunc,runDestructors,argTypes[0],argTypes[1]];if(isClassMethodFunc){invokerFnBody+="var thisWired = classParam.toWireType("+dtorStack+", this);\n"}for(var i=0;i<argCount-2;++i){invokerFnBody+="var arg"+i+"Wired = argType"+i+".toWireType("+dtorStack+", arg"+i+"); // "+argTypes[i+2].name+"\n";args1.push("argType"+i);args2.push(argTypes[i+2])}if(isClassMethodFunc){argsListWired="thisWired"+(argsListWired.length>0?", ":"")+argsListWired}invokerFnBody+=(returns?"var rv = ":"")+"invoker(fn"+(argsListWired.length>0?", ":"")+argsListWired+");\n";if(needsDestructorStack){invokerFnBody+="runDestructors(destructors);\n"}else{for(var i=isClassMethodFunc?1:2;i<argTypes.length;++i){var paramName=i===1?"thisWired":"arg"+(i-2)+"Wired";if(argTypes[i].destructorFunction!==null){invokerFnBody+=paramName+"_dtor("+paramName+"); // "+argTypes[i].name+"\n";args1.push(paramName+"_dtor");args2.push(argTypes[i].destructorFunction)}}}if(returns){invokerFnBody+="var ret = retType.fromWireType(rv);\n"+"return ret;\n"}else{}invokerFnBody+="}\n";args1.push(invokerFnBody);var invokerFunction=new_(Function,args1).apply(null,args2);return invokerFunction}function __embind_register_class_function(rawClassType,methodName,argCount,rawArgTypesAddr,invokerSignature,rawInvoker,context,isPureVirtual){var rawArgTypes=heap32VectorToArray(argCount,rawArgTypesAddr);methodName=readLatin1String(methodName);rawInvoker=embind__requireFunction(invokerSignature,rawInvoker);whenDependentTypesAreResolved([],[rawClassType],function(classType){classType=classType[0];var humanName=classType.name+"."+methodName;if(isPureVirtual){classType.registeredClass.pureVirtualFunctions.push(methodName)}function unboundTypesHandler(){throwUnboundTypeError("Cannot call "+humanName+" due to unbound types",rawArgTypes)}var proto=classType.registeredClass.instancePrototype;var method=proto[methodName];if(undefined===method||undefined===method.overloadTable&&method.className!==classType.name&&method.argCount===argCount-2){unboundTypesHandler.argCount=argCount-2;unboundTypesHandler.className=classType.name;proto[methodName]=unboundTypesHandler}else{ensureOverloadTable(proto,methodName,humanName);proto[methodName].overloadTable[argCount-2]=unboundTypesHandler}whenDependentTypesAreResolved([],rawArgTypes,function(argTypes){var memberFunction=craftInvokerFunction(humanName,argTypes,classType,rawInvoker,context);if(undefined===proto[methodName].overloadTable){memberFunction.argCount=argCount-2;proto[methodName]=memberFunction}else{proto[methodName].overloadTable[argCount-2]=memberFunction}return[]});return[]})}var emval_free_list=[];var emval_handle_array=[{},{value:undefined},{value:null},{value:true},{value:false}];function __emval_decref(handle){if(handle>4&&0===--emval_handle_array[handle].refcount){emval_handle_array[handle]=undefined;emval_free_list.push(handle)}}function count_emval_handles(){var count=0;for(var i=5;i<emval_handle_array.length;++i){if(emval_handle_array[i]!==undefined){++count}}return count}function get_first_emval(){for(var i=5;i<emval_handle_array.length;++i){if(emval_handle_array[i]!==undefined){return emval_handle_array[i]}}return null}function init_emval(){Module["count_emval_handles"]=count_emval_handles;Module["get_first_emval"]=get_first_emval}function __emval_register(value){switch(value){case undefined:{return 1}case null:{return 2}case true:{return 3}case false:{return 4}default:{var handle=emval_free_list.length?emval_free_list.pop():emval_handle_array.length;emval_handle_array[handle]={refcount:1,value:value};return handle}}}function __embind_register_emval(rawType,name){name=readLatin1String(name);registerType(rawType,{name:name,"fromWireType":function(handle){var rv=emval_handle_array[handle].value;__emval_decref(handle);return rv},"toWireType":function(destructors,value){return __emval_register(value)},"argPackAdvance":8,"readValueFromPointer":simpleReadValueFromPointer,destructorFunction:null})}function enumReadValueFromPointer(name,shift,signed){switch(shift){case 0:return function(pointer){var heap=signed?HEAP8:HEAPU8;return this["fromWireType"](heap[pointer])};case 1:return function(pointer){var heap=signed?HEAP16:HEAPU16;return this["fromWireType"](heap[pointer>>1])};case 2:return function(pointer){var heap=signed?HEAP32:HEAPU32;return this["fromWireType"](heap[pointer>>2])};default:throw new TypeError("Unknown integer type: "+name)}}function __embind_register_enum(rawType,name,size,isSigned){var shift=getShiftFromSize(size);name=readLatin1String(name);function ctor(){}ctor.values={};registerType(rawType,{name:name,constructor:ctor,"fromWireType":function(c){return this.constructor.values[c]},"toWireType":function(destructors,c){return c.value},"argPackAdvance":8,"readValueFromPointer":enumReadValueFromPointer(name,shift,isSigned),destructorFunction:null});exposePublicSymbol(name,ctor)}function requireRegisteredType(rawType,humanName){var impl=registeredTypes[rawType];if(undefined===impl){throwBindingError(humanName+" has unknown type "+getTypeName(rawType))}return impl}function __embind_register_enum_value(rawEnumType,name,enumValue){var enumType=requireRegisteredType(rawEnumType,"enum");name=readLatin1String(name);var Enum=enumType.constructor;var Value=Object.create(enumType.constructor.prototype,{value:{value:enumValue},constructor:{value:createNamedFunction(enumType.name+"_"+name,function(){})}});Enum.values[enumValue]=Value;Enum[name]=Value}function _embind_repr(v){if(v===null){return"null"}var t=typeof v;if(t==="object"||t==="array"||t==="function"){return v.toString()}else{return""+v}}function floatReadValueFromPointer(name,shift){switch(shift){case 2:return function(pointer){return this["fromWireType"](HEAPF32[pointer>>2])};case 3:return function(pointer){return this["fromWireType"](HEAPF64[pointer>>3])};default:throw new TypeError("Unknown float type: "+name)}}function __embind_register_float(rawType,name,size){var shift=getShiftFromSize(size);name=readLatin1String(name);registerType(rawType,{name:name,"fromWireType":function(value){return value},"toWireType":function(destructors,value){if(typeof value!=="number"&&typeof value!=="boolean"){throw new TypeError('Cannot convert "'+_embind_repr(value)+'" to '+this.name)}return value},"argPackAdvance":8,"readValueFromPointer":floatReadValueFromPointer(name,shift),destructorFunction:null})}function __embind_register_function(name,argCount,rawArgTypesAddr,signature,rawInvoker,fn){var argTypes=heap32VectorToArray(argCount,rawArgTypesAddr);name=readLatin1String(name);rawInvoker=embind__requireFunction(signature,rawInvoker);exposePublicSymbol(name,function(){throwUnboundTypeError("Cannot call "+name+" due to unbound types",argTypes)},argCount-1);whenDependentTypesAreResolved([],argTypes,function(argTypes){var invokerArgsArray=[argTypes[0],null].concat(argTypes.slice(1));replacePublicSymbol(name,craftInvokerFunction(name,invokerArgsArray,null,rawInvoker,fn),argCount-1);return[]})}function integerReadValueFromPointer(name,shift,signed){switch(shift){case 0:return signed?function readS8FromPointer(pointer){return HEAP8[pointer]}:function readU8FromPointer(pointer){return HEAPU8[pointer]};case 1:return signed?function readS16FromPointer(pointer){return HEAP16[pointer>>1]}:function readU16FromPointer(pointer){return HEAPU16[pointer>>1]};case 2:return signed?function readS32FromPointer(pointer){return HEAP32[pointer>>2]}:function readU32FromPointer(pointer){return HEAPU32[pointer>>2]};default:throw new TypeError("Unknown integer type: "+name)}}function __embind_register_integer(primitiveType,name,size,minRange,maxRange){name=readLatin1String(name);if(maxRange===-1){maxRange=4294967295}var shift=getShiftFromSize(size);var fromWireType=function(value){return value};if(minRange===0){var bitshift=32-8*size;fromWireType=function(value){return value<<bitshift>>>bitshift}}var isUnsignedType=name.indexOf("unsigned")!=-1;registerType(primitiveType,{name:name,"fromWireType":fromWireType,"toWireType":function(destructors,value){if(typeof value!=="number"&&typeof value!=="boolean"){throw new TypeError('Cannot convert "'+_embind_repr(value)+'" to '+this.name)}if(value<minRange||value>maxRange){throw new TypeError('Passing a number "'+_embind_repr(value)+'" from JS side to C/C++ side to an argument of type "'+name+'", which is outside the valid range ['+minRange+", "+maxRange+"]!")}return isUnsignedType?value>>>0:value|0},"argPackAdvance":8,"readValueFromPointer":integerReadValueFromPointer(name,shift,minRange!==0),destructorFunction:null})}function __embind_register_memory_view(rawType,dataTypeIndex,name){var typeMapping=[Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array];var TA=typeMapping[dataTypeIndex];function decodeMemoryView(handle){handle=handle>>2;var heap=HEAPU32;var size=heap[handle];var data=heap[handle+1];return new TA(buffer,data,size)}name=readLatin1String(name);registerType(rawType,{name:name,"fromWireType":decodeMemoryView,"argPackAdvance":8,"readValueFromPointer":decodeMemoryView},{ignoreDuplicateRegistrations:true})}function __embind_register_std_string(rawType,name){name=readLatin1String(name);var stdStringIsUTF8=name==="std::string";registerType(rawType,{name:name,"fromWireType":function(value){var length=HEAPU32[value>>2];var str;if(stdStringIsUTF8){var decodeStartPtr=value+4;for(var i=0;i<=length;++i){var currentBytePtr=value+4+i;if(i==length||HEAPU8[currentBytePtr]==0){var maxRead=currentBytePtr-decodeStartPtr;var stringSegment=UTF8ToString(decodeStartPtr,maxRead);if(str===undefined){str=stringSegment}else{str+=String.fromCharCode(0);str+=stringSegment}decodeStartPtr=currentBytePtr+1}}}else{var a=new Array(length);for(var i=0;i<length;++i){a[i]=String.fromCharCode(HEAPU8[value+4+i])}str=a.join("")}_free(value);return str},"toWireType":function(destructors,value){if(value instanceof ArrayBuffer){value=new Uint8Array(value)}var getLength;var valueIsOfTypeString=typeof value==="string";if(!(valueIsOfTypeString||value instanceof Uint8Array||value instanceof Uint8ClampedArray||value instanceof Int8Array)){throwBindingError("Cannot pass non-string to std::string")}if(stdStringIsUTF8&&valueIsOfTypeString){getLength=function(){return lengthBytesUTF8(value)}}else{getLength=function(){return value.length}}var length=getLength();var ptr=_malloc(4+length+1);HEAPU32[ptr>>2]=length;if(stdStringIsUTF8&&valueIsOfTypeString){stringToUTF8(value,ptr+4,length+1)}else{if(valueIsOfTypeString){for(var i=0;i<length;++i){var charCode=value.charCodeAt(i);if(charCode>255){_free(ptr);throwBindingError("String has UTF-16 code units that do not fit in 8 bits")}HEAPU8[ptr+4+i]=charCode}}else{for(var i=0;i<length;++i){HEAPU8[ptr+4+i]=value[i]}}}if(destructors!==null){destructors.push(_free,ptr)}return ptr},"argPackAdvance":8,"readValueFromPointer":simpleReadValueFromPointer,destructorFunction:function(ptr){_free(ptr)}})}function __embind_register_std_wstring(rawType,charSize,name){name=readLatin1String(name);var decodeString,encodeString,getHeap,lengthBytesUTF,shift;if(charSize===2){decodeString=UTF16ToString;encodeString=stringToUTF16;lengthBytesUTF=lengthBytesUTF16;getHeap=function(){return HEAPU16};shift=1}else if(charSize===4){decodeString=UTF32ToString;encodeString=stringToUTF32;lengthBytesUTF=lengthBytesUTF32;getHeap=function(){return HEAPU32};shift=2}registerType(rawType,{name:name,"fromWireType":function(value){var length=HEAPU32[value>>2];var HEAP=getHeap();var str;var decodeStartPtr=value+4;for(var i=0;i<=length;++i){var currentBytePtr=value+4+i*charSize;if(i==length||HEAP[currentBytePtr>>shift]==0){var maxReadBytes=currentBytePtr-decodeStartPtr;var stringSegment=decodeString(decodeStartPtr,maxReadBytes);if(str===undefined){str=stringSegment}else{str+=String.fromCharCode(0);str+=stringSegment}decodeStartPtr=currentBytePtr+charSize}}_free(value);return str},"toWireType":function(destructors,value){if(!(typeof value==="string")){throwBindingError("Cannot pass non-string to C++ string type "+name)}var length=lengthBytesUTF(value);var ptr=_malloc(4+length+charSize);HEAPU32[ptr>>2]=length>>shift;encodeString(value,ptr+4,length+charSize);if(destructors!==null){destructors.push(_free,ptr)}return ptr},"argPackAdvance":8,"readValueFromPointer":simpleReadValueFromPointer,destructorFunction:function(ptr){_free(ptr)}})}function __embind_register_value_object(rawType,name,constructorSignature,rawConstructor,destructorSignature,rawDestructor){structRegistrations[rawType]={name:readLatin1String(name),rawConstructor:embind__requireFunction(constructorSignature,rawConstructor),rawDestructor:embind__requireFunction(destructorSignature,rawDestructor),fields:[]}}function __embind_register_value_object_field(structType,fieldName,getterReturnType,getterSignature,getter,getterContext,setterArgumentType,setterSignature,setter,setterContext){structRegistrations[structType].fields.push({fieldName:readLatin1String(fieldName),getterReturnType:getterReturnType,getter:embind__requireFunction(getterSignature,getter),getterContext:getterContext,setterArgumentType:setterArgumentType,setter:embind__requireFunction(setterSignature,setter),setterContext:setterContext})}function __embind_register_void(rawType,name){name=readLatin1String(name);registerType(rawType,{isVoid:true,name:name,"argPackAdvance":0,"fromWireType":function(){return undefined},"toWireType":function(destructors,o){return undefined}})}function requireHandle(handle){if(!handle){throwBindingError("Cannot use deleted val. handle = "+handle)}return emval_handle_array[handle].value}function __emval_as(handle,returnType,destructorsRef){handle=requireHandle(handle);returnType=requireRegisteredType(returnType,"emval::as");var destructors=[];var rd=__emval_register(destructors);HEAP32[destructorsRef>>2]=rd;return returnType["toWireType"](destructors,handle)}var emval_symbols={};function getStringOrSymbol(address){var symbol=emval_symbols[address];if(symbol===undefined){return readLatin1String(address)}else{return symbol}}var emval_methodCallers=[];function __emval_call_void_method(caller,handle,methodName,args){caller=emval_methodCallers[caller];handle=requireHandle(handle);methodName=getStringOrSymbol(methodName);caller(handle,methodName,null,args)}function emval_get_global(){if(typeof globalThis==="object"){return globalThis}return function(){return Function}()("return this")()}function __emval_get_global(name){if(name===0){return __emval_register(emval_get_global())}else{name=getStringOrSymbol(name);return __emval_register(emval_get_global()[name])}}function __emval_addMethodCaller(caller){var id=emval_methodCallers.length;emval_methodCallers.push(caller);return id}function __emval_lookupTypes(argCount,argTypes){var a=new Array(argCount);for(var i=0;i<argCount;++i){a[i]=requireRegisteredType(HEAP32[(argTypes>>2)+i],"parameter "+i)}return a}function __emval_get_method_caller(argCount,argTypes){var types=__emval_lookupTypes(argCount,argTypes);var retType=types[0];var signatureName=retType.name+"_$"+types.slice(1).map(function(t){return t.name}).join("_")+"$";var params=["retType"];var args=[retType];var argsList="";for(var i=0;i<argCount-1;++i){argsList+=(i!==0?", ":"")+"arg"+i;params.push("argType"+i);args.push(types[1+i])}var functionName=makeLegalFunctionName("methodCaller_"+signatureName);var functionBody="return function "+functionName+"(handle, name, destructors, args) {\n";var offset=0;for(var i=0;i<argCount-1;++i){functionBody+="    var arg"+i+" = argType"+i+".readValueFromPointer(args"+(offset?"+"+offset:"")+");\n";offset+=types[i+1]["argPackAdvance"]}functionBody+="    var rv = handle[name]("+argsList+");\n";for(var i=0;i<argCount-1;++i){if(types[i+1]["deleteObject"]){functionBody+="    argType"+i+".deleteObject(arg"+i+");\n"}}if(!retType.isVoid){functionBody+="    return retType.toWireType(destructors, rv);\n"}functionBody+="};\n";params.push(functionBody);var invokerFunction=new_(Function,params).apply(null,args);return __emval_addMethodCaller(invokerFunction)}function __emval_get_module_property(name){name=getStringOrSymbol(name);return __emval_register(Module[name])}function __emval_get_property(handle,key){handle=requireHandle(handle);key=requireHandle(key);return __emval_register(handle[key])}function __emval_incref(handle){if(handle>4){emval_handle_array[handle].refcount+=1}}function craftEmvalAllocator(argCount){var argsList="";for(var i=0;i<argCount;++i){argsList+=(i!==0?", ":"")+"arg"+i}var functionBody="return function emval_allocator_"+argCount+"(constructor, argTypes, args) {\n";for(var i=0;i<argCount;++i){functionBody+="var argType"+i+" = requireRegisteredType(Module['HEAP32'][(argTypes >>> 2) + "+i+'], "parameter '+i+'");\n'+"var arg"+i+" = argType"+i+".readValueFromPointer(args);\n"+"args += argType"+i+"['argPackAdvance'];\n"}functionBody+="var obj = new constructor("+argsList+");\n"+"return __emval_register(obj);\n"+"}\n";return new Function("requireRegisteredType","Module","__emval_register",functionBody)(requireRegisteredType,Module,__emval_register)}var emval_newers={};function __emval_new(handle,argCount,argTypes,args){handle=requireHandle(handle);var newer=emval_newers[argCount];if(!newer){newer=craftEmvalAllocator(argCount);emval_newers[argCount]=newer}return newer(handle,argTypes,args)}function __emval_new_cstring(v){return __emval_register(getStringOrSymbol(v))}function __emval_run_destructors(handle){var destructors=emval_handle_array[handle].value;runDestructors(destructors);__emval_decref(handle)}function _abort(){abort()}function _emscripten_memcpy_big(dest,src,num){HEAPU8.copyWithin(dest,src,src+num)}function _emscripten_get_heap_size(){return HEAPU8.length}function emscripten_realloc_buffer(size){try{wasmMemory.grow(size-buffer.byteLength+65535>>>16);updateGlobalBufferAndViews(wasmMemory.buffer);return 1}catch(e){}}function _emscripten_resize_heap(requestedSize){requestedSize=requestedSize>>>0;var oldSize=_emscripten_get_heap_size();var maxHeapSize=2147483648;if(requestedSize>maxHeapSize){return false}var minHeapSize=16777216;for(var cutDown=1;cutDown<=4;cutDown*=2){var overGrownHeapSize=oldSize*(1+.2/cutDown);overGrownHeapSize=Math.min(overGrownHeapSize,requestedSize+100663296);var newSize=Math.min(maxHeapSize,alignUp(Math.max(minHeapSize,requestedSize,overGrownHeapSize),65536));var replacement=emscripten_realloc_buffer(newSize);if(replacement){return true}}return false}InternalError=Module["InternalError"]=extendError(Error,"InternalError");embind_init_charCodes();BindingError=Module["BindingError"]=extendError(Error,"BindingError");init_ClassHandle();init_RegisteredPointer();init_embind();UnboundTypeError=Module["UnboundTypeError"]=extendError(Error,"UnboundTypeError");init_emval();__ATINIT__.push({func:function(){___wasm_call_ctors()}});var asmLibraryArg={"G":___cxa_allocate_exception,"F":___cxa_throw,"s":__embind_finalize_value_object,"D":__embind_register_bool,"x":__embind_register_class,"w":__embind_register_class_constructor,"d":__embind_register_class_function,"C":__embind_register_emval,"o":__embind_register_enum,"b":__embind_register_enum_value,"u":__embind_register_float,"j":__embind_register_function,"h":__embind_register_integer,"g":__embind_register_memory_view,"v":__embind_register_std_string,"r":__embind_register_std_wstring,"t":__embind_register_value_object,"c":__embind_register_value_object_field,"E":__embind_register_void,"l":__emval_as,"p":__emval_call_void_method,"a":__emval_decref,"y":__emval_get_global,"q":__emval_get_method_caller,"n":__emval_get_module_property,"e":__emval_get_property,"i":__emval_incref,"m":__emval_new,"f":__emval_new_cstring,"k":__emval_run_destructors,"B":_abort,"z":_emscripten_memcpy_big,"A":_emscripten_resize_heap};var asm=createWasm();var ___wasm_call_ctors=Module["___wasm_call_ctors"]=function(){return(___wasm_call_ctors=Module["___wasm_call_ctors"]=Module["asm"]["J"]).apply(null,arguments)};var _malloc=Module["_malloc"]=function(){return(_malloc=Module["_malloc"]=Module["asm"]["K"]).apply(null,arguments)};var _free=Module["_free"]=function(){return(_free=Module["_free"]=Module["asm"]["L"]).apply(null,arguments)};var ___getTypeName=Module["___getTypeName"]=function(){return(___getTypeName=Module["___getTypeName"]=Module["asm"]["M"]).apply(null,arguments)};var ___embind_register_native_and_builtin_types=Module["___embind_register_native_and_builtin_types"]=function(){return(___embind_register_native_and_builtin_types=Module["___embind_register_native_and_builtin_types"]=Module["asm"]["N"]).apply(null,arguments)};var calledRun;function ExitStatus(status){this.name="ExitStatus";this.message="Program terminated with exit("+status+")";this.status=status}dependenciesFulfilled=function runCaller(){if(!calledRun)run();if(!calledRun)dependenciesFulfilled=runCaller};function run(args){args=args||arguments_;if(runDependencies>0){return}preRun();if(runDependencies>0)return;function doRun(){if(calledRun)return;calledRun=true;Module["calledRun"]=true;if(ABORT)return;initRuntime();preMain();readyPromiseResolve(Module);if(Module["onRuntimeInitialized"])Module["onRuntimeInitialized"]();postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout(function(){setTimeout(function(){Module["setStatus"]("")},1);doRun()},1)}else{doRun()}}Module["run"]=run;if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].pop()()}}noExitRuntime=true;run();
 
 
-  return BASIS
+  return BASIS.ready
 }
 );
 })();
 if (typeof exports === 'object' && typeof module === 'object')
-      module.exports = BASIS;
-    else if (typeof define === 'function' && define['amd'])
-      define([], function() { return BASIS; });
-    else if (typeof exports === 'object')
-      exports["BASIS"] = BASIS;
+  module.exports = BASIS;
+else if (typeof define === 'function' && define['amd'])
+  define([], function() { return BASIS; });
+else if (typeof exports === 'object')
+  exports["BASIS"] = BASIS;
diff --git a/webgl/transcoder/build/basis_transcoder.wasm b/webgl/transcoder/build/basis_transcoder.wasm
index 08e026b..bfb0162 100644
--- a/webgl/transcoder/build/basis_transcoder.wasm
+++ b/webgl/transcoder/build/basis_transcoder.wasm
Binary files differ
diff --git a/webgl_videotest/basis.js b/webgl_videotest/basis.js
index eb881fd..2612e08 100644
--- a/webgl_videotest/basis.js
+++ b/webgl_videotest/basis.js
@@ -1,20 +1 @@
-var Module;if(!Module)Module=(typeof Module!=="undefined"?Module:null)||{};var moduleOverrides={};for(var key in Module){if(Module.hasOwnProperty(key)){moduleOverrides[key]=Module[key]}}var ENVIRONMENT_IS_WEB=typeof window==="object";var ENVIRONMENT_IS_WORKER=typeof importScripts==="function";var ENVIRONMENT_IS_NODE=typeof process==="object"&&typeof require==="function"&&!ENVIRONMENT_IS_WEB&&!ENVIRONMENT_IS_WORKER;var ENVIRONMENT_IS_SHELL=!ENVIRONMENT_IS_WEB&&!ENVIRONMENT_IS_NODE&&!ENVIRONMENT_IS_WORKER;if(ENVIRONMENT_IS_NODE){if(!Module["print"])Module["print"]=function print(x){process["stdout"].write(x+"\n")};if(!Module["printErr"])Module["printErr"]=function printErr(x){process["stderr"].write(x+"\n")};var nodeFS=require("fs");var nodePath=require("path");Module["read"]=function read(filename,binary){filename=nodePath["normalize"](filename);var ret=nodeFS["readFileSync"](filename);if(!ret&&filename!=nodePath["resolve"](filename)){filename=path.join(__dirname,"..","src",filename);ret=nodeFS["readFileSync"](filename)}if(ret&&!binary)ret=ret.toString();return ret};Module["readBinary"]=function readBinary(filename){var ret=Module["read"](filename,true);if(!ret.buffer){ret=new Uint8Array(ret)}assert(ret.buffer);return ret};Module["load"]=function load(f){globalEval(read(f))};if(!Module["thisProgram"]){if(process["argv"].length>1){Module["thisProgram"]=process["argv"][1].replace(/\\/g,"/")}else{Module["thisProgram"]="unknown-program"}}Module["arguments"]=process["argv"].slice(2);if(typeof module!=="undefined"){module["exports"]=Module}process["on"]("uncaughtException",(function(ex){if(!(ex instanceof ExitStatus)){throw ex}}));Module["inspect"]=(function(){return"[Emscripten Module object]"})}else if(ENVIRONMENT_IS_SHELL){if(!Module["print"])Module["print"]=print;if(typeof printErr!="undefined")Module["printErr"]=printErr;if(typeof read!="undefined"){Module["read"]=read}else{Module["read"]=function read(){throw"no read() available (jsc?)"}}Module["readBinary"]=function readBinary(f){if(typeof readbuffer==="function"){return new Uint8Array(readbuffer(f))}var data=read(f,"binary");assert(typeof data==="object");return data};if(typeof scriptArgs!="undefined"){Module["arguments"]=scriptArgs}else if(typeof arguments!="undefined"){Module["arguments"]=arguments}}else if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){Module["read"]=function read(url){var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.send(null);return xhr.responseText};if(typeof arguments!="undefined"){Module["arguments"]=arguments}if(typeof console!=="undefined"){if(!Module["print"])Module["print"]=function print(x){console.log(x)};if(!Module["printErr"])Module["printErr"]=function printErr(x){console.log(x)}}else{var TRY_USE_DUMP=false;if(!Module["print"])Module["print"]=TRY_USE_DUMP&&typeof dump!=="undefined"?(function(x){dump(x)}):(function(x){})}if(ENVIRONMENT_IS_WORKER){Module["load"]=importScripts}if(typeof Module["setWindowTitle"]==="undefined"){Module["setWindowTitle"]=(function(title){document.title=title})}}else{throw"Unknown runtime environment. Where are we?"}function globalEval(x){eval.call(null,x)}if(!Module["load"]&&Module["read"]){Module["load"]=function load(f){globalEval(Module["read"](f))}}if(!Module["print"]){Module["print"]=(function(){})}if(!Module["printErr"]){Module["printErr"]=Module["print"]}if(!Module["arguments"]){Module["arguments"]=[]}if(!Module["thisProgram"]){Module["thisProgram"]="./this.program"}Module.print=Module["print"];Module.printErr=Module["printErr"];Module["preRun"]=[];Module["postRun"]=[];for(var key in moduleOverrides){if(moduleOverrides.hasOwnProperty(key)){Module[key]=moduleOverrides[key]}}var Runtime={setTempRet0:(function(value){tempRet0=value}),getTempRet0:(function(){return tempRet0}),stackSave:(function(){return STACKTOP}),stackRestore:(function(stackTop){STACKTOP=stackTop}),getNativeTypeSize:(function(type){switch(type){case"i1":case"i8":return 1;case"i16":return 2;case"i32":return 4;case"i64":return 8;case"float":return 4;case"double":return 8;default:{if(type[type.length-1]==="*"){return Runtime.QUANTUM_SIZE}else if(type[0]==="i"){var bits=parseInt(type.substr(1));assert(bits%8===0);return bits/8}else{return 0}}}}),getNativeFieldSize:(function(type){return Math.max(Runtime.getNativeTypeSize(type),Runtime.QUANTUM_SIZE)}),STACK_ALIGN:16,prepVararg:(function(ptr,type){if(type==="double"||type==="i64"){if(ptr&7){assert((ptr&7)===4);ptr+=4}}else{assert((ptr&3)===0)}return ptr}),getAlignSize:(function(type,size,vararg){if(!vararg&&(type=="i64"||type=="double"))return 8;if(!type)return Math.min(size,8);return Math.min(size||(type?Runtime.getNativeFieldSize(type):0),Runtime.QUANTUM_SIZE)}),dynCall:(function(sig,ptr,args){if(args&&args.length){if(!args.splice)args=Array.prototype.slice.call(args);args.splice(0,0,ptr);return Module["dynCall_"+sig].apply(null,args)}else{return Module["dynCall_"+sig].call(null,ptr)}}),functionPointers:[],addFunction:(function(func){for(var i=0;i<Runtime.functionPointers.length;i++){if(!Runtime.functionPointers[i]){Runtime.functionPointers[i]=func;return 2*(1+i)}}throw"Finished up all reserved function pointers. Use a higher value for RESERVED_FUNCTION_POINTERS."}),removeFunction:(function(index){Runtime.functionPointers[(index-2)/2]=null}),warnOnce:(function(text){if(!Runtime.warnOnce.shown)Runtime.warnOnce.shown={};if(!Runtime.warnOnce.shown[text]){Runtime.warnOnce.shown[text]=1;Module.printErr(text)}}),funcWrappers:{},getFuncWrapper:(function(func,sig){assert(sig);if(!Runtime.funcWrappers[sig]){Runtime.funcWrappers[sig]={}}var sigCache=Runtime.funcWrappers[sig];if(!sigCache[func]){sigCache[func]=function dynCall_wrapper(){return Runtime.dynCall(sig,func,arguments)}}return sigCache[func]}),getCompilerSetting:(function(name){throw"You must build with -s RETAIN_COMPILER_SETTINGS=1 for Runtime.getCompilerSetting or emscripten_get_compiler_setting to work"}),stackAlloc:(function(size){var ret=STACKTOP;STACKTOP=STACKTOP+size|0;STACKTOP=STACKTOP+15&-16;return ret}),staticAlloc:(function(size){var ret=STATICTOP;STATICTOP=STATICTOP+size|0;STATICTOP=STATICTOP+15&-16;return ret}),dynamicAlloc:(function(size){var ret=DYNAMICTOP;DYNAMICTOP=DYNAMICTOP+size|0;DYNAMICTOP=DYNAMICTOP+15&-16;if(DYNAMICTOP>=TOTAL_MEMORY){var success=enlargeMemory();if(!success){DYNAMICTOP=ret;return 0}}return ret}),alignMemory:(function(size,quantum){var ret=size=Math.ceil(size/(quantum?quantum:16))*(quantum?quantum:16);return ret}),makeBigInt:(function(low,high,unsigned){var ret=unsigned?+(low>>>0)+ +(high>>>0)*+4294967296:+(low>>>0)+ +(high|0)*+4294967296;return ret}),GLOBAL_BASE:8,QUANTUM_SIZE:4,__dummy__:0};Module["Runtime"]=Runtime;var __THREW__=0;var ABORT=false;var EXITSTATUS=0;var undef=0;var tempValue,tempInt,tempBigInt,tempInt2,tempBigInt2,tempPair,tempBigIntI,tempBigIntR,tempBigIntS,tempBigIntP,tempBigIntD,tempDouble,tempFloat;var tempI64,tempI64b;var tempRet0,tempRet1,tempRet2,tempRet3,tempRet4,tempRet5,tempRet6,tempRet7,tempRet8,tempRet9;function assert(condition,text){if(!condition){abort("Assertion failed: "+text)}}var globalScope=this;function getCFunc(ident){var func=Module["_"+ident];if(!func){try{func=eval("_"+ident)}catch(e){}}assert(func,"Cannot call unknown function "+ident+" (perhaps LLVM optimizations or closure removed it?)");return func}var cwrap,ccall;((function(){var JSfuncs={"stackSave":(function(){Runtime.stackSave()}),"stackRestore":(function(){Runtime.stackRestore()}),"arrayToC":(function(arr){var ret=Runtime.stackAlloc(arr.length);writeArrayToMemory(arr,ret);return ret}),"stringToC":(function(str){var ret=0;if(str!==null&&str!==undefined&&str!==0){ret=Runtime.stackAlloc((str.length<<2)+1);writeStringToMemory(str,ret)}return ret})};var toC={"string":JSfuncs["stringToC"],"array":JSfuncs["arrayToC"]};ccall=function ccallFunc(ident,returnType,argTypes,args,opts){var func=getCFunc(ident);var cArgs=[];var stack=0;if(args){for(var i=0;i<args.length;i++){var converter=toC[argTypes[i]];if(converter){if(stack===0)stack=Runtime.stackSave();cArgs[i]=converter(args[i])}else{cArgs[i]=args[i]}}}var ret=func.apply(null,cArgs);if(returnType==="string")ret=Pointer_stringify(ret);if(stack!==0){if(opts&&opts.async){EmterpreterAsync.asyncFinalizers.push((function(){Runtime.stackRestore(stack)}));return}Runtime.stackRestore(stack)}return ret};var sourceRegex=/^function\s*\(([^)]*)\)\s*{\s*([^*]*?)[\s;]*(?:return\s*(.*?)[;\s]*)?}$/;function parseJSFunc(jsfunc){var parsed=jsfunc.toString().match(sourceRegex).slice(1);return{arguments:parsed[0],body:parsed[1],returnValue:parsed[2]}}var JSsource={};for(var fun in JSfuncs){if(JSfuncs.hasOwnProperty(fun)){JSsource[fun]=parseJSFunc(JSfuncs[fun])}}cwrap=function cwrap(ident,returnType,argTypes){argTypes=argTypes||[];var cfunc=getCFunc(ident);var numericArgs=argTypes.every((function(type){return type==="number"}));var numericRet=returnType!=="string";if(numericRet&&numericArgs){return cfunc}var argNames=argTypes.map((function(x,i){return"$"+i}));var funcstr="(function("+argNames.join(",")+") {";var nargs=argTypes.length;if(!numericArgs){funcstr+="var stack = "+JSsource["stackSave"].body+";";for(var i=0;i<nargs;i++){var arg=argNames[i],type=argTypes[i];if(type==="number")continue;var convertCode=JSsource[type+"ToC"];funcstr+="var "+convertCode.arguments+" = "+arg+";";funcstr+=convertCode.body+";";funcstr+=arg+"="+convertCode.returnValue+";"}}var cfuncname=parseJSFunc((function(){return cfunc})).returnValue;funcstr+="var ret = "+cfuncname+"("+argNames.join(",")+");";if(!numericRet){var strgfy=parseJSFunc((function(){return Pointer_stringify})).returnValue;funcstr+="ret = "+strgfy+"(ret);"}if(!numericArgs){funcstr+=JSsource["stackRestore"].body.replace("()","(stack)")+";"}funcstr+="return ret})";return eval(funcstr)}}))();Module["ccall"]=ccall;Module["cwrap"]=cwrap;function setValue(ptr,value,type,noSafe){type=type||"i8";if(type.charAt(type.length-1)==="*")type="i32";switch(type){case"i1":HEAP8[ptr>>0]=value;break;case"i8":HEAP8[ptr>>0]=value;break;case"i16":HEAP16[ptr>>1]=value;break;case"i32":HEAP32[ptr>>2]=value;break;case"i64":tempI64=[value>>>0,(tempDouble=value,+Math_abs(tempDouble)>=+1?tempDouble>+0?(Math_min(+Math_floor(tempDouble/+4294967296),+4294967295)|0)>>>0:~~+Math_ceil((tempDouble- +(~~tempDouble>>>0))/+4294967296)>>>0:0)],HEAP32[ptr>>2]=tempI64[0],HEAP32[ptr+4>>2]=tempI64[1];break;case"float":HEAPF32[ptr>>2]=value;break;case"double":HEAPF64[ptr>>3]=value;break;default:abort("invalid type for setValue: "+type)}}Module["setValue"]=setValue;function getValue(ptr,type,noSafe){type=type||"i8";if(type.charAt(type.length-1)==="*")type="i32";switch(type){case"i1":return HEAP8[ptr>>0];case"i8":return HEAP8[ptr>>0];case"i16":return HEAP16[ptr>>1];case"i32":return HEAP32[ptr>>2];case"i64":return HEAP32[ptr>>2];case"float":return HEAPF32[ptr>>2];case"double":return HEAPF64[ptr>>3];default:abort("invalid type for setValue: "+type)}return null}Module["getValue"]=getValue;var ALLOC_NORMAL=0;var ALLOC_STACK=1;var ALLOC_STATIC=2;var ALLOC_DYNAMIC=3;var ALLOC_NONE=4;Module["ALLOC_NORMAL"]=ALLOC_NORMAL;Module["ALLOC_STACK"]=ALLOC_STACK;Module["ALLOC_STATIC"]=ALLOC_STATIC;Module["ALLOC_DYNAMIC"]=ALLOC_DYNAMIC;Module["ALLOC_NONE"]=ALLOC_NONE;function allocate(slab,types,allocator,ptr){var zeroinit,size;if(typeof slab==="number"){zeroinit=true;size=slab}else{zeroinit=false;size=slab.length}var singleType=typeof types==="string"?types:null;var ret;if(allocator==ALLOC_NONE){ret=ptr}else{ret=[_malloc,Runtime.stackAlloc,Runtime.staticAlloc,Runtime.dynamicAlloc][allocator===undefined?ALLOC_STATIC:allocator](Math.max(size,singleType?1:types.length))}if(zeroinit){var ptr=ret,stop;assert((ret&3)==0);stop=ret+(size&~3);for(;ptr<stop;ptr+=4){HEAP32[ptr>>2]=0}stop=ret+size;while(ptr<stop){HEAP8[ptr++>>0]=0}return ret}if(singleType==="i8"){if(slab.subarray||slab.slice){HEAPU8.set(slab,ret)}else{HEAPU8.set(new Uint8Array(slab),ret)}return ret}var i=0,type,typeSize,previousType;while(i<size){var curr=slab[i];if(typeof curr==="function"){curr=Runtime.getFunctionIndex(curr)}type=singleType||types[i];if(type===0){i++;continue}if(type=="i64")type="i32";setValue(ret+i,curr,type);if(previousType!==type){typeSize=Runtime.getNativeTypeSize(type);previousType=type}i+=typeSize}return ret}Module["allocate"]=allocate;function getMemory(size){if(!staticSealed)return Runtime.staticAlloc(size);if(typeof _sbrk!=="undefined"&&!_sbrk.called||!runtimeInitialized)return Runtime.dynamicAlloc(size);return _malloc(size)}Module["getMemory"]=getMemory;function Pointer_stringify(ptr,length){if(length===0||!ptr)return"";var hasUtf=0;var t;var i=0;while(1){t=HEAPU8[ptr+i>>0];hasUtf|=t;if(t==0&&!length)break;i++;if(length&&i==length)break}if(!length)length=i;var ret="";if(hasUtf<128){var MAX_CHUNK=1024;var curr;while(length>0){curr=String.fromCharCode.apply(String,HEAPU8.subarray(ptr,ptr+Math.min(length,MAX_CHUNK)));ret=ret?ret+curr:curr;ptr+=MAX_CHUNK;length-=MAX_CHUNK}return ret}return Module["UTF8ToString"](ptr)}Module["Pointer_stringify"]=Pointer_stringify;function AsciiToString(ptr){var str="";while(1){var ch=HEAP8[ptr++>>0];if(!ch)return str;str+=String.fromCharCode(ch)}}Module["AsciiToString"]=AsciiToString;function stringToAscii(str,outPtr){return writeAsciiToMemory(str,outPtr,false)}Module["stringToAscii"]=stringToAscii;function UTF8ArrayToString(u8Array,idx){var u0,u1,u2,u3,u4,u5;var str="";while(1){u0=u8Array[idx++];if(!u0)return str;if(!(u0&128)){str+=String.fromCharCode(u0);continue}u1=u8Array[idx++]&63;if((u0&224)==192){str+=String.fromCharCode((u0&31)<<6|u1);continue}u2=u8Array[idx++]&63;if((u0&240)==224){u0=(u0&15)<<12|u1<<6|u2}else{u3=u8Array[idx++]&63;if((u0&248)==240){u0=(u0&7)<<18|u1<<12|u2<<6|u3}else{u4=u8Array[idx++]&63;if((u0&252)==248){u0=(u0&3)<<24|u1<<18|u2<<12|u3<<6|u4}else{u5=u8Array[idx++]&63;u0=(u0&1)<<30|u1<<24|u2<<18|u3<<12|u4<<6|u5}}}if(u0<65536){str+=String.fromCharCode(u0)}else{var ch=u0-65536;str+=String.fromCharCode(55296|ch>>10,56320|ch&1023)}}}Module["UTF8ArrayToString"]=UTF8ArrayToString;function UTF8ToString(ptr){return UTF8ArrayToString(HEAPU8,ptr)}Module["UTF8ToString"]=UTF8ToString;function stringToUTF8Array(str,outU8Array,outIdx,maxBytesToWrite){if(!(maxBytesToWrite>0))return 0;var startIdx=outIdx;var endIdx=outIdx+maxBytesToWrite-1;for(var i=0;i<str.length;++i){var u=str.charCodeAt(i);if(u>=55296&&u<=57343)u=65536+((u&1023)<<10)|str.charCodeAt(++i)&1023;if(u<=127){if(outIdx>=endIdx)break;outU8Array[outIdx++]=u}else if(u<=2047){if(outIdx+1>=endIdx)break;outU8Array[outIdx++]=192|u>>6;outU8Array[outIdx++]=128|u&63}else if(u<=65535){if(outIdx+2>=endIdx)break;outU8Array[outIdx++]=224|u>>12;outU8Array[outIdx++]=128|u>>6&63;outU8Array[outIdx++]=128|u&63}else if(u<=2097151){if(outIdx+3>=endIdx)break;outU8Array[outIdx++]=240|u>>18;outU8Array[outIdx++]=128|u>>12&63;outU8Array[outIdx++]=128|u>>6&63;outU8Array[outIdx++]=128|u&63}else if(u<=67108863){if(outIdx+4>=endIdx)break;outU8Array[outIdx++]=248|u>>24;outU8Array[outIdx++]=128|u>>18&63;outU8Array[outIdx++]=128|u>>12&63;outU8Array[outIdx++]=128|u>>6&63;outU8Array[outIdx++]=128|u&63}else{if(outIdx+5>=endIdx)break;outU8Array[outIdx++]=252|u>>30;outU8Array[outIdx++]=128|u>>24&63;outU8Array[outIdx++]=128|u>>18&63;outU8Array[outIdx++]=128|u>>12&63;outU8Array[outIdx++]=128|u>>6&63;outU8Array[outIdx++]=128|u&63}}outU8Array[outIdx]=0;return outIdx-startIdx}Module["stringToUTF8Array"]=stringToUTF8Array;function stringToUTF8(str,outPtr,maxBytesToWrite){return stringToUTF8Array(str,HEAPU8,outPtr,maxBytesToWrite)}Module["stringToUTF8"]=stringToUTF8;function lengthBytesUTF8(str){var len=0;for(var i=0;i<str.length;++i){var u=str.charCodeAt(i);if(u>=55296&&u<=57343)u=65536+((u&1023)<<10)|str.charCodeAt(++i)&1023;if(u<=127){++len}else if(u<=2047){len+=2}else if(u<=65535){len+=3}else if(u<=2097151){len+=4}else if(u<=67108863){len+=5}else{len+=6}}return len}Module["lengthBytesUTF8"]=lengthBytesUTF8;function UTF16ToString(ptr){var i=0;var str="";while(1){var codeUnit=HEAP16[ptr+i*2>>1];if(codeUnit==0)return str;++i;str+=String.fromCharCode(codeUnit)}}Module["UTF16ToString"]=UTF16ToString;function stringToUTF16(str,outPtr,maxBytesToWrite){if(maxBytesToWrite===undefined){maxBytesToWrite=2147483647}if(maxBytesToWrite<2)return 0;maxBytesToWrite-=2;var startPtr=outPtr;var numCharsToWrite=maxBytesToWrite<str.length*2?maxBytesToWrite/2:str.length;for(var i=0;i<numCharsToWrite;++i){var codeUnit=str.charCodeAt(i);HEAP16[outPtr>>1]=codeUnit;outPtr+=2}HEAP16[outPtr>>1]=0;return outPtr-startPtr}Module["stringToUTF16"]=stringToUTF16;function lengthBytesUTF16(str){return str.length*2}Module["lengthBytesUTF16"]=lengthBytesUTF16;function UTF32ToString(ptr){var i=0;var str="";while(1){var utf32=HEAP32[ptr+i*4>>2];if(utf32==0)return str;++i;if(utf32>=65536){var ch=utf32-65536;str+=String.fromCharCode(55296|ch>>10,56320|ch&1023)}else{str+=String.fromCharCode(utf32)}}}Module["UTF32ToString"]=UTF32ToString;function stringToUTF32(str,outPtr,maxBytesToWrite){if(maxBytesToWrite===undefined){maxBytesToWrite=2147483647}if(maxBytesToWrite<4)return 0;var startPtr=outPtr;var endPtr=startPtr+maxBytesToWrite-4;for(var i=0;i<str.length;++i){var codeUnit=str.charCodeAt(i);if(codeUnit>=55296&&codeUnit<=57343){var trailSurrogate=str.charCodeAt(++i);codeUnit=65536+((codeUnit&1023)<<10)|trailSurrogate&1023}HEAP32[outPtr>>2]=codeUnit;outPtr+=4;if(outPtr+4>endPtr)break}HEAP32[outPtr>>2]=0;return outPtr-startPtr}Module["stringToUTF32"]=stringToUTF32;function lengthBytesUTF32(str){var len=0;for(var i=0;i<str.length;++i){var codeUnit=str.charCodeAt(i);if(codeUnit>=55296&&codeUnit<=57343)++i;len+=4}return len}Module["lengthBytesUTF32"]=lengthBytesUTF32;function demangle(func){var hasLibcxxabi=!!Module["___cxa_demangle"];if(hasLibcxxabi){try{var buf=_malloc(func.length);writeStringToMemory(func.substr(1),buf);var status=_malloc(4);var ret=Module["___cxa_demangle"](buf,0,0,status);if(getValue(status,"i32")===0&&ret){return Pointer_stringify(ret)}}catch(e){}finally{if(buf)_free(buf);if(status)_free(status);if(ret)_free(ret)}}var i=3;var basicTypes={"v":"void","b":"bool","c":"char","s":"short","i":"int","l":"long","f":"float","d":"double","w":"wchar_t","a":"signed char","h":"unsigned char","t":"unsigned short","j":"unsigned int","m":"unsigned long","x":"long long","y":"unsigned long long","z":"..."};var subs=[];var first=true;function dump(x){if(x)Module.print(x);Module.print(func);var pre="";for(var a=0;a<i;a++)pre+=" ";Module.print(pre+"^")}function parseNested(){i++;if(func[i]==="K")i++;var parts=[];while(func[i]!=="E"){if(func[i]==="S"){i++;var next=func.indexOf("_",i);var num=func.substring(i,next)||0;parts.push(subs[num]||"?");i=next+1;continue}if(func[i]==="C"){parts.push(parts[parts.length-1]);i+=2;continue}var size=parseInt(func.substr(i));var pre=size.toString().length;if(!size||!pre){i--;break}var curr=func.substr(i+pre,size);parts.push(curr);subs.push(curr);i+=pre+size}i++;return parts}function parse(rawList,limit,allowVoid){limit=limit||Infinity;var ret="",list=[];function flushList(){return"("+list.join(", ")+")"}var name;if(func[i]==="N"){name=parseNested().join("::");limit--;if(limit===0)return rawList?[name]:name}else{if(func[i]==="K"||first&&func[i]==="L")i++;var size=parseInt(func.substr(i));if(size){var pre=size.toString().length;name=func.substr(i+pre,size);i+=pre+size}}first=false;if(func[i]==="I"){i++;var iList=parse(true);var iRet=parse(true,1,true);ret+=iRet[0]+" "+name+"<"+iList.join(", ")+">"}else{ret=name}paramLoop:while(i<func.length&&limit-->0){var c=func[i++];if(c in basicTypes){list.push(basicTypes[c])}else{switch(c){case"P":list.push(parse(true,1,true)[0]+"*");break;case"R":list.push(parse(true,1,true)[0]+"&");break;case"L":{i++;var end=func.indexOf("E",i);var size=end-i;list.push(func.substr(i,size));i+=size+2;break};case"A":{var size=parseInt(func.substr(i));i+=size.toString().length;if(func[i]!=="_")throw"?";i++;list.push(parse(true,1,true)[0]+" ["+size+"]");break};case"E":break paramLoop;default:ret+="?"+c;break paramLoop}}}if(!allowVoid&&list.length===1&&list[0]==="void")list=[];if(rawList){if(ret){list.push(ret+"?")}return list}else{return ret+flushList()}}var parsed=func;try{if(func=="Object._main"||func=="_main"){return"main()"}if(typeof func==="number")func=Pointer_stringify(func);if(func[0]!=="_")return func;if(func[1]!=="_")return func;if(func[2]!=="Z")return func;switch(func[3]){case"n":return"operator new()";case"d":return"operator delete()"}parsed=parse()}catch(e){parsed+="?"}if(parsed.indexOf("?")>=0&&!hasLibcxxabi){Runtime.warnOnce("warning: a problem occurred in builtin C++ name demangling; build with  -s DEMANGLE_SUPPORT=1  to link in libcxxabi demangling")}return parsed}function demangleAll(text){return text.replace(/__Z[\w\d_]+/g,(function(x){var y=demangle(x);return x===y?x:x+" ["+y+"]"}))}function jsStackTrace(){var err=new Error;if(!err.stack){try{throw new Error(0)}catch(e){err=e}if(!err.stack){return"(no stack trace available)"}}return err.stack.toString()}function stackTrace(){return demangleAll(jsStackTrace())}Module["stackTrace"]=stackTrace;var PAGE_SIZE=4096;function alignMemoryPage(x){if(x%4096>0){x+=4096-x%4096}return x}var HEAP;var HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;var STATIC_BASE=0,STATICTOP=0,staticSealed=false;var STACK_BASE=0,STACKTOP=0,STACK_MAX=0;var DYNAMIC_BASE=0,DYNAMICTOP=0;function abortOnCannotGrowMemory(){abort("Cannot enlarge memory arrays. Either (1) compile with  -s TOTAL_MEMORY=X  with X higher than the current value "+TOTAL_MEMORY+", (2) compile with  -s ALLOW_MEMORY_GROWTH=1  which adjusts the size at runtime but prevents some optimizations, (3) set Module.TOTAL_MEMORY to a higher value before the program runs, or if you want malloc to return NULL (0) instead of this abort, compile with  -s ABORTING_MALLOC=0 ")}function enlargeMemory(){abortOnCannotGrowMemory()}var TOTAL_STACK=Module["TOTAL_STACK"]||5242880;var TOTAL_MEMORY=Module["TOTAL_MEMORY"]||499974144;var totalMemory=64*1024;while(totalMemory<TOTAL_MEMORY||totalMemory<2*TOTAL_STACK){if(totalMemory<16*1024*1024){totalMemory*=2}else{totalMemory+=16*1024*1024}}if(totalMemory!==TOTAL_MEMORY){TOTAL_MEMORY=totalMemory}assert(typeof Int32Array!=="undefined"&&typeof Float64Array!=="undefined"&&!!(new Int32Array(1))["subarray"]&&!!(new Int32Array(1))["set"],"JS engine does not provide full typed array support");var buffer;buffer=new ArrayBuffer(TOTAL_MEMORY);HEAP8=new Int8Array(buffer);HEAP16=new Int16Array(buffer);HEAP32=new Int32Array(buffer);HEAPU8=new Uint8Array(buffer);HEAPU16=new Uint16Array(buffer);HEAPU32=new Uint32Array(buffer);HEAPF32=new Float32Array(buffer);HEAPF64=new Float64Array(buffer);HEAP32[0]=255;assert(HEAPU8[0]===255&&HEAPU8[3]===0,"Typed arrays 2 must be run on a little-endian system");Module["HEAP"]=HEAP;Module["buffer"]=buffer;Module["HEAP8"]=HEAP8;Module["HEAP16"]=HEAP16;Module["HEAP32"]=HEAP32;Module["HEAPU8"]=HEAPU8;Module["HEAPU16"]=HEAPU16;Module["HEAPU32"]=HEAPU32;Module["HEAPF32"]=HEAPF32;Module["HEAPF64"]=HEAPF64;function callRuntimeCallbacks(callbacks){while(callbacks.length>0){var callback=callbacks.shift();if(typeof callback=="function"){callback();continue}var func=callback.func;if(typeof func==="number"){if(callback.arg===undefined){Runtime.dynCall("v",func)}else{Runtime.dynCall("vi",func,[callback.arg])}}else{func(callback.arg===undefined?null:callback.arg)}}}var __ATPRERUN__=[];var __ATINIT__=[];var __ATMAIN__=[];var __ATEXIT__=[];var __ATPOSTRUN__=[];var runtimeInitialized=false;var runtimeExited=false;function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="function")Module["preRun"]=[Module["preRun"]];while(Module["preRun"].length){addOnPreRun(Module["preRun"].shift())}}callRuntimeCallbacks(__ATPRERUN__)}function ensureInitRuntime(){if(runtimeInitialized)return;runtimeInitialized=true;callRuntimeCallbacks(__ATINIT__)}function preMain(){callRuntimeCallbacks(__ATMAIN__)}function exitRuntime(){callRuntimeCallbacks(__ATEXIT__);runtimeExited=true}function postRun(){if(Module["postRun"]){if(typeof Module["postRun"]=="function")Module["postRun"]=[Module["postRun"]];while(Module["postRun"].length){addOnPostRun(Module["postRun"].shift())}}callRuntimeCallbacks(__ATPOSTRUN__)}function addOnPreRun(cb){__ATPRERUN__.unshift(cb)}Module["addOnPreRun"]=addOnPreRun;function addOnInit(cb){__ATINIT__.unshift(cb)}Module["addOnInit"]=addOnInit;function addOnPreMain(cb){__ATMAIN__.unshift(cb)}Module["addOnPreMain"]=addOnPreMain;function addOnExit(cb){__ATEXIT__.unshift(cb)}Module["addOnExit"]=addOnExit;function addOnPostRun(cb){__ATPOSTRUN__.unshift(cb)}Module["addOnPostRun"]=addOnPostRun;function intArrayFromString(stringy,dontAddNull,length){var len=length>0?length:lengthBytesUTF8(stringy)+1;var u8array=new Array(len);var numBytesWritten=stringToUTF8Array(stringy,u8array,0,u8array.length);if(dontAddNull)u8array.length=numBytesWritten;return u8array}Module["intArrayFromString"]=intArrayFromString;function intArrayToString(array){var ret=[];for(var i=0;i<array.length;i++){var chr=array[i];if(chr>255){chr&=255}ret.push(String.fromCharCode(chr))}return ret.join("")}Module["intArrayToString"]=intArrayToString;function writeStringToMemory(string,buffer,dontAddNull){var array=intArrayFromString(string,dontAddNull);var i=0;while(i<array.length){var chr=array[i];HEAP8[buffer+i>>0]=chr;i=i+1}}Module["writeStringToMemory"]=writeStringToMemory;function writeArrayToMemory(array,buffer){for(var i=0;i<array.length;i++){HEAP8[buffer++>>0]=array[i]}}Module["writeArrayToMemory"]=writeArrayToMemory;function writeAsciiToMemory(str,buffer,dontAddNull){for(var i=0;i<str.length;++i){HEAP8[buffer++>>0]=str.charCodeAt(i)}if(!dontAddNull)HEAP8[buffer>>0]=0}Module["writeAsciiToMemory"]=writeAsciiToMemory;function unSign(value,bits,ignore){if(value>=0){return value}return bits<=32?2*Math.abs(1<<bits-1)+value:Math.pow(2,bits)+value}function reSign(value,bits,ignore){if(value<=0){return value}var half=bits<=32?Math.abs(1<<bits-1):Math.pow(2,bits-1);if(value>=half&&(bits<=32||value>half)){value=-2*half+value}return value}if(!Math["imul"]||Math["imul"](4294967295,5)!==-5)Math["imul"]=function imul(a,b){var ah=a>>>16;var al=a&65535;var bh=b>>>16;var bl=b&65535;return al*bl+(ah*bl+al*bh<<16)|0};Math.imul=Math["imul"];if(!Math["clz32"])Math["clz32"]=(function(x){x=x>>>0;for(var i=0;i<32;i++){if(x&1<<31-i)return i}return 32});Math.clz32=Math["clz32"];var Math_abs=Math.abs;var Math_cos=Math.cos;var Math_sin=Math.sin;var Math_tan=Math.tan;var Math_acos=Math.acos;var Math_asin=Math.asin;var Math_atan=Math.atan;var Math_atan2=Math.atan2;var Math_exp=Math.exp;var Math_log=Math.log;var Math_sqrt=Math.sqrt;var Math_ceil=Math.ceil;var Math_floor=Math.floor;var Math_pow=Math.pow;var Math_imul=Math.imul;var Math_fround=Math.fround;var Math_min=Math.min;var Math_clz32=Math.clz32;var runDependencies=0;var runDependencyWatcher=null;var dependenciesFulfilled=null;function getUniqueRunDependency(id){return id}function addRunDependency(id){runDependencies++;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}}Module["addRunDependency"]=addRunDependency;function removeRunDependency(id){runDependencies--;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}if(runDependencies==0){if(runDependencyWatcher!==null){clearInterval(runDependencyWatcher);runDependencyWatcher=null}if(dependenciesFulfilled){var callback=dependenciesFulfilled;dependenciesFulfilled=null;callback()}}}Module["removeRunDependency"]=removeRunDependency;Module["preloadedImages"]={};Module["preloadedAudios"]={};var memoryInitializer=null;var ASM_CONSTS=[];STATIC_BASE=8;STATICTOP=STATIC_BASE+510960;__ATINIT__.push();memoryInitializer="basis.js.mem";var tempDoublePtr=Runtime.alignMemory(allocate(12,"i8",ALLOC_STATIC),8);assert(tempDoublePtr%8==0);function copyTempFloat(ptr){HEAP8[tempDoublePtr]=HEAP8[ptr];HEAP8[tempDoublePtr+1]=HEAP8[ptr+1];HEAP8[tempDoublePtr+2]=HEAP8[ptr+2];HEAP8[tempDoublePtr+3]=HEAP8[ptr+3]}function copyTempDouble(ptr){HEAP8[tempDoublePtr]=HEAP8[ptr];HEAP8[tempDoublePtr+1]=HEAP8[ptr+1];HEAP8[tempDoublePtr+2]=HEAP8[ptr+2];HEAP8[tempDoublePtr+3]=HEAP8[ptr+3];HEAP8[tempDoublePtr+4]=HEAP8[ptr+4];HEAP8[tempDoublePtr+5]=HEAP8[ptr+5];HEAP8[tempDoublePtr+6]=HEAP8[ptr+6];HEAP8[tempDoublePtr+7]=HEAP8[ptr+7]}function ___setErrNo(value){if(Module["___errno_location"])HEAP32[Module["___errno_location"]()>>2]=value;return value}var ERRNO_CODES={EPERM:1,ENOENT:2,ESRCH:3,EINTR:4,EIO:5,ENXIO:6,E2BIG:7,ENOEXEC:8,EBADF:9,ECHILD:10,EAGAIN:11,EWOULDBLOCK:11,ENOMEM:12,EACCES:13,EFAULT:14,ENOTBLK:15,EBUSY:16,EEXIST:17,EXDEV:18,ENODEV:19,ENOTDIR:20,EISDIR:21,EINVAL:22,ENFILE:23,EMFILE:24,ENOTTY:25,ETXTBSY:26,EFBIG:27,ENOSPC:28,ESPIPE:29,EROFS:30,EMLINK:31,EPIPE:32,EDOM:33,ERANGE:34,ENOMSG:42,EIDRM:43,ECHRNG:44,EL2NSYNC:45,EL3HLT:46,EL3RST:47,ELNRNG:48,EUNATCH:49,ENOCSI:50,EL2HLT:51,EDEADLK:35,ENOLCK:37,EBADE:52,EBADR:53,EXFULL:54,ENOANO:55,EBADRQC:56,EBADSLT:57,EDEADLOCK:35,EBFONT:59,ENOSTR:60,ENODATA:61,ETIME:62,ENOSR:63,ENONET:64,ENOPKG:65,EREMOTE:66,ENOLINK:67,EADV:68,ESRMNT:69,ECOMM:70,EPROTO:71,EMULTIHOP:72,EDOTDOT:73,EBADMSG:74,ENOTUNIQ:76,EBADFD:77,EREMCHG:78,ELIBACC:79,ELIBBAD:80,ELIBSCN:81,ELIBMAX:82,ELIBEXEC:83,ENOSYS:38,ENOTEMPTY:39,ENAMETOOLONG:36,ELOOP:40,EOPNOTSUPP:95,EPFNOSUPPORT:96,ECONNRESET:104,ENOBUFS:105,EAFNOSUPPORT:97,EPROTOTYPE:91,ENOTSOCK:88,ENOPROTOOPT:92,ESHUTDOWN:108,ECONNREFUSED:111,EADDRINUSE:98,ECONNABORTED:103,ENETUNREACH:101,ENETDOWN:100,ETIMEDOUT:110,EHOSTDOWN:112,EHOSTUNREACH:113,EINPROGRESS:115,EALREADY:114,EDESTADDRREQ:89,EMSGSIZE:90,EPROTONOSUPPORT:93,ESOCKTNOSUPPORT:94,EADDRNOTAVAIL:99,ENETRESET:102,EISCONN:106,ENOTCONN:107,ETOOMANYREFS:109,EUSERS:87,EDQUOT:122,ESTALE:116,ENOTSUP:95,ENOMEDIUM:123,EILSEQ:84,EOVERFLOW:75,ECANCELED:125,ENOTRECOVERABLE:131,EOWNERDEAD:130,ESTRPIPE:86};function _sysconf(name){switch(name){case 30:return PAGE_SIZE;case 85:return totalMemory/PAGE_SIZE;case 132:case 133:case 12:case 137:case 138:case 15:case 235:case 16:case 17:case 18:case 19:case 20:case 149:case 13:case 10:case 236:case 153:case 9:case 21:case 22:case 159:case 154:case 14:case 77:case 78:case 139:case 80:case 81:case 82:case 68:case 67:case 164:case 11:case 29:case 47:case 48:case 95:case 52:case 51:case 46:return 200809;case 79:return 0;case 27:case 246:case 127:case 128:case 23:case 24:case 160:case 161:case 181:case 182:case 242:case 183:case 184:case 243:case 244:case 245:case 165:case 178:case 179:case 49:case 50:case 168:case 169:case 175:case 170:case 171:case 172:case 97:case 76:case 32:case 173:case 35:return-1;case 176:case 177:case 7:case 155:case 8:case 157:case 125:case 126:case 92:case 93:case 129:case 130:case 131:case 94:case 91:return 1;case 74:case 60:case 69:case 70:case 4:return 1024;case 31:case 42:case 72:return 32;case 87:case 26:case 33:return 2147483647;case 34:case 1:return 47839;case 38:case 36:return 99;case 43:case 37:return 2048;case 0:return 2097152;case 3:return 65536;case 28:return 32768;case 44:return 32767;case 75:return 16384;case 39:return 1e3;case 89:return 700;case 71:return 256;case 40:return 255;case 2:return 100;case 180:return 64;case 25:return 20;case 5:return 16;case 6:return 6;case 73:return 4;case 84:{if(typeof navigator==="object")return navigator["hardwareConcurrency"]||1;return 1}}___setErrNo(ERRNO_CODES.EINVAL);return-1}var _fabsf=Math_abs;function ___assert_fail(condition,filename,line,func){ABORT=true;throw"Assertion failed: "+Pointer_stringify(condition)+", at: "+[filename?Pointer_stringify(filename):"unknown filename",line,func?Pointer_stringify(func):"unknown function"]+" at "+stackTrace()}function __ZSt18uncaught_exceptionv(){return!!__ZSt18uncaught_exceptionv.uncaught_exception}var EXCEPTIONS={last:0,caught:[],infos:{},deAdjust:(function(adjusted){if(!adjusted||EXCEPTIONS.infos[adjusted])return adjusted;for(var ptr in EXCEPTIONS.infos){var info=EXCEPTIONS.infos[ptr];if(info.adjusted===adjusted){return ptr}}return adjusted}),addRef:(function(ptr){if(!ptr)return;var info=EXCEPTIONS.infos[ptr];info.refcount++}),decRef:(function(ptr){if(!ptr)return;var info=EXCEPTIONS.infos[ptr];assert(info.refcount>0);info.refcount--;if(info.refcount===0){if(info.destructor){Runtime.dynCall("vi",info.destructor,[ptr])}delete EXCEPTIONS.infos[ptr];___cxa_free_exception(ptr)}}),clearRef:(function(ptr){if(!ptr)return;var info=EXCEPTIONS.infos[ptr];info.refcount=0})};function ___resumeException(ptr){if(!EXCEPTIONS.last){EXCEPTIONS.last=ptr}EXCEPTIONS.clearRef(EXCEPTIONS.deAdjust(ptr));throw ptr+" - Exception catching is disabled, this exception cannot be caught. Compile with -s DISABLE_EXCEPTION_CATCHING=0 or DISABLE_EXCEPTION_CATCHING=2 to catch."}function ___cxa_find_matching_catch(){var thrown=EXCEPTIONS.last;if(!thrown){return(asm["setTempRet0"](0),0)|0}var info=EXCEPTIONS.infos[thrown];var throwntype=info.type;if(!throwntype){return(asm["setTempRet0"](0),thrown)|0}var typeArray=Array.prototype.slice.call(arguments);var pointer=Module["___cxa_is_pointer_type"](throwntype);if(!___cxa_find_matching_catch.buffer)___cxa_find_matching_catch.buffer=_malloc(4);HEAP32[___cxa_find_matching_catch.buffer>>2]=thrown;thrown=___cxa_find_matching_catch.buffer;for(var i=0;i<typeArray.length;i++){if(typeArray[i]&&Module["___cxa_can_catch"](typeArray[i],throwntype,thrown)){thrown=HEAP32[thrown>>2];info.adjusted=thrown;return(asm["setTempRet0"](typeArray[i]),thrown)|0}}thrown=HEAP32[thrown>>2];return(asm["setTempRet0"](throwntype),thrown)|0}function ___cxa_throw(ptr,type,destructor){EXCEPTIONS.infos[ptr]={ptr:ptr,adjusted:ptr,type:type,destructor:destructor,refcount:0};EXCEPTIONS.last=ptr;if(!("uncaught_exception"in __ZSt18uncaught_exceptionv)){__ZSt18uncaught_exceptionv.uncaught_exception=1}else{__ZSt18uncaught_exceptionv.uncaught_exception++}throw ptr+" - Exception catching is disabled, this exception cannot be caught. Compile with -s DISABLE_EXCEPTION_CATCHING=0 or DISABLE_EXCEPTION_CATCHING=2 to catch."}Module["_memset"]=_memset;function _pthread_cleanup_push(routine,arg){__ATEXIT__.push((function(){Runtime.dynCall("vi",routine,[arg])}));_pthread_cleanup_push.level=__ATEXIT__.length}Module["_bitshift64Lshr"]=_bitshift64Lshr;Module["_bitshift64Shl"]=_bitshift64Shl;function _pthread_cleanup_pop(){assert(_pthread_cleanup_push.level==__ATEXIT__.length,"cannot pop if something else added meanwhile!");__ATEXIT__.pop();_pthread_cleanup_push.level=__ATEXIT__.length}function _abort(){Module["abort"]()}var _sqrtf=Math_sqrt;function ___unlock(){}var ERRNO_MESSAGES={0:"Success",1:"Not super-user",2:"No such file or directory",3:"No such process",4:"Interrupted system call",5:"I/O error",6:"No such device or address",7:"Arg list too long",8:"Exec format error",9:"Bad file number",10:"No children",11:"No more processes",12:"Not enough core",13:"Permission denied",14:"Bad address",15:"Block device required",16:"Mount device busy",17:"File exists",18:"Cross-device link",19:"No such device",20:"Not a directory",21:"Is a directory",22:"Invalid argument",23:"Too many open files in system",24:"Too many open files",25:"Not a typewriter",26:"Text file busy",27:"File too large",28:"No space left on device",29:"Illegal seek",30:"Read only file system",31:"Too many links",32:"Broken pipe",33:"Math arg out of domain of func",34:"Math result not representable",35:"File locking deadlock error",36:"File or path name too long",37:"No record locks available",38:"Function not implemented",39:"Directory not empty",40:"Too many symbolic links",42:"No message of desired type",43:"Identifier removed",44:"Channel number out of range",45:"Level 2 not synchronized",46:"Level 3 halted",47:"Level 3 reset",48:"Link number out of range",49:"Protocol driver not attached",50:"No CSI structure available",51:"Level 2 halted",52:"Invalid exchange",53:"Invalid request descriptor",54:"Exchange full",55:"No anode",56:"Invalid request code",57:"Invalid slot",59:"Bad font file fmt",60:"Device not a stream",61:"No data (for no delay io)",62:"Timer expired",63:"Out of streams resources",64:"Machine is not on the network",65:"Package not installed",66:"The object is remote",67:"The link has been severed",68:"Advertise error",69:"Srmount error",70:"Communication error on send",71:"Protocol error",72:"Multihop attempted",73:"Cross mount point (not really error)",74:"Trying to read unreadable message",75:"Value too large for defined data type",76:"Given log. name not unique",77:"f.d. invalid for this operation",78:"Remote address changed",79:"Can   access a needed shared lib",80:"Accessing a corrupted shared lib",81:".lib section in a.out corrupted",82:"Attempting to link in too many libs",83:"Attempting to exec a shared library",84:"Illegal byte sequence",86:"Streams pipe error",87:"Too many users",88:"Socket operation on non-socket",89:"Destination address required",90:"Message too long",91:"Protocol wrong type for socket",92:"Protocol not available",93:"Unknown protocol",94:"Socket type not supported",95:"Not supported",96:"Protocol family not supported",97:"Address family not supported by protocol family",98:"Address already in use",99:"Address not available",100:"Network interface is not configured",101:"Network is unreachable",102:"Connection reset by network",103:"Connection aborted",104:"Connection reset by peer",105:"No buffer space available",106:"Socket is already connected",107:"Socket is not connected",108:"Can't send after socket shutdown",109:"Too many references",110:"Connection timed out",111:"Connection refused",112:"Host is down",113:"Host is unreachable",114:"Socket already connected",115:"Connection already in progress",116:"Stale file handle",122:"Quota exceeded",123:"No medium (in tape drive)",125:"Operation canceled",130:"Previous owner died",131:"State not recoverable"};var PATH={splitPath:(function(filename){var splitPathRe=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;return splitPathRe.exec(filename).slice(1)}),normalizeArray:(function(parts,allowAboveRoot){var up=0;for(var i=parts.length-1;i>=0;i--){var last=parts[i];if(last==="."){parts.splice(i,1)}else if(last===".."){parts.splice(i,1);up++}else if(up){parts.splice(i,1);up--}}if(allowAboveRoot){for(;up--;up){parts.unshift("..")}}return parts}),normalize:(function(path){var isAbsolute=path.charAt(0)==="/",trailingSlash=path.substr(-1)==="/";path=PATH.normalizeArray(path.split("/").filter((function(p){return!!p})),!isAbsolute).join("/");if(!path&&!isAbsolute){path="."}if(path&&trailingSlash){path+="/"}return(isAbsolute?"/":"")+path}),dirname:(function(path){var result=PATH.splitPath(path),root=result[0],dir=result[1];if(!root&&!dir){return"."}if(dir){dir=dir.substr(0,dir.length-1)}return root+dir}),basename:(function(path){if(path==="/")return"/";var lastSlash=path.lastIndexOf("/");if(lastSlash===-1)return path;return path.substr(lastSlash+1)}),extname:(function(path){return PATH.splitPath(path)[3]}),join:(function(){var paths=Array.prototype.slice.call(arguments,0);return PATH.normalize(paths.join("/"))}),join2:(function(l,r){return PATH.normalize(l+"/"+r)}),resolve:(function(){var resolvedPath="",resolvedAbsolute=false;for(var i=arguments.length-1;i>=-1&&!resolvedAbsolute;i--){var path=i>=0?arguments[i]:FS.cwd();if(typeof path!=="string"){throw new TypeError("Arguments to path.resolve must be strings")}else if(!path){return""}resolvedPath=path+"/"+resolvedPath;resolvedAbsolute=path.charAt(0)==="/"}resolvedPath=PATH.normalizeArray(resolvedPath.split("/").filter((function(p){return!!p})),!resolvedAbsolute).join("/");return(resolvedAbsolute?"/":"")+resolvedPath||"."}),relative:(function(from,to){from=PATH.resolve(from).substr(1);to=PATH.resolve(to).substr(1);function trim(arr){var start=0;for(;start<arr.length;start++){if(arr[start]!=="")break}var end=arr.length-1;for(;end>=0;end--){if(arr[end]!=="")break}if(start>end)return[];return arr.slice(start,end-start+1)}var fromParts=trim(from.split("/"));var toParts=trim(to.split("/"));var length=Math.min(fromParts.length,toParts.length);var samePartsLength=length;for(var i=0;i<length;i++){if(fromParts[i]!==toParts[i]){samePartsLength=i;break}}var outputParts=[];for(var i=samePartsLength;i<fromParts.length;i++){outputParts.push("..")}outputParts=outputParts.concat(toParts.slice(samePartsLength));return outputParts.join("/")})};var TTY={ttys:[],init:(function(){}),shutdown:(function(){}),register:(function(dev,ops){TTY.ttys[dev]={input:[],output:[],ops:ops};FS.registerDevice(dev,TTY.stream_ops)}),stream_ops:{open:(function(stream){var tty=TTY.ttys[stream.node.rdev];if(!tty){throw new FS.ErrnoError(ERRNO_CODES.ENODEV)}stream.tty=tty;stream.seekable=false}),close:(function(stream){stream.tty.ops.flush(stream.tty)}),flush:(function(stream){stream.tty.ops.flush(stream.tty)}),read:(function(stream,buffer,offset,length,pos){if(!stream.tty||!stream.tty.ops.get_char){throw new FS.ErrnoError(ERRNO_CODES.ENXIO)}var bytesRead=0;for(var i=0;i<length;i++){var result;try{result=stream.tty.ops.get_char(stream.tty)}catch(e){throw new FS.ErrnoError(ERRNO_CODES.EIO)}if(result===undefined&&bytesRead===0){throw new FS.ErrnoError(ERRNO_CODES.EAGAIN)}if(result===null||result===undefined)break;bytesRead++;buffer[offset+i]=result}if(bytesRead){stream.node.timestamp=Date.now()}return bytesRead}),write:(function(stream,buffer,offset,length,pos){if(!stream.tty||!stream.tty.ops.put_char){throw new FS.ErrnoError(ERRNO_CODES.ENXIO)}for(var i=0;i<length;i++){try{stream.tty.ops.put_char(stream.tty,buffer[offset+i])}catch(e){throw new FS.ErrnoError(ERRNO_CODES.EIO)}}if(length){stream.node.timestamp=Date.now()}return i})},default_tty_ops:{get_char:(function(tty){if(!tty.input.length){var result=null;if(ENVIRONMENT_IS_NODE){var BUFSIZE=256;var buf=new Buffer(BUFSIZE);var bytesRead=0;var fd=process.stdin.fd;var usingDevice=false;try{fd=fs.openSync("/dev/stdin","r");usingDevice=true}catch(e){}bytesRead=fs.readSync(fd,buf,0,BUFSIZE,null);if(usingDevice){fs.closeSync(fd)}if(bytesRead>0){result=buf.slice(0,bytesRead).toString("utf-8")}else{result=null}}else if(typeof window!="undefined"&&typeof window.prompt=="function"){result=window.prompt("Input: ");if(result!==null){result+="\n"}}else if(typeof readline=="function"){result=readline();if(result!==null){result+="\n"}}if(!result){return null}tty.input=intArrayFromString(result,true)}return tty.input.shift()}),put_char:(function(tty,val){if(val===null||val===10){Module["print"](UTF8ArrayToString(tty.output,0));tty.output=[]}else{if(val!=0)tty.output.push(val)}}),flush:(function(tty){if(tty.output&&tty.output.length>0){Module["print"](UTF8ArrayToString(tty.output,0));tty.output=[]}})},default_tty1_ops:{put_char:(function(tty,val){if(val===null||val===10){Module["printErr"](UTF8ArrayToString(tty.output,0));tty.output=[]}else{if(val!=0)tty.output.push(val)}}),flush:(function(tty){if(tty.output&&tty.output.length>0){Module["printErr"](UTF8ArrayToString(tty.output,0));tty.output=[]}})}};var MEMFS={ops_table:null,mount:(function(mount){return MEMFS.createNode(null,"/",16384|511,0)}),createNode:(function(parent,name,mode,dev){if(FS.isBlkdev(mode)||FS.isFIFO(mode)){throw new FS.ErrnoError(ERRNO_CODES.EPERM)}if(!MEMFS.ops_table){MEMFS.ops_table={dir:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr,lookup:MEMFS.node_ops.lookup,mknod:MEMFS.node_ops.mknod,rename:MEMFS.node_ops.rename,unlink:MEMFS.node_ops.unlink,rmdir:MEMFS.node_ops.rmdir,readdir:MEMFS.node_ops.readdir,symlink:MEMFS.node_ops.symlink},stream:{llseek:MEMFS.stream_ops.llseek}},file:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr},stream:{llseek:MEMFS.stream_ops.llseek,read:MEMFS.stream_ops.read,write:MEMFS.stream_ops.write,allocate:MEMFS.stream_ops.allocate,mmap:MEMFS.stream_ops.mmap,msync:MEMFS.stream_ops.msync}},link:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr,readlink:MEMFS.node_ops.readlink},stream:{}},chrdev:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr},stream:FS.chrdev_stream_ops}}}var node=FS.createNode(parent,name,mode,dev);if(FS.isDir(node.mode)){node.node_ops=MEMFS.ops_table.dir.node;node.stream_ops=MEMFS.ops_table.dir.stream;node.contents={}}else if(FS.isFile(node.mode)){node.node_ops=MEMFS.ops_table.file.node;node.stream_ops=MEMFS.ops_table.file.stream;node.usedBytes=0;node.contents=null}else if(FS.isLink(node.mode)){node.node_ops=MEMFS.ops_table.link.node;node.stream_ops=MEMFS.ops_table.link.stream}else if(FS.isChrdev(node.mode)){node.node_ops=MEMFS.ops_table.chrdev.node;node.stream_ops=MEMFS.ops_table.chrdev.stream}node.timestamp=Date.now();if(parent){parent.contents[name]=node}return node}),getFileDataAsRegularArray:(function(node){if(node.contents&&node.contents.subarray){var arr=[];for(var i=0;i<node.usedBytes;++i)arr.push(node.contents[i]);return arr}return node.contents}),getFileDataAsTypedArray:(function(node){if(!node.contents)return new Uint8Array;if(node.contents.subarray)return node.contents.subarray(0,node.usedBytes);return new Uint8Array(node.contents)}),expandFileStorage:(function(node,newCapacity){if(node.contents&&node.contents.subarray&&newCapacity>node.contents.length){node.contents=MEMFS.getFileDataAsRegularArray(node);node.usedBytes=node.contents.length}if(!node.contents||node.contents.subarray){var prevCapacity=node.contents?node.contents.buffer.byteLength:0;if(prevCapacity>=newCapacity)return;var CAPACITY_DOUBLING_MAX=1024*1024;newCapacity=Math.max(newCapacity,prevCapacity*(prevCapacity<CAPACITY_DOUBLING_MAX?2:1.125)|0);if(prevCapacity!=0)newCapacity=Math.max(newCapacity,256);var oldContents=node.contents;node.contents=new Uint8Array(newCapacity);if(node.usedBytes>0)node.contents.set(oldContents.subarray(0,node.usedBytes),0);return}if(!node.contents&&newCapacity>0)node.contents=[];while(node.contents.length<newCapacity)node.contents.push(0)}),resizeFileStorage:(function(node,newSize){if(node.usedBytes==newSize)return;if(newSize==0){node.contents=null;node.usedBytes=0;return}if(!node.contents||node.contents.subarray){var oldContents=node.contents;node.contents=new Uint8Array(new ArrayBuffer(newSize));if(oldContents){node.contents.set(oldContents.subarray(0,Math.min(newSize,node.usedBytes)))}node.usedBytes=newSize;return}if(!node.contents)node.contents=[];if(node.contents.length>newSize)node.contents.length=newSize;else while(node.contents.length<newSize)node.contents.push(0);node.usedBytes=newSize}),node_ops:{getattr:(function(node){var attr={};attr.dev=FS.isChrdev(node.mode)?node.id:1;attr.ino=node.id;attr.mode=node.mode;attr.nlink=1;attr.uid=0;attr.gid=0;attr.rdev=node.rdev;if(FS.isDir(node.mode)){attr.size=4096}else if(FS.isFile(node.mode)){attr.size=node.usedBytes}else if(FS.isLink(node.mode)){attr.size=node.link.length}else{attr.size=0}attr.atime=new Date(node.timestamp);attr.mtime=new Date(node.timestamp);attr.ctime=new Date(node.timestamp);attr.blksize=4096;attr.blocks=Math.ceil(attr.size/attr.blksize);return attr}),setattr:(function(node,attr){if(attr.mode!==undefined){node.mode=attr.mode}if(attr.timestamp!==undefined){node.timestamp=attr.timestamp}if(attr.size!==undefined){MEMFS.resizeFileStorage(node,attr.size)}}),lookup:(function(parent,name){throw FS.genericErrors[ERRNO_CODES.ENOENT]}),mknod:(function(parent,name,mode,dev){return MEMFS.createNode(parent,name,mode,dev)}),rename:(function(old_node,new_dir,new_name){if(FS.isDir(old_node.mode)){var new_node;try{new_node=FS.lookupNode(new_dir,new_name)}catch(e){}if(new_node){for(var i in new_node.contents){throw new FS.ErrnoError(ERRNO_CODES.ENOTEMPTY)}}}delete old_node.parent.contents[old_node.name];old_node.name=new_name;new_dir.contents[new_name]=old_node;old_node.parent=new_dir}),unlink:(function(parent,name){delete parent.contents[name]}),rmdir:(function(parent,name){var node=FS.lookupNode(parent,name);for(var i in node.contents){throw new FS.ErrnoError(ERRNO_CODES.ENOTEMPTY)}delete parent.contents[name]}),readdir:(function(node){var entries=[".",".."];for(var key in node.contents){if(!node.contents.hasOwnProperty(key)){continue}entries.push(key)}return entries}),symlink:(function(parent,newname,oldpath){var node=MEMFS.createNode(parent,newname,511|40960,0);node.link=oldpath;return node}),readlink:(function(node){if(!FS.isLink(node.mode)){throw new FS.ErrnoError(ERRNO_CODES.EINVAL)}return node.link})},stream_ops:{read:(function(stream,buffer,offset,length,position){var contents=stream.node.contents;if(position>=stream.node.usedBytes)return 0;var size=Math.min(stream.node.usedBytes-position,length);assert(size>=0);if(size>8&&contents.subarray){buffer.set(contents.subarray(position,position+size),offset)}else{for(var i=0;i<size;i++)buffer[offset+i]=contents[position+i]}return size}),write:(function(stream,buffer,offset,length,position,canOwn){if(!length)return 0;var node=stream.node;node.timestamp=Date.now();if(buffer.subarray&&(!node.contents||node.contents.subarray)){if(canOwn){node.contents=buffer.subarray(offset,offset+length);node.usedBytes=length;return length}else if(node.usedBytes===0&&position===0){node.contents=new Uint8Array(buffer.subarray(offset,offset+length));node.usedBytes=length;return length}else if(position+length<=node.usedBytes){node.contents.set(buffer.subarray(offset,offset+length),position);return length}}MEMFS.expandFileStorage(node,position+length);if(node.contents.subarray&&buffer.subarray)node.contents.set(buffer.subarray(offset,offset+length),position);else{for(var i=0;i<length;i++){node.contents[position+i]=buffer[offset+i]}}node.usedBytes=Math.max(node.usedBytes,position+length);return length}),llseek:(function(stream,offset,whence){var position=offset;if(whence===1){position+=stream.position}else if(whence===2){if(FS.isFile(stream.node.mode)){position+=stream.node.usedBytes}}if(position<0){throw new FS.ErrnoError(ERRNO_CODES.EINVAL)}return position}),allocate:(function(stream,offset,length){MEMFS.expandFileStorage(stream.node,offset+length);stream.node.usedBytes=Math.max(stream.node.usedBytes,offset+length)}),mmap:(function(stream,buffer,offset,length,position,prot,flags){if(!FS.isFile(stream.node.mode)){throw new FS.ErrnoError(ERRNO_CODES.ENODEV)}var ptr;var allocated;var contents=stream.node.contents;if(!(flags&2)&&(contents.buffer===buffer||contents.buffer===buffer.buffer)){allocated=false;ptr=contents.byteOffset}else{if(position>0||position+length<stream.node.usedBytes){if(contents.subarray){contents=contents.subarray(position,position+length)}else{contents=Array.prototype.slice.call(contents,position,position+length)}}allocated=true;ptr=_malloc(length);if(!ptr){throw new FS.ErrnoError(ERRNO_CODES.ENOMEM)}buffer.set(contents,ptr)}return{ptr:ptr,allocated:allocated}}),msync:(function(stream,buffer,offset,length,mmapFlags){if(!FS.isFile(stream.node.mode)){throw new FS.ErrnoError(ERRNO_CODES.ENODEV)}if(mmapFlags&2){return 0}var bytesWritten=MEMFS.stream_ops.write(stream,buffer,0,length,offset,false);return 0})}};var IDBFS={dbs:{},indexedDB:(function(){if(typeof indexedDB!=="undefined")return indexedDB;var ret=null;if(typeof window==="object")ret=window.indexedDB||window.mozIndexedDB||window.webkitIndexedDB||window.msIndexedDB;assert(ret,"IDBFS used, but indexedDB not supported");return ret}),DB_VERSION:21,DB_STORE_NAME:"FILE_DATA",mount:(function(mount){return MEMFS.mount.apply(null,arguments)}),syncfs:(function(mount,populate,callback){IDBFS.getLocalSet(mount,(function(err,local){if(err)return callback(err);IDBFS.getRemoteSet(mount,(function(err,remote){if(err)return callback(err);var src=populate?remote:local;var dst=populate?local:remote;IDBFS.reconcile(src,dst,callback)}))}))}),getDB:(function(name,callback){var db=IDBFS.dbs[name];if(db){return callback(null,db)}var req;try{req=IDBFS.indexedDB().open(name,IDBFS.DB_VERSION)}catch(e){return callback(e)}req.onupgradeneeded=(function(e){var db=e.target.result;var transaction=e.target.transaction;var fileStore;if(db.objectStoreNames.contains(IDBFS.DB_STORE_NAME)){fileStore=transaction.objectStore(IDBFS.DB_STORE_NAME)}else{fileStore=db.createObjectStore(IDBFS.DB_STORE_NAME)}if(!fileStore.indexNames.contains("timestamp")){fileStore.createIndex("timestamp","timestamp",{unique:false})}});req.onsuccess=(function(){db=req.result;IDBFS.dbs[name]=db;callback(null,db)});req.onerror=(function(e){callback(this.error);e.preventDefault()})}),getLocalSet:(function(mount,callback){var entries={};function isRealDir(p){return p!=="."&&p!==".."}function toAbsolute(root){return(function(p){return PATH.join2(root,p)})}var check=FS.readdir(mount.mountpoint).filter(isRealDir).map(toAbsolute(mount.mountpoint));while(check.length){var path=check.pop();var stat;try{stat=FS.stat(path)}catch(e){return callback(e)}if(FS.isDir(stat.mode)){check.push.apply(check,FS.readdir(path).filter(isRealDir).map(toAbsolute(path)))}entries[path]={timestamp:stat.mtime}}return callback(null,{type:"local",entries:entries})}),getRemoteSet:(function(mount,callback){var entries={};IDBFS.getDB(mount.mountpoint,(function(err,db){if(err)return callback(err);var transaction=db.transaction([IDBFS.DB_STORE_NAME],"readonly");transaction.onerror=(function(e){callback(this.error);e.preventDefault()});var store=transaction.objectStore(IDBFS.DB_STORE_NAME);var index=store.index("timestamp");index.openKeyCursor().onsuccess=(function(event){var cursor=event.target.result;if(!cursor){return callback(null,{type:"remote",db:db,entries:entries})}entries[cursor.primaryKey]={timestamp:cursor.key};cursor.continue()})}))}),loadLocalEntry:(function(path,callback){var stat,node;try{var lookup=FS.lookupPath(path);node=lookup.node;stat=FS.stat(path)}catch(e){return callback(e)}if(FS.isDir(stat.mode)){return callback(null,{timestamp:stat.mtime,mode:stat.mode})}else if(FS.isFile(stat.mode)){node.contents=MEMFS.getFileDataAsTypedArray(node);return callback(null,{timestamp:stat.mtime,mode:stat.mode,contents:node.contents})}else{return callback(new Error("node type not supported"))}}),storeLocalEntry:(function(path,entry,callback){try{if(FS.isDir(entry.mode)){FS.mkdir(path,entry.mode)}else if(FS.isFile(entry.mode)){FS.writeFile(path,entry.contents,{encoding:"binary",canOwn:true})}else{return callback(new Error("node type not supported"))}FS.chmod(path,entry.mode);FS.utime(path,entry.timestamp,entry.timestamp)}catch(e){return callback(e)}callback(null)}),removeLocalEntry:(function(path,callback){try{var lookup=FS.lookupPath(path);var stat=FS.stat(path);if(FS.isDir(stat.mode)){FS.rmdir(path)}else if(FS.isFile(stat.mode)){FS.unlink(path)}}catch(e){return callback(e)}callback(null)}),loadRemoteEntry:(function(store,path,callback){var req=store.get(path);req.onsuccess=(function(event){callback(null,event.target.result)});req.onerror=(function(e){callback(this.error);e.preventDefault()})}),storeRemoteEntry:(function(store,path,entry,callback){var req=store.put(entry,path);req.onsuccess=(function(){callback(null)});req.onerror=(function(e){callback(this.error);e.preventDefault()})}),removeRemoteEntry:(function(store,path,callback){var req=store.delete(path);req.onsuccess=(function(){callback(null)});req.onerror=(function(e){callback(this.error);e.preventDefault()})}),reconcile:(function(src,dst,callback){var total=0;var create=[];Object.keys(src.entries).forEach((function(key){var e=src.entries[key];var e2=dst.entries[key];if(!e2||e.timestamp>e2.timestamp){create.push(key);total++}}));var remove=[];Object.keys(dst.entries).forEach((function(key){var e=dst.entries[key];var e2=src.entries[key];if(!e2){remove.push(key);total++}}));if(!total){return callback(null)}var errored=false;var completed=0;var db=src.type==="remote"?src.db:dst.db;var transaction=db.transaction([IDBFS.DB_STORE_NAME],"readwrite");var store=transaction.objectStore(IDBFS.DB_STORE_NAME);function done(err){if(err){if(!done.errored){done.errored=true;return callback(err)}return}if(++completed>=total){return callback(null)}}transaction.onerror=(function(e){done(this.error);e.preventDefault()});create.sort().forEach((function(path){if(dst.type==="local"){IDBFS.loadRemoteEntry(store,path,(function(err,entry){if(err)return done(err);IDBFS.storeLocalEntry(path,entry,done)}))}else{IDBFS.loadLocalEntry(path,(function(err,entry){if(err)return done(err);IDBFS.storeRemoteEntry(store,path,entry,done)}))}}));remove.sort().reverse().forEach((function(path){if(dst.type==="local"){IDBFS.removeLocalEntry(path,done)}else{IDBFS.removeRemoteEntry(store,path,done)}}))})};var NODEFS={isWindows:false,staticInit:(function(){NODEFS.isWindows=!!process.platform.match(/^win/)}),mount:(function(mount){assert(ENVIRONMENT_IS_NODE);return NODEFS.createNode(null,"/",NODEFS.getMode(mount.opts.root),0)}),createNode:(function(parent,name,mode,dev){if(!FS.isDir(mode)&&!FS.isFile(mode)&&!FS.isLink(mode)){throw new FS.ErrnoError(ERRNO_CODES.EINVAL)}var node=FS.createNode(parent,name,mode);node.node_ops=NODEFS.node_ops;node.stream_ops=NODEFS.stream_ops;return node}),getMode:(function(path){var stat;try{stat=fs.lstatSync(path);if(NODEFS.isWindows){stat.mode=stat.mode|(stat.mode&146)>>1}}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(ERRNO_CODES[e.code])}return stat.mode}),realPath:(function(node){var parts=[];while(node.parent!==node){parts.push(node.name);node=node.parent}parts.push(node.mount.opts.root);parts.reverse();return PATH.join.apply(null,parts)}),flagsToPermissionStringMap:{0:"r",1:"r+",2:"r+",64:"r",65:"r+",66:"r+",129:"rx+",193:"rx+",514:"w+",577:"w",578:"w+",705:"wx",706:"wx+",1024:"a",1025:"a",1026:"a+",1089:"a",1090:"a+",1153:"ax",1154:"ax+",1217:"ax",1218:"ax+",4096:"rs",4098:"rs+"},flagsToPermissionString:(function(flags){flags&=~32768;if(flags in NODEFS.flagsToPermissionStringMap){return NODEFS.flagsToPermissionStringMap[flags]}else{throw new FS.ErrnoError(ERRNO_CODES.EINVAL)}}),node_ops:{getattr:(function(node){var path=NODEFS.realPath(node);var stat;try{stat=fs.lstatSync(path)}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(ERRNO_CODES[e.code])}if(NODEFS.isWindows&&!stat.blksize){stat.blksize=4096}if(NODEFS.isWindows&&!stat.blocks){stat.blocks=(stat.size+stat.blksize-1)/stat.blksize|0}return{dev:stat.dev,ino:stat.ino,mode:stat.mode,nlink:stat.nlink,uid:stat.uid,gid:stat.gid,rdev:stat.rdev,size:stat.size,atime:stat.atime,mtime:stat.mtime,ctime:stat.ctime,blksize:stat.blksize,blocks:stat.blocks}}),setattr:(function(node,attr){var path=NODEFS.realPath(node);try{if(attr.mode!==undefined){fs.chmodSync(path,attr.mode);node.mode=attr.mode}if(attr.timestamp!==undefined){var date=new Date(attr.timestamp);fs.utimesSync(path,date,date)}if(attr.size!==undefined){fs.truncateSync(path,attr.size)}}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(ERRNO_CODES[e.code])}}),lookup:(function(parent,name){var path=PATH.join2(NODEFS.realPath(parent),name);var mode=NODEFS.getMode(path);return NODEFS.createNode(parent,name,mode)}),mknod:(function(parent,name,mode,dev){var node=NODEFS.createNode(parent,name,mode,dev);var path=NODEFS.realPath(node);try{if(FS.isDir(node.mode)){fs.mkdirSync(path,node.mode)}else{fs.writeFileSync(path,"",{mode:node.mode})}}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(ERRNO_CODES[e.code])}return node}),rename:(function(oldNode,newDir,newName){var oldPath=NODEFS.realPath(oldNode);var newPath=PATH.join2(NODEFS.realPath(newDir),newName);try{fs.renameSync(oldPath,newPath)}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(ERRNO_CODES[e.code])}}),unlink:(function(parent,name){var path=PATH.join2(NODEFS.realPath(parent),name);try{fs.unlinkSync(path)}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(ERRNO_CODES[e.code])}}),rmdir:(function(parent,name){var path=PATH.join2(NODEFS.realPath(parent),name);try{fs.rmdirSync(path)}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(ERRNO_CODES[e.code])}}),readdir:(function(node){var path=NODEFS.realPath(node);try{return fs.readdirSync(path)}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(ERRNO_CODES[e.code])}}),symlink:(function(parent,newName,oldPath){var newPath=PATH.join2(NODEFS.realPath(parent),newName);try{fs.symlinkSync(oldPath,newPath)}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(ERRNO_CODES[e.code])}}),readlink:(function(node){var path=NODEFS.realPath(node);try{path=fs.readlinkSync(path);path=NODEJS_PATH.relative(NODEJS_PATH.resolve(node.mount.opts.root),path);return path}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(ERRNO_CODES[e.code])}})},stream_ops:{open:(function(stream){var path=NODEFS.realPath(stream.node);try{if(FS.isFile(stream.node.mode)){stream.nfd=fs.openSync(path,NODEFS.flagsToPermissionString(stream.flags))}}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(ERRNO_CODES[e.code])}}),close:(function(stream){try{if(FS.isFile(stream.node.mode)&&stream.nfd){fs.closeSync(stream.nfd)}}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(ERRNO_CODES[e.code])}}),read:(function(stream,buffer,offset,length,position){if(length===0)return 0;var nbuffer=new Buffer(length);var res;try{res=fs.readSync(stream.nfd,nbuffer,0,length,position)}catch(e){throw new FS.ErrnoError(ERRNO_CODES[e.code])}if(res>0){for(var i=0;i<res;i++){buffer[offset+i]=nbuffer[i]}}return res}),write:(function(stream,buffer,offset,length,position){var nbuffer=new Buffer(buffer.subarray(offset,offset+length));var res;try{res=fs.writeSync(stream.nfd,nbuffer,0,length,position)}catch(e){throw new FS.ErrnoError(ERRNO_CODES[e.code])}return res}),llseek:(function(stream,offset,whence){var position=offset;if(whence===1){position+=stream.position}else if(whence===2){if(FS.isFile(stream.node.mode)){try{var stat=fs.fstatSync(stream.nfd);position+=stat.size}catch(e){throw new FS.ErrnoError(ERRNO_CODES[e.code])}}}if(position<0){throw new FS.ErrnoError(ERRNO_CODES.EINVAL)}return position})}};var WORKERFS={DIR_MODE:16895,FILE_MODE:33279,reader:null,mount:(function(mount){assert(ENVIRONMENT_IS_WORKER);if(!WORKERFS.reader)WORKERFS.reader=new FileReaderSync;var root=WORKERFS.createNode(null,"/",WORKERFS.DIR_MODE,0);var createdParents={};function ensureParent(path){var parts=path.split("/");var parent=root;for(var i=0;i<parts.length-1;i++){var curr=parts.slice(0,i+1).join("/");if(!createdParents[curr]){createdParents[curr]=WORKERFS.createNode(parent,curr,WORKERFS.DIR_MODE,0)}parent=createdParents[curr]}return parent}function base(path){var parts=path.split("/");return parts[parts.length-1]}Array.prototype.forEach.call(mount.opts["files"]||[],(function(file){WORKERFS.createNode(ensureParent(file.name),base(file.name),WORKERFS.FILE_MODE,0,file,file.lastModifiedDate)}));(mount.opts["blobs"]||[]).forEach((function(obj){WORKERFS.createNode(ensureParent(obj["name"]),base(obj["name"]),WORKERFS.FILE_MODE,0,obj["data"])}));(mount.opts["packages"]||[]).forEach((function(pack){pack["metadata"].files.forEach((function(file){var name=file.filename.substr(1);WORKERFS.createNode(ensureParent(name),base(name),WORKERFS.FILE_MODE,0,pack["blob"].slice(file.start,file.end))}))}));return root}),createNode:(function(parent,name,mode,dev,contents,mtime){var node=FS.createNode(parent,name,mode);node.mode=mode;node.node_ops=WORKERFS.node_ops;node.stream_ops=WORKERFS.stream_ops;node.timestamp=(mtime||new Date).getTime();assert(WORKERFS.FILE_MODE!==WORKERFS.DIR_MODE);if(mode===WORKERFS.FILE_MODE){node.size=contents.size;node.contents=contents}else{node.size=4096;node.contents={}}if(parent){parent.contents[name]=node}return node}),node_ops:{getattr:(function(node){return{dev:1,ino:undefined,mode:node.mode,nlink:1,uid:0,gid:0,rdev:undefined,size:node.size,atime:new Date(node.timestamp),mtime:new Date(node.timestamp),ctime:new Date(node.timestamp),blksize:4096,blocks:Math.ceil(node.size/4096)}}),setattr:(function(node,attr){if(attr.mode!==undefined){node.mode=attr.mode}if(attr.timestamp!==undefined){node.timestamp=attr.timestamp}}),lookup:(function(parent,name){throw new FS.ErrnoError(ERRNO_CODES.ENOENT)}),mknod:(function(parent,name,mode,dev){throw new FS.ErrnoError(ERRNO_CODES.EPERM)}),rename:(function(oldNode,newDir,newName){throw new FS.ErrnoError(ERRNO_CODES.EPERM)}),unlink:(function(parent,name){throw new FS.ErrnoError(ERRNO_CODES.EPERM)}),rmdir:(function(parent,name){throw new FS.ErrnoError(ERRNO_CODES.EPERM)}),readdir:(function(node){throw new FS.ErrnoError(ERRNO_CODES.EPERM)}),symlink:(function(parent,newName,oldPath){throw new FS.ErrnoError(ERRNO_CODES.EPERM)}),readlink:(function(node){throw new FS.ErrnoError(ERRNO_CODES.EPERM)})},stream_ops:{read:(function(stream,buffer,offset,length,position){if(position>=stream.node.size)return 0;var chunk=stream.node.contents.slice(position,position+length);var ab=WORKERFS.reader.readAsArrayBuffer(chunk);buffer.set(new Uint8Array(ab),offset);return chunk.size}),write:(function(stream,buffer,offset,length,position){throw new FS.ErrnoError(ERRNO_CODES.EIO)}),llseek:(function(stream,offset,whence){var position=offset;if(whence===1){position+=stream.position}else if(whence===2){if(FS.isFile(stream.node.mode)){position+=stream.node.size}}if(position<0){throw new FS.ErrnoError(ERRNO_CODES.EINVAL)}return position})}};var _stdin=allocate(1,"i32*",ALLOC_STATIC);var _stdout=allocate(1,"i32*",ALLOC_STATIC);var _stderr=allocate(1,"i32*",ALLOC_STATIC);var FS={root:null,mounts:[],devices:[null],streams:[],nextInode:1,nameTable:null,currentPath:"/",initialized:false,ignorePermissions:true,trackingDelegate:{},tracking:{openFlags:{READ:1,WRITE:2}},ErrnoError:null,genericErrors:{},filesystems:null,handleFSError:(function(e){if(!(e instanceof FS.ErrnoError))throw e+" : "+stackTrace();return ___setErrNo(e.errno)}),lookupPath:(function(path,opts){path=PATH.resolve(FS.cwd(),path);opts=opts||{};if(!path)return{path:"",node:null};var defaults={follow_mount:true,recurse_count:0};for(var key in defaults){if(opts[key]===undefined){opts[key]=defaults[key]}}if(opts.recurse_count>8){throw new FS.ErrnoError(ERRNO_CODES.ELOOP)}var parts=PATH.normalizeArray(path.split("/").filter((function(p){return!!p})),false);var current=FS.root;var current_path="/";for(var i=0;i<parts.length;i++){var islast=i===parts.length-1;if(islast&&opts.parent){break}current=FS.lookupNode(current,parts[i]);current_path=PATH.join2(current_path,parts[i]);if(FS.isMountpoint(current)){if(!islast||islast&&opts.follow_mount){current=current.mounted.root}}if(!islast||opts.follow){var count=0;while(FS.isLink(current.mode)){var link=FS.readlink(current_path);current_path=PATH.resolve(PATH.dirname(current_path),link);var lookup=FS.lookupPath(current_path,{recurse_count:opts.recurse_count});current=lookup.node;if(count++>40){throw new FS.ErrnoError(ERRNO_CODES.ELOOP)}}}}return{path:current_path,node:current}}),getPath:(function(node){var path;while(true){if(FS.isRoot(node)){var mount=node.mount.mountpoint;if(!path)return mount;return mount[mount.length-1]!=="/"?mount+"/"+path:mount+path}path=path?node.name+"/"+path:node.name;node=node.parent}}),hashName:(function(parentid,name){var hash=0;for(var i=0;i<name.length;i++){hash=(hash<<5)-hash+name.charCodeAt(i)|0}return(parentid+hash>>>0)%FS.nameTable.length}),hashAddNode:(function(node){var hash=FS.hashName(node.parent.id,node.name);node.name_next=FS.nameTable[hash];FS.nameTable[hash]=node}),hashRemoveNode:(function(node){var hash=FS.hashName(node.parent.id,node.name);if(FS.nameTable[hash]===node){FS.nameTable[hash]=node.name_next}else{var current=FS.nameTable[hash];while(current){if(current.name_next===node){current.name_next=node.name_next;break}current=current.name_next}}}),lookupNode:(function(parent,name){var err=FS.mayLookup(parent);if(err){throw new FS.ErrnoError(err,parent)}var hash=FS.hashName(parent.id,name);for(var node=FS.nameTable[hash];node;node=node.name_next){var nodeName=node.name;if(node.parent.id===parent.id&&nodeName===name){return node}}return FS.lookup(parent,name)}),createNode:(function(parent,name,mode,rdev){if(!FS.FSNode){FS.FSNode=(function(parent,name,mode,rdev){if(!parent){parent=this}this.parent=parent;this.mount=parent.mount;this.mounted=null;this.id=FS.nextInode++;this.name=name;this.mode=mode;this.node_ops={};this.stream_ops={};this.rdev=rdev});FS.FSNode.prototype={};var readMode=292|73;var writeMode=146;Object.defineProperties(FS.FSNode.prototype,{read:{get:(function(){return(this.mode&readMode)===readMode}),set:(function(val){val?this.mode|=readMode:this.mode&=~readMode})},write:{get:(function(){return(this.mode&writeMode)===writeMode}),set:(function(val){val?this.mode|=writeMode:this.mode&=~writeMode})},isFolder:{get:(function(){return FS.isDir(this.mode)})},isDevice:{get:(function(){return FS.isChrdev(this.mode)})}})}var node=new FS.FSNode(parent,name,mode,rdev);FS.hashAddNode(node);return node}),destroyNode:(function(node){FS.hashRemoveNode(node)}),isRoot:(function(node){return node===node.parent}),isMountpoint:(function(node){return!!node.mounted}),isFile:(function(mode){return(mode&61440)===32768}),isDir:(function(mode){return(mode&61440)===16384}),isLink:(function(mode){return(mode&61440)===40960}),isChrdev:(function(mode){return(mode&61440)===8192}),isBlkdev:(function(mode){return(mode&61440)===24576}),isFIFO:(function(mode){return(mode&61440)===4096}),isSocket:(function(mode){return(mode&49152)===49152}),flagModes:{"r":0,"rs":1052672,"r+":2,"w":577,"wx":705,"xw":705,"w+":578,"wx+":706,"xw+":706,"a":1089,"ax":1217,"xa":1217,"a+":1090,"ax+":1218,"xa+":1218},modeStringToFlags:(function(str){var flags=FS.flagModes[str];if(typeof flags==="undefined"){throw new Error("Unknown file open mode: "+str)}return flags}),flagsToPermissionString:(function(flag){var perms=["r","w","rw"][flag&3];if(flag&512){perms+="w"}return perms}),nodePermissions:(function(node,perms){if(FS.ignorePermissions){return 0}if(perms.indexOf("r")!==-1&&!(node.mode&292)){return ERRNO_CODES.EACCES}else if(perms.indexOf("w")!==-1&&!(node.mode&146)){return ERRNO_CODES.EACCES}else if(perms.indexOf("x")!==-1&&!(node.mode&73)){return ERRNO_CODES.EACCES}return 0}),mayLookup:(function(dir){var err=FS.nodePermissions(dir,"x");if(err)return err;if(!dir.node_ops.lookup)return ERRNO_CODES.EACCES;return 0}),mayCreate:(function(dir,name){try{var node=FS.lookupNode(dir,name);return ERRNO_CODES.EEXIST}catch(e){}return FS.nodePermissions(dir,"wx")}),mayDelete:(function(dir,name,isdir){var node;try{node=FS.lookupNode(dir,name)}catch(e){return e.errno}var err=FS.nodePermissions(dir,"wx");if(err){return err}if(isdir){if(!FS.isDir(node.mode)){return ERRNO_CODES.ENOTDIR}if(FS.isRoot(node)||FS.getPath(node)===FS.cwd()){return ERRNO_CODES.EBUSY}}else{if(FS.isDir(node.mode)){return ERRNO_CODES.EISDIR}}return 0}),mayOpen:(function(node,flags){if(!node){return ERRNO_CODES.ENOENT}if(FS.isLink(node.mode)){return ERRNO_CODES.ELOOP}else if(FS.isDir(node.mode)){if((flags&2097155)!==0||flags&512){return ERRNO_CODES.EISDIR}}return FS.nodePermissions(node,FS.flagsToPermissionString(flags))}),MAX_OPEN_FDS:4096,nextfd:(function(fd_start,fd_end){fd_start=fd_start||0;fd_end=fd_end||FS.MAX_OPEN_FDS;for(var fd=fd_start;fd<=fd_end;fd++){if(!FS.streams[fd]){return fd}}throw new FS.ErrnoError(ERRNO_CODES.EMFILE)}),getStream:(function(fd){return FS.streams[fd]}),createStream:(function(stream,fd_start,fd_end){if(!FS.FSStream){FS.FSStream=(function(){});FS.FSStream.prototype={};Object.defineProperties(FS.FSStream.prototype,{object:{get:(function(){return this.node}),set:(function(val){this.node=val})},isRead:{get:(function(){return(this.flags&2097155)!==1})},isWrite:{get:(function(){return(this.flags&2097155)!==0})},isAppend:{get:(function(){return this.flags&1024})}})}var newStream=new FS.FSStream;for(var p in stream){newStream[p]=stream[p]}stream=newStream;var fd=FS.nextfd(fd_start,fd_end);stream.fd=fd;FS.streams[fd]=stream;return stream}),closeStream:(function(fd){FS.streams[fd]=null}),chrdev_stream_ops:{open:(function(stream){var device=FS.getDevice(stream.node.rdev);stream.stream_ops=device.stream_ops;if(stream.stream_ops.open){stream.stream_ops.open(stream)}}),llseek:(function(){throw new FS.ErrnoError(ERRNO_CODES.ESPIPE)})},major:(function(dev){return dev>>8}),minor:(function(dev){return dev&255}),makedev:(function(ma,mi){return ma<<8|mi}),registerDevice:(function(dev,ops){FS.devices[dev]={stream_ops:ops}}),getDevice:(function(dev){return FS.devices[dev]}),getMounts:(function(mount){var mounts=[];var check=[mount];while(check.length){var m=check.pop();mounts.push(m);check.push.apply(check,m.mounts)}return mounts}),syncfs:(function(populate,callback){if(typeof populate==="function"){callback=populate;populate=false}var mounts=FS.getMounts(FS.root.mount);var completed=0;function done(err){if(err){if(!done.errored){done.errored=true;return callback(err)}return}if(++completed>=mounts.length){callback(null)}}mounts.forEach((function(mount){if(!mount.type.syncfs){return done(null)}mount.type.syncfs(mount,populate,done)}))}),mount:(function(type,opts,mountpoint){var root=mountpoint==="/";var pseudo=!mountpoint;var node;if(root&&FS.root){throw new FS.ErrnoError(ERRNO_CODES.EBUSY)}else if(!root&&!pseudo){var lookup=FS.lookupPath(mountpoint,{follow_mount:false});mountpoint=lookup.path;node=lookup.node;if(FS.isMountpoint(node)){throw new FS.ErrnoError(ERRNO_CODES.EBUSY)}if(!FS.isDir(node.mode)){throw new FS.ErrnoError(ERRNO_CODES.ENOTDIR)}}var mount={type:type,opts:opts,mountpoint:mountpoint,mounts:[]};var mountRoot=type.mount(mount);mountRoot.mount=mount;mount.root=mountRoot;if(root){FS.root=mountRoot}else if(node){node.mounted=mount;if(node.mount){node.mount.mounts.push(mount)}}return mountRoot}),unmount:(function(mountpoint){var lookup=FS.lookupPath(mountpoint,{follow_mount:false});if(!FS.isMountpoint(lookup.node)){throw new FS.ErrnoError(ERRNO_CODES.EINVAL)}var node=lookup.node;var mount=node.mounted;var mounts=FS.getMounts(mount);Object.keys(FS.nameTable).forEach((function(hash){var current=FS.nameTable[hash];while(current){var next=current.name_next;if(mounts.indexOf(current.mount)!==-1){FS.destroyNode(current)}current=next}}));node.mounted=null;var idx=node.mount.mounts.indexOf(mount);assert(idx!==-1);node.mount.mounts.splice(idx,1)}),lookup:(function(parent,name){return parent.node_ops.lookup(parent,name)}),mknod:(function(path,mode,dev){var lookup=FS.lookupPath(path,{parent:true});var parent=lookup.node;var name=PATH.basename(path);if(!name||name==="."||name===".."){throw new FS.ErrnoError(ERRNO_CODES.EINVAL)}var err=FS.mayCreate(parent,name);if(err){throw new FS.ErrnoError(err)}if(!parent.node_ops.mknod){throw new FS.ErrnoError(ERRNO_CODES.EPERM)}return parent.node_ops.mknod(parent,name,mode,dev)}),create:(function(path,mode){mode=mode!==undefined?mode:438;mode&=4095;mode|=32768;return FS.mknod(path,mode,0)}),mkdir:(function(path,mode){mode=mode!==undefined?mode:511;mode&=511|512;mode|=16384;return FS.mknod(path,mode,0)}),mkdev:(function(path,mode,dev){if(typeof dev==="undefined"){dev=mode;mode=438}mode|=8192;return FS.mknod(path,mode,dev)}),symlink:(function(oldpath,newpath){if(!PATH.resolve(oldpath)){throw new FS.ErrnoError(ERRNO_CODES.ENOENT)}var lookup=FS.lookupPath(newpath,{parent:true});var parent=lookup.node;if(!parent){throw new FS.ErrnoError(ERRNO_CODES.ENOENT)}var newname=PATH.basename(newpath);var err=FS.mayCreate(parent,newname);if(err){throw new FS.ErrnoError(err)}if(!parent.node_ops.symlink){throw new FS.ErrnoError(ERRNO_CODES.EPERM)}return parent.node_ops.symlink(parent,newname,oldpath)}),rename:(function(old_path,new_path){var old_dirname=PATH.dirname(old_path);var new_dirname=PATH.dirname(new_path);var old_name=PATH.basename(old_path);var new_name=PATH.basename(new_path);var lookup,old_dir,new_dir;try{lookup=FS.lookupPath(old_path,{parent:true});old_dir=lookup.node;lookup=FS.lookupPath(new_path,{parent:true});new_dir=lookup.node}catch(e){throw new FS.ErrnoError(ERRNO_CODES.EBUSY)}if(!old_dir||!new_dir)throw new FS.ErrnoError(ERRNO_CODES.ENOENT);if(old_dir.mount!==new_dir.mount){throw new FS.ErrnoError(ERRNO_CODES.EXDEV)}var old_node=FS.lookupNode(old_dir,old_name);var relative=PATH.relative(old_path,new_dirname);if(relative.charAt(0)!=="."){throw new FS.ErrnoError(ERRNO_CODES.EINVAL)}relative=PATH.relative(new_path,old_dirname);if(relative.charAt(0)!=="."){throw new FS.ErrnoError(ERRNO_CODES.ENOTEMPTY)}var new_node;try{new_node=FS.lookupNode(new_dir,new_name)}catch(e){}if(old_node===new_node){return}var isdir=FS.isDir(old_node.mode);var err=FS.mayDelete(old_dir,old_name,isdir);if(err){throw new FS.ErrnoError(err)}err=new_node?FS.mayDelete(new_dir,new_name,isdir):FS.mayCreate(new_dir,new_name);if(err){throw new FS.ErrnoError(err)}if(!old_dir.node_ops.rename){throw new FS.ErrnoError(ERRNO_CODES.EPERM)}if(FS.isMountpoint(old_node)||new_node&&FS.isMountpoint(new_node)){throw new FS.ErrnoError(ERRNO_CODES.EBUSY)}if(new_dir!==old_dir){err=FS.nodePermissions(old_dir,"w");if(err){throw new FS.ErrnoError(err)}}try{if(FS.trackingDelegate["willMovePath"]){FS.trackingDelegate["willMovePath"](old_path,new_path)}}catch(e){console.log("FS.trackingDelegate['willMovePath']('"+old_path+"', '"+new_path+"') threw an exception: "+e.message)}FS.hashRemoveNode(old_node);try{old_dir.node_ops.rename(old_node,new_dir,new_name)}catch(e){throw e}finally{FS.hashAddNode(old_node)}try{if(FS.trackingDelegate["onMovePath"])FS.trackingDelegate["onMovePath"](old_path,new_path)}catch(e){console.log("FS.trackingDelegate['onMovePath']('"+old_path+"', '"+new_path+"') threw an exception: "+e.message)}}),rmdir:(function(path){var lookup=FS.lookupPath(path,{parent:true});var parent=lookup.node;var name=PATH.basename(path);var node=FS.lookupNode(parent,name);var err=FS.mayDelete(parent,name,true);if(err){throw new FS.ErrnoError(err)}if(!parent.node_ops.rmdir){throw new FS.ErrnoError(ERRNO_CODES.EPERM)}if(FS.isMountpoint(node)){throw new FS.ErrnoError(ERRNO_CODES.EBUSY)}try{if(FS.trackingDelegate["willDeletePath"]){FS.trackingDelegate["willDeletePath"](path)}}catch(e){console.log("FS.trackingDelegate['willDeletePath']('"+path+"') threw an exception: "+e.message)}parent.node_ops.rmdir(parent,name);FS.destroyNode(node);try{if(FS.trackingDelegate["onDeletePath"])FS.trackingDelegate["onDeletePath"](path)}catch(e){console.log("FS.trackingDelegate['onDeletePath']('"+path+"') threw an exception: "+e.message)}}),readdir:(function(path){var lookup=FS.lookupPath(path,{follow:true});var node=lookup.node;if(!node.node_ops.readdir){throw new FS.ErrnoError(ERRNO_CODES.ENOTDIR)}return node.node_ops.readdir(node)}),unlink:(function(path){var lookup=FS.lookupPath(path,{parent:true});var parent=lookup.node;var name=PATH.basename(path);var node=FS.lookupNode(parent,name);var err=FS.mayDelete(parent,name,false);if(err){if(err===ERRNO_CODES.EISDIR)err=ERRNO_CODES.EPERM;throw new FS.ErrnoError(err)}if(!parent.node_ops.unlink){throw new FS.ErrnoError(ERRNO_CODES.EPERM)}if(FS.isMountpoint(node)){throw new FS.ErrnoError(ERRNO_CODES.EBUSY)}try{if(FS.trackingDelegate["willDeletePath"]){FS.trackingDelegate["willDeletePath"](path)}}catch(e){console.log("FS.trackingDelegate['willDeletePath']('"+path+"') threw an exception: "+e.message)}parent.node_ops.unlink(parent,name);FS.destroyNode(node);try{if(FS.trackingDelegate["onDeletePath"])FS.trackingDelegate["onDeletePath"](path)}catch(e){console.log("FS.trackingDelegate['onDeletePath']('"+path+"') threw an exception: "+e.message)}}),readlink:(function(path){var lookup=FS.lookupPath(path);var link=lookup.node;if(!link){throw new FS.ErrnoError(ERRNO_CODES.ENOENT)}if(!link.node_ops.readlink){throw new FS.ErrnoError(ERRNO_CODES.EINVAL)}return PATH.resolve(FS.getPath(link.parent),link.node_ops.readlink(link))}),stat:(function(path,dontFollow){var lookup=FS.lookupPath(path,{follow:!dontFollow});var node=lookup.node;if(!node){throw new FS.ErrnoError(ERRNO_CODES.ENOENT)}if(!node.node_ops.getattr){throw new FS.ErrnoError(ERRNO_CODES.EPERM)}return node.node_ops.getattr(node)}),lstat:(function(path){return FS.stat(path,true)}),chmod:(function(path,mode,dontFollow){var node;if(typeof path==="string"){var lookup=FS.lookupPath(path,{follow:!dontFollow});node=lookup.node}else{node=path}if(!node.node_ops.setattr){throw new FS.ErrnoError(ERRNO_CODES.EPERM)}node.node_ops.setattr(node,{mode:mode&4095|node.mode&~4095,timestamp:Date.now()})}),lchmod:(function(path,mode){FS.chmod(path,mode,true)}),fchmod:(function(fd,mode){var stream=FS.getStream(fd);if(!stream){throw new FS.ErrnoError(ERRNO_CODES.EBADF)}FS.chmod(stream.node,mode)}),chown:(function(path,uid,gid,dontFollow){var node;if(typeof path==="string"){var lookup=FS.lookupPath(path,{follow:!dontFollow});node=lookup.node}else{node=path}if(!node.node_ops.setattr){throw new FS.ErrnoError(ERRNO_CODES.EPERM)}node.node_ops.setattr(node,{timestamp:Date.now()})}),lchown:(function(path,uid,gid){FS.chown(path,uid,gid,true)}),fchown:(function(fd,uid,gid){var stream=FS.getStream(fd);if(!stream){throw new FS.ErrnoError(ERRNO_CODES.EBADF)}FS.chown(stream.node,uid,gid)}),truncate:(function(path,len){if(len<0){throw new FS.ErrnoError(ERRNO_CODES.EINVAL)}var node;if(typeof path==="string"){var lookup=FS.lookupPath(path,{follow:true});node=lookup.node}else{node=path}if(!node.node_ops.setattr){throw new FS.ErrnoError(ERRNO_CODES.EPERM)}if(FS.isDir(node.mode)){throw new FS.ErrnoError(ERRNO_CODES.EISDIR)}if(!FS.isFile(node.mode)){throw new FS.ErrnoError(ERRNO_CODES.EINVAL)}var err=FS.nodePermissions(node,"w");if(err){throw new FS.ErrnoError(err)}node.node_ops.setattr(node,{size:len,timestamp:Date.now()})}),ftruncate:(function(fd,len){var stream=FS.getStream(fd);if(!stream){throw new FS.ErrnoError(ERRNO_CODES.EBADF)}if((stream.flags&2097155)===0){throw new FS.ErrnoError(ERRNO_CODES.EINVAL)}FS.truncate(stream.node,len)}),utime:(function(path,atime,mtime){var lookup=FS.lookupPath(path,{follow:true});var node=lookup.node;node.node_ops.setattr(node,{timestamp:Math.max(atime,mtime)})}),open:(function(path,flags,mode,fd_start,fd_end){if(path===""){throw new FS.ErrnoError(ERRNO_CODES.ENOENT)}flags=typeof flags==="string"?FS.modeStringToFlags(flags):flags;mode=typeof mode==="undefined"?438:mode;if(flags&64){mode=mode&4095|32768}else{mode=0}var node;if(typeof path==="object"){node=path}else{path=PATH.normalize(path);try{var lookup=FS.lookupPath(path,{follow:!(flags&131072)});node=lookup.node}catch(e){}}var created=false;if(flags&64){if(node){if(flags&128){throw new FS.ErrnoError(ERRNO_CODES.EEXIST)}}else{node=FS.mknod(path,mode,0);created=true}}if(!node){throw new FS.ErrnoError(ERRNO_CODES.ENOENT)}if(FS.isChrdev(node.mode)){flags&=~512}if(flags&65536&&!FS.isDir(node.mode)){throw new FS.ErrnoError(ERRNO_CODES.ENOTDIR)}if(!created){var err=FS.mayOpen(node,flags);if(err){throw new FS.ErrnoError(err)}}if(flags&512){FS.truncate(node,0)}flags&=~(128|512);var stream=FS.createStream({node:node,path:FS.getPath(node),flags:flags,seekable:true,position:0,stream_ops:node.stream_ops,ungotten:[],error:false},fd_start,fd_end);if(stream.stream_ops.open){stream.stream_ops.open(stream)}if(Module["logReadFiles"]&&!(flags&1)){if(!FS.readFiles)FS.readFiles={};if(!(path in FS.readFiles)){FS.readFiles[path]=1;Module["printErr"]("read file: "+path)}}try{if(FS.trackingDelegate["onOpenFile"]){var trackingFlags=0;if((flags&2097155)!==1){trackingFlags|=FS.tracking.openFlags.READ}if((flags&2097155)!==0){trackingFlags|=FS.tracking.openFlags.WRITE}FS.trackingDelegate["onOpenFile"](path,trackingFlags)}}catch(e){console.log("FS.trackingDelegate['onOpenFile']('"+path+"', flags) threw an exception: "+e.message)}return stream}),close:(function(stream){if(stream.getdents)stream.getdents=null;try{if(stream.stream_ops.close){stream.stream_ops.close(stream)}}catch(e){throw e}finally{FS.closeStream(stream.fd)}}),llseek:(function(stream,offset,whence){if(!stream.seekable||!stream.stream_ops.llseek){throw new FS.ErrnoError(ERRNO_CODES.ESPIPE)}stream.position=stream.stream_ops.llseek(stream,offset,whence);stream.ungotten=[];return stream.position}),read:(function(stream,buffer,offset,length,position){if(length<0||position<0){throw new FS.ErrnoError(ERRNO_CODES.EINVAL)}if((stream.flags&2097155)===1){throw new FS.ErrnoError(ERRNO_CODES.EBADF)}if(FS.isDir(stream.node.mode)){throw new FS.ErrnoError(ERRNO_CODES.EISDIR)}if(!stream.stream_ops.read){throw new FS.ErrnoError(ERRNO_CODES.EINVAL)}var seeking=true;if(typeof position==="undefined"){position=stream.position;seeking=false}else if(!stream.seekable){throw new FS.ErrnoError(ERRNO_CODES.ESPIPE)}var bytesRead=stream.stream_ops.read(stream,buffer,offset,length,position);if(!seeking)stream.position+=bytesRead;return bytesRead}),write:(function(stream,buffer,offset,length,position,canOwn){if(length<0||position<0){throw new FS.ErrnoError(ERRNO_CODES.EINVAL)}if((stream.flags&2097155)===0){throw new FS.ErrnoError(ERRNO_CODES.EBADF)}if(FS.isDir(stream.node.mode)){throw new FS.ErrnoError(ERRNO_CODES.EISDIR)}if(!stream.stream_ops.write){throw new FS.ErrnoError(ERRNO_CODES.EINVAL)}if(stream.flags&1024){FS.llseek(stream,0,2)}var seeking=true;if(typeof position==="undefined"){position=stream.position;seeking=false}else if(!stream.seekable){throw new FS.ErrnoError(ERRNO_CODES.ESPIPE)}var bytesWritten=stream.stream_ops.write(stream,buffer,offset,length,position,canOwn);if(!seeking)stream.position+=bytesWritten;try{if(stream.path&&FS.trackingDelegate["onWriteToFile"])FS.trackingDelegate["onWriteToFile"](stream.path)}catch(e){console.log("FS.trackingDelegate['onWriteToFile']('"+path+"') threw an exception: "+e.message)}return bytesWritten}),allocate:(function(stream,offset,length){if(offset<0||length<=0){throw new FS.ErrnoError(ERRNO_CODES.EINVAL)}if((stream.flags&2097155)===0){throw new FS.ErrnoError(ERRNO_CODES.EBADF)}if(!FS.isFile(stream.node.mode)&&!FS.isDir(node.mode)){throw new FS.ErrnoError(ERRNO_CODES.ENODEV)}if(!stream.stream_ops.allocate){throw new FS.ErrnoError(ERRNO_CODES.EOPNOTSUPP)}stream.stream_ops.allocate(stream,offset,length)}),mmap:(function(stream,buffer,offset,length,position,prot,flags){if((stream.flags&2097155)===1){throw new FS.ErrnoError(ERRNO_CODES.EACCES)}if(!stream.stream_ops.mmap){throw new FS.ErrnoError(ERRNO_CODES.ENODEV)}return stream.stream_ops.mmap(stream,buffer,offset,length,position,prot,flags)}),msync:(function(stream,buffer,offset,length,mmapFlags){if(!stream||!stream.stream_ops.msync){return 0}return stream.stream_ops.msync(stream,buffer,offset,length,mmapFlags)}),munmap:(function(stream){return 0}),ioctl:(function(stream,cmd,arg){if(!stream.stream_ops.ioctl){throw new FS.ErrnoError(ERRNO_CODES.ENOTTY)}return stream.stream_ops.ioctl(stream,cmd,arg)}),readFile:(function(path,opts){opts=opts||{};opts.flags=opts.flags||"r";opts.encoding=opts.encoding||"binary";if(opts.encoding!=="utf8"&&opts.encoding!=="binary"){throw new Error('Invalid encoding type "'+opts.encoding+'"')}var ret;var stream=FS.open(path,opts.flags);var stat=FS.stat(path);var length=stat.size;var buf=new Uint8Array(length);FS.read(stream,buf,0,length,0);if(opts.encoding==="utf8"){ret=UTF8ArrayToString(buf,0)}else if(opts.encoding==="binary"){ret=buf}FS.close(stream);return ret}),writeFile:(function(path,data,opts){opts=opts||{};opts.flags=opts.flags||"w";opts.encoding=opts.encoding||"utf8";if(opts.encoding!=="utf8"&&opts.encoding!=="binary"){throw new Error('Invalid encoding type "'+opts.encoding+'"')}var stream=FS.open(path,opts.flags,opts.mode);if(opts.encoding==="utf8"){var buf=new Uint8Array(lengthBytesUTF8(data)+1);var actualNumBytes=stringToUTF8Array(data,buf,0,buf.length);FS.write(stream,buf,0,actualNumBytes,0,opts.canOwn)}else if(opts.encoding==="binary"){FS.write(stream,data,0,data.length,0,opts.canOwn)}FS.close(stream)}),cwd:(function(){return FS.currentPath}),chdir:(function(path){var lookup=FS.lookupPath(path,{follow:true});if(!FS.isDir(lookup.node.mode)){throw new FS.ErrnoError(ERRNO_CODES.ENOTDIR)}var err=FS.nodePermissions(lookup.node,"x");if(err){throw new FS.ErrnoError(err)}FS.currentPath=lookup.path}),createDefaultDirectories:(function(){FS.mkdir("/tmp");FS.mkdir("/home");FS.mkdir("/home/web_user")}),createDefaultDevices:(function(){FS.mkdir("/dev");FS.registerDevice(FS.makedev(1,3),{read:(function(){return 0}),write:(function(stream,buffer,offset,length,pos){return length})});FS.mkdev("/dev/null",FS.makedev(1,3));TTY.register(FS.makedev(5,0),TTY.default_tty_ops);TTY.register(FS.makedev(6,0),TTY.default_tty1_ops);FS.mkdev("/dev/tty",FS.makedev(5,0));FS.mkdev("/dev/tty1",FS.makedev(6,0));var random_device;if(typeof crypto!=="undefined"){var randomBuffer=new Uint8Array(1);random_device=(function(){crypto.getRandomValues(randomBuffer);return randomBuffer[0]})}else if(ENVIRONMENT_IS_NODE){random_device=(function(){return require("crypto").randomBytes(1)[0]})}else{random_device=(function(){return Math.random()*256|0})}FS.createDevice("/dev","random",random_device);FS.createDevice("/dev","urandom",random_device);FS.mkdir("/dev/shm");FS.mkdir("/dev/shm/tmp")}),createSpecialDirectories:(function(){FS.mkdir("/proc");FS.mkdir("/proc/self");FS.mkdir("/proc/self/fd");FS.mount({mount:(function(){var node=FS.createNode("/proc/self","fd",16384|511,73);node.node_ops={lookup:(function(parent,name){var fd=+name;var stream=FS.getStream(fd);if(!stream)throw new FS.ErrnoError(ERRNO_CODES.EBADF);var ret={parent:null,mount:{mountpoint:"fake"},node_ops:{readlink:(function(){return stream.path})}};ret.parent=ret;return ret})};return node})},{},"/proc/self/fd")}),createStandardStreams:(function(){if(Module["stdin"]){FS.createDevice("/dev","stdin",Module["stdin"])}else{FS.symlink("/dev/tty","/dev/stdin")}if(Module["stdout"]){FS.createDevice("/dev","stdout",null,Module["stdout"])}else{FS.symlink("/dev/tty","/dev/stdout")}if(Module["stderr"]){FS.createDevice("/dev","stderr",null,Module["stderr"])}else{FS.symlink("/dev/tty1","/dev/stderr")}var stdin=FS.open("/dev/stdin","r");assert(stdin.fd===0,"invalid handle for stdin ("+stdin.fd+")");var stdout=FS.open("/dev/stdout","w");assert(stdout.fd===1,"invalid handle for stdout ("+stdout.fd+")");var stderr=FS.open("/dev/stderr","w");assert(stderr.fd===2,"invalid handle for stderr ("+stderr.fd+")")}),ensureErrnoError:(function(){if(FS.ErrnoError)return;FS.ErrnoError=function ErrnoError(errno,node){this.node=node;this.setErrno=(function(errno){this.errno=errno;for(var key in ERRNO_CODES){if(ERRNO_CODES[key]===errno){this.code=key;break}}});this.setErrno(errno);this.message=ERRNO_MESSAGES[errno]};FS.ErrnoError.prototype=new Error;FS.ErrnoError.prototype.constructor=FS.ErrnoError;[ERRNO_CODES.ENOENT].forEach((function(code){FS.genericErrors[code]=new FS.ErrnoError(code);FS.genericErrors[code].stack="<generic error, no stack>"}))}),staticInit:(function(){FS.ensureErrnoError();FS.nameTable=new Array(4096);FS.mount(MEMFS,{},"/");FS.createDefaultDirectories();FS.createDefaultDevices();FS.createSpecialDirectories();FS.filesystems={"MEMFS":MEMFS,"IDBFS":IDBFS,"NODEFS":NODEFS,"WORKERFS":WORKERFS}}),init:(function(input,output,error){assert(!FS.init.initialized,"FS.init was previously called. If you want to initialize later with custom parameters, remove any earlier calls (note that one is automatically added to the generated code)");FS.init.initialized=true;FS.ensureErrnoError();Module["stdin"]=input||Module["stdin"];Module["stdout"]=output||Module["stdout"];Module["stderr"]=error||Module["stderr"];FS.createStandardStreams()}),quit:(function(){FS.init.initialized=false;var fflush=Module["_fflush"];if(fflush)fflush(0);for(var i=0;i<FS.streams.length;i++){var stream=FS.streams[i];if(!stream){continue}FS.close(stream)}}),getMode:(function(canRead,canWrite){var mode=0;if(canRead)mode|=292|73;if(canWrite)mode|=146;return mode}),joinPath:(function(parts,forceRelative){var path=PATH.join.apply(null,parts);if(forceRelative&&path[0]=="/")path=path.substr(1);return path}),absolutePath:(function(relative,base){return PATH.resolve(base,relative)}),standardizePath:(function(path){return PATH.normalize(path)}),findObject:(function(path,dontResolveLastLink){var ret=FS.analyzePath(path,dontResolveLastLink);if(ret.exists){return ret.object}else{___setErrNo(ret.error);return null}}),analyzePath:(function(path,dontResolveLastLink){try{var lookup=FS.lookupPath(path,{follow:!dontResolveLastLink});path=lookup.path}catch(e){}var ret={isRoot:false,exists:false,error:0,name:null,path:null,object:null,parentExists:false,parentPath:null,parentObject:null};try{var lookup=FS.lookupPath(path,{parent:true});ret.parentExists=true;ret.parentPath=lookup.path;ret.parentObject=lookup.node;ret.name=PATH.basename(path);lookup=FS.lookupPath(path,{follow:!dontResolveLastLink});ret.exists=true;ret.path=lookup.path;ret.object=lookup.node;ret.name=lookup.node.name;ret.isRoot=lookup.path==="/"}catch(e){ret.error=e.errno}return ret}),createFolder:(function(parent,name,canRead,canWrite){var path=PATH.join2(typeof parent==="string"?parent:FS.getPath(parent),name);var mode=FS.getMode(canRead,canWrite);return FS.mkdir(path,mode)}),createPath:(function(parent,path,canRead,canWrite){parent=typeof parent==="string"?parent:FS.getPath(parent);var parts=path.split("/").reverse();while(parts.length){var part=parts.pop();if(!part)continue;var current=PATH.join2(parent,part);try{FS.mkdir(current)}catch(e){}parent=current}return current}),createFile:(function(parent,name,properties,canRead,canWrite){var path=PATH.join2(typeof parent==="string"?parent:FS.getPath(parent),name);var mode=FS.getMode(canRead,canWrite);return FS.create(path,mode)}),createDataFile:(function(parent,name,data,canRead,canWrite,canOwn){var path=name?PATH.join2(typeof parent==="string"?parent:FS.getPath(parent),name):parent;var mode=FS.getMode(canRead,canWrite);var node=FS.create(path,mode);if(data){if(typeof data==="string"){var arr=new Array(data.length);for(var i=0,len=data.length;i<len;++i)arr[i]=data.charCodeAt(i);data=arr}FS.chmod(node,mode|146);var stream=FS.open(node,"w");FS.write(stream,data,0,data.length,0,canOwn);FS.close(stream);FS.chmod(node,mode)}return node}),createDevice:(function(parent,name,input,output){var path=PATH.join2(typeof parent==="string"?parent:FS.getPath(parent),name);var mode=FS.getMode(!!input,!!output);if(!FS.createDevice.major)FS.createDevice.major=64;var dev=FS.makedev(FS.createDevice.major++,0);FS.registerDevice(dev,{open:(function(stream){stream.seekable=false}),close:(function(stream){if(output&&output.buffer&&output.buffer.length){output(10)}}),read:(function(stream,buffer,offset,length,pos){var bytesRead=0;for(var i=0;i<length;i++){var result;try{result=input()}catch(e){throw new FS.ErrnoError(ERRNO_CODES.EIO)}if(result===undefined&&bytesRead===0){throw new FS.ErrnoError(ERRNO_CODES.EAGAIN)}if(result===null||result===undefined)break;bytesRead++;buffer[offset+i]=result}if(bytesRead){stream.node.timestamp=Date.now()}return bytesRead}),write:(function(stream,buffer,offset,length,pos){for(var i=0;i<length;i++){try{output(buffer[offset+i])}catch(e){throw new FS.ErrnoError(ERRNO_CODES.EIO)}}if(length){stream.node.timestamp=Date.now()}return i})});return FS.mkdev(path,mode,dev)}),createLink:(function(parent,name,target,canRead,canWrite){var path=PATH.join2(typeof parent==="string"?parent:FS.getPath(parent),name);return FS.symlink(target,path)}),forceLoadFile:(function(obj){if(obj.isDevice||obj.isFolder||obj.link||obj.contents)return true;var success=true;if(typeof XMLHttpRequest!=="undefined"){throw new Error("Lazy loading should have been performed (contents set) in createLazyFile, but it was not. Lazy loading only works in web workers. Use --embed-file or --preload-file in emcc on the main thread.")}else if(Module["read"]){try{obj.contents=intArrayFromString(Module["read"](obj.url),true);obj.usedBytes=obj.contents.length}catch(e){success=false}}else{throw new Error("Cannot load without read() or XMLHttpRequest.")}if(!success)___setErrNo(ERRNO_CODES.EIO);return success}),createLazyFile:(function(parent,name,url,canRead,canWrite){function LazyUint8Array(){this.lengthKnown=false;this.chunks=[]}LazyUint8Array.prototype.get=function LazyUint8Array_get(idx){if(idx>this.length-1||idx<0){return undefined}var chunkOffset=idx%this.chunkSize;var chunkNum=idx/this.chunkSize|0;return this.getter(chunkNum)[chunkOffset]};LazyUint8Array.prototype.setDataGetter=function LazyUint8Array_setDataGetter(getter){this.getter=getter};LazyUint8Array.prototype.cacheLength=function LazyUint8Array_cacheLength(){var xhr=new XMLHttpRequest;xhr.open("HEAD",url,false);xhr.send(null);if(!(xhr.status>=200&&xhr.status<300||xhr.status===304))throw new Error("Couldn't load "+url+". Status: "+xhr.status);var datalength=Number(xhr.getResponseHeader("Content-length"));var header;var hasByteServing=(header=xhr.getResponseHeader("Accept-Ranges"))&&header==="bytes";var chunkSize=1024*1024;if(!hasByteServing)chunkSize=datalength;var doXHR=(function(from,to){if(from>to)throw new Error("invalid range ("+from+", "+to+") or no bytes requested!");if(to>datalength-1)throw new Error("only "+datalength+" bytes available! programmer error!");var xhr=new XMLHttpRequest;xhr.open("GET",url,false);if(datalength!==chunkSize)xhr.setRequestHeader("Range","bytes="+from+"-"+to);if(typeof Uint8Array!="undefined")xhr.responseType="arraybuffer";if(xhr.overrideMimeType){xhr.overrideMimeType("text/plain; charset=x-user-defined")}xhr.send(null);if(!(xhr.status>=200&&xhr.status<300||xhr.status===304))throw new Error("Couldn't load "+url+". Status: "+xhr.status);if(xhr.response!==undefined){return new Uint8Array(xhr.response||[])}else{return intArrayFromString(xhr.responseText||"",true)}});var lazyArray=this;lazyArray.setDataGetter((function(chunkNum){var start=chunkNum*chunkSize;var end=(chunkNum+1)*chunkSize-1;end=Math.min(end,datalength-1);if(typeof lazyArray.chunks[chunkNum]==="undefined"){lazyArray.chunks[chunkNum]=doXHR(start,end)}if(typeof lazyArray.chunks[chunkNum]==="undefined")throw new Error("doXHR failed!");return lazyArray.chunks[chunkNum]}));this._length=datalength;this._chunkSize=chunkSize;this.lengthKnown=true};if(typeof XMLHttpRequest!=="undefined"){if(!ENVIRONMENT_IS_WORKER)throw"Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc";var lazyArray=new LazyUint8Array;Object.defineProperty(lazyArray,"length",{get:(function(){if(!this.lengthKnown){this.cacheLength()}return this._length})});Object.defineProperty(lazyArray,"chunkSize",{get:(function(){if(!this.lengthKnown){this.cacheLength()}return this._chunkSize})});var properties={isDevice:false,contents:lazyArray}}else{var properties={isDevice:false,url:url}}var node=FS.createFile(parent,name,properties,canRead,canWrite);if(properties.contents){node.contents=properties.contents}else if(properties.url){node.contents=null;node.url=properties.url}Object.defineProperty(node,"usedBytes",{get:(function(){return this.contents.length})});var stream_ops={};var keys=Object.keys(node.stream_ops);keys.forEach((function(key){var fn=node.stream_ops[key];stream_ops[key]=function forceLoadLazyFile(){if(!FS.forceLoadFile(node)){throw new FS.ErrnoError(ERRNO_CODES.EIO)}return fn.apply(null,arguments)}}));stream_ops.read=function stream_ops_read(stream,buffer,offset,length,position){if(!FS.forceLoadFile(node)){throw new FS.ErrnoError(ERRNO_CODES.EIO)}var contents=stream.node.contents;if(position>=contents.length)return 0;var size=Math.min(contents.length-position,length);assert(size>=0);if(contents.slice){for(var i=0;i<size;i++){buffer[offset+i]=contents[position+i]}}else{for(var i=0;i<size;i++){buffer[offset+i]=contents.get(position+i)}}return size};node.stream_ops=stream_ops;return node}),createPreloadedFile:(function(parent,name,url,canRead,canWrite,onload,onerror,dontCreateFile,canOwn,preFinish){Browser.init();var fullname=name?PATH.resolve(PATH.join2(parent,name)):parent;var dep=getUniqueRunDependency("cp "+fullname);function processData(byteArray){function finish(byteArray){if(preFinish)preFinish();if(!dontCreateFile){FS.createDataFile(parent,name,byteArray,canRead,canWrite,canOwn)}if(onload)onload();removeRunDependency(dep)}var handled=false;Module["preloadPlugins"].forEach((function(plugin){if(handled)return;if(plugin["canHandle"](fullname)){plugin["handle"](byteArray,fullname,finish,(function(){if(onerror)onerror();removeRunDependency(dep)}));handled=true}}));if(!handled)finish(byteArray)}addRunDependency(dep);if(typeof url=="string"){Browser.asyncLoad(url,(function(byteArray){processData(byteArray)}),onerror)}else{processData(url)}}),indexedDB:(function(){return window.indexedDB||window.mozIndexedDB||window.webkitIndexedDB||window.msIndexedDB}),DB_NAME:(function(){return"EM_FS_"+window.location.pathname}),DB_VERSION:20,DB_STORE_NAME:"FILE_DATA",saveFilesToDB:(function(paths,onload,onerror){onload=onload||(function(){});onerror=onerror||(function(){});var indexedDB=FS.indexedDB();try{var openRequest=indexedDB.open(FS.DB_NAME(),FS.DB_VERSION)}catch(e){return onerror(e)}openRequest.onupgradeneeded=function openRequest_onupgradeneeded(){console.log("creating db");var db=openRequest.result;db.createObjectStore(FS.DB_STORE_NAME)};openRequest.onsuccess=function openRequest_onsuccess(){var db=openRequest.result;var transaction=db.transaction([FS.DB_STORE_NAME],"readwrite");var files=transaction.objectStore(FS.DB_STORE_NAME);var ok=0,fail=0,total=paths.length;function finish(){if(fail==0)onload();else onerror()}paths.forEach((function(path){var putRequest=files.put(FS.analyzePath(path).object.contents,path);putRequest.onsuccess=function putRequest_onsuccess(){ok++;if(ok+fail==total)finish()};putRequest.onerror=function putRequest_onerror(){fail++;if(ok+fail==total)finish()}}));transaction.onerror=onerror};openRequest.onerror=onerror}),loadFilesFromDB:(function(paths,onload,onerror){onload=onload||(function(){});onerror=onerror||(function(){});var indexedDB=FS.indexedDB();try{var openRequest=indexedDB.open(FS.DB_NAME(),FS.DB_VERSION)}catch(e){return onerror(e)}openRequest.onupgradeneeded=onerror;openRequest.onsuccess=function openRequest_onsuccess(){var db=openRequest.result;try{var transaction=db.transaction([FS.DB_STORE_NAME],"readonly")}catch(e){onerror(e);return}var files=transaction.objectStore(FS.DB_STORE_NAME);var ok=0,fail=0,total=paths.length;function finish(){if(fail==0)onload();else onerror()}paths.forEach((function(path){var getRequest=files.get(path);getRequest.onsuccess=function getRequest_onsuccess(){if(FS.analyzePath(path).exists){FS.unlink(path)}FS.createDataFile(PATH.dirname(path),PATH.basename(path),getRequest.result,true,true,true);ok++;if(ok+fail==total)finish()};getRequest.onerror=function getRequest_onerror(){fail++;if(ok+fail==total)finish()}}));transaction.onerror=onerror};openRequest.onerror=onerror})};var SYSCALLS={DEFAULT_POLLMASK:5,mappings:{},umask:511,calculateAt:(function(dirfd,path){if(path[0]!=="/"){var dir;if(dirfd===-100){dir=FS.cwd()}else{var dirstream=FS.getStream(dirfd);if(!dirstream)throw new FS.ErrnoError(ERRNO_CODES.EBADF);dir=dirstream.path}path=PATH.join2(dir,path)}return path}),doStat:(function(func,path,buf){try{var stat=func(path)}catch(e){if(e&&e.node&&PATH.normalize(path)!==PATH.normalize(FS.getPath(e.node))){return-ERRNO_CODES.ENOTDIR}throw e}HEAP32[buf>>2]=stat.dev;HEAP32[buf+4>>2]=0;HEAP32[buf+8>>2]=stat.ino;HEAP32[buf+12>>2]=stat.mode;HEAP32[buf+16>>2]=stat.nlink;HEAP32[buf+20>>2]=stat.uid;HEAP32[buf+24>>2]=stat.gid;HEAP32[buf+28>>2]=stat.rdev;HEAP32[buf+32>>2]=0;HEAP32[buf+36>>2]=stat.size;HEAP32[buf+40>>2]=4096;HEAP32[buf+44>>2]=stat.blocks;HEAP32[buf+48>>2]=stat.atime.getTime()/1e3|0;HEAP32[buf+52>>2]=0;HEAP32[buf+56>>2]=stat.mtime.getTime()/1e3|0;HEAP32[buf+60>>2]=0;HEAP32[buf+64>>2]=stat.ctime.getTime()/1e3|0;HEAP32[buf+68>>2]=0;HEAP32[buf+72>>2]=stat.ino;return 0}),doMsync:(function(addr,stream,len,flags){var buffer=new Uint8Array(HEAPU8.subarray(addr,addr+len));FS.msync(stream,buffer,0,len,flags)}),doMkdir:(function(path,mode){path=PATH.normalize(path);if(path[path.length-1]==="/")path=path.substr(0,path.length-1);FS.mkdir(path,mode,0);return 0}),doMknod:(function(path,mode,dev){switch(mode&61440){case 32768:case 8192:case 24576:case 4096:case 49152:break;default:return-ERRNO_CODES.EINVAL}FS.mknod(path,mode,dev);return 0}),doReadlink:(function(path,buf,bufsize){if(bufsize<=0)return-ERRNO_CODES.EINVAL;var ret=FS.readlink(path);ret=ret.slice(0,Math.max(0,bufsize));writeStringToMemory(ret,buf,true);return ret.length}),doAccess:(function(path,amode){if(amode&~7){return-ERRNO_CODES.EINVAL}var node;var lookup=FS.lookupPath(path,{follow:true});node=lookup.node;var perms="";if(amode&4)perms+="r";if(amode&2)perms+="w";if(amode&1)perms+="x";if(perms&&FS.nodePermissions(node,perms)){return-ERRNO_CODES.EACCES}return 0}),doDup:(function(path,flags,suggestFD){var suggest=FS.getStream(suggestFD);if(suggest)FS.close(suggest);return FS.open(path,flags,0,suggestFD,suggestFD).fd}),doReadv:(function(stream,iov,iovcnt,offset){var ret=0;for(var i=0;i<iovcnt;i++){var ptr=HEAP32[iov+i*8>>2];var len=HEAP32[iov+(i*8+4)>>2];var curr=FS.read(stream,HEAP8,ptr,len,offset);if(curr<0)return-1;ret+=curr;if(curr<len)break}return ret}),doWritev:(function(stream,iov,iovcnt,offset){var ret=0;for(var i=0;i<iovcnt;i++){var ptr=HEAP32[iov+i*8>>2];var len=HEAP32[iov+(i*8+4)>>2];var curr=FS.write(stream,HEAP8,ptr,len,offset);if(curr<0)return-1;ret+=curr}return ret}),varargs:0,get:(function(varargs){SYSCALLS.varargs+=4;var ret=HEAP32[SYSCALLS.varargs-4>>2];return ret}),getStr:(function(){var ret=Pointer_stringify(SYSCALLS.get());return ret}),getStreamFromFD:(function(){var stream=FS.getStream(SYSCALLS.get());if(!stream)throw new FS.ErrnoError(ERRNO_CODES.EBADF);return stream}),getSocketFromFD:(function(){var socket=SOCKFS.getSocket(SYSCALLS.get());if(!socket)throw new FS.ErrnoError(ERRNO_CODES.EBADF);return socket}),getSocketAddress:(function(allowNull){var addrp=SYSCALLS.get(),addrlen=SYSCALLS.get();if(allowNull&&addrp===0)return null;var info=__read_sockaddr(addrp,addrlen);if(info.errno)throw new FS.ErrnoError(info.errno);info.addr=DNS.lookup_addr(info.addr)||info.addr;return info}),get64:(function(){var low=SYSCALLS.get(),high=SYSCALLS.get();if(low>=0)assert(high===0);else assert(high===-1);return low}),getZero:(function(){assert(SYSCALLS.get()===0)})};function ___syscall6(which,varargs){SYSCALLS.varargs=varargs;try{var stream=SYSCALLS.getStreamFromFD();FS.close(stream);return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return-e.errno}}Module["_i64Add"]=_i64Add;function _sbrk(bytes){var self=_sbrk;if(!self.called){DYNAMICTOP=alignMemoryPage(DYNAMICTOP);self.called=true;assert(Runtime.dynamicAlloc);self.alloc=Runtime.dynamicAlloc;Runtime.dynamicAlloc=(function(){abort("cannot dynamically allocate, sbrk now has control")})}var ret=DYNAMICTOP;if(bytes!=0){var success=self.alloc(bytes);if(!success)return-1>>>0}return ret}function ___syscall146(which,varargs){SYSCALLS.varargs=varargs;try{var stream=SYSCALLS.getStreamFromFD(),iov=SYSCALLS.get(),iovcnt=SYSCALLS.get();return SYSCALLS.doWritev(stream,iov,iovcnt)}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return-e.errno}}function _emscripten_memcpy_big(dest,src,num){HEAPU8.set(HEAPU8.subarray(src,src+num),dest);return dest}Module["_memcpy"]=_memcpy;function ___lock(){}function _emscripten_set_main_loop_timing(mode,value){Browser.mainLoop.timingMode=mode;Browser.mainLoop.timingValue=value;if(!Browser.mainLoop.func){return 1}if(mode==0){Browser.mainLoop.scheduler=function Browser_mainLoop_scheduler_setTimeout(){setTimeout(Browser.mainLoop.runner,value)};Browser.mainLoop.method="timeout"}else if(mode==1){Browser.mainLoop.scheduler=function Browser_mainLoop_scheduler_rAF(){Browser.requestAnimationFrame(Browser.mainLoop.runner)};Browser.mainLoop.method="rAF"}else if(mode==2){if(!window["setImmediate"]){var setImmediates=[];var emscriptenMainLoopMessageId="__emcc";function Browser_setImmediate_messageHandler(event){if(event.source===window&&event.data===emscriptenMainLoopMessageId){event.stopPropagation();setImmediates.shift()()}}window.addEventListener("message",Browser_setImmediate_messageHandler,true);window["setImmediate"]=function Browser_emulated_setImmediate(func){setImmediates.push(func);window.postMessage(emscriptenMainLoopMessageId,"*")}}Browser.mainLoop.scheduler=function Browser_mainLoop_scheduler_setImmediate(){window["setImmediate"](Browser.mainLoop.runner)};Browser.mainLoop.method="immediate"}return 0}function _emscripten_set_main_loop(func,fps,simulateInfiniteLoop,arg,noSetTiming){Module["noExitRuntime"]=true;assert(!Browser.mainLoop.func,"emscripten_set_main_loop: there can only be one main loop function at once: call emscripten_cancel_main_loop to cancel the previous one before setting a new one with different parameters.");Browser.mainLoop.func=func;Browser.mainLoop.arg=arg;var thisMainLoopId=Browser.mainLoop.currentlyRunningMainloop;Browser.mainLoop.runner=function Browser_mainLoop_runner(){if(ABORT)return;if(Browser.mainLoop.queue.length>0){var start=Date.now();var blocker=Browser.mainLoop.queue.shift();blocker.func(blocker.arg);if(Browser.mainLoop.remainingBlockers){var remaining=Browser.mainLoop.remainingBlockers;var next=remaining%1==0?remaining-1:Math.floor(remaining);if(blocker.counted){Browser.mainLoop.remainingBlockers=next}else{next=next+.5;Browser.mainLoop.remainingBlockers=(8*remaining+next)/9}}console.log('main loop blocker "'+blocker.name+'" took '+(Date.now()-start)+" ms");Browser.mainLoop.updateStatus();setTimeout(Browser.mainLoop.runner,0);return}if(thisMainLoopId<Browser.mainLoop.currentlyRunningMainloop)return;Browser.mainLoop.currentFrameNumber=Browser.mainLoop.currentFrameNumber+1|0;if(Browser.mainLoop.timingMode==1&&Browser.mainLoop.timingValue>1&&Browser.mainLoop.currentFrameNumber%Browser.mainLoop.timingValue!=0){Browser.mainLoop.scheduler();return}if(Browser.mainLoop.method==="timeout"&&Module.ctx){Module.printErr("Looks like you are rendering without using requestAnimationFrame for the main loop. You should use 0 for the frame rate in emscripten_set_main_loop in order to use requestAnimationFrame, as that can greatly improve your frame rates!");Browser.mainLoop.method=""}Browser.mainLoop.runIter((function(){if(typeof arg!=="undefined"){Runtime.dynCall("vi",func,[arg])}else{Runtime.dynCall("v",func)}}));if(thisMainLoopId<Browser.mainLoop.currentlyRunningMainloop)return;if(typeof SDL==="object"&&SDL.audio&&SDL.audio.queueNewAudioData)SDL.audio.queueNewAudioData();Browser.mainLoop.scheduler()};if(!noSetTiming){if(fps&&fps>0)_emscripten_set_main_loop_timing(0,1e3/fps);else _emscripten_set_main_loop_timing(1,1);Browser.mainLoop.scheduler()}if(simulateInfiniteLoop){throw"SimulateInfiniteLoop"}}var Browser={mainLoop:{scheduler:null,method:"",currentlyRunningMainloop:0,func:null,arg:0,timingMode:0,timingValue:0,currentFrameNumber:0,queue:[],pause:(function(){Browser.mainLoop.scheduler=null;Browser.mainLoop.currentlyRunningMainloop++}),resume:(function(){Browser.mainLoop.currentlyRunningMainloop++;var timingMode=Browser.mainLoop.timingMode;var timingValue=Browser.mainLoop.timingValue;var func=Browser.mainLoop.func;Browser.mainLoop.func=null;_emscripten_set_main_loop(func,0,false,Browser.mainLoop.arg,true);_emscripten_set_main_loop_timing(timingMode,timingValue);Browser.mainLoop.scheduler()}),updateStatus:(function(){if(Module["setStatus"]){var message=Module["statusMessage"]||"Please wait...";var remaining=Browser.mainLoop.remainingBlockers;var expected=Browser.mainLoop.expectedBlockers;if(remaining){if(remaining<expected){Module["setStatus"](message+" ("+(expected-remaining)+"/"+expected+")")}else{Module["setStatus"](message)}}else{Module["setStatus"]("")}}}),runIter:(function(func){if(ABORT)return;if(Module["preMainLoop"]){var preRet=Module["preMainLoop"]();if(preRet===false){return}}try{func()}catch(e){if(e instanceof ExitStatus){return}else{if(e&&typeof e==="object"&&e.stack)Module.printErr("exception thrown: "+[e,e.stack]);throw e}}if(Module["postMainLoop"])Module["postMainLoop"]()})},isFullScreen:false,pointerLock:false,moduleContextCreatedCallbacks:[],workers:[],init:(function(){if(!Module["preloadPlugins"])Module["preloadPlugins"]=[];if(Browser.initted)return;Browser.initted=true;try{new Blob;Browser.hasBlobConstructor=true}catch(e){Browser.hasBlobConstructor=false;console.log("warning: no blob constructor, cannot create blobs with mimetypes")}Browser.BlobBuilder=typeof MozBlobBuilder!="undefined"?MozBlobBuilder:typeof WebKitBlobBuilder!="undefined"?WebKitBlobBuilder:!Browser.hasBlobConstructor?console.log("warning: no BlobBuilder"):null;Browser.URLObject=typeof window!="undefined"?window.URL?window.URL:window.webkitURL:undefined;if(!Module.noImageDecoding&&typeof Browser.URLObject==="undefined"){console.log("warning: Browser does not support creating object URLs. Built-in browser image decoding will not be available.");Module.noImageDecoding=true}var imagePlugin={};imagePlugin["canHandle"]=function imagePlugin_canHandle(name){return!Module.noImageDecoding&&/\.(jpg|jpeg|png|bmp)$/i.test(name)};imagePlugin["handle"]=function imagePlugin_handle(byteArray,name,onload,onerror){var b=null;if(Browser.hasBlobConstructor){try{b=new Blob([byteArray],{type:Browser.getMimetype(name)});if(b.size!==byteArray.length){b=new Blob([(new Uint8Array(byteArray)).buffer],{type:Browser.getMimetype(name)})}}catch(e){Runtime.warnOnce("Blob constructor present but fails: "+e+"; falling back to blob builder")}}if(!b){var bb=new Browser.BlobBuilder;bb.append((new Uint8Array(byteArray)).buffer);b=bb.getBlob()}var url=Browser.URLObject.createObjectURL(b);var img=new Image;img.onload=function img_onload(){assert(img.complete,"Image "+name+" could not be decoded");var canvas=document.createElement("canvas");canvas.width=img.width;canvas.height=img.height;var ctx=canvas.getContext("2d");ctx.drawImage(img,0,0);Module["preloadedImages"][name]=canvas;Browser.URLObject.revokeObjectURL(url);if(onload)onload(byteArray)};img.onerror=function img_onerror(event){console.log("Image "+url+" could not be decoded");if(onerror)onerror()};img.src=url};Module["preloadPlugins"].push(imagePlugin);var audioPlugin={};audioPlugin["canHandle"]=function audioPlugin_canHandle(name){return!Module.noAudioDecoding&&name.substr(-4)in{".ogg":1,".wav":1,".mp3":1}};audioPlugin["handle"]=function audioPlugin_handle(byteArray,name,onload,onerror){var done=false;function finish(audio){if(done)return;done=true;Module["preloadedAudios"][name]=audio;if(onload)onload(byteArray)}function fail(){if(done)return;done=true;Module["preloadedAudios"][name]=new Audio;if(onerror)onerror()}if(Browser.hasBlobConstructor){try{var b=new Blob([byteArray],{type:Browser.getMimetype(name)})}catch(e){return fail()}var url=Browser.URLObject.createObjectURL(b);var audio=new Audio;audio.addEventListener("canplaythrough",(function(){finish(audio)}),false);audio.onerror=function audio_onerror(event){if(done)return;console.log("warning: browser could not fully decode audio "+name+", trying slower base64 approach");function encode64(data){var BASE="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";var PAD="=";var ret="";var leftchar=0;var leftbits=0;for(var i=0;i<data.length;i++){leftchar=leftchar<<8|data[i];leftbits+=8;while(leftbits>=6){var curr=leftchar>>leftbits-6&63;leftbits-=6;ret+=BASE[curr]}}if(leftbits==2){ret+=BASE[(leftchar&3)<<4];ret+=PAD+PAD}else if(leftbits==4){ret+=BASE[(leftchar&15)<<2];ret+=PAD}return ret}audio.src="data:audio/x-"+name.substr(-3)+";base64,"+encode64(byteArray);finish(audio)};audio.src=url;Browser.safeSetTimeout((function(){finish(audio)}),1e4)}else{return fail()}};Module["preloadPlugins"].push(audioPlugin);var canvas=Module["canvas"];function pointerLockChange(){Browser.pointerLock=document["pointerLockElement"]===canvas||document["mozPointerLockElement"]===canvas||document["webkitPointerLockElement"]===canvas||document["msPointerLockElement"]===canvas}if(canvas){canvas.requestPointerLock=canvas["requestPointerLock"]||canvas["mozRequestPointerLock"]||canvas["webkitRequestPointerLock"]||canvas["msRequestPointerLock"]||(function(){});canvas.exitPointerLock=document["exitPointerLock"]||document["mozExitPointerLock"]||document["webkitExitPointerLock"]||document["msExitPointerLock"]||(function(){});canvas.exitPointerLock=canvas.exitPointerLock.bind(document);document.addEventListener("pointerlockchange",pointerLockChange,false);document.addEventListener("mozpointerlockchange",pointerLockChange,false);document.addEventListener("webkitpointerlockchange",pointerLockChange,false);document.addEventListener("mspointerlockchange",pointerLockChange,false);if(Module["elementPointerLock"]){canvas.addEventListener("click",(function(ev){if(!Browser.pointerLock&&canvas.requestPointerLock){canvas.requestPointerLock();ev.preventDefault()}}),false)}}}),createContext:(function(canvas,useWebGL,setInModule,webGLContextAttributes){if(useWebGL&&Module.ctx&&canvas==Module.canvas)return Module.ctx;var ctx;var contextHandle;if(useWebGL){var contextAttributes={antialias:false,alpha:false};if(webGLContextAttributes){for(var attribute in webGLContextAttributes){contextAttributes[attribute]=webGLContextAttributes[attribute]}}contextHandle=GL.createContext(canvas,contextAttributes);if(contextHandle){ctx=GL.getContext(contextHandle).GLctx}canvas.style.backgroundColor="black"}else{ctx=canvas.getContext("2d")}if(!ctx)return null;if(setInModule){if(!useWebGL)assert(typeof GLctx==="undefined","cannot set in module if GLctx is used, but we are a non-GL context that would replace it");Module.ctx=ctx;if(useWebGL)GL.makeContextCurrent(contextHandle);Module.useWebGL=useWebGL;Browser.moduleContextCreatedCallbacks.forEach((function(callback){callback()}));Browser.init()}return ctx}),destroyContext:(function(canvas,useWebGL,setInModule){}),fullScreenHandlersInstalled:false,lockPointer:undefined,resizeCanvas:undefined,requestFullScreen:(function(lockPointer,resizeCanvas,vrDevice){Browser.lockPointer=lockPointer;Browser.resizeCanvas=resizeCanvas;Browser.vrDevice=vrDevice;if(typeof Browser.lockPointer==="undefined")Browser.lockPointer=true;if(typeof Browser.resizeCanvas==="undefined")Browser.resizeCanvas=false;if(typeof Browser.vrDevice==="undefined")Browser.vrDevice=null;var canvas=Module["canvas"];function fullScreenChange(){Browser.isFullScreen=false;var canvasContainer=canvas.parentNode;if((document["webkitFullScreenElement"]||document["webkitFullscreenElement"]||document["mozFullScreenElement"]||document["mozFullscreenElement"]||document["fullScreenElement"]||document["fullscreenElement"]||document["msFullScreenElement"]||document["msFullscreenElement"]||document["webkitCurrentFullScreenElement"])===canvasContainer){canvas.cancelFullScreen=document["cancelFullScreen"]||document["mozCancelFullScreen"]||document["webkitCancelFullScreen"]||document["msExitFullscreen"]||document["exitFullscreen"]||(function(){});canvas.cancelFullScreen=canvas.cancelFullScreen.bind(document);if(Browser.lockPointer)canvas.requestPointerLock();Browser.isFullScreen=true;if(Browser.resizeCanvas)Browser.setFullScreenCanvasSize()}else{canvasContainer.parentNode.insertBefore(canvas,canvasContainer);canvasContainer.parentNode.removeChild(canvasContainer);if(Browser.resizeCanvas)Browser.setWindowedCanvasSize()}if(Module["onFullScreen"])Module["onFullScreen"](Browser.isFullScreen);Browser.updateCanvasDimensions(canvas)}if(!Browser.fullScreenHandlersInstalled){Browser.fullScreenHandlersInstalled=true;document.addEventListener("fullscreenchange",fullScreenChange,false);document.addEventListener("mozfullscreenchange",fullScreenChange,false);document.addEventListener("webkitfullscreenchange",fullScreenChange,false);document.addEventListener("MSFullscreenChange",fullScreenChange,false)}var canvasContainer=document.createElement("div");canvas.parentNode.insertBefore(canvasContainer,canvas);canvasContainer.appendChild(canvas);canvasContainer.requestFullScreen=canvasContainer["requestFullScreen"]||canvasContainer["mozRequestFullScreen"]||canvasContainer["msRequestFullscreen"]||(canvasContainer["webkitRequestFullScreen"]?(function(){canvasContainer["webkitRequestFullScreen"](Element["ALLOW_KEYBOARD_INPUT"])}):null);if(vrDevice){canvasContainer.requestFullScreen({vrDisplay:vrDevice})}else{canvasContainer.requestFullScreen()}}),nextRAF:0,fakeRequestAnimationFrame:(function(func){var now=Date.now();if(Browser.nextRAF===0){Browser.nextRAF=now+1e3/60}else{while(now+2>=Browser.nextRAF){Browser.nextRAF+=1e3/60}}var delay=Math.max(Browser.nextRAF-now,0);setTimeout(func,delay)}),requestAnimationFrame:function requestAnimationFrame(func){if(typeof window==="undefined"){Browser.fakeRequestAnimationFrame(func)}else{if(!window.requestAnimationFrame){window.requestAnimationFrame=window["requestAnimationFrame"]||window["mozRequestAnimationFrame"]||window["webkitRequestAnimationFrame"]||window["msRequestAnimationFrame"]||window["oRequestAnimationFrame"]||Browser.fakeRequestAnimationFrame}window.requestAnimationFrame(func)}},safeCallback:(function(func){return(function(){if(!ABORT)return func.apply(null,arguments)})}),allowAsyncCallbacks:true,queuedAsyncCallbacks:[],pauseAsyncCallbacks:(function(){Browser.allowAsyncCallbacks=false}),resumeAsyncCallbacks:(function(){Browser.allowAsyncCallbacks=true;if(Browser.queuedAsyncCallbacks.length>0){var callbacks=Browser.queuedAsyncCallbacks;Browser.queuedAsyncCallbacks=[];callbacks.forEach((function(func){func()}))}}),safeRequestAnimationFrame:(function(func){return Browser.requestAnimationFrame((function(){if(ABORT)return;if(Browser.allowAsyncCallbacks){func()}else{Browser.queuedAsyncCallbacks.push(func)}}))}),safeSetTimeout:(function(func,timeout){Module["noExitRuntime"]=true;return setTimeout((function(){if(ABORT)return;if(Browser.allowAsyncCallbacks){func()}else{Browser.queuedAsyncCallbacks.push(func)}}),timeout)}),safeSetInterval:(function(func,timeout){Module["noExitRuntime"]=true;return setInterval((function(){if(ABORT)return;if(Browser.allowAsyncCallbacks){func()}}),timeout)}),getMimetype:(function(name){return{"jpg":"image/jpeg","jpeg":"image/jpeg","png":"image/png","bmp":"image/bmp","ogg":"audio/ogg","wav":"audio/wav","mp3":"audio/mpeg"}[name.substr(name.lastIndexOf(".")+1)]}),getUserMedia:(function(func){if(!window.getUserMedia){window.getUserMedia=navigator["getUserMedia"]||navigator["mozGetUserMedia"]}window.getUserMedia(func)}),getMovementX:(function(event){return event["movementX"]||event["mozMovementX"]||event["webkitMovementX"]||0}),getMovementY:(function(event){return event["movementY"]||event["mozMovementY"]||event["webkitMovementY"]||0}),getMouseWheelDelta:(function(event){var delta=0;switch(event.type){case"DOMMouseScroll":delta=event.detail;break;case"mousewheel":delta=event.wheelDelta;break;case"wheel":delta=event["deltaY"];break;default:throw"unrecognized mouse wheel event: "+event.type}return delta}),mouseX:0,mouseY:0,mouseMovementX:0,mouseMovementY:0,touches:{},lastTouches:{},calculateMouseEvent:(function(event){if(Browser.pointerLock){if(event.type!="mousemove"&&"mozMovementX"in event){Browser.mouseMovementX=Browser.mouseMovementY=0}else{Browser.mouseMovementX=Browser.getMovementX(event);Browser.mouseMovementY=Browser.getMovementY(event)}if(typeof SDL!="undefined"){Browser.mouseX=SDL.mouseX+Browser.mouseMovementX;Browser.mouseY=SDL.mouseY+Browser.mouseMovementY}else{Browser.mouseX+=Browser.mouseMovementX;Browser.mouseY+=Browser.mouseMovementY}}else{var rect=Module["canvas"].getBoundingClientRect();var cw=Module["canvas"].width;var ch=Module["canvas"].height;var scrollX=typeof window.scrollX!=="undefined"?window.scrollX:window.pageXOffset;var scrollY=typeof window.scrollY!=="undefined"?window.scrollY:window.pageYOffset;if(event.type==="touchstart"||event.type==="touchend"||event.type==="touchmove"){var touch=event.touch;if(touch===undefined){return}var adjustedX=touch.pageX-(scrollX+rect.left);var adjustedY=touch.pageY-(scrollY+rect.top);adjustedX=adjustedX*(cw/rect.width);adjustedY=adjustedY*(ch/rect.height);var coords={x:adjustedX,y:adjustedY};if(event.type==="touchstart"){Browser.lastTouches[touch.identifier]=coords;Browser.touches[touch.identifier]=coords}else if(event.type==="touchend"||event.type==="touchmove"){var last=Browser.touches[touch.identifier];if(!last)last=coords;Browser.lastTouches[touch.identifier]=last;Browser.touches[touch.identifier]=coords}return}var x=event.pageX-(scrollX+rect.left);var y=event.pageY-(scrollY+rect.top);x=x*(cw/rect.width);y=y*(ch/rect.height);Browser.mouseMovementX=x-Browser.mouseX;Browser.mouseMovementY=y-Browser.mouseY;Browser.mouseX=x;Browser.mouseY=y}}),xhrLoad:(function(url,onload,onerror){var xhr=new XMLHttpRequest;xhr.open("GET",url,true);xhr.responseType="arraybuffer";xhr.onload=function xhr_onload(){if(xhr.status==200||xhr.status==0&&xhr.response){onload(xhr.response)}else{onerror()}};xhr.onerror=onerror;xhr.send(null)}),asyncLoad:(function(url,onload,onerror,noRunDep){Browser.xhrLoad(url,(function(arrayBuffer){assert(arrayBuffer,'Loading data file "'+url+'" failed (no arrayBuffer).');onload(new Uint8Array(arrayBuffer));if(!noRunDep)removeRunDependency("al "+url)}),(function(event){if(onerror){onerror()}else{throw'Loading data file "'+url+'" failed.'}}));if(!noRunDep)addRunDependency("al "+url)}),resizeListeners:[],updateResizeListeners:(function(){var canvas=Module["canvas"];Browser.resizeListeners.forEach((function(listener){listener(canvas.width,canvas.height)}))}),setCanvasSize:(function(width,height,noUpdates){var canvas=Module["canvas"];Browser.updateCanvasDimensions(canvas,width,height);if(!noUpdates)Browser.updateResizeListeners()}),windowedWidth:0,windowedHeight:0,setFullScreenCanvasSize:(function(){if(typeof SDL!="undefined"){var flags=HEAPU32[SDL.screen+Runtime.QUANTUM_SIZE*0>>2];flags=flags|8388608;HEAP32[SDL.screen+Runtime.QUANTUM_SIZE*0>>2]=flags}Browser.updateResizeListeners()}),setWindowedCanvasSize:(function(){if(typeof SDL!="undefined"){var flags=HEAPU32[SDL.screen+Runtime.QUANTUM_SIZE*0>>2];flags=flags&~8388608;HEAP32[SDL.screen+Runtime.QUANTUM_SIZE*0>>2]=flags}Browser.updateResizeListeners()}),updateCanvasDimensions:(function(canvas,wNative,hNative){if(wNative&&hNative){canvas.widthNative=wNative;canvas.heightNative=hNative}else{wNative=canvas.widthNative;hNative=canvas.heightNative}var w=wNative;var h=hNative;if(Module["forcedAspectRatio"]&&Module["forcedAspectRatio"]>0){if(w/h<Module["forcedAspectRatio"]){w=Math.round(h*Module["forcedAspectRatio"])}else{h=Math.round(w/Module["forcedAspectRatio"])}}if((document["webkitFullScreenElement"]||document["webkitFullscreenElement"]||document["mozFullScreenElement"]||document["mozFullscreenElement"]||document["fullScreenElement"]||document["fullscreenElement"]||document["msFullScreenElement"]||document["msFullscreenElement"]||document["webkitCurrentFullScreenElement"])===canvas.parentNode&&typeof screen!="undefined"){var factor=Math.min(screen.width/w,screen.height/h);w=Math.round(w*factor);h=Math.round(h*factor)}if(Browser.resizeCanvas){if(canvas.width!=w)canvas.width=w;if(canvas.height!=h)canvas.height=h;if(typeof canvas.style!="undefined"){canvas.style.removeProperty("width");canvas.style.removeProperty("height")}}else{if(canvas.width!=wNative)canvas.width=wNative;if(canvas.height!=hNative)canvas.height=hNative;if(typeof canvas.style!="undefined"){if(w!=wNative||h!=hNative){canvas.style.setProperty("width",w+"px","important");canvas.style.setProperty("height",h+"px","important")}else{canvas.style.removeProperty("width");canvas.style.removeProperty("height")}}}}),wgetRequests:{},nextWgetRequestHandle:0,getNextWgetRequestHandle:(function(){var handle=Browser.nextWgetRequestHandle;Browser.nextWgetRequestHandle++;return handle})};function _time(ptr){var ret=Date.now()/1e3|0;if(ptr){HEAP32[ptr>>2]=ret}return ret}function _pthread_self(){return 0}function ___syscall140(which,varargs){SYSCALLS.varargs=varargs;try{var stream=SYSCALLS.getStreamFromFD(),offset_high=SYSCALLS.get(),offset_low=SYSCALLS.get(),result=SYSCALLS.get(),whence=SYSCALLS.get();var offset=offset_low;assert(offset_high===0);FS.llseek(stream,offset,whence);HEAP32[result>>2]=stream.position;if(stream.getdents&&offset===0&&whence===0)stream.getdents=null;return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return-e.errno}}function _malloc(bytes){var ptr=Runtime.dynamicAlloc(bytes+8);return ptr+8&4294967288}Module["_malloc"]=_malloc;function ___cxa_allocate_exception(size){return _malloc(size)}function ___syscall54(which,varargs){SYSCALLS.varargs=varargs;try{var stream=SYSCALLS.getStreamFromFD(),op=SYSCALLS.get();switch(op){case 21505:{if(!stream.tty)return-ERRNO_CODES.ENOTTY;return 0};case 21506:{if(!stream.tty)return-ERRNO_CODES.ENOTTY;return 0};case 21519:{if(!stream.tty)return-ERRNO_CODES.ENOTTY;var argp=SYSCALLS.get();HEAP32[argp>>2]=0;return 0};case 21520:{if(!stream.tty)return-ERRNO_CODES.ENOTTY;return-ERRNO_CODES.EINVAL};case 21531:{var argp=SYSCALLS.get();return FS.ioctl(stream,op,argp)};default:abort("bad ioctl syscall "+op)}}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return-e.errno}}FS.staticInit();__ATINIT__.unshift((function(){if(!Module["noFSInit"]&&!FS.init.initialized)FS.init()}));__ATMAIN__.push((function(){FS.ignorePermissions=false}));__ATEXIT__.push((function(){FS.quit()}));Module["FS_createFolder"]=FS.createFolder;Module["FS_createPath"]=FS.createPath;Module["FS_createDataFile"]=FS.createDataFile;Module["FS_createPreloadedFile"]=FS.createPreloadedFile;Module["FS_createLazyFile"]=FS.createLazyFile;Module["FS_createLink"]=FS.createLink;Module["FS_createDevice"]=FS.createDevice;Module["FS_unlink"]=FS.unlink;__ATINIT__.unshift((function(){TTY.init()}));__ATEXIT__.push((function(){TTY.shutdown()}));if(ENVIRONMENT_IS_NODE){var fs=require("fs");var NODEJS_PATH=require("path");NODEFS.staticInit()}Module["requestFullScreen"]=function Module_requestFullScreen(lockPointer,resizeCanvas,vrDevice){Browser.requestFullScreen(lockPointer,resizeCanvas,vrDevice)};Module["requestAnimationFrame"]=function Module_requestAnimationFrame(func){Browser.requestAnimationFrame(func)};Module["setCanvasSize"]=function Module_setCanvasSize(width,height,noUpdates){Browser.setCanvasSize(width,height,noUpdates)};Module["pauseMainLoop"]=function Module_pauseMainLoop(){Browser.mainLoop.pause()};Module["resumeMainLoop"]=function Module_resumeMainLoop(){Browser.mainLoop.resume()};Module["getUserMedia"]=function Module_getUserMedia(){Browser.getUserMedia()};Module["createContext"]=function Module_createContext(canvas,useWebGL,setInModule,webGLContextAttributes){return Browser.createContext(canvas,useWebGL,setInModule,webGLContextAttributes)};STACK_BASE=STACKTOP=Runtime.alignMemory(STATICTOP);staticSealed=true;STACK_MAX=STACK_BASE+TOTAL_STACK;DYNAMIC_BASE=DYNAMICTOP=Runtime.alignMemory(STACK_MAX);assert(DYNAMIC_BASE<TOTAL_MEMORY,"TOTAL_MEMORY not big enough for stack");var cttz_i8=allocate([8,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,7,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0],"i8",ALLOC_DYNAMIC);function invoke_iiii(index,a1,a2,a3){try{return Module["dynCall_iiii"](index,a1,a2,a3)}catch(e){if(typeof e!=="number"&&e!=="longjmp")throw e;asm["setThrew"](1,0)}}function invoke_viiiii(index,a1,a2,a3,a4,a5){try{Module["dynCall_viiiii"](index,a1,a2,a3,a4,a5)}catch(e){if(typeof e!=="number"&&e!=="longjmp")throw e;asm["setThrew"](1,0)}}function invoke_vi(index,a1){try{Module["dynCall_vi"](index,a1)}catch(e){if(typeof e!=="number"&&e!=="longjmp")throw e;asm["setThrew"](1,0)}}function invoke_ii(index,a1){try{return Module["dynCall_ii"](index,a1)}catch(e){if(typeof e!=="number"&&e!=="longjmp")throw e;asm["setThrew"](1,0)}}function invoke_viii(index,a1,a2,a3){try{Module["dynCall_viii"](index,a1,a2,a3)}catch(e){if(typeof e!=="number"&&e!=="longjmp")throw e;asm["setThrew"](1,0)}}function invoke_v(index){try{Module["dynCall_v"](index)}catch(e){if(typeof e!=="number"&&e!=="longjmp")throw e;asm["setThrew"](1,0)}}function invoke_viiiiii(index,a1,a2,a3,a4,a5,a6){try{Module["dynCall_viiiiii"](index,a1,a2,a3,a4,a5,a6)}catch(e){if(typeof e!=="number"&&e!=="longjmp")throw e;asm["setThrew"](1,0)}}function invoke_viiii(index,a1,a2,a3,a4){try{Module["dynCall_viiii"](index,a1,a2,a3,a4)}catch(e){if(typeof e!=="number"&&e!=="longjmp")throw e;asm["setThrew"](1,0)}}Module.asmGlobalArg={"Math":Math,"Int8Array":Int8Array,"Int16Array":Int16Array,"Int32Array":Int32Array,"Uint8Array":Uint8Array,"Uint16Array":Uint16Array,"Uint32Array":Uint32Array,"Float32Array":Float32Array,"Float64Array":Float64Array,"NaN":NaN,"Infinity":Infinity};Module.asmLibraryArg={"abort":abort,"assert":assert,"invoke_iiii":invoke_iiii,"invoke_viiiii":invoke_viiiii,"invoke_vi":invoke_vi,"invoke_ii":invoke_ii,"invoke_viii":invoke_viii,"invoke_v":invoke_v,"invoke_viiiiii":invoke_viiiiii,"invoke_viiii":invoke_viiii,"_pthread_cleanup_pop":_pthread_cleanup_pop,"___syscall54":___syscall54,"___syscall6":___syscall6,"___setErrNo":___setErrNo,"___assert_fail":___assert_fail,"___cxa_allocate_exception":___cxa_allocate_exception,"___cxa_find_matching_catch":___cxa_find_matching_catch,"_emscripten_set_main_loop_timing":_emscripten_set_main_loop_timing,"_fabsf":_fabsf,"_sbrk":_sbrk,"_emscripten_memcpy_big":_emscripten_memcpy_big,"___resumeException":___resumeException,"__ZSt18uncaught_exceptionv":__ZSt18uncaught_exceptionv,"_sysconf":_sysconf,"_pthread_self":_pthread_self,"_sqrtf":_sqrtf,"___unlock":___unlock,"_emscripten_set_main_loop":_emscripten_set_main_loop,"___cxa_throw":___cxa_throw,"___lock":___lock,"_abort":_abort,"_pthread_cleanup_push":_pthread_cleanup_push,"_time":_time,"___syscall140":___syscall140,"___syscall146":___syscall146,"STACKTOP":STACKTOP,"STACK_MAX":STACK_MAX,"tempDoublePtr":tempDoublePtr,"ABORT":ABORT,"cttz_i8":cttz_i8};// EMSCRIPTEN_START_ASM
-var asm=(function(global,env,buffer) {
-"use asm";var a=new global.Int8Array(buffer);var b=new global.Int16Array(buffer);var c=new global.Int32Array(buffer);var d=new global.Uint8Array(buffer);var e=new global.Uint16Array(buffer);var f=new global.Uint32Array(buffer);var g=new global.Float32Array(buffer);var h=new global.Float64Array(buffer);var i=env.STACKTOP|0;var j=env.STACK_MAX|0;var k=env.tempDoublePtr|0;var l=env.ABORT|0;var m=env.cttz_i8|0;var n=0;var o=0;var p=0;var q=0;var r=global.NaN,s=global.Infinity;var t=0,u=0,v=0,w=0,x=0.0,y=0,z=0,A=0,B=0.0;var C=0;var D=0;var E=0;var F=0;var G=0;var H=0;var I=0;var J=0;var K=0;var L=0;var M=global.Math.floor;var N=global.Math.abs;var O=global.Math.sqrt;var P=global.Math.pow;var Q=global.Math.cos;var R=global.Math.sin;var S=global.Math.tan;var T=global.Math.acos;var U=global.Math.asin;var V=global.Math.atan;var W=global.Math.atan2;var X=global.Math.exp;var Y=global.Math.log;var Z=global.Math.ceil;var _=global.Math.imul;var $=global.Math.min;var aa=global.Math.clz32;var ba=env.abort;var ca=env.assert;var da=env.invoke_iiii;var ea=env.invoke_viiiii;var fa=env.invoke_vi;var ga=env.invoke_ii;var ha=env.invoke_viii;var ia=env.invoke_v;var ja=env.invoke_viiiiii;var ka=env.invoke_viiii;var la=env._pthread_cleanup_pop;var ma=env.___syscall54;var na=env.___syscall6;var oa=env.___setErrNo;var pa=env.___assert_fail;var qa=env.___cxa_allocate_exception;var ra=env.___cxa_find_matching_catch;var sa=env._emscripten_set_main_loop_timing;var ta=env._fabsf;var ua=env._sbrk;var va=env._emscripten_memcpy_big;var wa=env.___resumeException;var xa=env.__ZSt18uncaught_exceptionv;var ya=env._sysconf;var za=env._pthread_self;var Aa=env._sqrtf;var Ba=env.___unlock;var Ca=env._emscripten_set_main_loop;var Da=env.___cxa_throw;var Ea=env.___lock;var Fa=env._abort;var Ga=env._pthread_cleanup_push;var Ha=env._time;var Ia=env.___syscall140;var Ja=env.___syscall146;var Ka=0.0;
-// EMSCRIPTEN_START_FUNCS
-function mb(b,f,g,h){b=b|0;f=f|0;g=g|0;h=h|0;var j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0,R=0,S=0;j=i;i=i+16|0;k=j;l=a[g+8>>0]|0;m=l&255;n=a[g+9>>0]|0;o=n&255;p=a[f+4>>0]|0;q=p&255;if(l<<24>>24==n<<24>>24){if((l&255)>=4)pa(500021,474791,827,500031);r=d[f>>0]|0;s=d[f+1>>0]|0;t=s<<3|s>>>2;s=d[f+2>>0]|0;u=s<<3|s>>>2;s=c[17484+(q<<4)+(m<<2)>>2]|0;v=(r<<3|r>>>2)+s|0;if(v>>>0>255)if((v|0)<0){w=0;x=6}else y=255;else{w=v;x=6}if((x|0)==6)y=w;w=t+s|0;if(w>>>0>255)if((w|0)<0){z=0;x=9}else A=255;else{z=w;x=9}if((x|0)==9)A=z;z=u+s|0;if(z>>>0>255)if((z|0)<0){B=0;x=12}else C=255;else{B=z;x=12}if((x|0)==12)C=B;B=d[468643+(A<<1)>>0]<<5|d[467619+(y<<1)>>0]<<11|d[467619+(C<<1)>>0];z=d[468643+(A<<1)+1>>0]<<5|d[467619+(y<<1)+1>>0]<<11|d[467619+(C<<1)+1>>0];if((z|0)==(B|0)&(h^1))if(!B){D=1;E=0;F=0;G=0;H=85}else{I=B+-1|0;J=0;x=16}else{I=z;J=170;x=16}if((x|0)==16){z=B>>>0<I>>>0;C=z?I:B;y=z?B:I;D=C&255;E=y&255;F=(C&65535)>>>8&255;G=(y&65535)>>>8&255;H=(z?J|85:J)&255}a[b>>0]=D;a[b+1>>0]=F;a[b+2>>0]=E;a[b+3>>0]=G;Hd(b+4|0,H|0,4)|0;i=j;return}if((p&255)>6?n<<24>>24==3&(l<<24>>24==0&(a[g+10>>0]|0)==2):0){ob(k,f,q);l=c[k>>2]|0;n=c[k+12>>2]|0;k=d[469155+((l>>>8&255)<<1)>>0]<<5|d[468131+((l&255)<<1)>>0]<<11|d[468131+((l>>>16&255)<<1)>>0];l=d[469155+((n>>>8&255)<<1)>>0]<<5|d[468131+((n&255)<<1)>>0]<<11|d[468131+((n>>>16&255)<<1)>>0];if((l|0)==(k|0))if(!k){K=1;L=0;M=0;N=0;O=1;P=1}else{Q=k+-1|0;R=0;x=23}else{Q=l;R=1;x=23}if((x|0)==23){l=k>>>0<Q>>>0;n=l?Q:k;p=l?k:Q;K=n&255;L=p&255;M=(n&65535)>>>8&255;N=(p&65535)>>>8&255;O=l?0:R;P=l&1}a[b>>0]=K;a[b+1>>0]=M;a[b+2>>0]=L;a[b+3>>0]=N;N=0;while(1){L=g+N|0;M=b+4+N|0;K=(a[L>>0]&3)==3?O:P;if((K|N)>>>0>=4){x=27;break}l=d[M>>0]&252|K;a[M>>0]=l;K=(a[L>>0]&12)==12?O:P;if((K|N)>>>0>=4){x=27;break}R=l&243|K<<2;a[M>>0]=R;K=(a[L>>0]&48)==48?O:P;if((K|N)>>>0>=4){x=27;break}l=R&207|K<<4;a[M>>0]=l;if((N|3|0)!=3){x=25;break}K=(d[L>>0]|0)>191?O:P;if((K|N)>>>0>=4){x=27;break}a[M>>0]=l&63|K<<6;N=N+1|0;if(N>>>0>=4){x=33;break}}if((x|0)==25)pa(499759,499604,740,499924);else if((x|0)==27)pa(499986,474791,957,499911);else if((x|0)==33){i=j;return}}x=q<<5;q=(c[16480+(m<<4)+(o<<2)>>2]|0)*10|0;o=(((d[f>>0]|0)+x|0)*60|0)+q|0;m=(((d[f+1>>0]|0)+x|0)*60|0)+q|0;N=(((d[f+2>>0]|0)+x|0)*60|0)+q|0;q=(e[147612+(m<<2)+2>>1]|0)+(e[86172+(o<<2)+2>>1]|0)+(e[86172+(N<<2)+2>>1]|0)|0;x=(e[147612+((m|1)<<2)+2>>1]|0)+(e[86172+((o|1)<<2)+2>>1]|0)+(e[86172+((N|1)<<2)+2>>1]|0)|0;f=x>>>0<q>>>0;P=f?x:q;q=(e[147612+(m+2<<2)+2>>1]|0)+(e[86172+(o+2<<2)+2>>1]|0)+(e[86172+(N+2<<2)+2>>1]|0)|0;x=q>>>0<P>>>0;O=x?q:P;P=(e[147612+(m+3<<2)+2>>1]|0)+(e[86172+(o+3<<2)+2>>1]|0)+(e[86172+(N+3<<2)+2>>1]|0)|0;q=P>>>0<O>>>0;K=q?P:O;O=(e[147612+(m+4<<2)+2>>1]|0)+(e[86172+(o+4<<2)+2>>1]|0)+(e[86172+(N+4<<2)+2>>1]|0)|0;P=O>>>0<K>>>0;l=P?O:K;K=(e[147612+(m+5<<2)+2>>1]|0)+(e[86172+(o+5<<2)+2>>1]|0)+(e[86172+(N+5<<2)+2>>1]|0)|0;O=K>>>0<l>>>0;M=O?K:l;l=(e[147612+(m+6<<2)+2>>1]|0)+(e[86172+(o+6<<2)+2>>1]|0)+(e[86172+(N+6<<2)+2>>1]|0)|0;K=l>>>0<M>>>0;L=K?l:M;M=(e[147612+(m+7<<2)+2>>1]|0)+(e[86172+(o+7<<2)+2>>1]|0)+(e[86172+(N+7<<2)+2>>1]|0)|0;l=M>>>0<L>>>0;R=l?M:L;L=(e[147612+(m+8<<2)+2>>1]|0)+(e[86172+(o+8<<2)+2>>1]|0)+(e[86172+(N+8<<2)+2>>1]|0)|0;M=L>>>0<R>>>0;p=((e[147612+(m+9<<2)+2>>1]|0)+(e[86172+(o+9<<2)+2>>1]|0)+(e[86172+(N+9<<2)+2>>1]|0)|0)>>>0<(M?L:R)>>>0?9:M?8:l?7:K?6:O?5:P?4:q?3:x?2:f&1;f=p+o|0;o=p+m|0;m=p+N|0;N=d[86172+(f<<2)>>0]<<11&63488|d[86172+(m<<2)>>0]|d[147612+(o<<2)>>0]<<5;x=d[86172+(f<<2)+1>>0]<<11&63488|d[86172+(m<<2)+1>>0]|d[147612+(o<<2)+1>>0]<<5;o=N>>>0<x>>>0;m=o?x:N;f=o?N:x;x=o?472231:469671;a[b>>0]=m;o=b+1|0;a[o>>0]=(m&65535)>>>8;N=b+2|0;a[N>>0]=f;q=b+3|0;a[q>>0]=(f&65535)>>>8;if((m|0)!=(f|0)){a[b+4>>0]=a[(d[g>>0]|0)+(x+(p<<8))>>0]|0;a[b+5>>0]=a[(d[g+1>>0]|0)+(x+(p<<8))>>0]|0;a[b+6>>0]=a[(d[g+2>>0]|0)+(x+(p<<8))>>0]|0;a[b+7>>0]=a[(d[g+3>>0]|0)+(x+(p<<8))>>0]|0;i=j;return}if(h)S=0;else{h=(m|0)==0;p=h?0:m+-1|0;x=h?1:m;a[b>>0]=x;a[o>>0]=(x&65535)>>>8;a[N>>0]=p;a[q>>0]=(p&65535)>>>8;S=h?85:0}Hd(b+4|0,S|0,4)|0;i=j;return}function nb(b,f,g){b=b|0;f=f|0;g=g|0;var h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0;h=i;i=i+16|0;j=h;k=b+4|0;l=c[k>>2]&2147450878|-2147450880;c[k>>2]=l;m=a[g+8>>0]|0;n=m&255;o=a[g+9>>0]|0;p=o&255;q=a[f+4>>0]|0;r=q&255;if(m<<24>>24!=o<<24>>24){if((q&255)>6?o<<24>>24==3&(m<<24>>24==0&(a[g+10>>0]|0)==2):0){ob(j,f,r);o=c[j>>2]|0;q=j+12|0;j=a[495984+((o&255)<<1)+1>>0]|0;s=a[495984+((o>>>8&255)<<1)+1>>0]|0;t=a[495472+((o>>>16&255)<<1)+1>>0]|0;if(!(((s|j)&255)<32&(t&255)<16))pa(501721,474791,6735,507574);o=d[q+2>>0]|0;u=d[q+1>>0]|0;v=d[q>>0]|0;q=(s&255)<<5&992|(j&255)<<10&31744|(t&255)<<1&30|c[k>>2]&-32767;c[k>>2]=q;t=a[495984+(v<<1)+1>>0]|0;v=a[495984+(u<<1)+1>>0]|0;u=a[495984+(o<<1)+1>>0]|0;if(((v|t|u)&255)>=32)pa(500605,474791,6744,507621);c[k>>2]=(t&255)<<26&2080374784|q&-2147418113|(v&255)<<21&65011712|(u&255)<<16&2031616;a[b>>0]=a[g>>0]|0;a[b+1>>0]=a[g+1>>0]|0;a[b+2>>0]=a[g+2>>0]|0;a[b+3>>0]=a[g+3>>0]|0;i=h;return}u=r<<5;v=(c[18148+(n<<4)+(p<<2)>>2]|0)*10|0;p=(((d[f>>0]|0)+u|0)*60|0)+v|0;q=(((d[f+1>>0]|0)+u|0)*60|0)+v|0;t=(((d[f+2>>0]|0)+u|0)*60|0)+v|0;v=(e[278684+(q<<2)+2>>1]|0)+(e[278684+(p<<2)+2>>1]|0)+(e[401564+(t<<2)+2>>1]|0)|0;u=(e[278684+((q|1)<<2)+2>>1]|0)+(e[278684+((p|1)<<2)+2>>1]|0)+(e[401564+((t|1)<<2)+2>>1]|0)|0;o=u>>>0<v>>>0;j=o?u:v;v=(e[278684+(q+2<<2)+2>>1]|0)+(e[278684+(p+2<<2)+2>>1]|0)+(e[401564+(t+2<<2)+2>>1]|0)|0;u=v>>>0<j>>>0;s=u?v:j;j=(e[278684+(q+3<<2)+2>>1]|0)+(e[278684+(p+3<<2)+2>>1]|0)+(e[401564+(t+3<<2)+2>>1]|0)|0;v=j>>>0<s>>>0;w=v?j:s;s=(e[278684+(q+4<<2)+2>>1]|0)+(e[278684+(p+4<<2)+2>>1]|0)+(e[401564+(t+4<<2)+2>>1]|0)|0;j=s>>>0<w>>>0;x=j?s:w;w=(e[278684+(q+5<<2)+2>>1]|0)+(e[278684+(p+5<<2)+2>>1]|0)+(e[401564+(t+5<<2)+2>>1]|0)|0;s=w>>>0<x>>>0;y=s?w:x;x=(e[278684+(q+6<<2)+2>>1]|0)+(e[278684+(p+6<<2)+2>>1]|0)+(e[401564+(t+6<<2)+2>>1]|0)|0;w=x>>>0<y>>>0;z=w?x:y;y=(e[278684+(q+7<<2)+2>>1]|0)+(e[278684+(p+7<<2)+2>>1]|0)+(e[401564+(t+7<<2)+2>>1]|0)|0;x=y>>>0<z>>>0;A=x?y:z;z=(e[278684+(q+8<<2)+2>>1]|0)+(e[278684+(p+8<<2)+2>>1]|0)+(e[401564+(t+8<<2)+2>>1]|0)|0;y=z>>>0<A>>>0;B=((e[278684+(q+9<<2)+2>>1]|0)+(e[278684+(p+9<<2)+2>>1]|0)+(e[401564+(t+9<<2)+2>>1]|0)|0)>>>0<(y?z:A)>>>0?9:y?8:x?7:w?6:s?5:j?4:v?3:u?2:o&1;o=B+p|0;p=a[278684+(o<<2)>>0]|0;u=B+q|0;q=a[278684+(u<<2)>>0]|0;v=B+t|0;t=a[401564+(v<<2)>>0]|0;if(!(((q|p)&255)<32&(t&255)<16))pa(501721,474791,6735,507574);j=(q&255)<<5&992|(p&255)<<10&31744|(t&255)<<1&30|c[k>>2]&-32767;c[k>>2]=j;t=a[278684+(o<<2)+1>>0]|0;o=a[278684+(u<<2)+1>>0]|0;u=a[401564+(v<<2)+1>>0]|0;if(((o|t|u)&255)>=32)pa(500605,474791,6744,507621);c[k>>2]=(t&255)<<26&2080374784|j&-2147418113|(o&255)<<21&65011712|(u&255)<<16&2031616;u=a[g>>0]|0;if((B|0)==6){a[b>>0]=u;a[b+1>>0]=a[g+1>>0]|0;a[b+2>>0]=a[g+2>>0]|0;a[b+3>>0]=a[g+3>>0]|0;i=h;return}else{o=u&255;u=d[g+1>>0]|0;j=d[g+2>>0]|0;t=d[g+3>>0]|0;g=d[(u>>>2&3)+(507534+(B<<2))>>0]<<2|d[(u&3)+(507534+(B<<2))>>0]|d[(u>>>4&3)+(507534+(B<<2))>>0]<<4|d[(u>>>6)+(507534+(B<<2))>>0]<<6;u=d[(j>>>2&3)+(507534+(B<<2))>>0]<<2|d[(j&3)+(507534+(B<<2))>>0]|d[(j>>>4&3)+(507534+(B<<2))>>0]<<4|d[(j>>>6)+(507534+(B<<2))>>0]<<6;j=d[(t>>>2&3)+(507534+(B<<2))>>0]<<2|d[(t&3)+(507534+(B<<2))>>0]|d[(t>>>4&3)+(507534+(B<<2))>>0]<<4|d[(t>>>6)+(507534+(B<<2))>>0]<<6;a[b>>0]=d[(o>>>2&3)+(507534+(B<<2))>>0]<<2|d[(o&3)+(507534+(B<<2))>>0]|d[(o>>>4&3)+(507534+(B<<2))>>0]<<4|d[(o>>>6)+(507534+(B<<2))>>0]<<6;a[b+1>>0]=g;a[b+2>>0]=u;a[b+3>>0]=j;i=h;return}}else{if((m&255)>=4)pa(500021,474791,827,500031);m=d[f>>0]|0;j=d[f+1>>0]|0;u=j<<3|j>>>2;j=d[f+2>>0]|0;f=j<<3|j>>>2;j=c[17484+(r<<4)+(n<<2)>>2]|0;n=(m<<3|m>>>2)+j|0;if(n>>>0>255)if((n|0)<0){C=0;D=6}else E=255;else{C=n;D=6}if((D|0)==6)E=C;C=u+j|0;if(C>>>0>255)if((C|0)<0){F=0;D=9}else G=255;else{F=C;D=9}if((D|0)==9)G=F;F=f+j|0;if(F>>>0>255)if((F|0)<0){H=0;D=12}else I=255;else{H=F;D=12}if((D|0)==12)I=H;H=a[494448+(E<<1)>>0]|0;D=a[494448+(G<<1)>>0]|0;F=a[493936+(I<<1)>>0]|0;if(!(((D|H)&255)<32&(F&255)<16))pa(501721,474791,6735,507574);j=(D&255)<<5&992|(H&255)<<10&31744|(F&255)<<1&30;c[k>>2]=j|l&-32768;l=a[494448+(E<<1)+1>>0]|0;E=a[494448+(G<<1)+1>>0]|0;G=a[493936+(I<<1)+1>>0]|0;if(((E|l|G)&255)>=32)pa(500605,474791,6744,507621);c[k>>2]=(l&255)<<26|(j|-2147450880)|(E&255)<<21&65011712|(G&255)<<16&2031616;a[b>>0]=85;a[b+1>>0]=85;a[b+2>>0]=85;a[b+3>>0]=85;i=h;return}}function ob(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0;f=c[d>>2]|0;d=f&255;g=f>>>5;h=f>>>10&63;i=f>>>13;j=f>>>18&63;f=d<<3&248|d>>>2;d=c[17484+(e<<4)>>2]|0;k=f+d|0;if(k>>>0>255)if((k|0)<0){l=0;m=3}else n=255;else{l=k;m=3}if((m|0)==3)n=l;l=g&248|h;h=d+l|0;if(h>>>0>255)if((h|0)<0){o=0;m=6}else p=255;else{o=h;m=6}if((m|0)==6)p=o;o=i&248|j;j=d+o|0;if(j>>>0>255)if((j|0)<0){q=0;m=9}else r=255;else{q=j;m=9}if((m|0)==9)r=q;a[b>>0]=n;a[b+1>>0]=p;a[b+2>>0]=r;a[b+3>>0]=-1;r=b+4|0;p=c[17484+(e<<4)+4>>2]|0;n=p+f|0;if(n>>>0>255)if((n|0)<0){s=0;m=12}else t=255;else{s=n;m=12}if((m|0)==12)t=s;s=p+l|0;if(s>>>0>255)if((s|0)<0){u=0;m=15}else v=255;else{u=s;m=15}if((m|0)==15)v=u;u=p+o|0;if(u>>>0>255)if((u|0)<0){w=0;m=18}else x=255;else{w=u;m=18}if((m|0)==18)x=w;a[r>>0]=t;a[r+1>>0]=v;a[r+2>>0]=x;a[r+3>>0]=-1;r=b+8|0;x=c[17484+(e<<4)+8>>2]|0;v=x+f|0;if(v>>>0>255)if((v|0)<0){y=0;m=21}else z=255;else{y=v;m=21}if((m|0)==21)z=y;y=x+l|0;if(y>>>0>255)if((y|0)<0){A=0;m=24}else B=255;else{A=y;m=24}if((m|0)==24)B=A;A=x+o|0;if(A>>>0>255)if((A|0)<0){C=0;m=27}else D=255;else{C=A;m=27}if((m|0)==27)D=C;a[r>>0]=z;a[r+1>>0]=B;a[r+2>>0]=D;a[r+3>>0]=-1;r=b+12|0;b=c[17484+(e<<4)+12>>2]|0;e=b+f|0;if(e>>>0>255)if((e|0)<0){E=0;m=30}else F=255;else{E=e;m=30}if((m|0)==30)F=E;E=b+l|0;if(E>>>0>255)if((E|0)<0){G=0;m=33}else H=255;else{G=E;m=33}if((m|0)==33)H=G;G=b+o|0;if(G>>>0>255)if((G|0)<0)I=0;else{J=255;K=F&255;a[r>>0]=K;L=H&255;M=r+1|0;a[M>>0]=L;N=J&255;O=r+2|0;a[O>>0]=N;P=r+3|0;a[P>>0]=-1;return}else I=G;J=I;K=F&255;a[r>>0]=K;L=H&255;M=r+1|0;a[M>>0]=L;N=J&255;O=r+2|0;a[O>>0]=N;P=r+3|0;a[P>>0]=-1;return}function pb(a){a=a|0;return (a+-13|0)>>>0<4|0}function qb(b,d,e,f,g,h,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x){b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;k=k|0;l=l|0;m=m|0;n=n|0;o=o|0;p=p|0;q=q|0;r=r|0;s=s|0;t=t|0;u=u|0;v=v|0;w=w|0;x=x|0;var y=0,z=0,A=0,B=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0,R=0;y=i;i=i+32|0;z=y+12|0;A=y;B=Kd(p|0,0,o|0,0)|0;D=C;if(D>>>0>0|(D|0)==0&B>>>0>h>>>0){E=0;i=y;return E|0}B=(r|0)!=0;if(B){D=Kd(r|0,0,q|0,0)|0;F=C;if(F>>>0>0|(F|0)==0&D>>>0>h>>>0){E=0;i=y;return E|0}}else if(t)pa(475193,474791,8765,475222);h=(d|0)==9;if((d&-2|0)==8){D=j<<2;if(!D){E=0;i=y;return E|0}if(D+-1&D){E=0;i=y;return E|0}D=k<<2;if(!D){E=0;i=y;return E|0}if(D+-1&D){E=0;i=y;return E|0}}D=h?(t?d:8):d;d=(s&4|0)==0;switch(D|0){case 20:case 19:case 18:case 11:case 9:case 8:case 4:case 2:case 0:{G=8;H=16;break}case 21:case 17:case 12:case 10:case 5:case 3:case 1:case 7:case 6:{G=16;H=16;break}case 13:{I=4;J=_(k,j)|0;H=17;break}case 16:case 15:case 14:{G=2;H=16;break}default:pa(475191,474791,10833,475639)}do if((H|0)==16){s=_(k,j)|0;if((D+-13|0)>>>0>=4)if((D|0)==17){if((_((m+3|0)>>>2,(l+7|0)>>>3)|0)>>>0>f>>>0)E=0;else{K=G;L=s;break}i=y;return E|0}else{if(s>>>0>f>>>0)E=0;else{K=G;L=s;break}i=y;return E|0}else{I=G;J=s;H=17}}while(0);if((H|0)==17)if((_((x|0)==0?m:x,(v|0)==0?l:v)|0)>>>0>f>>>0){E=0;i=y;return E|0}else{K=I;L=J}J=g+o|0;if(t){M=d?p:r;N=d^1;O=d?J:g+q|0}else{M=p;N=0;O=J}do switch(D|0){case 0:{E=lb(b,e,j,k,O,M,0,K,0,u,N,n,l,m,v,w,0,0,x)|0;i=y;return E|0}case 2:{E=lb(b,e,j,k,O,M,2,K,1,u,N,n,l,m,v,w,0,0,x)|0;i=y;return E|0}case 4:{E=lb(b,e,j,k,O,M,4,K,0,u,N,n,l,m,v,w,0,0,x)|0;i=y;return E|0}case 8:{E=lb(b,e,j,k,O,M,6,K,0,u,N,n,l,m,v,w,0,0,x)|0;i=y;return E|0}case 9:{if(!t)pa(475238,474791,8870,475222);if(!B)pa(475266,474791,8871,475222);c[A>>2]=0;d=A+4|0;c[d>>2]=0;c[A+8>>2]=0;do if(L)if(L>>>0>1073741823)Kc(A);else{o=L<<2;I=Lc(o)|0;c[A>>2]=I;f=I+(L<<2)|0;c[A+8>>2]=f;Hd(I|0,0,o|0)|0;c[d>>2]=f;P=A;Q=I;break}else{P=A;Q=0}while(0);if(lb(b,Q,j,k,g+q|0,r,20,4,0,u,1,n,l,m,j,w,0,0,0)|0)R=lb(b,e,j,k,J,p,7,K,0,u,0,n,l,m,v,w,0,c[P>>2]|0,0)|0;else R=0;I=c[A>>2]|0;if(!I){E=R;i=y;return E|0}f=c[d>>2]|0;if((f|0)!=(I|0))c[d>>2]=f+(~((f+-4-I|0)>>>2)<<2);Mc(I);E=R;i=y;return E|0}case 7:case 6:{if((K|0)!=16)pa(475279,474791,8903,475222);I=lb(b,e,j,k,J,p,9,16,0,u,0,n,l,m,v,w,0,0,x)|0;if(!(I&t)){E=I;i=y;return E|0}E=lb(b,e,j,k,g+q|0,r,10,16,0,u,1,n,l,m,v,w,0,0,x)|0;i=y;return E|0}case 1:{if((K|0)!=16)pa(475279,474791,8931,475222);if(t){if(!(lb(b,e,j,k,g+q|0,r,11,16,0,u,1,n,l,m,v,w,0,0,x)|0)){E=0;i=y;return E|0}}else if(k){I=((v|0)==0?j:v)<<4;f=(j|0)==0;o=0;do{if(!f){H=_(I,o)|0;G=0;while(1){s=e+H|0;a[s>>0]=255;a[s+1>>0]=29;s=e+(H+2)|0;a[s>>0]=a[463004]|0;a[s+1>>0]=a[463005]|0;a[s+2>>0]=a[463006]|0;a[s+3>>0]=a[463007]|0;a[s+4>>0]=a[463008]|0;a[s+5>>0]=a[463009]|0;G=G+1|0;if((G|0)==(j|0))break;else H=H+16|0}}o=o+1|0}while((o|0)!=(k|0))}E=lb(b,e+8|0,j,k,J,p,0,16,0,u,0,n,l,m,v,w,0,0,x)|0;i=y;return E|0}case 3:{if((K|0)!=16)pa(475279,474791,8972,475222);if(t){if(!(lb(b,e,j,k,g+q|0,r,4,16,0,u,1,n,l,m,v,w,0,0,x)|0)){E=0;i=y;return E|0}}else{a[z>>0]=0;a[z+1>>0]=0;a[z+2>>0]=0;a[z+3>>0]=0;a[z+4>>0]=0;a[z+5>>0]=0;if(k){o=((v|0)==0?j:v)<<4;I=(j|0)==0;f=0;do{if(!I){d=_(o,f)|0;H=0;while(1){a[e+d>>0]=-1;a[e+(d+1)>>0]=-1;G=e+(d+2)|0;a[G>>0]=a[z>>0]|0;a[G+1>>0]=a[z+1>>0]|0;a[G+2>>0]=a[z+2>>0]|0;a[G+3>>0]=a[z+3>>0]|0;a[G+4>>0]=a[z+4>>0]|0;a[G+5>>0]=a[z+5>>0]|0;H=H+1|0;if((H|0)==(j|0))break;else d=d+16|0}}f=f+1|0}while((f|0)!=(k|0))}}E=lb(b,e+8|0,j,k,J,p,2,16,0,u,0,n,l,m,v,w,0,0,x)|0;i=y;return E|0}case 5:{if((K|0)!=16)pa(475279,474791,9009,475222);if(!(lb(b,e,j,k,J,p,4,16,0,u,0,n,l,m,v,w,0,0,x)|0)){E=0;i=y;return E|0}if(t){E=lb(b,e+8|0,j,k,g+q|0,r,4,16,0,u,1,n,l,m,v,w,0,0,x)|0;i=y;return E|0};a[z>>0]=0;a[z+1>>0]=0;a[z+2>>0]=0;a[z+3>>0]=0;a[z+4>>0]=0;a[z+5>>0]=0;if(k){f=((v|0)==0?j:v)<<4;o=(j|0)==0;I=0;do{if(!o){d=_(f,I)|0;H=0;while(1){a[e+(d+8)>>0]=-1;a[e+(d+9)>>0]=-1;G=e+(d+10)|0;a[G>>0]=a[z>>0]|0;a[G+1>>0]=a[z+1>>0]|0;a[G+2>>0]=a[z+2>>0]|0;a[G+3>>0]=a[z+3>>0]|0;a[G+4>>0]=a[z+4>>0]|0;a[G+5>>0]=a[z+5>>0]|0;H=H+1|0;if((H|0)==(j|0))break;else d=d+16|0}}I=I+1|0}while((I|0)!=(k|0))}E=1;i=y;return E|0}case 10:{if((K|0)!=16)pa(475279,474791,9048,475222);if(!t){E=lb(b,e,j,k,J,p,12,16,0,u,0,n,l,m,v,w,0,0,x)|0;i=y;return E|0}if(!(lb(b,e,j,k,g+q|0,r,20,16,0,u,1,n,l,m,v,w,0,0,x)|0)){E=0;i=y;return E|0}E=lb(b,e,j,k,J,p,12,16,0,u,0,n,l,m,v,w,1,0,x)|0;i=y;return E|0}case 11:{E=lb(b,e,j,k,O,M,13,K,0,u,N,n,l,m,v,w,0,0,x)|0;i=y;return E|0}case 12:{if((K|0)!=16)pa(475279,474791,9098,475222);if(t){if(!(lb(b,e,j,k,g+q|0,r,4,16,0,u,1,n,l,m,v,w,0,0,x)|0)){E=0;i=y;return E|0}}else{a[z>>0]=0;a[z+1>>0]=0;a[z+2>>0]=0;a[z+3>>0]=0;a[z+4>>0]=0;a[z+5>>0]=0;if(k){I=((v|0)==0?j:v)<<4;f=(j|0)==0;o=0;do{if(!f){d=_(I,o)|0;H=0;while(1){a[e+d>>0]=-1;a[e+(d+1)>>0]=-1;G=e+(d+2)|0;a[G>>0]=a[z>>0]|0;a[G+1>>0]=a[z+1>>0]|0;a[G+2>>0]=a[z+2>>0]|0;a[G+3>>0]=a[z+3>>0]|0;a[G+4>>0]=a[z+4>>0]|0;a[G+5>>0]=a[z+5>>0]|0;H=H+1|0;if((H|0)==(j|0))break;else d=d+16|0}}o=o+1|0}while((o|0)!=(k|0))}}E=lb(b,e+8|0,j,k,J,p,13,16,0,u,0,n,l,m,v,w,0,0,x)|0;i=y;return E|0}case 18:{E=lb(b,e,j,k,O,M,16,K,0,u,N,n,l,m,v,w,0,0,x)|0;i=y;return E|0}case 19:{if(!t){E=lb(b,e,j,k,J,p,16,K,0,u,0,n,l,m,v,w,0,0,x)|0;i=y;return E|0}if(!(lb(b,e,j,k,g+q|0,r,20,K,0,u,1,n,l,m,v,w,0,0,x)|0)){E=0;i=y;return E|0}E=lb(b,e,j,k,J,p,17,K,0,u,0,n,l,m,v,w,1,0,x)|0;i=y;return E|0}case 13:{if(t?!(lb(b,e,j,k,g+q|0,r,23,4,0,u,1,n,l,m,v,w,0,0,x)|0):0){E=0;i=y;return E|0}E=lb(b,e,j,k,J,p,t?21:22,4,0,u,0,n,l,m,v,w,0,0,x)|0;i=y;return E|0}case 15:case 14:{E=lb(b,e,j,k,O,M,(D|0)==14?24:25,2,0,u,N,n,l,m,v,w,0,0,x)|0;i=y;return E|0}case 16:{if(t?!(lb(b,e,j,k,g+q|0,r,27,2,0,u,1,n,l,m,v,w,0,0,x)|0):0){E=0;i=y;return E|0}E=lb(b,e,j,k,J,p,t?26:28,2,0,u,0,n,l,m,v,w,0,0,x)|0;i=y;return E|0}case 17:{E=lb(b,e,j,k,O,M,15,K,0,u,N,n,l,m,v,w,0,0,x)|0;i=y;return E|0}case 20:{E=lb(b,e,j,k,O,M,18,K,0,u,N,n,l,m,v,w,0,0,x)|0;i=y;return E|0}case 21:{if((K|0)!=16)pa(475279,474791,9277,475222);if(t){if(!(lb(b,e+8|0,j,k,g+q|0,r,18,16,0,u,1,n,l,m,v,w,0,0,x)|0)){E=0;i=y;return E|0}}else if(k){o=((v|0)==0?j:v)<<4;I=(j|0)==0;f=0;do{if(!I){d=_(o,f)|0;H=0;while(1){G=e+(d+8)|0;a[G>>0]=255;a[G+1>>0]=29;G=e+(d+10)|0;a[G>>0]=a[463004]|0;a[G+1>>0]=a[463005]|0;a[G+2>>0]=a[463006]|0;a[G+3>>0]=a[463007]|0;a[G+4>>0]=a[463008]|0;a[G+5>>0]=a[463009]|0;H=H+1|0;if((H|0)==(j|0))break;else d=d+16|0}}f=f+1|0}while((f|0)!=(k|0))}E=lb(b,e,j,k,J,p,18,16,0,u,0,n,l,m,v,w,0,0,x)|0;i=y;return E|0}default:pa(475191,474791,9310,475222)}while(0);return 0}function rb(a){a=a|0;var b=0;switch(a|0){case 20:case 19:case 18:case 11:case 9:case 8:case 4:case 2:case 0:{b=8;break}case 21:case 17:case 12:case 10:case 5:case 3:case 1:case 7:case 6:{b=16;break}case 13:{b=4;break}case 16:case 15:case 14:{b=2;break}default:pa(475191,474791,10833,475639)}return b|0}function sb(e,f,g,h,j,k,l,m,n,o,p,q,r,s,t,u,v,w){e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;k=k|0;l=l|0;m=m|0;n=n|0;o=o|0;p=p|0;q=q|0;r=r|0;s=s|0;t=t|0;u=u|0;v=v|0;w=w|0;var x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0,$=0,aa=0,ba=0,ca=0,da=0,ea=0,fa=0,ga=0,ha=0,ia=0,ja=0,ka=0,la=0,ma=0,na=0,oa=0,qa=0,ra=0,sa=0,ta=0,ua=0,va=0,wa=0,xa=0,ya=0,za=0,Aa=0,Ba=0,Ca=0,Da=0,Ea=0,Fa=0,Ga=0,Ha=0,Ia=0,Ja=0,Ka=0,La=0;s=i;i=i+256|0;n=s+96|0;e=s;x=l+-21|0;if(!r)if(x>>>0>=9)if((l|0)==15)y=(p+7|0)>>>3;else y=g;else y=p;else y=r;r=x>>>0>8|(t|0)!=0?t:q;if((_(g<<4,h)|0)>>>0>k>>>0){z=0;i=s;return z|0}k=(w&4|0)!=0&o;if((l&-2|0)==6)if((l|0)==7){tb(j,f,g,h,0)|0;z=1;i=s;return z|0}else{ub(j,f,g,h,0,k)|0;z=1;i=s;return z|0}if(!h){z=1;i=s;return z|0}o=_(y,m)|0;q=(g|0)==0;t=n+104|0;x=n+108|0;p=n+112|0;A=n+104|0;B=n+108|0;C=n+112|0;D=(w&32|0)!=0;w=n+104|0;E=n+112|0;F=n+108|0;G=n+112|0;H=n+104|0;I=n+112|0;J=n+108|0;K=n+112|0;L=n+104|0;M=n+112|0;N=n+104|0;O=n+112|0;P=n+108|0;Q=n+112|0;R=D?2:1;S=n+104|0;T=n+108|0;U=n+112|0;V=(m|0)==4;W=y<<2;X=n+104|0;Y=n+108|0;Z=n+112|0;$=(m|0)==2;aa=y<<1;ba=(l|0)==24;ca=n+104|0;da=n+108|0;ea=n+112|0;fa=~y;ga=u;u=v;v=0;ha=~r;ia=j;a:while(1){j=(ha|0)>-5?~ha:4;b:do if(q){ja=ga;ka=u;la=ia}else{ma=_(v,y)|0;na=(r|0)==(v<<2|0);oa=ga;qa=u;ra=0;sa=fa;ta=f+(_(o,v)|0)|0;ua=ia;while(1){va=(sa|0)>-5?~sa:4;c:do switch(l|0){case 0:{if(k)if(vb(ua,ta,3)|0){wa=qa;xa=oa;break c}else{z=0;ya=98;break a}if(!(Qb(ua,n,0,1)|0)){ya=95;break a}za=c[t>>2]|0;if((za|0)!=8)Rb(za,c[x>>2]|0,p,n,e,0)|0;Vb(n,e,ta);wa=qa;xa=oa;break}case 1:{if(!(Qb(ua,n,0,1)|0)){ya=25;break a}za=c[A>>2]|0;if((za|0)!=8)Rb(za,c[B>>2]|0,C,n,e,0)|0;Wb(n,e,ta);Vb(n,e,ta+8|0);wa=qa;xa=oa;break}case 2:{if(wb(ua,ta,D)|0){wa=qa;xa=oa}else{z=0;ya=98;break a}break}case 3:{if(xb(ua,ta,D)|0){wa=qa;xa=oa}else{z=0;ya=98;break a}break}case 4:{za=(oa|0)<0?0:oa;if(!(Qb(ua,n,0,1)|0)){ya=33;break a}Aa=c[w>>2]|0;if((Aa|0)==8){Ba=a[E+za>>0]|0;a[ta>>0]=Ba;a[ta+1>>0]=Ba;Ba=ta+2|0;a[Ba>>0]=0;a[Ba+1>>0]=0;a[Ba+2>>0]=0;a[Ba+3>>0]=0;a[Ba+4>>0]=0;a[Ba+5>>0]=0}else{Rb(Aa,c[F>>2]|0,G,n,e,0)|0;Xb(ta,e+za|0,4)}wa=qa;xa=za;break}case 5:{za=(oa|0)<0?0:oa;Aa=(qa|0)<0?3:qa;if(!(Qb(ua,n,0,1)|0)){ya=39;break a}Ba=c[H>>2]|0;Ca=ta+8|0;if((Ba|0)==8){Da=a[I+za>>0]|0;a[ta>>0]=Da;a[ta+1>>0]=Da;Da=ta+2|0;a[Da>>0]=0;a[Da+1>>0]=0;a[Da+2>>0]=0;a[Da+3>>0]=0;a[Da+4>>0]=0;a[Da+5>>0]=0;Da=a[I+Aa>>0]|0;a[Ca>>0]=Da;a[ta+9>>0]=Da;Da=ta+10|0;a[Da>>0]=0;a[Da+1>>0]=0;a[Da+2>>0]=0;a[Da+3>>0]=0;a[Da+4>>0]=0;a[Da+5>>0]=0}else{Rb(Ba,c[J>>2]|0,K,n,e,0)|0;Xb(ta,e+za|0,4);Xb(Ca,e+Aa|0,4)}wa=Aa;xa=za;break}case 9:case 8:{if(!(Qb(ua,n,0,0)|0)){ya=41;break a}if(!(Sb(n,e)|0))break a;Nb(ta,e);wa=qa;xa=oa;break}case 12:{if(!(Qb(ua,n,1,0)|0)){ya=50;break a}za=c[L>>2]|0;if((za|0)==8)Ob(ta,M);else Pb(ta,n,za)|0;wa=qa;xa=oa;break}case 18:{za=(oa|0)<0?0:oa;if(!(Qb(ua,n,0,1)|0)){ya=59;break a}Aa=c[N>>2]|0;if((Aa|0)!=8){Rb(Aa,c[P>>2]|0,Q,n,e,0)|0;if((za|0)==3)Wb(n,e,ta);else Pa[R&3](ta,e+za|0,4)}else{b[ta>>1]=d[O+za>>0]|0|3328;Aa=ta+2|0;a[Aa>>0]=a[463004]|0;a[Aa+1>>0]=a[463005]|0;a[Aa+2>>0]=a[463006]|0;a[Aa+3>>0]=a[463007]|0;a[Aa+4>>0]=a[463008]|0;a[Aa+5>>0]=a[463009]|0}wa=qa;xa=za;break}case 19:{za=(oa|0)<0?0:oa;Aa=(qa|0)<3?3:qa;if(yb(ua,ta,D,za,Aa)|0){wa=Aa;xa=za}else{z=0;ya=98;break a}break}case 22:{if(Qb(ua,n,0,0)|0){Rb(c[S>>2]|0,c[T>>2]|0,U,n,e,0)|0;Ea=1}else Ea=0;if(!V){ya=64;break a}if(!na){za=(y|0)==(ra<<2|0);Aa=f+(ra+ma<<4)|0;Ca=0;while(1){if(!za){Ba=0;do{Da=e+(Ca<<4)+(Ba<<2)|0;Fa=Ba<<2;a[Aa+Fa>>0]=a[Da>>0]|0;a[Aa+(Fa|1)>>0]=a[Da+1>>0]|0;a[Aa+(Fa|2)>>0]=a[Da+2>>0]|0;a[Aa+(Fa|3)>>0]=a[Da+3>>0]|0;Ba=Ba+1|0}while((Ba|0)!=(va|0))}Ca=Ca+1|0;if((Ca|0)==(j|0))break;else Aa=Aa+W|0}}if(Ea){wa=qa;xa=oa}else{z=0;ya=98;break a}break}case 25:case 24:{if(Qb(ua,n,0,0)|0){Rb(c[X>>2]|0,c[Y>>2]|0,Z,n,e,0)|0;Ga=1}else Ga=0;if(!$){ya=74;break a}if(!na){Aa=(y|0)==(ra<<2|0);Ca=f+(ra+ma<<3)|0;za=0;while(1){if(!Aa){Ba=0;do{Da=e+(za<<4)+(Ba<<2)|0;if(ba){Fa=c[Da>>2]|0;Ha=((Fa&255)*31|0)+128|0;Ia=((Fa>>>8&255)*63|0)+128|0;Ja=((Fa>>>16&255)*31|0)+128|0;Ka=((Ia>>>8)+Ia|0)>>>8<<5|((Ha>>>8)+Ha|0)>>>8<<11|((Ja>>>8)+Ja|0)>>>8}else{Ja=((d[Da+2>>0]|0)*31|0)+128|0;Ha=((d[Da+1>>0]|0)*63|0)+128|0;Ia=((d[Da>>0]|0)*31|0)+128|0;Ka=((Ha>>>8)+Ha|0)>>>8<<5|((Ja>>>8)+Ja|0)>>>8<<11|((Ia>>>8)+Ia|0)>>>8}Ia=Ba<<1;a[Ca+Ia>>0]=Ka;a[Ca+(Ia|1)>>0]=Ka>>>8;Ba=Ba+1|0}while((Ba|0)!=(va|0))}za=za+1|0;if((za|0)==(j|0))break;else Ca=Ca+aa|0}}if(Ga){wa=qa;xa=oa}else{z=0;ya=98;break a}break}case 29:{if(Qb(ua,n,0,0)|0){Rb(c[ca>>2]|0,c[da>>2]|0,ea,n,e,0)|0;La=1}else La=0;if(!$){ya=87;break a}if(!na){Ca=(y|0)==(ra<<2|0);za=f+(ra+ma<<3)|0;Aa=0;while(1){if(!Ca){Ba=0;do{Ia=c[e+(Aa<<4)+(Ba<<2)>>2]|0;Ja=((Ia&255)*15|0)+128|0;Ha=((Ia>>>8&255)*15|0)+128|0;Da=((Ia>>>16&255)*15|0)+128|0;Fa=((Da>>>8)+Da|0)>>>8<<4;Da=((Ia>>>24)*15|0)+128|0;Ia=Ba<<1;a[za+Ia>>0]=Fa|((Da>>>8)+Da|0)>>>8;a[za+(Ia|1)>>0]=(((Ja>>>8)+Ja|0)>>>8<<12|(Ha>>>8)+Ha&16128|Fa)>>>8;Ba=Ba+1|0}while((Ba|0)!=(va|0))}Aa=Aa+1|0;if((Aa|0)==(j|0))break;else za=za+aa|0}}if(La){wa=qa;xa=oa}else{z=0;ya=98;break a}break}default:{ya=94;break a}}while(0);ra=ra+1|0;va=ua+16|0;if(ra>>>0>=g>>>0){ja=xa;ka=wa;la=va;break b}else{oa=xa;qa=wa;sa=sa+4|0;ta=ta+m|0;ua=va}}}while(0);v=v+1|0;if(v>>>0>=h>>>0){z=1;ya=98;break}else{ga=ja;u=ka;ha=ha+4|0;ia=la}}switch(ya|0){case 25:{z=0;i=s;return z|0}case 33:{z=0;i=s;return z|0}case 39:{z=0;i=s;return z|0}case 41:break;case 50:{z=0;i=s;return z|0}case 59:{z=0;i=s;return z|0}case 64:{pa(475075,474791,9453,474827);break}case 74:{pa(475133,474791,9482,474827);break}case 87:{pa(475133,474791,9511,474827);break}case 94:{pa(475191,474791,9534,474827);break}case 95:{z=0;i=s;return z|0}case 98:{i=s;return z|0}}z=0;i=s;return z|0}function tb(b,f,g,h,j){b=b|0;f=f|0;g=g|0;h=h|0;j=j|0;var k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0,$=0,aa=0,ba=0,ca=0,da=0,ea=0,fa=0,ga=0,ha=0,ia=0,ja=0,ka=0,la=0,ma=0,na=0,oa=0,qa=0,ra=0,sa=0,ta=0,ua=0,va=0,wa=0,xa=0,ya=0,za=0,Aa=0,Ba=0,Ca=0,Da=0,Ea=0,Fa=0,Ga=0,Ha=0,Ia=0,Ja=0,Ka=0,La=0,Ma=0,Na=0,Oa=0,Pa=0,Qa=0,Ra=0,Sa=0,Ta=0,Ua=0,Va=0,Wa=0,Xa=0,Ya=0,Za=0,_a=0,$a=0,ab=0,bb=0,cb=0,db=0,eb=0,fb=0,gb=0,hb=0,ib=0,jb=0,kb=0,lb=0,mb=0,nb=0,ob=0,pb=0,qb=0,rb=0,sb=0,tb=0,ub=0,vb=0,wb=0,xb=0,yb=0,zb=0,Ab=0,Bb=0,Cb=0,Db=0,Eb=0,Fb=0,Gb=0,Hb=0,Ib=0,Jb=0,Kb=0,Lb=0,Mb=0,Nb=0,Ob=0,Pb=0,Sb=0;j=i;i=i+368|0;k=j+216|0;l=j+152|0;m=j+88|0;n=j+76|0;o=j;p=j+64|0;if(!((g|0)!=0&(h|0)!=0)){q=0;i=j;return q|0}r=g<<2;if(!r){q=0;i=j;return q|0}if(r+-1&r){q=0;i=j;return q|0}r=h<<2;if(!r){q=0;i=j;return q|0}if(r+-1&r){q=0;i=j;return q|0}r=_(h,g)|0;c[p>>2]=0;s=p+4|0;c[s>>2]=0;c[p+8>>2]=0;do if(r)if(r>>>0>1073741823)Kc(p);else{t=r<<2;u=Lc(t)|0;c[p>>2]=u;v=u+(r<<2)|0;c[p+8>>2]=v;Hd(u|0,0,t|0)|0;c[s>>2]=v;break}while(0);r=k+104|0;v=k+108|0;t=k+112|0;u=0;a:while(1){w=_(u,g)|0;x=0;while(1){y=x+w|0;if(!(Qb(b+(y<<4)|0,k,0,0)|0)){z=36;break a}Rb(c[r>>2]|0,c[v>>2]|0,t,k,l,0)|0;A=-1;B=-1;C=-1;D=-1;E=0;F=0;G=0;H=0;I=0;while(1){J=c[l+(I<<2)>>2]|0;K=J&255;L=(K&255)<(A&255)?K:A;M=(J&65535)>>>8&255;N=(M&255)<(B&255)?M:B;O=J>>>16&255;P=(O&255)<(C&255)?O:C;Q=J>>>24&255;J=(Q&255)<(D&255)?Q:D;R=(E&255)<(K&255)?K:E;K=(F&255)<(M&255)?M:F;M=(G&255)<(O&255)?O:G;O=(H&255)<(Q&255)?Q:H;I=I+1|0;if((I|0)==16){S=L;T=N;U=P;V=J;W=R;X=K;Y=M;Z=O;break}else{A=L;B=N;C=P;D=J;E=R;F=K;G=M;H=O}}H=a[501192+(V&255)>>0]|0;G=S&255;if(V<<24>>24==-1){F=a[500093+G>>0]|0;E=a[500093+(T&255)>>0]|0;if(((E|F)&255)>=32){z=17;break a}D=(F&255)<<10|(E&255)<<5|(d[500349+(U&255)>>0]|0)<<1|32768;if(D>>>0<65536)$=D;else{z=19;break a}}else{D=a[500349+G>>0]|0;G=a[500349+(T&255)>>0]|0;E=a[501448+(U&255)>>0]|0;if(!(((G|D)&255)<16&((E|H)&255)<8)){z=21;break a}F=(D&255)<<8|(H&255)<<12|(G&255)<<4|(E&255)<<1;if(F>>>0<65536)$=F;else{z=23;break a}}F=Z&255;E=a[501841+F>>0]|0;G=W&255;if((F+-239|0)>>>0<17){F=a[500680+G>>0]|0;H=a[500680+(X&255)>>0]|0;D=a[500680+(Y&255)>>0]|0;if(((H|F|D)&255)>=32){z=26;break a}C=(F&255)<<10|(H&255)<<5|D&255|32768;if(C>>>0>=65536){z=28;break a}aa=C<<16|$&65535}else{C=a[500936+G>>0]|0;G=a[500936+(X&255)>>0]|0;D=a[500936+(Y&255)>>0]|0;if(!((Z&255)<239?((G|C|D)&255)<16:0)){z=31;break a}H=(C&255)<<8|(E&255)<<12|(G&255)<<4|D&255;if(H>>>0>=65536){z=33;break a}aa=H<<16|$&65535}H=c[p>>2]|0;c[H+(y<<2)>>2]=aa;x=x+1|0;if(x>>>0>=g>>>0){ba=H;break}}u=u+1|0;if(u>>>0>=h>>>0){ca=ba;z=38;break}}switch(z|0){case 17:{pa(501721,474791,3147,501704);break}case 19:{pa(500638,474791,3176,501704);break}case 21:{pa(501754,474791,3164,501704);break}case 23:{pa(500638,474791,3176,501704);break}case 26:{pa(500605,474791,3154,501704);break}case 28:{pa(500638,474791,3176,501704);break}case 31:{pa(501797,474791,3171,501704);break}case 33:{pa(500638,474791,3176,501704);break}case 36:{da=0;break}case 38:{z=g+-1|0;ba=h+-1|0;if(!z)ea=0;else{u=z;aa=0;while(1){u=u>>>1;$=aa+1|0;if(!u){ea=$;break}else aa=$}}if(!ba)fa=0;else{aa=ba;u=0;while(1){aa=aa>>>1;$=u+1|0;if(!aa){fa=$;break}else u=$}}u=ea>>>0<fa>>>0?ea:fa;fa=u<<1;ea=(1<<fa)+-1|0;if((h|0)>0){aa=(g|0)>0;$=k+104|0;Z=k+108|0;Y=k+112|0;X=(g|0)==(h|0);W=l+32|0;U=m+32|0;T=n+4|0;V=l+36|0;S=m+36|0;t=n+8|0;v=l+40|0;r=m+40|0;x=l+16|0;w=l+4|0;H=l+20|0;D=m+16|0;G=m+4|0;E=m+20|0;C=l+8|0;F=l+24|0;B=m+8|0;A=m+24|0;I=g>>>0>h>>>0;O=o+4|0;M=o+16|0;K=o+20|0;R=o+8|0;J=o+12|0;P=o+24|0;N=o+28|0;L=o+32|0;Q=o+36|0;ga=o+48|0;ha=o+52|0;ia=o+40|0;ja=o+44|0;ka=o+56|0;la=o+60|0;ma=0;na=0;while(1){oa=na+-1|0;qa=0;do{ra=_(oa+qa&ba,g)|0;c[n+(qa<<2)>>2]=ca+(ra<<2);sa=0;do{ta=c[ca+((sa+-1&z)+ra<<2)>>2]|0;if(!(ta&32768)){ua=a[508839+(ta>>>12&7)>>0]|0;va=d[508831+(ta>>>1&7)>>0]|0;wa=d[508815+(ta>>>4&15)>>0]|0;xa=d[508815+(ta>>>8&15)>>0]|0}else{ua=-1;va=d[508815+(ta>>>1&15)>>0]|0;wa=d[508783+(ta>>>5&31)>>0]|0;xa=d[508783+(ta>>>10&31)>>0]|0}c[l+(sa<<4)+(qa<<2)>>2]=wa+xa+va+(ua&255);ya=ta>>>16;if(!(ya&32768)){za=a[508839+(ta>>>28&7)>>0]|0;Aa=d[508815+(ya&15)>>0]|0;Ba=d[508815+(ta>>>20&15)>>0]|0;Ca=d[508815+(ta>>>24&15)>>0]|0}else{za=-1;Aa=d[508783+(ya&31)>>0]|0;Ba=d[508783+(ta>>>21&31)>>0]|0;Ca=d[508783+(ta>>>26&31)>>0]|0}c[m+(sa<<4)+(qa<<2)>>2]=Ba+Ca+Aa+(za&255);sa=sa+1|0}while((sa|0)!=3);qa=qa+1|0}while((qa|0)!=3);if(aa){qa=(e[467106+(na>>8<<1)>>1]|0)<<16|(e[467106+((na&255)<<1)>>1]|0);oa=c[n>>2]|0;sa=c[T>>2]|0;ra=c[t>>2]|0;y=na>>u<<fa;ta=ma;ya=0;while(1){if(Qb(b+(ta<<4)|0,k,0,0)|0)Rb(c[$>>2]|0,c[Z>>2]|0,Y,k,o,0)|0;Da=qa|(e[467106+(ya>>8<<1)>>1]|0)<<17|(e[467106+((ya&255)<<1)>>1]|0)<<1;do if(!X){Ea=Da&ea;if(I){Fa=Ea|ya>>u<<fa;break}else{Fa=Ea|y;break}}else Fa=Da;while(0);c[f+(Fa<<3)+4>>2]=c[ca+(ta<<2)>>2];ya=ya+1|0;Da=ya&z;Ea=c[oa+(Da<<2)>>2]|0;if(!(Ea&32768)){Ga=a[508839+(Ea>>>12&7)>>0]|0;Ha=d[508831+(Ea>>>1&7)>>0]|0;Ia=d[508815+(Ea>>>4&15)>>0]|0;Ja=d[508815+(Ea>>>8&15)>>0]|0}else{Ga=-1;Ha=d[508815+(Ea>>>1&15)>>0]|0;Ia=d[508783+(Ea>>>5&31)>>0]|0;Ja=d[508783+(Ea>>>10&31)>>0]|0}c[W>>2]=Ia+Ja+Ha+(Ga&255);Ka=Ea>>>16;if(!(Ka&32768)){La=a[508839+(Ea>>>28&7)>>0]|0;Ma=d[508815+(Ka&15)>>0]|0;Na=d[508815+(Ea>>>20&15)>>0]|0;Oa=d[508815+(Ea>>>24&15)>>0]|0}else{La=-1;Ma=d[508783+(Ka&31)>>0]|0;Na=d[508783+(Ea>>>21&31)>>0]|0;Oa=d[508783+(Ea>>>26&31)>>0]|0}c[U>>2]=Na+Oa+Ma+(La&255);Ea=c[sa+(Da<<2)>>2]|0;if(!(Ea&32768)){Pa=a[508839+(Ea>>>12&7)>>0]|0;Qa=d[508831+(Ea>>>1&7)>>0]|0;Ra=d[508815+(Ea>>>4&15)>>0]|0;Sa=d[508815+(Ea>>>8&15)>>0]|0}else{Pa=-1;Qa=d[508815+(Ea>>>1&15)>>0]|0;Ra=d[508783+(Ea>>>5&31)>>0]|0;Sa=d[508783+(Ea>>>10&31)>>0]|0}c[V>>2]=Ra+Sa+Qa+(Pa&255);Ka=Ea>>>16;if(!(Ka&32768)){Ta=a[508839+(Ea>>>28&7)>>0]|0;Ua=d[508815+(Ka&15)>>0]|0;Va=d[508815+(Ea>>>20&15)>>0]|0;Wa=d[508815+(Ea>>>24&15)>>0]|0}else{Ta=-1;Ua=d[508783+(Ka&31)>>0]|0;Va=d[508783+(Ea>>>21&31)>>0]|0;Wa=d[508783+(Ea>>>26&31)>>0]|0}c[S>>2]=Va+Wa+Ua+(Ta&255);Ea=c[ra+(Da<<2)>>2]|0;if(!(Ea&32768)){Xa=a[508839+(Ea>>>12&7)>>0]|0;Ya=d[508831+(Ea>>>1&7)>>0]|0;Za=d[508815+(Ea>>>4&15)>>0]|0;_a=d[508815+(Ea>>>8&15)>>0]|0}else{Xa=-1;Ya=d[508815+(Ea>>>1&15)>>0]|0;Za=d[508783+(Ea>>>5&31)>>0]|0;_a=d[508783+(Ea>>>10&31)>>0]|0}c[v>>2]=Za+_a+Ya+(Xa&255);Da=Ea>>>16;if(!(Da&32768)){$a=a[508839+(Ea>>>28&7)>>0]|0;ab=d[508815+(Da&15)>>0]|0;bb=d[508815+(Ea>>>20&15)>>0]|0;cb=d[508815+(Ea>>>24&15)>>0]|0}else{$a=-1;ab=d[508783+(Da&31)>>0]|0;bb=d[508783+(Ea>>>21&31)>>0]|0;cb=d[508783+(Ea>>>26&31)>>0]|0}Ea=bb+cb+ab+($a&255)|0;c[r>>2]=Ea;Da=c[l>>2]|0;Ka=c[x>>2]|0;db=c[w>>2]|0;eb=c[H>>2]|0;fb=c[m>>2]|0;gb=c[D>>2]|0;hb=c[G>>2]|0;ib=c[E>>2]|0;jb=Ka+Da+db+eb<<2;kb=gb+fb+hb+ib<<2;lb=c[o>>2]|0;mb=kb-jb|0;nb=((lb>>>24)+(lb&255)+(lb>>>8&255)+(lb>>>16&255)<<4)-jb<<4;lb=(kb|0)<(jb|0);jb=lb?0-nb|0:nb;nb=lb?0-mb|0:mb;mb=Da<<1;lb=Ka*6|0;kb=eb*6|0;ob=lb+mb+(db<<1)+kb|0;pb=fb<<1;qb=gb*6|0;rb=ib*6|0;sb=qb+pb+(hb<<1)+rb|0;tb=c[O>>2]|0;ub=sb-ob|0;vb=((tb>>>24)+(tb&255)+(tb>>>8&255)+(tb>>>16&255)<<4)-ob<<4;tb=(sb|0)<(ob|0);ob=tb?0-vb|0:vb;vb=tb?0-ub|0:ub;ub=(Ka<<1)+mb+(db*6|0)+kb|0;mb=(gb<<1)+pb+(hb*6|0)+rb|0;pb=c[M>>2]|0;tb=mb-ub|0;sb=((pb>>>24)+(pb&255)+(pb>>>8&255)+(pb>>>16&255)<<4)-ub<<4;pb=(mb|0)<(ub|0);ub=pb?0-sb|0:sb;sb=pb?0-tb|0:tb;tb=Ka*3|0;pb=db*3|0;mb=eb*9|0;wb=tb+Da+pb+mb|0;Da=gb*3|0;xb=hb*3|0;yb=ib*9|0;zb=Da+fb+xb+yb|0;fb=c[K>>2]|0;Ab=zb-wb|0;Bb=((fb>>>24)+(fb&255)+(fb>>>8&255)+(fb>>>16&255)<<4)-wb<<4;fb=(zb|0)<(wb|0);wb=fb?0-Bb|0:Bb;Bb=fb?0-Ab|0:Ab;Ab=c[W>>2]|0;fb=c[V>>2]|0;zb=c[U>>2]|0;Cb=c[S>>2]|0;Db=eb+Ka<<3;Eb=ib+gb<<3;Fb=c[R>>2]|0;Gb=Eb-Db|0;Hb=((Fb>>>24)+(Fb&255)+(Fb>>>8&255)+(Fb>>>16&255)<<4)-Db<<4;Fb=(Eb|0)<(Db|0);Db=Fb?0-Hb|0:Hb;Hb=Fb?0-Gb|0:Gb;Gb=kb+lb+(Ab<<1)+(fb<<1)|0;lb=rb+qb+(zb<<1)+(Cb<<1)|0;qb=c[J>>2]|0;rb=lb-Gb|0;kb=((qb>>>24)+(qb&255)+(qb>>>8&255)+(qb>>>16&255)<<4)-Gb<<4;qb=(lb|0)<(Gb|0);Gb=qb?0-kb|0:kb;kb=qb?0-rb|0:rb;rb=eb*12|0;qb=rb+(Ka<<2)|0;Ka=ib*12|0;lb=Ka+(gb<<2)|0;gb=c[P>>2]|0;Fb=lb-qb|0;Eb=((gb>>>24)+(gb&255)+(gb>>>8&255)+(gb>>>16&255)<<4)-qb<<4;gb=(lb|0)<(qb|0);qb=gb?0-Eb|0:Eb;Eb=gb?0-Fb|0:Fb;Fb=fb*3|0;gb=mb+tb+Ab+Fb|0;Ab=Cb*3|0;tb=yb+Da+zb+Ab|0;zb=c[N>>2]|0;Da=tb-gb|0;lb=((zb>>>24)+(zb&255)+(zb>>>8&255)+(zb>>>16&255)<<4)-gb<<4;zb=(tb|0)<(gb|0);gb=zb?0-lb|0:lb;lb=zb?0-Da|0:Da;Da=c[C>>2]|0;zb=c[F>>2]|0;tb=c[B>>2]|0;Ib=c[A>>2]|0;Jb=eb+db|0;Kb=Jb<<3;Lb=ib+hb|0;Mb=Lb<<3;Nb=c[L>>2]|0;Ob=Mb-Kb|0;Pb=((Nb>>>24)+(Nb&255)+(Nb>>>8&255)+(Nb>>>16&255)<<4)-Kb<<4;Nb=(Mb|0)<(Kb|0);Kb=Nb?0-Pb|0:Pb;Pb=Nb?0-Ob|0:Ob;Ob=rb+(db<<2)|0;db=Ka+(hb<<2)|0;hb=c[Q>>2]|0;Nb=db-Ob|0;Mb=((hb>>>24)+(hb&255)+(hb>>>8&255)+(hb>>>16&255)<<4)-Ob<<4;hb=(db|0)<(Ob|0);Ob=hb?0-Mb|0:Mb;Mb=hb?0-Nb|0:Nb;Nb=(Da<<1)+(Jb*6|0)+(zb<<1)|0;Jb=(tb<<1)+(Lb*6|0)+(Ib<<1)|0;Lb=c[ga>>2]|0;hb=Jb-Nb|0;db=((Lb>>>24)+(Lb&255)+(Lb>>>8&255)+(Lb>>>16&255)<<4)-Nb<<4;Lb=(Jb|0)<(Nb|0);Nb=Lb?0-db|0:db;db=Lb?0-hb|0:hb;hb=zb*3|0;Lb=mb+pb+Da+hb|0;Da=Ib*3|0;pb=yb+xb+tb+Da|0;tb=c[ha>>2]|0;xb=pb-Lb|0;Jb=((tb>>>24)+(tb&255)+(tb>>>8&255)+(tb>>>16&255)<<4)-Lb<<4;tb=(pb|0)<(Lb|0);Lb=tb?0-Jb|0:Jb;Jb=tb?0-xb|0:xb;xb=eb<<4;eb=ib<<4;ib=c[ia>>2]|0;tb=eb-xb|0;pb=((ib>>>24)+(ib&255)+(ib>>>8&255)+(ib>>>16&255)<<4)-xb<<4;ib=(eb|0)<(xb|0);xb=ib?0-tb|0:tb;tb=ib?0-pb|0:pb;pb=(fb<<2)+rb|0;fb=(Cb<<2)+Ka|0;Cb=c[ja>>2]|0;ib=fb-pb|0;eb=((Cb>>>24)+(Cb&255)+(Cb>>>8&255)+(Cb>>>16&255)<<4)-pb<<4;Cb=(fb|0)<(pb|0);pb=Cb?0-ib|0:ib;ib=Cb?0-eb|0:eb;eb=(zb<<2)+rb|0;rb=(Ib<<2)+Ka|0;Ka=c[ka>>2]|0;Ib=rb-eb|0;zb=((Ka>>>24)+(Ka&255)+(Ka>>>8&255)+(Ka>>>16&255)<<4)-eb<<4;Ka=(rb|0)<(eb|0);eb=Ka?0-Ib|0:Ib;Ib=Ka?0-zb|0:zb;zb=Fb+mb+hb+(c[v>>2]|0)|0;hb=yb+Ea+Ab+Da|0;Da=c[la>>2]|0;Ab=hb-zb|0;Ea=((Da>>>24)+(Da&255)+(Da>>>8&255)+(Da>>>16&255)<<4)-zb<<4;Da=(hb|0)<(zb|0);zb=Da?0-Ab|0:Ab;Ab=Da?0-Ea|0:Ea;c[f+(Fa<<3)>>2]=((ob|0)>(vb*13|0)?12:(ob|0)>(vb<<3|0)?8:(ob|0)>(vb*3|0)?4:0)|((jb|0)>(nb*13|0)?3:(jb|0)>(nb<<3|0)?2:(jb|0)>(nb*3|0)&1)|((ub|0)>(sb*13|0)?768:(ub|0)>(sb<<3|0)?512:(ub|0)>(sb*3|0)?256:0)|((wb|0)>(Bb*13|0)?3072:(wb|0)>(Bb<<3|0)?2048:(wb|0)>(Bb*3|0)?1024:0)|((Db|0)>(Hb*13|0)?48:(Db|0)>(Hb<<3|0)?32:(Db|0)>(Hb*3|0)?16:0)|((Gb|0)>(kb*13|0)?192:(Gb|0)>(kb<<3|0)?128:(Gb|0)>(kb*3|0)?64:0)|((qb|0)>(Eb*13|0)?12288:(qb|0)>(Eb<<3|0)?8192:(qb|0)>(Eb*3|0)?4096:0)|((gb|0)>(lb*13|0)?49152:(gb|0)>(lb<<3|0)?32768:(gb|0)>(lb*3|0)?16384:0)|((Kb|0)>(Pb*13|0)?196608:(Kb|0)>(Pb<<3|0)?131072:(Kb|0)>(Pb*3|0)?65536:0)|((Ob|0)>(Mb*13|0)?786432:(Ob|0)>(Mb<<3|0)?524288:(Ob|0)>(Mb*3|0)?262144:0)|((Nb|0)>(db*13|0)?50331648:(Nb|0)>(db<<3|0)?33554432:(Nb|0)>(db*3|0)?16777216:0)|((Lb|0)>(Jb*13|0)?201326592:(Lb|0)>(Jb<<3|0)?134217728:(Lb|0)>(Jb*3|0)?67108864:0)|((tb|0)>(xb*13|0)?3145728:(tb|0)>(xb<<3|0)?2097152:(tb|0)>(xb*3|0)?1048576:0)|((ib|0)>(pb*13|0)?12582912:(ib|0)>(pb<<3|0)?8388608:(ib|0)>(pb*3|0)?4194304:0)|((Ib|0)>(eb*13|0)?805306368:(Ib|0)>(eb<<3|0)?536870912:(Ib|0)>(eb*3|0)?268435456:0)|((Ab|0)>(zb*13|0)?-1073741824:(Ab|0)>(zb<<3|0)?-2147483648:(Ab|0)>(zb*3|0)?1073741824:0);c[l>>2]=c[x>>2];c[x>>2]=c[W>>2];c[w>>2]=c[H>>2];c[H>>2]=c[V>>2];c[C>>2]=c[F>>2];c[F>>2]=c[v>>2];c[m>>2]=c[D>>2];c[D>>2]=c[U>>2];c[G>>2]=c[E>>2];c[E>>2]=c[S>>2];c[B>>2]=c[A>>2];c[A>>2]=c[r>>2];if((ya|0)==(g|0))break;else ta=ta+1|0}Sb=ma+g|0}else Sb=ma;na=na+1|0;if((na|0)==(h|0))break;else ma=Sb}}da=1;break}}Sb=c[p>>2]|0;if(!Sb){q=da;i=j;return q|0}p=c[s>>2]|0;if((p|0)!=(Sb|0))c[s>>2]=p+(~((p+-4-Sb|0)>>>2)<<2);Mc(Sb);q=da;i=j;return q|0}function ub(b,f,g,h,j,k){b=b|0;f=f|0;g=g|0;h=h|0;j=j|0;k=k|0;var l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0,$=0,aa=0,ba=0,ca=0,da=0,ea=0,fa=0,ga=0,ha=0,ia=0,ja=0,ka=0,la=0,ma=0,na=0,oa=0,qa=0,ra=0,sa=0,ta=0,ua=0,va=0,wa=0,xa=0,ya=0,za=0,Aa=0,Ba=0,Ca=0,Da=0,Ea=0,Fa=0,Ga=0,Ha=0,Ia=0,Ja=0,Ka=0,La=0,Ma=0,Na=0,Oa=0,Pa=0,Qa=0,Ra=0,Sa=0,Ta=0,Ua=0,Va=0,Wa=0,Xa=0,Ya=0,Za=0,_a=0,$a=0,ab=0,bb=0,cb=0,db=0,eb=0,fb=0,gb=0,hb=0,ib=0,jb=0,kb=0,lb=0,mb=0,nb=0,ob=0,pb=0,qb=0,rb=0,sb=0,tb=0,ub=0,vb=0,wb=0,xb=0,yb=0,zb=0,Ab=0,Bb=0,Cb=0,Db=0,Eb=0,Fb=0,Gb=0,Hb=0,Ib=0,Jb=0,Kb=0,Lb=0,Mb=0,Nb=0,Ob=0,Pb=0,Sb=0,Tb=0,Ub=0,Vb=0,Wb=0,Xb=0,Yb=0,Zb=0,_b=0,$b=0,ac=0,bc=0,cc=0,dc=0,ec=0,fc=0,gc=0,hc=0,ic=0,jc=0,kc=0,lc=0,mc=0,nc=0,oc=0,pc=0,qc=0,rc=0,sc=0,tc=0,uc=0,vc=0,wc=0,xc=0,yc=0,zc=0,Ac=0,Bc=0,Cc=0,Dc=0,Ec=0,Fc=0,Gc=0,Hc=0,Ic=0,Jc=0,Nc=0,Oc=0,Pc=0,Qc=0,Rc=0;j=i;i=i+368|0;l=j+216|0;m=j+152|0;n=j+88|0;o=j+76|0;p=j;q=j+64|0;if(!((g|0)!=0&(h|0)!=0)){r=0;i=j;return r|0}s=g<<2;if(!s){r=0;i=j;return r|0}if(s+-1&s){r=0;i=j;return r|0}s=h<<2;if(!s){r=0;i=j;return r|0}if(s+-1&s){r=0;i=j;return r|0}s=_(h,g)|0;c[q>>2]=0;t=q+4|0;c[t>>2]=0;c[q+8>>2]=0;do if(s)if(s>>>0>1073741823)Kc(q);else{u=s<<2;v=Lc(u)|0;c[q>>2]=v;w=v+(s<<2)|0;c[q+8>>2]=w;Hd(v|0,0,u|0)|0;c[t>>2]=w;break}while(0);s=l+104|0;w=l+108|0;u=l+112|0;v=m+3|0;x=m+4+3|0;y=m+8+3|0;z=m+12+3|0;A=m+16+3|0;B=m+20+3|0;C=m+24+3|0;D=m+28+3|0;E=m+32+3|0;F=m+36+3|0;G=m+40+3|0;H=m+44+3|0;I=m+48+3|0;J=m+52+3|0;K=m+56+3|0;L=m+60+3|0;M=0;a:while(1){N=_(M,g)|0;O=0;while(1){P=O+N|0;if(!(Qb(b+(P<<4)|0,l,0,0)|0)){Q=23;break a}Rb(c[s>>2]|0,c[w>>2]|0,u,l,m,0)|0;if(k){R=d[v>>0]|0;S=d[x>>0]|0;T=S>>>0<R>>>0?S:R;U=R>>>0<S>>>0?S:R;R=d[y>>0]|0;S=R>>>0<T>>>0?R:T;T=U>>>0<R>>>0?R:U;U=d[z>>0]|0;R=U>>>0<S>>>0?U:S;S=T>>>0<U>>>0?U:T;T=d[A>>0]|0;U=T>>>0<R>>>0?T:R;R=S>>>0<T>>>0?T:S;S=d[B>>0]|0;T=S>>>0<U>>>0?S:U;U=R>>>0<S>>>0?S:R;R=d[C>>0]|0;S=R>>>0<T>>>0?R:T;T=U>>>0<R>>>0?R:U;U=d[D>>0]|0;R=U>>>0<S>>>0?U:S;S=T>>>0<U>>>0?U:T;T=d[E>>0]|0;U=T>>>0<R>>>0?T:R;R=S>>>0<T>>>0?T:S;S=d[F>>0]|0;T=S>>>0<U>>>0?S:U;U=R>>>0<S>>>0?S:R;R=d[G>>0]|0;S=R>>>0<T>>>0?R:T;T=U>>>0<R>>>0?R:U;U=d[H>>0]|0;R=U>>>0<S>>>0?U:S;S=T>>>0<U>>>0?U:T;T=d[I>>0]|0;U=T>>>0<R>>>0?T:R;R=S>>>0<T>>>0?T:S;S=d[J>>0]|0;T=S>>>0<U>>>0?S:U;U=R>>>0<S>>>0?S:R;R=d[K>>0]|0;S=R>>>0<T>>>0?R:T;T=U>>>0<R>>>0?R:U;U=d[L>>0]|0;R=(U>>>0<S>>>0?U:S)&255;S=(T>>>0<U>>>0?U:T)&255;V=R;W=R;X=R;Y=S;Z=S;$=S}else{S=-1;R=-1;T=-1;U=0;aa=0;ba=0;ca=0;while(1){da=c[m+(ca<<2)>>2]|0;ea=da&255;fa=(ea&255)<(S&255)?ea:S;ga=(da&65535)>>>8&255;ha=(ga&255)<(R&255)?ga:R;ia=da>>>16&255;da=(ia&255)<(T&255)?ia:T;ja=(U&255)<(ea&255)?ea:U;ea=(aa&255)<(ga&255)?ga:aa;ga=(ba&255)<(ia&255)?ia:ba;ca=ca+1|0;if((ca|0)==16){V=da;W=ha;X=fa;Y=ga;Z=ea;$=ja;break}else{S=fa;R=ha;T=da;U=ja;aa=ea;ba=ga}}}ba=(d[500349+(V&255)>>0]|0)<<1;if(ba>>>0>=32){Q=17;break a}aa=ba|(d[500093+(W&255)>>0]|0)<<5|(d[500093+(X&255)>>0]|0)<<10|32768;if(aa>>>0>=65536){Q=19;break a}ba=d[500680+(Y&255)>>0]|0|(d[500680+(Z&255)>>0]|0)<<5|(d[500680+($&255)>>0]|0)<<10|32768;if(ba>>>0>=65536){Q=21;break a}U=c[q>>2]|0;c[U+(P<<2)>>2]=ba<<16|aa&65534;O=O+1|0;if(O>>>0>=g>>>0){ka=U;break}}M=M+1|0;if(M>>>0>=h>>>0){la=ka;Q=25;break}}if((Q|0)==17)pa(500605,474791,3082,500067);else if((Q|0)==19)pa(500638,474791,3092,500067);else if((Q|0)==21)pa(500638,474791,3123,500655);else if((Q|0)==23)ma=0;else if((Q|0)==25){ka=g+-1|0;M=h+-1|0;if(!ka)na=0;else{$=ka;Z=0;while(1){$=$>>>1;Y=Z+1|0;if(!$){na=Y;break}else Z=Y}}if(!M)oa=0;else{Z=M;$=0;while(1){Z=Z>>>1;Y=$+1|0;if(!Z){oa=Y;break}else $=Y}}$=na>>>0<oa>>>0?na:oa;oa=$<<1;na=(1<<oa)+-1|0;b:do if((h|0)>0){Z=(g|0)>0;Y=l+104|0;X=l+108|0;W=l+112|0;V=(g|0)==(h|0);L=m+32|0;K=n+32|0;J=o+4|0;I=m+36|0;H=n+36|0;G=o+8|0;F=m+40|0;E=n+40|0;D=m+16|0;C=m+4|0;B=m+20|0;A=n+16|0;z=n+4|0;y=n+20|0;x=m+8|0;v=m+24|0;u=n+8|0;w=n+24|0;s=g>>>0>h>>>0;O=ka&1;N=p+3|0;U=p+1|0;aa=p+2|0;ba=p+3|0;T=p+4|0;R=T+3|0;S=T+1|0;ca=T+2|0;ga=T+3|0;ea=p+8|0;ja=ea+3|0;da=ea+1|0;ha=ea+2|0;fa=ea+3|0;ia=p+12|0;qa=ia+3|0;ra=ia+1|0;sa=ia+2|0;ta=ia+3|0;ua=p+16|0;va=ua+3|0;wa=ua+1|0;xa=ua+2|0;ya=ua+3|0;za=p+20|0;Aa=za+3|0;Ba=za+1|0;Ca=za+2|0;Da=za+3|0;Ea=p+24|0;Fa=Ea+3|0;Ga=Ea+1|0;Ha=Ea+2|0;Ia=Ea+3|0;Ja=p+28|0;Ka=Ja+3|0;La=Ja+1|0;Ma=Ja+2|0;Na=Ja+3|0;Oa=p+32|0;Pa=Oa+3|0;Qa=Oa+1|0;Ra=Oa+2|0;Sa=Oa+3|0;Ta=p+36|0;Ua=Ta+3|0;Va=Ta+1|0;Wa=Ta+2|0;Xa=Ta+3|0;Ya=p+40|0;Za=Ya+3|0;_a=Ya+1|0;$a=Ya+2|0;ab=Ya+3|0;bb=p+44|0;cb=bb+3|0;db=bb+1|0;eb=bb+2|0;fb=bb+3|0;gb=p+48|0;hb=gb+3|0;ib=gb+1|0;jb=gb+2|0;kb=gb+3|0;lb=p+52|0;mb=lb+3|0;nb=lb+1|0;ob=lb+2|0;pb=lb+3|0;qb=p+56|0;rb=qb+3|0;sb=qb+1|0;tb=qb+2|0;ub=qb+3|0;vb=p+60|0;wb=vb+3|0;xb=vb+1|0;yb=vb+2|0;zb=vb+3|0;Ab=p+4|0;Bb=p+16|0;Cb=p+20|0;Db=p+8|0;Eb=p+12|0;Fb=p+24|0;Gb=p+28|0;Hb=p+32|0;Ib=p+36|0;Jb=p+48|0;Kb=p+52|0;Lb=p+40|0;Mb=p+44|0;Nb=p+56|0;Ob=p+60|0;Pb=0;Sb=0;c:while(1){Tb=Sb+-1|0;Ub=0;do{Vb=_(Tb+Ub&M,g)|0;Wb=la+(Vb<<2)|0;c[o+(Ub<<2)>>2]=Wb;Xb=c[la+(Vb+ka<<2)>>2]|0;if(!(Xb&32768)){Q=33;break c}Yb=Xb&30;c[m+(Ub<<2)>>2]=((((Xb>>>10&31)+(Xb>>>5&31)+(Yb>>>4|Yb)|0)*255|0)>>>0)/31|0;Yb=Xb>>>16;if(!(Yb&32768)){Q=35;break c}c[n+(Ub<<2)>>2]=((((Xb>>>26&31)+(Xb>>>21&31)+(Yb&31)|0)*255|0)>>>0)/31|0;Yb=c[Wb>>2]|0;if(!(Yb&32768)){Q=33;break c}Wb=Yb&30;c[m+16+(Ub<<2)>>2]=((((Yb>>>10&31)+(Yb>>>5&31)+(Wb>>>4|Wb)|0)*255|0)>>>0)/31|0;Wb=Yb>>>16;if(!(Wb&32768)){Q=35;break c}c[n+16+(Ub<<2)>>2]=((((Yb>>>26&31)+(Yb>>>21&31)+(Wb&31)|0)*255|0)>>>0)/31|0;Wb=c[la+(Vb+O<<2)>>2]|0;if(!(Wb&32768)){Q=33;break c}Vb=Wb&30;c[m+32+(Ub<<2)>>2]=((((Wb>>>10&31)+(Wb>>>5&31)+(Vb>>>4|Vb)|0)*255|0)>>>0)/31|0;Vb=Wb>>>16;if(!(Vb&32768)){Q=35;break c}c[n+32+(Ub<<2)>>2]=((((Wb>>>26&31)+(Wb>>>21&31)+(Vb&31)|0)*255|0)>>>0)/31|0;Ub=Ub+1|0}while((Ub|0)<3);if(Z){Ub=(e[467106+(Sb>>8<<1)>>1]|0)<<16|(e[467106+((Sb&255)<<1)>>1]|0);Tb=c[o>>2]|0;P=c[J>>2]|0;Vb=c[G>>2]|0;Wb=Sb>>$<<oa;Yb=Pb;Xb=0;while(1){if(Qb(b+(Yb<<4)|0,l,0,0)|0)Rb(c[Y>>2]|0,c[X>>2]|0,W,l,p,0)|0;if(k){Zb=a[N>>0]|0;a[p>>0]=Zb;a[U>>0]=Zb;a[aa>>0]=Zb;a[ba>>0]=-1;Zb=a[R>>0]|0;a[T>>0]=Zb;a[S>>0]=Zb;a[ca>>0]=Zb;a[ga>>0]=-1;Zb=a[ja>>0]|0;a[ea>>0]=Zb;a[da>>0]=Zb;a[ha>>0]=Zb;a[fa>>0]=-1;Zb=a[qa>>0]|0;a[ia>>0]=Zb;a[ra>>0]=Zb;a[sa>>0]=Zb;a[ta>>0]=-1;Zb=a[va>>0]|0;a[ua>>0]=Zb;a[wa>>0]=Zb;a[xa>>0]=Zb;a[ya>>0]=-1;Zb=a[Aa>>0]|0;a[za>>0]=Zb;a[Ba>>0]=Zb;a[Ca>>0]=Zb;a[Da>>0]=-1;Zb=a[Fa>>0]|0;a[Ea>>0]=Zb;a[Ga>>0]=Zb;a[Ha>>0]=Zb;a[Ia>>0]=-1;Zb=a[Ka>>0]|0;a[Ja>>0]=Zb;a[La>>0]=Zb;a[Ma>>0]=Zb;a[Na>>0]=-1;Zb=a[Pa>>0]|0;a[Oa>>0]=Zb;a[Qa>>0]=Zb;a[Ra>>0]=Zb;a[Sa>>0]=-1;Zb=a[Ua>>0]|0;a[Ta>>0]=Zb;a[Va>>0]=Zb;a[Wa>>0]=Zb;a[Xa>>0]=-1;Zb=a[Za>>0]|0;a[Ya>>0]=Zb;a[_a>>0]=Zb;a[$a>>0]=Zb;a[ab>>0]=-1;Zb=a[cb>>0]|0;a[bb>>0]=Zb;a[db>>0]=Zb;a[eb>>0]=Zb;a[fb>>0]=-1;Zb=a[hb>>0]|0;a[gb>>0]=Zb;a[ib>>0]=Zb;a[jb>>0]=Zb;a[kb>>0]=-1;Zb=a[mb>>0]|0;a[lb>>0]=Zb;a[nb>>0]=Zb;a[ob>>0]=Zb;a[pb>>0]=-1;Zb=a[rb>>0]|0;a[qb>>0]=Zb;a[sb>>0]=Zb;a[tb>>0]=Zb;a[ub>>0]=-1;Zb=a[wb>>0]|0;a[vb>>0]=Zb;a[xb>>0]=Zb;a[yb>>0]=Zb;a[zb>>0]=-1}Zb=Ub|(e[467106+(Xb>>8<<1)>>1]|0)<<17|(e[467106+((Xb&255)<<1)>>1]|0)<<1;do if(!V){_b=Zb&na;if(s){$b=_b|Xb>>$<<oa;break}else{$b=_b|Wb;break}}else $b=Zb;while(0);c[f+($b<<3)+4>>2]=c[la+(Yb<<2)>>2];Xb=Xb+1|0;Zb=Xb&ka;_b=c[Tb+(Zb<<2)>>2]|0;if(!(_b&32768)){Q=48;break c}ac=_b&30;c[L>>2]=((((_b>>>10&31)+(_b>>>5&31)+(ac>>>4|ac)|0)*255|0)>>>0)/31|0;ac=_b>>>16;if(!(ac&32768)){Q=50;break c}c[K>>2]=((((_b>>>26&31)+(_b>>>21&31)+(ac&31)|0)*255|0)>>>0)/31|0;ac=c[P+(Zb<<2)>>2]|0;if(!(ac&32768)){Q=52;break c}_b=ac&30;c[I>>2]=((((ac>>>10&31)+(ac>>>5&31)+(_b>>>4|_b)|0)*255|0)>>>0)/31|0;_b=ac>>>16;if(!(_b&32768)){Q=54;break c}c[H>>2]=((((ac>>>26&31)+(ac>>>21&31)+(_b&31)|0)*255|0)>>>0)/31|0;_b=c[Vb+(Zb<<2)>>2]|0;if(!(_b&32768)){Q=56;break c}Zb=_b&30;c[F>>2]=((((_b>>>10&31)+(_b>>>5&31)+(Zb>>>4|Zb)|0)*255|0)>>>0)/31|0;Zb=_b>>>16;if(!(Zb&32768)){Q=58;break c}ac=((((_b>>>26&31)+(_b>>>21&31)+(Zb&31)|0)*255|0)>>>0)/31|0;c[E>>2]=ac;Zb=c[m>>2]|0;_b=c[D>>2]|0;bc=c[C>>2]|0;cc=c[B>>2]|0;dc=c[n>>2]|0;ec=c[A>>2]|0;fc=c[z>>2]|0;gc=c[y>>2]|0;hc=_b+Zb+bc+cc<<2;ic=ec+dc+fc+gc<<2;jc=c[p>>2]|0;kc=ic-hc|0;lc=((jc>>>8&255)+(jc&255)+(jc>>>16&255)<<4)-hc<<4;jc=(ic|0)<(hc|0);hc=jc?0-lc|0:lc;lc=jc?0-kc|0:kc;kc=Zb<<1;jc=_b*6|0;ic=cc*6|0;mc=jc+kc+(bc<<1)+ic|0;nc=dc<<1;oc=ec*6|0;pc=gc*6|0;qc=oc+nc+(fc<<1)+pc|0;rc=c[Ab>>2]|0;sc=qc-mc|0;tc=((rc>>>8&255)+(rc&255)+(rc>>>16&255)<<4)-mc<<4;rc=(qc|0)<(mc|0);mc=rc?0-tc|0:tc;tc=rc?0-sc|0:sc;sc=(_b<<1)+kc+(bc*6|0)+ic|0;kc=(ec<<1)+nc+(fc*6|0)+pc|0;nc=c[Bb>>2]|0;rc=kc-sc|0;qc=((nc>>>8&255)+(nc&255)+(nc>>>16&255)<<4)-sc<<4;nc=(kc|0)<(sc|0);sc=nc?0-qc|0:qc;qc=nc?0-rc|0:rc;rc=_b*3|0;nc=bc*3|0;kc=cc*9|0;uc=rc+Zb+nc+kc|0;Zb=ec*3|0;vc=fc*3|0;wc=gc*9|0;xc=Zb+dc+vc+wc|0;dc=c[Cb>>2]|0;yc=xc-uc|0;zc=((dc>>>8&255)+(dc&255)+(dc>>>16&255)<<4)-uc<<4;dc=(xc|0)<(uc|0);uc=dc?0-zc|0:zc;zc=dc?0-yc|0:yc;yc=c[L>>2]|0;dc=c[I>>2]|0;xc=c[K>>2]|0;Ac=c[H>>2]|0;Bc=cc+_b<<3;Cc=gc+ec<<3;Dc=c[Db>>2]|0;Ec=Cc-Bc|0;Fc=((Dc>>>8&255)+(Dc&255)+(Dc>>>16&255)<<4)-Bc<<4;Dc=(Cc|0)<(Bc|0);Bc=Dc?0-Fc|0:Fc;Fc=Dc?0-Ec|0:Ec;Ec=ic+jc+(yc<<1)+(dc<<1)|0;jc=pc+oc+(xc<<1)+(Ac<<1)|0;oc=c[Eb>>2]|0;pc=jc-Ec|0;ic=((oc>>>8&255)+(oc&255)+(oc>>>16&255)<<4)-Ec<<4;oc=(jc|0)<(Ec|0);Ec=oc?0-ic|0:ic;ic=oc?0-pc|0:pc;pc=cc*12|0;oc=pc+(_b<<2)|0;_b=gc*12|0;jc=_b+(ec<<2)|0;ec=c[Fb>>2]|0;Dc=jc-oc|0;Cc=((ec>>>8&255)+(ec&255)+(ec>>>16&255)<<4)-oc<<4;ec=(jc|0)<(oc|0);oc=ec?0-Cc|0:Cc;Cc=ec?0-Dc|0:Dc;Dc=dc*3|0;ec=kc+rc+yc+Dc|0;yc=Ac*3|0;rc=wc+Zb+xc+yc|0;xc=c[Gb>>2]|0;Zb=rc-ec|0;jc=((xc>>>8&255)+(xc&255)+(xc>>>16&255)<<4)-ec<<4;xc=(rc|0)<(ec|0);ec=xc?0-jc|0:jc;jc=xc?0-Zb|0:Zb;Zb=c[x>>2]|0;xc=c[v>>2]|0;rc=c[u>>2]|0;Gc=c[w>>2]|0;Hc=cc+bc|0;Ic=Hc<<3;Jc=gc+fc|0;Nc=Jc<<3;Oc=c[Hb>>2]|0;Pc=Nc-Ic|0;Qc=((Oc>>>8&255)+(Oc&255)+(Oc>>>16&255)<<4)-Ic<<4;Oc=(Nc|0)<(Ic|0);Ic=Oc?0-Qc|0:Qc;Qc=Oc?0-Pc|0:Pc;Pc=pc+(bc<<2)|0;bc=_b+(fc<<2)|0;fc=c[Ib>>2]|0;Oc=bc-Pc|0;Nc=((fc>>>8&255)+(fc&255)+(fc>>>16&255)<<4)-Pc<<4;fc=(bc|0)<(Pc|0);Pc=fc?0-Nc|0:Nc;Nc=fc?0-Oc|0:Oc;Oc=(Zb<<1)+(Hc*6|0)+(xc<<1)|0;Hc=(rc<<1)+(Jc*6|0)+(Gc<<1)|0;Jc=c[Jb>>2]|0;fc=Hc-Oc|0;bc=((Jc>>>8&255)+(Jc&255)+(Jc>>>16&255)<<4)-Oc<<4;Jc=(Hc|0)<(Oc|0);Oc=Jc?0-bc|0:bc;bc=Jc?0-fc|0:fc;fc=xc*3|0;Jc=kc+nc+Zb+fc|0;Zb=Gc*3|0;nc=wc+vc+rc+Zb|0;rc=c[Kb>>2]|0;vc=nc-Jc|0;Hc=((rc>>>8&255)+(rc&255)+(rc>>>16&255)<<4)-Jc<<4;rc=(nc|0)<(Jc|0);Jc=rc?0-Hc|0:Hc;Hc=rc?0-vc|0:vc;vc=cc<<4;cc=gc<<4;gc=c[Lb>>2]|0;rc=cc-vc|0;nc=((gc>>>8&255)+(gc&255)+(gc>>>16&255)<<4)-vc<<4;gc=(cc|0)<(vc|0);vc=gc?0-rc|0:rc;rc=gc?0-nc|0:nc;nc=(dc<<2)+pc|0;dc=(Ac<<2)+_b|0;Ac=c[Mb>>2]|0;gc=dc-nc|0;cc=((Ac>>>8&255)+(Ac&255)+(Ac>>>16&255)<<4)-nc<<4;Ac=(dc|0)<(nc|0);nc=Ac?0-gc|0:gc;gc=Ac?0-cc|0:cc;cc=(xc<<2)+pc|0;pc=(Gc<<2)+_b|0;_b=c[Nb>>2]|0;Gc=pc-cc|0;xc=((_b>>>8&255)+(_b&255)+(_b>>>16&255)<<4)-cc<<4;_b=(pc|0)<(cc|0);cc=_b?0-Gc|0:Gc;Gc=_b?0-xc|0:xc;xc=Dc+kc+fc+(c[F>>2]|0)|0;fc=wc+ac+yc+Zb|0;Zb=c[Ob>>2]|0;yc=fc-xc|0;ac=((Zb>>>8&255)+(Zb&255)+(Zb>>>16&255)<<4)-xc<<4;Zb=(fc|0)<(xc|0);xc=Zb?0-yc|0:yc;yc=Zb?0-ac|0:ac;c[f+($b<<3)>>2]=((mc|0)>(tc*13|0)?12:(mc|0)>(tc<<3|0)?8:(mc|0)>(tc*3|0)?4:0)|((hc|0)>(lc*13|0)?3:(hc|0)>(lc<<3|0)?2:(hc|0)>(lc*3|0)&1)|((sc|0)>(qc*13|0)?768:(sc|0)>(qc<<3|0)?512:(sc|0)>(qc*3|0)?256:0)|((uc|0)>(zc*13|0)?3072:(uc|0)>(zc<<3|0)?2048:(uc|0)>(zc*3|0)?1024:0)|((Bc|0)>(Fc*13|0)?48:(Bc|0)>(Fc<<3|0)?32:(Bc|0)>(Fc*3|0)?16:0)|((Ec|0)>(ic*13|0)?192:(Ec|0)>(ic<<3|0)?128:(Ec|0)>(ic*3|0)?64:0)|((oc|0)>(Cc*13|0)?12288:(oc|0)>(Cc<<3|0)?8192:(oc|0)>(Cc*3|0)?4096:0)|((ec|0)>(jc*13|0)?49152:(ec|0)>(jc<<3|0)?32768:(ec|0)>(jc*3|0)?16384:0)|((Ic|0)>(Qc*13|0)?196608:(Ic|0)>(Qc<<3|0)?131072:(Ic|0)>(Qc*3|0)?65536:0)|((Pc|0)>(Nc*13|0)?786432:(Pc|0)>(Nc<<3|0)?524288:(Pc|0)>(Nc*3|0)?262144:0)|((Oc|0)>(bc*13|0)?50331648:(Oc|0)>(bc<<3|0)?33554432:(Oc|0)>(bc*3|0)?16777216:0)|((Jc|0)>(Hc*13|0)?201326592:(Jc|0)>(Hc<<3|0)?134217728:(Jc|0)>(Hc*3|0)?67108864:0)|((rc|0)>(vc*13|0)?3145728:(rc|0)>(vc<<3|0)?2097152:(rc|0)>(vc*3|0)?1048576:0)|((gc|0)>(nc*13|0)?12582912:(gc|0)>(nc<<3|0)?8388608:(gc|0)>(nc*3|0)?4194304:0)|((Gc|0)>(cc*13|0)?805306368:(Gc|0)>(cc<<3|0)?536870912:(Gc|0)>(cc*3|0)?268435456:0)|((yc|0)>(xc*13|0)?-1073741824:(yc|0)>(xc<<3|0)?-2147483648:(yc|0)>(xc*3|0)?1073741824:0);c[m>>2]=c[D>>2];c[D>>2]=c[L>>2];c[C>>2]=c[B>>2];c[B>>2]=c[I>>2];c[x>>2]=c[v>>2];c[v>>2]=c[F>>2];c[n>>2]=c[A>>2];c[A>>2]=c[K>>2];c[z>>2]=c[y>>2];c[y>>2]=c[H>>2];c[u>>2]=c[w>>2];c[w>>2]=c[E>>2];xc=Yb+1|0;if((Xb|0)>=(g|0)){Rc=xc;break}else Yb=xc}}else Rc=Pb;Sb=Sb+1|0;if((Sb|0)>=(h|0))break b;else Pb=Rc}if((Q|0)==33)pa(508721,474791,3304,508737);else if((Q|0)==35)pa(508721,474791,3319,508760);else if((Q|0)==48)pa(508721,474791,3304,508737);else if((Q|0)==50)pa(508721,474791,3319,508760);else if((Q|0)==52)pa(508721,474791,3304,508737);else if((Q|0)==54)pa(508721,474791,3319,508760);else if((Q|0)==56)pa(508721,474791,3304,508737);else if((Q|0)==58)pa(508721,474791,3319,508760)}while(0);ma=1}Q=c[q>>2]|0;if(!Q){r=ma;i=j;return r|0}q=c[t>>2]|0;if((q|0)!=(Q|0))c[t>>2]=q+(~((q+-4-Q|0)>>>2)<<2);Mc(Q);r=ma;i=j;return r|0}function vb(b,f,g){b=b|0;f=f|0;g=g|0;var h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0,$=0,aa=0,ba=0,ca=0,da=0,ea=0,fa=0,ga=0,ha=0,ia=0,ja=0,ka=0,la=0,ma=0,na=0,oa=0,qa=0,ra=0,sa=0,ta=0,ua=0,va=0,wa=0,xa=0,ya=0,za=0,Aa=0,Ba=0,Ca=0,Da=0,Ea=0,Fa=0,Ga=0,Ha=0,Ia=0,Ja=0,Ka=0,La=0,Ma=0,Na=0,Oa=0,Pa=0,Qa=0,Ra=0,Sa=0,Ta=0,Ua=0,Va=0,Wa=0,Xa=0,Ya=0,Za=0,_a=0,$a=0,ab=0,bb=0,cb=0;h=i;i=i+336|0;j=h+168|0;k=h+104|0;l=h+320|0;m=h+24|0;n=h+16|0;o=h+96|0;p=h+80|0;q=h+72|0;r=h+64|0;s=h+48|0;t=h+8|0;u=h+32|0;v=h;if(!(Qb(b,j,0,1)|0)){w=0;i=h;return w|0}b=c[j+104>>2]|0;if((b|0)==8){if(g>>>0>=4)pa(499740,499604,685,499748);x=e[22684+((d[j+112+g>>0]|0)<<1)>>1]|0;y=x>>>7;a[f+3>>0]=y<<2|y<<5|2;y=x<<3&255;a[f>>0]=y;a[f+1>>0]=y;a[f+2>>0]=y;y=f+4|0;z=491006+((x>>>5&3)<<2)|0;x=d[z>>0]|d[z+1>>0]<<8|d[z+2>>0]<<16|d[z+3>>0]<<24;a[y>>0]=x;a[y+1>>0]=x>>8;a[y+2>>0]=x>>16;a[y+3>>0]=x>>24;w=1;i=h;return w|0}Rb(b,c[j+108>>2]|0,j+112|0,j,k,0)|0;if(g>>>0>=4)pa(499740,499604,685,499748);j=a[k+g>>0]|0;a[l>>0]=j;b=a[k+4+g>>0]|0;a[l+1>>0]=b;x=a[k+8+g>>0]|0;a[l+2>>0]=x;y=a[k+12+g>>0]|0;a[l+3>>0]=y;z=a[k+16+g>>0]|0;a[l+4>>0]=z;A=a[k+20+g>>0]|0;a[l+5>>0]=A;B=a[k+24+g>>0]|0;a[l+6>>0]=B;C=a[k+28+g>>0]|0;a[l+7>>0]=C;D=a[k+32+g>>0]|0;a[l+8>>0]=D;E=a[k+36+g>>0]|0;a[l+9>>0]=E;F=a[k+40+g>>0]|0;a[l+10>>0]=F;G=a[k+44+g>>0]|0;a[l+11>>0]=G;H=a[k+48+g>>0]|0;a[l+12>>0]=H;I=a[k+52+g>>0]|0;a[l+13>>0]=I;J=a[k+56+g>>0]|0;a[l+14>>0]=J;K=a[k+60+g>>0]|0;a[l+15>>0]=K;g=j&255;k=z&255;z=b&255;b=A&255;A=x&255;x=B&255;B=y&255;y=C&255;C=x+A+B+y|0;L=D&255;D=H&255;H=E&255;E=I&255;I=D+L+H+E|0;M=F&255;F=J&255;J=G&255;G=K&255;K=F+M+J+G|0;N=g+4+k+z+b|0;O=(C+N|0)>>>3;P=(I+4+K|0)>>>3;Q=(I+N|0)>>>3;N=(C+4+K|0)>>>3;K=j;j=0;C=0;I=0;R=0;S=0;while(1){T=j<<2;U=(K&255)-O|0;V=(_(U,U)|0)+S|0;U=(d[l+(j+8)>>0]|0)-P|0;W=(_(U,U)|0)+I|0;U=(d[l+T>>0]|0)-Q|0;X=(_(U,U)|0)+C|0;U=(d[l+(T|2)>>0]|0)-N|0;Y=(_(U,U)|0)+R|0;U=(d[l+(j+4)>>0]|0)-O|0;Z=V+(_(U,U)|0)|0;U=(d[l+(j+12)>>0]|0)-P|0;V=W+(_(U,U)|0)|0;U=(d[l+(T|1)>>0]|0)-Q|0;W=X+(_(U,U)|0)|0;U=(d[l+(T|3)>>0]|0)-N|0;T=Y+(_(U,U)|0)|0;U=j+1|0;if((U|0)==4){$=Z;aa=V;ba=W;ca=T;break}K=a[l+U>>0]|0;j=U;C=W;I=V;R=T;S=Z}S=(aa+$|0)<(ca+ba|0);ba=m;c[ba>>2]=255;c[ba+4>>2]=255;ba=n;c[ba>>2]=0;c[ba+4>>2]=0;ba=z>>>0<g>>>0?z:g;ca=g>>>0<z>>>0?z:g;if(S){g=A>>>0<ba>>>0?A:ba;z=ca>>>0<A>>>0?A:ca;$=B>>>0<g>>>0?B:g;g=z>>>0<B>>>0?B:z;z=k>>>0<$>>>0?k:$;$=g>>>0<k>>>0?k:g;g=b>>>0<z>>>0?b:z;z=$>>>0<b>>>0?b:$;$=x>>>0<g>>>0?x:g;g=z>>>0<x>>>0?x:z;z=y>>>0<$>>>0?y:$;$=g>>>0<y>>>0?y:g;c[m>>2]=z;c[n>>2]=$;g=H>>>0<L>>>0?H:L;aa=L>>>0<H>>>0?H:L;R=M>>>0<g>>>0?M:g;g=aa>>>0<M>>>0?M:aa;aa=J>>>0<R>>>0?J:R;R=g>>>0<J>>>0?J:g;g=D>>>0<aa>>>0?D:aa;aa=R>>>0<D>>>0?D:R;R=E>>>0<g>>>0?E:g;g=aa>>>0<E>>>0?E:aa;aa=F>>>0<R>>>0?F:R;R=g>>>0<F>>>0?F:g;g=G>>>0<aa>>>0?G:aa;aa=R>>>0<G>>>0?G:R;c[m+4>>2]=g;c[n+4>>2]=aa;da=$;ea=z;fa=aa;ga=g}else{g=k>>>0<ba>>>0?k:ba;ba=ca>>>0<k>>>0?k:ca;ca=b>>>0<g>>>0?b:g;g=ba>>>0<b>>>0?b:ba;ba=L>>>0<ca>>>0?L:ca;ca=g>>>0<L>>>0?L:g;g=H>>>0<ba>>>0?H:ba;ba=ca>>>0<H>>>0?H:ca;ca=D>>>0<g>>>0?D:g;g=ba>>>0<D>>>0?D:ba;ba=E>>>0<ca>>>0?E:ca;ca=g>>>0<E>>>0?E:g;c[m>>2]=ba;c[n>>2]=ca;g=B>>>0<A>>>0?B:A;E=A>>>0<B>>>0?B:A;A=x>>>0<g>>>0?x:g;g=E>>>0<x>>>0?x:E;E=y>>>0<A>>>0?y:A;A=g>>>0<y>>>0?y:g;g=M>>>0<E>>>0?M:E;E=A>>>0<M>>>0?M:A;A=J>>>0<g>>>0?J:g;g=E>>>0<J>>>0?J:E;E=F>>>0<A>>>0?F:A;A=g>>>0<F>>>0?F:g;g=G>>>0<E>>>0?G:E;E=A>>>0<G>>>0?G:A;c[m+4>>2]=g;c[n+4>>2]=E;da=ca;ea=ba;fa=E;ga=g}g=da-ea|0;c[o>>2]=g;E=fa-ga|0;c[o+4>>2]=E;ba=S&1;ca=f+3|0;a[ca>>0]=ba;do if((E|g)>>>0<4){a[f>>0]=0;A=f+1|0;a[A>>0]=0;G=f+2|0;a[G>>0]=0;F=p+4|0;J=p+8|0;M=p+12|0;y=g;x=ba;B=0;D=0;H=0;L=0;b=0;k=0;a:while(1){do if(y){aa=c[m+(k<<2)>>2]|0;if(y>>>0<2){ha=23708+(aa<<1)|0;ia=aa;break}else{ha=24220+(aa<<1)|0;ia=aa;break}}else{aa=c[m+(k<<2)>>2]|0;ha=23196+(aa<<1)|0;ia=aa}while(0);aa=e[ha>>1]|0;z=aa>>>3&31;if(z>>>0>=16){ja=21;break}c[p>>2]=aa>>>8&3;c[F>>2]=aa>>>10&3;c[J>>2]=aa>>>12&3;c[M>>2]=aa>>>14;$=(k|0)!=0;R=(x&255|(aa&7)<<($?2:5))&255;a[ca>>0]=R;aa=z<<($?0:4);$=B&255|aa;a[f>>0]=$;z=D&255|aa;a[A>>0]=z;I=H&255|aa;a[G>>0]=I;aa=k<<1;if(S){C=n+(k<<2)|0;j=L;K=b;Z=aa;T=0;while(1){V=T+aa|0;W=d[l+(V<<2)>>0]|0;if(W>>>0<ia>>>0){ja=26;break a}U=c[C>>2]|0;if(W>>>0>U>>>0){ja=26;break a}Y=W-ia|0;if(Y>>>0>=4){ja=28;break a}W=d[491170+(c[p+(Y<<2)>>2]|0)>>0]|0;Y=Z+4|0;X=d[l+(V<<2)+1>>0]|0;if(X>>>0<ia>>>0|X>>>0>U>>>0){ja=26;break a}ka=X-ia|0;if(ka>>>0>=4){ja=28;break a}X=d[491170+(c[p+(ka<<2)>>2]|0)>>0]|0;ka=Z+8|0;la=d[l+(V<<2)+2>>0]|0;if(la>>>0<ia>>>0|la>>>0>U>>>0){ja=26;break a}ma=la-ia|0;if(ma>>>0>=4){ja=28;break a}la=d[491170+(c[p+(ma<<2)>>2]|0)>>0]|0;ma=Z+12|0;na=d[l+(V<<2)+3>>0]|0;if(na>>>0<ia>>>0|na>>>0>U>>>0){ja=26;break a}U=na-ia|0;if(U>>>0>=4){ja=28;break a}na=d[491170+(c[p+(U<<2)>>2]|0)>>0]|0;U=((na&1)<<ma|((la&1)<<ka|((X&1)<<Y|((W&1)<<Z|K&65535))))&65535;V=(na>>>1<<ma|(la>>>1<<ka|(X>>>1<<Y|(W>>>1<<Z|j&65535))))&65535;T=T+1|0;if(T>>>0>=2){oa=V;qa=U;break}else{j=V;K=U;Z=Z+1|0}}}else{Z=n+(k<<2)|0;K=L;j=b;T=k<<3;C=0;while(1){U=C+aa|0;V=d[l+U>>0]|0;if(V>>>0<ia>>>0){ja=33;break a}W=c[Z>>2]|0;if(V>>>0>W>>>0){ja=33;break a}Y=V-ia|0;if(Y>>>0>=4){ja=35;break a}V=d[491170+(c[p+(Y<<2)>>2]|0)>>0]|0;Y=T|1;X=d[l+4+U>>0]|0;if(X>>>0<ia>>>0|X>>>0>W>>>0){ja=33;break a}ka=X-ia|0;if(ka>>>0>=4){ja=35;break a}X=d[491170+(c[p+(ka<<2)>>2]|0)>>0]|0;ka=T|2;la=d[l+8+U>>0]|0;if(la>>>0<ia>>>0|la>>>0>W>>>0){ja=33;break a}ma=la-ia|0;if(ma>>>0>=4){ja=35;break a}la=d[491170+(c[p+(ma<<2)>>2]|0)>>0]|0;ma=T|3;na=d[l+12+U>>0]|0;if(na>>>0<ia>>>0|na>>>0>W>>>0){ja=33;break a}W=na-ia|0;if(W>>>0>=4){ja=35;break a}na=d[491170+(c[p+(W<<2)>>2]|0)>>0]|0;W=((na&1)<<ma|((la&1)<<ka|((X&1)<<Y|((V&1)<<T|j&65535))))&65535;U=(na>>>1<<ma|(la>>>1<<ka|(X>>>1<<Y|(V>>>1<<T|K&65535))))&65535;C=C+1|0;if(C>>>0>=2){oa=U;qa=W;break}else{K=U;j=W;T=T+4|0}}}T=k+1|0;if(T>>>0>=2){ra=oa;sa=qa;ja=39;break}y=c[o+(T<<2)>>2]|0;x=R;B=$;D=z;H=I;L=oa;b=qa;k=T}if((ja|0)==21)pa(491086,474791,14053,491097);else if((ja|0)==26)pa(491121,474791,14071,491097);else if((ja|0)==28)pa(491163,474791,14073,491097);else if((ja|0)==33)pa(491121,474791,14094,491097);else if((ja|0)==35)pa(491163,474791,14096,491097);else if((ja|0)==39){a[f+7>>0]=sa;a[f+6>>0]=(sa&65535)>>>8;a[f+5>>0]=ra;a[f+4>>0]=(ra&65535)>>>8;break}}else{k=S?O:Q;b=(((k*31|0)+127|0)>>>0)/255|0;L=S?P:N;H=((((L*31|0)+127|0)>>>0)/255|0)-b|0;if((H+4|0)>>>0>7){D=(((k*15|0)+127|0)>>>0)/255|0;k=(((L*15|0)+127|0)>>>0)/255|0;L=D<<4;B=(k|L)&255;a[f>>0]=B;ta=q+4|0;ua=L|D;va=B;wa=ba;xa=k<<4|k;ya=0}else{k=(H|0)<-4?-4:(H|0)>3?3:H;H=k+b|0;B=b<<3;D=(((k|0)<0?k+8|0:k)|B)&255;a[f>>0]=D;k=(S&1|2)&255;a[ca>>0]=k;ta=q+4|0;ua=B|b>>>2;va=D;wa=k;xa=H<<3|H>>>2;ya=1}H=f+1|0;a[H>>0]=va;k=f+2|0;a[k>>0]=va;c[q>>2]=ua;c[ta>>2]=xa;D=da-ua|0;b=(D|0)<0?0-D|0:D;D=ua-ea|0;B=(D|0)<0?0-D|0:D;c[r>>2]=(b|0)>(B|0)?b:B;B=c[ta>>2]|0;b=fa-B|0;D=(b|0)<0?0-b|0:b;b=B-ga|0;B=(b|0)<0?0-b|0:b;c[r+4>>2]=(D|0)>(B|0)?D:B;B=u+4|0;D=u+8|0;b=u+12|0;L=s+4|0;x=s+8|0;y=s+12|0;G=t+1|0;A=t+2|0;M=t+3|0;J=t+4|0;F=t+5|0;T=t+6|0;j=t+7|0;K=t+2|0;C=t+4|0;Z=t+6|0;aa=t+1|0;W=t+3|0;U=t+5|0;V=t+7|0;Y=wa;X=0;ka=0;la=0;b:while(1){if(!ya?(ma=c[o+(la<<2)>>2]|0,ma>>>0<4):0){do if(ma){na=c[m+(la<<2)>>2]|0;if(ma>>>0<2){za=23708+(na<<1)|0;Aa=na;break}else{za=24220+(na<<1)|0;Aa=na;break}}else{na=c[m+(la<<2)>>2]|0;za=23196+(na<<1)|0;Aa=na}while(0);ma=e[za>>1]|0;I=ma>>>3&31;if(I>>>0>=16){ja=52;break}c[s>>2]=ma>>>8&3;c[L>>2]=ma>>>10&3;c[x>>2]=ma>>>12&3;c[y>>2]=ma>>>14;z=(la|0)!=0;$=(Y&255|(ma&7)<<(z?2:5))&255;a[ca>>0]=$;ma=z?0:4;z=~(15<<ma);R=(d[H>>0]|0)&z;na=(d[k>>0]|0)&z;Ba=I<<ma;a[f>>0]=(d[f>>0]|0)&z|Ba;a[H>>0]=R|Ba;a[k>>0]=na|Ba;Ba=la<<1;if(S){na=n+(la<<2)|0;R=X;z=ka;ma=Ba;I=0;while(1){Ca=I+Ba|0;Da=d[l+(Ca<<2)>>0]|0;if(Da>>>0<Aa>>>0){ja=57;break b}Ea=c[na>>2]|0;if(Da>>>0>Ea>>>0){ja=57;break b}Fa=Da-Aa|0;if(Fa>>>0>=4){ja=59;break b}Da=d[491170+(c[s+(Fa<<2)>>2]|0)>>0]|0;Fa=ma+4|0;Ga=d[l+(Ca<<2)+1>>0]|0;if(Ga>>>0<Aa>>>0|Ga>>>0>Ea>>>0){ja=57;break b}Ha=Ga-Aa|0;if(Ha>>>0>=4){ja=59;break b}Ga=d[491170+(c[s+(Ha<<2)>>2]|0)>>0]|0;Ha=ma+8|0;Ia=d[l+(Ca<<2)+2>>0]|0;if(Ia>>>0<Aa>>>0|Ia>>>0>Ea>>>0){ja=57;break b}Ja=Ia-Aa|0;if(Ja>>>0>=4){ja=59;break b}Ia=d[491170+(c[s+(Ja<<2)>>2]|0)>>0]|0;Ja=ma+12|0;Ka=d[l+(Ca<<2)+3>>0]|0;if(Ka>>>0<Aa>>>0|Ka>>>0>Ea>>>0){ja=57;break b}Ea=Ka-Aa|0;if(Ea>>>0>=4){ja=59;break b}Ka=d[491170+(c[s+(Ea<<2)>>2]|0)>>0]|0;Ea=((Ka&1)<<Ja|((Ia&1)<<Ha|((Ga&1)<<Fa|((Da&1)<<ma|z&65535))))&65535;Ca=(Ka>>>1<<Ja|(Ia>>>1<<Ha|(Ga>>>1<<Fa|(Da>>>1<<ma|R&65535))))&65535;I=I+1|0;if(I>>>0>=2){La=$;Ma=Ca;Na=Ea;break}else{R=Ca;z=Ea;ma=ma+1|0}}}else{ma=n+(la<<2)|0;z=X;R=ka;I=la<<3;na=0;while(1){Ea=na+Ba|0;Ca=d[l+Ea>>0]|0;if(Ca>>>0<Aa>>>0){ja=64;break b}Da=c[ma>>2]|0;if(Ca>>>0>Da>>>0){ja=64;break b}Fa=Ca-Aa|0;if(Fa>>>0>=4){ja=66;break b}Ca=d[491170+(c[s+(Fa<<2)>>2]|0)>>0]|0;Fa=I|1;Ga=d[l+4+Ea>>0]|0;if(Ga>>>0<Aa>>>0|Ga>>>0>Da>>>0){ja=64;break b}Ha=Ga-Aa|0;if(Ha>>>0>=4){ja=66;break b}Ga=d[491170+(c[s+(Ha<<2)>>2]|0)>>0]|0;Ha=I|2;Ia=d[l+8+Ea>>0]|0;if(Ia>>>0<Aa>>>0|Ia>>>0>Da>>>0){ja=64;break b}Ja=Ia-Aa|0;if(Ja>>>0>=4){ja=66;break b}Ia=d[491170+(c[s+(Ja<<2)>>2]|0)>>0]|0;Ja=I|3;Ka=d[l+12+Ea>>0]|0;if(Ka>>>0<Aa>>>0|Ka>>>0>Da>>>0){ja=64;break b}Da=Ka-Aa|0;if(Da>>>0>=4){ja=66;break b}Ka=d[491170+(c[s+(Da<<2)>>2]|0)>>0]|0;Da=((Ka&1)<<Ja|((Ia&1)<<Ha|((Ga&1)<<Fa|((Ca&1)<<I|R&65535))))&65535;Ea=(Ka>>>1<<Ja|(Ia>>>1<<Ha|(Ga>>>1<<Fa|(Ca>>>1<<I|z&65535))))&65535;na=na+1|0;if(na>>>0>=2){La=$;Ma=Ea;Na=Da;break}else{z=Ea;R=Da;I=I+4|0}}}}else ja=68;do if((ja|0)==68){ja=0;I=c[q+(la<<2)>>2]|0;R=0-I|0;z=255-I|0;if((z|I|0)<=-1){ja=69;break b}$=c[r+(la<<2)>>2]|0;if($>>>0<52){na=$>>>0>22?14:15;ma=($+-4|0)>>>0>35?na&13:na;na=$>>>0<9?ma&11:ma;Oa=$>>>0<12?na&7:na}else{na=$>>>0>60?248:252;ma=$>>>0>89?na&244:na;na=$>>>0>120?ma&236:ma;ma=$>>>0>136?na&220:na;Oa=$>>>0>174?ma&188:ma}ma=n+(la<<2)|0;$=la<<1;na=m+(la<<2)|0;Ba=$|1;Da=$|1;Ea=$|1;Ca=-1;Fa=0;Ga=0;while(1){if(1<<Ga&Oa){Ha=c[17484+(Ga<<4)>>2]|0;Ia=(Ha|0)>(R|0)?Ha:R;Ha=c[17484+(Ga<<4)+4>>2]|0;Ja=(Ha|0)>(R|0)?Ha:R;Ha=c[17484+(Ga<<4)+8>>2]|0;Ka=(Ha|0)<(z|0)?Ha:z;Ha=c[17484+(Ga<<4)+12>>2]|0;Pa=(Ha|0)<(z|0)?Ha:z;if((Ia|0)>(Ja|0)|(Ja|0)>(Ka|0)|(Ka|0)>(Pa|0)){ja=76;break b}c[u>>2]=Ka;c[B>>2]=Pa;c[D>>2]=Ja;c[b>>2]=Ia;Ha=Ja+Ia|0;Qa=Ka+Ja|0;Ja=Pa+Ka|0;if((Ha|0)>(Qa|0)|(Qa|0)>(Ja|0)){ja=78;break b}Ka=((c[ma>>2]|0)-I<<1|0)<(Ha|0);c:do if(S){if(Ka){Ra=v;c[Ra>>2]=50529027;c[Ra+4>>2]=50529027;Ra=0;Sa=0;while(1){Ta=Sa+$|0;Ua=I-(d[l+(Ta<<2)>>0]|0)+Ia|0;Va=(Ua|0)<0?0-Ua|0:Ua;Ua=(_(Va,Va)|0)+Ra|0;Va=I-(d[l+(Ta<<2)+1>>0]|0)+Ia|0;Wa=(Va|0)<0?0-Va|0:Va;Va=(_(Wa,Wa)|0)+Ua|0;Ua=I-(d[l+(Ta<<2)+2>>0]|0)+Ia|0;Wa=(Ua|0)<0?0-Ua|0:Ua;Ua=(_(Wa,Wa)|0)+Va|0;Va=I-(d[l+(Ta<<2)+3>>0]|0)+Ia|0;Ta=(Va|0)<0?0-Va|0:Va;Va=(_(Ta,Ta)|0)+Ua|0;Sa=Sa+1|0;if(!(Va>>>0<Ca>>>0&Sa>>>0<2)){Xa=Va;break c}else Ra=Va}}if(((c[na>>2]|0)-I<<1|0)<(Ja|0)){Ra=0;Sa=0;while(1){Va=Sa+$|0;Ua=Sa<<2;Ta=(d[l+(Va<<2)>>0]|0)-I|0;Wa=Ta<<1;Ya=a[509284+(((Wa|0)<(Ha|0)&1)+((Wa|0)<(Qa|0)&1)+((Wa|0)<(Ja|0)&1))>>0]|0;a[v+Ua>>0]=Ya;Wa=(c[u+((Ya&255)<<2)>>2]|0)-Ta|0;Ta=(Wa|0)<0?0-Wa|0:Wa;Wa=(_(Ta,Ta)|0)+Ra|0;Ta=(d[l+(Va<<2)+1>>0]|0)-I|0;Ya=Ta<<1;Za=a[509284+(((Ya|0)<(Ha|0)&1)+((Ya|0)<(Qa|0)&1)+((Ya|0)<(Ja|0)&1))>>0]|0;a[v+(Ua|1)>>0]=Za;Ya=(c[u+((Za&255)<<2)>>2]|0)-Ta|0;Ta=(Ya|0)<0?0-Ya|0:Ya;Ya=(_(Ta,Ta)|0)+Wa|0;Wa=(d[l+(Va<<2)+2>>0]|0)-I|0;Ta=Wa<<1;Za=a[509284+(((Ta|0)<(Ha|0)&1)+((Ta|0)<(Qa|0)&1)+((Ta|0)<(Ja|0)&1))>>0]|0;a[v+(Ua|2)>>0]=Za;Ta=(c[u+((Za&255)<<2)>>2]|0)-Wa|0;Wa=(Ta|0)<0?0-Ta|0:Ta;Ta=(_(Wa,Wa)|0)+Ya|0;Ya=(d[l+(Va<<2)+3>>0]|0)-I|0;Va=Ya<<1;Wa=a[509284+(((Va|0)<(Ha|0)&1)+((Va|0)<(Qa|0)&1)+((Va|0)<(Ja|0)&1))>>0]|0;a[v+(Ua|3)>>0]=Wa;Ua=(c[u+((Wa&255)<<2)>>2]|0)-Ya|0;Ya=(Ua|0)<0?0-Ua|0:Ua;Ua=(_(Ya,Ya)|0)+Ta|0;Sa=Sa+1|0;if(!(Ua>>>0<Ca>>>0&Sa>>>0<2)){Xa=Ua;break c}else Ra=Ua}}Ra=v;c[Ra>>2]=16843009;c[Ra+4>>2]=16843009;Ra=0;Sa=0;while(1){Ua=Sa+$|0;Ta=I-(d[l+(Ua<<2)>>0]|0)+Pa|0;Ya=(Ta|0)<0?0-Ta|0:Ta;Ta=(_(Ya,Ya)|0)+Ra|0;Ya=I-(d[l+(Ua<<2)+1>>0]|0)+Pa|0;Wa=(Ya|0)<0?0-Ya|0:Ya;Ya=(_(Wa,Wa)|0)+Ta|0;Ta=I-(d[l+(Ua<<2)+2>>0]|0)+Pa|0;Wa=(Ta|0)<0?0-Ta|0:Ta;Ta=(_(Wa,Wa)|0)+Ya|0;Ya=I-(d[l+(Ua<<2)+3>>0]|0)+Pa|0;Ua=(Ya|0)<0?0-Ya|0:Ya;Ya=(_(Ua,Ua)|0)+Ta|0;Sa=Sa+1|0;if(!(Ya>>>0<Ca>>>0&Sa>>>0<2)){Xa=Ya;break}else Ra=Ya}}else{if(Ka){Ra=v;c[Ra>>2]=50529027;c[Ra+4>>2]=50529027;Ra=0;Sa=0;while(1){Ya=I-(d[l+(Sa<<2)+$>>0]|0)+Ia|0;Ta=(Ya|0)<0?0-Ya|0:Ya;Ya=(_(Ta,Ta)|0)+Ra|0;Ta=I-(d[l+(Sa<<2)+Ba>>0]|0)+Ia|0;Ua=(Ta|0)<0?0-Ta|0:Ta;Ta=(_(Ua,Ua)|0)+Ya|0;Sa=Sa+1|0;if(!(Ta>>>0<Ca>>>0&Sa>>>0<4)){Xa=Ta;break c}else Ra=Ta}}if(((c[na>>2]|0)-I<<1|0)<(Ja|0)){Ra=0;Sa=0;while(1){Ta=Sa<<1;Ya=(d[l+(Sa<<2)+$>>0]|0)-I|0;Ua=Ya<<1;Wa=a[509284+(((Ua|0)<(Ha|0)&1)+((Ua|0)<(Qa|0)&1)+((Ua|0)<(Ja|0)&1))>>0]|0;a[v+Ta>>0]=Wa;Ua=(c[u+((Wa&255)<<2)>>2]|0)-Ya|0;Ya=(Ua|0)<0?0-Ua|0:Ua;Ua=(_(Ya,Ya)|0)+Ra|0;Ya=(d[l+(Sa<<2)+Ea>>0]|0)-I|0;Wa=Ya<<1;Va=a[509284+(((Wa|0)<(Ha|0)&1)+((Wa|0)<(Qa|0)&1)+((Wa|0)<(Ja|0)&1))>>0]|0;a[v+(Ta|1)>>0]=Va;Ta=(c[u+((Va&255)<<2)>>2]|0)-Ya|0;Ya=(Ta|0)<0?0-Ta|0:Ta;Ta=(_(Ya,Ya)|0)+Ua|0;Sa=Sa+1|0;if(!(Ta>>>0<Ca>>>0&Sa>>>0<4)){Xa=Ta;break c}else Ra=Ta}}Ra=v;c[Ra>>2]=16843009;c[Ra+4>>2]=16843009;Ra=0;Sa=0;while(1){Ta=I-(d[l+(Sa<<2)+$>>0]|0)+Pa|0;Ua=(Ta|0)<0?0-Ta|0:Ta;Ta=(_(Ua,Ua)|0)+Ra|0;Ua=I-(d[l+(Sa<<2)+Da>>0]|0)+Pa|0;Ya=(Ua|0)<0?0-Ua|0:Ua;Ua=(_(Ya,Ya)|0)+Ta|0;Sa=Sa+1|0;if(!(Ua>>>0<Ca>>>0&Sa>>>0<4)){Xa=Ua;break}else Ra=Ua}}while(0);if(Xa>>>0<Ca>>>0){Pa=v;Ja=c[Pa+4>>2]|0;Qa=t;c[Qa>>2]=c[Pa>>2];c[Qa+4>>2]=Ja;_a=Xa;$a=Ga}else{_a=Ca;$a=Fa}}else{_a=Ca;$a=Fa}Ga=Ga+1|0;if(Ga>>>0>=8){ab=$a;break}else{Ca=_a;Fa=$a}}Fa=(d[ca>>0]|0|ab<<((la|0)!=0?2:5))&255;a[ca>>0]=Fa;if(S){Ca=d[t>>0]|0;Ga=$+4|0;Da=d[G>>0]|0;I=$+8|0;Ea=d[A>>0]|0;na=$+12|0;Ba=d[M>>0]|0;ma=$|1;z=d[J>>0]|0;R=ma+4|0;Ja=d[F>>0]|0;Qa=ma+8|0;Pa=d[T>>0]|0;Ha=ma+12|0;Ia=d[j>>0]|0;La=Fa;Ma=(Ia>>>1<<Ha|(Pa>>>1<<Qa|(Ja>>>1<<R|(z>>>1<<ma|(Ba>>>1<<na|(Ea>>>1<<I|(Da>>>1<<Ga|(Ca>>>1<<$|X&65535))))))))&65535;Na=((Ia&1)<<Ha|((Pa&1)<<Qa|((Ja&1)<<R|((z&1)<<ma|((Ba&1)<<na|((Ea&1)<<I|((Da&1)<<Ga|((Ca&1)<<$|ka&65535))))))))&65535;break}else{Ca=la<<3;Ga=d[t>>0]|0;Da=Ca|1;I=d[K>>0]|0;Ea=Da+1|0;na=d[C>>0]|0;Ba=Ca|3;ma=d[Z>>0]|0;z=Ba+1|0;R=d[aa>>0]|0;Ja=Ba+2|0;Qa=d[W>>0]|0;Pa=Ba+3|0;Ha=d[U>>0]|0;Ia=Ca|7;Ka=d[V>>0]|0;La=Fa;Ma=(Ka>>>1<<Ia|(Ha>>>1<<Pa|(Qa>>>1<<Ja|(R>>>1<<z|(ma>>>1<<Ba|(na>>>1<<Ea|(I>>>1<<Da|(Ga>>>1<<Ca|X&65535))))))))&65535;Na=((Ka&1)<<Ia|((Ha&1)<<Pa|((Qa&1)<<Ja|((R&1)<<z|((ma&1)<<Ba|((na&1)<<Ea|((I&1)<<Da|((Ga&1)<<Ca|ka&65535))))))))&65535;break}}while(0);la=la+1|0;if(la>>>0>=2){bb=Ma;cb=Na;ja=99;break}else{Y=La;X=Ma;ka=Na}}if((ja|0)==52)pa(491086,474791,14170,491097);else if((ja|0)==57)pa(491121,474791,14194,491097);else if((ja|0)==59)pa(491163,474791,14196,491097);else if((ja|0)==64)pa(491121,474791,14217,491097);else if((ja|0)==66)pa(491163,474791,14219,491097);else if((ja|0)==69)pa(491174,474791,14243,491097);else if((ja|0)==76)pa(491208,474791,14293,491097);else if((ja|0)==78)pa(491247,474791,14301,491097);else if((ja|0)==99){a[f+7>>0]=cb;a[f+6>>0]=(cb&65535)>>>8;a[f+5>>0]=bb;a[f+4>>0]=(bb&65535)>>>8;break}}while(0);w=1;i=h;return w|0}function wb(b,e,f){b=b|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0;g=i;i=i+224|0;h=g+64|0;j=g;if(!(Qb(b,h,0,1)|0)){k=0;i=g;return k|0}b=h+104|0;l=c[b>>2]|0;if((l|0)==8){m=c[h+112>>2]|0;n=m&255;o=m>>>8&255;p=m>>>16&255;m=d[468643+(o<<1)>>0]<<5|d[467619+(n<<1)>>0]<<11|d[467619+(p<<1)>>0];q=d[468643+(o<<1)+1>>0]<<5|d[467619+(n<<1)+1>>0]<<11|d[467619+(p<<1)+1>>0];if((q|0)==(m|0))if(!m){r=1;s=0;t=0;u=0;v=85}else{w=m+-1|0;x=0;y=6}else{w=q;x=170;y=6}if((y|0)==6){y=m>>>0<w>>>0;q=y?w:m;p=y?m:w;r=q&255;s=p&255;t=(q&65535)>>>8&255;u=(p&65535)>>>8&255;v=(y?x|85:x)&255}a[e>>0]=r;a[e+1>>0]=t;a[e+2>>0]=s;a[e+3>>0]=u;Hd(e+4|0,v|0,4)|0;k=1;i=g;return k|0}if(!f?(a[h+116>>0]|0)!=0:0){$b(h,e);k=1;i=g;return k|0}Rb(l,c[h+108>>2]|0,h+112|0,h,j,0)|0;if(!(a[h+117>>0]|0))Yb(e,j,f&1);else{l=c[b>>2]|0;a[e>>0]=1;a[e+1>>0]=0;a[e+2>>0]=0;a[e+3>>0]=0;b=c[17612+(d[476832+l>>0]<<2)>>2]|0;v=(d[476908+l>>0]|0)+-1|0;l=15;u=0;while(1){s=d[b+(d[(l<<v)+(h+39)>>0]|0)>>0]|u<<2;if((l|0)>0){l=l+-1|0;u=s}else{z=s;A=u;break}}a[e+4>>0]=z;a[e+5>>0]=A>>>6;a[e+6>>0]=A>>>14;a[e+7>>0]=A>>>22;Yb(e,j,f&1|4)}k=1;i=g;return k|0}function xb(e,f,g){e=e|0;f=f|0;g=g|0;var h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0;h=i;i=i+224|0;j=h+64|0;k=h;if(!(Qb(e,j,0,1)|0)){l=0;i=h;return l|0}e=j+104|0;m=c[e>>2]|0;n=f+8|0;if((m|0)==8){o=j+112|0;p=a[o+3>>0]|0;a[f>>0]=p;a[f+1>>0]=p;p=f+2|0;a[p>>0]=0;a[p+1>>0]=0;a[p+2>>0]=0;a[p+3>>0]=0;a[p+4>>0]=0;a[p+5>>0]=0;p=c[o>>2]|0;o=p&255;q=p>>>8&255;r=p>>>16&255;p=(d[468643+(q<<1)>>0]|0)<<5|(d[467619+(o<<1)>>0]|0)<<11|(d[467619+(r<<1)>>0]|0);s=(d[468643+(q<<1)+1>>0]|0)<<5|(d[467619+(o<<1)+1>>0]|0)<<11|(d[467619+(r<<1)+1>>0]|0);if((s|0)==(p|0))if(!p){t=1;u=0;v=0;w=0;x=85}else{y=p+-1|0;z=0;A=6}else{y=s;z=170;A=6}if((A|0)==6){s=p>>>0<y>>>0;r=s?y:p;o=s?p:y;t=r&255;u=o&255;v=(r&65535)>>>8&255;w=(o&65535)>>>8&255;x=(s?z|85:z)&255}a[n>>0]=t;a[f+9>>0]=v;a[f+10>>0]=u;a[f+11>>0]=w;Hd(f+12|0,x|0,4)|0;l=1;i=h;return l|0}Rb(m,c[j+108>>2]|0,j+112|0,j,k,0)|0;Xb(f,k+3|0,4);do if(!g){m=b[j+116>>1]|0;if(!((m&255)<<24>>24)){B=(m&65535)>>>8&255;A=13;break}else{$b(j,n);break}}else{B=a[j+117>>0]|0;A=13}while(0);do if((A|0)==13){if(!(B<<24>>24)){Yb(n,k,g&1);break}m=c[e>>2]|0;a[n>>0]=1;a[f+9>>0]=0;a[f+10>>0]=0;a[f+11>>0]=0;x=c[17612+((d[476832+m>>0]|0)<<2)>>2]|0;w=(d[476908+m>>0]|0)+-1|0;m=15;u=0;while(1){v=d[x+(d[(m<<w)+(j+39)>>0]|0)>>0]|0|u<<2;if((m|0)>0){m=m+-1|0;u=v}else{C=v;D=u;break}}a[f+12>>0]=C;a[f+13>>0]=D>>>6;a[f+14>>0]=D>>>14;a[f+15>>0]=D>>>22;Yb(n,k,g&1|4)}while(0);l=1;i=h;return l|0}function yb(e,f,g,h,j){e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;var k=0,l=0,m=0,n=0,o=0,p=0;k=i;i=i+224|0;l=k+64|0;m=k;if(!(Qb(e,l,0,1)|0)){n=0;i=k;return n|0}e=c[l+104>>2]|0;if((e|0)==8){o=l+112|0;b[f>>1]=d[o+h>>0]|0|3328;p=f+2|0;a[p>>0]=a[463004]|0;a[p+1>>0]=a[463005]|0;a[p+2>>0]=a[463006]|0;a[p+3>>0]=a[463007]|0;a[p+4>>0]=a[463008]|0;a[p+5>>0]=a[463009]|0;b[f+8>>1]=d[o+j>>0]|0|3328;o=f+10|0;a[o>>0]=a[463004]|0;a[o+1>>0]=a[463005]|0;a[o+2>>0]=a[463006]|0;a[o+3>>0]=a[463007]|0;a[o+4>>0]=a[463008]|0;a[o+5>>0]=a[463009]|0;n=1;i=k;return n|0}Rb(e,c[l+108>>2]|0,l+112|0,l,m,0)|0;if((h|0)==3)Wb(l,m,f);else Pa[(g?2:1)&3](f,m+h|0,4);if((j|0)==3)Wb(l,m,f+8|0);else Pa[(g?2:1)&3](f+8|0,m+j|0,4);n=1;i=k;return n|0}function zb(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;i=i|0;j=j|0;k=k|0;l=l|0;m=m|0;n=n|0;o=o|0;p=p|0;q=q|0;r=r|0;s=s|0;t=t|0;u=u|0;var v=0,w=0,x=0,y=0,z=0,A=0,B=0,D=0;r=Kd(m|0,0,l|0,0)|0;p=C;if(p>>>0>0|(p|0)==0&r>>>0>f>>>0){v=0;return v|0}f=(b|0)==9;if((b&-2|0)==8){r=g<<2;if(!r){v=0;return v|0}if(r+-1&r){v=0;return v|0}r=h<<2;if(!r){v=0;return v|0}if(r+-1&r){v=0;return v|0}}r=f?(o?b:8):b;b=n>>>2;switch(r|0){case 20:case 19:case 18:case 11:case 9:case 8:case 4:case 2:case 0:{w=8;x=11;break}case 21:case 17:case 12:case 10:case 5:case 3:case 1:case 7:case 6:{w=16;x=11;break}case 13:{y=4;x=12;break}case 16:case 15:case 14:{w=2;x=11;break}default:pa(475191,474791,10833,475639)}if((x|0)==11)if((r+-13|0)>>>0>=4)if((_(h,g)|0)>>>0>d>>>0|(r|0)==17){v=0;return v|0}else z=w;else{y=w;x=12}if((x|0)==12)if((_((s|0)==0?j:s,(q|0)==0?i:q)|0)>>>0>d>>>0){v=0;return v|0}else z=y;do switch(r|0){case 0:{v=sb(0,c,g,h,e+l|0,m,0,z,0,o,i,j,q,0,s,t,u,0)|0;return v|0}case 1:{v=sb(0,c,g,h,e+l|0,m,1,z,0,o,i,j,q,0,s,t,u,0)|0;return v|0}case 2:{if((_(g<<4,h)|0)>>>0>m>>>0){v=0;return v|0}if(!h){v=1;return v|0}y=_(z,(q|0)==0?g:q)|0;d=(g|0)==0;w=0;n=e+l|0;a:while(1){if(d)A=n;else{f=0;p=c+(_(y,w)|0)|0;k=n;while(1){if(!(wb(k,p,0)|0)){v=0;x=55;break a}f=f+1|0;a=k+16|0;if(f>>>0>=g>>>0){A=a;break}else{p=p+z|0;k=a}}}w=w+1|0;if(w>>>0>=h>>>0){v=1;x=55;break}else n=A}if((x|0)==55)return v|0;break}case 3:{if((_(g<<4,h)|0)>>>0>m>>>0){v=0;return v|0}if(!h){v=1;return v|0}n=_(z,(q|0)==0?g:q)|0;w=(g|0)==0;y=0;d=e+l|0;b:while(1){if(w)B=d;else{k=0;p=c+(_(n,y)|0)|0;f=d;while(1){if(!(xb(f,p,0)|0)){v=0;x=55;break b}k=k+1|0;a=f+16|0;if(k>>>0>=g>>>0){B=a;break}else{p=p+z|0;f=a}}}y=y+1|0;if(y>>>0>=h>>>0){v=1;x=55;break}else d=B}if((x|0)==55)return v|0;break}case 4:{v=sb(0,c,g,h,e+l|0,m,4,z,0,o,i,j,q,0,s,(b&1|0)!=0&o?3:0,-1,0)|0;return v|0}case 5:{v=sb(0,c,g,h,e+l|0,m,5,z,0,o,i,j,q,0,s,0,3,0)|0;return v|0}case 7:case 6:{v=sb(0,c,g,h,e+l|0,m,8,z,0,o,i,j,q,0,s,-1,-1,0)|0;return v|0}case 8:{if((_(g<<4,h)|0)>>>0>m>>>0){v=0;return v|0}ub(e+l|0,c,g,h,0,0)|0;v=1;return v|0}case 9:{if((_(g<<4,h)|0)>>>0>m>>>0){v=0;return v|0}tb(e+l|0,c,g,h,0)|0;v=1;return v|0}case 10:{v=sb(0,c,g,h,e+l|0,m,12,z,0,o,i,j,q,0,s,-1,-1,0)|0;return v|0}case 20:{v=sb(0,c,g,h,e+l|0,m,18,z,0,o,i,j,q,0,s,(b&1|0)!=0&o?3:0,-1,0)|0;return v|0}case 21:{if((_(g<<4,h)|0)>>>0>m>>>0){v=0;return v|0}if(!h){v=1;return v|0}d=_(z,(q|0)==0?g:q)|0;y=(g|0)==0;n=0;w=e+l|0;c:while(1){if(y)D=w;else{f=0;p=c+(_(d,n)|0)|0;k=w;while(1){if(!(yb(k,p,0,0,3)|0)){v=0;x=55;break c}f=f+1|0;a=k+16|0;if(f>>>0>=g>>>0){D=a;break}else{p=p+z|0;k=a}}}n=n+1|0;if(n>>>0>=h>>>0){v=1;x=55;break}else w=D}if((x|0)==55)return v|0;break}case 13:{v=sb(0,c,g,h,e+l|0,m,22,z,0,o,i,j,q,0,s,-1,-1,0)|0;return v|0}case 14:{v=sb(0,c,g,h,e+l|0,m,24,z,0,o,i,j,q,0,s,-1,-1,0)|0;return v|0}case 15:{v=sb(0,c,g,h,e+l|0,m,25,z,0,o,i,j,q,0,s,-1,-1,0)|0;return v|0}case 16:{v=sb(0,c,g,h,e+l|0,m,29,z,0,o,i,j,q,0,s,-1,-1,0)|0;return v|0}case 19:case 18:case 17:case 12:case 11:{v=0;return v|0}default:pa(475191,474791,9841,475222)}while(0);return 0}function Ab(b,d){b=b|0;d=d|0;c[b>>2]=0;c[b+4>>2]=0;c[b+8>>2]=0;c[b+12>>2]=0;c[b+16>>2]=0;c[b+20>>2]=0;c[b+24>>2]=d;Hd(b+28|0,0,148)|0;fb(b+176|0);a[b+585>>0]=0;return}function Bb(b,c,e){b=b|0;c=c|0;e=e|0;var f=0,g=0,h=0;if(e>>>0<78)return 0;if((d[c+1>>0]<<8|d[c>>0]|0)!=17011)return 0;if((d[c+3>>0]<<8|d[c+2>>0]|0)!=19)return 0;if((d[c+5>>0]<<8|d[c+4>>0]|0)!=77)return 0;if(((d[c+10>>0]<<16|d[c+11>>0]<<24|d[c+9>>0]<<8|d[c+8>>0])+77|0)>>>0>e>>>0)return 0;b=d[c+18>>0]<<8|d[c+19>>0]<<16|d[c+17>>0];if(!b)return 0;f=d[c+14>>0]|0;g=d[c+15>>0]<<8|d[c+16>>0]<<16|f;if((g|0)==0|b>>>0>g>>>0)return 0;b=a[c+21>>0]|0;h=b&255;if(!(a[c+20>>0]|0)){if((h&4|0)!=0&(f&1|0)!=0|(b&1)==0)return 0}else if(h&1)return 0;h=d[c+67>>0]<<16|d[c+68>>0]<<24|d[c+66>>0]<<8|d[c+65>>0];if(h>>>0<e>>>0)return (e-h|0)>>>0>=(g*23|0)>>>0|0;else return 0;return 0}function Cb(a,b,c){a=a|0;b=b|0;c=c|0;var e=0;if(c>>>0<78)return 0;if(((d[b+1>>0]|0)<<8|(d[b>>0]|0)|0)!=17011)return 0;if(((d[b+3>>0]|0)<<8|(d[b+2>>0]|0)|0)!=19)return 0;if(((d[b+5>>0]|0)<<8|(d[b+4>>0]|0)|0)!=77)return 0;if((((d[b+10>>0]|0)<<16|(d[b+11>>0]|0)<<24|(d[b+9>>0]|0)<<8|(d[b+8>>0]|0))+77|0)>>>0>c>>>0)return 0;a=(d[b+15>>0]|0)<<8|(d[b+16>>0]|0)<<16|(d[b+14>>0]|0);if(!a)return 0;if(!((d[b+18>>0]|0)<<8|(d[b+19>>0]|0)<<16|(d[b+17>>0]|0)))return 0;e=(d[b+67>>0]|0)<<16|(d[b+68>>0]|0)<<24|(d[b+66>>0]|0)<<8|(d[b+65>>0]|0);if(e>>>0<c>>>0)return (c-e|0)>>>0>=(a*23|0)>>>0|0;else return 0;return 0}function Db(a,b,c){a=a|0;b=b|0;c=c|0;var e=0;if(!(Cb(0,b,c)|0)){e=0;return e|0}e=(d[b+18>>0]|0)<<8|(d[b+19>>0]|0)<<16|(d[b+17>>0]|0);return e|0}function Eb(b,e,f,g,h){b=b|0;e=e|0;f=f|0;g=g|0;h=h|0;var i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0;if(!(Cb(0,e,f)|0)){i=0;return i|0}f=d[e+15>>0]<<8|d[e+16>>0]<<16|d[e+14>>0];if(!f){i=0;return i|0}b=e+(d[e+67>>0]<<16|d[e+68>>0]<<24|d[e+66>>0]<<8|d[e+65>>0])|0;j=0;while(1){if((d[b+(j*23|0)+1>>0]<<8|d[b+(j*23|0)+2>>0]<<16|d[b+(j*23|0)>>0]|0)==(h|0)?(a[b+(j*23|0)+3>>0]|0)==0:0){k=j;break}j=j+1|0;if(j>>>0>=f>>>0){i=0;l=17;break}}if((l|0)==17)return i|0;if((k|0)<0){i=0;return i|0}if((d[e+18>>0]<<8|d[e+19>>0]<<16|d[e+17>>0])>>>0<=h>>>0){i=0;return i|0}l=k+1|0;if(l>>>0<f>>>0){j=l;l=1;while(1){if((d[b+(j*23|0)+1>>0]<<8|d[b+(j*23|0)+2>>0]<<16|d[b+(j*23|0)>>0]|0)!=(h|0)){m=l;break}n=(d[b+(j*23|0)+3>>0]|0)+1|0;o=l>>>0>n>>>0?l:n;j=j+1|0;if(j>>>0>=f>>>0){m=o;break}else l=o}if(m>>>0>16){i=0;return i|0}else p=m}else p=1;c[g>>2]=h;c[g+4>>2]=p;p=g+40|0;a[p>>0]=0;if(!(a[e+20>>0]|0)){q=b+(k*23|0)+4|0;r=(d[e+21>>0]|0)>>>2}else{e=b+(k*23|0)+4|0;q=e;r=d[e>>0]|0}a[p>>0]=r&1;a[g+41>>0]=(d[q>>0]|0)>>>1&1;q=b+(k*23|0)+10|0;r=b+(k*23|0)+9|0;c[g+16>>2]=(d[q>>0]<<8|d[r>>0])<<2;p=b+(k*23|0)+12|0;e=b+(k*23|0)+11|0;c[g+20>>2]=(d[p>>0]<<8|d[e>>0])<<2;c[g+8>>2]=d[b+(k*23|0)+6>>0]<<8|d[b+(k*23|0)+5>>0];c[g+12>>2]=d[b+(k*23|0)+8>>0]<<8|d[b+(k*23|0)+7>>0];b=d[q>>0]<<8|d[r>>0];c[g+24>>2]=b;r=d[p>>0]<<8|d[e>>0];c[g+28>>2]=r;c[g+32>>2]=_(r,b)|0;c[g+36>>2]=k;i=1;return i|0}function Fb(a,b,e,f,g,h,i,j){a=a|0;b=b|0;e=e|0;f=f|0;g=g|0;h=h|0;i=i|0;j=j|0;var k=0,l=0,m=0,n=0;if(!(Cb(0,b,e)|0)){k=0;return k|0}e=(d[b+15>>0]|0)<<8|(d[b+16>>0]|0)<<16|(d[b+14>>0]|0);if(!e){k=0;return k|0}a=b+((d[b+67>>0]|0)<<16|(d[b+68>>0]|0)<<24|(d[b+66>>0]|0)<<8|(d[b+65>>0]|0))|0;l=0;while(1){if(((d[a+(l*23|0)+1>>0]|0)<<8|(d[a+(l*23|0)+2>>0]|0)<<16|(d[a+(l*23|0)>>0]|0)|0)==(f|0)?(d[a+(l*23|0)+3>>0]|0|0)==(g|0):0){m=l;break}l=l+1|0;if(l>>>0>=e>>>0){k=0;n=10;break}}if((n|0)==10)return k|0;if((m|0)<0){k=0;return k|0}if(((d[b+18>>0]|0)<<8|(d[b+19>>0]|0)<<16|(d[b+17>>0]|0))>>>0<=f>>>0){k=0;return k|0}c[h>>2]=(d[a+(m*23|0)+6>>0]|0)<<8|(d[a+(m*23|0)+5>>0]|0);c[i>>2]=(d[a+(m*23|0)+8>>0]|0)<<8|(d[a+(m*23|0)+7>>0]|0);c[j>>2]=_((d[a+(m*23|0)+12>>0]|0)<<8|(d[a+(m*23|0)+11>>0]|0),(d[a+(m*23|0)+10>>0]|0)<<8|(d[a+(m*23|0)+9>>0]|0))|0;k=1;return k|0}function Gb(b,e,f,g,h,i){b=b|0;e=e|0;f=f|0;g=g|0;h=h|0;i=i|0;var j=0,k=0,l=0,m=0,n=0,o=0;if(!(Cb(0,e,f)|0)){j=0;return j|0}f=d[e+15>>0]<<8|d[e+16>>0]<<16|d[e+14>>0];if(!f){j=0;return j|0}b=e+(d[e+67>>0]<<16|d[e+68>>0]<<24|d[e+66>>0]<<8|d[e+65>>0])|0;k=0;while(1){if((d[b+(k*23|0)+1>>0]<<8|d[b+(k*23|0)+2>>0]<<16|d[b+(k*23|0)>>0]|0)==(h|0)?(d[b+(k*23|0)+3>>0]|0)==(i|0):0){l=k;break}k=k+1|0;if(k>>>0>=f>>>0){j=0;m=13;break}}if((m|0)==13)return j|0;if((l|0)<0){j=0;return j|0}if((d[e+18>>0]<<8|d[e+19>>0]<<16|d[e+17>>0])>>>0<=h>>>0){j=0;return j|0}c[g>>2]=h;c[g+4>>2]=i;if(!(a[e+20>>0]|0)){n=b+(l*23|0)+4|0;o=(d[e+21>>0]|0)>>>2}else{e=b+(l*23|0)+4|0;n=e;o=d[e>>0]|0}a[g+40>>0]=o&1;a[g+41>>0]=(d[n>>0]|0)>>>1&1;n=b+(l*23|0)+10|0;o=b+(l*23|0)+9|0;c[g+16>>2]=(d[n>>0]<<8|d[o>>0])<<2;e=b+(l*23|0)+12|0;i=b+(l*23|0)+11|0;c[g+20>>2]=(d[e>>0]<<8|d[i>>0])<<2;c[g+8>>2]=d[b+(l*23|0)+6>>0]<<8|d[b+(l*23|0)+5>>0];c[g+12>>2]=d[b+(l*23|0)+8>>0]<<8|d[b+(l*23|0)+7>>0];b=d[n>>0]<<8|d[o>>0];c[g+24>>2]=b;o=d[e>>0]<<8|d[i>>0];c[g+28>>2]=o;c[g+32>>2]=_(o,b)|0;c[g+36>>2]=l;j=1;return j|0}function Hb(b,e,f){b=b|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0;if(!(Cb(0,e,f)|0)){g=0;return g|0}h=(c[b+4>>2]|0)!=(c[b>>2]|0);if(!(a[e+20>>0]|0)){if(h)Ib(b);i=d[e+43>>0]<<16|d[e+44>>0]<<24|d[e+42>>0]<<8|d[e+41>>0];if(i>>>0>f>>>0){g=0;return g|0}j=d[e+52>>0]<<16|d[e+53>>0]<<24|d[e+51>>0]<<8|d[e+50>>0];if(j>>>0>f>>>0){g=0;return g|0}k=e+57|0;l=e+60|0;m=e+59|0;n=e+58|0;o=d[m>>0]<<16|d[l>>0]<<24|d[n>>0]<<8|d[k>>0];if(o>>>0>f>>>0){g=0;return g|0}p=d[e+46>>0]<<8|d[e+47>>0]<<16|d[e+45>>0];if(p>>>0>(f-i|0)>>>0){g=0;return g|0}q=d[e+55>>0]<<8|d[e+56>>0]<<16|d[e+54>>0];if(q>>>0>(f-j|0)>>>0){g=0;return g|0}r=e+61|0;s=e+64|0;t=e+63|0;u=e+62|0;if((d[t>>0]<<16|d[s>>0]<<24|d[u>>0]<<8|d[r>>0])>>>0>(f-o|0)>>>0){g=0;return g|0}if(!(gb(b,d[e+40>>0]<<8|d[e+39>>0],e+i|0,p,d[e+49>>0]<<8|d[e+48>>0],e+j|0,q)|0)){g=0;return g|0}if(!(kb(b,e+(d[m>>0]<<16|d[l>>0]<<24|d[n>>0]<<8|d[k>>0])|0,d[t>>0]<<16|d[s>>0]<<24|d[u>>0]<<8|d[r>>0])|0)){g=0;return g|0}}else if(h)Ib(b);a[b+585>>0]=1;g=1;return g|0}function Ib(a){a=a|0;var b=0,d=0,e=0,f=0;b=c[a>>2]|0;d=a+4|0;e=c[d>>2]|0;if((e|0)!=(b|0))c[d>>2]=e+(~((e+-8-b|0)>>>3)<<3);b=c[a+12>>2]|0;e=a+16|0;d=c[e>>2]|0;if((d|0)!=(b|0))c[e>>2]=d+(~(((0-b+(d+-11)|0)>>>0)/11|0)*11|0);d=c[a+28>>2]|0;b=a+32|0;if((c[b>>2]|0)!=(d|0))c[b>>2]=d;d=c[a+40>>2]|0;b=a+44|0;e=c[b>>2]|0;if((d|0)!=(e|0))c[b>>2]=e+(~((e+-4-d|0)>>>2)<<2);d=c[a+52>>2]|0;e=a+56|0;b=c[e>>2]|0;if((d|0)!=(b|0))c[e>>2]=b+(~((b+-2-d|0)>>>1)<<1);d=c[a+64>>2]|0;b=a+68|0;if((c[b>>2]|0)!=(d|0))c[b>>2]=d;d=c[a+76>>2]|0;b=a+80|0;e=c[b>>2]|0;if((d|0)!=(e|0))c[b>>2]=e+(~((e+-4-d|0)>>>2)<<2);d=c[a+88>>2]|0;e=a+92|0;b=c[e>>2]|0;if((d|0)!=(b|0))c[e>>2]=b+(~((b+-2-d|0)>>>1)<<1);d=c[a+100>>2]|0;b=a+104|0;if((c[b>>2]|0)!=(d|0))c[b>>2]=d;d=c[a+112>>2]|0;b=a+116|0;e=c[b>>2]|0;if((d|0)!=(e|0))c[b>>2]=e+(~((e+-4-d|0)>>>2)<<2);d=c[a+124>>2]|0;e=a+128|0;b=c[e>>2]|0;if((d|0)!=(b|0))c[e>>2]=b+(~((b+-2-d|0)>>>1)<<1);d=c[a+136>>2]|0;b=a+140|0;if((c[b>>2]|0)!=(d|0))c[b>>2]=d;d=c[a+148>>2]|0;b=a+152|0;e=c[b>>2]|0;if((d|0)!=(e|0))c[b>>2]=e+(~((e+-4-d|0)>>>2)<<2);d=c[a+160>>2]|0;e=a+164|0;b=c[e>>2]|0;if((d|0)==(b|0)){f=a+172|0;c[f>>2]=0;return}c[e>>2]=b+(~((b+-2-d|0)>>>1)<<1);f=a+172|0;c[f>>2]=0;return}function Jb(b){b=b|0;Ib(b);a[b+585>>0]=0;return 1}function Kb(b,c,e,f,g,h,i,j,k,l,m,n){b=b|0;c=c|0;e=e|0;f=f|0;g=g|0;h=h|0;i=i|0;j=j|0;k=k|0;l=l|0;m=m|0;n=n|0;var o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0;switch(j|0){case 20:case 19:case 18:case 11:case 9:case 8:case 4:case 2:case 0:{o=8;break}case 21:case 17:case 12:case 10:case 5:case 3:case 1:case 7:case 6:{o=16;break}case 13:{o=4;break}case 16:case 15:case 14:{o=2;break}default:pa(475191,474791,10833,475639)}if(!((k&2|0)==0&(a[b+585>>0]|0)!=0)){p=0;return p|0}if(!(Cb(0,c,e)|0)){p=0;return p|0}q=c+(d[c+67>>0]<<16|d[c+68>>0]<<24|d[c+66>>0]<<8|d[c+65>>0])|0;r=(d[c+21>>0]|0)>>>2;s=d[c+15>>0]<<8|d[c+16>>0]<<16|d[c+14>>0];if(!s){p=0;return p|0}else t=0;while(1){if((d[q+(t*23|0)+1>>0]<<8|d[q+(t*23|0)+2>>0]<<16|d[q+(t*23|0)>>0]|0)==(f|0)?(u=q+(t*23|0)+3|0,(d[u>>0]|0)==(g|0)):0){v=u;w=t;break}t=t+1|0;if(t>>>0>=s>>>0){p=0;x=39;break}}if((x|0)==39)return p|0;if((w|0)<0){p=0;return p|0}x=r&1;r=(x|0)==0;t=(j|0)==9&r?8:j;j=c+20|0;g=a[j>>0]|0;if(!(g<<24>>24)){if(a[q+(w*23|0)+4>>0]&1){p=0;return p|0}if(!r){r=w+1|0;if(r>>>0>=s>>>0){p=0;return p|0}if(!(a[q+(r*23|0)+4>>0]&1)){p=0;return p|0}if((d[q+(w*23|0)+10>>0]<<8|d[q+(w*23|0)+9>>0]|0)!=(d[q+(r*23|0)+10>>0]<<8|d[q+(r*23|0)+9>>0]|0)){p=0;return p|0}if((d[q+(w*23|0)+12>>0]<<8|d[q+(w*23|0)+11>>0]|0)!=(d[q+(r*23|0)+12>>0]<<8|d[q+(r*23|0)+11>>0]|0)){p=0;return p|0}}}r=q+(w*23|0)+10|0;s=q+(w*23|0)+9|0;f=q+(w*23|0)+12|0;u=q+(w*23|0)+11|0;y=_(d[f>>0]<<8|d[u>>0],d[r>>0]<<8|d[s>>0])|0;if((t&-2|0)==8&y>>>0<i>>>0){Hd(h+(_(y,o)|0)|0,0,_(i-y|0,o)|0)|0;z=a[j>>0]|0}else z=g;if(z<<24>>24==1){p=zb(0,t,h,i,c,e,d[r>>0]<<8|d[s>>0],d[f>>0]<<8|d[u>>0],d[q+(w*23|0)+6>>0]<<8|d[q+(w*23|0)+5>>0],d[q+(w*23|0)+8>>0]<<8|d[q+(w*23|0)+7>>0],0,d[q+(w*23|0)+15>>0]<<16|d[q+(w*23|0)+16>>0]<<24|d[q+(w*23|0)+14>>0]<<8|d[q+(w*23|0)+13>>0],d[q+(w*23|0)+19>>0]<<16|d[q+(w*23|0)+20>>0]<<24|d[q+(w*23|0)+18>>0]<<8|d[q+(w*23|0)+17>>0],k,(x|0)!=0,0,l,0,n,-1,-1)|0;return p|0}z=(x|0)!=0;x=z?q+((w+1|0)*23|0)|0:0;if(a[q+(w*23|0)+4>>0]&1)pa(475310,474791,10769,475364);g=(x|0)!=0;if(g){if(!(a[x+4>>0]&1))pa(475386,474791,10774,475364);j=a[r>>0]|0;o=a[s>>0]|0;if(((j&255)<<8|o&255|0)!=(d[x+10>>0]<<8|d[x+9>>0]|0))pa(475446,474791,10775,475364);y=a[f>>0]|0;A=a[u>>0]|0;if(((y&255)<<8|A&255|0)!=(d[x+12>>0]<<8|d[x+11>>0]|0))pa(475511,474791,10776,475364);B=a[v>>0]|0;if(B<<24>>24==(a[x+3>>0]|0)){C=j;D=o;E=y;F=A;G=B}else pa(475576,474791,10777,475364)}else{C=a[r>>0]|0;D=a[s>>0]|0;E=a[f>>0]|0;F=a[u>>0]|0;G=a[v>>0]|0}if(g){H=d[x+15>>0]<<16|d[x+16>>0]<<24|d[x+14>>0]<<8|d[x+13>>0];I=d[x+19>>0]<<16|d[x+20>>0]<<24|d[x+18>>0]<<8|d[x+17>>0]}else{H=0;I=0}p=qb(b,t,h,i,c,e,(C&255)<<8|D&255,(E&255)<<8|F&255,d[q+(w*23|0)+6>>0]<<8|d[q+(w*23|0)+5>>0],d[q+(w*23|0)+8>>0]<<8|d[q+(w*23|0)+7>>0],G&255,d[q+(w*23|0)+15>>0]<<16|d[q+(w*23|0)+16>>0]<<24|d[q+(w*23|0)+14>>0]<<8|d[q+(w*23|0)+13>>0],d[q+(w*23|0)+19>>0]<<16|d[q+(w*23|0)+20>>0]<<24|d[q+(w*23|0)+18>>0]<<8|d[q+(w*23|0)+17>>0],H,I,k,z,(a[c+23>>0]|0)==3,l,m,n)|0;return p|0}function Lb(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0;if(f>>>0>=21)pa(487698,474791,11376,487731);g=c[16704+(f*12|0)>>2]|0;if(!(898778>>>f&1)){if(!(e|d)){h=8;i=0}else pa(487753,474791,11385,487731);while(1){j=(h|0)<(g|0);k=j?h:g;l=b>>>(j?g-k|0:0);if(l>>>0>=1<<k>>>0){m=7;break}h=h-k|0;k=l<<h|i;if((h|0)<=0){n=k;m=14;break}else i=k}if((m|0)==7)pa(487785,474791,11396,487731);else if((m|0)==14)return n|0}m=(b&1|0)!=0?511:0;i=c[16956+(f<<3)+4>>2]|0;if(!(898768>>>f&1))pa(487799,474791,11408,487731);h=c[16956+(f<<3)>>2]|0;g=a[h>>0]|0;if(g<<24>>24==48)o=0;else o=b>>>(((g&255)<<24)+-1627389952>>24)<<1&2;g=a[h+1>>0]|0;if(g<<24>>24==48)p=o;else p=b>>>(((g&255)<<24)+-1627389952>>24)&1|o;o=p<<1;p=a[h+2>>0]|0;if(p<<24>>24==48)q=o;else q=b>>>(((p&255)<<24)+-1627389952>>24)&1|o;o=q<<1;q=a[h+3>>0]|0;if(q<<24>>24==48)r=o;else r=b>>>(((q&255)<<24)+-1627389952>>24)&1|o;o=r<<1;r=a[h+4>>0]|0;if(r<<24>>24==48)s=o;else s=b>>>(((r&255)<<24)+-1627389952>>24)&1|o;o=s<<1;s=a[h+5>>0]|0;if(s<<24>>24==48)t=o;else t=b>>>(((s&255)<<24)+-1627389952>>24)&1|o;o=t<<1;t=a[h+6>>0]|0;if(t<<24>>24==48)u=o;else u=b>>>(((t&255)<<24)+-1627389952>>24)&1|o;o=u<<1;u=a[h+7>>0]|0;if(u<<24>>24==48)v=o;else v=b>>>(((u&255)<<24)+-1627389952>>24)&1|o;o=v<<1;v=a[h+8>>0]|0;if(v<<24>>24==48)w=o;else w=b>>>(((v&255)<<24)+-1627389952>>24)&1|o;n=(w+(_(i,(599186>>>f&1|0)!=0?d:e)|0)^m)>>>2|m&128;return n|0}function Mb(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0;if(b>>>0>=21)pa(487698,474791,11433,487801);d=c[16704+(b*12|0)>>2]|0;if((c[16704+(b*12|0)+4>>2]<<1|1)+(c[16704+(b*12|0)+8>>2]<<2)<<d>>>0<=a>>>0)pa(487827,474791,11434,487801);if(!(898778>>>b&1)){e=Lb(a,0,0,b)|0;return e|0}f=(1<<d)+-1&a;g=a>>>d;if(!(599186>>>b&1)){e=Lb(f,0,g,b)|0;return e|0}else{e=Lb(f,g,0,b)|0;return e|0}return 0}function Nb(b,e){b=b|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0,_=0,$=0,aa=0,ba=0,ca=0,da=0,ea=0,fa=0,ga=0,ha=0,ia=0,ja=0,ka=0,la=0,ma=0,na=0,oa=0,qa=0,ra=0,sa=0,ta=0,ua=0,va=0,wa=0,xa=0,ya=0,za=0,Aa=0;f=i;i=i+96|0;g=f+80|0;h=f+64|0;j=f+52|0;k=f+40|0;l=f+16|0;m=f;n=c[e>>2]|0;o=d[490129+n>>0]|0;p=n+-4|0;do if(p>>>0>=3){q=c[e+4>>2]<<4;if(!(138>>>n&1)){r=488913+q|0;break}else{r=487889+q|0;break}}else r=487873;while(0);q=g;s=e+8|0;t=q+16|0;do{a[q>>0]=a[s>>0]|0;q=q+1|0;s=s+1|0}while((q|0)<(t|0));q=h;s=e+24|0;t=q+16|0;do{a[q>>0]=a[s>>0]|0;q=q+1|0;s=s+1|0}while((q|0)<(t|0));q=j;s=e+40|0;t=q+12|0;do{a[q>>0]=a[s>>0]|0;q=q+1|0;s=s+1|0}while((q|0)<(t|0));q=k;s=e+52|0;t=q+12|0;do{a[q>>0]=a[s>>0]|0;q=q+1|0;s=s+1|0}while((q|0)<(t|0));s=e+64|0;c[l>>2]=c[s>>2];c[l+4>>2]=c[s+4>>2];c[l+8>>2]=c[s+8>>2];c[l+12>>2]=c[s+12>>2];c[l+16>>2]=c[s+16>>2];c[l+20>>2]=c[s+20>>2];c[m>>2]=-1;c[m+4>>2]=-1;c[m+8>>2]=-1;s=c[e+88>>2]|0;u=1<<(d[490137+n>>0]|0)+s;v=u>>>1;w=(n&-2|0)==4;x=490161+n|0;y=u+255|0;u=(n|0)==1;z=(n&-3|0)==0;A=e+4|0;B=0;do{do if(B){if(z&(B|0)==1){D=d[490001+(c[A>>2]|0)>>0]|0;break}E=c[A>>2]|0;if(z&(B|0)==2){D=d[490065+E>>0]|0;break}else{D=d[489937+E>>0]|0;break}}else D=0;while(0);c[m+(B<<2)>>2]=D;if(v&d[g+D>>0]){E=0;do{if((d[r+E>>0]|0)==(B|0)){F=g+E|0;a[F>>0]=y-(d[F>>0]|0)}E=E+1|0}while((E|0)!=16);if(w){E=j+(B<<2)|0;F=a[E>>0]|0;G=k+(B<<2)|0;a[E>>0]=a[G>>0]|0;a[G>>0]=F;F=j+(B<<2)+1|0;G=a[F>>0]|0;E=k+(B<<2)+1|0;a[F>>0]=a[E>>0]|0;a[E>>0]=G;G=j+(B<<2)+2|0;E=a[G>>0]|0;F=k+(B<<2)+2|0;a[G>>0]=a[F>>0]|0;a[F>>0]=E}else{E=j+(B<<2)|0;F=d[E>>0]|d[E+1>>0]<<8|d[E+2>>0]<<16|d[E+3>>0]<<24;G=k+(B<<2)|0;H=d[G>>0]|d[G+1>>0]<<8|d[G+2>>0]<<16|d[G+3>>0]<<24;a[E>>0]=H;a[E+1>>0]=H>>8;a[E+2>>0]=H>>16;a[E+3>>0]=H>>24;a[G>>0]=F;a[G+1>>0]=F>>8;a[G+2>>0]=F>>16;a[G+3>>0]=F>>24}if(!u){F=l+(B<<3)|0;G=c[F>>2]|0;H=l+(B<<3)+4|0;c[F>>2]=c[H>>2];c[H>>2]=G;I=21}}else I=21;if(((I|0)==21?(I=0,w):0)?(G=1<<(d[x>>0]|0)-s,(G>>>1&d[h+D>>0]|0)!=0):0){H=G+255|0;G=0;do{if((d[r+G>>0]|0)==(B|0)){F=h+G|0;a[F>>0]=H-(d[F>>0]|0)}G=G+1|0}while((G|0)!=16);G=j+(B<<2)+3|0;H=a[G>>0]|0;F=k+(B<<2)+3|0;a[G>>0]=a[F>>0]|0;a[F>>0]=H}B=B+1|0}while(B>>>0<o>>>0);q=b;t=q+16|0;do{a[q>>0]=0;q=q+1|0}while((q|0)<(t|0));q=1<<n;t=n+1|0;if(t>>>0>=33)pa(508949,474791,11511,508996);B=Jd(1,0,t|0)|0;r=C;if(!(0<r>>>0|0==(r|0)&q>>>0<B>>>0))pa(508949,474791,11511,508996);if(t){B=t;t=q;q=0;while(1){r=q&7;D=8-r|0;s=D>>>0<B>>>0?D:B;D=b+(q>>>3)|0;a[D>>0]=d[D>>0]|t<<r;r=s+q|0;if((B|0)==(s|0)){J=r;break}else{B=B-s|0;t=t>>>s;q=r}}if(J>>>0<129)K=J;else pa(509015,474791,11520,508996)}else K=0;J=(n|0)==4;q=(n&-2|0)==4;if(q){t=c[e+92>>2]|0;if(t>>>0<4){L=2;M=t;N=K}else pa(508949,474791,11511,508996);while(1){t=N&7;B=8-t|0;r=B>>>0<L>>>0?B:L;B=b+(N>>>3)|0;a[B>>0]=d[B>>0]|M<<t;t=r+N|0;if((L|0)==(r|0)){O=t;break}else{L=L-r|0;M=M>>>r;N=t}}if(O>>>0<129)P=O;else pa(509015,474791,11520,508996)}else P=K;if(J){J=c[e+88>>2]|0;if(J>>>0<2){Q=1;R=J;S=P}else pa(508949,474791,11511,508996);while(1){J=S&7;K=8-J|0;O=K>>>0<Q>>>0?K:Q;K=b+(S>>>3)|0;a[K>>0]=d[K>>0]|R<<J;J=O+S|0;if((Q|0)==(O|0)){T=J;break}else{Q=Q-O|0;R=R>>>O;S=J}}if(T>>>0<129)U=T;else pa(509015,474791,11520,508996)}else U=P;if(p>>>0>2){p=c[e+4>>2]|0;P=142>>>n<<1&2|4;T=Jd(1,0,P|0)|0;S=C;if(0<S>>>0|0==(S|0)&p>>>0<T>>>0){V=P;W=p;X=U}else pa(508949,474791,11511,508996);while(1){p=X&7;P=8-p|0;T=P>>>0<V>>>0?P:V;P=b+(X>>>3)|0;a[P>>0]=d[P>>0]|W<<p;p=T+X|0;if((V|0)==(T|0)){Y=p;break}else{V=V-T|0;W=W>>>T;X=p}}if(Y>>>0<129)Z=Y;else pa(509015,474791,11520,508996)}else Z=U;U=n>>>0>3?4:3;Y=490153+n|0;X=490145+n|0;W=Z;Z=0;a:while(1){V=(Z|0)==3;p=W;T=0;while(1){P=a[j+(T<<2)+Z>>0]|0;if(V)_=a[Y>>0]|0;else _=d[X>>0]|0;if(_>>>0>=33){I=62;break a}S=Jd(1,0,_|0)|0;R=C;if(!(0<R>>>0|0==(R|0)&(P&255)>>>0<S>>>0)){I=62;break a}if(_){S=_;R=P&255;P=p;while(1){Q=P&7;J=8-Q|0;O=J>>>0<S>>>0?J:S;J=b+(P>>>3)|0;a[J>>0]=d[J>>0]|R<<Q;Q=O+P|0;if((S|0)==(O|0)){$=Q;break}else{S=S-O|0;R=R>>>O;P=Q}}if($>>>0<129)aa=$;else{I=66;break a}}else aa=p;P=a[k+(T<<2)+Z>>0]|0;if(V)ba=a[Y>>0]|0;else ba=d[X>>0]|0;if(ba>>>0>=33){I=72;break a}R=Jd(1,0,ba|0)|0;S=C;if(!(0<S>>>0|0==(S|0)&(P&255)>>>0<R>>>0)){I=72;break a}if(ba){R=ba;S=P&255;P=aa;while(1){Q=P&7;O=8-Q|0;J=O>>>0<R>>>0?O:R;O=b+(P>>>3)|0;a[O>>0]=d[O>>0]|S<<Q;Q=J+P|0;if((R|0)==(J|0)){ca=Q;break}else{R=R-J|0;S=S>>>J;P=Q}}if(ca>>>0<129)da=ca;else{I=76;break a}}else da=aa;T=T+1|0;if(T>>>0>=o>>>0){ea=da;break}else p=da}Z=Z+1|0;if(Z>>>0>=U>>>0){fa=ea;I=78;break}else W=ea}if((I|0)==62)pa(508949,474791,11511,508996);else if((I|0)==66)pa(509015,474791,11520,508996);else if((I|0)==72)pa(508949,474791,11511,508996);else if((I|0)==76)pa(509015,474791,11520,508996);else if((I|0)==78){b:do if(203>>>n&1){ea=(n|0)==1;W=fa;U=0;while(1){Z=c[l+(U<<3)>>2]|0;if(Z>>>0<2){ga=1;ha=Z;ia=W}else{I=82;break}while(1){Z=ia&7;da=8-Z|0;aa=da>>>0<ga>>>0?da:ga;da=b+(ia>>>3)|0;a[da>>0]=d[da>>0]|ha<<Z;Z=aa+ia|0;if((ga|0)==(aa|0)){ja=Z;break}else{ga=ga-aa|0;ha=ha>>>aa;ia=Z}}if(ja>>>0>=129){I=85;break}if(!ea){Z=c[l+(U<<3)+4>>2]|0;if(Z>>>0<2){ka=1;la=Z;ma=ja}else{I=88;break}while(1){Z=ma&7;aa=8-Z|0;da=aa>>>0<ka>>>0?aa:ka;aa=b+(ma>>>3)|0;a[aa>>0]=d[aa>>0]|la<<Z;Z=da+ma|0;if((ka|0)==(da|0)){na=Z;break}else{ka=ka-da|0;la=la>>>da;ma=Z}}if(na>>>0<129)oa=na;else{I=91;break}}else oa=ja;U=U+1|0;if(U>>>0>=o>>>0){qa=oa;break b}else W=oa}if((I|0)==82)pa(508949,474791,11511,508996);else if((I|0)==85)pa(509015,474791,11520,508996);else if((I|0)==88)pa(508949,474791,11511,508996);else if((I|0)==91)pa(509015,474791,11520,508996)}else qa=fa;while(0);fa=e+88|0;e=490137+n|0;oa=c[m>>2]|0;o=c[m+4>>2]|0;ja=c[m+8>>2]|0;m=490161+n|0;n=qa;qa=0;c:while(1){na=qa<<2;ma=n;la=0;while(1){ka=la+na|0;l=c[fa>>2]|0;ia=(l|0)==0;if(ia)ra=d[e>>0]|0;else ra=(d[m>>0]|0)-l|0;l=ra+(((ka|0)==(oa|0)|(ka|0)==(o|0)|(ka|0)==(ja|0))<<31>>31)|0;ha=a[(ia?g:h)+ka>>0]|0;if(l>>>0>=33){I=100;break c}ka=Jd(1,0,l|0)|0;ia=C;if(!(0<ia>>>0|0==(ia|0)&(ha&255)>>>0<ka>>>0)){I=100;break c}if(l){ka=l;l=ha&255;ha=ma;while(1){ia=ha&7;ga=8-ia|0;W=ga>>>0<ka>>>0?ga:ka;ga=b+(ha>>>3)|0;a[ga>>0]=d[ga>>0]|l<<ia;ia=W+ha|0;if((ka|0)==(W|0)){sa=ia;break}else{ka=ka-W|0;l=l>>>W;ha=ia}}if(sa>>>0<129)ta=sa;else{I=104;break c}}else ta=ma;la=la+1|0;if(la>>>0>=4){ua=ta;break}else ma=ta}qa=qa+1|0;if(qa>>>0>=4){va=ua;I=106;break}else n=ua}if((I|0)==100)pa(508949,474791,11511,508996);else if((I|0)==104)pa(509015,474791,11520,508996);else if((I|0)==106){d:do if(q){ua=va;n=0;e:while(1){qa=n<<2;ta=ua;sa=0;while(1){ra=sa+qa|0;ma=c[fa>>2]|0;la=(ma|0)==0;if(la)wa=d[m>>0]|0;else wa=(d[e>>0]|0)+ma|0;ma=wa+(((ra|0)==(oa|0)|(ra|0)==(o|0)|(ra|0)==(ja|0))<<31>>31)|0;na=a[(la?h:g)+ra>>0]|0;if(ma>>>0>=33){I=114;break e}ra=Jd(1,0,ma|0)|0;la=C;if(!(0<la>>>0|0==(la|0)&(na&255)>>>0<ra>>>0)){I=114;break e}if(ma){ra=ma;ma=na&255;na=ta;while(1){la=na&7;ha=8-la|0;l=ha>>>0<ra>>>0?ha:ra;ha=b+(na>>>3)|0;a[ha>>0]=d[ha>>0]|ma<<la;la=l+na|0;if((ra|0)==(l|0)){xa=la;break}else{ra=ra-l|0;ma=ma>>>l;na=la}}if(xa>>>0<129)ya=xa;else{I=118;break e}}else ya=ta;sa=sa+1|0;if(sa>>>0>=4){za=ya;break}else ta=ya}n=n+1|0;if(n>>>0>=4){Aa=za;break d}else ua=za}if((I|0)==114)pa(508949,474791,11511,508996);else if((I|0)==118)pa(509015,474791,11520,508996)}else Aa=va;while(0);if((Aa|0)==128){i=f;return}else pa(490169,474791,11690,490188)}}}function Ob(b,e){b=b|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;f=d[e>>0]|0;g=a[e+1>>0]|0;h=a[e+2>>0]|0;i=a[e+3>>0]|0;a[b>>0]=-4;a[b+1>>0]=-3;a[b+2>>0]=-1;a[b+3>>0]=-1;c[b+4>>2]=-1;c[b+8>>2]=0;c[b+12>>2]=0;e=16;j=f<<8|f;f=64;while(1){k=f&7;l=8-k|0;m=(l|0)<(e|0)?l:e;l=b+(f>>3)|0;a[l>>0]=d[l>>0]|0|j<<k;k=m+f|0;if((e|0)==(m|0)){n=k;break}else{e=e-m|0;j=j>>>m;f=k}}f=g&255;g=h&255;h=i&255;i=16;j=f<<8|f;f=n;while(1){n=f&7;e=8-n|0;k=(e|0)<(i|0)?e:i;e=b+(f>>3)|0;a[e>>0]=d[e>>0]|0|j<<n;n=k+f|0;if((i|0)==(k|0)){o=n;break}else{i=i-k|0;j=j>>>k;f=n}}f=16;j=g<<8|g;g=o;while(1){o=g&7;i=8-o|0;n=(i|0)<(f|0)?i:f;i=b+(g>>3)|0;a[i>>0]=d[i>>0]|0|j<<o;o=n+g|0;if((f|0)==(n|0)){p=o;break}else{f=f-n|0;j=j>>>n;g=o}}g=16;j=h<<8|h;h=p;while(1){p=h&7;f=8-p|0;o=(f|0)<(g|0)?f:g;f=b+(h>>3)|0;a[f>>0]=d[f>>0]|0|j<<p;if((g|0)==(o|0))break;else{g=g-o|0;j=j>>>o;h=o+h|0}}return}function Pb(b,e,f){b=b|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0;g=i;i=i+32|0;h=g+20|0;j=g;k=g+24|0;if(f>>>0>=19)pa(490205,474791,11897,490236);l=e+20|0;m=(a[l>>0]|0)!=0?32:16;n=c[17372+(f<<2)>>2]|0;a[b>>0]=n;o=n>>>8;n=b+1|0;a[n>>0]=o;p=b+2|0;q=p;r=q+14|0;do{a[q>>0]=0;q=q+1|0}while((q|0)<(r|0));q=c[e>>2]|0;if(599186>>>q&1)pa(490252,474791,11912,490236);if(299592>>>q&1)pa(490252,474791,11912,490236);r=c[16704+(q*12|0)>>2]|0;q=e+4|0;s=o|(c[q>>2]<<3)+248;a[n>>0]=s;if((c[q>>2]|0)==1){o=c[e+12>>2]|0;a[n>>0]=s|o<<5;a[p>>0]=o>>>3;t=17}else{o=10;p=c[e+8>>2]|0;s=13;while(1){n=s&7;u=8-n|0;v=(u|0)<(o|0)?u:o;u=b+(s>>3)|0;a[u>>0]=d[u>>0]|p<<n;n=v+s|0;if((o|0)==(v|0)){w=n;break}else{o=o-v|0;p=p>>>v;s=n}}s=w&7;p=(c[e+12>>2]<<2&60)<<s;o=w>>3;n=b+o|0;a[n>>0]=p|d[n>>0];if((8-s|0)>>>0<6){s=b+(o+1)|0;a[s>>0]=d[s>>0]|p>>>8}t=w+6|0}do if(a[l>>0]|0){w=_(r,m)|0;if((w+-24|0)>>>0<73){p=b+(126-w>>3)|0;a[p>>0]=d[p>>0]|c[e+16>>2]<<6;break}else pa(490359,474791,11935,490236)}while(0);l=_((c[e+12>>2]>>2)+1|0,c[q>>2]|0)|0;if((l|0)>=10)pa(490414,474791,11942,490236);q=l<<1;p=d[476870+f>>0]|0;c[h>>2]=t;c[j>>2]=0;c[j+4>>2]=0;c[j+8>>2]=0;c[j+12>>2]=0;c[j+16>>2]=0;f=c[16704+(p*12|0)>>2]|0;if(!(599186>>>p&1))if(!(299592>>>p&1)){if((l|0)>0){l=(p&253|0)==1;p=t;t=0;while(1){if(l)x=p;else{w=p&7;s=d[e+21+t>>0]<<w;o=p>>3;n=j+o|0;a[n>>0]=d[n>>0]|s;if((8-w|0)>>>0<f>>>0){w=j+(o+1)|0;a[w>>0]=d[w>>0]|s>>>8}s=p+f|0;c[h>>2]=s;x=s}t=t+1|0;if((t|0)==(q|0))break;else p=x}}}else{y=3;z=23}else{y=5;z=23}a:do if((z|0)==23?(x=(y|0)==5,p=x?(q+4|0)/5|0:(q+2|0)/3|0,(p|0)>0):0){t=(1<<f)+-1|0;l=k+1|0;s=k+2|0;w=f<<1;o=f*3|0;n=o+7|0;v=(n|0)==0;u=f+3|0;A=w+3|0;B=w+5|0;w=o+5|0;o=~q;C=~y;D=0;while(1){E=_(D,y)|0;F=E+o|0;a[k>>0]=0;a[k+1>>0]=0;a[k+2>>0]=0;a[k+3>>0]=0;a[k+4>>0]=0;G=q-E|0;if((((G|0)<(y|0)?G:y)|0)>0)Ld(k|0,e+21+E|0,~((F|0)>(C|0)?F:C)|0)|0;if(!x){F=d[k>>0]|0;E=d[l>>0]|0;G=d[s>>0]|0;H=((E>>>f)*5|0)+(F>>>f)+((G>>>f)*25|0)|0;if((H|0)>=125)break;I=d[509078+H>>0]|0;if(!v){H=n;J=(E&t)<<u|F&t|(G&t)<<B|(I&7)<<f|(I>>>3&3)<<A|(I>>>5&3)<<w;I=c[h>>2]|0;while(1){G=I&7;F=8-G|0;E=(F|0)<(H|0)?F:H;F=j+(I>>3)|0;a[F>>0]=d[F>>0]|J<<G;G=E+I|0;if((H|0)==(E|0)){K=G;break}else{H=H-E|0;J=J>>>E;I=G}}c[h>>2]=K}}else oc(j,k,h,f);D=D+1|0;if((D|0)>=(p|0))break a}pa(509046,474791,11837,509059)}while(0);c[b>>2]=c[b>>2]|c[j>>2];f=b+4|0;c[f>>2]=c[f>>2]|c[j+4>>2];f=b+8|0;c[f>>2]=c[f>>2]|c[j+8>>2];f=b+12|0;c[f>>2]=c[f>>2]|c[j+12>>2];switch(r|0){case 1:{r=0;do{j=127-r|0;f=b+(j>>>3)|0;a[f>>0]=d[f>>0]|d[e+39+r>>0]<<(j&7);r=r+1|0}while((r|0)<(m|0));i=g;return 1}case 2:{r=0;do{j=126-(r<<1)|0;f=b+(j>>>3)|0;a[f>>0]=d[f>>0]|d[507257+(d[e+39+r>>0]|0)>>0]<<(j&6);r=r+1|0}while((r|0)<(m|0));i=g;return 1}case 3:{r=0;while(1){j=(_(r,-3)|0)+125|0;f=d[490433+(d[e+39+r>>0]|0)>>0]<<(j&7);h=j>>>3;if(j>>>0>=128){z=45;break}j=h+1|0;k=b+h|0;a[k>>0]=d[k>>0]|f;if(j>>>0<16){k=b+j|0;a[k>>0]=d[k>>0]|f>>>8}r=r+1|0;if((r|0)>=(m|0)){z=59;break}}if((z|0)==45)pa(490441,474791,11983,490236);else if((z|0)==59){i=g;return 1}break}case 4:{r=0;while(1){f=124-(r<<2)|0;if((f|0)<=-1){z=51;break}k=f>>3;if((k|0)>=16){z=51;break}j=b+k|0;a[j>>0]=d[j>>0]|d[490452+(d[e+39+r>>0]|0)>>0]<<(f&4);r=r+1|0;if((r|0)>=(m|0)){z=59;break}}if((z|0)==51)pa(490468,474791,11997,490236);else if((z|0)==59){i=g;return 1}break}case 5:{r=0;while(1){f=(_(r,-5)|0)+123|0;j=d[490496+(d[e+39+r>>0]|0)>>0]<<(f&7);k=f>>>3;if(f>>>0>=128){z=54;break}f=k+1|0;h=b+k|0;a[h>>0]=d[h>>0]|j;if(f>>>0<16){h=b+f|0;a[h>>0]=d[h>>0]|j>>>8}r=r+1|0;if((r|0)>=(m|0)){z=59;break}}if((z|0)==54)pa(490441,474791,12013,490236);else if((z|0)==59){i=g;return 1}break}default:pa(475191,474791,12022,490236)}return 0}function Qb(b,f,g,h){b=b|0;f=f|0;g=g|0;h=h|0;var j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0,$=0,aa=0,ba=0,ca=0,da=0,ea=0,fa=0,ga=0,ha=0,ia=0,ja=0,ka=0,la=0,ma=0,na=0,oa=0,qa=0,ra=0,sa=0,ta=0,ua=0,va=0,wa=0,xa=0,ya=0,za=0,Aa=0,Ba=0;j=i;i=i+48|0;k=j;l=j+32|0;m=d[b>>0]&127;n=a[490544+m>>0]|0;o=n&255;if((m|0)==69){p=0;i=j;return p|0}c[f+104>>2]=o;m=c[16544+(o<<3)+4>>2]|0;if(n<<24>>24==8){q=m>>>3;r=m&7;s=(d[b+q>>0]|0)>>>r;t=8-r|0;if(t>>>0>7)u=s;else u=d[b+(q+1)>>0]<<t|s;s=m+8|0;t=f+112|0;a[t>>0]=u;if(s>>>0>=112)pa(509223,474791,12121,509203);u=s>>>3;q=s&7;s=(d[b+u>>0]|0)>>>q;r=8-q|0;if(r>>>0>7)v=s;else v=d[b+(u+1)>>0]<<r|s;s=m+16|0;a[t+1>>0]=v;if(s>>>0>=112)pa(509223,474791,12121,509203);v=s>>>3;r=s&7;s=(d[b+v>>0]|0)>>>r;u=8-r|0;if(u>>>0>7)w=s;else w=d[b+(v+1)>>0]<<u|s;s=m+24|0;a[t+2>>0]=w;if(s>>>0>=112)pa(509223,474791,12121,509203);w=s>>>3;u=s&7;s=(d[b+w>>0]|0)>>>u;v=8-u|0;if(v>>>0>7)x=s;else x=d[b+(w+1)>>0]<<v|s;s=m+32|0;a[t+3>>0]=x;if(!h){p=1;i=j;return p|0}a[f+118>>0]=0;x=m+33|0;a[f+119>>0]=(d[b+(s>>>3)>>0]&1<<(s&7)|0)!=0&1;if(x>>>0>=112)pa(509223,474791,12121,509203);s=x>>>3;t=x&7;x=(d[b+s>>0]|0)>>>t;v=8-t|0;if(v>>>0>2)y=x;else y=d[b+(s+1)>>0]<<v|x;x=m+36|0;c[f+120>>2]=y&7;c[f+124>>2]=0;if(x>>>0>=112)pa(509223,474791,12121,509203);y=x>>>3;v=x&7;x=(d[b+y>>0]|0)>>>v;s=8-v|0;if(s>>>0>1)z=x;else z=d[b+(y+1)>>0]<<s|x;x=m+38|0;c[f+136>>2]=z&3;if(x>>>0>=112)pa(509223,474791,12121,509203);z=x>>>3;s=x&7;x=(d[b+z>>0]|0)>>>s;y=8-s|0;if(y>>>0>4)A=x;else A=d[b+(z+1)>>0]<<y|x;x=m+43|0;c[f+140>>2]=A&31;if(x>>>0>=112)pa(509223,474791,12121,509203);A=x>>>3;y=x&7;x=(d[b+A>>0]|0)>>>y;z=8-y|0;if(z>>>0>4)B=x;else B=d[b+(A+1)>>0]<<z|x;x=m+48|0;c[f+144>>2]=B&31;if(x>>>0>=112)pa(509223,474791,12121,509203);B=x>>>3;z=x&7;x=(d[b+B>>0]|0)>>>z;A=8-z|0;if(A>>>0>4)D=x;else D=d[b+(B+1)>>0]<<A|x;c[f+148>>2]=D&31;c[f+128>>2]=0;c[f+132>>2]=0;p=1;i=j;return p|0}do if(h){D=m+1|0;a[f+116>>0]=(d[b+(m>>>3)>>0]&1<<(m&7)|0)!=0&1;x=(516863>>>o&1|0)==0;if(x){E=0;F=D}else{E=(d[b+(D>>>3)>>0]&1<<(D&7)|0)!=0&1;F=m+2|0}a[f+117>>0]=E;D=F+1|0;a[f+118>>0]=(d[b+(F>>>3)>>0]&1<<(F&7)|0)!=0&1;A=F+2|0;a[f+119>>0]=(d[b+(D>>>3)>>0]&1<<(D&7)|0)!=0&1;if(A>>>0>=112)pa(509223,474791,12121,509203);D=A>>>3;B=A&7;A=(d[b+D>>0]|0)>>>B;z=8-B|0;if(z>>>0>2)G=A;else G=d[b+(D+1)>>0]<<z|A;A=F+5|0;c[f+120>>2]=G&7;if(A>>>0>=112)pa(509223,474791,12121,509203);z=A>>>3;D=A&7;A=(d[b+z>>0]|0)>>>D;B=8-D|0;if(B>>>0>2)H=A;else H=d[b+(z+1)>>0]<<B|A;A=F+8|0;c[f+124>>2]=H&7;if(x){c[f+128>>2]=0;I=A}else{if(A>>>0>=112)pa(509223,474791,12121,509203);x=A>>>3;B=A&7;A=(d[b+x>>0]|0)>>>B;z=8-B|0;if(z>>>0>4)J=A;else J=d[b+(x+1)>>0]<<z|A;c[f+128>>2]=J&31;I=F+13|0}if((o+-8|0)>>>0>=10){c[f+132>>2]=0;K=I;break}if(I>>>0>=112)pa(509223,474791,12121,509203);A=I>>>3;z=I&7;x=(d[b+A>>0]|0)>>>z;B=8-z|0;if(B>>>0>7)L=x;else L=d[b+(A+1)>>0]<<B|x;c[f+132>>2]=L&255;K=I+8|0}else K=(d[490672+o>>0]|0)+m|0;while(0);switch(o|0){case 16:case 9:case 7:case 4:case 2:{if(K>>>0>=112)pa(509223,474791,12121,509203);m=K>>>3;I=K&7;L=(d[b+m>>0]|0)>>>I;F=8-I|0;if(F>>>0>4)M=L;else M=d[b+(m+1)>>0]<<F|L;c[f+108>>2]=M&31;N=K+5|0;O=2;break}case 3:{if(K>>>0>=112)pa(509223,474791,12121,509203);M=K>>>3;L=K&7;F=(d[b+M>>0]|0)>>>L;m=8-L|0;if(m>>>0>3)P=F;else P=d[b+(M+1)>>0]<<m|F;c[f+108>>2]=P&15;N=K+4|0;O=3;break}default:{N=K;O=1}}a:do switch(o|0){case 16:case 9:case 4:case 2:{K=c[f+108>>2]|0;if(K>>>0>29){p=0;i=j;return p|0}else{Q=e[19252+(K*6|0)+2>>1]|0;R=83;break a}break}case 3:{K=c[f+108>>2]|0;if(K>>>0>10){p=0;i=j;return p|0}else{S=N;T=e[19546+(K*6|0)+2>>1]|0;U=1;break a}break}case 7:{K=c[f+108>>2]|0;if(K>>>0>18){p=0;i=j;return p|0}else{S=N;T=e[19432+(K*6|0)+2>>1]|0;U=1;break a}break}default:{Q=0;R=83}}while(0);b:do if((R|0)==83){switch(o|0){case 13:case 11:case 6:break;case 17:{c[f+16>>2]=3;S=N;T=Q;U=2;break b;break}default:{S=N;T=Q;U=1;break b}}if(N>>>0>=112)pa(509223,474791,12121,509203);K=N>>>3;P=N&7;F=(d[b+K>>0]|0)>>>P;m=8-P|0;if(m>>>0>1)V=F;else V=d[b+(K+1)>>0]<<m|F;c[f+16>>2]=V&3;S=N+2|0;T=Q;U=2}while(0);Q=(U|0)==2;a[f+20>>0]=Q&1;c[f+4>>2]=O;c[f+8>>2]=T;T=d[476927+o>>0]|0;N=d[476832+o>>0]|0;c[f>>2]=d[476851+o>>0];V=T<<1;F=_(V,O)|0;m=d[476870+o>>0]|0;c[f+12>>2]=d[490691+o>>0];K=c[16704+(m*12|0)>>2]|0;P=599186>>>m&1;M=(P|0)!=0;if(!M)if(!(299592>>>m&1)){W=S;X=1;Y=0;Z=0;$=0}else{aa=3;ba=5;ca=((F+2|0)>>>0)/3|0;R=94}else{aa=5;ba=3;ca=((F+4|0)>>>0)/5|0;R=94}c:do if((R|0)==94){L=(ca|0)==0;if(!L){I=P+7|0;J=ca+-1|0;H=F-(_(J,aa)|0)|0;G=(299592>>>m&1|0)==0;E=I>>>0<10;h=S;x=0;while(1){d:do if((x|0)==(J|0)){if(!M){if(G){R=107;break}switch(H|0){case 1:{da=3;break d;break}case 2:break;default:{R=107;break d}}da=5;break}switch(H|0){case 1:{da=2;break d;break}case 2:{da=4;break d;break}case 3:{da=5;break d;break}case 4:{da=7;break d;break}default:{R=107;break d}}}else R=107;while(0);if((R|0)==107){R=0;if(E)da=I;else{R=108;break}}if(h>>>0>=112){R=110;break}B=h>>>3;A=h&7;z=(d[b+B>>0]|0)>>>A;D=8-A|0;A=(D|0)>(da|0)?da:D;if((A|0)==(da|0))ea=z;else ea=d[b+(B+1)>>0]<<A|z;z=da+h|0;c[k+(x<<2)>>2]=ea&(1<<da)+-1;x=x+1|0;if(x>>>0>=ca>>>0){W=z;X=L;Y=aa;Z=ba;$=ca;break c}else h=z}if((R|0)==108)pa(509032,474791,12118,509203);else if((R|0)==110)pa(509223,474791,12121,509203)}else{W=S;X=1;Y=aa;Z=ba;$=0}}while(0);e:do if(F){ba=(m&253|0)==1;aa=(1<<K)+-1|0;S=W;ca=0;da=0;ea=0;M=0;while(1){if(ba){fa=0;ga=S}else{if(S>>>0>=112){R=116;break}P=S>>>3;h=S&7;L=(d[b+P>>0]|0)>>>h;x=8-h|0;h=(x|0)>(K|0)?K:x;if((h|0)==(K|0))ha=L;else ha=d[b+(P+1)>>0]<<h|L;fa=ha&aa;ga=S+K|0}if(X){ia=ca;ja=da;ka=M;la=fa}else{if(!da){if(M>>>0>=$>>>0){R=123;break}ma=c[k+(M<<2)>>2]|0;na=Y;oa=M+1|0}else{ma=ca;na=da;oa=M}ia=(ma>>>0)/(Z>>>0)|0;ja=na+-1|0;ka=oa;la=((ma>>>0)%(Z>>>0)|0)<<K|fa}a[f+21+ea>>0]=la;ea=ea+1|0;if(ea>>>0>=F>>>0){qa=ga;break e}else{S=ga;ca=ia;da=ja;M=ka}}if((R|0)==116)pa(509223,474791,12121,509203);else if((R|0)==123)pa(490710,474791,12383,490736)}else qa=W;while(0);W=c[f+108>>2]|0;do if(O>>>0>1){if((O|0)==3){ra=476172+(W<<4)|0;sa=476742+(W*3|0)|0;R=133;break}if(n<<24>>24==7){ta=476348+(W<<4)|0;ua=476775+(W*3|0)|0;R=141;break}else{ra=475692+(W<<4)|0;sa=476652+(W*3|0)|0;R=133;break}}else{ra=490528;sa=490528;R=133}while(0);f:do if((R|0)==133)if(n<<24>>24==18){W=qa;ka=0;while(1){ja=(((ka|0)==0)<<31>>31)+N|0;if(ja>>>0>=10)break;if(!ja){va=0;wa=W}else{ia=W>>>3;ga=W&7;F=(d[b+ia>>0]|0)>>>ga;la=8-ga|0;ga=(la|0)>(ja|0)?ja:la;if((ga|0)==(ja|0))xa=F;else xa=d[b+(ia+1)>>0]<<ga|F;va=xa&(1<<ja)+-1;wa=ja+W|0}a[f+39+ka>>0]=va;ka=ka+1|0;if(ka>>>0>=16){ya=ra;break f}else W=wa}pa(509032,474791,12065,509240)}else{ta=ra;ua=sa;R=141}while(0);g:do if((R|0)==141){sa=128-qa|0;ra=(sa|0)<64?sa:64;if(ra>>>0>=65)pa(509256,474791,12095,509272);if(!ra){za=0;Aa=0}else{sa=qa;wa=0;va=0;xa=0;while(1){n=sa&7;W=ra-xa|0;ka=8-n|0;ja=(W|0)<(ka|0)?W:ka;ka=Jd((1<<ja)+-1&(d[b+(sa>>>3)>>0]|0)>>>n|0,0,xa|0)|0;n=ka|wa;ka=C|va;xa=ja+xa|0;if(xa>>>0>=ra>>>0){za=n;Aa=ka;break}else{sa=ja+sa|0;wa=n;va=ka}}}va=(1<<N)+-1|0;wa=N+-1|0;sa=(1<<wa)+-1|0;if(Q){a[f+39>>0]=za&sa;ra=Id(za|0,Aa|0,wa|0)|0;a[f+40>>0]=ra&sa;ra=wa<<1;xa=2;while(1){ka=Id(za|0,Aa|0,ra|0)|0;a[f+39+xa>>0]=ka&va;xa=xa+1|0;if((xa|0)==32){ya=ta;break g}else ra=ra+N|0}}if((O|0)!=1){ra=d[ua>>0]|0;xa=d[ua+1>>0]|0;ka=d[ua+2>>0]|0;n=0;ja=0;while(1){W=(ja|0)==(ka|0)|((ja|0)==(ra|0)|(ja|0)==(xa|0));F=Id(za|0,Aa|0,n|0)|0;a[f+39+ja>>0]=F&(W?sa:va);ja=ja+1|0;if((ja|0)==16){ya=ta;break g}else n=(W?wa:N)+n|0}}if(!(33793>>>o&1)){a[f+39>>0]=za&sa;n=Id(za|0,Aa|0,wa|0)|0;a[f+40>>0]=n&va;n=wa+N|0;ja=Id(za|0,Aa|0,n|0)|0;a[f+41>>0]=ja&va;ja=n+N|0;n=Id(za|0,Aa|0,ja|0)|0;a[f+42>>0]=n&va;n=ja+N|0;ja=Id(za|0,Aa|0,n|0)|0;a[f+43>>0]=ja&va;ja=n+N|0;n=Id(za|0,Aa|0,ja|0)|0;a[f+44>>0]=n&va;n=ja+N|0;ja=Id(za|0,Aa|0,n|0)|0;a[f+45>>0]=ja&va;ja=n+N|0;n=Id(za|0,Aa|0,ja|0)|0;a[f+46>>0]=n&va;n=ja+N|0;ja=Id(za|0,Aa|0,n|0)|0;a[f+47>>0]=ja&va;ja=n+N|0;n=Id(za|0,Aa|0,ja|0)|0;a[f+48>>0]=n&va;n=ja+N|0;ja=Id(za|0,Aa|0,n|0)|0;a[f+49>>0]=ja&va;ja=n+N|0;n=Id(za|0,Aa|0,ja|0)|0;a[f+50>>0]=n&va;n=ja+N|0;ja=Id(za|0,Aa|0,n|0)|0;a[f+51>>0]=ja&va;ja=n+N|0;n=Id(za|0,Aa|0,ja|0)|0;a[f+52>>0]=n&va;n=ja+N|0;ja=Id(za|0,Aa|0,n|0)|0;a[f+53>>0]=ja&va;ja=Id(za|0,Aa|0,n+N|0)|0;a[f+54>>0]=ja&va;ya=ta;break}else{a[f+39>>0]=za&7;ja=Id(za|0,Aa|0,3)|0;a[f+40>>0]=ja&15;ja=Id(za|0,Aa|0,7)|0;a[f+41>>0]=ja&15;ja=Id(za|0,Aa|0,11)|0;a[f+42>>0]=ja&15;ja=Id(za|0,Aa|0,15)|0;a[f+43>>0]=ja&15;ja=Id(za|0,Aa|0,19)|0;a[f+44>>0]=ja&15;ja=Id(za|0,Aa|0,23)|0;a[f+45>>0]=ja&15;ja=Id(za|0,Aa|0,27)|0;a[f+46>>0]=ja&15;ja=Id(za|0,Aa|0,31)|0;a[f+47>>0]=ja&15;ja=Id(za|0,Aa|0,35)|0;a[f+48>>0]=ja&15;ja=Id(za|0,Aa|0,39)|0;a[f+49>>0]=ja&15;ja=Id(za|0,Aa|0,43)|0;a[f+50>>0]=ja&15;ja=Id(za|0,Aa|0,47)|0;a[f+51>>0]=ja&15;ja=Id(za|0,Aa|0,51)|0;a[f+52>>0]=ja&15;ja=Id(za|0,Aa|0,55)|0;a[f+53>>0]=ja&15;ja=Id(za|0,Aa|0,59)|0;a[f+54>>0]=ja&15;ya=ta;break}}while(0);if(!((o+-15|0)>>>0>2&g)){p=1;i=j;return p|0};a[l>>0]=0;a[l+1>>0]=0;a[l+2>>0]=0;g=0;o=0;while(1){ta=_(V,o)|0;if(((d[476946+(m<<9)+(d[ta+3+(f+21)>>0]<<1)>>0]|0)+(d[476946+(m<<9)+(d[(ta|1)+(f+21)>>0]<<1)>>0]|0)+(d[476946+(m<<9)+(d[ta+5+(f+21)>>0]<<1)>>0]|0)|0)<((d[476946+(m<<9)+(d[ta+2+(f+21)>>0]<<1)>>0]|0)+(d[476946+(m<<9)+(d[f+21+ta>>0]<<1)>>0]|0)+(d[476946+(m<<9)+(d[ta+4+(f+21)>>0]<<1)>>0]|0)|0)){Aa=0;do{za=(Aa<<1)+ta|0;ua=f+21+za|0;b=(za|1)+(f+21)|0;za=a[ua>>0]|0;a[ua>>0]=a[b>>0]|0;a[b>>0]=za;Aa=Aa+1|0}while(Aa>>>0<T>>>0);a[l+o>>0]=1;Ba=1}else Ba=g;o=o+1|0;if(o>>>0>=O>>>0)break;else g=Ba}if(!Ba){p=1;i=j;return p|0}Ba=(1<<N)+-1|0;N=0;do{if((a[l+(d[ya+N>>0]|0)>>0]|0)!=0?(g=_(N,U)|0,O=f+39+g|0,a[O>>0]=Ba-(d[O>>0]|0),Q):0){O=g+1+(f+39)|0;a[O>>0]=Ba-(d[O>>0]|0)}N=N+1|0}while((N|0)!=16);p=1;i=j;return p|0}
-function lb(f,h,j,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A){f=f|0;h=h|0;j=j|0;l=l|0;m=m|0;n=n|0;o=o|0;p=p|0;q=q|0;r=r|0;s=s|0;t=t|0;u=u|0;v=v|0;w=w|0;x=x|0;y=y|0;z=z|0;A=A|0;var B=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0,$=0,aa=0,ba=0,ca=0,da=0,ea=0,fa=0,ga=0,ha=0,ia=0,ja=0,ka=0,la=0,ma=0,na=0,oa=0,qa=0,ra=0,sa=0,ta=0,ua=0,va=0,wa=0,xa=0,ya=0,za=0,Aa=0,Ba=0,Ca=0,Da=0,Ea=0,Fa=0,Ga=0,Ha=0,Ia=0,Ja=0,Ka=0,La=0,Ma=0,Na=0,Oa=0,Pa=0,Qa=0,Ra=0,Sa=0,Ta=0,Ua=0,Va=0,Wa=0,Xa=0,Ya=0,Za=0,_a=0,$a=0,ab=0,bb=0,cb=0,db=0,eb=0,fb=0,gb=0,hb=0,ib=0,jb=0,kb=0,lb=0,pb=0,qb=0,rb=0,sb=0,tb=0,ub=0,vb=0,wb=0,xb=0,yb=0,zb=0,Ab=0,Bb=0,Cb=0,Db=0,Eb=0,Fb=0,Gb=0,Hb=0,Ib=0,Jb=0,Kb=0,Lb=0,Mb=0,Nb=0,Ob=0,Pb=0,Qb=0,Rb=0,Sb=0,Tb=0,Ub=0,Vb=0,Wb=0,Xb=0,Yb=0,Zb=0,_b=0,$b=0,ac=0,bc=0,cc=0,dc=0,fc=0,gc=0,hc=0,ic=0,jc=0,kc=0,lc=0,mc=0,nc=0,pc=0,qc=0,rc=0,sc=0,vc=0,wc=0,xc=0,yc=0,zc=0,Ac=0,Bc=0,Cc=0,Dc=0,Ec=0,Fc=0,Gc=0,Hc=0,Ic=0,Jc=0,Kc=0,Lc=0,Nc=0,Oc=0,Pc=0,Qc=0,Rc=0,Sc=0,Tc=0,Uc=0,Vc=0,Wc=0,Xc=0,Yc=0,Zc=0,_c=0,$c=0,ad=0,bd=0,cd=0,dd=0,ed=0,fd=0,gd=0,hd=0,id=0,jd=0,kd=0,ld=0,md=0,nd=0,od=0,pd=0,qd=0,rd=0,ud=0,vd=0,wd=0,xd=0,yd=0,zd=0,Ad=0,Bd=0,Cd=0,Dd=0,Ed=0,Fd=0,Gd=0,Hd=0,Kd=0,Ld=0,Md=0,Nd=0,Od=0,Pd=0,Qd=0,Rd=0,Sd=0,Td=0,Ud=0,Vd=0,Wd=0,Xd=0,Yd=0,Zd=0,_d=0,$d=0,ae=0,be=0,ce=0,de=0,ee=0,fe=0,ge=0,he=0,ie=0,je=0,ke=0,le=0,me=0,ne=0,oe=0,pe=0,qe=0,re=0,se=0,te=0,ue=0,ve=0,we=0,xe=0,ye=0,ze=0,Ae=0,Be=0,Ce=0,De=0,Ee=0,Fe=0,Ge=0,He=0,Ie=0,Je=0,Ke=0,Le=0,Me=0,Ne=0,Oe=0,Pe=0,Qe=0,Re=0,Se=0,Te=0,Ue=0,Ve=0,We=0,Xe=0,Ye=0,Ze=0,_e=0,$e=0,af=0,bf=0,cf=0,df=0,ef=0,ff=0,gf=0,hf=0,jf=0,kf=0,lf=0,mf=0,nf=0,of=0,pf=0,qf=0,rf=0,sf=0,tf=0,uf=0,vf=0,wf=0,xf=0,yf=0,zf=0,Af=0,Bf=0,Cf=0,Df=0,Ef=0,Ff=0,Gf=0,Hf=0,If=0,Jf=0,Kf=0,Lf=0,Mf=0,Nf=0,Of=0,Pf=0,Qf=0,Rf=0,Sf=0,Tf=0,Uf=0,Vf=0,Wf=0,Xf=0,Yf=0,Zf=0,_f=0,$f=0,ag=0,bg=0,cg=0,dg=0,eg=0,fg=0,gg=0,hg=0,ig=0,jg=0,kg=0,lg=0,mg=0,ng=0,og=0,pg=0,qg=0,rg=0,sg=0,tg=0,ug=0,vg=0,wg=0,xg=0,yg=0,zg=0,Ag=0,Bg=0,Cg=0,Dg=0,Eg=0,Fg=0,Gg=0,Hg=0,Ig=0,Jg=0,Kg=0,Lg=0,Mg=0,Ng=0,Og=0,Pg=0,Qg=0,Rg=0,Sg=0,Tg=0,Ug=0,Vg=0,Wg=0,Xg=0,Yg=0,Zg=0,_g=0,$g=0,ah=0,bh=0,ch=0,dh=0,eh=0,fh=0,gh=0,hh=0,ih=0,jh=0,kh=0,lh=0,mh=0,nh=0,oh=0,ph=0,qh=0,rh=0,sh=0,th=0,uh=0,vh=0,wh=0,xh=0,yh=0,zh=0,Ah=0,Bh=0,Ch=0,Dh=0,Eh=0,Fh=0,Gh=0,Hh=0,Ih=0,Jh=0,Kh=0,Lh=0,Mh=0,Nh=0,Oh=0,Ph=0,Qh=0,Rh=0,Sh=0,Th=0,Uh=0,Vh=0,Wh=0,Xh=0,Yh=0,Zh=0,_h=0,$h=0,ai=0,bi=0,ci=0,di=0,ei=0,fi=0,gi=0,hi=0,ii=0,ji=0,ki=0,li=0,mi=0,ni=0,oi=0,pi=0,qi=0,ri=0,si=0,ti=0,ui=0,vi=0,wi=0,xi=0,yi=0,zi=0,Ai=0,Bi=0,Ci=0,Di=0,Ei=0,Fi=0,Gi=0,Hi=0,Ii=0,Ji=0,Ki=0,Li=0,Mi=0,Ni=0,Oi=0,Pi=0,Qi=0,Ri=0,Si=0,Ti=0,Ui=0,Vi=0,Wi=0,Xi=0,Yi=0,Zi=0,_i=0,$i=0,aj=0,bj=0,cj=0,dj=0,ej=0,fj=0,gj=0,hj=0,ij=0,jj=0,kj=0,lj=0,mj=0,nj=0,oj=0,pj=0,qj=0,rj=0,sj=0,tj=0,uj=0,vj=0,wj=0,xj=0,yj=0,zj=0,Aj=0,Bj=0,Cj=0,Dj=0,Ej=0,Fj=0,Gj=0,Hj=0,Ij=0,Jj=0,Kj=0,Lj=0,Mj=0,Nj=0,Oj=0,Pj=0,Qj=0,Rj=0,Sj=0,Tj=0,Uj=0,Vj=0,Wj=0,Xj=0,Yj=0,Zj=0,_j=0,$j=0,ak=0,bk=0,ck=0,dk=0,ek=0,fk=0,gk=0,hk=0,ik=0,jk=0,kk=0,lk=0,mk=0,nk=0,ok=0,pk=0,qk=0,rk=0,sk=0,tk=0,uk=0,vk=0,wk=0,xk=0,yk=0,zk=0,Ak=0,Bk=0,Ck=0,Dk=0,Ek=0,Fk=0,Gk=0,Hk=0,Ik=0,Jk=0,Kk=0,Lk=0,Mk=0,Nk=0,Ok=0,Pk=0,Qk=0,Rk=0,Sk=0,Tk=0,Uk=0,Vk=0,Wk=0,Xk=0,Yk=0,Zk=0,_k=0,$k=0,al=0,bl=0,cl=0,dl=0,el=0,fl=0,gl=0,hl=0,il=0,jl=0,kl=0,ll=0,ml=0,nl=0,ol=0,pl=0,ql=0,rl=0,sl=0,tl=0,ul=0,vl=0,wl=0,xl=0,yl=0,zl=0,Al=0,Bl=0.0,Cl=0.0,Dl=0.0,El=0.0,Fl=0.0,Gl=0.0,Hl=0.0,Il=0.0,Jl=0.0,Kl=0.0,Ll=0.0,Ml=0.0,Nl=0.0,Ol=0.0,Pl=0.0,Ql=0.0,Rl=0.0,Sl=0.0,Tl=0.0,Ul=0.0,Vl=0.0,Wl=0.0,Xl=0.0,Yl=0.0,Zl=0.0,_l=0.0,$l=0.0,am=0.0,bm=0.0,cm=0.0,dm=0.0,em=0.0,fm=0.0,gm=0.0,hm=0.0,im=0.0,jm=0.0,km=0.0,lm=0.0,mm=0.0,nm=0.0,om=0.0,pm=0.0,qm=0.0,rm=0.0,sm=0.0,tm=0.0,um=0.0,vm=0.0,wm=0.0,xm=0.0,ym=0.0,zm=0.0,Am=0.0,Bm=0,Cm=0,Dm=0,Em=0,Fm=0,Gm=0,Hm=0,Im=0,Jm=0,Km=0,Lm=0,Mm=0,Nm=0,Om=0,Pm=0,Qm=0,Rm=0,Sm=0,Tm=0,Um=0,Vm=0,Wm=0,Xm=0,Ym=0,Zm=0,_m=0,$m=0,an=0,bn=0,cn=0,dn=0,en=0,fn=0,gn=0,hn=0,jn=0,kn=0,ln=0,mn=0,nn=0,on=0,pn=0,qn=0,rn=0,sn=0,tn=0,un=0,vn=0,wn=0,xn=0,yn=0,zn=0,An=0,Bn=0,Cn=0,Dn=0,En=0,Fn=0,Gn=0,Hn=0,In=0,Jn=0,Kn=0,Ln=0,Mn=0,Nn=0,On=0,Pn=0,Qn=0,Rn=0,Sn=0,Tn=0,Un=0,Vn=0,Wn=0,Xn=0,Yn=0,Zn=0,_n=0,$n=0,ao=0,bo=0,co=0,eo=0,fo=0,go=0,ho=0,io=0,jo=0,ko=0,lo=0,mo=0,no=0,oo=0,po=0,qo=0,ro=0,so=0,to=0,uo=0,vo=0;B=i;i=i+416|0;D=B+320|0;E=B+256|0;F=B+240|0;G=B+224|0;H=B+208|0;I=B+192|0;J=B+160|0;K=B+80|0;L=B+48|0;M=B+16|0;N=B+176|0;P=B+144|0;Q=B+128|0;R=B+112|0;S=B+96|0;T=B+408|0;U=B+64|0;V=B+400|0;W=B+32|0;X=B+392|0;Y=B;Z=B+384|0;$=(x|0)==0?f+176|0:x;x=_(l,j)|0;aa=o+-21|0;if(!w)if(aa>>>0>=9)if((o|0)==15)ba=(u+7|0)>>>3;else ba=j;else ba=u;else ba=w;w=aa>>>0>8|(A|0)!=0?A:v;if(r){if(t>>>0>15){ca=0;i=B;return ca|0}v=s&1;s=$+24+(v*192|0)+(t*12|0)|0;A=(c[$+24+(v*192|0)+(t*12|0)+4>>2]|0)-(c[s>>2]|0)>>2;if(x>>>0>A>>>0){tc(s,x-A|0);da=s}else da=s}else da=0;if((m|0)==0&(n|0)!=0){ca=0;i=B;return ca|0}s=m+n|0;n=f+172|0;A=c[n>>2]|0;c[N>>2]=0;t=N+4|0;c[t>>2]=0;c[N+8>>2]=0;if(!A)ea=0;else{ec(N,A);ea=c[n>>2]|0}v=N+12|0;c[v>>2]=A>>>1;A=f+16|0;aa=f+12|0;u=ea+(((c[A>>2]|0)-(c[aa>>2]|0)|0)/11|0)|0;if((o&-2|0)==6){ea=sd(x*12|0)|0;if(!ea)fa=0;else{ga=ea+(x<<3)|0;ha=ea;ia=15}}else{ga=0;ha=0;ia=15}a:do if((ia|0)==15){ea=(c[$+4>>2]|0)-(c[$>>2]|0)>>2;do if(ea>>>0<j>>>0){uc($,j-ea|0);ja=$+12|0;ka=$+16|0;la=c[ka>>2]|0;ma=c[ja>>2]|0;na=la-ma>>2;if(na>>>0<j>>>0){uc(ja,j-na|0);break}if(na>>>0>j>>>0?(na=ma+(j<<2)|0,(la|0)!=(na|0)):0)c[ka>>2]=la+(~((la+-4-na|0)>>>2)<<2)}while(0);b:do if(l){ea=(j|0)==0;na=f+32|0;la=f+28|0;ka=f+40|0;ma=f+52|0;ja=f+68|0;oa=f+64|0;qa=f+76|0;ra=f+4|0;sa=f+88|0;ta=r^1;ua=f+104|0;va=f+100|0;wa=f+112|0;xa=f+140|0;ya=f+136|0;za=f+148|0;Aa=f+160|0;Ba=f+124|0;Ca=(o&-3|0)==0;Da=(z|0)==0;Ea=D+1|0;Fa=D+2|0;Ga=D+3|0;Ha=L+4|0;Ia=L+8|0;Ja=L+12|0;Ka=E+8|0;La=E+9|0;Ma=E+2|0;Na=E+4|0;Oa=E+1|0;Pa=E+3|0;Qa=E+5|0;Ra=M+4|0;Sa=M+8|0;Ta=M+12|0;Ua=E+6|0;Va=E+7|0;Wa=E+11|0;Xa=E+13|0;Ya=E+15|0;Za=E+17|0;_a=E+19|0;$a=E+21|0;ab=E+23|0;bb=E+25|0;cb=E+27|0;db=E+29|0;eb=E+31|0;fb=E+33|0;gb=E+35|0;hb=E+37|0;ib=E+39|0;jb=E+41|0;kb=J+4|0;lb=J+8|0;pb=J+12|0;qb=F+1|0;rb=F+12+1|0;sb=E+10|0;tb=E+12|0;ub=E+14|0;vb=E+16|0;wb=E+18|0;xb=E+20|0;yb=E+22|0;zb=E+24|0;Ab=E+26|0;Bb=E+28|0;Cb=E+30|0;Db=E+32|0;Eb=E+34|0;Fb=E+36|0;Gb=E+38|0;Hb=E+40|0;Ib=H+12|0;Jb=I+12|0;Kb=Jb+2|0;Lb=Jb+1|0;Mb=D+1|0;Nb=D+2|0;Ob=D+3|0;Pb=D+4|0;Qb=D+5|0;Rb=D+6|0;Sb=D+7|0;Tb=I+1|0;Ub=I+2|0;Vb=I+3|0;Wb=I+4|0;Xb=Wb+1|0;Yb=Wb+2|0;Zb=Wb+3|0;_b=I+8|0;$b=_b+1|0;ac=_b+2|0;bc=_b+3|0;cc=I+12|0;dc=cc+1|0;fc=cc+2|0;gc=cc+3|0;hc=E+4|0;ic=E+8|0;jc=E+12|0;kc=F+4|0;lc=F+8|0;mc=F+12|0;nc=G+4|0;pc=G+8|0;qc=G+12|0;rc=H+4|0;sc=K+4|0;vc=H+8|0;wc=K+8|0;xc=H+12|0;yc=K+12|0;zc=(p|0)==4;Ac=P+4|0;Bc=P+8|0;Cc=P+12|0;Dc=ba<<2;Ec=(p|0)==2;Fc=(o|0)==24;Gc=ba<<1;Hc=~ba;Ic=S+4|0;Jc=T+2|0;Kc=S+8|0;Lc=T+4|0;Nc=S+12|0;Oc=T+6|0;Pc=S+2|0;Qc=S+1|0;Rc=S+4|0;Sc=Rc+2|0;Tc=Rc+1|0;Uc=T+2|0;Vc=S+8|0;Wc=Vc+2|0;Xc=Vc+1|0;Yc=T+4|0;Zc=S+12|0;_c=Zc+2|0;$c=Zc+1|0;ad=T+6|0;bd=U+4|0;cd=V+2|0;dd=U+8|0;ed=V+4|0;fd=U+12|0;gd=V+6|0;hd=W+4|0;id=X+2|0;jd=W+8|0;kd=X+4|0;ld=W+12|0;md=X+6|0;nd=Y+1|0;od=Y+4+1|0;pd=Z+2|0;qd=Y+8+1|0;rd=Z+4|0;ud=Y+12+1|0;vd=Z+6|0;wd=0;xd=0;yd=0;zd=3;Ad=m;Bd=0;Cd=0;Dd=0;Ed=0;Fd=0;Gd=0;Hd=~w;Kd=0;Ld=0;c:while(1){Md=(Hd|0)>-5?~Hd:4;Nd=Dd&1;d:do if(ea){Od=zd;Pd=yd;Qd=xd;Rd=wd;Sd=Cd;Td=Bd;Ud=Ad;Vd=Ed;Wd=Fd;Xd=Gd;Yd=Kd;Zd=Ld}else{_d=(Nd|0)==0;$d=$+((Nd^1)*12|0)|0;ae=$+(Nd*12|0)|0;be=_(Dd,j)|0;ce=_(Dd,ba)|0;de=(w|0)==(Dd<<2|0);ee=(Dd|0)==0;fe=(Dd|0)!=0;ge=wd;he=xd;ie=yd;je=zd;ke=Ad;le=Bd;me=Cd;ne=0;oe=Ed;pe=Fd;qe=Gd;re=Hc;se=Kd;te=Ld;while(1){ue=(re|0)>-5?~re:4;ve=(ne&1|0)==0;do if(ve){if(!_d){we=me;xe=le;ye=ke;ze=d[(c[ae>>2]|0)+(ne<<2)+2>>0]|0;Ae=qe;Be=te;break}do if(!qe){if((c[na>>2]|0)==(c[la>>2]|0)){ia=30;break c}else{Ce=me;De=ke;Ee=le}while(1){if(Ce>>>0>=16){Fe=Ee;Ge=De;He=Ce;break}if(De>>>0<s>>>0){Ie=De+1|0;Je=d[De>>0]|0}else{Ie=De;Je=0}Ee=Je<<Ce|Ee;Ce=Ce+8|0;if(Ce>>>0>=33){ia=35;break c}else De=Ie}Ke=c[(c[ka>>2]|0)+((Fe&1023)<<2)>>2]|0;if((Ke|0)>-1){Le=Ke>>16;Me=Ke&65535}else{Ne=c[ma>>2]|0;Oe=10;Pe=Ke;while(1){Ke=Oe+1|0;Qe=b[Ne+((Fe>>>Oe&1)+~Pe<<1)>>1]|0;Re=Qe<<16>>16;if(Qe<<16>>16<0){Oe=Ke;Pe=Re}else{Le=Ke;Me=Re;break}}}Pe=Fe>>>Le;Oe=He-Le|0;if((Me|0)==256){Se=Oe;Te=Pe;Ue=Ge;Ve=0;We=0}else{Xe=Oe;Ye=Pe;Ze=Ge;_e=0;$e=Me;break}while(1){Pe=Se;Oe=Ue;Ne=Te;while(1){if(Pe>>>0>=5){af=Ne;bf=Oe;cf=Pe;break}if(Oe>>>0<s>>>0){df=Oe+1|0;ef=d[Oe>>0]|0}else{df=Oe;ef=0}Ne=ef<<Pe|Ne;Pe=Pe+8|0;if(Pe>>>0>=33){ia=46;break c}else Oe=df}Oe=af>>>5;Pe=cf+-5|0;Ne=(af&15)<<Ve|We;Re=Ve+4|0;if(!(af&16)){ff=bf;gf=Oe;hf=Pe;jf=Ne;break}if(Re>>>0>31){ia=49;break c}else{Se=Pe;Te=Oe;Ue=bf;Ve=Re;We=Ne}}Xe=hf;Ye=gf;Ze=ff;_e=jf+2|0;$e=te}else{Xe=me;Ye=le;Ze=ke;_e=qe+-1|0;$e=te}while(0);a[(c[$d>>2]|0)+(ne<<2)+2>>0]=$e>>>4;we=Xe;xe=Ye;ye=Ze;ze=$e;Ae=_e;Be=$e}else{we=me;xe=le;ye=ke;ze=oe;Ae=qe;Be=te}while(0);Ne=ze&3;Re=ze>>>2;e:do switch(Ne|0){case 0:{if(!ne){ia=55;break c}else{kf=se;ia=79}break}case 1:{if(ee){ia=58;break c}kf=e[(c[$d>>2]|0)+(ne<<2)>>1]|0;ia=79;break}case 2:{if(r){Oe=c[(c[da>>2]|0)+(ne+be<<2)>>2]|0;lf=we;mf=xe;nf=ye;of=Oe&65535;pf=Oe>>>16;ia=80;break e}if(!(fe&(ne|0)!=0)){ia=64;break c}lf=we;mf=xe;nf=ye;of=e[(c[$d>>2]|0)+(ne+-1<<2)>>1]|0;pf=0;ia=80;break}default:{if((c[ja>>2]|0)==(c[oa>>2]|0)){ia=68;break c}else{qf=we;rf=ye;sf=xe}while(1){if(qf>>>0>=16){tf=sf;uf=rf;vf=qf;break}if(rf>>>0<s>>>0){wf=rf+1|0;xf=d[rf>>0]|0}else{wf=rf;xf=0}sf=xf<<qf|sf;qf=qf+8|0;if(qf>>>0>=33){ia=73;break c}else rf=wf}Oe=c[(c[qa>>2]|0)+((tf&1023)<<2)>>2]|0;if((Oe|0)>-1){yf=Oe>>16;zf=Oe&65535}else{Pe=c[sa>>2]|0;Ke=10;Qe=Oe;while(1){Oe=Ke+1|0;Af=b[Pe+((tf>>>Ke&1)+~Qe<<1)>>1]|0;Bf=Af<<16>>16;if(Af<<16>>16<0){Ke=Oe;Qe=Bf}else{yf=Oe;zf=Bf;break}}}Qe=zf+se|0;Ke=(c[ra>>2]|0)-(c[f>>2]|0)>>3;lf=vf-yf|0;mf=tf>>>yf;nf=uf;of=Qe-(Qe>>>0<Ke>>>0?0:Ke)|0;pf=0;ia=80}}while(0);if((ia|0)==79){ia=0;Ke=kf&65535;b[(c[ae>>2]|0)+(ne<<2)>>1]=Ke;Cf=Ke;Df=ye;Ef=xe;Ff=we;Gf=kf;ia=81}else if((ia|0)==80){ia=0;Ke=of&65535;b[(c[ae>>2]|0)+(ne<<2)>>1]=Ke;if((Ne|0)!=2|ta){Cf=Ke;Df=nf;Ef=mf;Ff=lf;Gf=of;ia=81}else{Hf=Ke;If=lf;Jf=mf;Kf=nf;Lf=pe;Mf=of;Nf=pf}}do if((ia|0)==81){ia=0;if(!pe){if((c[ua>>2]|0)==(c[va>>2]|0)){ia=84;break c}else{Of=Ff;Pf=Df;Qf=Ef}while(1){if(Of>>>0>=16){Rf=Qf;Sf=Pf;Tf=Of;break}if(Pf>>>0<s>>>0){Uf=Pf+1|0;Vf=d[Pf>>0]|0}else{Uf=Pf;Vf=0}Qf=Vf<<Of|Qf;Of=Of+8|0;if(Of>>>0>=33){ia=89;break c}else Pf=Uf}Ke=c[(c[wa>>2]|0)+((Rf&1023)<<2)>>2]|0;if((Ke|0)>-1){Wf=Ke>>16;Xf=Ke&65535}else{Qe=c[Ba>>2]|0;Pe=10;Bf=Ke;while(1){Ke=Pe+1|0;Oe=b[Qe+((Rf>>>Pe&1)+~Bf<<1)>>1]|0;Af=Oe<<16>>16;if(Oe<<16>>16<0){Pe=Ke;Bf=Af}else{Wf=Ke;Xf=Af;break}}}Bf=Rf>>>Wf;Pe=Tf-Wf|0;if((Xf|0)==(u|0)){if((c[xa>>2]|0)==(c[ya>>2]|0)){ia=96;break c}else{Yf=Pe;Zf=Sf;_f=Bf}while(1){if(Yf>>>0>=16){$f=_f;ag=Zf;bg=Yf;break}if(Zf>>>0<s>>>0){cg=Zf+1|0;dg=d[Zf>>0]|0}else{cg=Zf;dg=0}_f=dg<<Yf|_f;Yf=Yf+8|0;if(Yf>>>0>=33){ia=101;break c}else Zf=cg}Qe=c[(c[za>>2]|0)+(($f&1023)<<2)>>2]|0;if((Qe|0)>-1){eg=Qe>>16;fg=Qe&65535}else{Af=c[Aa>>2]|0;Ke=10;Oe=Qe;while(1){Qe=Ke+1|0;gg=b[Af+(($f>>>Ke&1)+~Oe<<1)>>1]|0;hg=gg<<16>>16;if(gg<<16>>16<0){Ke=Qe;Oe=hg}else{eg=Qe;fg=hg;break}}}Oe=$f>>>eg;Ke=bg-eg|0;do if((fg|0)==63){Af=Ke;hg=ag;Qe=Oe;while(1){if(Af>>>0>=8){ig=Qe;jg=hg;kg=Af;break}if(hg>>>0<s>>>0){lg=hg+1|0;mg=d[hg>>0]|0}else{lg=hg;mg=0}Qe=mg<<Af|Qe;Af=Af+8|0;if(Af>>>0>=33){ia=111;break c}else hg=lg}hg=ig>>>8;Af=kg+-8|0;Qe=ig&127;if(!(ig&128)){ng=Af;og=hg;pg=jg;qg=Qe;break}else{rg=Af;sg=jg;tg=hg}while(1){if(rg>>>0>=8){ug=tg;vg=sg;wg=rg;break}if(sg>>>0<s>>>0){xg=sg+1|0;yg=d[sg>>0]|0}else{xg=sg;yg=0}tg=yg<<rg|tg;rg=rg+8|0;if(rg>>>0>=33){ia=111;break c}else sg=xg}hg=ug>>>8;Af=wg+-8|0;gg=ug<<7&16256|Qe;if(!(ug&128)){ng=Af;og=hg;pg=vg;qg=gg;break}else{zg=Af;Ag=vg;Bg=hg}while(1){if(zg>>>0>=8){Cg=Bg;Dg=Ag;Eg=zg;break}if(Ag>>>0<s>>>0){Fg=Ag+1|0;Gg=d[Ag>>0]|0}else{Fg=Ag;Gg=0}Bg=Gg<<zg|Bg;zg=zg+8|0;if(zg>>>0>=33){ia=111;break c}else Ag=Fg}Qe=Cg>>>8;hg=Eg+-8|0;Af=Cg<<14&2080768|gg;if(!(Cg&128)){ng=hg;og=Qe;pg=Dg;qg=Af;break}else{Hg=hg;Ig=Dg;Jg=Qe}while(1){if(Hg>>>0>=8){Kg=Jg;Lg=Ig;Mg=Hg;break}if(Ig>>>0<s>>>0){Ng=Ig+1|0;Og=d[Ig>>0]|0}else{Ng=Ig;Og=0}Jg=Og<<Hg|Jg;Hg=Hg+8|0;if(Hg>>>0>=33){ia=111;break c}else Ig=Ng}gg=Kg>>>8;Qe=Mg+-8|0;hg=Kg<<21&266338304|Af;if(!(Kg&128)){ng=Qe;og=gg;pg=Lg;qg=hg;break}else{Pg=Qe;Qg=Lg;Rg=gg}while(1){if(Pg>>>0>=8){Sg=Rg;Tg=Qg;Ug=Pg;break}if(Qg>>>0<s>>>0){Vg=Qg+1|0;Wg=d[Qg>>0]|0}else{Vg=Qg;Wg=0}Rg=Wg<<Pg|Rg;Pg=Pg+8|0;if(Pg>>>0>=33){ia=111;break c}else Qg=Vg}if(!(Sg&128)){ng=Ug+-8|0;og=Sg>>>8;pg=Tg;qg=Sg<<28|hg}else{ia=808;break c}}else{ng=Ke;og=Oe;pg=ag;qg=fg}while(0);if((qg+3|0)>>>0>x>>>0){ia=114;break c}Xg=ng;Yg=og;Zg=pg;_g=qg+2|0;$g=((c[A>>2]|0)-(c[aa>>2]|0)|0)/11|0}else{Xg=Pe;Yg=Bf;Zg=Sf;_g=0;$g=Xf}}else{Xg=Ff;Yg=Ef;Zg=Df;_g=pe+-1|0;$g=((c[A>>2]|0)-(c[aa>>2]|0)|0)/11|0}Oe=((c[A>>2]|0)-(c[aa>>2]|0)|0)/11|0;Ke=(c[n>>2]|0)==0;if(($g|0)<(Oe|0)){if(Ke){Hf=Cf;If=Xg;Jf=Yg;Kf=Zg;Lf=_g;Mf=Gf;Nf=$g;break}Af=c[v>>2]|0;c[v>>2]=Af+1;gg=c[N>>2]|0;c[gg+(Af<<2)>>2]=$g;Af=c[v>>2]|0;if((Af|0)!=((c[t>>2]|0)-gg>>2|0)){Hf=Cf;If=Xg;Jf=Yg;Kf=Zg;Lf=_g;Mf=Gf;Nf=$g;break}c[v>>2]=Af>>>1;Hf=Cf;If=Xg;Jf=Yg;Kf=Zg;Lf=_g;Mf=Gf;Nf=$g;break}if(Ke){ia=119;break c}Ke=$g-Oe|0;Af=c[N>>2]|0;if((Ke|0)>=((c[t>>2]|0)-Af>>2|0)){ia=121;break c}gg=Af+(Ke<<2)|0;Qe=c[gg>>2]|0;if(($g|0)==(Oe|0)){Hf=Cf;If=Xg;Jf=Yg;Kf=Zg;Lf=_g;Mf=Gf;Nf=Qe}else{Oe=Af+(Ke>>>1<<2)|0;Ke=c[Oe>>2]|0;c[Oe>>2]=Qe;c[gg>>2]=Ke;Hf=Cf;If=Xg;Jf=Yg;Kf=Zg;Lf=_g;Mf=Gf;Nf=Qe}}while(0);Qe=c[f>>2]|0;if(Mf>>>0>=(c[ra>>2]|0)-Qe>>3>>>0){ia=130;break c}Ke=c[aa>>2]|0;if(Nf>>>0>=(((c[A>>2]|0)-Ke|0)/11|0)>>>0){ia=130;break c}if(r)c[(c[da>>2]|0)+(ne+be<<2)>>2]=Nf<<16|Mf;gg=c[22]|0;f:do if((Ne|0)==2&r&(Ca&(gg&1|0)!=0)){Oe=h+(_(ne+ce|0,p)|0)|0;c[Oe>>2]=-1;c[Oe+4>>2]=-1;ah=je;bh=ie;ch=he;dh=ge}else{Oe=Qe+(Mf<<3)|0;Af=Ke+(Nf*11|0)|0;do switch(o|0){case 0:{eh=_(ne+ce|0,p)|0;fh=a[Oe>>0]|0;gh=a[Oe+1>>0]|0;hh=d[Oe+2>>0]|0;ih=(gh&255)<31?(gh&255)<<5:992;gh=(hh>>>0<31?hh:31)|ih;hh=(ih|((fh&255)<31?(fh&255)<<10:31744))>>>7&248|ge&7;fh=gh>>>2&248|he&7;ih=gh<<3|ie&7;gh=a[Qe+(Mf<<3)+4>>0]|0;jh=gh&255;if((gh&255)>=8){ia=138;break c}gh=jh<<5|je&3|jh<<2;c[h+eh>>2]=hh|gh<<24|ih<<16&16711680|fh<<8;jh=a[Ke+(Nf*11|0)+5>>0]|0;kh=a[Ke+(Nf*11|0)+6>>0]|0;lh=a[Ke+(Nf*11|0)+7>>0]|0;a[h+(eh+4)>>0]=a[Ke+(Nf*11|0)+4>>0]|0;a[h+(eh+5)>>0]=jh;a[h+(eh+6)>>0]=kh;a[h+(eh+7)>>0]=lh;ah=gh&255;bh=ih&255;ch=fh&255;dh=hh&255;break f;break}case 2:{hh=_(ne+ce|0,p)|0;fh=h+hh|0;mb(fh,Oe,Af,q);if(!(gg&6)){ah=je;bh=ie;ch=he;dh=ge;break f}ih=c[22]|0;if(ih&2){a[fh>>0]=-1;a[h+(hh+1)>>0]=-1;a[h+(hh+2)>>0]=0;a[h+(hh+3)>>0]=0;ah=je;bh=ie;ch=he;dh=ge;break f}if(!(ih&4)){ah=je;bh=ie;ch=he;dh=ge;break f}a[h+(hh+4)>>0]=0;a[h+(hh+5)>>0]=0;a[h+(hh+6)>>0]=85;a[h+(hh+7)>>0]=85;ah=je;bh=ie;ch=he;dh=ge;break f;break}case 4:{hh=_(ne+ce|0,p)|0;ih=h+hh|0;fh=a[Ke+(Nf*11|0)+8>>0]|0;gh=fh&255;lh=a[Ke+(Nf*11|0)+9>>0]|0;eh=lh&255;kh=d[Qe+(Mf<<3)+4>>0]|0;g:do if(fh<<24>>24==lh<<24>>24){if((fh&255)>=4){ia=146;break c}jh=d[Oe>>0]|0;mh=(jh<<3|jh>>>2)+(c[17484+(kh<<4)+(gh<<2)>>2]|0)|0;if(mh>>>0>255)if((mh|0)<0){nh=0;ia=149}else oh=255;else{nh=mh;ia=149}if((ia|0)==149){ia=0;oh=nh}mh=oh&255;a[ih>>0]=mh;a[h+(hh+1)>>0]=mh;mh=h+(hh+2)|0;a[mh>>0]=0;a[mh+1>>0]=0;a[mh+2>>0]=0;a[mh+3>>0]=0;a[mh+4>>0]=0;a[mh+5>>0]=0}else{if((a[Ke+(Nf*11|0)+10>>0]|0)==2){ob(I,Oe,kh);mh=a[I+(eh<<2)>>0]|0;a[ih>>0]=a[I+(gh<<2)>>0]|0;a[h+(hh+1)>>0]=mh;mh=0;while(1){jh=Ke+(Nf*11|0)+mh|0;ph=mh<<2;qh=0;do{if((qh|mh)>>>0>=4){ia=156;break c}rh=(qh+ph|0)*3|0;sh=rh>>>3;th=rh&7;uh=ih+2+sh|0;vh=d[uh>>0]|0;wh=rh>>>0<40;if(wh)xh=d[sh+1+(ih+2)>>0]<<8|vh;else xh=vh;vh=xh&~(7<<th)|(((d[jh>>0]|0)>>>(qh<<1)&3|0)==(eh|0)&1)<<th;a[uh>>0]=vh;if(wh)a[sh+1+(ih+2)>>0]=vh>>>8;qh=qh+1|0}while(qh>>>0<4);mh=mh+1|0;if(mh>>>0>=4)break g}}h:do switch(fh<<24>>24){case 0:{if(lh<<24>>24==3){yh=0;break h}if(lh<<24>>24==2)yh=2;else ia=177;break}case 1:{if(lh<<24>>24==3){yh=1;break h}if(lh<<24>>24==2)yh=3;else ia=177;break}default:ia=177}while(0);if((ia|0)==177){ia=0;yh=4}mh=yh>>>0>3?0:yh;qh=(d[Oe>>0]|0)+(kh<<5)|0;a[ih>>0]=a[209052+(qh<<4)+(mh<<2)>>0]|0;a[h+(hh+1)>>0]=a[209052+(qh<<4)+(mh<<2)+1>>0]|0;jh=209052+(qh<<4)+(mh<<2)+2|0;mh=0;do{qh=Ke+(Nf*11|0)+mh|0;ph=mh<<2;vh=0;do{if((vh|mh)>>>0>=4){ia=167;break c}sh=(vh+ph|0)*3|0;wh=sh>>>3;uh=sh&7;th=ih+2+wh|0;rh=d[th>>0]|0;zh=sh>>>0<40;if(zh)Ah=d[wh+1+(ih+2)>>0]<<8|rh;else Ah=rh;rh=Ah&~(7<<uh)|((e[jh>>1]|0)>>>(((d[qh>>0]|0)>>>(vh<<1)&3)*3|0)&7)<<uh;a[th>>0]=rh;if(zh)a[wh+1+(ih+2)>>0]=rh>>>8;vh=vh+1|0}while(vh>>>0<4);mh=mh+1|0}while(mh>>>0<4)}while(0);ah=je;bh=ie;ch=he;dh=ge;break f;break}case 6:{ih=a[Oe>>0]|0;hh=a[Oe+1>>0]|0;kh=d[Oe+2>>0]|0;lh=(hh&255)<31?(hh&255)<<5:992;hh=(kh>>>0<31?kh:31)|lh;kh=(lh|((ih&255)<31?(ih&255)<<10:31744))>>>7&248|ge&7;ih=kh&255;lh=hh>>>2&248|he&7;fh=lh&255;eh=hh<<3|ie&7;hh=eh&255;gh=Qe+(Mf<<3)+4|0;hg=a[gh>>0]|0;mh=hg&255;if((hg&255)>=8){ia=180;break c}hg=mh<<5|je&3|mh<<2;mh=a[Ke+(Nf*11|0)+4>>0]|0;jh=a[Ke+(Nf*11|0)+5>>0]|0;vh=a[Ke+(Nf*11|0)+6>>0]|0;qh=ne+be|0;ph=Jd(d[Ke+(Nf*11|0)+7>>0]|0,0,56)|0;rh=C;wh=Jd(vh&255|0,0,48)|0;vh=C;zh=Jd(jh&255|0,0,40)|0;jh=ha+(qh<<3)|0;c[jh>>2]=kh|hg<<24|eh<<16&16711680|lh<<8|zh|wh|ph;c[jh+4>>2]=mh&255|C|vh|rh;rh=hg&255;hg=d[gh>>0]|0;gh=d[Ke+(Nf*11|0)+9>>0]|0;vh=c[Oe>>2]|0;mh=vh&255;jh=vh>>>5;ph=vh>>>10&63;wh=vh>>>13;zh=vh>>>18&63;vh=mh<<3&248|mh>>>2;mh=c[17484+(hg<<4)+(d[Ke+(Nf*11|0)+8>>0]<<2)>>2]|0;lh=vh+mh|0;if(lh>>>0>255)if((lh|0)<0){Bh=0;ia=183}else Ch=255;else{Bh=lh;ia=183}if((ia|0)==183){ia=0;Ch=Bh}lh=jh&248|ph;ph=lh+mh|0;if(ph>>>0>255)if((ph|0)<0){Dh=0;ia=186}else Eh=255;else{Dh=ph;ia=186}if((ia|0)==186){ia=0;Eh=Dh}ph=wh&248|zh;zh=ph+mh|0;if(zh>>>0>255)if((zh|0)<0){Fh=0;ia=189}else Gh=255;else{Fh=zh;ia=189}if((ia|0)==189){ia=0;Gh=Fh}zh=Ch&255;mh=Eh&255;wh=Gh&255;jh=c[17484+(hg<<4)+(gh<<2)>>2]|0;gh=jh+vh|0;if(gh>>>0>255)if((gh|0)<0){Hh=0;ia=192}else Ih=255;else{Hh=gh;ia=192}if((ia|0)==192){ia=0;Ih=Hh}gh=jh+lh|0;if(gh>>>0>255)if((gh|0)<0){Jh=0;ia=195}else Kh=255;else{Jh=gh;ia=195}if((ia|0)==195){ia=0;Kh=Jh}gh=jh+ph|0;if(gh>>>0>255)if((gh|0)<0){Lh=0;ia=198}else Mh=255;else{Lh=gh;ia=198}if((ia|0)==198){ia=0;Mh=Lh}if((zh&255)>(Ih&255)){ia=200;break c}if((mh&255)>(Kh&255)){ia=202;break c}if((wh&255)>(Mh&255)){ia=204;break c}wh=d[500349+(Gh&255)>>0]<<1;if(wh>>>0>=32){ia=206;break c}mh=wh|d[500093+(Eh&255)>>0]<<5|d[500093+(Ch&255)>>0]<<10|32768;if(mh>>>0>=65536){ia=208;break c}wh=d[500680+(Mh&255)>>0]|d[500680+(Kh&255)>>0]<<5|d[500680+(Ih&255)>>0]<<10|32768;if(wh>>>0>=65536){ia=210;break c}c[ga+(qh<<2)>>2]=wh<<16|mh&65534;ah=rh;bh=hh;ch=fh;dh=ih;break f;break}case 7:{if(Da){ia=213;break c}ih=a[Oe>>0]|0;fh=a[Oe+1>>0]|0;hh=d[Oe+2>>0]|0;rh=(fh&255)<31?(fh&255)<<5:992;fh=(hh>>>0<31?hh:31)|rh;hh=(rh|((ih&255)<31?(ih&255)<<10:31744))>>>7&248|ge&7;ih=hh&255;rh=fh>>>2&248|he&7;mh=rh&255;wh=fh<<3|ie&7;fh=wh&255;qh=Qe+(Mf<<3)+4|0;zh=a[qh>>0]|0;gh=zh&255;if((zh&255)>=8){ia=215;break c}zh=gh<<5|je&3|gh<<2;gh=a[Af>>0]|0;ph=a[Ke+(Nf*11|0)+1>>0]|0;jh=a[Ke+(Nf*11|0)+2>>0]|0;lh=ne+be|0;vh=Jd(d[Ke+(Nf*11|0)+3>>0]|0,0,56)|0;hg=C;eh=Jd(jh&255|0,0,48)|0;jh=C;kh=Jd(ph&255|0,0,40)|0;ph=ha+(lh<<3)|0;c[ph>>2]=hh|zh<<24|wh<<16&16711680|rh<<8|kh|eh|vh;c[ph+4>>2]=gh&255|C|jh|hg;hg=zh&255;zh=d[qh>>0]|0;qh=d[Ke+(Nf*11|0)+9>>0]|0;jh=c[Oe>>2]|0;gh=jh&255;ph=jh>>>5;vh=jh>>>10&63;eh=jh>>>13;kh=jh>>>18&63;jh=gh<<3&248|gh>>>2;gh=c[17484+(zh<<4)+(d[Ke+(Nf*11|0)+8>>0]<<2)>>2]|0;rh=jh+gh|0;if(rh>>>0>255)if((rh|0)<0){Nh=0;ia=218}else Oh=255;else{Nh=rh;ia=218}if((ia|0)==218){ia=0;Oh=Nh}rh=ph&248|vh;vh=rh+gh|0;if(vh>>>0>255)if((vh|0)<0){Ph=0;ia=221}else Qh=255;else{Ph=vh;ia=221}if((ia|0)==221){ia=0;Qh=Ph}vh=eh&248|kh;kh=vh+gh|0;if(kh>>>0>255)if((kh|0)<0){Rh=0;ia=224}else Sh=255;else{Rh=kh;ia=224}if((ia|0)==224){ia=0;Sh=Rh}kh=Oh&255;gh=Qh&255;eh=Sh&255;ph=c[17484+(zh<<4)+(qh<<2)>>2]|0;qh=ph+jh|0;if(qh>>>0>255)if((qh|0)<0){Th=0;ia=227}else Uh=255;else{Th=qh;ia=227}if((ia|0)==227){ia=0;Uh=Th}qh=ph+rh|0;if(qh>>>0>255)if((qh|0)<0){Vh=0;ia=230}else Wh=255;else{Vh=qh;ia=230}if((ia|0)==230){ia=0;Wh=Vh}qh=ph+vh|0;if(qh>>>0>255)if((qh|0)<0){Xh=0;ia=233}else Yh=255;else{Xh=qh;ia=233}if((ia|0)==233){ia=0;Yh=Xh}if((kh&255)>(Uh&255)){ia=235;break c}if((gh&255)>(Wh&255)){ia=237;break c}if((eh&255)>(Yh&255)){ia=239;break c}eh=lh<<2;gh=e[z+eh>>1]|0;kh=e[z+(eh|2)>>1]|0;eh=d[Qe+(gh<<3)+4>>0]|0;qh=d[Ke+(kh*11|0)+9>>0]|0;vh=d[Qe+(gh<<3)+1>>0]|0;gh=vh<<3&248|vh>>>2;vh=gh+(c[17484+(eh<<4)+(d[Ke+(kh*11|0)+8>>0]<<2)>>2]|0)|0;if(vh>>>0>255)if((vh|0)<0){Zh=0;ia=242}else _h=255;else{Zh=vh;ia=242}if((ia|0)==242){ia=0;_h=Zh}vh=(c[17484+(eh<<4)+(qh<<2)>>2]|0)+gh|0;if(vh>>>0>255)if((vh|0)<0){$h=0;ia=245}else ai=255;else{$h=vh;ia=245}if((ia|0)==245){ia=0;ai=$h}if(_h>>>0>ai>>>0){ia=247;break c}vh=ai&255;gh=a[501192+(_h&255)>>0]|0;qh=Oh&255;if((_h&255)<<24>>24==-1){eh=a[500093+qh>>0]|0;kh=a[500093+(Qh&255)>>0]|0;if(((kh|eh)&255)>=32){ia=250;break c}ph=(eh&255)<<10|(kh&255)<<5|d[500349+(Sh&255)>>0]<<1|32768;if(ph>>>0<65536)bi=ph;else{ia=252;break c}}else{ph=a[500349+qh>>0]|0;qh=a[500349+(Qh&255)>>0]|0;kh=a[501448+(Sh&255)>>0]|0;if(!(((qh|ph)&255)<16&((kh|gh)&255)<8)){ia=254;break c}eh=(ph&255)<<8|(gh&255)<<12|(qh&255)<<4|(kh&255)<<1;if(eh>>>0<65536)bi=eh;else{ia=256;break c}}eh=ai&255;kh=a[501841+eh>>0]|0;qh=Uh&255;if((eh+-239|0)>>>0<17){eh=a[500680+qh>>0]|0;gh=a[500680+(Wh&255)>>0]|0;ph=a[500680+(Yh&255)>>0]|0;if(((gh|eh|ph)&255)>=32){ia=259;break c}rh=(eh&255)<<10|(gh&255)<<5|ph&255|32768;if(rh>>>0>=65536){ia=261;break c}ci=rh<<16|bi&65535}else{rh=a[500936+qh>>0]|0;qh=a[500936+(Wh&255)>>0]|0;ph=a[500936+(Yh&255)>>0]|0;if(!((vh&255)<239?((qh|rh|ph)&255)<16:0)){ia=264;break c}vh=(rh&255)<<8|(kh&255)<<12|(qh&255)<<4|ph&255;if(vh>>>0>=65536){ia=266;break c}ci=vh<<16|bi&65535}c[ga+(lh<<2)>>2]=ci;ah=hg;bh=fh;ch=mh;dh=ih;break f;break}case 9:case 8:{ih=_(ne+ce|0,p)|0;mh=h+ih|0;fh=mh;c[fh>>2]=32;c[fh+4>>2]=-262144;fh=h+(ih+8)|0;c[fh>>2]=3;c[fh+4>>2]=0;fh=a[Ke+(Nf*11|0)+8>>0]|0;hg=fh&255;lh=d[Ke+(Nf*11|0)+9>>0]|0;vh=a[Oe>>0]|0;ph=a[Oe+1>>0]|0;qh=a[Oe+2>>0]|0;kh=d[Qe+(Mf<<3)+4>>0]|0;switch(a[Ke+(Nf*11|0)+10>>0]|0){case 1:{if((fh&255)>=4){ia=271;break c}fh=vh&255;rh=ph&255;gh=rh<<3|rh>>>2;rh=qh&255;eh=rh<<3|rh>>>2;rh=c[17484+(kh<<4)+(hg<<2)>>2]|0;jh=rh+(fh<<3|fh>>>2)|0;if(jh>>>0>255)if((jh|0)<0){di=0;ia=274}else ei=255;else{di=jh;ia=274}if((ia|0)==274){ia=0;ei=di}jh=rh+gh|0;if(jh>>>0>255)if((jh|0)<0){fi=0;ia=277}else gi=255;else{fi=jh;ia=277}if((ia|0)==277){ia=0;gi=fi}jh=rh+eh|0;if(jh>>>0>255)if((jh|0)<0){hi=0;ia=280}else ii=255;else{hi=jh;ia=280}if((ia|0)==280){ia=0;ii=hi}jh=Jd(d[502097+(ei<<1)+1>>0]|0,0,8)|0;eh=Jd(d[502097+(gi<<1)+1>>0]|0,0,22)|0;Jd(d[502097+(ii<<1)+1>>0]|0,0,36)|0;rh=C&2032;gh=Jd(d[502097+(ei<<1)>>0]|0,0,15)|0;fh=Jd(d[502097+(gi<<1)>>0]|0,0,29)|0;zh=C&15;wh=mh;c[wh>>2]=Jd(d[502097+(ii<<1)>>0]|0,0,43)|0|(jh&32512|eh&532676608|gh&4161536|fh&-536870912)|32;c[wh+4>>2]=rh|zh|C|-262144;zh=66;rh=31;wh=715827883;fh=2147483647;while(1){gh=zh&7;eh=8-gh|0;jh=eh>>>0<rh>>>0?eh:rh;eh=h+((zh>>>3)+ih)|0;a[eh>>0]=d[eh>>0]&(fh<<gh^255)|wh<<gh;if((rh|0)==(jh|0))break;else{zh=jh+zh|0;rh=rh-jh|0;wh=wh>>>jh;fh=fh>>>jh}}break}case 2:{a[D>>0]=vh;a[Ea>>0]=ph;a[Fa>>0]=qh;a[Ga>>0]=-1;ob(I,D,kh);fh=c[I+(hg<<2)>>2]|0;wh=fh>>>9&127;rh=fh>>>17&127;zh=c[I+(lh<<2)>>2]|0;jh=zh>>>9&127;gh=zh>>>17&127;eh=fh>>>1&127;fh=mh;hh=c[fh>>2]|0;th=c[fh+4>>2]|0;fh=Jd(eh|0,0,8)|0;uh=C;sh=Jd(wh|0,0,22)|0;ji=C;ki=Jd(rh|0,0,36)|0;li=C;mi=zh>>>1&127;zh=Jd(mi|0,0,15)|0;ni=C;oi=Jd(jh|0,0,29)|0;pi=C;qi=Jd(gh|0,0,43)|0;ri=fh|hh&255|sh|ki|zh|oi|qi;qi=uh|th&-262144|ji|li|ni|pi|C;pi=mh;c[pi>>2]=ri;c[pi+4>>2]=qi;pi=Jd(mi|0,0,8)|0;mi=C;ni=Jd(jh|0,0,22)|0;jh=C;li=Jd(gh|0,0,36)|0;gh=C;ji=Jd(eh|0,0,15)|0;eh=C;th=Jd(wh|0,0,29)|0;wh=C;uh=Jd(rh|0,0,43)|0;rh=th|ji|uh|pi|ni|li;li=wh|eh|C|mi|jh|gh;gh=ri;ri=qi;qi=0;jh=0;mi=0;eh=0;while(1){wh=Ke+(Nf*11|0)+eh|0;ni=a[wh>>0]|0;pi=(ni&3|0)==(hg|0)?mi:mi^3;do if(!eh){if(!(pi&2)){si=ni;ti=gh;ui=ri;vi=1;wi=pi;xi=mi;break}uh=rh|gh&255;ji=li|ri&-262144;th=mh;c[th>>2]=uh;c[th+4>>2]=ji;si=a[wh>>0]|0;ti=uh;ui=ji;vi=1;wi=0;xi=3}else{si=ni;ti=gh;ui=ri;vi=2;wi=pi;xi=mi}while(0);pi=vi+qi|0;ni=si&255;wh=xi^3;ji=wi<<qi|jh|((ni>>>6|0)==(hg|0)?xi:wh)<<pi+4|((ni>>>2&3|0)==(hg|0)?xi:wh)<<pi|((ni>>>4&3|0)==(hg|0)?xi:wh)<<pi+2;eh=eh+1|0;if((eh|0)==4){yi=ji;break}else{gh=ti;ri=ui;qi=pi+6|0;jh=ji;mi=xi}}if((yi|0)>-1){zi=66;Ai=31;Bi=yi;Ci=2147483647}else{ia=288;break c}while(1){mi=zi&7;jh=8-mi|0;qi=jh>>>0<Ai>>>0?jh:Ai;jh=h+((zi>>>3)+ih)|0;a[jh>>0]=d[jh>>0]&(Ci<<mi^255)|Bi<<mi;if((Ai|0)==(qi|0))break;else{zi=qi+zi|0;Ai=Ai-qi|0;Bi=Bi>>>qi;Ci=Ci>>>qi}}break}default:{qi=kh<<5;mi=(c[17764+(hg<<4)+(lh<<2)>>2]|0)*10|0;jh=mi+((qi+(vh&255)|0)*60|0)|0;ri=mi+((qi+(ph&255)|0)*60|0)|0;gh=mi+((qi+(qh&255)|0)*60|0)|0;qi=(e[213148+(ri<<2)+2>>1]|0)+(e[213148+(jh<<2)+2>>1]|0)+(e[213148+(gh<<2)+2>>1]|0)|0;mi=(e[213148+((ri|1)<<2)+2>>1]|0)+(e[213148+((jh|1)<<2)+2>>1]|0)+(e[213148+((gh|1)<<2)+2>>1]|0)|0;eh=mi>>>0<qi>>>0;li=eh?mi:qi;qi=(e[213148+(ri+2<<2)+2>>1]|0)+(e[213148+(jh+2<<2)+2>>1]|0)+(e[213148+(gh+2<<2)+2>>1]|0)|0;mi=qi>>>0<li>>>0;rh=mi?qi:li;li=(e[213148+(ri+3<<2)+2>>1]|0)+(e[213148+(jh+3<<2)+2>>1]|0)+(e[213148+(gh+3<<2)+2>>1]|0)|0;qi=li>>>0<rh>>>0;ji=qi?li:rh;rh=(e[213148+(ri+4<<2)+2>>1]|0)+(e[213148+(jh+4<<2)+2>>1]|0)+(e[213148+(gh+4<<2)+2>>1]|0)|0;li=rh>>>0<ji>>>0;pi=li?rh:ji;ji=(e[213148+(ri+5<<2)+2>>1]|0)+(e[213148+(jh+5<<2)+2>>1]|0)+(e[213148+(gh+5<<2)+2>>1]|0)|0;rh=ji>>>0<pi>>>0;wh=rh?ji:pi;pi=(e[213148+(ri+6<<2)+2>>1]|0)+(e[213148+(jh+6<<2)+2>>1]|0)+(e[213148+(gh+6<<2)+2>>1]|0)|0;ji=pi>>>0<wh>>>0;ni=ji?pi:wh;wh=(e[213148+(ri+7<<2)+2>>1]|0)+(e[213148+(jh+7<<2)+2>>1]|0)+(e[213148+(gh+7<<2)+2>>1]|0)|0;pi=wh>>>0<ni>>>0;uh=pi?wh:ni;ni=(e[213148+(ri+8<<2)+2>>1]|0)+(e[213148+(jh+8<<2)+2>>1]|0)+(e[213148+(gh+8<<2)+2>>1]|0)|0;wh=ni>>>0<uh>>>0;th=((e[213148+(ri+9<<2)+2>>1]|0)+(e[213148+(jh+9<<2)+2>>1]|0)+(e[213148+(gh+9<<2)+2>>1]|0)|0)>>>0<(wh?ni:uh)>>>0?9:wh?8:pi?7:ji?6:rh?5:li?4:qi?3:mi?2:eh&1;eh=th+jh|0;jh=a[213148+(eh<<2)>>0]|0;if(!(a[(d[Af>>0]&3)+(507534+(th<<2))>>0]&2)){mi=mh;qi=c[mi>>2]|0;li=c[mi+4>>2]|0;mi=Jd(jh&255|0,0,8)|0;rh=th+ri|0;ji=Jd(d[213148+(rh<<2)>>0]|0,0,22)|0;pi=th+gh|0;Jd(d[213148+(pi<<2)>>0]|0,0,36)|0;wh=li&-2048|C&2032;li=Jd(d[213148+(eh<<2)+1>>0]|0,0,15)|0;uh=Jd(d[213148+(rh<<2)+1>>0]|0,0,29)|0;rh=qi&255|mi&32512|ji&532676608|li&4161536|uh&-536870912;uh=wh|C&15;wh=mh;c[wh>>2]=rh;c[wh+4>>2]=uh;Jd(d[213148+(pi<<2)+1>>0]|0,0,43)|0;Di=rh;Ei=uh&-260097|C&260096;Fi=0}else{uh=mh;rh=c[uh>>2]|0;pi=c[uh+4>>2]|0;uh=Jd(d[213148+(eh<<2)+1>>0]|0,0,8)|0;eh=th+ri|0;ri=Jd(d[213148+(eh<<2)+1>>0]|0,0,22)|0;wh=th+gh|0;Jd(d[213148+(wh<<2)+1>>0]|0,0,36)|0;gh=C&2032;li=Jd(jh&255|0,0,15)|0;jh=Jd(d[213148+(eh<<2)>>0]|0,0,29)|0;eh=rh&255|li&4161536|uh&32512|ri&532676608|jh&-536870912;jh=pi&-2048|gh|C&15;gh=mh;c[gh>>2]=eh;c[gh+4>>2]=jh;Jd(d[213148+(wh<<2)>>0]|0,0,43)|0;Di=eh;Ei=jh&-260097|C&260096;Fi=3}jh=mh;c[jh>>2]=Di;c[jh+4>>2]=Ei;jh=0;eh=0;wh=0;while(1){gh=d[Ke+(Nf*11|0)+wh>>0]|0;pi=((wh|0)==0?1:2)+jh|0;ri=(d[(gh>>>4&3)+(507534+(th<<2))>>0]^Fi)<<pi+2|eh|(d[(gh>>>2&3)+(507534+(th<<2))>>0]^Fi)<<pi|(d[(gh&3)+(507534+(th<<2))>>0]^Fi)<<jh|(d[(gh>>>6)+(507534+(th<<2))>>0]^Fi)<<pi+4;wh=wh+1|0;if(wh>>>0>=4){Gi=ri;break}else{jh=pi+6|0;eh=ri}}if((Gi|0)>-1){Hi=66;Ii=31;Ji=Gi;Ki=2147483647}else{ia=295;break c}while(1){eh=Hi&7;jh=8-eh|0;wh=jh>>>0<Ii>>>0?jh:Ii;jh=h+((Hi>>>3)+ih)|0;a[jh>>0]=d[jh>>0]&(Ki<<eh^255)|Ji<<eh;if((Ii|0)==(wh|0))break;else{Hi=wh+Hi|0;Ii=Ii-wh|0;Ji=Ji>>>wh;Ki=Ki>>>wh}}}}ah=je;bh=ie;ch=he;dh=ge;break f;break}case 10:{ih=_(ne+ce|0,p)|0;wh=h+ih|0;eh=a[Ke+(Nf*11|0)+8>>0]|0;jh=eh&255;th=d[Ke+(Nf*11|0)+9>>0]|0;mh=d[Qe+(Mf<<3)+4>>0]|0;switch(a[Ke+(Nf*11|0)+10>>0]|0){case 1:{if((eh&255)>=4){ia=302;break c}eh=d[Oe>>0]|0;qh=(eh<<3|eh>>>2)+(c[17484+(mh<<4)+(jh<<2)>>2]|0)|0;if(qh>>>0>255)if((qh|0)<0){Li=0;ia=305}else Mi=255;else{Li=qh;ia=305}if((ia|0)==305){ia=0;Mi=Li}qh=wh;eh=c[qh>>2]|0;ph=c[qh+4>>2]|0;Jd(Mi|0,0,50)|0;qh=C;vh=wh;c[vh>>2]=Jd(Mi|0,0,58)|0|eh;c[vh+4>>2]=C|ph&262143|qh&66846720;qh=h+(ih+8)|0;ph=qh;vh=c[ph+4>>2]|0;eh=qh;c[eh>>2]=c[ph>>2]&-4|Mi>>>6&3;c[eh+4>>2]=vh;break}case 2:{vh=d[Oe+1>>0]|0;eh=vh<<3|vh>>>2;vh=eh+(c[17484+(mh<<4)>>2]|0)|0;if(vh>>>0>255)if((vh|0)<0){Ni=0;ia=309}else Oi=255;else{Ni=vh;ia=309}if((ia|0)==309){ia=0;Oi=Ni}c[L>>2]=Oi;vh=(c[17484+(mh<<4)+4>>2]|0)+eh|0;if(vh>>>0>255)if((vh|0)<0){Pi=0;ia=312}else Qi=255;else{Pi=vh;ia=312}if((ia|0)==312){ia=0;Qi=Pi}c[Ha>>2]=Qi;vh=(c[17484+(mh<<4)+8>>2]|0)+eh|0;if(vh>>>0>255)if((vh|0)<0){Ri=0;ia=315}else Si=255;else{Ri=vh;ia=315}if((ia|0)==315){ia=0;Si=Ri}c[Ia>>2]=Si;vh=(c[17484+(mh<<4)+12>>2]|0)+eh|0;if(vh>>>0>255)if((vh|0)<0){Ti=0;ia=318}else Ui=255;else{Ti=vh;ia=318}if((ia|0)==318){ia=0;Ui=Ti}c[Ja>>2]=Ui;vh=c[L+(jh<<2)>>2]|0;eh=wh;ph=c[eh>>2]|0;qh=c[eh+4>>2]|0;Jd(vh|0,0,50)|0;eh=C&66846720|qh&262143;qh=c[L+(th<<2)>>2]|0;lh=ph|(Jd(qh|0,0,58)|0);ph=eh|C;eh=wh;c[eh>>2]=lh;c[eh+4>>2]=ph;eh=h+(ih+8)|0;hg=eh;kh=c[hg+4>>2]|0;ri=qh>>>6&3|c[hg>>2]&-4;hg=eh;c[hg>>2]=ri;c[hg+4>>2]=kh;Jd(qh|0,0,50)|0;qh=C&66846720;hg=Jd(vh|0,0,58)|0;pi=vh>>>6&3;vh=qh|C;qh=ph;ph=lh;lh=ri;ri=kh;kh=0;gh=0;uh=0;li=0;while(1){rh=Ke+(Nf*11|0)+li|0;ji=(d[rh>>0]&3|0)==(jh|0)?uh:uh^3;do if(!li){if(!(ji&2)){Vi=lh;Wi=ri;Xi=ph;Yi=qh;Zi=1;_i=ji;$i=uh;break}mi=hg|ph;qi=vh|qh&262143;ni=wh;c[ni>>2]=mi;c[ni+4>>2]=qi;ni=lh&-4|pi;oi=eh;c[oi>>2]=ni;c[oi+4>>2]=ri;Vi=ni;Wi=ri;Xi=mi;Yi=qi;Zi=1;_i=0;$i=3}else{Vi=lh;Wi=ri;Xi=ph;Yi=qh;Zi=2;_i=ji;$i=uh}while(0);ji=Zi+kh|0;qi=d[rh>>0]|0;mi=$i^3;ni=((qi>>>6|0)==(jh|0)?$i:mi)<<ji+4|(((qi>>>4&3|0)==(jh|0)?$i:mi)<<ji+2|(((qi>>>2&3|0)==(jh|0)?$i:mi)<<ji|(_i<<kh|gh)));li=li+1|0;if(li>>>0>=4){aj=ni;break}else{qh=Yi;ph=Xi;lh=Vi;ri=Wi;kh=ji+6|0;gh=ni;uh=$i}}if((aj|0)>-1){bj=97;cj=31;dj=aj;ej=2147483647}else{ia=324;break c}while(1){uh=bj&7;gh=8-uh|0;kh=gh>>>0<cj>>>0?gh:cj;gh=h+((bj>>>3)+ih)|0;a[gh>>0]=d[gh>>0]&(ej<<uh^255)|dj<<uh;if((cj|0)==(kh|0))break;else{bj=kh+bj|0;cj=cj-kh|0;dj=dj>>>kh;ej=ej>>>kh}}break}default:{kh=(c[17828+(jh<<4)+(th<<2)>>2]|0)+(mh*192|0)+((d[Oe>>0]|0)*6|0)|0;uh=a[502649+(kh*3|0)>>0]|0;gh=uh&255;ri=wh;lh=c[ri>>2]|0;ph=c[ri+4>>2]|0;ri=Jd(gh|0,0,50)|0;qh=C;li=a[502649+(kh*3|0)+1>>0]|0;eh=li&255;pi=Jd(eh|0,0,58)|0;vh=lh|ri|pi;pi=ph&262143|qh|C;qh=wh;c[qh>>2]=vh;c[qh+4>>2]=pi;qh=h+(ih+8)|0;ph=qh;ri=c[ph+4>>2]|0;lh=(li&255)>>>6|c[ph>>2]&-4;ph=qh;c[ph>>2]=lh;c[ph+4>>2]=ri;ph=d[502649+(kh*3|0)+2>>0]|0;kh=Jd(eh|0,0,50)|0;eh=C;li=Jd(gh|0,0,58)|0;gh=(uh&255)>>>6;uh=kh|li;li=eh|C;eh=pi;pi=vh;vh=lh;lh=ri;ri=0;kh=0;hg=ph;ph=0;while(1){ni=Ke+(Nf*11|0)+ph|0;ji=hg>>>(d[ni>>0]<<1&6);mi=ji&3;do if(!ph){if(!(ji&2)){fj=vh;gj=lh;hj=pi;ij=eh;jj=1;kj=mi;lj=hg;break}qi=uh|pi;oi=li|eh&262143;zh=wh;c[zh>>2]=qi;c[zh+4>>2]=oi;zh=vh&-4|gh;ki=qh;c[ki>>2]=zh;c[ki+4>>2]=lh;fj=zh;gj=lh;hj=qi;ij=oi;jj=1;kj=mi^3;lj=hg^255}else{fj=vh;gj=lh;hj=pi;ij=eh;jj=2;kj=mi;lj=hg}while(0);mi=jj+ri|0;ji=d[ni>>0]|0;rh=(lj>>>(ji>>>5&6)&3)<<mi+4|((lj>>>(ji>>>3&6)&3)<<mi+2|((lj>>>(ji>>>1&6)&3)<<mi|(kj<<ri|kh)));ph=ph+1|0;if(ph>>>0>=4){mj=rh;break}else{eh=ij;pi=hj;vh=fj;lh=gj;ri=mi+6|0;kh=rh;hg=lj}}if((mj|0)>-1){nj=97;oj=31;pj=mj;qj=2147483647}else{ia=331;break c}while(1){hg=nj&7;kh=8-hg|0;ri=kh>>>0<oj>>>0?kh:oj;kh=h+((nj>>>3)+ih)|0;a[kh>>0]=d[kh>>0]&(qj<<hg^255)|pj<<hg;if((oj|0)==(ri|0))break;else{nj=ri+nj|0;oj=oj-ri|0;pj=pj>>>ri;qj=qj>>>ri}}}}ah=je;bh=ie;ch=he;dh=ge;break f;break}case 11:{ih=_(ne+ce|0,p)|0;ri=h+ih|0;hg=a[Ke+(Nf*11|0)+8>>0]|0;kh=hg&255;lh=a[Ke+(Nf*11|0)+9>>0]|0;vh=d[Qe+(Mf<<3)+4>>0]|0;if(hg<<24>>24==lh<<24>>24){if((hg&255)>=4){ia=337;break c}pi=d[Oe>>0]|0;eh=(pi<<3|pi>>>2)+(c[17484+(vh<<4)+(kh<<2)>>2]|0)|0;if(eh>>>0>255)if((eh|0)<0){rj=0;ia=340}else sj=255;else{rj=eh;ia=340}if((ia|0)==340){ia=0;sj=rj}b[ri>>1]=sj&255|7424;eh=h+(ih+2)|0;a[eh>>0]=a[463004]|0;a[eh+1>>0]=a[463005]|0;a[eh+2>>0]=a[463006]|0;a[eh+3>>0]=a[463007]|0;a[eh+4>>0]=a[463008]|0;a[eh+5>>0]=a[463009]|0;ah=je;bh=ie;ch=he;dh=ge;break f}i:do switch(hg<<24>>24){case 0:{if(lh<<24>>24==3){tj=0;break i}if(lh<<24>>24==2)tj=2;else ia=349;break}case 1:{if(lh<<24>>24==3){tj=1;break i}if(lh<<24>>24==2)tj=3;else ia=349;break}default:ia=349}while(0);if((ia|0)==349){ia=0;tj=4}lh=tj>>>0>3?0:tj;hg=(d[Oe>>0]|0)+(vh<<5)|0;eh=a[274588+(hg<<4)+(lh<<2)+1>>0]|0;b[ri>>1]=(eh&255)<<12&65535|d[274588+(hg<<4)+(lh<<2)>>0]|((eh&255)>>>4&255)<<8&65535;eh=e[274588+(hg<<4)+(lh<<2)+2>>1]|0;lh=0;hg=0;kh=0;while(1){pi=d[Ke+(Nf*11|0)+kh>>0]|0;ph=_(kh,-3)|0;qh=Jd(eh>>>((pi>>>4&3)*3|0)&7|0,0,ph+21|0)|0;gh=C;wh=Jd(eh>>>((pi>>>2&3)*3|0)&7|0,0,ph+33|0)|0;li=C;uh=Jd(eh>>>((pi&3)*3|0)&7|0,0,ph+45|0)|0;mh=C|hg;th=Jd(eh>>>((pi>>>6)*3|0)&7|0,0,ph+9|0)|0;ph=uh|lh|th|wh|qh;qh=mh|C|li|gh;kh=kh+1|0;if(kh>>>0>=4){uj=ph;vj=qh;break}else{lh=ph;hg=qh}}hg=Id(uj|0,vj|0,40)|0;a[h+(ih+2)>>0]=hg;a[h+(ih+3)>>0]=vj;hg=Id(uj|0,vj|0,24)|0;a[h+(ih+4)>>0]=hg;hg=Id(uj|0,vj|0,16)|0;a[h+(ih+5)>>0]=hg;hg=Id(uj|0,vj|0,8)|0;a[h+(ih+6)>>0]=hg;a[h+(ih+7)>>0]=uj;ah=je;bh=ie;ch=he;dh=ge;break f;break}case 12:{hg=_(ne+ce|0,p)|0;lh=h+hg|0;a[Ka>>0]=0;a[La>>0]=0;do if(y){kh=e[h+(hg+2)>>1]|0;eh=a[Ke+(kh*11|0)+10>>0]|0;ri=eh&255;if(eh<<24>>24!=1){wj=255;xj=ri;break}eh=e[lh>>1]|0;vh=d[Qe+(eh<<3)+4>>0]|0;qh=d[Qe+(eh<<3)+1>>0]|0;eh=qh<<3|qh>>>2;qh=eh+(c[17484+(vh<<4)>>2]|0)|0;if(qh>>>0>255)if((qh|0)<0){yj=0;ia=354}else zj=255;else{yj=qh;ia=354}if((ia|0)==354){ia=0;zj=yj}c[L>>2]=zj;qh=(c[17484+(vh<<4)+4>>2]|0)+eh|0;if(qh>>>0>255)if((qh|0)<0){Aj=0;ia=357}else Bj=255;else{Aj=qh;ia=357}if((ia|0)==357){ia=0;Bj=Aj}c[Ha>>2]=Bj;qh=(c[17484+(vh<<4)+8>>2]|0)+eh|0;if(qh>>>0>255)if((qh|0)<0){Cj=0;ia=360}else Dj=255;else{Cj=qh;ia=360}if((ia|0)==360){ia=0;Dj=Cj}c[Ia>>2]=Dj;qh=(c[17484+(vh<<4)+12>>2]|0)+eh|0;if(qh>>>0>255)if((qh|0)<0){Ej=0;ia=363}else Fj=255;else{Ej=qh;ia=363}if((ia|0)==363){ia=0;Fj=Ej}c[Ja>>2]=Fj;wj=c[L+(d[Ke+(kh*11|0)+8>>0]<<2)>>2]|0;xj=ri}else{wj=255;xj=1}while(0);ih=a[Qe+(Mf<<3)+4>>0]|0;ri=ih&255;kh=Ke+(Nf*11|0)+8|0;qh=a[kh>>0]|0;eh=qh&255;vh=Ke+(Nf*11|0)+9|0;ph=a[vh>>0]|0;gh=ph&255;li=Ke+(Nf*11|0)+10|0;mh=a[li>>0]|0;j:do if((xj|0)==1&mh<<24>>24==1){if((qh&255)>=4){ia=367;break c}wh=d[Oe>>0]|0;th=d[Oe+1>>0]|0;uh=th<<3|th>>>2;th=d[Oe+2>>0]|0;pi=th<<3|th>>>2;th=c[17484+(ri<<4)+(eh<<2)>>2]|0;jh=(wh<<3|wh>>>2)+th|0;if(jh>>>0>255)if((jh|0)<0){Gj=0;ia=370}else Hj=255;else{Gj=jh;ia=370}if((ia|0)==370){ia=0;Hj=Gj}jh=uh+th|0;if(jh>>>0>255)if((jh|0)<0){Ij=0;ia=373}else Jj=255;else{Ij=jh;ia=373}if((ia|0)==373){ia=0;Jj=Ij}jh=pi+th|0;if(jh>>>0>255)if((jh|0)<0){Kj=0;ia=376}else Lj=255;else{Kj=jh;ia=376}if((ia|0)==376){ia=0;Lj=Kj}a[lh>>0]=-4;a[h+(hg+1)>>0]=-3;a[h+(hg+2)>>0]=-1;a[h+(hg+3)>>0]=-1;c[h+(hg+4)>>2]=-1;c[h+(hg+8)>>2]=0;c[h+(hg+12)>>2]=0;jh=16;th=Hj<<8|Hj;pi=64;while(1){uh=pi&7;wh=8-uh|0;rh=(wh|0)<(jh|0)?wh:jh;wh=h+((pi>>3)+hg)|0;a[wh>>0]=d[wh>>0]|th<<uh;uh=rh+pi|0;if((jh|0)==(rh|0)){Mj=uh;break}else{jh=jh-rh|0;th=th>>>rh;pi=uh}}pi=16;th=Jj<<8|Jj;jh=Mj;while(1){ni=jh&7;uh=8-ni|0;rh=(uh|0)<(pi|0)?uh:pi;uh=h+((jh>>3)+hg)|0;a[uh>>0]=d[uh>>0]|th<<ni;ni=rh+jh|0;if((pi|0)==(rh|0)){Nj=ni;break}else{pi=pi-rh|0;th=th>>>rh;jh=ni}}jh=16;th=Lj<<8|Lj;pi=Nj;while(1){ni=pi&7;rh=8-ni|0;uh=(rh|0)<(jh|0)?rh:jh;rh=h+((pi>>3)+hg)|0;a[rh>>0]=d[rh>>0]|th<<ni;ni=uh+pi|0;if((jh|0)==(uh|0)){Oj=ni;break}else{jh=jh-uh|0;th=th>>>uh;pi=ni}}pi=16;th=wj<<8|wj;jh=Oj;while(1){ni=jh&7;uh=8-ni|0;rh=(uh|0)<(pi|0)?uh:pi;uh=h+((jh>>3)+hg)|0;a[uh>>0]=d[uh>>0]|th<<ni;if((pi|0)==(rh|0))break;else{pi=pi-rh|0;th=th>>>rh;jh=rh+jh|0}}}else{if(xj>>>0<3&(mh&255)<3){ob(I,Oe,ri);jh=c[I+(eh<<2)>>2]|0;th=jh&255;a[E>>0]=th;pi=(jh&65535)>>>8;rh=pi&255;a[Ma>>0]=rh;ni=jh>>>16;uh=ni&255;a[Na>>0]=uh;wh=c[I+(gh<<2)>>2]|0;mi=wh&255;a[Oa>>0]=mi;ji=(wh&65535)>>>8;oi=ji&255;a[Pa>>0]=oi;qi=wh>>>16;zh=qi&255;a[Qa>>0]=zh;if(((qi&255)+(wh&255)+(ji&65535)|0)<((ni&255)+(jh&255)+(pi&65535)|0)){a[E>>0]=mi;a[Oa>>0]=th;a[Ma>>0]=oi;a[Pa>>0]=rh;a[Na>>0]=zh;a[Qa>>0]=uh;Pj=mi;Qj=1}else{Pj=th;Qj=0}if(y){th=e[lh>>1]|0;mi=e[h+(hg+2)>>1]|0;uh=d[Qe+(th<<3)+4>>0]|0;zh=d[Ke+(mi*11|0)+8>>0]|0;rh=d[Ke+(mi*11|0)+9>>0]|0;oi=d[Qe+(th<<3)+1>>0]|0;th=oi<<3|oi>>>2;oi=th+(c[17484+(uh<<4)>>2]|0)|0;if(oi>>>0>255)if((oi|0)<0){Rj=0;ia=391}else Sj=255;else{Rj=oi;ia=391}if((ia|0)==391){ia=0;Sj=Rj}c[M>>2]=Sj;oi=(c[17484+(uh<<4)+4>>2]|0)+th|0;if(oi>>>0>255)if((oi|0)<0){Tj=0;ia=394}else Uj=255;else{Tj=oi;ia=394}if((ia|0)==394){ia=0;Uj=Tj}c[Ra>>2]=Uj;oi=(c[17484+(uh<<4)+8>>2]|0)+th|0;if(oi>>>0>255)if((oi|0)<0){Vj=0;ia=397}else Wj=255;else{Vj=oi;ia=397}if((ia|0)==397){ia=0;Wj=Vj}c[Sa>>2]=Wj;oi=(c[17484+(uh<<4)+12>>2]|0)+th|0;if(oi>>>0>255)if((oi|0)<0){Xj=0;ia=400}else Yj=255;else{Xj=oi;ia=400}if((ia|0)==400){ia=0;Yj=Xj}c[Ta>>2]=Yj;a[Ua>>0]=c[M+(zh<<2)>>2];a[Va>>0]=c[M+(rh<<2)>>2];zh=d[Ke+(mi*11|0)>>0]|0;a[Wa>>0]=(zh&3|0)==(rh|0)&1;a[Xa>>0]=(zh>>>2&3|0)==(rh|0)&1;a[Ya>>0]=(zh>>>4&3|0)==(rh|0)&1;a[Za>>0]=(zh>>>6|0)==(rh|0)&1;zh=d[Ke+(mi*11|0)+1>>0]|0;a[_a>>0]=(zh&3|0)==(rh|0)&1;a[$a>>0]=(zh>>>2&3|0)==(rh|0)&1;a[